summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore9
-rw-r--r--.hgignore19
-rw-r--r--BCT/BCT.sln782
-rw-r--r--BCT/BCT.vsmdi6
-rw-r--r--BCT/BytecodeTranslator/BytecodeTranslator.csproj241
-rw-r--r--BCT/BytecodeTranslator/CLRSemantics.cs41
-rw-r--r--BCT/BytecodeTranslator/ExceptionAnalysis.cs121
-rw-r--r--BCT/BytecodeTranslator/ExpressionTraverser.cs2608
-rw-r--r--BCT/BytecodeTranslator/Heap.cs349
-rw-r--r--BCT/BytecodeTranslator/HeapFactory.cs582
-rw-r--r--BCT/BytecodeTranslator/MetadataTraverser.cs721
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs174
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs865
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs64
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs377
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs81
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs375
-rw-r--r--BCT/BytecodeTranslator/Phone/stubs.bpl41
-rw-r--r--BCT/BytecodeTranslator/Prelude.cs20
-rw-r--r--BCT/BytecodeTranslator/Program.cs894
-rw-r--r--BCT/BytecodeTranslator/Readme.txt5
-rw-r--r--BCT/BytecodeTranslator/Sink.cs1437
-rw-r--r--BCT/BytecodeTranslator/StatementTraverser.cs599
-rw-r--r--BCT/BytecodeTranslator/TranslationException.cs27
-rw-r--r--BCT/BytecodeTranslator/TranslationHelper.cs205
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/BytecodeTranslator/BytecodeTranslatorPlugin.cs27
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/ContractAwareTranslator.cs15
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/IContractAwareTranslator.cs15
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/ITranslationPlugin.cs12
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/ITranslator.cs11
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneFeedbackPlugin.cs15
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneInitializationPlugin.cs21
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/Translator.cs169
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs41
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs36
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneInitializationTranslator.cs61
-rw-r--r--BCT/BytecodeTranslator/TraverserFactory.cs42
-rw-r--r--BCT/BytecodeTranslator/WholeProgram.cs338
-rw-r--r--BCT/BytecodeTranslator/app.config3
-rw-r--r--BCT/GetMeHere/AssertionInjector/AssertionInjector.csproj105
-rw-r--r--BCT/GetMeHere/AssertionInjector/Program.cs111
-rw-r--r--BCT/GetMeHere/AssertionInjector/Properties/AssemblyInfo.cs36
-rw-r--r--BCT/Local.testsettings31
-rw-r--r--BCT/PhoneControlsExtractor/MS Phone App Analysis doc.docxbin52801 -> 0 bytes
-rw-r--r--BCT/PhoneControlsExtractor/NavGraphBuilder.README.txt14
-rw-r--r--BCT/PhoneControlsExtractor/PhoneBoogieCodeGenerator.py288
-rw-r--r--BCT/PhoneControlsExtractor/PhoneControlsExtractor.py248
-rw-r--r--BCT/PhoneControlsExtractor/market_apps_analyses.xlsxbin11687 -> 0 bytes
-rw-r--r--BCT/PhoneControlsExtractor/navGraphBuilder.py299
-rw-r--r--BCT/RegressionTests/RegressionTestInput/Class1.cs212
-rw-r--r--BCT/RegressionTests/RegressionTestInput/Properties/AssemblyInfo.cs36
-rw-r--r--BCT/RegressionTests/RegressionTestInput/RegressionTestInput.csproj54
-rw-r--r--BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt1893
-rw-r--r--BCT/RegressionTests/TranslationTest/Properties/AssemblyInfo.cs35
-rw-r--r--BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt1879
-rw-r--r--BCT/RegressionTests/TranslationTest/TranslationTest.csproj98
-rw-r--r--BCT/RegressionTests/TranslationTest/UnitTest0.cs107
-rw-r--r--BCT/Samples/CodeCounter/codecounter.sln51
-rw-r--r--BCT/Samples/CodeCounter/codecounter.suobin33792 -> 0 bytes
-rw-r--r--BCT/Samples/CodeCounter/codecounter.vssscc10
-rw-r--r--BCT/Samples/CodeCounter/console/App.config18
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounter.csproj87
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounter.csproj.user6
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc10
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounterEngine.cs270
-rw-r--r--BCT/Samples/CodeCounter/console/CountCounterEvents.cs169
-rw-r--r--BCT/Samples/CodeCounter/console/FileTypes.cs47
-rw-r--r--BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC5
-rw-r--r--BCT/Samples/CodeCounter/console/Program.cs642
-rw-r--r--BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs36
-rw-r--r--BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dllbin155648 -> 0 bytes
-rw-r--r--BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs177
-rw-r--r--BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs136
-rw-r--r--BCT/Samples/CodeCounter/library/ConfigFileSections.cs122
-rw-r--r--BCT/Samples/CodeCounter/library/CustomExceptions.cs60
-rw-r--r--BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs120
-rw-r--r--BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC5
-rw-r--r--BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs57
-rw-r--r--BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs169
-rw-r--r--BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs161
-rw-r--r--BCT/Samples/CodeCounter/library/codecounterlibrary.csproj139
-rw-r--r--BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc10
-rw-r--r--BCT/Samples/Exceptions/ExceptionsExample.cs35
-rw-r--r--BCT/Samples/Generics/GenericsExample.cs20
-rw-r--r--BCT/Samples/Strings/StringsExample.cs20
-rw-r--r--BCT/Test/BCTClassTest/Answer0
-rw-r--r--BCT/Test/BCTClassTest/BCTClassTest.sln20
-rw-r--r--BCT/Test/BCTClassTest/BCTClassTest/BCTClassTest.csproj59
-rw-r--r--BCT/Test/BCTClassTest/BCTClassTest/Program.cs51
-rw-r--r--BCT/Test/BCTClassTest/BCTClassTest/Properties/AssemblyInfo.cs36
-rw-r--r--BCT/Test/BCTClassTest/runtest.bat13
-rw-r--r--BCT/Test/BCTStmtTest/Answer0
-rw-r--r--BCT/Test/BCTStmtTest/BCTStmtTest.sln20
-rw-r--r--BCT/Test/BCTStmtTest/BCTStmtTest/BCTStmtTest.csproj59
-rw-r--r--BCT/Test/BCTStmtTest/BCTStmtTest/Program.cs57
-rw-r--r--BCT/Test/BCTStmtTest/BCTStmtTest/Properties/AssemblyInfo.cs36
-rw-r--r--BCT/Test/BCTStmtTest/runtest.bat13
-rw-r--r--BCT/Test/alltests.txt2
-rw-r--r--BCT/Test/build.bat46
-rw-r--r--BCT/Test/buildall.bat24
-rw-r--r--BCT/Test/runtest.bat36
-rw-r--r--BCT/Test/runtestall.bat24
-rw-r--r--BCT/Test/test0/Answer99
-rw-r--r--BCT/Test/test0/runtest.bat19
-rw-r--r--BCT/Test/test0/stmts.cs57
-rw-r--r--BCT/Test/test1/Answer0
-rw-r--r--BCT/Test/test1/Locals.cs23
-rw-r--r--BCT/Test/test1/runtest.bat17
-rw-r--r--BCT/TraceAndTestImpact.testsettings21
-rw-r--r--BCT/TranslationPlugins/PhoneControlsPlugin.cs404
-rw-r--r--BCT/TranslationPlugins/Properties/AssemblyInfo.cs36
-rw-r--r--BCT/TranslationPlugins/TranslationPlugin.cs10
-rw-r--r--BCT/TranslationPlugins/TranslationPlugins.csproj55
-rw-r--r--Binaries/PrepareBoogieZip.bat7
-rw-r--r--Chalice/build.sbt10
-rw-r--r--Chalice/chalice.bat55
-rw-r--r--Chalice/doc/ast_2010-11-13.pdfbin38624 -> 0 bytes
-rw-r--r--Chalice/doc/ast_a3tiles_2010-11-13.pdfbin47185 -> 0 bytes
-rw-r--r--Chalice/readme.txt19
-rwxr-xr-xChalice/sbt1
-rw-r--r--Chalice/sbt-launch.jarbin937683 -> 0 bytes
-rw-r--r--Chalice/sbt.bat5
-rw-r--r--Chalice/scripts/create_release/README.TXT3
-rw-r--r--Chalice/scripts/create_release/create_release.bat24
-rw-r--r--Chalice/scripts/create_release/files/chalice.bat5
-rw-r--r--Chalice/src/main/scala/Ast.scala953
-rw-r--r--Chalice/src/main/scala/Boogie.scala310
-rw-r--r--Chalice/src/main/scala/Chalice.cs108
-rw-r--r--Chalice/src/main/scala/Chalice.scala500
-rw-r--r--Chalice/src/main/scala/ChaliceToCSharp.scala266
-rw-r--r--Chalice/src/main/scala/Graph.scala166
-rw-r--r--Chalice/src/main/scala/Parser.scala645
-rw-r--r--Chalice/src/main/scala/Prelude.scala432
-rw-r--r--Chalice/src/main/scala/PrettyPrinter.scala396
-rw-r--r--Chalice/src/main/scala/Resolver.scala1494
-rw-r--r--Chalice/src/main/scala/SmokeTest.scala249
-rw-r--r--Chalice/src/main/scala/Translator.scala3616
-rw-r--r--Chalice/tests/examples/AVLTree.iterative.chalice227
-rw-r--r--Chalice/tests/examples/AVLTree.iterative.output.txt4
-rw-r--r--Chalice/tests/examples/AVLTree.nokeys.chalice609
-rw-r--r--Chalice/tests/examples/AVLTree.nokeys.output.txt4
-rw-r--r--Chalice/tests/examples/AssociationList.chalice122
-rw-r--r--Chalice/tests/examples/AssociationList.output.txt10
-rw-r--r--Chalice/tests/examples/BackgroundComputation.chalice38
-rw-r--r--Chalice/tests/examples/BackgroundComputation.output.txt4
-rw-r--r--Chalice/tests/examples/CopyLessMessagePassing-with-ack.chalice87
-rw-r--r--Chalice/tests/examples/CopyLessMessagePassing-with-ack.output.txt8
-rw-r--r--Chalice/tests/examples/CopyLessMessagePassing-with-ack2.chalice86
-rw-r--r--Chalice/tests/examples/CopyLessMessagePassing-with-ack2.output.txt7
-rw-r--r--Chalice/tests/examples/CopyLessMessagePassing.chalice72
-rw-r--r--Chalice/tests/examples/CopyLessMessagePassing.output.txt4
-rw-r--r--Chalice/tests/examples/FictionallyDisjointCells.chalice75
-rw-r--r--Chalice/tests/examples/FictionallyDisjointCells.output.txt4
-rw-r--r--Chalice/tests/examples/ForkJoin.chalice77
-rw-r--r--Chalice/tests/examples/ForkJoin.output.txt4
-rw-r--r--Chalice/tests/examples/HandOverHand.chalice132
-rw-r--r--Chalice/tests/examples/HandOverHand.output.txt4
-rw-r--r--Chalice/tests/examples/OwickiGries.chalice35
-rw-r--r--Chalice/tests/examples/OwickiGries.output.txt4
-rw-r--r--Chalice/tests/examples/PetersonsAlgorithm.chalice79
-rw-r--r--Chalice/tests/examples/PetersonsAlgorithm.output.txt8
-rw-r--r--Chalice/tests/examples/ProdConsChannel.chalice45
-rw-r--r--Chalice/tests/examples/ProdConsChannel.output.txt4
-rw-r--r--Chalice/tests/examples/RockBand.chalice112
-rw-r--r--Chalice/tests/examples/RockBand.output.txt4
-rw-r--r--Chalice/tests/examples/Sieve.chalice63
-rw-r--r--Chalice/tests/examples/Sieve.output.txt4
-rw-r--r--Chalice/tests/examples/Solver.chalice44
-rw-r--r--Chalice/tests/examples/Solver.output.txt4
-rw-r--r--Chalice/tests/examples/TreeOfWorker.chalice29
-rw-r--r--Chalice/tests/examples/TreeOfWorker.output.txt4
-rw-r--r--Chalice/tests/examples/UnboundedThreads.chalice59
-rw-r--r--Chalice/tests/examples/UnboundedThreads.output.txt5
-rw-r--r--Chalice/tests/examples/cell.chalice163
-rw-r--r--Chalice/tests/examples/cell.output.txt8
-rw-r--r--Chalice/tests/examples/dining-philosophers.chalice93
-rw-r--r--Chalice/tests/examples/dining-philosophers.output.txt6
-rw-r--r--Chalice/tests/examples/generate_reference.bat2
-rw-r--r--Chalice/tests/examples/generate_reference_all.bat2
-rw-r--r--Chalice/tests/examples/iterator.chalice150
-rw-r--r--Chalice/tests/examples/iterator.output.txt4
-rw-r--r--Chalice/tests/examples/iterator2.chalice134
-rw-r--r--Chalice/tests/examples/iterator2.output.txt4
-rw-r--r--Chalice/tests/examples/linkedlist.chalice91
-rw-r--r--Chalice/tests/examples/linkedlist.output.txt4
-rw-r--r--Chalice/tests/examples/list-reverse.chalice44
-rw-r--r--Chalice/tests/examples/list-reverse.output.txt4
-rw-r--r--Chalice/tests/examples/lseg.chalice86
-rw-r--r--Chalice/tests/examples/lseg.output.txt4
-rw-r--r--Chalice/tests/examples/producer-consumer.chalice202
-rw-r--r--Chalice/tests/examples/producer-consumer.output.txt7
-rw-r--r--Chalice/tests/examples/reg_test.bat2
-rw-r--r--Chalice/tests/examples/reg_test_all.bat2
-rw-r--r--Chalice/tests/examples/swap.chalice20
-rw-r--r--Chalice/tests/examples/swap.output.txt4
-rw-r--r--Chalice/tests/examples/test.bat2
-rw-r--r--Chalice/tests/general-tests/FunctionPostcondition.chalice10
-rw-r--r--Chalice/tests/general-tests/FunctionPostcondition.output.txt4
-rw-r--r--Chalice/tests/general-tests/ImplicitLocals.chalice27
-rw-r--r--Chalice/tests/general-tests/ImplicitLocals.output.txt4
-rw-r--r--Chalice/tests/general-tests/LoopLockChange.chalice142
-rw-r--r--Chalice/tests/general-tests/LoopLockChange.output.txt12
-rw-r--r--Chalice/tests/general-tests/RockBand-automagic.chalice112
-rw-r--r--Chalice/tests/general-tests/RockBand-automagic.output.txt4
-rw-r--r--Chalice/tests/general-tests/SmokeTestTest.chalice121
-rw-r--r--Chalice/tests/general-tests/SmokeTestTest.output.txt23
-rw-r--r--Chalice/tests/general-tests/VariationsOfProdConsChannel.chalice88
-rw-r--r--Chalice/tests/general-tests/VariationsOfProdConsChannel.output.txt13
-rw-r--r--Chalice/tests/general-tests/cell-defaults.chalice153
-rw-r--r--Chalice/tests/general-tests/cell-defaults.output.txt10
-rw-r--r--Chalice/tests/general-tests/counter.chalice153
-rw-r--r--Chalice/tests/general-tests/counter.output.txt17
-rw-r--r--Chalice/tests/general-tests/generate_reference.bat2
-rw-r--r--Chalice/tests/general-tests/generate_reference_all.bat2
-rw-r--r--Chalice/tests/general-tests/ll-lastnode.chalice82
-rw-r--r--Chalice/tests/general-tests/ll-lastnode.output.txt6
-rw-r--r--Chalice/tests/general-tests/nestedPredicates.chalice114
-rw-r--r--Chalice/tests/general-tests/nestedPredicates.output.txt12
-rw-r--r--Chalice/tests/general-tests/prog0.chalice109
-rw-r--r--Chalice/tests/general-tests/prog0.output.txt146
-rw-r--r--Chalice/tests/general-tests/prog1.chalice86
-rw-r--r--Chalice/tests/general-tests/prog1.output.txt19
-rw-r--r--Chalice/tests/general-tests/prog2.chalice92
-rw-r--r--Chalice/tests/general-tests/prog2.output.txt12
-rw-r--r--Chalice/tests/general-tests/prog3.chalice246
-rw-r--r--Chalice/tests/general-tests/prog3.output.txt11
-rw-r--r--Chalice/tests/general-tests/prog4.chalice53
-rw-r--r--Chalice/tests/general-tests/prog4.output.txt14
-rw-r--r--Chalice/tests/general-tests/quantifiers.chalice59
-rw-r--r--Chalice/tests/general-tests/quantifiers.output.txt5
-rw-r--r--Chalice/tests/general-tests/reg_test.bat2
-rw-r--r--Chalice/tests/general-tests/reg_test_all.bat2
-rw-r--r--Chalice/tests/general-tests/test.bat2
-rw-r--r--Chalice/tests/general-tests/triggers.chalice81
-rw-r--r--Chalice/tests/general-tests/triggers.output.txt7
-rw-r--r--Chalice/tests/permission-model/basic.chalice232
-rw-r--r--Chalice/tests/permission-model/basic.output.txt8
-rw-r--r--Chalice/tests/permission-model/channels.chalice45
-rw-r--r--Chalice/tests/permission-model/channels.output.txt6
-rw-r--r--Chalice/tests/permission-model/generate_reference.bat2
-rw-r--r--Chalice/tests/permission-model/generate_reference_all.bat2
-rw-r--r--Chalice/tests/permission-model/locks.chalice146
-rw-r--r--Chalice/tests/permission-model/locks.output.txt20
-rw-r--r--Chalice/tests/permission-model/peculiar.chalice55
-rw-r--r--Chalice/tests/permission-model/peculiar.output.txt8
-rw-r--r--Chalice/tests/permission-model/permarith_parser.chalice37
-rw-r--r--Chalice/tests/permission-model/permarith_parser.output.txt13
-rw-r--r--Chalice/tests/permission-model/permission_arithmetic.chalice246
-rw-r--r--Chalice/tests/permission-model/permission_arithmetic.output.txt22
-rw-r--r--Chalice/tests/permission-model/predicate_error1.chalice20
-rw-r--r--Chalice/tests/permission-model/predicate_error1.output.txt3
-rw-r--r--Chalice/tests/permission-model/predicate_error2.chalice20
-rw-r--r--Chalice/tests/permission-model/predicate_error2.output.txt3
-rw-r--r--Chalice/tests/permission-model/predicate_error3.chalice20
-rw-r--r--Chalice/tests/permission-model/predicate_error3.output.txt3
-rw-r--r--Chalice/tests/permission-model/predicate_error4.chalice20
-rw-r--r--Chalice/tests/permission-model/predicate_error4.output.txt3
-rw-r--r--Chalice/tests/permission-model/predicates.chalice103
-rw-r--r--Chalice/tests/permission-model/predicates.output.txt11
-rw-r--r--Chalice/tests/permission-model/reg_test.bat2
-rw-r--r--Chalice/tests/permission-model/reg_test_all.bat2
-rw-r--r--Chalice/tests/permission-model/scaling.chalice76
-rw-r--r--Chalice/tests/permission-model/scaling.output.txt16
-rw-r--r--Chalice/tests/permission-model/sequences.chalice85
-rw-r--r--Chalice/tests/permission-model/sequences.output.txt6
-rw-r--r--Chalice/tests/permission-model/test.bat2
-rw-r--r--Chalice/tests/predicates/FoldUnfoldExperiments.chalice32
-rw-r--r--Chalice/tests/predicates/FoldUnfoldExperiments.output.txt4
-rw-r--r--Chalice/tests/predicates/LinkedList-various.chalice176
-rw-r--r--Chalice/tests/predicates/LinkedList-various.output.txt4
-rw-r--r--Chalice/tests/predicates/aux-info.chalice33
-rw-r--r--Chalice/tests/predicates/aux-info.output.txt4
-rw-r--r--Chalice/tests/predicates/framing-fields.chalice21
-rw-r--r--Chalice/tests/predicates/framing-fields.output.txt5
-rw-r--r--Chalice/tests/predicates/framing-functions.chalice25
-rw-r--r--Chalice/tests/predicates/framing-functions.output.txt5
-rw-r--r--Chalice/tests/predicates/generate_reference.bat2
-rw-r--r--Chalice/tests/predicates/generate_reference_all.bat2
-rw-r--r--Chalice/tests/predicates/list-reverse-extra-unfold-fold.chalice51
-rw-r--r--Chalice/tests/predicates/list-reverse-extra-unfold-fold.output.txt4
-rw-r--r--Chalice/tests/predicates/mutual-dependence.chalice24
-rw-r--r--Chalice/tests/predicates/mutual-dependence.output.txt5
-rw-r--r--Chalice/tests/predicates/reg_test.bat2
-rw-r--r--Chalice/tests/predicates/reg_test_all.bat2
-rw-r--r--Chalice/tests/predicates/setset.chalice57
-rw-r--r--Chalice/tests/predicates/setset.output.txt8
-rw-r--r--Chalice/tests/predicates/test.bat2
-rw-r--r--Chalice/tests/predicates/test.chalice35
-rw-r--r--Chalice/tests/predicates/test.output.txt4
-rw-r--r--Chalice/tests/predicates/test1.chalice50
-rw-r--r--Chalice/tests/predicates/test1.output.txt4
-rw-r--r--Chalice/tests/predicates/test10.chalice18
-rw-r--r--Chalice/tests/predicates/test10.output.txt4
-rw-r--r--Chalice/tests/predicates/test2.chalice55
-rw-r--r--Chalice/tests/predicates/test2.output.txt4
-rw-r--r--Chalice/tests/predicates/test3.chalice29
-rw-r--r--Chalice/tests/predicates/test3.output.txt4
-rw-r--r--Chalice/tests/predicates/test4.chalice56
-rw-r--r--Chalice/tests/predicates/test4.output.txt5
-rw-r--r--Chalice/tests/predicates/test7.chalice109
-rw-r--r--Chalice/tests/predicates/test7.output.txt16
-rw-r--r--Chalice/tests/predicates/test8.chalice55
-rw-r--r--Chalice/tests/predicates/test8.output.txt4
-rw-r--r--Chalice/tests/predicates/unfolding.chalice32
-rw-r--r--Chalice/tests/predicates/unfolding.output.txt5
-rw-r--r--Chalice/tests/readme.txt45
-rw-r--r--Chalice/tests/refinements/AngelicExec.chalice34
-rw-r--r--Chalice/tests/refinements/Answer50
-rw-r--r--Chalice/tests/refinements/Calculator.chalice69
-rw-r--r--Chalice/tests/refinements/Celebrity.chalice48
-rw-r--r--Chalice/tests/refinements/Counter.chalice112
-rw-r--r--Chalice/tests/refinements/CounterReverse.chalice21
-rw-r--r--Chalice/tests/refinements/DSW.chalice119
-rw-r--r--Chalice/tests/refinements/Duplicates.chalice115
-rw-r--r--Chalice/tests/refinements/DuplicatesLight.chalice42
-rw-r--r--Chalice/tests/refinements/DuplicatesVideo.chalice43
-rw-r--r--Chalice/tests/refinements/List.chalice47
-rw-r--r--Chalice/tests/refinements/LoopFiniteDiff.chalice61
-rw-r--r--Chalice/tests/refinements/LoopSqRoot.chalice43
-rw-r--r--Chalice/tests/refinements/Pick.chalice28
-rw-r--r--Chalice/tests/refinements/RecFiniteDiff.chalice51
-rw-r--r--Chalice/tests/refinements/RecSqRoot.chalice46
-rw-r--r--Chalice/tests/refinements/RefinesLoop.chalice3
-rw-r--r--Chalice/tests/refinements/SpecStmt.chalice35
-rw-r--r--Chalice/tests/refinements/SumCubes.chalice29
-rw-r--r--Chalice/tests/refinements/TestCoupling.chalice74
-rw-r--r--Chalice/tests/refinements/TestRefines.chalice56
-rw-r--r--Chalice/tests/refinements/TestTransform.chalice38
-rw-r--r--Chalice/tests/refinements/experiments/CounterPredicate.chalice136
-rw-r--r--Chalice/tests/refinements/experiments/DSW0.chalice145
-rw-r--r--Chalice/tests/refinements/experiments/DSW1.chalice91
-rw-r--r--Chalice/tests/refinements/experiments/DSW10.chalice120
-rw-r--r--Chalice/tests/refinements/experiments/DSW2.chalice95
-rw-r--r--Chalice/tests/refinements/experiments/DSW3.chalice106
-rw-r--r--Chalice/tests/refinements/experiments/DSW4.chalice117
-rw-r--r--Chalice/tests/refinements/experiments/List.chalice159
-rw-r--r--Chalice/tests/refinements/experiments/ListNode.chalice163
-rw-r--r--Chalice/tests/refinements/experiments/ListPredicate.chalice109
-rw-r--r--Chalice/tests/refinements/experiments/StringBuilder.chalice67
-rw-r--r--Chalice/tests/refinements/test.bat47
-rw-r--r--Chalice/tests/regressions/generate_reference.bat2
-rw-r--r--Chalice/tests/regressions/generate_reference_all.bat2
-rw-r--r--Chalice/tests/regressions/internal-bug-1.chalice16
-rw-r--r--Chalice/tests/regressions/internal-bug-1.output.txt4
-rw-r--r--Chalice/tests/regressions/internal-bug-2.chalice13
-rw-r--r--Chalice/tests/regressions/internal-bug-2.output.txt8
-rw-r--r--Chalice/tests/regressions/internal-bug-3.chalice8
-rw-r--r--Chalice/tests/regressions/internal-bug-3.output.txt4
-rw-r--r--Chalice/tests/regressions/internal-bug-4.chalice17
-rw-r--r--Chalice/tests/regressions/internal-bug-4.output.txt6
-rw-r--r--Chalice/tests/regressions/internal-bug-5.chalice38
-rw-r--r--Chalice/tests/regressions/internal-bug-5.output.txt5
-rw-r--r--Chalice/tests/regressions/internal-bug-6.chalice10
-rw-r--r--Chalice/tests/regressions/internal-bug-6.output.txt4
-rw-r--r--Chalice/tests/regressions/internal-bug-7.chalice26
-rw-r--r--Chalice/tests/regressions/internal-bug-7.output.txt4
-rw-r--r--Chalice/tests/regressions/reg_test.bat2
-rw-r--r--Chalice/tests/regressions/reg_test_all.bat2
-rw-r--r--Chalice/tests/regressions/test.bat2
-rw-r--r--Chalice/tests/regressions/workitem-10147.chalice22
-rw-r--r--Chalice/tests/regressions/workitem-10147.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10189.chalice23
-rw-r--r--Chalice/tests/regressions/workitem-10189.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10190.chalice6
-rw-r--r--Chalice/tests/regressions/workitem-10190.output.txt5
-rw-r--r--Chalice/tests/regressions/workitem-10192.chalice19
-rw-r--r--Chalice/tests/regressions/workitem-10192.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10194.chalice37
-rw-r--r--Chalice/tests/regressions/workitem-10194.output.txt6
-rw-r--r--Chalice/tests/regressions/workitem-10195.chalice38
-rw-r--r--Chalice/tests/regressions/workitem-10195.output.txt12
-rw-r--r--Chalice/tests/regressions/workitem-10196.chalice11
-rw-r--r--Chalice/tests/regressions/workitem-10196.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10197.chalice7
-rw-r--r--Chalice/tests/regressions/workitem-10197.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10198.chalice17
-rw-r--r--Chalice/tests/regressions/workitem-10198.output.txt5
-rw-r--r--Chalice/tests/regressions/workitem-10199.chalice21
-rw-r--r--Chalice/tests/regressions/workitem-10199.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10200.chalice25
-rw-r--r--Chalice/tests/regressions/workitem-10200.output.txt5
-rw-r--r--Chalice/tests/regressions/workitem-10208.chalice41
-rw-r--r--Chalice/tests/regressions/workitem-10208.output.txt8
-rw-r--r--Chalice/tests/regressions/workitem-10221.chalice158
-rw-r--r--Chalice/tests/regressions/workitem-10221.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10222.chalice8
-rw-r--r--Chalice/tests/regressions/workitem-10222.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-10223.chalice8
-rw-r--r--Chalice/tests/regressions/workitem-10223.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-8234.chalice26
-rw-r--r--Chalice/tests/regressions/workitem-8234.output.txt4
-rw-r--r--Chalice/tests/regressions/workitem-8236.chalice16
-rw-r--r--Chalice/tests/regressions/workitem-8236.output.txt5
-rw-r--r--Chalice/tests/regressions/workitem-9978.chalice9
-rw-r--r--Chalice/tests/regressions/workitem-9978.output.txt6
-rw-r--r--Chalice/tests/runalltests.bat37
-rw-r--r--Chalice/tests/test-scripts/diff.bat21
-rw-r--r--Chalice/tests/test-scripts/generate_reference.bat7
-rw-r--r--Chalice/tests/test-scripts/generate_reference_all.bat9
-rw-r--r--Chalice/tests/test-scripts/getboogieoutput.bat33
-rw-r--r--Chalice/tests/test-scripts/readme.txt3
-rw-r--r--Chalice/tests/test-scripts/reg_test.bat75
-rw-r--r--Chalice/tests/test-scripts/reg_test_all.bat24
-rw-r--r--Chalice/tests/test-scripts/test.bat37
-rw-r--r--Jennisys/Jennisys.sln58
-rw-r--r--Jennisys/Jennisys/Analyzer.fs953
-rw-r--r--Jennisys/Jennisys/Ast.fs95
-rw-r--r--Jennisys/Jennisys/AstUtils.fs1033
-rw-r--r--Jennisys/Jennisys/CodeGen.fs429
-rw-r--r--Jennisys/Jennisys/DafnyModelUtils.fs455
-rw-r--r--Jennisys/Jennisys/DafnyPrinter.fs135
-rw-r--r--Jennisys/Jennisys/EnvUtils.fs9
-rw-r--r--Jennisys/Jennisys/FixpointSolver.fs374
-rw-r--r--Jennisys/Jennisys/Getters.fs284
-rw-r--r--Jennisys/Jennisys/Jennisys.fs72
-rw-r--r--Jennisys/Jennisys/Jennisys.fsproj118
-rw-r--r--Jennisys/Jennisys/Lexer.fsl83
-rw-r--r--Jennisys/Jennisys/Logger.fs41
-rw-r--r--Jennisys/Jennisys/MethodUnifier.fs107
-rw-r--r--Jennisys/Jennisys/Modularizer.fs206
-rw-r--r--Jennisys/Jennisys/Options.fs162
-rw-r--r--Jennisys/Jennisys/Parser.fsy214
-rw-r--r--Jennisys/Jennisys/PipelineUtils.fs63
-rw-r--r--Jennisys/Jennisys/PrintUtils.fs12
-rw-r--r--Jennisys/Jennisys/Printer.fs156
-rw-r--r--Jennisys/Jennisys/README.txt28
-rw-r--r--Jennisys/Jennisys/Resolver.fs380
-rw-r--r--Jennisys/Jennisys/SymGen.fs9
-rw-r--r--Jennisys/Jennisys/TypeChecker.fs67
-rw-r--r--Jennisys/Jennisys/Utils.fs368
-rw-r--r--Jennisys/Jennisys/examples/BHeap.jen33
-rw-r--r--Jennisys/Jennisys/examples/DList.jen39
-rw-r--r--Jennisys/Jennisys/examples/List.jen77
-rw-r--r--Jennisys/Jennisys/examples/List2.jen68
-rw-r--r--Jennisys/Jennisys/examples/List3.jen71
-rw-r--r--Jennisys/Jennisys/examples/Number.jen44
-rw-r--r--Jennisys/Jennisys/examples/NumberMethods.jen40
-rw-r--r--Jennisys/Jennisys/examples/Set.jen72
-rw-r--r--Jennisys/Jennisys/examples/Set2.jen60
-rw-r--r--Jennisys/Jennisys/examples/Simple.jen31
-rw-r--r--Jennisys/Jennisys/examples/jennisys-synth_List.dfy147
-rw-r--r--Jennisys/Jennisys/examples/jennisys-synth_List2.dfy207
-rw-r--r--Jennisys/Jennisys/examples/jennisys-synth_List3.dfy255
-rw-r--r--Jennisys/Jennisys/examples/jennisys-synth_Number.dfy202
-rw-r--r--Jennisys/Jennisys/examples/jennisys-synth_Set.dfy344
-rw-r--r--Jennisys/Jennisys/examples/mod/jennisys-synth_List.dfy202
-rw-r--r--Jennisys/Jennisys/examples/mod/jennisys-synth_List2.dfy323
-rw-r--r--Jennisys/Jennisys/examples/mod/jennisys-synth_List3.dfy393
-rw-r--r--Jennisys/Jennisys/examples/mod/jennisys-synth_Number.dfy233
-rw-r--r--Jennisys/Jennisys/examples/mod/jennisys-synth_Set.dfy388
-rw-r--r--Jennisys/Jennisys/examples/mod2/jennisys-synth_DList.dfy255
-rw-r--r--Jennisys/Jennisys/examples/mod2/jennisys-synth_List.dfy249
-rw-r--r--Jennisys/Jennisys/examples/mod2/jennisys-synth_List2.dfy225
-rw-r--r--Jennisys/Jennisys/examples/mod2/jennisys-synth_List3.dfy309
-rw-r--r--Jennisys/Jennisys/examples/mod2/jennisys-synth_Number.dfy181
-rw-r--r--Jennisys/Jennisys/examples/mod2/jennisys-synth_NumberMethods.dfy167
-rw-r--r--Jennisys/Jennisys/examples/mod2/jennisys-synth_Set.dfy304
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/BHeap.jen34
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/BHeap_synth.dfy220
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/DList.jen40
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/DList_synth.dfy154
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/IntSet.jen30
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/IntSet_synth.dfy130
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/List.jen29
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/List_synth.dfy146
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/Math.jen20
-rw-r--r--Jennisys/Jennisys/examples/oopsla12/Math_synth.dfy105
-rw-r--r--Jennisys/Jennisys/examples/set.dfy246
-rw-r--r--Jennisys/Jennisys/scripts/StartDafny-jen.bat2
-rw-r--r--Source/Dafny/Cloner.cs539
-rw-r--r--Source/Dafny/Compiler.cs2432
-rw-r--r--Source/Dafny/Dafny.atg1990
-rw-r--r--Source/Dafny/DafnyAst.cs4472
-rw-r--r--Source/Dafny/DafnyMain.cs88
-rw-r--r--Source/Dafny/DafnyOptions.cs155
-rw-r--r--Source/Dafny/DafnyPipeline.csproj199
-rw-r--r--Source/Dafny/Makefile22
-rw-r--r--Source/Dafny/Parser.cs3470
-rw-r--r--Source/Dafny/Printer.cs1410
-rw-r--r--Source/Dafny/RefinementTransformer.cs1411
-rw-r--r--Source/Dafny/Resolver.cs6706
-rw-r--r--Source/Dafny/Rewriter.cs342
-rw-r--r--Source/Dafny/Scanner.cs823
-rw-r--r--Source/Dafny/SccGraph.cs370
-rw-r--r--Source/Dafny/Translator.cs9249
-rw-r--r--Source/Dafny/Util.cs20
-rw-r--r--Source/Dafny/cce.cs112
-rw-r--r--Source/DafnyDriver/DafnyDriver.cs796
-rw-r--r--Source/DafnyDriver/DafnyDriver.csproj182
-rw-r--r--Source/DafnyDriver/app.config3
-rw-r--r--Test/Makefile4
-rw-r--r--Test/alltests.txt7
-rw-r--r--Util/BoogieBuildAndTest.cmd (renamed from Util/BoogieDafnyBuildandTest.cmd)8
-rw-r--r--Util/Emacs/chalice-mode.el118
-rw-r--r--Util/Emacs/dafny-mode.el116
-rw-r--r--Util/Emacs/jennisys-mode.el113
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService.sln20
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/ChaliceLanguageService.csproj179
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Configuration.cs24
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/GlobalSuppressions.cs11
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Grammar.cs399
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Guids.cs13
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/AuthoringScope.cs66
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Configuration.cs116
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declaration.cs30
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declarations.cs56
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/IASTResolver.cs13
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyLanguageService.cs347
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyViewFilter.cs42
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/LineScanner.cs58
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Method.cs20
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Methods.cs50
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Package.cs130
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Resolver.cs50
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Integration/Source.cs41
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/IronyLanguageServicePackage.cs91
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Key.snkbin596 -> 0 bytes
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Properties/AssemblyInfo.cs36
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Resources.Designer.cs63
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Resources.resx130
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/Resources/Irony.dllbin236032 -> 0 bytes
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/VSPackage.resx129
-rw-r--r--Util/VS2010/Chalice/ChaliceLanguageService/source.extension.vsixmanifest27
-rw-r--r--Util/VS2010/Chalice/StartChalice.bat10
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService.sln20
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Configuration.cs24
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/DafnyLanguageService.csproj179
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/GlobalSuppressions.cs11
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs388
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Guids.cs13
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/AuthoringScope.cs66
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Configuration.cs116
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Declaration.cs30
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Declarations.cs56
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/IASTResolver.cs13
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs373
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyViewFilter.cs42
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/LineScanner.cs58
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Method.cs20
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Methods.cs50
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Package.cs130
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Resolver.cs50
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/Source.cs41
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/IronyLanguageServicePackage.cs90
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Key.snkbin596 -> 0 bytes
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Properties/AssemblyInfo.cs36
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Resources.Designer.cs63
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Resources.resx130
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Resources/Irony.dllbin236032 -> 0 bytes
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/VSPackage.resx129
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/source.extension.vsixmanifest27
-rw-r--r--Util/VS2010/Dafny/StartDafny.bat10
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension.sln20
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/BraceMatching.cs253
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/BufferIdleEventUtil.cs155
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/ClassificationTagger.cs107
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/ContentType.cs18
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/DafnyDriver.cs419
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/DafnyExtension.csproj191
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/ErrorTagger.cs85
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/HoverText.cs126
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/IdentifierTagger.cs344
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/OutliningTagger.cs185
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/ProgressMargin.cs260
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/Properties/AssemblyInfo.cs33
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/ResolverTagger.cs321
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs342
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/WordHighlighter.cs211
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/source.extension.vsixmanifest25
-rw-r--r--Util/latex/chalice.sty63
-rw-r--r--Util/latex/dafny.sty110
-rw-r--r--Util/vim/syntax/chalice.vim44
-rw-r--r--Util/vim/syntax/dafny.vim44
-rw-r--r--_admin/Chalice/aste/summary.log16
574 files changed, 3 insertions, 95743 deletions
diff --git a/.gitignore b/.gitignore
index b0fb03cb..09d82658 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,21 +64,12 @@ Binaries/VCGeneration.dll
Binaries/VCGeneration.pdb
Binaries/CodeContractsExtender.dll
Binaries/CodeContractsExtender.pdb
-Binaries/Dafny.exe*
-Binaries/Dafny.pdb
Binaries/*.vshost.exe*
-Binaries/DafnyPipeline.dll
-Binaries/DafnyPipeline.pdb
Binaries/BVD.exe*
Binaries/BVD.pdb
Binaries/ParserHelper.dll
Binaries/ParserHelper.pdb
Binaries/BytecodeTranslator*
-BCT/Binaries/*
-BCT/*.suo
-BCT/*/obj
-BCT/*/*/bin
-BCT/*/*/obj
Test/*/Output
Test/*/*.sx
Test/VSComp2010/out.cs
diff --git a/.hgignore b/.hgignore
index 46d9d269..fe35b0ed 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,33 +1,18 @@
syntax: regexp
^Source/t$
^Source/_ReSharper\.Boogie$
-^(Source|BCT|Jennisys)/.*\.(user|suo|cache|vs10x)$
-^Source/(Core|Dafny)/(Parser|Scanner).cs.old$
+^Source/.*\.(user|suo|cache|vs10x)$
+^Source/Core/(Parser|Scanner).cs.old$
^Binaries/.*\.(dll|pdb|exe|manifest|config)$
^.*(bin|obj)/([^/]*/)?(Debug|Release|Checked|Debug All|DEBUG ALL)/.*$
-^Binaries/BytecodeTranslator$
-^BCT/Binaries/.*$
-^Chalice/tests/(examples|permission-model|refinements|general-tests|regressions|predicates)/.*\.bpl
Test/.*/Output
Test/([^/]*)/([^/]*)\.sx
-Test/(dafny0|dafny1|dafny2|VSI-Benchmarks|vacid0|VSComp2010|vstte2012)/(out\.cs|.*\.dll|.*\.pdb|.*\.exe|.*\.tmp.*)
Test/desktop/
^.*~$
syntax: glob
-BCT/TestResults/
-BCT/testimpactdata.sdf
backup.diff
-BCT/Samples/CodeCounter/console/ClassDiagram1.cd
-Jennisys/Jennisys/examples/bak
-Chalice/project/boot
-Chalice/project/target
-Chalice/target
-Chalice/bin
-Chalice/scripts/create_release/release
-BCT/InternalBCT.sln
*.pyc
*.dll.mdb
*.exe.mdb
*.pidb
*.userprefs
-Binaries/Dafny.suo
diff --git a/BCT/BCT.sln b/BCT/BCT.sln
deleted file mode 100644
index 91844548..00000000
--- a/BCT/BCT.sln
+++ /dev/null
@@ -1,782 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BytecodeTranslator", "BytecodeTranslator\BytecodeTranslator.csproj", "{9C8E4D74-0251-479D-ADAC-A9A469977301}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RegressionTests", "RegressionTests", "{AA77A7CB-972F-4A5C-A16C-3810B448F6EA}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegressionTestInput", "RegressionTests\RegressionTestInput\RegressionTestInput.csproj", "{3D13D2CC-6387-46FA-BDC2-4BEEFC460118}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TranslationTest", "RegressionTests\TranslationTest\TranslationTest.csproj", "{A112AFBA-D6F6-44A4-A683-C3D458A68D84}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{45E691A6-BFA4-4545-93AC-EA7290A6B565}"
- ProjectSection(SolutionItems) = preProject
- BCT.vsmdi = BCT.vsmdi
- Local.testsettings = Local.testsettings
- TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TranslationPlugins", "TranslationPlugins\TranslationPlugins.csproj", "{8C242D42-9714-440F-884D-F64F09E78C7B}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeModel", "..\..\CCICodePlex\Ast\Sources\CodeModel\CodeModel.csproj", "{035FEA7F-0D36-4AE4-B694-EC45191B9AF2}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeModelToIL", "..\..\CCICodePlex\Ast\Sources\CodeModelToIL\CodeModelToIL.csproj", "{CEB76EA1-A168-49B0-A410-2C4195FEE86F}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContractExtractor", "..\..\CCICodePlex\Ast\Sources\ContractExtractor\ContractExtractor.csproj", "{0703D916-A881-45E6-A5CD-6BC50E2E30E2}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlAndDataFlowGraph", "..\..\CCICodePlex\Ast\Metadata\Sources\ControlAndDataFlowGraph\ControlAndDataFlowGraph.csproj", "{2596EFB0-87AE-42CE-89EB-84F35D6350D2}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILGarbageCollect", "..\..\CCICodePlex\Ast\Metadata\Samples\ILGarbageCollect\ILGarbageCollect.csproj", "{60CD0C85-1E4A-4068-A4EC-D15B7981A908}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILGenerator", "..\..\CCICodePlex\Ast\Metadata\Sources\ILGenerator\ILGenerator.csproj", "{08156C78-403A-4112-AD81-8646AC51CD2F}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetadataHelper", "..\..\CCICodePlex\Ast\Metadata\Sources\MetadataHelper\MetadataHelper.csproj", "{4A34A3C5-6176-49D7-A4C5-B2B671247F8F}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetadataModel", "..\..\CCICodePlex\Ast\Metadata\Sources\MetadataModel\MetadataModel.csproj", "{33CAB640-0D03-43DF-81BD-22CDC6C0A597}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MutableCodeModel", "..\..\CCICodePlex\Ast\Sources\MutableCodeModel\MutableCodeModel.csproj", "{319E150C-8F33-49E7-81CA-30F02F9BA90A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MutableMetadataModel", "..\..\CCICodePlex\Ast\Metadata\Sources\MutableMetadataModel\MutableMetadataModel.csproj", "{319E151C-8F33-49E7-81C9-30F02F9BA90A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewILToCodeModel", "..\..\CCICodePlex\Ast\Sources\NewILToCodeModel\NewILToCodeModel.csproj", "{A555D4CB-F16F-4049-A8CF-180B8A05C755}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdbReader", "..\..\CCICodePlex\Ast\Metadata\Sources\PdbReader\PdbReader.csproj", "{A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdbWriter", "..\..\CCICodePlex\Ast\Metadata\Sources\PdbWriter\PdbWriter.csproj", "{6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeReader", "..\..\CCICodePlex\Ast\Metadata\Sources\PeReader\PeReader.csproj", "{34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeWriter", "..\..\CCICodePlex\Ast\Metadata\Sources\PeWriter\PeWriter.csproj", "{304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceModel", "..\..\CCICodePlex\Ast\Metadata\Sources\SourceModel\SourceModel.csproj", "{4B0054FD-124A-4037-9965-BDB55E6BF389}"
-EndProject
-Global
- GlobalSection(TeamFoundationVersionControl) = preSolution
- SccNumberOfProjects = 18
- SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccTeamFoundationServer = http://vstfcodebox:8080/tfs/psi
- SccProjectUniqueName0 = ..\\..\\CCICodeBox\\CoreObjectModel\\CodeModel\\CodeModel.csproj
- SccProjectName0 = $/cci/CoreObjectModel/CodeModel
- SccAuxPath0 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath0 = ..\\..\\CCICodeBox\\CoreObjectModel\\CodeModel
- SccProvider0 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName1 = ..\\..\\CCICodeBox\\Converters\\ContractExtractor\\ContractExtractor.csproj
- SccProjectName1 = $/cci/Converters/ContractExtractor
- SccAuxPath1 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath1 = ..\\..\\CCICodeBox\\Converters\\ContractExtractor
- SccProvider1 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName2 = ..\\..\\CCICodeBox\\Converters\\ILToCodeModel\\ILToCodeModel.csproj
- SccProjectName2 = $/cci/Converters/ILToCodeModel
- SccAuxPath2 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath2 = ..\\..\\CCICodeBox\\Converters\\ILToCodeModel
- SccProvider2 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName3 = ..\\..\\CCICodeBox\\CoreObjectModel\\MetadataHelper\\MetadataHelper.csproj
- SccProjectName3 = $/cci/CoreObjectModel/MetadataHelper
- SccAuxPath3 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath3 = ..\\..\\CCICodeBox\\CoreObjectModel\\MetadataHelper
- SccProvider3 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName4 = ..\\..\\CCICodeBox\\CoreObjectModel\\MetadataModel\\MetadataModel.csproj
- SccProjectName4 = $/cci/CoreObjectModel/MetadataModel
- SccAuxPath4 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath4 = ..\\..\\CCICodeBox\\CoreObjectModel\\MetadataModel
- SccProvider4 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName5 = ..\\..\\CCICodeBox\\CoreObjectModel\\MutableCodeModel\\MutableCodeModel.csproj
- SccProjectName5 = $/cci/CoreObjectModel/MutableCodeModel
- SccAuxPath5 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath5 = ..\\..\\CCICodeBox\\CoreObjectModel\\MutableCodeModel
- SccProvider5 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName6 = ..\\..\\CCICodeBox\\CoreObjectModel\\MutableMetadataModel\\MutableMetadataModel.csproj
- SccProjectName6 = $/cci/CoreObjectModel/MutableMetadataModel
- SccAuxPath6 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath6 = ..\\..\\CCICodeBox\\CoreObjectModel\\MutableMetadataModel
- SccProvider6 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName7 = ..\\..\\CCICodeBox\\PDBReaderAndWriter\\PdbReader\\PdbReader.csproj
- SccProjectName7 = $/cci/PDBReaderAndWriter/PdbReader
- SccAuxPath7 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath7 = ..\\..\\CCICodeBox\\PDBReaderAndWriter\\PdbReader
- SccProvider7 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName8 = ..\\..\\CCICodeBox\\PEReaderAndWriter\\PEReader\\PeReader.csproj
- SccProjectName8 = $/cci/PEReaderAndWriter/PEReader
- SccAuxPath8 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath8 = ..\\..\\CCICodeBox\\PEReaderAndWriter\\PEReader
- SccProvider8 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName9 = ..\\..\\CCICodeBox\\CoreObjectModel\\SourceModel\\SourceModel.csproj
- SccProjectName9 = $/cci/CoreObjectModel/SourceModel
- SccAuxPath9 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath9 = ..\\..\\CCICodeBox\\CoreObjectModel\\SourceModel
- SccProvider9 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName10 = ..\\..\\CCICodeBox\\Converters\\ILGenerator\\ILGenerator.csproj
- SccProjectName10 = $/cci/Converters/ILGenerator
- SccAuxPath10 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath10 = ..\\..\\CCICodeBox\\Converters\\ILGenerator
- SccProvider10 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName11 = ..\\..\\CCICodeBox\\PEReaderAndWriter\\PEWriter\\PeWriter.csproj
- SccProjectName11 = $/cci/PEReaderAndWriter/PEWriter
- SccAuxPath11 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath11 = ..\\..\\CCICodeBox\\PEReaderAndWriter\\PEWriter
- SccProvider11 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName12 = ..\\..\\CCICodeBox\\Converters\\CodeModelToIL\\CodeModelToIL.csproj
- SccProjectName12 = $/cci/Converters/CodeModelToIL
- SccAuxPath12 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath12 = ..\\..\\CCICodeBox\\Converters\\CodeModelToIL
- SccProvider12 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName13 = ..\\..\\CCICodeBox\\PDBReaderAndWriter\\PdbWriter\\PdbWriter.csproj
- SccProjectName13 = $/cci/PDBReaderAndWriter/PdbWriter
- SccAuxPath13 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath13 = ..\\..\\CCICodeBox\\PDBReaderAndWriter\\PdbWriter
- SccProvider13 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName14 = ..\\..\\CCICodeBox\\Microsoft.Contracts\\Microsoft.Contracts.csproj
- SccProjectName14 = $/cci/Microsoft.Contracts
- SccAuxPath14 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath14 = ..\\..\\CCICodeBox\\Microsoft.Contracts
- SccProvider14 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName15 = ..\\..\\CCICodeBox\\Samples\\ILGarbageCollect\\ILGarbageCollect.csproj
- SccProjectName15 = $/cci/Samples/ILGarbageCollect
- SccAuxPath15 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath15 = ..\\..\\CCICodeBox\\Samples\\ILGarbageCollect
- SccProvider15 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName16 = ..\\..\\ccicodebox\\CodeGenerators\\ControlAndDataFlowGraph\\ControlAndDataFlowGraph.csproj
- SccProjectName16 = $/cci/CodeGenerators/ControlAndDataFlowGraph
- SccAuxPath16 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath16 = ..\\..\\ccicodebox\\CodeGenerators\\ControlAndDataFlowGraph
- SccProvider16 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccProjectUniqueName17 = ..\\..\\ccicodebox\\Converters\\NewILToCodeModel\\NewILToCodeModel.csproj
- SccProjectName17 = $/cci/Converters/NewILToCodeModel
- SccAuxPath17 = http://vstfcodebox:8080/tfs/psi
- SccLocalPath17 = ..\\..\\ccicodebox\\Converters\\NewILToCodeModel
- SccProvider17 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- EndGlobalSection
- GlobalSection(TestCaseManagementSettings) = postSolution
- CategoryFile = BCT.vsmdi
- EndGlobalSection
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- CompilerOnly|Any CPU = CompilerOnly|Any CPU
- CompilerOnly|Mixed Platforms = CompilerOnly|Mixed Platforms
- CompilerOnly|x86 = CompilerOnly|x86
- Debug|Any CPU = Debug|Any CPU
- Debug|Mixed Platforms = Debug|Mixed Platforms
- Debug|x86 = Debug|x86
- FastpathSim|Any CPU = FastpathSim|Any CPU
- FastpathSim|Mixed Platforms = FastpathSim|Mixed Platforms
- FastpathSim|x86 = FastpathSim|x86
- NightlyDebug|Any CPU = NightlyDebug|Any CPU
- NightlyDebug|Mixed Platforms = NightlyDebug|Mixed Platforms
- NightlyDebug|x86 = NightlyDebug|x86
- NightlyRelease|Any CPU = NightlyRelease|Any CPU
- NightlyRelease|Mixed Platforms = NightlyRelease|Mixed Platforms
- NightlyRelease|x86 = NightlyRelease|x86
- Release|Any CPU = Release|Any CPU
- Release|Mixed Platforms = Release|Mixed Platforms
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Debug|x86.ActiveCfg = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Release|Any CPU.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {9C8E4D74-0251-479D-ADAC-A9A469977301}.Release|x86.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Debug|x86.ActiveCfg = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Release|Any CPU.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118}.Release|x86.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Debug|x86.ActiveCfg = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Release|Any CPU.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84}.Release|x86.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Debug|x86.ActiveCfg = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Release|Any CPU.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {8C242D42-9714-440F-884D-F64F09E78C7B}.Release|x86.ActiveCfg = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Debug|x86.ActiveCfg = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Release|Any CPU.Build.0 = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {035FEA7F-0D36-4AE4-B694-EC45191B9AF2}.Release|x86.ActiveCfg = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Debug|x86.ActiveCfg = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Release|Any CPU.Build.0 = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {CEB76EA1-A168-49B0-A410-2C4195FEE86F}.Release|x86.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Debug|x86.ActiveCfg = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Release|Any CPU.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {0703D916-A881-45E6-A5CD-6BC50E2E30E2}.Release|x86.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Debug|x86.ActiveCfg = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Release|Any CPU.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {2596EFB0-87AE-42CE-89EB-84F35D6350D2}.Release|x86.ActiveCfg = Release|Any CPU
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.CompilerOnly|Any CPU.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.CompilerOnly|Mixed Platforms.Build.0 = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.CompilerOnly|x86.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.CompilerOnly|x86.Build.0 = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Debug|Any CPU.ActiveCfg = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Debug|Mixed Platforms.Build.0 = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Debug|x86.ActiveCfg = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Debug|x86.Build.0 = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.FastpathSim|Any CPU.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.FastpathSim|Mixed Platforms.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.FastpathSim|Mixed Platforms.Build.0 = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.FastpathSim|x86.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.FastpathSim|x86.Build.0 = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyDebug|Any CPU.ActiveCfg = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyDebug|Mixed Platforms.Build.0 = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyDebug|x86.ActiveCfg = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyDebug|x86.Build.0 = Debug|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyRelease|Any CPU.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyRelease|Mixed Platforms.Build.0 = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyRelease|x86.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.NightlyRelease|x86.Build.0 = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Release|Any CPU.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Release|Mixed Platforms.Build.0 = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Release|x86.ActiveCfg = Release|x86
- {60CD0C85-1E4A-4068-A4EC-D15B7981A908}.Release|x86.Build.0 = Release|x86
- {08156C78-403A-4112-AD81-8646AC51CD2F}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Debug|x86.ActiveCfg = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Release|Any CPU.Build.0 = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {08156C78-403A-4112-AD81-8646AC51CD2F}.Release|x86.ActiveCfg = Release|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Debug|x86.ActiveCfg = Debug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyDebug|Any CPU.ActiveCfg = NightlyDebug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyDebug|Any CPU.Build.0 = NightlyDebug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyDebug|Mixed Platforms.ActiveCfg = NightlyDebug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyDebug|Mixed Platforms.Build.0 = NightlyDebug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyDebug|x86.ActiveCfg = NightlyDebug|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyRelease|Any CPU.ActiveCfg = NightlyRelease|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyRelease|Any CPU.Build.0 = NightlyRelease|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyRelease|Mixed Platforms.ActiveCfg = NightlyRelease|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyRelease|Mixed Platforms.Build.0 = NightlyRelease|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.NightlyRelease|x86.ActiveCfg = NightlyRelease|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Release|Any CPU.Build.0 = Release|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {4A34A3C5-6176-49D7-A4C5-B2B671247F8F}.Release|x86.ActiveCfg = Release|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Debug|x86.ActiveCfg = Debug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyDebug|Any CPU.ActiveCfg = NightlyDebug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyDebug|Any CPU.Build.0 = NightlyDebug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyDebug|Mixed Platforms.ActiveCfg = NightlyDebug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyDebug|Mixed Platforms.Build.0 = NightlyDebug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyDebug|x86.ActiveCfg = NightlyDebug|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyRelease|Any CPU.ActiveCfg = NightlyRelease|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyRelease|Any CPU.Build.0 = NightlyRelease|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyRelease|Mixed Platforms.ActiveCfg = NightlyRelease|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyRelease|Mixed Platforms.Build.0 = NightlyRelease|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.NightlyRelease|x86.ActiveCfg = NightlyRelease|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Release|Any CPU.Build.0 = Release|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {33CAB640-0D03-43DF-81BD-22CDC6C0A597}.Release|x86.ActiveCfg = Release|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Debug|x86.ActiveCfg = Debug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyDebug|Any CPU.ActiveCfg = NightlyDebug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyDebug|Any CPU.Build.0 = NightlyDebug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyDebug|Mixed Platforms.ActiveCfg = NightlyDebug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyDebug|Mixed Platforms.Build.0 = NightlyDebug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyDebug|x86.ActiveCfg = NightlyDebug|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyRelease|Any CPU.ActiveCfg = NightlyRelease|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyRelease|Any CPU.Build.0 = NightlyRelease|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyRelease|Mixed Platforms.ActiveCfg = NightlyRelease|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyRelease|Mixed Platforms.Build.0 = NightlyRelease|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.NightlyRelease|x86.ActiveCfg = NightlyRelease|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Release|Any CPU.Build.0 = Release|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {319E150C-8F33-49E7-81CA-30F02F9BA90A}.Release|x86.ActiveCfg = Release|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Debug|x86.ActiveCfg = Debug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyDebug|Any CPU.ActiveCfg = NightlyDebug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyDebug|Any CPU.Build.0 = NightlyDebug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyDebug|Mixed Platforms.ActiveCfg = NightlyDebug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyDebug|Mixed Platforms.Build.0 = NightlyDebug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyDebug|x86.ActiveCfg = NightlyDebug|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyRelease|Any CPU.ActiveCfg = NightlyRelease|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyRelease|Any CPU.Build.0 = NightlyRelease|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyRelease|Mixed Platforms.ActiveCfg = NightlyRelease|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyRelease|Mixed Platforms.Build.0 = NightlyRelease|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.NightlyRelease|x86.ActiveCfg = NightlyRelease|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Release|Any CPU.Build.0 = Release|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {319E151C-8F33-49E7-81C9-30F02F9BA90A}.Release|x86.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Debug|x86.ActiveCfg = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Release|Any CPU.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {A555D4CB-F16F-4049-A8CF-180B8A05C755}.Release|x86.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Debug|x86.ActiveCfg = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Release|Any CPU.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}.Release|x86.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Debug|x86.ActiveCfg = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Release|Any CPU.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}.Release|x86.ActiveCfg = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Debug|x86.ActiveCfg = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Release|Any CPU.Build.0 = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}.Release|x86.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.CompilerOnly|Any CPU.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.CompilerOnly|Any CPU.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.CompilerOnly|Mixed Platforms.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.CompilerOnly|Mixed Platforms.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.CompilerOnly|x86.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Debug|x86.ActiveCfg = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.FastpathSim|Any CPU.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.FastpathSim|Any CPU.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.FastpathSim|Mixed Platforms.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.FastpathSim|Mixed Platforms.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.FastpathSim|x86.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Release|Any CPU.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}.Release|x86.ActiveCfg = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.CompilerOnly|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.CompilerOnly|Any CPU.Build.0 = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.CompilerOnly|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.CompilerOnly|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.CompilerOnly|x86.ActiveCfg = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Debug|x86.ActiveCfg = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.FastpathSim|Any CPU.ActiveCfg = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.FastpathSim|Any CPU.Build.0 = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.FastpathSim|Mixed Platforms.ActiveCfg = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.FastpathSim|Mixed Platforms.Build.0 = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.FastpathSim|x86.ActiveCfg = CompilerOnly|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyDebug|Any CPU.Build.0 = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyDebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyDebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyDebug|x86.ActiveCfg = Debug|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyRelease|Any CPU.ActiveCfg = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyRelease|Any CPU.Build.0 = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyRelease|Mixed Platforms.Build.0 = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.NightlyRelease|x86.ActiveCfg = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Release|Any CPU.Build.0 = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {4B0054FD-124A-4037-9965-BDB55E6BF389}.Release|x86.ActiveCfg = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {3D13D2CC-6387-46FA-BDC2-4BEEFC460118} = {AA77A7CB-972F-4A5C-A16C-3810B448F6EA}
- {A112AFBA-D6F6-44A4-A683-C3D458A68D84} = {AA77A7CB-972F-4A5C-A16C-3810B448F6EA}
- {45E691A6-BFA4-4545-93AC-EA7290A6B565} = {AA77A7CB-972F-4A5C-A16C-3810B448F6EA}
- EndGlobalSection
-EndGlobal
diff --git a/BCT/BCT.vsmdi b/BCT/BCT.vsmdi
deleted file mode 100644
index 08dd31d7..00000000
--- a/BCT/BCT.vsmdi
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
- <TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
- <RunConfiguration id="f898dc7f-7e79-4656-a1cd-5ca50fff2b5d" name="Local" storage="local.testsettings" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- </TestList>
-</TestLists> \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/BytecodeTranslator.csproj b/BCT/BytecodeTranslator/BytecodeTranslator.csproj
deleted file mode 100644
index 26dfc103..00000000
--- a/BCT/BytecodeTranslator/BytecodeTranslator.csproj
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{9C8E4D74-0251-479D-ADAC-A9A469977301}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>BytecodeTranslator</RootNamespace>
- <AssemblyName>BytecodeTranslator</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>3.5</OldToolsVersion>
- <UpgradeBackupLocation />
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- <TargetFrameworkProfile />
- <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>..\Binaries\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
- <CodeContractsCustomRewriterAssembly>
- </CodeContractsCustomRewriterAssembly>
- <CodeContractsCustomRewriterClass>
- </CodeContractsCustomRewriterClass>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsBuildReferenceAssembly>False</CodeContractsBuildReferenceAssembly>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsLibPaths>
- </CodeContractsLibPaths>
- <CodeContractsPlatformPath>
- </CodeContractsPlatformPath>
- <CodeContractsExtraAnalysisOptions>
- </CodeContractsExtraAnalysisOptions>
- <CodeContractsBaseLineFile>
- </CodeContractsBaseLineFile>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsExtraRewriteOptions />
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>..\Binaries\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="AbsInt, Version=1.0.21126.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\Binaries\AbsInt.dll</HintPath>
- </Reference>
- <Reference Include="AIFramework, Version=1.0.21126.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\Binaries\AIFramework.dll</HintPath>
- </Reference>
- <Reference Include="Basetypes, Version=1.0.21126.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\Binaries\Basetypes.dll</HintPath>
- </Reference>
- <Reference Include="Core, Version=1.0.21126.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\Binaries\Core.dll</HintPath>
- </Reference>
- <Reference Include="ParserHelper">
- <HintPath>..\..\Binaries\ParserHelper.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Xml.Linq">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data.DataSetExtensions">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="ExceptionAnalysis.cs" />
- <Compile Include="TranslationPlugins\PhoneTranslator\PhoneFeedbackPlugin.cs" />
- <Compile Include="TranslationPlugins\Translators\BaseTranslator.cs" />
- <Compile Include="CLRSemantics.cs" />
- <Compile Include="Heap.cs" />
- <Compile Include="HeapFactory.cs" />
- <Compile Include="MetadataTraverser.cs" />
- <Compile Include="Phone\PhoneBackKeyCallbackTraverser.cs" />
- <Compile Include="Phone\PhoneCodeHelper.cs" />
- <Compile Include="Phone\PhoneControlFeedbackTraverser.cs" />
- <Compile Include="Phone\PhoneInitializationTraverser.cs" />
- <Compile Include="Phone\PhoneMethodInliningTraverser.cs" />
- <Compile Include="Phone\PhoneNavigationTraverser.cs" />
- <Compile Include="Prelude.cs" />
- <Compile Include="ExpressionTraverser.cs" />
- <Compile Include="Sink.cs" />
- <Compile Include="StatementTraverser.cs" />
- <Compile Include="Program.cs" />
- <Compile Include="TranslationException.cs" />
- <Compile Include="TranslationHelper.cs" />
- <Compile Include="TranslationPlugins\BytecodeTranslator\BytecodeTranslatorPlugin.cs" />
- <Compile Include="TranslationPlugins\ContractAwareTranslator.cs" />
- <Compile Include="TranslationPlugins\ITranslationPlugin.cs" />
- <Compile Include="TranslationPlugins\PhoneTranslator\PhoneInitializationPlugin.cs" />
- <Compile Include="TranslationPlugins\Translator.cs" />
- <Compile Include="TranslationPlugins\Translators\PhoneFeedbackTranslator.cs" />
- <Compile Include="TranslationPlugins\Translators\PhoneInitializationTranslator.cs" />
- <Compile Include="TraverserFactory.cs" />
- <Compile Include="WholeProgram.cs" />
- </ItemGroup>
- <ItemGroup>
- <Content Include="Readme.txt" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Metadata\Samples\ILGarbageCollect\ILGarbageCollect.csproj">
- <Project>{60CD0C85-1E4A-4068-A4EC-D15B7981A908}</Project>
- <Name>ILGarbageCollect</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Metadata\Sources\MetadataHelper\MetadataHelper.csproj">
- <Project>{4A34A3C5-6176-49D7-A4C5-B2B671247F8F}</Project>
- <Name>MetadataHelper</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Metadata\Sources\MetadataModel\MetadataModel.csproj">
- <Project>{33CAB640-0D03-43DF-81BD-22CDC6C0A597}</Project>
- <Name>MetadataModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Metadata\Sources\MutableMetadataModel\MutableMetadataModel.csproj">
- <Project>{319E151C-8F33-49E7-81C9-30F02F9BA90A}</Project>
- <Name>MutableMetadataModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Metadata\Sources\PdbReader\PdbReader.csproj">
- <Project>{A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}</Project>
- <Name>PdbReader</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Metadata\Sources\PeReader\PeReader.csproj">
- <Project>{34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}</Project>
- <Name>PeReader</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Metadata\Sources\SourceModel\SourceModel.csproj">
- <Project>{4B0054FD-124A-4037-9965-BDB55E6BF389}</Project>
- <Name>SourceModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Sources\CodeModel\CodeModel.csproj">
- <Project>{035FEA7F-0D36-4AE4-B694-EC45191B9AF2}</Project>
- <Name>CodeModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Sources\ContractExtractor\ContractExtractor.csproj">
- <Project>{0703D916-A881-45E6-A5CD-6BC50E2E30E2}</Project>
- <Name>ContractExtractor</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Sources\MutableCodeModel\MutableCodeModel.csproj">
- <Project>{319E150C-8F33-49E7-81CA-30F02F9BA90A}</Project>
- <Name>MutableCodeModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\CCICodePlex\Ast\Sources\NewILToCodeModel\NewILToCodeModel.csproj">
- <Project>{A555D4CB-F16F-4049-A8CF-180B8A05C755}</Project>
- <Name>NewILToCodeModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\TranslationPlugins\TranslationPlugins.csproj">
- <Project>{8C242D42-9714-440F-884D-F64F09E78C7B}</Project>
- <Name>TranslationPlugins</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <Folder Include="Properties\" />
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- </ItemGroup>
- <ItemGroup>
- <WCFMetadata Include="Service References\" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/CLRSemantics.cs b/BCT/BytecodeTranslator/CLRSemantics.cs
deleted file mode 100644
index 8b7cda22..00000000
--- a/BCT/BytecodeTranslator/CLRSemantics.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using BytecodeTranslator.TranslationPlugins;
-
-namespace BytecodeTranslator {
-
- public class CLRSemantics : TraverserFactory {
-
- public override Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
- Translator translator = new BaseTranslator(this, sink, contractProviders, pdbReaders);
- return translator;
- }
-
- public override ExpressionTraverser MakeExpressionTraverser(Sink sink, StatementTraverser/*?*/ statementTraverser, bool contractContext, bool expressionIsStatement) {
- return new CLRExpressionSemantics(sink, statementTraverser, contractContext, expressionIsStatement);
- }
-
-
- public class CLRExpressionSemantics : ExpressionTraverser {
-
- public CLRExpressionSemantics(Sink sink, StatementTraverser/*?*/ statementTraverser, bool contractContext, bool expressionIsStatement)
- : base(sink, statementTraverser, contractContext, expressionIsStatement) { }
-
- }
- }
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/ExceptionAnalysis.cs b/BCT/BytecodeTranslator/ExceptionAnalysis.cs
deleted file mode 100644
index f1f44fe7..00000000
--- a/BCT/BytecodeTranslator/ExceptionAnalysis.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics.Contracts;
-using TranslationPlugins;
-using BytecodeTranslator.Phone;
-
-
-namespace BytecodeTranslator {
-
- internal class ExceptionAnalyzer : CodeTraverser {
-
- private Dictionary<IMethodDefinition, HashSet<ITypeReference>> exceptionsExplicitlyThrownByMethod;
- private bool resultsChanged;
-
- private ExceptionAnalyzer() {
- this.exceptionsExplicitlyThrownByMethod = new Dictionary<IMethodDefinition, HashSet<ITypeReference>>();
- }
-
- public static Predicate<IMethodDefinition> ComputeExplicitlyThrownExceptions(IEnumerable<IUnit> units) {
- var me = new ExceptionAnalyzer();
- do {
- me.resultsChanged = false;
- foreach (var u in units)
- me.Traverse(u.UnitNamespaceRoot);
- } while (me.resultsChanged);
- return m => m != null && me.exceptionsExplicitlyThrownByMethod.ContainsKey(m);
- }
-
- public override void TraverseChildren(IMethodDefinition method) {
- var newExceptions = MethodExceptionAnalyzer.ExplicitlyThrownExceptions(this, method);
- HashSet<ITypeReference> alreadyKnownExceptions = null;
- if (this.exceptionsExplicitlyThrownByMethod.TryGetValue(method, out alreadyKnownExceptions)) {
- if (!newExceptions.SetEquals(alreadyKnownExceptions)) {
- this.resultsChanged = true;
- this.exceptionsExplicitlyThrownByMethod[method] = newExceptions;
- }
- } else {
- if (0 < newExceptions.Count) {
- this.resultsChanged = true;
- this.exceptionsExplicitlyThrownByMethod[method] = newExceptions;
- }
- }
-
- }
-
- private class MethodExceptionAnalyzer : CodeTraverser {
-
- private ExceptionAnalyzer parent;
- private HashSet<ITypeReference> exceptionsThrown;
-
- /// <summary>
- /// Used to track the type thrown by rethrow statements.
- /// </summary>
- private ITypeReference/*?*/ currentCatchClauseExceptionType;
-
- private MethodExceptionAnalyzer(ExceptionAnalyzer parent) {
- this.parent = parent;
- this.exceptionsThrown = new HashSet<ITypeReference>();
- }
-
- public static HashSet<ITypeReference> ExplicitlyThrownExceptions(ExceptionAnalyzer parent, IMethodDefinition methodDefinition) {
- var me = new MethodExceptionAnalyzer(parent);
- me.Traverse(methodDefinition);
- return me.exceptionsThrown;
- }
-
- public override void TraverseChildren(ICatchClause catchClause) {
- this.exceptionsThrown.RemoveWhere(t => TypeHelper.Type1DerivesFromOrIsTheSameAsType2(t.ResolvedType, catchClause.ExceptionType, true));
-
- // no need to save the current value: catch clauses cannot be nested.
- this.currentCatchClauseExceptionType = catchClause.ExceptionType;
- base.TraverseChildren(catchClause);
- this.currentCatchClauseExceptionType = null;
- }
-
- public override void TraverseChildren(IMethodCall methodCall) {
- var calledMethod = MemberHelper.UninstantiateAndUnspecialize(methodCall.MethodToCall.ResolvedMethod).ResolvedMethod;
- HashSet<ITypeReference> calledMethodExceptionSet;
- if (this.parent.exceptionsExplicitlyThrownByMethod.TryGetValue(calledMethod, out calledMethodExceptionSet))
- this.exceptionsThrown.UnionWith(calledMethodExceptionSet);
- base.TraverseChildren(methodCall);
- }
-
- public override void TraverseChildren(IRethrowStatement rethrowStatement) {
- this.exceptionsThrown.Add(this.currentCatchClauseExceptionType);
- }
-
- public override void TraverseChildren(IThrowStatement throwStatement) {
- this.exceptionsThrown.Add(throwStatement.Exception.Type);
- }
-
- public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFilterFinallyStatement) {
- var savedExceptions = this.exceptionsThrown;
- this.exceptionsThrown = new HashSet<ITypeReference>();
-
- base.TraverseChildren(tryCatchFilterFinallyStatement);
-
- savedExceptions.UnionWith(this.exceptionsThrown);
- this.exceptionsThrown = savedExceptions;
- }
- }
-
- }
-
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/ExpressionTraverser.cs b/BCT/BytecodeTranslator/ExpressionTraverser.cs
deleted file mode 100644
index 6a830cab..00000000
--- a/BCT/BytecodeTranslator/ExpressionTraverser.cs
+++ /dev/null
@@ -1,2608 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics.Contracts;
-using TranslationPlugins;
-using BytecodeTranslator.Phone;
-
-
-namespace BytecodeTranslator
-{
- public class ExpressionTraverser : CodeTraverser
- {
- public readonly Stack<Bpl.Expr> TranslatedExpressions;
-
- protected readonly Sink sink;
-
- protected readonly StatementTraverser StmtTraverser;
-
- private bool contractContext;
-
- private Bpl.Expr FindOrCreateTypeReferenceInCodeContext(ITypeReference typeReference) {
- return this.sink.FindOrCreateTypeReference(typeReference, true);
-
- IGenericTypeParameter gtp = typeReference as IGenericTypeParameter;
- if (gtp != null) {
- var selectorName = gtp.Name.Value;
- selectorName = TranslationHelper.TurnStringIntoValidIdentifier(selectorName);
- var typeName = TypeHelper.GetTypeName(gtp.DefiningType, NameFormattingOptions.DocumentationId);
- typeName = TranslationHelper.TurnStringIntoValidIdentifier(typeName);
- var funcName = String.Format("{0}#{1}", selectorName, typeName);
- Bpl.IToken tok = Bpl.Token.NoToken;
- var identExpr = Bpl.Expr.Ident(new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, funcName, this.sink.Heap.TypeType)));
- var funcCall = new Bpl.FunctionCall(identExpr);
- var thisArg = new Bpl.IdentifierExpr(tok, this.sink.ThisVariable);
- var dynType = this.sink.Heap.DynamicType(thisArg);
- var nary = new Bpl.NAryExpr(Bpl.Token.NoToken, funcCall, new Bpl.ExprSeq(dynType));
- return nary;
- }
- return this.sink.FindOrCreateTypeReference(typeReference);
- }
-
- private static IMethodDefinition ResolveUnspecializedMethodOrThrow(IMethodReference methodReference) {
- var resolvedMethod = Sink.Unspecialize(methodReference).ResolvedMethod;
- if (resolvedMethod == Dummy.Method) { // avoid downstream errors, fail early
- throw new TranslationException(ExceptionType.UnresolvedMethod, MemberHelper.GetMethodSignature(methodReference, NameFormattingOptions.None));
- }
- return resolvedMethod;
- }
-
- /// <summary>
- /// True when the binary expression currently being processed is the top level expression of an ExpressionStatement and it has
- /// a target expression as its left operand (i.e. it is an assignment statement of the form tgt op= src).
- /// Be sure to clear this flag before any sub expresions are processed.
- /// </summary>
- bool currentExpressionIsOpAssignStatement;
-
-
- #region Constructors
-
- ///// <summary>
- ///// Use this constructor for translating expressions that do *not* occur
- ///// within the context of the statements in a method body.
- ///// </summary>
- //public ExpressionTraverser(Sink sink)
- // : this(sink, null)
- //{ }
-
- /// <summary>
- /// Use this constructor for translating expressions that do occur within
- /// the context of the statements in a method body.
- /// </summary>
- public ExpressionTraverser(Sink sink, StatementTraverser/*?*/ statementTraverser, bool contractContext, bool expressionIsStatement)
- {
- this.sink = sink;
- this.StmtTraverser = statementTraverser;
- TranslatedExpressions = new Stack<Bpl.Expr>();
-
- this.contractContext = contractContext;
- this.currentExpressionIsOpAssignStatement = expressionIsStatement;
- }
-
- #endregion
-
- #region Translate Variable Access
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="addressableExpression"></param>
- /// <remarks>still a stub</remarks>
- public override void TraverseChildren(IAddressableExpression addressableExpression)
- {
- Contract.Assume(false, "The expression containing this as a subexpression should never allow a call to this routine.");
- }
-
- private void LoadAddressOf(object container, IExpression/*?*/ instance) {
-
- ILocalDefinition/*?*/ local = container as ILocalDefinition;
- if (local != null)
- {
- TranslatedExpressions.Push(Bpl.Expr.Ident(this.sink.FindOrCreateLocalVariable(local)));
- return;
- }
- IParameterDefinition/*?*/ param = container as IParameterDefinition;
- if (param != null)
- {
- this.LoadParameter(param);
- return;
- }
- IFieldReference/*?*/ field = container as IFieldReference;
- if (field != null) {
- var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field.ResolvedField));
- if (instance == null) {
- TranslatedExpressions.Push(f);
- } else {
- this.Traverse(instance);
- Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
- Bpl.IdentifierExpr temp = Bpl.Expr.Ident(this.sink.CreateFreshLocal(field.ResolvedField.Type));
- AssertOrAssumeNonNull(Bpl.Token.NoToken, instanceExpr);
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(temp, this.sink.Heap.ReadHeap(instanceExpr, f, field.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, temp.Type)));
- TranslatedExpressions.Push(temp);
- }
- return;
- }
- IArrayIndexer/*?*/ arrayIndexer = container as IArrayIndexer;
- if (arrayIndexer != null)
- {
- this.Traverse(arrayIndexer);
- return;
- }
- IAddressDereference/*?*/ addressDereference = container as IAddressDereference;
- if (addressDereference != null)
- {
- this.Traverse(addressDereference);
- return;
- }
- IBlockExpression block = container as IBlockExpression;
- if (block != null) {
- this.Traverse(block);
- return;
- }
- IMethodReference/*?*/ method = container as IMethodReference;
- if (method != null)
- {
- Console.WriteLine(MemberHelper.GetMethodSignature(method, NameFormattingOptions.Signature));
- //TODO
- throw new NotImplementedException();
- }
- IExpression/*?*/ expression = container as IExpression;
- if (expression != null) {
-
- this.Traverse(expression);
- var e = this.TranslatedExpressions.Pop();
-
- var newLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(expression.Type));
- var cmd = Bpl.Cmd.SimpleAssign(Bpl.Token.NoToken, newLocal, e);
- this.StmtTraverser.StmtBuilder.Add(cmd);
-
- this.TranslatedExpressions.Push(newLocal);
-
- return;
- }
-
- Contract.Assume(false);
- }
-
- public override void TraverseChildren(IAddressDereference addressDereference)
- {
- IBoundExpression be = addressDereference.Address as IBoundExpression;
- if (be != null)
- {
- IParameterDefinition pd = be.Definition as IParameterDefinition;
- if (pd != null)
- {
- this.LoadParameter(pd);
- return;
- }
- }
- this.Traverse(addressDereference.Address);
- return;
- }
-
- public override void TraverseChildren(IArrayIndexer arrayIndexer) {
-
- //if (!IsAtomicInstance(arrayIndexer.IndexedObject)) {
- // // Simplify the BE so that all nested dereferences and method calls are broken up into separate assignments to locals.
- // var se = ExpressionSimplifier.Simplify(this.sink, arrayIndexer);
- // this.Traverse(se);
- // return;
- //}
-
- this.Traverse(arrayIndexer.IndexedObject);
- Bpl.Expr arrayExpr = TranslatedExpressions.Pop();
-
- var be = arrayIndexer.IndexedObject as IBoundExpression;
- if (be != null && be.Instance != null) {
- var l = this.sink.CreateFreshLocal(be.Type);
- var lhs = Bpl.Expr.Ident(l);
- var cmd = Bpl.Cmd.SimpleAssign(arrayIndexer.Token(), lhs, arrayExpr);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- arrayExpr = lhs;
- }
-
- this.Traverse(arrayIndexer.Indices);
- int count = arrayIndexer.Indices.Count();
- Bpl.Expr[] indexExprs = new Bpl.Expr[count];
- for (int i = count; i > 0; i--) {
- indexExprs[i - 1] = TranslatedExpressions.Pop();
- }
- Bpl.Expr indexExpr;
- if (indexExprs.Length == 1) {
- indexExpr = indexExprs[0];
- }
- else {
- Bpl.Function f = this.sink.FindOrCreateNaryIntFunction(indexExprs.Length);
- indexExpr = new Bpl.NAryExpr(arrayIndexer.Token(), new Bpl.FunctionCall(f), new Bpl.ExprSeq(indexExprs));
- }
-
- AssertOrAssumeNonNull(arrayIndexer.Token(), arrayExpr);
- this.TranslatedExpressions.Push(this.sink.Heap.ReadHeap(arrayExpr, indexExpr, AccessType.Array, this.sink.CciTypeToBoogie(arrayIndexer.Type)));
- }
-
- public override void TraverseChildren(ITargetExpression targetExpression)
- {
- Contract.Assume(false, "The expression containing this as a subexpression should never allow a call to this routine.");
- }
-
- public override void TraverseChildren(IThisReference thisReference)
- {
- TranslatedExpressions.Push(new Bpl.IdentifierExpr(thisReference.Token(),
- this.sink.ThisVariable));
- }
-
- public override void TraverseChildren(IBoundExpression boundExpression)
- {
-
- //if (boundExpression.Instance != null && !IsAtomicInstance(boundExpression.Instance)) {
- // // Simplify the BE so that all nested dereferences and method calls are broken up into separate assignments to locals.
- // var se = ExpressionSimplifier.Simplify(this.sink, boundExpression);
- // this.Traverse(se);
- // return;
- //}
-
- if (boundExpression.Instance != null) {
- this.Traverse(boundExpression.Instance);
- var nestedBE = boundExpression.Instance as IBoundExpression;
- if (nestedBE != null) {
- var l = this.sink.CreateFreshLocal(nestedBE.Type);
- var e = this.TranslatedExpressions.Pop();
- var lhs = Bpl.Expr.Ident(l);
- var cmd = Bpl.Cmd.SimpleAssign(boundExpression.Token(), lhs, e);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(lhs);
- }
- }
-
- #region Local
- ILocalDefinition local = boundExpression.Definition as ILocalDefinition;
- if (local != null)
- {
- TranslatedExpressions.Push(Bpl.Expr.Ident(this.sink.FindOrCreateLocalVariable(local)));
- return;
- }
- #endregion
-
- #region Parameter
- IParameterDefinition param = boundExpression.Definition as IParameterDefinition;
- if (param != null)
- {
- this.LoadParameter(param);
- return;
- }
- #endregion
-
- #region Field
- IFieldReference field = boundExpression.Definition as IFieldReference;
- if (field != null) {
- var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field.ResolvedField));
- var instance = boundExpression.Instance;
- if (instance == null) {
- TranslatedExpressions.Push(f);
- } else {
-// this.Traverse(instance);
- Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
- var bplType = this.sink.CciTypeToBoogie(field.Type);
- var e = this.sink.Heap.ReadHeap(instanceExpr, f, field.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, bplType);
-
- AssertOrAssumeNonNull(boundExpression.Token(), instanceExpr);
-
- this.TranslatedExpressions.Push(e);
- }
- return;
- }
- #endregion
-
- #region ArrayIndexer
- IArrayIndexer/*?*/ indexer = boundExpression.Definition as IArrayIndexer;
- if (indexer != null)
- {
- this.Traverse(indexer);
- return;
- }
- #endregion
-
- #region AddressDereference
- IAddressDereference/*?*/ deref = boundExpression.Definition as IAddressDereference;
- if (deref != null)
- {
- IAddressOf/*?*/ addressOf = deref.Address as IAddressOf;
- if (addressOf != null)
- {
- this.Traverse(addressOf.Expression);
- return;
- }
- if (boundExpression.Instance != null)
- {
- // TODO
- this.Traverse(boundExpression.Instance);
- Console.Write("->");
- }
- else if (deref.Address.Type is IPointerTypeReference)
- Console.Write("*");
- this.Traverse(deref.Address);
- return;
- }
- else
- {
- if (boundExpression.Instance != null)
- {
- throw new NotImplementedException("Addr DeRef without instance.");
- }
- }
- #endregion
- }
-
- private void AssertOrAssumeNonNull(Bpl.IToken token, Bpl.Expr instance) {
- if (this.sink.Options.dereference != Options.Dereference.None) {
- Bpl.Cmd c;
- var n = Bpl.Expr.Ident(this.sink.Heap.NullRef);
- var neq = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, instance, n);
- if (this.sink.Options.dereference == Options.Dereference.Assume) {
- c = new Bpl.AssumeCmd(token, neq);
- } else {
- c = new Bpl.AssertCmd(token, neq);
- }
- this.StmtTraverser.StmtBuilder.Add(c);
- }
- }
-
- internal static bool IsAtomicInstance(IExpression expression) {
- var thisInst = expression as IThisReference;
- if (thisInst != null) return true;
- if (expression is IDupValue) return true;
- // Since we're treating structs as being kept in the heap,
- // the expression "&s" is atomic if s is atomic.
- var addressOf = expression as IAddressOf;
- if (addressOf != null) {
- var ae = addressOf.Expression;
- return ae.Instance == null || IsAtomicInstance(ae.Instance);
- }
- var be = expression as IBoundExpression;
- if (be == null) return false;
- return be.Instance == null;
- }
-
- public override void TraverseChildren(IDupValue dupValue) {
- var e = this.sink.operandStack.Peek();
- this.TranslatedExpressions.Push(e);
- }
- public override void TraverseChildren(IPopValue popValue) {
- var locExpr = this.sink.operandStack.Pop();
- this.TranslatedExpressions.Push(locExpr);
- }
-
- private void LoadParameter(IParameterDefinition parameter) {
- TranslatedExpressions.Push(Bpl.Expr.Ident(this.sink.FindParameterVariable(parameter, this.contractContext)));
- return;
- }
-
- /// <summary>
- /// If the expression's type is a generic parameter (either method or type),
- /// then this returns a "unboxed" expression, i.e., the value as a ref.
- /// Otherwise it just translates the underlying expression and boxes it.
- /// </summary>
- public override void TraverseChildren(IAddressOf addressOf)
- {
- var t = addressOf.Expression.Type;
- var boogieT = this.sink.CciTypeToBoogie(t);
-
- if (t is IGenericParameterReference && boogieT == this.sink.Heap.UnionType) {
- // then the expression will be represented by something of type Box
- // but the address of it must be a ref, so do the conversion
- this.Traverse(addressOf.Expression);
- var e = this.TranslatedExpressions.Pop();
- this.TranslatedExpressions.Push(this.sink.Heap.FromUnion(addressOf.Token(), this.sink.Heap.RefType, e));
- } else {
- object container = addressOf.Expression.Definition;
- IExpression/*?*/ instance = addressOf.Expression.Instance;
- this.LoadAddressOf(container, instance);
- return;
- }
- }
- #endregion
-
- #region Translate Constant Access
-
- public override void TraverseChildren(ICompileTimeConstant constant) {
- if (constant.Value == null) {
- var bplType = sink.CciTypeToBoogie(constant.Type);
- if (bplType == Bpl.Type.Int) {
- var lit = Bpl.Expr.Literal(0);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- } else if (bplType == Bpl.Type.Bool) {
- TranslatedExpressions.Push(Bpl.Expr.False);
- } else if (bplType == this.sink.Heap.RefType) {
- TranslatedExpressions.Push(Bpl.Expr.Ident(this.sink.Heap.NullRef));
- } else {
- throw new NotImplementedException(String.Format("Don't know how to translate type: '{0}'", TypeHelper.GetTypeName(constant.Type)));
- }
- return;
- }
- if (constant.Value is string) {
- var c = this.sink.FindOrCreateConstant((string)(constant.Value));
- TranslatedExpressions.Push(Bpl.Expr.Ident(c));
- return;
- }
- if (constant.Type.IsEnum) {
- var lit = Bpl.Expr.Literal((int)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- return;
- }
- switch (constant.Type.TypeCode) {
- case PrimitiveTypeCode.Boolean:
- // Decompiler might not have converted the constant back to a boolean? Not sure why,
- // but that's what I'm seeing here.
- if (constant.Value is bool) {
- TranslatedExpressions.Push(((bool)constant.Value) ? Bpl.Expr.True : Bpl.Expr.False);
- } else {
- TranslatedExpressions.Push(((int)constant.Value) != 0 ? Bpl.Expr.True : Bpl.Expr.False);
- }
- break;
- case PrimitiveTypeCode.Char: {
- var lit = Bpl.Expr.Literal((int)(char)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.Int8: {
- var lit = Bpl.Expr.Literal((int)(sbyte)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.Int16: {
- var lit = Bpl.Expr.Literal((int)(short)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.Int32: {
- var lit = Bpl.Expr.Literal((int)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.Int64: {
- var lit = Bpl.Expr.Literal(Microsoft.Basetypes.BigNum.FromLong((long)constant.Value));
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.UInt8: {
- var lit = Bpl.Expr.Literal((int)(byte)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.UInt16: {
- var lit = Bpl.Expr.Literal((int)(ushort)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.UInt32: {
- var lit = Bpl.Expr.Literal((int)(uint)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.UInt64: {
- var lit = Bpl.Expr.Literal(Microsoft.Basetypes.BigNum.FromULong((ulong)constant.Value));
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- break;
- }
- case PrimitiveTypeCode.Float32: {
- var c = this.sink.FindOrCreateConstant((float)(constant.Value));
- TranslatedExpressions.Push(Bpl.Expr.Ident(c));
- break;
- }
- case PrimitiveTypeCode.Float64: {
- var c = this.sink.FindOrCreateConstant((double)(constant.Value));
- TranslatedExpressions.Push(Bpl.Expr.Ident(c));
- break;
- }
- default:
- throw new NotImplementedException(String.Format("Can't translate compile-time constant of type '{0}'",
- TypeHelper.GetTypeName(constant.Type)));
- }
- return;
- }
-
- public override void TraverseChildren(IDefaultValue defaultValue) {
- var typ = defaultValue.Type;
-
- if (TranslationHelper.IsStruct(typ)) {
- translateStructDefaultValue(defaultValue, typ);
- return;
- }
-
- Bpl.Expr e;
- var bplType = this.sink.CciTypeToBoogie(typ);
- if (bplType == Bpl.Type.Int) {
- var lit = Bpl.Expr.Literal(0);
- lit.Type = Bpl.Type.Int;
- e = lit;
- } else if (bplType == Bpl.Type.Bool) {
- var lit = Bpl.Expr.False;
- lit.Type = Bpl.Type.Bool;
- e = lit;
- } else if (bplType == this.sink.Heap.RefType) {
- e = Bpl.Expr.Ident(this.sink.Heap.NullRef);
- } else if (bplType == this.sink.Heap.UnionType) {
- e = Bpl.Expr.Ident(this.sink.Heap.DefaultHeapValue);
- } else if (bplType == this.sink.Heap.RealType) {
- e = Bpl.Expr.Ident(this.sink.Heap.DefaultReal);
- } else {
- throw new NotImplementedException(String.Format("Don't know how to translate type: '{0}'", TypeHelper.GetTypeName(typ)));
- }
-
- TranslatedExpressions.Push(e);
- return;
- }
-
- private void translateStructDefaultValue(IDefaultValue defaultValue, ITypeReference typ) {
- // then it is a struct and gets special treatment
- // translate it as if it were a call to the nullary ctor for the struct type
- // (which doesn't actually exist, but gets generated for each struct type
- // encountered during translation)
-
- var tok = defaultValue.Token();
-
- var loc = this.sink.CreateFreshLocal(typ);
- var locExpr = Bpl.Expr.Ident(loc);
-
- // First generate an Alloc() call
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(tok, this.sink.AllocationMethodName, new Bpl.ExprSeq(), new Bpl.IdentifierExprSeq(locExpr)));
-
- // Second, generate the call to the appropriate ctor
- var proc = this.sink.FindOrCreateProcedureForDefaultStructCtor(typ);
- var invars = new List<Bpl.Expr>();
- invars.Add(locExpr);
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(tok, proc.Name, invars, new List<Bpl.IdentifierExpr>()));
-
- // Generate an assumption about the dynamic type of the just allocated object
- this.StmtTraverser.StmtBuilder.Add(
- new Bpl.AssumeCmd(tok,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
- this.sink.Heap.DynamicType(locExpr),
- this.FindOrCreateTypeReferenceInCodeContext(typ)
- )
- )
- );
-
- this.TranslatedExpressions.Push(locExpr);
- }
-
- #endregion
-
- #region Translate Method Calls
- /// <summary>
- ///
- /// </summary>
- /// <param name="methodCall"></param>
- /// <remarks>Stub, This one really needs comments!</remarks>
- public override void TraverseChildren(IMethodCall methodCall) {
- var resolvedMethod = ResolveUnspecializedMethodOrThrow(methodCall.MethodToCall);
-
- Bpl.IToken methodCallToken = methodCall.Token();
-
- if (this.sink.Options.getMeHere) {
- // TODO: Get a method reference so this isn't a string comparison?
- var methodName = MemberHelper.GetMethodSignature(methodCall.MethodToCall, NameFormattingOptions.None);
- if (methodName.Equals("GetMeHere.GetMeHere.Assert")) {
- // for now, just translate it as "assert e"
- this.Traverse(methodCall.Arguments.First());
- Bpl.Expr e = this.TranslatedExpressions.Pop();
- this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, e));
- return;
- }
- }
-
- // Handle type equality specially when it is testing against a constant, i.e., o.GetType() == typeof(T)
- if (IsOperator(resolvedMethod) && !IsConversionOperator(resolvedMethod) &&
- TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, this.sink.host.PlatformType.SystemType)) {
- // REVIEW: Assume the only operators on System.Type are == and !=
- var typeToTest = methodCall.Arguments.ElementAtOrDefault(0) as ITypeOf;
- IMethodCall callToGetType;
- if (typeToTest == null) {
- typeToTest = methodCall.Arguments.ElementAtOrDefault(1) as ITypeOf;
- callToGetType = methodCall.Arguments.ElementAtOrDefault(0) as IMethodCall;
- } else {
- callToGetType = methodCall.Arguments.ElementAtOrDefault(1) as IMethodCall;
- }
- if (typeToTest != null && callToGetType != null &&
- TypeHelper.TypesAreEquivalent(callToGetType.MethodToCall.ContainingType, this.sink.host.PlatformType.SystemObject) &&
- MemberHelper.GetMethodSignature(callToGetType.MethodToCall).Equals("System.Object.GetType")) {
-
- IExpression objectToTest = callToGetType.ThisArgument;
-
- // generate: is#T($DynamicType(o))
- var typeFunction = this.sink.FindOrDefineType(typeToTest.TypeToGet.ResolvedType);
- Contract.Assume(typeFunction != null);
- var funcName = String.Format("is#{0}", typeFunction.Name);
- var identExpr = Bpl.Expr.Ident(new Bpl.LocalVariable(methodCallToken, new Bpl.TypedIdent(methodCallToken, funcName, Bpl.Type.Bool)));
- var funcCall = new Bpl.FunctionCall(identExpr);
-
- this.Traverse(objectToTest);
- var e = this.TranslatedExpressions.Pop();
-
- var exprs = new Bpl.ExprSeq(this.sink.Heap.DynamicType(e));
- Bpl.Expr typeTestExpression = new Bpl.NAryExpr(methodCallToken, funcCall, exprs);
- if (MemberHelper.GetMethodSignature(resolvedMethod).Equals("System.Type.op_Inequality"))
- typeTestExpression = Bpl.Expr.Unary( methodCallToken, Bpl.UnaryOperator.Opcode.Not, typeTestExpression);
- this.TranslatedExpressions.Push(typeTestExpression);
- return;
- }
- }
-
-
- List<Bpl.Expr> inexpr;
- List<Bpl.IdentifierExpr> outvars;
- Bpl.IdentifierExpr thisExpr;
- Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toBoxed;
- var proc = TranslateArgumentsAndReturnProcedure(methodCallToken, methodCall.MethodToCall, resolvedMethod, methodCall.IsStaticCall ? null : methodCall.ThisArgument, methodCall.Arguments, out inexpr, out outvars, out thisExpr, out toBoxed);
- string methodname = proc.Name;
- var translateAsFunctionCall = proc is Bpl.Function;
- Bpl.QKeyValue attrib = null;
-
- // this code structure is quite chaotic, and some code needs to be evaluated regardless, hence the try-finally
- try {
- if (!translateAsFunctionCall) {
- foreach (var a in resolvedMethod.Attributes) {
- if (TypeHelper.GetTypeName(a.Type).EndsWith("AsyncAttribute")) {
- attrib = new Bpl.QKeyValue(methodCallToken, "async", new List<object>(), null);
- }
- }
- }
-
- var deferringCtorCall = resolvedMethod.IsConstructor && methodCall.ThisArgument is IThisReference;
- // REVIEW!! Ask Herman: is the above test enough? The following test is used in FindCtorCall.IsDeferringCtor,
- // but it doesn't work when the type is a struct S because then "this" has a type of "&S".
- //&& TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, methodCall.ThisArgument.Type);
-
- if (resolvedMethod.IsConstructor && resolvedMethod.ContainingTypeDefinition.IsStruct && !deferringCtorCall) {
- handleStructConstructorCall(methodCall, methodCallToken, inexpr, outvars, thisExpr, proc);
- return;
- }
-
- Bpl.CallCmd call;
- bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
- bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");
- if (isEventAdd || isEventRemove) {
- call = translateAddRemoveCall(methodCall, resolvedMethod, methodCallToken, inexpr, outvars, thisExpr, isEventAdd);
- } else {
- if (translateAsFunctionCall) {
- var func = proc as Bpl.Function;
- var exprSeq = new Bpl.ExprSeq();
- foreach (var e in inexpr) {
- exprSeq.Add(e);
- }
- var callFunction = new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(func), exprSeq);
- this.TranslatedExpressions.Push(callFunction);
- return;
- } else {
- EmitLineDirective(methodCallToken);
- if (attrib != null)
- call = new Bpl.CallCmd(methodCallToken, methodname, inexpr, outvars, attrib);
- else
- call = new Bpl.CallCmd(methodCallToken, methodname, inexpr, outvars);
- this.StmtTraverser.StmtBuilder.Add(call);
- }
- }
-
- foreach (KeyValuePair<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> kv in toBoxed) {
- var lhs = kv.Key;
- var tuple = kv.Value;
- var rhs = tuple.Item1;
- Bpl.Expr fromUnion;
- if (tuple.Item2) {
- // Since both structs and objects are represented by "Ref", need to make a distinction here.
- // Review: Introduce an explicit type "Struct"?
- fromUnion = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Union2Struct), new Bpl.ExprSeq(rhs));
- } else {
- fromUnion = this.sink.Heap.FromUnion(Bpl.Token.NoToken, lhs.Type, rhs);
- //this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(lhs, this.sink.Heap.FromUnion(Bpl.Token.NoToken, lhs.Type, rhs)));
- }
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(lhs, fromUnion));
- }
-
- if (this.sink.Options.modelExceptions == 2
- || (this.sink.Options.modelExceptions == 1 && this.sink.MethodThrowsExceptions(resolvedMethod))) {
- Bpl.Expr expr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef));
- this.StmtTraverser.RaiseException(expr);
- }
- } finally {
- // TODO move away phone related code from the translation, it would be better to have 2 or more translation phases
- if (PhoneCodeHelper.instance().PhonePlugin != null) {
- if (PhoneCodeHelper.instance().PhoneNavigationToggled) {
- if (PhoneCodeHelper.instance().isNavigationCall(methodCall)) {
- Bpl.AssignCmd assignCmd = PhoneCodeHelper.instance().createBoogieNavigationUpdateCmd(sink);
- this.StmtTraverser.StmtBuilder.Add(assignCmd);
- }
- }
-
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
- if (PhoneCodeHelper.instance().isMethodKnownUIChanger(methodCall)) {
- Bpl.AssumeCmd assumeFalse = new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False);
- this.StmtTraverser.StmtBuilder.Add(assumeFalse);
- }
- }
- }
- }
- }
-
- public virtual bool IsOperator(IMethodDefinition methodDefinition) {
- return (methodDefinition.IsSpecialName && methodDefinition.Name.Value.StartsWith("op_"));
- }
-
- public virtual bool IsConversionOperator(IMethodDefinition methodDefinition) {
- return (methodDefinition.IsSpecialName && (
- methodDefinition.Name.Value == "op_Explicit" || methodDefinition.Name.Value == "op_Implicit"));
- }
-
- private void EmitLineDirective(Bpl.IToken methodCallToken) {
- var sloc = this.StmtTraverser.lastSourceLocation;
- if (sloc != null) {
- var fileName = sloc.Document.Location;
- var lineNumber = sloc.StartLine;
- var attrib = new Bpl.QKeyValue(methodCallToken, "sourceLine", new List<object> { Bpl.Expr.Literal((int)lineNumber) }, null);
- attrib = new Bpl.QKeyValue(methodCallToken, "sourceFile", new List<object> { fileName }, attrib);
- this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, Bpl.Expr.True, attrib));
- }
- }
-
- private Bpl.CallCmd translateAddRemoveCall(IMethodCall methodCall, IMethodDefinition resolvedMethod, Bpl.IToken methodCallToken, List<Bpl.Expr> inexpr, List<Bpl.IdentifierExpr> outvars, Bpl.IdentifierExpr thisExpr, bool isEventAdd) {
- Bpl.CallCmd call;
- var mName = resolvedMethod.Name.Value;
- var eventName = mName.Substring(mName.IndexOf('_') + 1);
- var eventDef = TypeHelper.GetEvent(resolvedMethod.ContainingTypeDefinition, this.sink.host.NameTable.GetNameFor(eventName));
- Contract.Assert(eventDef != Dummy.Event);
- Bpl.Variable eventVar = this.sink.FindOrCreateEventVariable(eventDef);
- Bpl.Variable local = this.sink.CreateFreshLocal(eventDef.Type);
-
- if (methodCall.IsStaticCall) {
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), Bpl.Expr.Ident(eventVar)));
- inexpr.Insert(0, Bpl.Expr.Ident(local));
- } else {
- AssertOrAssumeNonNull(methodCallToken, thisExpr);
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), this.sink.Heap.ReadHeap(thisExpr, Bpl.Expr.Ident(eventVar), resolvedMethod.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, local.TypedIdent.Type)));
- inexpr[0] = Bpl.Expr.Ident(local);
- }
-
- System.Diagnostics.Debug.Assert(outvars.Count == 0);
- outvars.Insert(0, Bpl.Expr.Ident(local));
- string methodName = isEventAdd ? this.sink.DelegateAddName : this.sink.DelegateRemoveName;
- call = new Bpl.CallCmd(methodCallToken, methodName, inexpr, outvars);
- this.StmtTraverser.StmtBuilder.Add(call);
- if (methodCall.IsStaticCall) {
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local)));
- } else {
- this.StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(methodCallToken, thisExpr, Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local), resolvedMethod.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, local.TypedIdent.Type));
- }
- return call;
- }
-
- private void handleStructConstructorCall(IMethodCall methodCall, Bpl.IToken methodCallToken, List<Bpl.Expr> inexpr, List<Bpl.IdentifierExpr> outvars, Bpl.IdentifierExpr thisExpr, Bpl.DeclWithFormals proc) {
- // then the method call looks like "&s.S.ctor(...)" for some variable s of struct type S
- // treat it as if it was "s := new S(...)"
- // So this code is the same as Visit(ICreateObjectInstance)
- // TODO: factor the code into a single method?
-
- // First generate an Alloc() call
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(methodCallToken, this.sink.AllocationMethodName, new Bpl.ExprSeq(), new Bpl.IdentifierExprSeq(thisExpr)));
-
- // Second, generate the call to the appropriate ctor
- EmitLineDirective(methodCallToken);
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(methodCallToken, proc.Name, inexpr, outvars));
-
- // Generate an assumption about the dynamic type of the just allocated object
- this.StmtTraverser.StmtBuilder.Add(
- new Bpl.AssumeCmd(methodCallToken,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
- this.sink.Heap.DynamicType(thisExpr),
- this.FindOrCreateTypeReferenceInCodeContext(methodCall.MethodToCall.ResolvedMethod.ContainingTypeDefinition)
- )
- )
- );
- }
-
- // REVIEW: Does "thisExpr" really need to come back as an identifier? Can't it be a general expression?
- protected Bpl.DeclWithFormals TranslateArgumentsAndReturnProcedure(Bpl.IToken token, IMethodReference methodToCall, IMethodDefinition resolvedMethod, IExpression/*?*/ thisArg, IEnumerable<IExpression> arguments, out List<Bpl.Expr> inexpr, out List<Bpl.IdentifierExpr> outvars, out Bpl.IdentifierExpr thisExpr, out Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toUnioned) {
- inexpr = new List<Bpl.Expr>();
- outvars = new List<Bpl.IdentifierExpr>();
-
- #region Create the 'this' argument for the function call
- thisExpr = null;
- if (thisArg != null) {
-
- // Special case! thisArg is going to be an AddressOf expression if the receiver is a value-type
- // But if the method's containing type is something that doesn't get translated as a Ref, then
- // the AddressOf node should be ignored.
- var addrOf = thisArg as IAddressOf;
- var boogieType = this.sink.CciTypeToBoogie(methodToCall.ContainingType);
- if (false && addrOf != null && boogieType != this.sink.Heap.RefType) {
- thisArg = addrOf.Expression;
- }
-
- this.Traverse(thisArg);
-
- var e = this.TranslatedExpressions.Pop();
- var identifierExpr = e as Bpl.IdentifierExpr;
- if (identifierExpr == null) {
- var newLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(methodToCall.ContainingType));
- var cmd = Bpl.Cmd.SimpleAssign(token, newLocal, e);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- e = newLocal;
- } else {
-
- }
- inexpr.Add(e);
- thisExpr = (Bpl.IdentifierExpr) e;
- }
- #endregion
-
- toUnioned = new Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>>();
- IEnumerator<IParameterDefinition> penum = resolvedMethod.Parameters.GetEnumerator();
- penum.MoveNext();
- foreach (IExpression exp in arguments) {
- if (penum.Current == null) {
- throw new TranslationException("More arguments than parameters in method call");
- }
-
- var expressionToTraverse = exp;
- //Bpl.Type boogieTypeOfExpression;
-
- //// Special case! exp can be an AddressOf expression if it is a value type being passed by reference.
- //// But since we pass reference parameters by in-out value passing, need to short-circuit the
- //// AddressOf node if the underlying type is not a Ref.
- //var addrOf = exp as IAddressOf;
- //if (addrOf != null) {
- // boogieTypeOfExpression = this.sink.CciTypeToBoogie(addrOf.Expression.Type);
- // if (boogieTypeOfExpression != this.sink.Heap.RefType) {
- // expressionToTraverse = addrOf.Expression;
- // }
- //}
-
- //boogieTypeOfExpression = this.sink.CciTypeToBoogie(expressionToTraverse.Type);
- this.Traverse(expressionToTraverse);
-
- Bpl.Expr e = this.TranslatedExpressions.Pop();
- var currentType = penum.Current.Type;
-
- // If the argument is a struct, then make a copy of it to pass to the procedure.
- if (TranslationHelper.IsStruct(exp.Type)) {
- var proc = this.sink.FindOrCreateProcedureForStructCopy(exp.Type);
- var bplLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(exp.Type));
- var cmd = new Bpl.CallCmd(token, proc.Name, new List<Bpl.Expr> { e, }, new List<Bpl.IdentifierExpr> { bplLocal, });
- this.StmtTraverser.StmtBuilder.Add(cmd);
- e = bplLocal;
- }
-
- if (currentType is IGenericParameterReference && this.sink.CciTypeToBoogie(currentType) == this.sink.Heap.UnionType) {
- if (TranslationHelper.IsStruct(expressionToTraverse.Type)) {
- // Since both structs and objects are represented by "Ref", need to make a distinction here.
- // Review: Introduce an explicit type "Struct"?
- var toUnion = new Bpl.NAryExpr(token, new Bpl.FunctionCall(this.sink.Heap.Struct2Union), new Bpl.ExprSeq(e));
- inexpr.Add(toUnion);
- } else {
- inexpr.Add(sink.Heap.ToUnion(token, this.sink.CciTypeToBoogie(expressionToTraverse.Type), e));
- }
- } else {
- inexpr.Add(e);
- }
- if (penum.Current.IsByReference) {
- Bpl.IdentifierExpr unboxed = e as Bpl.IdentifierExpr;
- if (unboxed == null) {
- throw new TranslationException("Trying to pass a complex expression for an out or ref parameter");
- }
- if (penum.Current.Type is IGenericParameterReference) {
- var boogieType = this.sink.CciTypeToBoogie(penum.Current.Type);
- if (boogieType == this.sink.Heap.UnionType) {
- Bpl.IdentifierExpr boxed = Bpl.Expr.Ident(sink.CreateFreshLocal(this.sink.Heap.UnionType));
- toUnioned[unboxed] = Tuple.Create(boxed,false);
- outvars.Add(boxed);
- } else {
- outvars.Add(unboxed);
- }
- } else {
- outvars.Add(unboxed);
- }
- }
- penum.MoveNext();
- }
-
- if (resolvedMethod.IsStatic) {
- List<ITypeReference> consolidatedTypeArguments = new List<ITypeReference>();
- Sink.GetConsolidatedTypeArguments(consolidatedTypeArguments, methodToCall.ContainingType);
- foreach (ITypeReference typeReference in consolidatedTypeArguments) {
- inexpr.Add(this.FindOrCreateTypeReferenceInCodeContext(typeReference));
- }
- }
- IGenericMethodInstanceReference methodInstanceReference = methodToCall as IGenericMethodInstanceReference;
- if (methodInstanceReference != null) {
- foreach (ITypeReference typeReference in methodInstanceReference.GenericArguments) {
- inexpr.Add(this.FindOrCreateTypeReferenceInCodeContext(typeReference));
- }
- }
-
- var procInfo = this.sink.FindOrCreateProcedure(resolvedMethod);
- var translateAsFunctionCall = procInfo.Decl is Bpl.Function;
- if (!translateAsFunctionCall) {
- if (resolvedMethod.Type.ResolvedType.TypeCode != PrimitiveTypeCode.Void) {
- Bpl.Variable v = this.sink.CreateFreshLocal(methodToCall.ResolvedMethod.Type.ResolvedType);
- Bpl.IdentifierExpr unUnioned = new Bpl.IdentifierExpr(token, v);
- if (resolvedMethod.Type is IGenericParameterReference) {
- var boogieType = this.sink.CciTypeToBoogie(resolvedMethod.Type);
- if (boogieType == this.sink.Heap.UnionType) {
- Bpl.IdentifierExpr unioned = Bpl.Expr.Ident(this.sink.CreateFreshLocal(this.sink.Heap.UnionType));
- toUnioned[unUnioned] = Tuple.Create(unioned, TranslationHelper.IsStruct(methodToCall.ResolvedMethod.Type.ResolvedType));
- outvars.Add(unioned);
- } else {
- outvars.Add(unUnioned);
- }
- } else {
- outvars.Add(unUnioned);
- }
- TranslatedExpressions.Push(unUnioned);
- }
- }
-
- return procInfo.Decl;
- }
-
- #endregion
-
- #region Translate Assignments
-
- /// <summary>
- ///
- /// </summary>
- /// <remarks>(mschaef) Works, but still a stub </remarks>
- /// <param name="assignment"></param>
- public override void TraverseChildren(IAssignment assignment) {
- Contract.Assert(TranslatedExpressions.Count == 0);
- var tok = assignment.Token();
-
- bool translationIntercepted= false;
- ICompileTimeConstant constant= assignment.Source as ICompileTimeConstant;
- // TODO move away phone related code from the translation, it would be better to have 2 or more translation phases
- // NAVIGATION TODO maybe this will go away if I can handle it with stubs
- if (PhoneCodeHelper.instance().PhonePlugin != null && PhoneCodeHelper.instance().PhoneNavigationToggled) {
- IFieldReference target = assignment.Target.Definition as IFieldReference;
- if (target != null && target.Name.Value == PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE) {
- if (constant != null && constant.Type == sink.host.PlatformType.SystemString && constant.Value != null &&
- constant.Value.Equals(PhoneCodeHelper.BOOGIE_DO_HAVOC_CURRENTURI)) {
- TranslateHavocCurrentURI();
- translationIntercepted = true;
- }
- StmtTraverser.StmtBuilder.Add(PhoneCodeHelper.instance().getAddNavigationCheck(sink));
- }
- }
-
- if (!translationIntercepted)
- TranslateAssignment(tok, assignment.Target.Definition, assignment.Target.Instance, assignment.Source);
- }
-
- /// <summary>
- /// Patch, to account for URIs that cannot be tracked because of current dataflow restrictions
- /// </summary>
- private void TranslateHavocCurrentURI() {
- // TODO move away phone related code from the translation, it would be better to have 2 or more translation phases
- IMethodReference havocMethod= PhoneCodeHelper.instance().getUriHavocerMethod(sink);
- Sink.ProcedureInfo procInfo= sink.FindOrCreateProcedure(havocMethod.ResolvedMethod);
- Bpl.CallCmd havocCall = new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>());
- StmtTraverser.StmtBuilder.Add(havocCall);
- }
-
- /// <summary>
- /// Handles "instance.container := source".
- /// Note that instance can be null in which case the container better be
- /// a local, parameter, static field, or address dereference.
- /// </summary>
- private void TranslateAssignment(Bpl.IToken tok, object container, IExpression/*?*/ instance, IExpression source) {
- Contract.Assert(TranslatedExpressions.Count == 0);
-
- var typ = source.Type;
- var structCopy = TranslationHelper.IsStruct(typ) && !(source is IDefaultValue);
- // then a struct value of type S is being assigned: "lhs := s"
- // model this as the statement "call lhs := S..#copy_ctor(s)" that does the bit-wise copying
- Bpl.DeclWithFormals proc = null;
- if (structCopy) {
- proc = this.sink.FindOrCreateProcedureForStructCopy(typ);
- }
- Bpl.Cmd cmd;
-
- EmitLineDirective(tok);
-
- var/*?*/ local = container as ILocalDefinition;
- if (local != null) {
- Contract.Assume(instance == null);
- this.Traverse(source);
- var e = this.TranslatedExpressions.Pop();
- var bplLocal = Bpl.Expr.Ident(this.sink.FindOrCreateLocalVariable(local));
- if (structCopy) {
- cmd = new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr>{ e, }, new List<Bpl.IdentifierExpr>{ bplLocal, });
- } else {
- cmd = Bpl.Cmd.SimpleAssign(tok, bplLocal, e);
- }
- StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
- return;
- }
-
- var/*?*/ parameter = container as IParameterDefinition;
- if (parameter != null) {
- Contract.Assume(instance == null);
- this.Traverse(source);
- var e = this.TranslatedExpressions.Pop();
- var bplParam = Bpl.Expr.Ident(this.sink.FindParameterVariable(parameter, this.contractContext));
- if (structCopy) {
- cmd = new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr> { e, bplParam, }, new List<Bpl.IdentifierExpr>());
- } else {
- cmd = Bpl.Cmd.SimpleAssign(tok, bplParam, e);
- }
- StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
- return;
- }
-
- var/*?*/ field = container as IFieldReference;
- if (field != null) {
- this.Traverse(source);
- var e = this.TranslatedExpressions.Pop();
- var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field));
- if (instance == null) {
- // static fields are not kept in the heap
- StmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, f, e));
- }
- else {
- this.Traverse(instance);
- var x = this.TranslatedExpressions.Pop();
- var boogieType = sink.CciTypeToBoogie(field.Type);
- StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(tok, x, f, e,
- field.ResolvedField.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap,
- boogieType));
- this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
- }
- return;
- }
-
- var/*?*/ arrayIndexer = container as IArrayIndexer;
- if (arrayIndexer != null) {
- this.Traverse(instance);
- var x = this.TranslatedExpressions.Pop();
- this.Traverse(arrayIndexer.Indices);
- var indices_prime = this.TranslatedExpressions.Pop();
- this.Traverse(source);
- var e = this.TranslatedExpressions.Pop();
- StmtTraverser.StmtBuilder.Add(sink.Heap.WriteHeap(Bpl.Token.NoToken, x, indices_prime, e, AccessType.Array, sink.CciTypeToBoogie(arrayIndexer.Type)));
- this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
- return;
- }
-
- var/*?*/ addressDereference = container as IAddressDereference;
- if (addressDereference != null) {
- var addressOf = addressDereference.Address as IAddressOf;
- if (addressOf != null) {
- var ae = addressOf.Expression;
- TranslateAssignment(tok, ae.Definition, ae.Instance, source);
- return;
- }
- var pop = addressDereference.Address as IPopValue;
- if (pop != null) {
- var popValue = this.sink.operandStack.Pop();
- var be = popValue as IBoundExpression;
- if (be != null) {
- TranslateAssignment(tok, be.Definition, be.Instance, source);
- return;
- }
- var ao = popValue as IAddressOf;
- if (ao != null) {
- TranslateAssignment(tok, ao.Expression.Definition, ao.Expression.Instance, source);
- return;
- }
- }
- var be2 = addressDereference.Address as IBoundExpression;
- if (be2 != null) {
- TranslateAssignment(tok, be2.Definition, be2.Instance, source);
- return;
- }
- var thisExp = addressDereference.Address as IThisReference;
- if (thisExp != null) {
- // I believe this happens only when a struct calls the default
- // ctor (probably only ever done in a different ctor for the
- // struct). The assignment actually looks like "*this := DefaultValue(S)"
- Contract.Assume(instance == null);
- this.Traverse(source);
- var e = this.TranslatedExpressions.Pop();
- var bplLocal = Bpl.Expr.Ident(this.sink.ThisVariable);
- cmd = Bpl.Cmd.SimpleAssign(tok, bplLocal, e);
- StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
- return;
- }
- }
- throw new TranslationException("Untranslatable assignment statement.");
- }
-
- internal delegate void SourceTraverser(IExpression source);
-
- private void VisitAssignment(ITargetExpression target, IExpression source, SourceTraverser sourceTraverser,
- bool treatAsStatement, bool pushTargetRValue, bool resultIsInitialTargetRValue) {
- Contract.Requires(target != null);
- Contract.Requires(source != null);
- Contract.Requires(sourceTraverser != null);
- Contract.Requires(!resultIsInitialTargetRValue || pushTargetRValue);
- Contract.Requires(!pushTargetRValue || source is IBinaryOperation);
-
- var tok = source.Token();
- var typ = source.Type;
- var structCopy = TranslationHelper.IsStruct(typ) && !(source is IDefaultValue);
- // then a struct value of type S is being assigned: "lhs := s"
- // model this as the statement "call lhs := S..#copy_ctor(s)" that does the bit-wise copying
- Bpl.DeclWithFormals proc = null;
- if (structCopy) {
- proc = this.sink.FindOrCreateProcedureForStructCopy(typ);
- }
-
- object container = target.Definition;
-
- Top:
-
- ILocalDefinition/*?*/ local = container as ILocalDefinition;
- if (local != null) {
- if (source is IDefaultValue && !local.Type.ResolvedType.IsReferenceType) {
- // this.LoadAddressOf(local, null);
- // this.generator.Emit(OperationCode.Initobj, local.Type);
- // if (!treatAsStatement) this.LoadLocal(local);
- } else {
- Bpl.IdentifierExpr temp = null;
- var bplLocal = Bpl.Expr.Ident(this.sink.FindOrCreateLocalVariable(local));
- if (pushTargetRValue) {
- this.TranslatedExpressions.Push(bplLocal);
- if (!treatAsStatement && resultIsInitialTargetRValue) {
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var e3 = this.TranslatedExpressions.Pop();
- var cmd3 = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd3);
- this.TranslatedExpressions.Push(temp);
- }
- }
- sourceTraverser(source);
- var e = this.TranslatedExpressions.Pop();
- if (temp != null) this.TranslatedExpressions.Push(temp);
-
- Bpl.Cmd cmd;
- if (structCopy) {
- cmd = new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr> { e, }, new List<Bpl.IdentifierExpr> { bplLocal, });
- } else {
- cmd = Bpl.Cmd.SimpleAssign(tok, bplLocal, e);
- }
- StmtTraverser.StmtBuilder.Add(cmd);
-
- if (!treatAsStatement && !resultIsInitialTargetRValue) {
- this.TranslatedExpressions.Push(bplLocal);
- }
- }
- return;
- }
- IParameterDefinition/*?*/ parameter = container as IParameterDefinition;
- if (parameter != null) {
- if (source is IDefaultValue && !parameter.Type.ResolvedType.IsReferenceType) {
- //this.LoadAddressOf(parameter, null);
- //this.generator.Emit(OperationCode.Initobj, parameter.Type);
- //if (!treatAsStatement) this.LoadParameter(parameter);
- } else {
- Bpl.IdentifierExpr temp = null;
- if (pushTargetRValue) {
- this.LoadParameter(parameter);
- if (!treatAsStatement && resultIsInitialTargetRValue) {
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var e3 = this.TranslatedExpressions.Pop();
- var cmd3 = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd3);
- this.TranslatedExpressions.Push(temp);
- }
- }
- sourceTraverser(source);
- var e = this.TranslatedExpressions.Pop();
- if (temp != null) this.TranslatedExpressions.Push(temp);
- var bplParam = Bpl.Expr.Ident(this.sink.FindParameterVariable(parameter, this.contractContext));
-
- Bpl.Cmd cmd;
- if (structCopy) {
- cmd = new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr> { e, bplParam, }, new List<Bpl.IdentifierExpr>());
- } else {
- cmd = Bpl.Cmd.SimpleAssign(tok, bplParam, e);
- }
- StmtTraverser.StmtBuilder.Add(cmd);
-
- if (!treatAsStatement && !resultIsInitialTargetRValue) {
- this.LoadParameter(parameter);
- }
- }
- return;
- }
- IFieldReference/*?*/ field = container as IFieldReference;
- if (field != null) {
-
- var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field));
- var boogieTypeOfField = sink.CciTypeToBoogie(field.Type);
-
- if (source is IDefaultValue && !field.Type.ResolvedType.IsReferenceType) {
- //this.LoadAddressOf(field, target.Instance);
- //if (!treatAsStatement) {
- // this.generator.Emit(OperationCode.Dup);
- // this.StackSize++;
- //}
- //this.generator.Emit(OperationCode.Initobj, field.Type);
- //if (!treatAsStatement)
- // this.generator.Emit(OperationCode.Ldobj, field.Type);
- //else
- // this.StackSize--;
- } else {
- Bpl.Expr x = null;
- Bpl.IdentifierExpr temp = null;
- if (pushTargetRValue) {
- if (target.Instance != null) {
- this.Traverse(target.Instance);
- x = this.TranslatedExpressions.Pop();
- AssertOrAssumeNonNull(tok, x);
- var e2 = this.sink.Heap.ReadHeap(x, f, TranslationHelper.IsStruct(field.ContainingType) ? AccessType.Struct : AccessType.Heap, boogieTypeOfField);
- this.TranslatedExpressions.Push(e2);
- } else {
- TranslatedExpressions.Push(f);
- }
-
- if (!treatAsStatement && resultIsInitialTargetRValue) {
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var e3 = this.TranslatedExpressions.Pop();
- var cmd = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(temp);
- }
- }
- sourceTraverser(source);
- if (!treatAsStatement && !resultIsInitialTargetRValue) {
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var e3 = this.TranslatedExpressions.Pop();
- var cmd = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(temp);
- }
-
- var e = this.TranslatedExpressions.Pop();
- if (temp != null) this.TranslatedExpressions.Push(temp);
-
- if (target.Instance == null) {
- // static fields are not kept in the heap
- StmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, f, e));
- } else {
- StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(tok, x, f, e,
- field.ResolvedField.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap,
- boogieTypeOfField));
- }
-
- }
- return;
- }
-
- VisitArrayIndexer:
-
- IArrayIndexer/*?*/ arrayIndexer = container as IArrayIndexer;
- if (arrayIndexer != null) {
- Contract.Assume(arrayIndexer.Indices.Count() == 1); // BUG: deal with multi-dimensional arrays
- if (source is IDefaultValue && !arrayIndexer.Type.ResolvedType.IsReferenceType) {
- // this.LoadAddressOf(arrayIndexer, target.Instance);
- // if (!treatAsStatement) {
- // this.generator.Emit(OperationCode.Dup);
- // this.StackSize++;
- // }
- // this.generator.Emit(OperationCode.Initobj, arrayIndexer.Type);
- // if (!treatAsStatement)
- // this.generator.Emit(OperationCode.Ldobj, arrayIndexer.Type);
- // else
- // this.StackSize--;
- } else {
- Bpl.IdentifierExpr/*?*/ temp = null;
- this.Traverse(arrayIndexer.IndexedObject);
- var arrayExpr = this.TranslatedExpressions.Peek();
- this.Traverse(arrayIndexer.Indices);
- var indexExpr = this.TranslatedExpressions.Peek();
- if (pushTargetRValue) {
- AssertOrAssumeNonNull(tok, arrayExpr);
- var e2 = this.sink.Heap.ReadHeap(arrayExpr, indexExpr, AccessType.Array, this.sink.CciTypeToBoogie(arrayIndexer.Type));
- this.TranslatedExpressions.Push(e2);
-
- if (!treatAsStatement && resultIsInitialTargetRValue) {
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var e3 = this.TranslatedExpressions.Pop();
- var cmd = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(temp);
- }
- }
- sourceTraverser(source);
-
- var e = this.TranslatedExpressions.Pop();
- var indices_prime = this.TranslatedExpressions.Pop();
- var x = this.TranslatedExpressions.Pop();
- StmtTraverser.StmtBuilder.Add(sink.Heap.WriteHeap(Bpl.Token.NoToken, x, indices_prime, e, AccessType.Array, sink.CciTypeToBoogie(arrayIndexer.Type)));
-
- if (!treatAsStatement && !resultIsInitialTargetRValue) {
- AssertOrAssumeNonNull(tok, arrayExpr);
- var e2 = this.sink.Heap.ReadHeap(arrayExpr, indexExpr, AccessType.Array, this.sink.CciTypeToBoogie(arrayIndexer.Type));
- this.TranslatedExpressions.Push(e2);
- } else {
- if (temp != null) this.TranslatedExpressions.Push(temp);
- }
- }
- return;
- }
- IAddressDereference/*?*/ addressDereference = container as IAddressDereference;
- if (addressDereference != null) {
- var addrOf = addressDereference.Address as IAddressOf;
- if (addrOf != null) {
- var arrayIndexer2 = addrOf.Expression.Definition as IArrayIndexer;
- if (arrayIndexer2 != null) {
- container = arrayIndexer2;
- goto VisitArrayIndexer;
- }
- }
- var be = addressDereference.Address as IBoundExpression;
- if (be != null) {
- container = be.Definition;
- goto Top;
- }
- this.Traverse(addressDereference.Address);
- if (source is IDefaultValue && !addressDereference.Type.ResolvedType.IsReferenceType) {
- //if (!treatAsStatement) {
- // this.generator.Emit(OperationCode.Dup);
- // this.StackSize++;
- //}
- //this.generator.Emit(OperationCode.Initobj, addressDereference.Type);
- //if (!treatAsStatement)
- // this.generator.Emit(OperationCode.Ldobj, addressDereference.Type);
- //else
- // this.StackSize--;
- } else if (source is IAddressDereference) {
- //if (!treatAsStatement) {
- // this.generator.Emit(OperationCode.Dup);
- // this.StackSize++;
- //}
- //this.Traverse(((IAddressDereference)source).Address);
- //this.generator.Emit(OperationCode.Cpobj, addressDereference.Type);
- //this.StackSize -= 2;
- //if (!treatAsStatement)
- // this.generator.Emit(OperationCode.Ldobj, addressDereference.Type);
- } else {
- Bpl.IdentifierExpr/*?*/ temp = null;
- if (pushTargetRValue) {
- this.TranslatedExpressions.Push(this.TranslatedExpressions.Peek());
- if (!treatAsStatement && resultIsInitialTargetRValue) {
- this.TranslatedExpressions.Push(this.TranslatedExpressions.Peek());
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var e3 = this.TranslatedExpressions.Pop();
- var cmd = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(temp);
- }
- }
- sourceTraverser(source);
- if (!treatAsStatement && !resultIsInitialTargetRValue) {
- this.TranslatedExpressions.Push(this.TranslatedExpressions.Peek());
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var e3 = this.TranslatedExpressions.Pop();
- var cmd = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(temp);
- }
- //this.VisitAssignmentTo(addressDereference);
- if (temp != null) this.TranslatedExpressions.Push(temp);
- }
- return;
- }
- IPropertyDefinition/*?*/ propertyDefinition = container as IPropertyDefinition;
- if (propertyDefinition != null) {
- Contract.Assume(propertyDefinition.Getter != null && propertyDefinition.Setter != null);
- if (!propertyDefinition.IsStatic) {
- this.Traverse(target.Instance);
- }
- Bpl.IdentifierExpr temp = null;
- var token = Bpl.Token.NoToken;
- if (pushTargetRValue) {
-
- List<Bpl.Expr> inexpr;
- List<Bpl.IdentifierExpr> outvars;
- Bpl.IdentifierExpr thisExpr;
- Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr, bool>> toBoxed;
- var proc2 = TranslateArgumentsAndReturnProcedure(token, propertyDefinition.Getter, propertyDefinition.Getter.ResolvedMethod, target.Instance, Enumerable<IExpression>.Empty, out inexpr, out outvars, out thisExpr, out toBoxed);
-
- EmitLineDirective(token);
-
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(token, proc2.Name, inexpr, outvars));
-
- if (!treatAsStatement && resultIsInitialTargetRValue) {
- //var
- //this.generator.Emit(OperationCode.Dup);
- //this.StackSize++;
- //temp = new TemporaryVariable(source.Type, this.method);
- //this.VisitAssignmentTo(temp);
- }
- }
- sourceTraverser(source);
- if (!treatAsStatement && !resultIsInitialTargetRValue) {
- var e3 = this.TranslatedExpressions.Pop();
- var loc = this.sink.CreateFreshLocal(source.Type);
- temp = Bpl.Expr.Ident(loc);
- var cmd = Bpl.Cmd.SimpleAssign(tok, temp, e3);
- this.StmtTraverser.StmtBuilder.Add(cmd);
- this.TranslatedExpressions.Push(temp);
- }
-
- var setterArgs = new List<Bpl.Expr>();
- var setterArg = this.TranslatedExpressions.Pop();
- if (!propertyDefinition.IsStatic)
- setterArgs.Add(this.TranslatedExpressions.Pop());
- setterArgs.Add(setterArg);
-
- var setterProc = this.sink.FindOrCreateProcedure(propertyDefinition.Setter.ResolvedMethod);
- EmitLineDirective(token);
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(token, setterProc.Decl.Name, setterArgs, new List<Bpl.IdentifierExpr>()));
-
- if (temp != null) this.TranslatedExpressions.Push(temp);
- return;
- }
- Contract.Assume(false);
- }
-
- #endregion
-
- #region Translate Object Creation
-
- /// <summary>
- /// For "new A(...)" generate "{ A a = Alloc(); A..ctor(a); return a; }" where
- /// "a" is a fresh local.
- /// </summary>
- public override void TraverseChildren(ICreateObjectInstance createObjectInstance)
- {
- var ctor = createObjectInstance.MethodToCall;
- var resolvedMethod = ResolveUnspecializedMethodOrThrow(ctor);
-
- Bpl.IToken token = createObjectInstance.Token();
-
- var a = this.sink.CreateFreshLocal(createObjectInstance.Type);
-
- if (createObjectInstance.Type.TypeCode == PrimitiveTypeCode.IntPtr ||
- createObjectInstance.Type.TypeCode == PrimitiveTypeCode.UIntPtr) {
- List<Bpl.Expr> args = new List<Bpl.Expr>();
- foreach (IExpression e in createObjectInstance.Arguments) {
- this.Traverse(e);
- args.Add(TranslatedExpressions.Pop());
- }
- System.Diagnostics.Debug.Assert(args.Count == 1);
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(a), args[0]));
- }
- else {
- // First generate an Alloc() call
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(token, this.sink.AllocationMethodName, new Bpl.ExprSeq(), new Bpl.IdentifierExprSeq(Bpl.Expr.Ident(a))));
-
- // Second, generate the call to the appropriate ctor
-
- List<Bpl.Expr> inexpr;
- List<Bpl.IdentifierExpr> outvars;
- Bpl.IdentifierExpr thisExpr;
- Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toBoxed;
- var proc = TranslateArgumentsAndReturnProcedure(token, ctor, resolvedMethod, null, createObjectInstance.Arguments, out inexpr, out outvars, out thisExpr, out toBoxed);
- inexpr.Insert(0, Bpl.Expr.Ident(a));
-
- EmitLineDirective(token);
-
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(token, proc.Name, inexpr, outvars));
-
- // Generate an assumption about the dynamic type of the just allocated object
- this.StmtTraverser.StmtBuilder.Add(
- new Bpl.AssumeCmd(token,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
- this.sink.Heap.DynamicType(Bpl.Expr.Ident(a)),
- this.FindOrCreateTypeReferenceInCodeContext(createObjectInstance.Type)
- )
- )
- );
- }
- TranslatedExpressions.Push(Bpl.Expr.Ident(a));
- }
-
- public override void TraverseChildren(ICreateArray createArrayInstance)
- {
- Bpl.IToken cloc = createArrayInstance.Token();
- var a = this.sink.CreateFreshLocal(createArrayInstance.Type);
-
- Debug.Assert(createArrayInstance.Rank > 0);
- Bpl.Expr lengthExpr = Bpl.Expr.Literal(1);
- foreach (IExpression expr in createArrayInstance.Sizes) {
- this.Traverse(expr);
- lengthExpr = Bpl.Expr.Mul(lengthExpr, TranslatedExpressions.Pop());
- }
-
- // First generate an Alloc() call
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(cloc, this.sink.AllocationMethodName, new Bpl.ExprSeq(), new Bpl.IdentifierExprSeq(Bpl.Expr.Ident(a))));
- Bpl.Expr assumeExpr = Bpl.Expr.Eq(new Bpl.NAryExpr(cloc, new Bpl.FunctionCall(this.sink.Heap.ArrayLengthFunction), new Bpl.ExprSeq(Bpl.Expr.Ident(a))), lengthExpr);
- this.StmtTraverser.StmtBuilder.Add(new Bpl.AssumeCmd(cloc, assumeExpr));
- TranslatedExpressions.Push(Bpl.Expr.Ident(a));
- }
-
- public override void TraverseChildren(ICreateDelegateInstance createDelegateInstance)
- {
- if (createDelegateInstance.Instance == null) {
- TranslatedExpressions.Push(Bpl.Expr.Literal(0));
- }
- else {
- this.Traverse(createDelegateInstance.Instance);
- }
-
- TranslateDelegateCreation(createDelegateInstance.MethodToCallViaDelegate, createDelegateInstance.Type, createDelegateInstance);
- }
-
- private void TranslateDelegateCreation(IMethodReference methodToCall, ITypeReference type, IExpression creationAST)
- {
- Bpl.IToken cloc = creationAST.Token();
- var a = this.sink.CreateFreshLocal(creationAST.Type);
-
- ITypeDefinition unspecializedType = Microsoft.Cci.MutableContracts.ContractHelper.Unspecialized(type.ResolvedType).ResolvedType;
- IMethodDefinition unspecializedMethod = ResolveUnspecializedMethodOrThrow(methodToCall);
- sink.AddDelegate(unspecializedType, unspecializedMethod);
- Bpl.Constant constant = sink.FindOrCreateDelegateMethodConstant(unspecializedMethod);
- Bpl.Expr methodExpr = Bpl.Expr.Ident(constant);
- Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
-
- Bpl.ExprSeq typeParameterExprs = new Bpl.ExprSeq();
-
- if (unspecializedMethod.IsStatic) {
- List<ITypeReference> consolidatedTypeArguments = new List<ITypeReference>();
- Sink.GetConsolidatedTypeArguments(consolidatedTypeArguments, methodToCall.ContainingType);
- foreach (ITypeReference typeReference in consolidatedTypeArguments) {
- typeParameterExprs.Add(this.FindOrCreateTypeReferenceInCodeContext(typeReference));
- }
- }
- IGenericMethodInstanceReference methodInstanceReference = methodToCall as IGenericMethodInstanceReference;
- if (methodInstanceReference != null) {
- foreach (ITypeReference typeReference in methodInstanceReference.GenericArguments) {
- typeParameterExprs.Add(this.FindOrCreateTypeReferenceInCodeContext(typeReference));
- }
- }
- Bpl.Expr typeParameterExpr =
- new Bpl.NAryExpr(Bpl.Token.NoToken,
- new Bpl.FunctionCall(this.sink.FindOrCreateNaryTypeFunction(typeParameterExprs.Length)),
- typeParameterExprs);
- this.StmtTraverser.StmtBuilder.Add(
- new Bpl.CallCmd(cloc, this.sink.DelegateCreateName,
- new Bpl.ExprSeq(this.sink.CreateDelegate(methodExpr, instanceExpr, typeParameterExpr)),
- new Bpl.IdentifierExprSeq(Bpl.Expr.Ident(a))));
- TranslatedExpressions.Push(Bpl.Expr.Ident(a));
- }
-
- #endregion
-
- #region Translate Binary Operators
-
- public override void TraverseChildren(IAddition addition)
- {
- var targetExpression = addition.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x += e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, addition, (IExpression e) => this.TraverseAdditionRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: addition.ResultIsUnmodifiedLeftOperand);
- } else { // x + e
- this.Traverse(addition.LeftOperand);
- this.TraverseAdditionRightOperandAndDoOperation(addition);
- }
- }
- private void TraverseAdditionRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IAddition);
- var addition = (IAddition)expression;
- this.Traverse(addition.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
-
- Bpl.Expr e;
- switch (addition.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- addition.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealPlus),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Add, lexp, rexp);
- break;
- }
- TranslatedExpressions.Push(e);
- }
-
-
- public override void TraverseChildren(IBitwiseAnd bitwiseAnd) {
- var targetExpression = bitwiseAnd.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x &= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, bitwiseAnd, (IExpression e) => this.TraverseBitwiseAndRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: bitwiseAnd.ResultIsUnmodifiedLeftOperand);
- } else { // x & e
- this.Traverse(bitwiseAnd.LeftOperand);
- this.TraverseBitwiseAndRightOperandAndDoOperation(bitwiseAnd);
- }
- }
- private void TraverseBitwiseAndRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IBitwiseAnd);
- var bitwiseAnd = (IBitwiseAnd)expression;
-
- this.Traverse(bitwiseAnd.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e;
- if (bitwiseAnd.Type.TypeCode == PrimitiveTypeCode.Boolean) {
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, lexp, rexp);
- }
- else {
- if (lexp.Type != Bpl.Type.Int || rexp.Type != Bpl.Type.Int)
- throw new TranslationException("BitwiseAnd called in a non-boolean context, but at least one argument is not an integer!");
- e = new Bpl.NAryExpr(
- bitwiseAnd.Token(),
- new Bpl.FunctionCall(this.sink.Heap.BitwiseAnd),
- new Bpl.ExprSeq(lexp, rexp)
- );
- }
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IBitwiseOr bitwiseOr) {
- var targetExpression = bitwiseOr.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x |= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, bitwiseOr, (IExpression e) => this.TraverseBitwiseOrRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: bitwiseOr.ResultIsUnmodifiedLeftOperand);
- } else { // x | e
- this.Traverse(bitwiseOr.LeftOperand);
- this.TraverseBitwiseOrRightOperandAndDoOperation(bitwiseOr);
- }
- }
-
- private void TraverseBitwiseOrRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IBitwiseOr);
- var bitwiseOr = (IBitwiseOr)expression;
- this.Traverse(bitwiseOr.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e;
- if (bitwiseOr.Type.TypeCode == PrimitiveTypeCode.Boolean) {
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, lexp, rexp);
- }
- else {
- e = new Bpl.NAryExpr(
- bitwiseOr.Token(),
- new Bpl.FunctionCall(this.sink.Heap.BitwiseOr),
- new Bpl.ExprSeq(lexp, rexp)
- );
- }
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IModulus modulus) {
- var targetExpression = modulus.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x %= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, modulus, (IExpression e) => this.TraverseModulusRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: modulus.ResultIsUnmodifiedLeftOperand);
- } else { // x % e
- this.Traverse(modulus.LeftOperand);
- this.TraverseModulusRightOperandAndDoOperation(modulus);
- }
- }
-
- private void TraverseModulusRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IModulus);
- var modulus = (IModulus)expression;
- this.Traverse(modulus.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e;
- switch (modulus.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- modulus.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealModulus),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Mod, lexp, rexp);
- break;
- }
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IDivision division)
- {
- var targetExpression = division.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x /= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, division, (IExpression e) => this.TraverseDivisionRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: division.ResultIsUnmodifiedLeftOperand);
- } else { // x / e
- this.Traverse(division.LeftOperand);
- this.TraverseDivisionRightOperandAndDoOperation(division);
- }
- }
-
- private void TraverseDivisionRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IDivision);
- var division = (IDivision)expression;
- this.Traverse(division.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e;
- switch (division.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- division.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealDivide),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Div, lexp, rexp);
- break;
- }
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IExclusiveOr exclusiveOr) {
- var targetExpression = exclusiveOr.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x ^= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, exclusiveOr, (IExpression e) => this.TraverseExclusiveOrRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: exclusiveOr.ResultIsUnmodifiedLeftOperand);
- } else { // x ^ e
- this.Traverse(exclusiveOr.LeftOperand);
- this.TraverseExclusiveOrRightOperandAndDoOperation(exclusiveOr);
- }
- }
-
- private void TraverseExclusiveOrRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IExclusiveOr);
- var exclusiveOr = (IExclusiveOr)expression;
- this.Traverse(exclusiveOr.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- var e = new Bpl.NAryExpr(
- exclusiveOr.Token(),
- new Bpl.FunctionCall(this.sink.Heap.BitwiseExclusiveOr),
- new Bpl.ExprSeq(lexp, rexp)
- );
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(ISubtraction subtraction)
- {
- var targetExpression = subtraction.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x -= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, subtraction, (IExpression e) => this.TraverseSubtractionRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: subtraction.ResultIsUnmodifiedLeftOperand);
- } else { // x - e
- this.Traverse(subtraction.LeftOperand);
- this.TraverseSubtractionRightOperandAndDoOperation(subtraction);
- }
- }
- private void TraverseSubtractionRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is ISubtraction);
- var subtraction = (ISubtraction)expression;
-
- this.Traverse(subtraction.RightOperand);
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e;
- switch (subtraction.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- subtraction.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealMinus),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Sub, lexp, rexp);
- break;
- }
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IMultiplication multiplication)
- {
- var targetExpression = multiplication.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x *= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, multiplication, (IExpression e) => this.TraverseMultiplicationRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: multiplication.ResultIsUnmodifiedLeftOperand);
- } else { // x * e
- this.Traverse(multiplication.LeftOperand);
- this.TraverseMultiplicationRightOperandAndDoOperation(multiplication);
- }
- }
-
- private void TraverseMultiplicationRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IMultiplication);
- var multiplication = (IMultiplication)expression;
- this.Traverse(multiplication.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e;
- switch (multiplication.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- multiplication.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealTimes),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Mul, lexp, rexp);
- break;
- }
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IGreaterThan greaterThan)
- {
- base.TraverseChildren(greaterThan);
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
-
- Bpl.Expr e;
- switch (greaterThan.LeftOperand.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- greaterThan.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealGreaterThan),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Gt, lexp, rexp);
- break;
- }
-
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IGreaterThanOrEqual greaterEqual)
- {
- base.TraverseChildren(greaterEqual);
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
-
- Bpl.Expr e;
- switch (greaterEqual.LeftOperand.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- greaterEqual.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealGreaterThanOrEqual),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Ge, lexp, rexp);
- break;
- }
-
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(ILessThan lessThan)
- {
- base.TraverseChildren(lessThan);
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
-
- Bpl.Expr e;
- switch (lessThan.LeftOperand.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- lessThan.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealLessThan),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Lt, lexp, rexp);
- break;
- }
-
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(ILessThanOrEqual lessEqual)
- {
- base.TraverseChildren(lessEqual);
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
-
- Bpl.Expr e;
- switch (lessEqual.LeftOperand.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- lessEqual.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealLessThanOrEqual),
- new Bpl.ExprSeq(lexp, rexp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Le, lexp, rexp);
- break;
- }
-
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IEquality equal)
- {
- if ((equal.LeftOperand.Type.TypeCode != PrimitiveTypeCode.NotPrimitive || equal.RightOperand.Type.TypeCode != PrimitiveTypeCode.NotPrimitive)
- && !TypeHelper.TypesAreEquivalent(equal.LeftOperand.Type, equal.RightOperand.Type)
- && (!(IsConstantNull(equal.LeftOperand) || IsConstantNull(equal.RightOperand))) // null is "polymorphic": it can be compared against any reference type.
- ) {
- throw new TranslationException(
- String.Format("Decompiler messed up: equality's left operand is of type '{0}' but right operand is of type '{1}'.",
- TypeHelper.GetTypeName(equal.LeftOperand.Type),
- TypeHelper.GetTypeName(equal.RightOperand.Type)
- ));
- }
-
- base.TraverseChildren(equal);
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, lexp, rexp));
- }
-
- private bool IsConstantNull(IExpression iExpression) {
- var ctc = iExpression as ICompileTimeConstant;
- if (ctc == null) return false;
- return ctc.Value == null;
- }
-
- public override void TraverseChildren(INotEquality nonEqual)
- {
-
- if ((nonEqual.LeftOperand.Type.TypeCode != PrimitiveTypeCode.NotPrimitive || nonEqual.RightOperand.Type.TypeCode != PrimitiveTypeCode.NotPrimitive)
- &&
- !TypeHelper.TypesAreEquivalent(nonEqual.LeftOperand.Type, nonEqual.RightOperand.Type)
- && (!(IsConstantNull(nonEqual.LeftOperand) || IsConstantNull(nonEqual.RightOperand))) // null is "polymorphic": it can be compared against any reference type.
- ) {
- throw new TranslationException(
- String.Format("Decompiler messed up: inequality's left operand is of type '{0}' but right operand is of type '{1}'.",
- TypeHelper.GetTypeName(nonEqual.LeftOperand.Type),
- TypeHelper.GetTypeName(nonEqual.RightOperand.Type)
- ));
- }
-
- base.TraverseChildren(nonEqual);
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, lexp, rexp));
- }
-
- public override void TraverseChildren(IRightShift rightShift) {
- var targetExpression = rightShift.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x >>= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, rightShift, (IExpression e) => this.TraverseRightShiftRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: rightShift.ResultIsUnmodifiedLeftOperand);
- } else { // x >> e
- this.Traverse(rightShift.LeftOperand);
- this.TraverseRightShiftRightOperandAndDoOperation(rightShift);
- }
- }
-
- private void TraverseRightShiftRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is IRightShift);
- var rightShift = (IRightShift)expression;
- this.Traverse(rightShift.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e = new Bpl.NAryExpr(
- rightShift.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RightShift),
- new Bpl.ExprSeq(lexp, rexp)
- );
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(ILeftShift leftShift) {
- var targetExpression = leftShift.LeftOperand as ITargetExpression;
- if (targetExpression != null) { // x <<= e
- bool statement = this.currentExpressionIsOpAssignStatement;
- this.currentExpressionIsOpAssignStatement = false;
- this.VisitAssignment(targetExpression, leftShift, (IExpression e) => this.TraverseLeftShiftRightOperandAndDoOperation(e),
- treatAsStatement: statement, pushTargetRValue: true, resultIsInitialTargetRValue: leftShift.ResultIsUnmodifiedLeftOperand);
- } else { // x << e
- this.Traverse(leftShift.LeftOperand);
- this.TraverseLeftShiftRightOperandAndDoOperation(leftShift);
- }
- }
-
- private void TraverseLeftShiftRightOperandAndDoOperation(IExpression expression) {
- Contract.Assume(expression is ILeftShift);
- var leftShift = (ILeftShift)expression;
- this.Traverse(leftShift.RightOperand);
-
- Bpl.Expr rexp = TranslatedExpressions.Pop();
- Bpl.Expr lexp = TranslatedExpressions.Pop();
- Bpl.Expr e = new Bpl.NAryExpr(
- leftShift.Token(),
- new Bpl.FunctionCall(this.sink.Heap.LeftShift),
- new Bpl.ExprSeq(lexp, rexp)
- );
- TranslatedExpressions.Push(e);
- }
- /// <summary>
- /// There aren't any logical-and expressions or logical-or expressions in CCI.
- /// Instead they are encoded as "x ? y : 0" for "x && y" and "x ? 1 : y"
- /// for "x || y".
- /// TODO:
- /// If it isn't either of these short forms then emit the proper expression!
- /// </summary>
- public override void TraverseChildren(IConditional conditional) {
- /*
- #region Try and reconstruct And, Or, Not expressions
- if (conditional.Type.TypeCode == PrimitiveTypeCode.Boolean) {
- CompileTimeConstant ctc = conditional.ResultIfFalse as CompileTimeConstant;
- if (ctc != null) {
- var v = BooleanValueOfCompileTimeConstant(ctc);
- if (!v) { // x ? y : "false or 0" == x && y
- Visit(conditional.Condition);
- Bpl.Expr x = TranslatedExpressions.Pop();
- x = PossiblyCoerceRefToBool(x);
- Visit(conditional.ResultIfTrue);
- Bpl.Expr y = TranslatedExpressions.Pop();
- y = PossiblyCoerceRefToBool(y);
- TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, x, y));
- return;
- } else { // x ? y : "true or 1" == !x || y
- Visit(conditional.Condition);
- Bpl.Expr x = TranslatedExpressions.Pop();
- x = PossiblyCoerceRefToBool(x);
- Visit(conditional.ResultIfTrue);
- Bpl.Expr y = TranslatedExpressions.Pop();
- y = PossiblyCoerceRefToBool(y);
- var notX = Bpl.Expr.Unary(conditional.Token(), Bpl.UnaryOperator.Opcode.Not, x);
- TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, notX, y));
- return;
- }
- }
- ctc = conditional.ResultIfTrue as CompileTimeConstant;
- if (ctc != null && ctc.Type == BCT.Host.PlatformType.SystemInt32) {
- var v = BooleanValueOfCompileTimeConstant(ctc);
- if (v) { // x ? "true or 1" : y == x || y
- Visit(conditional.Condition);
- Bpl.Expr x = TranslatedExpressions.Pop();
- x = PossiblyCoerceRefToBool(x);
- Visit(conditional.ResultIfFalse);
- Bpl.Expr y = TranslatedExpressions.Pop();
- y = PossiblyCoerceRefToBool(y);
- TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, x, y));
- return;
- } else { // x ? "false or 0" : y == !x && y
- Visit(conditional.Condition);
- Bpl.Expr x = TranslatedExpressions.Pop();
- x = PossiblyCoerceRefToBool(x);
- Visit(conditional.ResultIfFalse);
- Bpl.Expr y = TranslatedExpressions.Pop();
- y = PossiblyCoerceRefToBool(y);
- var notX = Bpl.Expr.Unary(conditional.Token(), Bpl.UnaryOperator.Opcode.Not, x);
- TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, notX, y));
- return;
- }
- }
- }
- #endregion
-
- #region Just translate it as an if-then-else expression
- base.Visit(conditional);
- var ifFalse = TranslatedExpressions.Pop();
- var ifTrue = TranslatedExpressions.Pop();
- var c = TranslatedExpressions.Pop();
- var tok = conditional.Token();
- TranslatedExpressions.Push(
- new Bpl.NAryExpr(tok, new Bpl.IfThenElse(tok), new Bpl.ExprSeq(c, ifTrue, ifFalse))
- );
- return;
- #endregion
- */
-
-
- // TODO is this code actually needed at all? It seems that all this is already being done in the Statement traverser for the conditional
- StatementTraverser thenStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext);
- StatementTraverser elseStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext);
- ExpressionTraverser thenExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, thenStmtTraverser, this.contractContext);
- ExpressionTraverser elseExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, elseStmtTraverser, this.contractContext);
- thenExprTraverser.Traverse(conditional.ResultIfTrue);
- elseExprTraverser.Traverse(conditional.ResultIfFalse);
-
- this.Traverse(conditional.Condition);
- Bpl.Expr conditionExpr = this.TranslatedExpressions.Pop();
-
- Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditional.Token(),
- conditionExpr,
- thenStmtTraverser.StmtBuilder.Collect(conditional.ResultIfTrue.Token()),
- null,
- elseStmtTraverser.StmtBuilder.Collect(conditional.ResultIfFalse.Token())
- );
-
- this.StmtTraverser.StmtBuilder.Add(ifcmd);
-
- var ifFalse = elseExprTraverser.TranslatedExpressions.Pop();
- var ifTrue = thenExprTraverser.TranslatedExpressions.Pop();
- TranslatedExpressions.Push(new Bpl.NAryExpr(conditional.Token(), new Bpl.IfThenElse(conditional.Token()), new Bpl.ExprSeq(conditionExpr, ifTrue, ifFalse)));
- }
-
- private bool BooleanValueOfCompileTimeConstant(CompileTimeConstant ctc) {
- if (ctc.Type.TypeCode == PrimitiveTypeCode.Int32)
- return ((int)ctc.Value) != 0;
- if (ctc.Type.TypeCode == PrimitiveTypeCode.Boolean)
- return (bool)ctc.Value;
- throw new NotImplementedException("BooleanValueOfCompileTimeConstant: Unknown type of compile-time constant");
- }
-
- /// <summary>
- /// Sometimes the decompiler doesn't recreate the expression "o != null" when the
- /// IL tests an object for being null by just branching on the object instead of
- /// doing a ceq operation on the constant null.
- /// </summary>
- /// <returns>
- /// If o is not of type Ref, then it just returns o, otherwise it returns
- /// the expression "o != null".
- /// </returns>
- private Bpl.Expr PossiblyCoerceRefToBool(Bpl.Expr o) {
- if (o.Type != this.sink.Heap.RefType) return o;
- return Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, o, Bpl.Expr.Ident(this.sink.Heap.NullRef));
- }
-
- #endregion
-
- #region Translate Unary Operators
-
- public override void TraverseChildren(ICastIfPossible castIfPossible) {
- base.Traverse(castIfPossible.ValueToCast);
- var exp = TranslatedExpressions.Pop();
- var e = this.FindOrCreateTypeReferenceInCodeContext(castIfPossible.TargetType);
- var callAs = new Bpl.NAryExpr(
- castIfPossible.Token(),
- new Bpl.FunctionCall(this.sink.Heap.AsFunction),
- new Bpl.ExprSeq(exp, e)
- );
- TranslatedExpressions.Push(callAs);
- return;
- }
- public override void TraverseChildren(ICheckIfInstance checkIfInstance) {
- var e = this.FindOrCreateTypeReferenceInCodeContext(checkIfInstance.TypeToCheck);
- //var callTypeOf = new Bpl.NAryExpr(
- // checkIfInstance.Token(),
- // new Bpl.FunctionCall(this.sink.Heap.TypeOfFunction),
- // new Bpl.ExprSeq(new Bpl.IdentifierExpr(checkIfInstance.Token(), v))
- // );
- base.Traverse(checkIfInstance.Operand);
- var exp = TranslatedExpressions.Pop();
- var dynTypeOfOperand = this.sink.Heap.DynamicType(exp);
- //var subtype = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Subtype, dynTypeOfOperand, e);
- var subtype = new Bpl.NAryExpr(
- Bpl.Token.NoToken,
- new Bpl.FunctionCall(this.sink.Heap.Subtype),
- new Bpl.ExprSeq(dynTypeOfOperand, e)
- );
- var notnull = Bpl.Expr.Neq(exp, Bpl.Expr.Ident(this.sink.Heap.NullRef));
- var and = Bpl.Expr.And(notnull, subtype);
- TranslatedExpressions.Push(and);
- return;
- }
-
- public override void TraverseChildren(IConversion conversion) {
- var tok = conversion.ValueToConvert.Token();
- this.Traverse(conversion.ValueToConvert);
- var boogieTypeOfValue = this.sink.CciTypeToBoogie(conversion.ValueToConvert.Type);
- var boogieTypeToBeConvertedTo = this.sink.CciTypeToBoogie(conversion.TypeAfterConversion);
- if (boogieTypeOfValue == boogieTypeToBeConvertedTo && !TranslationHelper.IsStruct(conversion.ValueToConvert.Type)
- && !TranslationHelper.IsStruct(conversion.TypeAfterConversion)) {
- // then this conversion is a nop, just ignore it
- return;
- }
- var nameOfTypeToConvert = TypeHelper.GetTypeName(conversion.ValueToConvert.Type);
- var nameOfTypeToBeConvertedTo = TypeHelper.GetTypeName(conversion.TypeAfterConversion);
- var msg = String.Format("Can't convert '{0}' to '{1}'", nameOfTypeToConvert, nameOfTypeToBeConvertedTo);
-
- var exp = TranslatedExpressions.Pop();
-
- if (boogieTypeOfValue == this.sink.Heap.UnionType && boogieTypeToBeConvertedTo != this.sink.Heap.RefType) {
- var e = this.sink.Heap.FromUnion(tok, boogieTypeToBeConvertedTo, exp);
- TranslatedExpressions.Push(e);
- return;
- }
- if (boogieTypeToBeConvertedTo == this.sink.Heap.UnionType) {
- Bpl.Expr e;
- if (boogieTypeOfValue == this.sink.Heap.RefType)
- e = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Unbox2Union), new Bpl.ExprSeq(exp));
- else
- e = this.sink.Heap.ToUnion(tok, boogieTypeOfValue, exp);
- TranslatedExpressions.Push(e);
- return;
- }
-
- if (boogieTypeToBeConvertedTo == this.sink.Heap.RefType &&
- TranslationHelper.IsStruct(conversion.TypeAfterConversion) &&
- boogieTypeOfValue == this.sink.Heap.RefType) {
- // REVIEW: This also applies to conversions from one struct type to another!
- var e = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Unbox2Struct), new Bpl.ExprSeq(exp));
- TranslatedExpressions.Push(e);
- return;
- }
-
- if (boogieTypeToBeConvertedTo == Bpl.Type.Bool) {
- Bpl.Expr expr;
- if (boogieTypeOfValue == Bpl.Type.Int) {
- expr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, exp, Bpl.Expr.Literal(0));
- }
- else if (boogieTypeOfValue == this.sink.Heap.RefType) {
- expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Unbox2Bool), new Bpl.ExprSeq(exp));
- }
- else if (boogieTypeOfValue == this.sink.Heap.RealType) {
- expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Real2Int), new Bpl.ExprSeq(exp));
- expr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, expr, Bpl.Expr.Literal(0));
- }
- else if (boogieTypeOfValue == this.sink.Heap.UnionType) {
- expr = this.sink.Heap.FromUnion(tok, Bpl.Type.Bool, exp);
- }
- else {
- throw new NotImplementedException(msg);
- }
- TranslatedExpressions.Push(expr);
- return;
- }
-
- if (boogieTypeToBeConvertedTo == Bpl.Type.Int) {
- Bpl.Expr expr;
- if (boogieTypeOfValue == Bpl.Type.Bool) {
- expr = new Bpl.NAryExpr(tok, new Bpl.IfThenElse(tok), new Bpl.ExprSeq(exp, Bpl.Expr.Literal(1), Bpl.Expr.Literal(0)));
- }
- else if (boogieTypeOfValue == this.sink.Heap.RefType) {
- expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Unbox2Int), new Bpl.ExprSeq(exp));
- }
- else if (boogieTypeOfValue == this.sink.Heap.RealType) {
- expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Real2Int), new Bpl.ExprSeq(exp));
- }
- else if (boogieTypeOfValue == this.sink.Heap.UnionType) {
- expr = this.sink.Heap.FromUnion(Bpl.Token.NoToken, Bpl.Type.Int, exp);
- }
- else {
- throw new NotImplementedException(msg);
- }
- TranslatedExpressions.Push(expr);
- return;
- }
-
- if (boogieTypeToBeConvertedTo == this.sink.Heap.RefType) {
- // var a = BoxFromXXX(exp);
- Bpl.Variable a = this.sink.CreateFreshLocal(conversion.TypeAfterConversion);
- Bpl.Procedure boxOperator;
- if (boogieTypeOfValue == Bpl.Type.Bool)
- boxOperator = this.sink.Heap.BoxFromBool;
- else if (boogieTypeOfValue == Bpl.Type.Int)
- boxOperator = this.sink.Heap.BoxFromInt;
- else if (boogieTypeOfValue == this.sink.Heap.RealType)
- boxOperator = this.sink.Heap.BoxFromReal;
- else if (TranslationHelper.IsStruct(conversion.ValueToConvert.Type)) {
- // Boxing a struct implicitly makes a copy of the struct
- var typeOfValue = conversion.ValueToConvert.Type;
- var proc = this.sink.FindOrCreateProcedureForStructCopy(typeOfValue);
- var bplLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(typeOfValue));
- var cmd = new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr> { exp, }, new List<Bpl.IdentifierExpr> { bplLocal, });
- this.StmtTraverser.StmtBuilder.Add(cmd);
- exp = bplLocal;
- boxOperator = this.sink.Heap.BoxFromStruct;
- } else {
- if (boogieTypeOfValue != this.sink.Heap.UnionType)
- throw new NotImplementedException(msg);
- boxOperator = this.sink.Heap.BoxFromUnion;
- }
- var name = boxOperator.Name;
-
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, name, new Bpl.ExprSeq(exp), new Bpl.IdentifierExprSeq(Bpl.Expr.Ident(a))));
- TranslatedExpressions.Push(Bpl.Expr.Ident(a));
- return;
- }
-
- if (boogieTypeToBeConvertedTo == this.sink.Heap.RealType) {
- Bpl.Expr expr;
- if (boogieTypeOfValue == Bpl.Type.Bool) {
- expr = new Bpl.NAryExpr(tok, new Bpl.IfThenElse(tok), new Bpl.ExprSeq(exp, Bpl.Expr.Literal(1), Bpl.Expr.Literal(0)));
- expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Int2Real), new Bpl.ExprSeq(expr));
- }
- else if (boogieTypeOfValue == Bpl.Type.Int) {
- expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Int2Real), new Bpl.ExprSeq(exp));
- }
- else if (boogieTypeOfValue == this.sink.Heap.RefType) {
- expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Unbox2Real), new Bpl.ExprSeq(exp));
- }
- else if (boogieTypeOfValue == this.sink.Heap.UnionType) {
- expr = this.sink.Heap.FromUnion(tok, this.sink.Heap.RealType, exp);
- }
- else {
- throw new NotImplementedException(msg);
- }
- TranslatedExpressions.Push(expr);
- return;
- }
-
- //if (boogieTypeToBeConvertedTo == this.sink.Heap.UnionType) {
- // Bpl.Function func;
- // if (boogieTypeOfValue == Bpl.Type.Bool) {
- // func = this.sink.Heap.Bool2Union;
- // }
- // else if (boogieTypeOfValue == Bpl.Type.Int) {
- // func = this.sink.Heap.Int2Union;
- // }
- // else if (boogieTypeOfValue == this.sink.Heap.RefType) {
- // func = this.sink.Heap.Ref2Union;
- // }
- // else if (boogieTypeOfValue == this.sink.Heap.RealType) {
- // func = this.sink.Heap.Real2Union;
- // }
- // else {
- // throw new NotImplementedException(msg);
- // }
- // var boxExpr = new Bpl.NAryExpr(conversion.Token(), new Bpl.FunctionCall(func), new Bpl.ExprSeq(exp));
- // TranslatedExpressions.Push(boxExpr);
- // return;
- //}
- }
-
- public override void TraverseChildren(IOnesComplement onesComplement) {
- base.TraverseChildren(onesComplement);
- var exp = TranslatedExpressions.Pop();
- var e = new Bpl.NAryExpr(
- onesComplement.Token(),
- new Bpl.FunctionCall(this.sink.Heap.BitwiseNegation),
- new Bpl.ExprSeq(exp)
- );
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(IUnaryNegation unaryNegation)
- {
- base.TraverseChildren(unaryNegation);
- Bpl.Expr exp = TranslatedExpressions.Pop();
- Bpl.Expr e, zero, realZero;
- zero = Bpl.Expr.Literal(0);
- realZero = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Int2Real), new Bpl.ExprSeq(zero));
- switch (unaryNegation.Type.TypeCode) {
- case PrimitiveTypeCode.Float32:
- case PrimitiveTypeCode.Float64:
- e = new Bpl.NAryExpr(
- unaryNegation.Token(),
- new Bpl.FunctionCall(this.sink.Heap.RealMinus),
- new Bpl.ExprSeq(realZero, exp)
- );
- break;
- default:
- e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Sub, Bpl.Expr.Literal(0), exp);
- break;
- }
- TranslatedExpressions.Push(e);
- }
-
- public override void TraverseChildren(ILogicalNot logicalNot)
- {
- base.Traverse(logicalNot.Operand);
- Bpl.Expr exp = TranslatedExpressions.Pop();
- Bpl.Type operandType = this.sink.CciTypeToBoogie(logicalNot.Operand.Type);
- if (operandType == this.sink.Heap.RefType) {
- exp = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, exp, Bpl.Expr.Ident(this.sink.Heap.NullRef));
- }
- else if (operandType == Bpl.Type.Int) {
- exp = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, exp, Bpl.Expr.Literal(0));
- }
- else {
- //System.Diagnostics.Debug.Assert(operandType == Bpl.Type.Bool);
- }
- TranslatedExpressions.Push(Bpl.Expr.Unary(
- logicalNot.Token(),
- Bpl.UnaryOperator.Opcode.Not, exp));
- }
-
- public override void TraverseChildren(ITypeOf typeOf) {
- var e = this.FindOrCreateTypeReferenceInCodeContext(typeOf.TypeToGet);
- var callTypeOf = new Bpl.NAryExpr(
- typeOf.Token(),
- new Bpl.FunctionCall(this.sink.Heap.TypeOfFunction),
- new Bpl.ExprSeq(e)
- );
- TranslatedExpressions.Push(callTypeOf);
- }
-
- public override void TraverseChildren(IVectorLength vectorLength) {
- base.Traverse(vectorLength.Vector);
- var e = TranslatedExpressions.Pop();
- TranslatedExpressions.Push(new Bpl.NAryExpr(vectorLength.Token(), new Bpl.FunctionCall(this.sink.Heap.ArrayLengthFunction), new Bpl.ExprSeq(e)));
- }
-
- #endregion
-
- #region CodeContract Expressions
- public override void TraverseChildren(IOldValue oldValue)
- {
- base.TraverseChildren(oldValue);
- TranslatedExpressions.Push(new Bpl.OldExpr(oldValue.Token(),
- TranslatedExpressions.Pop()));
- }
-
- public override void TraverseChildren(IReturnValue returnValue)
- {
- if (this.sink.ReturnVariable == null)
- {
- throw new TranslationException(String.Format("Don't know what to do with return value {0}", returnValue.ToString()));
- }
- TranslatedExpressions.Push(new Bpl.IdentifierExpr(returnValue.Token(),
- this.sink.ReturnVariable));
-
- }
- #endregion
-
- public override void TraverseChildren(IBlockExpression blockExpression) {
- this.StmtTraverser.Traverse(blockExpression.BlockStatement);
- this.Traverse(blockExpression.Expression);
- }
-
- /// <summary>
- /// This is a rewriter so it must be used on a mutable Code Model!!!
- /// </summary>
- private class ExpressionSimplifier : CodeRewriter {
-
- Sink sink;
-
- private ExpressionSimplifier(Sink sink)
- : base(sink.host) {
- this.sink = sink;
- }
-
- public static IExpression Simplify(Sink sink, IExpression expression) {
- var a = new ExpressionSimplifier(sink);
- return a.Rewrite(expression);
- }
-
- public override IExpression Rewrite(IBoundExpression boundExpression) {
-
- if (boundExpression.Instance == null || ExpressionTraverser.IsAtomicInstance(boundExpression.Instance)) return boundExpression;
-
- // boundExpression == BE(inst, def), i.e., inst.def
- // return { loc := e; [assert loc != null;] | BE(BE(null,loc), def) }, i.e., "loc := e; loc.def"
- // where e is the rewritten inst
-
- var e = base.Rewrite(boundExpression.Instance);
-
- var loc = new LocalDefinition() {
- Name = this.host.NameTable.GetNameFor("_loc" + this.sink.LocalCounter.ToString()),
- Type = e.Type,
- };
- var locDecl = new LocalDeclarationStatement() {
- InitialValue = e,
- LocalVariable = loc,
- };
- return new BlockExpression() {
- BlockStatement = new BlockStatement() {
- Statements = new List<IStatement> { locDecl },
- },
- Expression = new BoundExpression() {
- Definition = boundExpression.Definition,
- Instance = new BoundExpression() {
- Definition = loc,
- Instance = null,
- Type = loc.Type,
- },
- Type = boundExpression.Type,
- },
- };
-
- }
-
- public override IExpression Rewrite(IArrayIndexer arrayIndexer) {
- if (ExpressionTraverser.IsAtomicInstance(arrayIndexer.IndexedObject)) return arrayIndexer;
-
- // arrayIndexer == AI(inst, [index]), i.e., inst[index0, index1,...]
- // return { loc := e; [assert loc != null;] | AI(BE(null,loc), [index]) }
- // where e is the rewritten array instance
-
- var e = base.Rewrite(arrayIndexer.IndexedObject);
-
- var loc = new LocalDefinition() {
- Name = this.host.NameTable.GetNameFor("_loc" + this.sink.LocalCounter.ToString()),
- Type = e.Type
- };
- var locDecl = new LocalDeclarationStatement() {
- InitialValue = e,
- LocalVariable = loc,
- };
- return new BlockExpression() {
- BlockStatement = new BlockStatement() {
- Statements = new List<IStatement> { locDecl },
- },
- Expression = new ArrayIndexer() {
- IndexedObject = new BoundExpression() {
- Definition = loc,
- Instance = null,
- Type = loc.Type,
- },
- Indices = new List<IExpression>(arrayIndexer.Indices),
- Type = arrayIndexer.Type,
- },
- };
- }
-
- public override ITargetExpression Rewrite(ITargetExpression targetExpression) {
- Contract.Assume(false, "The expression containing this as a subexpression should never allow a call to this routine.");
- return null;
- }
-
- }
- }
-
-}
diff --git a/BCT/BytecodeTranslator/Heap.cs b/BCT/BytecodeTranslator/Heap.cs
deleted file mode 100644
index 731d5e66..00000000
--- a/BCT/BytecodeTranslator/Heap.cs
+++ /dev/null
@@ -1,349 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using System.IO;
-using System.Reflection;
-
-
-namespace BytecodeTranslator {
-
- /// <summary>
- /// A heap representation that uses a separate global variable for each
- /// field. Each global variable is a map from int to T where T is the
- /// type of the field.
- /// </summary>
- public class SplitFieldsHeap : Heap {
-
- /// <summary>
- /// Prelude text for which access to the ASTs is not needed
- /// </summary>
- private readonly string InitialPreludeText = @"";
-
- private Sink sink;
-
- public override bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program) {
- heap = this;
- program = null;
- this.sink = sink;
- string prelude = this.InitialPreludeText + this.CommonText;
- var b = RepresentationFor.ParsePrelude(prelude, this, out program);
- if (b) {
- this.UnionType = new Bpl.CtorType(this.UnionTypeDecl.tok, this.UnionTypeDecl, new Bpl.TypeSeq());
- this.DelegateType = new Bpl.CtorType(this.DelegateTypeDecl.tok, this.DelegateTypeDecl, new Bpl.TypeSeq());
- this.DelegateMultisetType = new Bpl.TypeSynonymAnnotation(this.DelegateMultisetTypeDecl.tok, this.DelegateMultisetTypeDecl, new Bpl.TypeSeq());
- this.FieldType = new Bpl.CtorType(this.FieldTypeDecl.tok, this.FieldTypeDecl, new Bpl.TypeSeq());
- this.TypeType = new Bpl.CtorType(this.TypeTypeDecl.tok, this.TypeTypeDecl, new Bpl.TypeSeq());
- this.RefType = new Bpl.CtorType(this.RefTypeDecl.tok, this.RefTypeDecl, new Bpl.TypeSeq());
- this.RealType = new Bpl.CtorType(this.RealTypeDecl.tok, this.RealTypeDecl, new Bpl.TypeSeq());
- }
- return b;
- }
-
- /// <summary>
- /// Creates a fresh BPL variable to represent <paramref name="field"/>, deciding
- /// on its type based on the heap representation.
- /// </summary>
- public override Bpl.Variable CreateFieldVariable(IFieldReference field) {
- Bpl.Variable v;
- string fieldname = MemberHelper.GetMemberSignature(field, NameFormattingOptions.DocumentationId);
-
- fieldname = TranslationHelper.TurnStringIntoValidIdentifier(fieldname);
- Bpl.IToken tok = field.Token();
- Bpl.Type t = this.sink.CciTypeToBoogie(field.Type.ResolvedType);
-
- if (field.ResolvedField.IsStatic) {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.Type mt = new Bpl.MapType(tok, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(this.RefType), t);
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, mt);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- return v;
- }
-
- public override Bpl.Variable CreateEventVariable(IEventDefinition e) {
- Bpl.Variable v;
- string fieldName = MemberHelper.GetMemberSignature(e, NameFormattingOptions.DocumentationId);
-
- // HACK
- fieldName = fieldName.Replace("E:", "F:");
-
- fieldName = TranslationHelper.TurnStringIntoValidIdentifier(fieldName);
- Bpl.IToken tok = e.Token();
- Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType);
-
- if (e.Adder.ResolvedMethod.IsStatic) {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldName, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.Type mt = new Bpl.MapType(tok, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(this.RefType), t);
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldName, mt);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- return v;
- }
-
- /// <summary>
- /// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which must be non-null).
- /// </summary>
- /// <param name="o">The expression that represents the object to be dereferenced.
- /// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>.
- /// </param>
- public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType) {
- if (accessType == AccessType.Struct || accessType == AccessType.Heap) {
- Bpl.IdentifierExpr field = f as Bpl.IdentifierExpr;
- Debug.Assert(field != null);
- return Bpl.Expr.Select(field, o);
- }
- else
- return FromUnion(f.tok, unboxType, Bpl.Expr.Select(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f));
- }
-
- /// <summary>
- /// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null).
- /// </summary>
- public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType) {
- Debug.Assert(o != null);
- if (accessType == AccessType.Struct || accessType == AccessType.Heap) {
- Bpl.IdentifierExpr field = f as Bpl.IdentifierExpr;
- Debug.Assert(field != null);
- return Bpl.Cmd.MapAssign(tok, field, o, value);
- }
- else {
- return TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(ArrayContentsVariable), Bpl.Expr.Store(Bpl.Expr.Ident(ArrayContentsVariable), o, Bpl.Expr.Store(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f, ToUnion(f.tok, boxType, value))));
- }
- }
-
- }
-
- /// <summary>
- /// A heap representation that uses Boogie (in-line) functions
- /// for all heap reads and writes. That way the decision about
- /// how to exactly represent the heap is made in the Prelude.
- /// </summary>
- public class GeneralHeap : Heap {
-
- #region Fields
-
- [RepresentationFor("$Heap", "var $Heap: HeapType;", true)]
- private Bpl.Variable HeapVariable = null;
-
- [RepresentationFor("Read", "function {:inline true} Read(H:HeapType, o:Ref, f:Field): Union { H[o][f] }")]
- private Bpl.Function Read = null;
-
- [RepresentationFor("Write", "function {:inline true} Write(H:HeapType, o:Ref, f:Field, v:Union): HeapType { H[o := H[o][f := v]] }")]
- private Bpl.Function Write = null;
-
- /// <summary>
- /// Prelude text for which access to the ASTs is not needed
- /// </summary>
- private readonly string InitialPreludeText =
- @"type HeapType = [Ref][Field]Union;
-
-";
- private Sink sink;
-
- #endregion
-
- public override bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program) {
- this.sink = sink;
- heap = this;
- program = null;
- string prelude = this.InitialPreludeText + this.CommonText;
- var b = RepresentationFor.ParsePrelude(prelude, this, out program);
- if (b) {
- this.UnionType = new Bpl.CtorType(this.UnionTypeDecl.tok, this.UnionTypeDecl, new Bpl.TypeSeq());
- this.DelegateType = new Bpl.CtorType(this.DelegateTypeDecl.tok, this.DelegateTypeDecl, new Bpl.TypeSeq());
- this.DelegateMultisetType = new Bpl.TypeSynonymAnnotation(this.DelegateMultisetTypeDecl.tok, this.DelegateMultisetTypeDecl, new Bpl.TypeSeq());
- this.FieldType = new Bpl.CtorType(this.FieldTypeDecl.tok, this.FieldTypeDecl, new Bpl.TypeSeq());
- this.TypeType = new Bpl.CtorType(this.TypeTypeDecl.tok, this.TypeTypeDecl, new Bpl.TypeSeq());
- this.RefType = new Bpl.CtorType(this.RefTypeDecl.tok, this.RefTypeDecl, new Bpl.TypeSeq());
- this.RealType = new Bpl.CtorType(this.RealTypeDecl.tok, this.RealTypeDecl, new Bpl.TypeSeq());
- }
- return b;
- }
-
- /// <summary>
- /// Creates a fresh BPL variable to represent <paramref name="field"/>, deciding
- /// on its type based on the heap representation.
- /// </summary>
- public override Bpl.Variable CreateFieldVariable(IFieldReference field) {
- Bpl.Variable v;
- string fieldname = MemberHelper.GetMemberSignature(field, NameFormattingOptions.DocumentationId);
- fieldname = TranslationHelper.TurnStringIntoValidIdentifier(fieldname);
- Bpl.IToken tok = field.Token();
-
- if (field.ResolvedField.IsStatic) {
- Bpl.Type t = this.sink.CciTypeToBoogie(field.Type.ResolvedType);
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.Type t = this.FieldType;
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.Constant(tok, tident, true);
- }
- return v;
- }
-
- public override Bpl.Variable CreateEventVariable(IEventDefinition e) {
- Bpl.Variable v;
- string fieldname = MemberHelper.GetMemberSignature(e, NameFormattingOptions.DocumentationId);
- fieldname = TranslationHelper.TurnStringIntoValidIdentifier(fieldname);
- Bpl.IToken tok = e.Token();
-
- if (e.Adder.ResolvedMethod.IsStatic) {
- Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType);
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.Type t = this.FieldType;
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.Constant(tok, tident, true);
- }
- return v;
- }
-
- /// <summary>
- /// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which must be non-null).
- /// </summary>
- /// <param name="o">The expression that represents the object to be dereferenced.
- /// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>.
- /// </param>
- public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType) {
- Debug.Assert(o != null);
-
- Bpl.NAryExpr callRead;
- if (accessType == AccessType.Struct || accessType == AccessType.Heap)
- callRead = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(this.Read), new Bpl.ExprSeq(new Bpl.IdentifierExpr(f.tok, this.HeapVariable), o, f));
- else
- callRead = Bpl.Expr.Select(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f);
-
- // wrap it in the right conversion function
- var callExpr = FromUnion(f.tok, unboxType, callRead);
- return callExpr;
- }
-
- /// <summary>
- /// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null).
- /// </summary>
- public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType) {
- Debug.Assert(o != null);
-
- Bpl.IdentifierExpr h;
- Bpl.NAryExpr callWrite;
- var callConversion = ToUnion(f.tok, boxType, value);
-
- if (accessType == AccessType.Struct || accessType == AccessType.Heap) {
- h = Bpl.Expr.Ident(HeapVariable);
- callWrite = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(this.Write), new Bpl.ExprSeq(h, o, f, callConversion));
- }
- else {
- h = Bpl.Expr.Ident(ArrayContentsVariable);
- callWrite = Bpl.Expr.Store(Bpl.Expr.Ident(ArrayContentsVariable), o, Bpl.Expr.Store(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f, callConversion));
- }
- return Bpl.Cmd.SimpleAssign(f.tok, h, callWrite);
- }
-
- }
-
- internal class RepresentationFor : Attribute {
- internal string name;
- internal string declaration;
- internal bool required;
- internal RepresentationFor(string name, string declaration) { this.name = name; this.declaration = declaration; this.required = true; }
- internal RepresentationFor(string name, string declaration, bool required) { this.name = name; this.declaration = declaration; this.required = required; }
-
- internal static bool ParsePrelude(string initialPreludeText, object instance, out Bpl.Program/*?*/ prelude) {
-
- prelude = null;
-
- var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
- var type = instance.GetType();
- FieldInfo/*?*/[] fields = type.GetFields(flags);
- RepresentationFor[] rfs = new RepresentationFor[fields.Length];
- for (int i = 0; i < fields.Length; i++) {
- var field = fields[i];
- object[] cas = field.GetCustomAttributes(typeof(RepresentationFor), false);
- if (cas == null || cas.Length == 0) { // only look at fields that have the attribute
- fields[i] = null;
- }
- else {
- foreach (var a in cas) { // should be exactly one
- RepresentationFor rf = a as RepresentationFor;
- if (rf != null) {
- rfs[i] = rf;
- break;
- }
- }
- }
- }
-
- #region Gather all of the Boogie declarations from the fields of this class
- var preludeText = new StringBuilder(initialPreludeText);
- for (int i = 0; i < fields.Length; i++) {
- var field = fields[i];
- if (field == null) continue;
- preludeText.AppendLine(rfs[i].declaration);
- }
- #endregion
-
- #region Parse the declarations
- int errorCount = Bpl.Parser.Parse(preludeText.ToString(), "foo", out prelude);
- if (prelude == null || errorCount > 0) {
- prelude = null;
- return false;
- }
- #endregion
-
- #region Use the compiled program to get the ASTs
- for (int i = 0; i < fields.Length; i++) {
- var field = fields[i];
- if (field == null) continue;
- if (!rfs[i].required) continue;
- var val = prelude.TopLevelDeclarations.First(d => { Bpl.NamedDeclaration nd = d as Bpl.NamedDeclaration; return nd != null && nd.Name.Equals(rfs[i].name); });
- field.SetValue(instance, val);
- }
- #endregion
-
- #region Check that every field in this class has been set
- for (int i = 0; i < fields.Length; i++) {
- var field = fields[i];
- if (field == null) continue;
- if (!rfs[i].required) continue;
- if (field.GetValue(instance) == null) {
- return false;
- }
- }
- #endregion Check that every field in this class has been set
-
- return true;
- }
- }
-
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/HeapFactory.cs b/BCT/BytecodeTranslator/HeapFactory.cs
deleted file mode 100644
index dd9aa62d..00000000
--- a/BCT/BytecodeTranslator/HeapFactory.cs
+++ /dev/null
@@ -1,582 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-
-namespace BytecodeTranslator {
-
- /// <summary>
- /// Implementations of this interface determine how the heap is represented in
- /// the translated Boogie program.
- /// </summary>
- public interface IHeap {
-
- /// <summary>
- /// Creates a fresh BPL variable to represent <paramref name="field"/>, deciding
- /// on its type based on the heap representation.
- /// </summary>
- Bpl.Variable CreateFieldVariable(IFieldReference field);
-
- /// Creates a fresh BPL variable to represent <paramref name="type"/>, deciding
- /// on its type based on the heap representation. I.e., the value of this
- /// variable represents the value of the expression "typeof(type)".
- /// </summary>
- Bpl.Variable CreateTypeVariable(ITypeReference type, List<Bpl.ConstantParent> parents);
-
- Bpl.Variable CreateEventVariable(IEventDefinition e);
-
- /// <summary>
- /// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which should be non-null).
- /// </summary>
- /// <param name="o">The expression that represents the object to be dereferenced.
- /// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>.
- /// </param>
- Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType);
-
- /// <summary>
- /// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null).
- /// </summary>
- Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType);
-
- /// <summary>
- /// Returns the BPL expression that corresponds to the value of the dynamic type
- /// of the object represented by the expression <paramref name="o"/>.
- /// </summary>
- Bpl.Expr DynamicType(Bpl.Expr o);
-
- }
-
- public enum AccessType { Array, Heap, Struct };
-
- public abstract class Heap : HeapFactory, IHeap
- {
- [RepresentationFor("$ArrayContents", "var $ArrayContents: [Ref][int]Union;")]
- public Bpl.Variable ArrayContentsVariable = null;
- [RepresentationFor("$ArrayLength", "function $ArrayLength(Ref): int;")]
- public Bpl.Function ArrayLengthFunction = null;
-
- public abstract Bpl.Variable CreateFieldVariable(IFieldReference field);
-
- #region Boogie Types
-
- [RepresentationFor("Delegate", "type {:datatype} Delegate;")]
- public Bpl.TypeCtorDecl DelegateTypeDecl = null;
- public Bpl.CtorType DelegateType;
-
- [RepresentationFor("DelegateMultiset", "type DelegateMultiset = [Delegate]int;")]
- public Bpl.TypeSynonymDecl DelegateMultisetTypeDecl = null;
- public Bpl.TypeSynonymAnnotation DelegateMultisetType;
-
- [RepresentationFor("MultisetEmpty", "const unique MultisetEmpty: DelegateMultiset;")]
- public Bpl.Constant MultisetEmpty = null;
-
- [RepresentationFor("MultisetSingleton", "function {:inline true} MultisetSingleton(x: Delegate): DelegateMultiset { MultisetEmpty[x := 1] }")]
- public Bpl.Function MultisetSingleton = null;
-
- [RepresentationFor("MultisetPlus", "function {:inline true} MultisetPlus(x: DelegateMultiset, y: DelegateMultiset): DelegateMultiset { DelegateMapadd(x, y) }")]
- public Bpl.Function MultisetPlus = null;
-
- [RepresentationFor("MultisetMinus", "function {:inline true} MultisetMinus(x: DelegateMultiset, y: DelegateMultiset): DelegateMultiset { DelegateMapiteint(DelegateMapgt(x, y), DelegateMapsub(x, y), DelegateMapconstint(0)) }")]
- public Bpl.Function MultisetMinus = null;
-
- [RepresentationFor("Field", "type Field;")]
- public Bpl.TypeCtorDecl FieldTypeDecl = null;
- public Bpl.CtorType FieldType;
-
- [RepresentationFor("Union", "type Union;")]
- public Bpl.TypeCtorDecl UnionTypeDecl = null;
- public Bpl.CtorType UnionType;
-
- [RepresentationFor("$DefaultHeapValue", "const unique $DefaultHeapValue : Union;")]
- public Bpl.Constant DefaultHeapValue;
-
- [RepresentationFor("Ref", "type Ref;")]
- public Bpl.TypeCtorDecl RefTypeDecl = null;
- public Bpl.CtorType RefType;
- [RepresentationFor("null", "const unique null : Ref;")]
- public Bpl.Constant NullRef;
-
- [RepresentationFor("Type", "type {:datatype} Type;")]
- public Bpl.TypeCtorDecl TypeTypeDecl = null;
- public Bpl.CtorType TypeType;
-
- [RepresentationFor("Real", "type Real;")]
- protected Bpl.TypeCtorDecl RealTypeDecl = null;
- public Bpl.CtorType RealType;
- [RepresentationFor("$DefaultReal", "const unique $DefaultReal : Real;")]
- public Bpl.Constant DefaultReal;
-
- #endregion
-
- #region CLR Boxing
-
- [RepresentationFor("$BoxFromBool", "procedure {:inline 1} $BoxFromBool(b: bool) returns (r: Ref) { call r := Alloc(); assume $BoxedValue(r) == Bool2Union(b); }")]
- public Bpl.Procedure BoxFromBool = null;
-
- [RepresentationFor("$BoxFromInt", "procedure {:inline 1} $BoxFromInt(i: int) returns (r: Ref) { call r := Alloc(); assume $BoxedValue(r) == Int2Union(i); }")]
- public Bpl.Procedure BoxFromInt = null;
-
- [RepresentationFor("$BoxFromReal", "procedure {:inline 1} $BoxFromReal(r: Real) returns (rf: Ref) { call rf := Alloc(); assume $BoxedValue(rf) == Real2Union(r); }")]
- public Bpl.Procedure BoxFromReal = null;
-
- [RepresentationFor("$BoxFromStruct", "procedure {:inline 1} $BoxFromStruct(s: Ref) returns (r: Ref) { call r := Alloc(); assume $BoxedValue(r) == Struct2Union(s); }")]
- public Bpl.Procedure BoxFromStruct = null;
-
- [RepresentationFor("$BoxFromUnion", "procedure {:inline 1} $BoxFromUnion(u: Union) returns (r: Ref) { if (IsRef(u)) { r := Union2Ref(u); } else { call r := Alloc(); assume $BoxedValue(r) == u; } }")]
- public Bpl.Procedure BoxFromUnion = null;
-
- [RepresentationFor("$BoxedValue", "function $BoxedValue(r: Ref): Union;")]
- public Bpl.Function BoxedValue = null;
-
- [RepresentationFor("$Unbox2Bool", "function {:inline true} $Unbox2Bool(r: Ref): (bool) { Union2Bool($BoxedValue(r)) }")]
- public Bpl.Function Unbox2Bool = null;
-
- [RepresentationFor("$Unbox2Int", "function {:inline true} $Unbox2Int(r: Ref): (int) { Union2Int($BoxedValue(r)) }")]
- public Bpl.Function Unbox2Int = null;
-
- [RepresentationFor("$Unbox2Real", "function {:inline true} $Unbox2Real(r: Ref): (Real) { Union2Real($BoxedValue(r)) }")]
- public Bpl.Function Unbox2Real = null;
-
- [RepresentationFor("$Unbox2Struct", "function {:inline true} $Unbox2Struct(r: Ref): (Ref) { Union2Struct($BoxedValue(r)) }")]
- public Bpl.Function Unbox2Struct = null;
-
- [RepresentationFor("$Unbox2Union", "function {:inline true} $Unbox2Union(r: Ref): (Union) { $BoxedValue(r) }")]
- public Bpl.Function Unbox2Union = null;
-
- #endregion
-
- #region Conversions
-
- #region Heap values
-
- [RepresentationFor("Union2Bool", "function Union2Bool(u: Union): (bool);")]
- public Bpl.Function Union2Bool = null;
-
- [RepresentationFor("Union2Int", "function Union2Int(u: Union): (int);")]
- public Bpl.Function Union2Int = null;
-
- [RepresentationFor("Union2Ref", "function Union2Ref(u: Union): (Ref);")]
- public Bpl.Function Union2Ref = null;
-
- [RepresentationFor("Union2Real", "function Union2Real(u: Union): (Real);")]
- public Bpl.Function Union2Real = null;
-
- [RepresentationFor("Union2Struct", "function Union2Struct(u: Union): (Ref);")]
- public Bpl.Function Union2Struct = null;
-
- [RepresentationFor("Bool2Union", "function Bool2Union(boolValue: bool): Union;")]
- public Bpl.Function Bool2Union = null;
-
- [RepresentationFor("Int2Union", "function Int2Union(intValue: int): Union;")]
- public Bpl.Function Int2Union = null;
-
- [RepresentationFor("Ref2Union", "function Ref2Union(refValue: Ref): Union;")]
- public Bpl.Function Ref2Union = null;
-
- [RepresentationFor("Real2Union", "function Real2Union(realValue: Real): Union;")]
- public Bpl.Function Real2Union = null;
-
- [RepresentationFor("Struct2Union", "function Struct2Union(structValue: Ref): Union;")]
- public Bpl.Function Struct2Union = null;
-
- [RepresentationFor("Union2Union", "function {:inline true} Union2Union(u: Union): Union { u }")]
- public Bpl.Function Union2Union = null;
-
- public Bpl.Expr ToUnion(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr) {
- Bpl.Function conversion;
- if (boogieType == Bpl.Type.Bool)
- conversion = this.Bool2Union;
- else if (boogieType == Bpl.Type.Int)
- conversion = this.Int2Union;
- else if (boogieType == RefType)
- conversion = this.Ref2Union;
- else if (boogieType == RealType)
- conversion = this.Real2Union;
- else if (boogieType == UnionType)
- conversion = this.Union2Union;
- else
- throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString()));
-
- var callConversion = new Bpl.NAryExpr(
- tok,
- new Bpl.FunctionCall(conversion),
- new Bpl.ExprSeq(expr)
- );
- return callConversion;
- }
-
- public Bpl.Expr FromUnion(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr) {
- Bpl.Function conversion = null;
- if (boogieType == Bpl.Type.Bool)
- conversion = this.Union2Bool;
- else if (boogieType == Bpl.Type.Int)
- conversion = this.Union2Int;
- else if (boogieType == RefType)
- conversion = this.Union2Ref;
- else if (boogieType == RealType)
- conversion = this.Union2Real;
- else if (boogieType == UnionType)
- conversion = this.Union2Union;
- else
- throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString()));
-
- var callExpr = new Bpl.NAryExpr(
- tok,
- new Bpl.FunctionCall(conversion),
- new Bpl.ExprSeq(expr)
- );
- callExpr.Type = boogieType;
- return callExpr;
- }
-
- #endregion
-
- #region Real number conversions
- [RepresentationFor("Int2Real", "function Int2Real(int): Real;")]
- public Bpl.Function Int2Real = null;
- [RepresentationFor("Real2Int", "function Real2Int(Real): int;")]
- public Bpl.Function Real2Int = null;
- #endregion
-
- #region Real number operations
- [RepresentationFor("RealPlus", "function RealPlus(Real, Real): Real;")]
- public Bpl.Function RealPlus = null;
- [RepresentationFor("RealMinus", "function RealMinus(Real, Real): Real;")]
- public Bpl.Function RealMinus = null;
- [RepresentationFor("RealTimes", "function RealTimes(Real, Real): Real;")]
- public Bpl.Function RealTimes = null;
- [RepresentationFor("RealDivide", "function RealDivide(Real, Real): Real;")]
- public Bpl.Function RealDivide = null;
- [RepresentationFor("RealModulus", "function RealModulus(Real, Real): Real;")]
- public Bpl.Function RealModulus = null;
- [RepresentationFor("RealLessThan", "function RealLessThan(Real, Real): bool;")]
- public Bpl.Function RealLessThan = null;
- [RepresentationFor("RealLessThanOrEqual", "function RealLessThanOrEqual(Real, Real): bool;")]
- public Bpl.Function RealLessThanOrEqual = null;
- [RepresentationFor("RealGreaterThan", "function RealGreaterThan(Real, Real): bool;")]
- public Bpl.Function RealGreaterThan = null;
- [RepresentationFor("RealGreaterThanOrEqual", "function RealGreaterThanOrEqual(Real, Real): bool;")]
- public Bpl.Function RealGreaterThanOrEqual = null;
- #endregion
-
- #region Bitwise operations
- [RepresentationFor("BitwiseAnd", "function BitwiseAnd(int, int): int;")]
- public Bpl.Function BitwiseAnd = null;
- [RepresentationFor("BitwiseOr", "function BitwiseOr(int, int): int;")]
- public Bpl.Function BitwiseOr = null;
- [RepresentationFor("BitwiseExclusiveOr", "function BitwiseExclusiveOr(int, int): int;")]
- public Bpl.Function BitwiseExclusiveOr = null;
- [RepresentationFor("BitwiseNegation", "function BitwiseNegation(int): int;")]
- public Bpl.Function BitwiseNegation = null;
- [RepresentationFor("RightShift", "function RightShift(int,int): int;")]
- public Bpl.Function RightShift = null;
- [RepresentationFor("LeftShift", "function LeftShift(int,int): int;")]
- public Bpl.Function LeftShift = null;
- #endregion
-
- #endregion
-
- /// <summary>
- /// Creates a fresh BPL variable to represent <paramref name="type"/>, deciding
- /// on its type based on the heap representation. I.e., the value of this
- /// variable represents the value of the expression "typeof(type)".
- /// </summary>
- public Bpl.Variable CreateTypeVariable(ITypeReference type, List<Bpl.ConstantParent> parents)
- {
- string typename = TypeHelper.GetTypeName(type, NameFormattingOptions.DocumentationId);
- typename = TranslationHelper.TurnStringIntoValidIdentifier(typename);
- Bpl.IToken tok = type.Token();
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, typename, this.TypeType);
- Bpl.Constant v = new Bpl.Constant(tok, tident, true /*unique*/, parents, false, null);
- return v;
- }
-
- public Bpl.Function CreateTypeFunction(ITypeReference type, int parameterCount) {
- System.Diagnostics.Debug.Assert(parameterCount >= 0);
- string typename = TypeHelper.GetTypeName(type, NameFormattingOptions.DocumentationId);
- typename = TranslationHelper.TurnStringIntoValidIdentifier(typename);
- Bpl.IToken tok = type.Token();
- Bpl.VariableSeq inputs = new Bpl.VariableSeq();
- //for (int i = 0; i < parameterCount; i++) {
- // inputs.Add(new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "arg"+i, this.TypeType), true));
- //}
- foreach (var t in TranslationHelper.ConsolidatedGenericParameters(type)) {
- var n = t.Name.Value;
- var n2 = TranslationHelper.TurnStringIntoValidIdentifier(n);
- inputs.Add(new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, n2, this.TypeType), true));
- }
- Bpl.Variable output = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "result", this.TypeType), false);
- Bpl.Function func = new Bpl.Function(tok, typename, inputs, output);
- var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "constructor", new List<object>(1), null);
- func.Attributes = attrib;
- return func;
- }
-
-
- public abstract Bpl.Variable CreateEventVariable(IEventDefinition e);
-
- public abstract Bpl.Expr ReadHeap(Bpl.Expr o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType);
-
- public abstract Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType);
-
- [RepresentationFor("$DynamicType", "function $DynamicType(Ref): Type;")]
- protected Bpl.Function DynamicTypeFunction = null;
-
- /// <summary>
- /// Returns the BPL expression that corresponds to the value of the dynamic type
- /// of the object represented by the expression <paramref name="o"/>.
- /// </summary>
- public Bpl.Expr DynamicType(Bpl.Expr o) {
- // $DymamicType(o)
- var callDynamicType = new Bpl.NAryExpr(
- o.tok,
- new Bpl.FunctionCall(this.DynamicTypeFunction),
- new Bpl.ExprSeq(o)
- );
- return callDynamicType;
- }
-
- [RepresentationFor("$TypeOf", "function $TypeOf(Type): Ref;")]
- public Bpl.Function TypeOfFunction = null;
-
- [RepresentationFor("$As", "function $As(Ref, Type): Ref;")]
- public Bpl.Function AsFunction = null;
-
- [RepresentationFor("$Subtype", "function $Subtype(Type, Type): bool;")]
- public Bpl.Function Subtype = null;
-
- [RepresentationFor("$DisjointSubtree", "function $DisjointSubtree(Type, Type): bool;")]
- public Bpl.Function DisjointSubtree = null;
-
- [RepresentationFor("$Alloc", "var $Alloc: [Ref] bool;")]
- public Bpl.Variable AllocVariable = null;
-
- [RepresentationFor("$allocImp", "function {:builtin \"MapImp\"} $allocImp([Ref]bool, [Ref]bool) : [Ref]bool;")]
- public Bpl.Function AllocImplies = null;
- [RepresentationFor("$allocConstBool", "function {:builtin \"MapConst\"} $allocConstBool(bool) : [Ref]bool;")]
- public Bpl.Function AllocConstBool = null;
-
-
-
- protected readonly string CommonText =
- @"//var $Alloc: [Ref] bool;
-
-procedure {:inline 1} Alloc() returns (x: Ref)
- modifies $Alloc;
-{
- assume $Alloc[x] == false && x != null;
- $Alloc[x] := true;
-}
-
-function {:builtin ""MapAdd""} DelegateMapadd([Delegate]int, [Delegate]int) : [Delegate]int;
-function {:builtin ""MapSub""} DelegateMapsub([Delegate]int, [Delegate]int) : [Delegate]int;
-function {:builtin ""MapMul""} DelegateMapmul([Delegate]int, [Delegate]int) : [Delegate]int;
-function {:builtin ""MapDiv""} DelegateMapdiv([Delegate]int, [Delegate]int) : [Delegate]int;
-function {:builtin ""MapMod""} DelegateMapmod([Delegate]int, [Delegate]int) : [Delegate]int;
-function {:builtin ""MapConst""} DelegateMapconstint(int) : [Delegate]int;
-function {:builtin ""MapConst""} DelegateMapconstbool(bool) : [Delegate]bool;
-function {:builtin ""MapAnd""} DelegateMapand([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-function {:builtin ""MapOr""} DelegateMapor([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-function {:builtin ""MapNot""} DelegateMapnot([Delegate]bool) : [Delegate]bool;
-function {:builtin ""MapIte""} DelegateMapiteint([Delegate]bool, [Delegate]int, [Delegate]int) : [Delegate]int;
-function {:builtin ""MapIte""} DelegateMapitebool([Delegate]bool, [Delegate]bool, [Delegate]bool) : [Delegate]bool;
-function {:builtin ""MapLe""} DelegateMaple([Delegate]int, [Delegate]int) : [Delegate]bool;
-function {:builtin ""MapLt""} DelegateMaplt([Delegate]int, [Delegate]int) : [Delegate]bool;
-function {:builtin ""MapGe""} DelegateMapge([Delegate]int, [Delegate]int) : [Delegate]bool;
-function {:builtin ""MapGt""} DelegateMapgt([Delegate]int, [Delegate]int) : [Delegate]bool;
-function {:builtin ""MapEq""} DelegateMapeq([Delegate]int, [Delegate]int) : [Delegate]bool;
-function {:builtin ""MapIff""} DelegateMapiff([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-function {:builtin ""MapImp""} DelegateMapimp([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-axiom MultisetEmpty == DelegateMapconstint(0);
-
-function IsRef(u: Union) : (bool);
-axiom (forall x: bool :: {Bool2Union(x)} Union2Bool(Bool2Union(x)) == x && !IsRef(Bool2Union(x)));
-axiom (forall x: int :: {Int2Union(x)} Union2Int(Int2Union(x)) == x && !IsRef(Int2Union(x)));
-axiom (forall x: Real :: {Real2Union(x)} Union2Real(Real2Union(x)) == x && !IsRef(Real2Union(x)));
-axiom (forall x: Ref :: {Ref2Union(x)} Union2Ref(Ref2Union(x)) == x && IsRef(Ref2Union(x)));
-axiom (forall x: Ref :: {Struct2Union(x)} Union2Struct(Struct2Union(x)) == x && !IsRef(Struct2Union(x)));
-
-
-/*
-// Subtype is reflexive
-axiom (forall t: Type :: $Subtype(t, t) );
-
-// Subtype is anti-symmetric
-axiom (forall t0 : Type, t1 : Type :: { $Subtype(t0, t1), $Subtype(t1, t0) }
- $Subtype(t0, t1) && $Subtype(t1, t0) ==> (t0 == t1) );
-
-// Subtype is transitive
-axiom (forall t0 : Type, t1 : Type, t2 : Type :: { $Subtype(t0, t1), $Subtype(t1, t2) }
- $Subtype(t0, t1) && $Subtype(t1, t2) ==> $Subtype(t0, t2) );
-
-// Incomparable subtypes: the subtrees are disjoint for (some) subtypes (those that imply single inheritance)
-function oneDown(t0 : Type, t1 : Type) : Type; // uninterpreted function with no axioms
-axiom (forall C : Type, D : Type :: { $DisjointSubtree(D, C) }
- $DisjointSubtree(D, C) <==> (forall z : Type :: $Subtype(z, D) ==> oneDown(C,z) == D) );
-*/
-
-function $TypeOfInv(Ref): Type;
-axiom (forall t: Type :: {$TypeOf(t)} $TypeOfInv($TypeOf(t)) == t);
-
-procedure {:inline 1} System.Object.GetType(this: Ref) returns ($result: Ref)
-{
- $result := $TypeOf($DynamicType(this));
-}
-
-axiom Union2Int($DefaultHeapValue) == 0;
-axiom Union2Bool($DefaultHeapValue) == false;
-axiom Union2Ref($DefaultHeapValue) == null;
-
-function $ThreadDelegate(Ref) : Ref;
-
-procedure {:inline 1} System.Threading.Thread.#ctor$System.Threading.ParameterizedThreadStart(this: Ref, start$in: Ref)
-{
- assume $ThreadDelegate(this) == start$in;
-}
-procedure {:inline 1} System.Threading.Thread.Start$System.Object(this: Ref, parameter$in: Ref)
-{
- call {:async} Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object($ThreadDelegate(this), parameter$in);
-}
-procedure Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref) {
- $Exception := null;
- call System.Threading.ParameterizedThreadStart.Invoke$System.Object(this, obj$in);
-}
-procedure {:extern} System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref);
-
-procedure {:inline 1} System.Threading.Thread.#ctor$System.Threading.ThreadStart(this: Ref, start$in: Ref)
-{
- assume $ThreadDelegate(this) == start$in;
-}
-procedure {:inline 1} System.Threading.Thread.Start(this: Ref)
-{
- call {:async} Wrapper_System.Threading.ThreadStart.Invoke($ThreadDelegate(this));
-}
-procedure Wrapper_System.Threading.ThreadStart.Invoke(this: Ref) {
- $Exception := null;
- call System.Threading.ThreadStart.Invoke(this);
-}
-procedure {:extern} System.Threading.ThreadStart.Invoke(this: Ref);
-
-procedure {:inline 1} DelegateAdd(a: Ref, b: Ref) returns (c: Ref)
-{
- var d: Delegate;
-
- if (a == null)
- {
- c := b;
- }
- else if (b == null)
- {
- c := a;
- }
- else
- {
- call c := Alloc();
- assume $RefToDelegate(c) == $RefToDelegate(a) || $RefToDelegate(c) == $RefToDelegate(b);
- assume $RefToDelegateMultiset(c) == MultisetPlus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b));
- }
-}
-
-procedure {:inline 1} DelegateRemove(a: Ref, b: Ref) returns (c: Ref)
-{
- var d: Delegate;
-
- if (a == null)
- {
- c := null;
- }
- else if (b == null)
- {
- c := a;
- }
- else if (MultisetMinus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b)) == MultisetEmpty)
- {
- c := null;
- }
- else
- {
- call c := Alloc();
- assume $RefToDelegateMultiset(c) == MultisetMinus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b));
- assume $RefToDelegateMultiset(c)[$RefToDelegate(c)] > 0;
- }
-}
-
-procedure {:inline 1} DelegateCreate(d: Delegate) returns (c: Ref)
-{
- call c := Alloc();
- assume $RefToDelegate(c) == d;
- assume $RefToDelegateMultiset(c) == MultisetSingleton(d);
-}
-
-procedure {:inline 1} System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-procedure {:inline 1} System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-
-implementation System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool) {
- $result := (a$in == b$in);
-}
-
-implementation System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool) {
- $result := (a$in != b$in);
-}
-
-";
-
- [RepresentationFor("$RefToDelegate", "function $RefToDelegate(Ref): Delegate;")]
- public Bpl.Function RefToDelegate = null;
-
- [RepresentationFor("$RefToDelegateMultiset", "function $RefToDelegateMultiset(Ref): DelegateMultiset;")]
- public Bpl.Function RefToDelegateMultiset = null;
-
- [RepresentationFor("$RefToDelegateMultisetCons", "function {:constructor} $RefToDelegateMultisetCons($Method: int, $Receiver: Ref, $TypeParameters: Type): Delegate;")]
- public Bpl.DatatypeConstructor DelegateCons = null;
-
- public Bpl.Function DelegateMethod {
- get { return DelegateCons.selectors[0]; }
- }
-
- public Bpl.Function DelegateReceiver {
- get { return DelegateCons.selectors[1]; }
- }
-
- public Bpl.Function DelegateTypeParameters {
- get { return DelegateCons.selectors[2]; }
- }
-
- [RepresentationFor("$Exception", "var {:thread_local} $Exception: Ref;")]
- public Bpl.GlobalVariable ExceptionVariable = null;
- }
-
- public abstract class HeapFactory {
-
- /// <summary>
- /// Returns two things: an object that determines the heap representation,
- /// and (optionally) an initial program that contains declarations needed
- /// for the heap representation.
- /// </summary>
- /// <param name="sink">
- /// The heap might need to generate declarations so it needs access to the Sink.
- /// </param>
- /// <returns>
- /// false if and only if an error occurrs and the heap and/or program are not in a
- /// good state to be used.
- /// </returns>
- public abstract bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program);
- }
-
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/MetadataTraverser.cs b/BCT/BytecodeTranslator/MetadataTraverser.cs
deleted file mode 100644
index 491f0f96..00000000
--- a/BCT/BytecodeTranslator/MetadataTraverser.cs
+++ /dev/null
@@ -1,721 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics.Contracts;
-using TranslationPlugins;
-using BytecodeTranslator.Phone;
-using BytecodeTranslator.TranslationPlugins;
-
-
-namespace BytecodeTranslator {
-
- /// <summary>
- /// Responsible for traversing all metadata elements (i.e., everything exclusive
- /// of method bodies).
- /// </summary>
- public class BCTMetadataTraverser : MetadataTraverser {
-
- readonly Sink sink;
- public readonly TraverserFactory Factory;
-
- public readonly IDictionary<IUnit, PdbReader> PdbReaders;
- public PdbReader/*?*/ PdbReader;
-
- public BCTMetadataTraverser(Sink sink, IDictionary<IUnit, PdbReader> pdbReaders, TraverserFactory factory)
- : base() {
- this.sink = sink;
- this.Factory = factory;
- this.PdbReaders = pdbReaders;
- }
-
- public IEnumerable<Bpl.Requires> getPreconditionTranslation(IMethodContract contract) {
- ICollection<Bpl.Requires> translatedPres = new List<Bpl.Requires>();
- foreach (IPrecondition pre in contract.Preconditions) {
- var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true);
- ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true);
- exptravers.Traverse(pre.Condition); // TODO
- // Todo: Deal with Descriptions
- var req = new Bpl.Requires(pre.Token(), false, exptravers.TranslatedExpressions.Pop(), "");
- translatedPres.Add(req);
- }
-
- return translatedPres;
- }
-
- public IEnumerable<Bpl.Ensures> getPostconditionTranslation(IMethodContract contract) {
- ICollection<Bpl.Ensures> translatedPosts = new List<Bpl.Ensures>();
- foreach (IPostcondition post in contract.Postconditions) {
- var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true);
- ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true);
- exptravers.Traverse(post.Condition);
- // Todo: Deal with Descriptions
- var ens = new Bpl.Ensures(post.Token(), false, exptravers.TranslatedExpressions.Pop(), "");
- translatedPosts.Add(ens);
- }
-
- return translatedPosts;
- }
-
- public IEnumerable<Bpl.IdentifierExpr> getModifiedIdentifiers(IMethodContract contract) {
- ICollection<Bpl.IdentifierExpr> modifiedExpr = new List<Bpl.IdentifierExpr>();
- foreach (IAddressableExpression mod in contract.ModifiedVariables) {
- ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, null, true);
- exptravers.Traverse(mod);
- Bpl.IdentifierExpr idexp = exptravers.TranslatedExpressions.Pop() as Bpl.IdentifierExpr;
- if (idexp == null) {
- throw new TranslationException(String.Format("Cannot create IdentifierExpr for Modifyed Variable {0}", mod.ToString()));
- }
- modifiedExpr.Add(idexp);
- }
-
- return modifiedExpr;
- }
-
-
- #region Overrides
-
- public override void TraverseChildren(IModule module) {
- this.PdbReaders.TryGetValue(module, out this.PdbReader);
- if (!(module.EntryPoint is Dummy))
- this.entryPoint = module.EntryPoint;
-
- base.TraverseChildren(module);
- }
-
- public override void TraverseChildren(IAssembly assembly) {
- this.PdbReaders.TryGetValue(assembly, out this.PdbReader);
- this.sink.BeginAssembly(assembly);
- try {
- base.TraverseChildren(assembly);
- } finally {
- this.sink.EndAssembly(assembly);
- }
- }
-
- /// <summary>
- /// Translate the type definition.
- /// </summary>
- ///
- public override void TraverseChildren(ITypeDefinition typeDefinition) {
-
- if (!this.sink.TranslateType(typeDefinition)) return;
-
- var savedPrivateTypes = this.privateTypes;
- this.privateTypes = new List<ITypeDefinition>();
-
- trackPhonePageNameVariableName(typeDefinition);
- trackPhoneApplicationClassname(typeDefinition);
-
- var gtp = typeDefinition as IGenericTypeParameter;
- if (gtp != null) {
- return;
- }
-
- if (typeDefinition.IsClass) {
- bool savedSawCctor = this.sawCctor;
- this.sawCctor = false;
- sink.FindOrDefineType(typeDefinition);
- base.TraverseChildren(typeDefinition);
- if (!this.sawCctor) {
- CreateStaticConstructor(typeDefinition);
- }
- this.sawCctor = savedSawCctor;
- } else if (typeDefinition.IsDelegate) {
- ITypeDefinition unspecializedType = Microsoft.Cci.MutableContracts.ContractHelper.Unspecialized(typeDefinition).ResolvedType;
- sink.AddDelegateType(unspecializedType);
- } else if (typeDefinition.IsInterface) {
- sink.FindOrCreateTypeReference(typeDefinition);
- base.TraverseChildren(typeDefinition);
- } else if (typeDefinition.IsEnum) {
- return; // enums just are translated as ints
- } else if (typeDefinition.IsStruct) {
- sink.FindOrCreateTypeReference(typeDefinition);
- CreateDefaultStructConstructor(typeDefinition);
- CreateStructCopyConstructor(typeDefinition);
- base.TraverseChildren(typeDefinition);
- } else {
- Console.WriteLine("Unknown kind of type definition '{0}' was found",
- TypeHelper.GetTypeName(typeDefinition));
- throw new NotImplementedException(String.Format("Unknown kind of type definition '{0}'.", TypeHelper.GetTypeName(typeDefinition)));
- }
- this.Traverse(typeDefinition.PrivateHelperMembers);
- foreach (var t in this.privateTypes) {
- this.Traverse(t);
- }
- }
- List<ITypeDefinition> privateTypes = new List<ITypeDefinition>();
-
- private void trackPhoneApplicationClassname(ITypeDefinition typeDef) {
- if (PhoneCodeHelper.instance().PhonePlugin != null && typeDef.isPhoneApplicationClass(sink.host)) {
- INamespaceTypeDefinition namedTypeDef = typeDef as INamespaceTypeDefinition;
- // string fullyQualifiedName = namedTypeDef.ContainingNamespace.Name.Value + "." + namedTypeDef.Name.Value;
- string fullyQualifiedName = namedTypeDef.ToString();
- PhoneCodeHelper.instance().setMainAppTypeReference(typeDef);
- PhoneCodeHelper.instance().setMainAppTypeName(fullyQualifiedName);
- }
- }
-
- private void trackPhonePageNameVariableName(ITypeDefinition typeDef) {
- if (PhoneCodeHelper.instance().PhonePlugin != null && typeDef.isPhoneApplicationPageClass(sink.host)) {
- INamespaceTypeDefinition namedTypeDef = typeDef as INamespaceTypeDefinition;
- string fullyQualifiedName = namedTypeDef.ToString();
- string xamlForClass = PhoneCodeHelper.instance().getXAMLForPage(fullyQualifiedName);
- if (xamlForClass != null) { // if not it is possibly an abstract page
- string uriName = UriHelper.getURIBase(xamlForClass);
- Bpl.Constant uriConstant = sink.FindOrCreateConstant(uriName);
- PhoneCodeHelper.instance().setBoogieStringPageNameForPageClass(fullyQualifiedName, uriConstant.Name);
- }
- }
- }
-
- /*
- private void translateAnonymousControlsForPage(ITypeDefinition typeDef) {
- if (PhoneCodeHelper.instance().PhonePlugin != null && typeDef.isPhoneApplicationPageClass(sink.host)) {
- IEnumerable<ControlInfoStructure> pageCtrls= PhoneCodeHelper.instance().PhonePlugin.getControlsForPage(typeDef.ToString());
- foreach (ControlInfoStructure ctrlInfo in pageCtrls) {
- if (ctrlInfo.Name.Contains(PhoneControlsPlugin.BOOGIE_DUMMY_CONTROL) || ctrlInfo.Name == Dummy.Name.Value) {
- string anonymousControlName = ctrlInfo.Name;
- IFieldDefinition fieldDef = new FieldDefinition() {
- ContainingTypeDefinition = typeDef,
- Name = sink.host.NameTable.GetNameFor(anonymousControlName),
- InternFactory = sink.host.InternFactory,
- Visibility = TypeMemberVisibility.Public,
- Type = sink.host.PlatformType.SystemObject,
- IsStatic = false,
- };
- (typeDef as Microsoft.Cci.MutableCodeModel.NamespaceTypeDefinition).Fields.Add(fieldDef);
- //sink.FindOrCreateFieldVariable(fieldDef);
- }
- }
- }
- }
- */
-
- private void CreateDefaultStructConstructor(ITypeDefinition typeDefinition) {
- Contract.Requires(typeDefinition.IsStruct);
-
- var proc = this.sink.FindOrCreateProcedureForDefaultStructCtor(typeDefinition);
-
- this.sink.BeginMethod(typeDefinition);
- var stmtTranslator = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false);
- var stmts = new List<IStatement>();
-
- foreach (var f in typeDefinition.Fields) {
- if (f.IsStatic) continue;
- var s = new ExpressionStatement() {
- Expression = new Assignment() {
- Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, },
- Target = new TargetExpression() {
- Definition = f,
- Instance = new ThisReference() { Type = typeDefinition, },
- Type = f.Type,
- },
- Type = f.Type,
- },
- };
- stmts.Add(s);
- }
-
- stmtTranslator.Traverse(stmts);
- var translatedStatements = stmtTranslator.StmtBuilder.Collect(Bpl.Token.NoToken);
-
- var lit = Bpl.Expr.Literal(1);
- lit.Type = Bpl.Type.Int;
- var args = new List<object> { lit };
- var attrib = new Bpl.QKeyValue(typeDefinition.Token(), "inline", args, null); // TODO: Need to have it be {:inine 1} (and not just {:inline})?
-
- List<Bpl.Variable> vars = new List<Bpl.Variable>();
- foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) {
- vars.Add(v);
- }
- Bpl.VariableSeq vseq = new Bpl.VariableSeq(vars.ToArray());
-
- Bpl.Implementation impl =
- new Bpl.Implementation(Bpl.Token.NoToken,
- proc.Name,
- new Bpl.TypeVariableSeq(),
- proc.InParams,
- proc.OutParams,
- vseq,
- translatedStatements,
- attrib,
- new Bpl.Errors()
- );
-
- impl.Proc = (Bpl.Procedure) proc; // TODO: get rid of cast
- this.sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
- }
-
- private void CreateStructCopyConstructor(ITypeDefinition typeDefinition) {
- Contract.Requires(typeDefinition.IsStruct);
-
- var proc = this.sink.FindOrCreateProcedureForStructCopy(typeDefinition);
-
- var stmtBuilder = new Bpl.StmtListBuilder();
-
- var tok = Bpl.Token.NoToken;
-
- var o = Bpl.Expr.Ident(proc.OutParams[0]);
-
- // other := Alloc();
- stmtBuilder.Add(new Bpl.CallCmd(tok, this.sink.AllocationMethodName, new Bpl.ExprSeq(), new Bpl.IdentifierExprSeq(o)));
- // assume DynamicType(other) == S;
- stmtBuilder.Add(
- new Bpl.AssumeCmd(tok, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, this.sink.Heap.DynamicType(o), this.sink.FindOrCreateTypeReference(typeDefinition, true)))
- );
-
- var localVars = new Bpl.VariableSeq();
-
- foreach (var f in typeDefinition.Fields) {
- if (f.IsStatic) continue;
-
- var fExp = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(f));
- var boogieType = sink.CciTypeToBoogie(f.Type);
-
- if (TranslationHelper.IsStruct(f.Type)) {
- // generate a call to the copy constructor to copy the contents of f
- var proc2 = this.sink.FindOrCreateProcedureForStructCopy(f.Type);
- var e = this.sink.Heap.ReadHeap(Bpl.Expr.Ident(proc.InParams[0]), fExp, AccessType.Struct, boogieType);
- var bplLocal = this.sink.CreateFreshLocal(f.Type);
- var localExpr = Bpl.Expr.Ident(bplLocal);
- localVars.Add(bplLocal);
- var cmd = new Bpl.CallCmd(tok, proc2.Name, new List<Bpl.Expr> { e, }, new List<Bpl.IdentifierExpr>{ localExpr, });
- stmtBuilder.Add(cmd);
- var c = this.sink.Heap.WriteHeap(tok, o, fExp, localExpr, AccessType.Struct, boogieType);
- stmtBuilder.Add(c);
- } else {
- // just generate a normal assignment to the field f
- var e = this.sink.Heap.ReadHeap(Bpl.Expr.Ident(proc.InParams[0]), fExp, AccessType.Struct, boogieType);
- var c = this.sink.Heap.WriteHeap(tok, o, fExp, e, AccessType.Struct, boogieType);
- stmtBuilder.Add(c);
- }
- }
-
- var lit = Bpl.Expr.Literal(1);
- lit.Type = Bpl.Type.Int;
- var args = new List<object> { lit };
- var attrib = new Bpl.QKeyValue(typeDefinition.Token(), "inline", args, null);
- Bpl.Implementation impl =
- new Bpl.Implementation(Bpl.Token.NoToken,
- proc.Name,
- new Bpl.TypeVariableSeq(),
- proc.InParams,
- proc.OutParams,
- localVars,
- stmtBuilder.Collect(Bpl.Token.NoToken),
- attrib,
- new Bpl.Errors()
- );
-
- impl.Proc = (Bpl.Procedure)proc; // TODO: get rid of cast
- this.sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
- }
-
- private bool sawCctor = false;
- private IMethodReference/*?*/ entryPoint = null;
-
- private void CreateStaticConstructor(ITypeDefinition typeDefinition) {
- var typename = TypeHelper.GetTypeName(typeDefinition, Microsoft.Cci.NameFormattingOptions.DocumentationId);
- typename = TranslationHelper.TurnStringIntoValidIdentifier(typename);
- var proc = new Bpl.Procedure(Bpl.Token.NoToken, typename + ".#cctor",
- new Bpl.TypeVariableSeq(),
- new Bpl.VariableSeq(), // in
- new Bpl.VariableSeq(), // out
- new Bpl.RequiresSeq(),
- new Bpl.IdentifierExprSeq(), // modifies
- new Bpl.EnsuresSeq()
- );
-
- this.sink.TranslatedProgram.TopLevelDeclarations.Add(proc);
-
- this.sink.BeginMethod(typeDefinition);
-
- var stmtTranslator = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false);
- var stmts = new List<IStatement>();
-
- foreach (var f in typeDefinition.Fields) {
- if (!f.IsStatic) continue;
- stmts.Add(
- new ExpressionStatement() {
- Expression = new Assignment() {
- Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, },
- Target = new TargetExpression() {
- Definition = f,
- Instance = null,
- Type = f.Type,
- },
- Type = f.Type,
- }
- });
- }
-
- stmtTranslator.Traverse(stmts);
- var translatedStatements = stmtTranslator.StmtBuilder.Collect(Bpl.Token.NoToken);
-
- List<Bpl.Variable> vars = new List<Bpl.Variable>();
- foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) {
- vars.Add(v);
- }
- Bpl.VariableSeq vseq = new Bpl.VariableSeq(vars.ToArray());
-
- Bpl.Implementation impl =
- new Bpl.Implementation(Bpl.Token.NoToken,
- proc.Name,
- new Bpl.TypeVariableSeq(),
- proc.InParams,
- proc.OutParams,
- vseq,
- translatedStatements
- );
-
- impl.Proc = proc;
- this.sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
-
- }
-
- /// <summary>
- ///
- /// </summary>
- public override void TraverseChildren(IMethodDefinition method) {
-
- if (method.IsStaticConstructor) this.sawCctor = true;
-
- bool isEventAddOrRemove = method.IsSpecialName && (method.Name.Value.StartsWith("add_") || method.Name.Value.StartsWith("remove_"));
- if (isEventAddOrRemove)
- return;
-
-
- Sink.ProcedureInfo procInfo;
- IMethodDefinition stubMethod = null;
- if (IsStubMethod(method, out stubMethod)) {
- procInfo = this.sink.FindOrCreateProcedure(stubMethod);
- } else {
- procInfo = this.sink.FindOrCreateProcedure(method);
- }
-
- if (method.IsAbstract || method.IsExternal) { // we're done, just define the procedure
- return;
- }
-
- this.sink.BeginMethod(method);
- var decl = procInfo.Decl;
- var proc = decl as Bpl.Procedure;
- var formalMap = procInfo.FormalMap;
-
- if (this.entryPoint != null && method.InternedKey == this.entryPoint.InternedKey) {
- decl.AddAttribute("entrypoint");
- }
-
- // FEEDBACK inline handler methods to avoid more false alarms
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled && PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(method) &&
- !PhoneCodeHelper.instance().isMethodIgnoredForFeedback(method)) {
- proc.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE));
- PhoneCodeHelper.instance().trackCallableMethod(proc);
- }
-
- try {
- StatementTraverser stmtTraverser = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false);
-
- // FEEDBACK if this is a feedback method it will be plagued with false asserts. They will trigger if $Exception becomes other than null
- // FEEDBACK for modular analysis we need it to be non-null at the start
- // FEEDBACK also, callee is obviously non null
- IMethodDefinition translatedMethod= sink.getMethodBeingTranslated();
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled && translatedMethod != null &&
- PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(translatedMethod)) {
- // assign null to exception
- List<Bpl.AssignLhs> assignee= new List<Bpl.AssignLhs>();
- Bpl.AssignLhs exceptionAssignee= new Bpl.SimpleAssignLhs(Bpl.Token.NoToken, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable));
- assignee.Add(exceptionAssignee);
- List<Bpl.Expr> value= new List<Bpl.Expr>();
- value.Add(Bpl.Expr.Ident(this.sink.Heap.NullRef));
- Bpl.Cmd exceptionAssign= new Bpl.AssignCmd(Bpl.Token.NoToken, assignee, value);
- stmtTraverser.StmtBuilder.Add(exceptionAssign);
- }
-
- #region Add assignments from In-Params to local-Params
-
- foreach (MethodParameter mparam in formalMap) {
- if (mparam.inParameterCopy != null) {
- Bpl.IToken tok = method.Token();
- stmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok,
- new Bpl.IdentifierExpr(tok, mparam.outParameterCopy),
- new Bpl.IdentifierExpr(tok, mparam.inParameterCopy)));
- }
- }
-
- #endregion
-
- #region For non-deferring ctors and all cctors, initialize all fields to null-equivalent values
- var inits = InitializeFieldsInConstructor(method);
- if (0 < inits.Count) {
- foreach (var s in inits) {
- stmtTraverser.Traverse(s);
- }
- }
- #endregion
-
- #region Translate method attributes
- // Don't need an expression translator because there is a limited set of things
- // that can appear as arguments to custom attributes
- // TODO: decode enum values
- try {
- foreach (var a in method.Attributes) {
- var attrName = TypeHelper.GetTypeName(a.Type);
- if (attrName.EndsWith("Attribute"))
- attrName = attrName.Substring(0, attrName.Length - 9);
- var args = new object[IteratorHelper.EnumerableCount(a.Arguments)];
- int argIndex = 0;
- foreach (var c in a.Arguments) {
- var mdc = c as IMetadataConstant;
- if (mdc != null) {
- object o;
- if (mdc.Type.IsEnum) {
- var lit = Bpl.Expr.Literal((int) mdc.Value);
- lit.Type = Bpl.Type.Int;
- o = lit;
- } else {
- switch (mdc.Type.TypeCode) {
- case PrimitiveTypeCode.Boolean:
- o = (bool) mdc.Value ? Bpl.Expr.True : Bpl.Expr.False;
- break;
- case PrimitiveTypeCode.Int32:
- var lit = Bpl.Expr.Literal((int) mdc.Value);
- lit.Type = Bpl.Type.Int;
- o = lit;
- break;
- case PrimitiveTypeCode.String:
- o = mdc.Value;
- break;
- default:
- throw new InvalidCastException("Invalid metadata constant type");
- }
- }
- args[argIndex++] = o;
- }
- }
- decl.AddAttribute(attrName, args);
- }
- } catch (InvalidCastException) {
- Console.WriteLine("Warning: Cannot translate custom attributes for method\n '{0}':",
- MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
- Console.WriteLine(" >>Skipping attributes, continuing with method translation");
- }
- #endregion
-
- #region Translate body
- var helperTypes = stmtTraverser.TranslateMethod(method);
- if (helperTypes != null) {
- this.privateTypes.AddRange(helperTypes);
- }
- #endregion
-
- #region Create Local Vars For Implementation
- List<Bpl.Variable> vars = new List<Bpl.Variable>();
- foreach (MethodParameter mparam in formalMap) {
- if (!mparam.underlyingParameter.IsByReference)
- vars.Add(mparam.outParameterCopy);
- }
- foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) {
- vars.Add(v);
- }
- // LocalExcVariable holds the exception thrown by any method called from this method, even if this method swallows all exceptions
- if (0 <this.sink.Options.modelExceptions)
- vars.Add(procInfo.LocalExcVariable);
- vars.Add(procInfo.LabelVariable);
- Bpl.VariableSeq vseq = new Bpl.VariableSeq(vars.ToArray());
- #endregion
-
- var translatedBody = stmtTraverser.StmtBuilder.Collect(Bpl.Token.NoToken);
-
- #region Add implementation to Boogie program
- if (proc != null) {
- Bpl.Implementation impl =
- new Bpl.Implementation(method.Token(),
- decl.Name,
- new Microsoft.Boogie.TypeVariableSeq(),
- decl.InParams,
- decl.OutParams,
- vseq,
- translatedBody);
-
- impl.Proc = proc;
- this.sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
- } else { // method is translated as a function
- //var func = decl as Bpl.Function;
- //Contract.Assume(func != null);
- //var blocks = new List<Bpl.Block>();
- //var counter = 0;
- //var returnValue = decl.OutParams[0];
- //foreach (var bb in translatedBody.BigBlocks) {
- // var label = bb.LabelName ?? "L" + counter++.ToString();
- // var newTransferCmd = (bb.tc is Bpl.ReturnCmd)
- // ? new Bpl.ReturnExprCmd(bb.tc.tok, Bpl.Expr.Ident(returnValue))
- // : bb.tc;
- // var b = new Bpl.Block(bb.tok, label, bb.simpleCmds, newTransferCmd);
- // blocks.Add(b);
- //}
- //var localVars = new Bpl.VariableSeq();
- //localVars.Add(returnValue);
- //func.Body = new Bpl.CodeExpr(localVars, blocks);
- }
- #endregion
-
- } catch (TranslationException te) {
- Console.WriteLine("Translation error in body of \n '{0}':",
- MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
- Console.WriteLine("\t" + te.Message);
- } catch (Exception e) {
- Console.WriteLine("Error encountered during translation of \n '{0}':",
- MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
- Console.WriteLine("\t>>" + e.Message);
- } finally {
- }
- }
-
- private static List<IStatement> InitializeFieldsInConstructor(IMethodDefinition method) {
- Contract.Ensures(Contract.Result<List<IStatement>>() != null);
- var inits = new List<IStatement>();
- if (method.IsConstructor || method.IsStaticConstructor) {
- var smb = method.Body as ISourceMethodBody;
- if (method.IsStaticConstructor || (smb != null && !FindCtorCall.IsDeferringCtor(method, smb.Block))) {
- var thisExp = new ThisReference() { Type = method.ContainingTypeDefinition, };
- foreach (var f in method.ContainingTypeDefinition.Fields) {
- if (f.IsStatic == method.IsStatic) {
- var a = new Assignment() {
- Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, },
- Target = new TargetExpression() { Definition = f, Instance = method.IsConstructor ? thisExp : null, Type = f.Type },
- Type = f.Type,
- };
- inits.Add(new ExpressionStatement() { Expression = a, });
- }
- }
- }
- }
- return inits;
- }
- // TODO: do a type test, not a string test for the attribute
- private bool IsStubMethod(IMethodDefinition methodDefinition, out IMethodDefinition/*?*/ stubMethod) {
- stubMethod = null;
- var td = GetTypeDefinitionFromAttribute(methodDefinition.Attributes, "BytecodeTranslator.StubAttribute");
- if (td == null)
- td = GetTypeDefinitionFromAttribute(methodDefinition.ContainingTypeDefinition.Attributes, "BytecodeTranslator.StubAttribute");
- if (td != null) {
- foreach (var mem in td.GetMatchingMembersNamed(methodDefinition.Name, false,
- tdm => {
- var md = tdm as IMethodDefinition;
- return md != null && MemberHelper.MethodsAreEquivalent(methodDefinition, md);
- })) {
- stubMethod = mem as IMethodDefinition;
- return true;
- }
- }
- return false;
- }
- public static ITypeDefinition/*?*/ GetTypeDefinitionFromAttribute(IEnumerable<ICustomAttribute> attributes, string attributeName) {
- ICustomAttribute foundAttribute = null;
- foreach (ICustomAttribute attribute in attributes) {
- if (TypeHelper.GetTypeName(attribute.Type) == attributeName) {
- foundAttribute = attribute;
- break;
- }
- }
- if (foundAttribute == null) return null;
- List<IMetadataExpression> args = new List<IMetadataExpression>(foundAttribute.Arguments);
- if (args.Count < 1) return null;
- IMetadataTypeOf abstractTypeMD = args[0] as IMetadataTypeOf;
- if (abstractTypeMD == null) return null;
- ITypeReference referencedTypeReference = Microsoft.Cci.MutableContracts.ContractHelper.Unspecialized(abstractTypeMD.TypeToGet);
- ITypeDefinition referencedTypeDefinition = referencedTypeReference.ResolvedType;
- return referencedTypeDefinition;
- }
-
- public override void TraverseChildren(IFieldDefinition fieldDefinition) {
- Bpl.Variable fieldVar= this.sink.FindOrCreateFieldVariable(fieldDefinition);
-
- // if tracked by the phone plugin, we need to find out the bpl assigned name for future use
- if (PhoneCodeHelper.instance().PhonePlugin != null) {
- trackControlVariableName(fieldDefinition, fieldVar);
- trackNavigationVariableName(fieldDefinition, fieldVar);
- }
- }
-
- private static void trackNavigationVariableName(IFieldDefinition fieldDefinition, Bpl.Variable fieldVar) {
- if (fieldDefinition.Name.Value.Equals(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE)) {
- PhoneCodeHelper.instance().setBoogieNavigationVariable(fieldVar.Name);
- }
- }
-
- private static void trackControlVariableName(IFieldDefinition fieldDefinition, Bpl.Variable fieldVar) {
- INamespaceTypeReference namedContainerRef = fieldDefinition.ContainingType as INamespaceTypeReference;
- if (namedContainerRef != null) {
- string containerName = namedContainerRef.ContainingUnitNamespace.Unit.Name.Value + "." + namedContainerRef.Name.Value;
- IEnumerable<ControlInfoStructure> controls = PhoneCodeHelper.instance().PhonePlugin.getControlsForPage(containerName);
- if (controls != null) {
- ControlInfoStructure ctrlInfo = controls.FirstOrDefault(ctrl => ctrl.Name == fieldDefinition.Name.Value);
- if (ctrlInfo != null)
- ctrlInfo.BplName = fieldVar.Name;
- }
- }
- }
- #endregion
-
- private void addPhoneTopLevelDeclarations() {
- if (PhoneCodeHelper.instance().PhoneNavigationToggled) {
- Bpl.Variable continueOnPageVar = sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_CONTINUE_ON_PAGE_VARIABLE, Bpl.Type.Bool);
- sink.TranslatedProgram.TopLevelDeclarations.Add(continueOnPageVar);
- Bpl.Variable navigationCheckVar = sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool);
- sink.TranslatedProgram.TopLevelDeclarations.Add(navigationCheckVar);
- }
- }
-
- #region Public API
- public virtual void TranslateAssemblies(IEnumerable<IUnit> assemblies) {
- if (PhoneCodeHelper.instance().PhonePlugin != null)
- addPhoneTopLevelDeclarations();
-
- foreach (var a in assemblies) {
- this.Traverse((IAssembly)a);
- }
- }
- #endregion
-
- #region Helpers
- private class FindCtorCall : CodeTraverser {
- private bool isDeferringCtor = false;
- public ITypeReference containingType;
- public static bool IsDeferringCtor(IMethodDefinition method, IBlockStatement body) {
- var fcc = new FindCtorCall(method.ContainingType);
- fcc.Traverse(body);
- return fcc.isDeferringCtor;
- }
- private FindCtorCall(ITypeReference containingType) {
- this.containingType = containingType;
- }
- public override void TraverseChildren(IMethodCall methodCall) {
- var md = methodCall.MethodToCall.ResolvedMethod;
- if (md != null && md.IsConstructor && methodCall.ThisArgument is IThisReference) {
- this.isDeferringCtor = TypeHelper.TypesAreEquivalent(md.ContainingType, containingType);
- return;
- }
- base.TraverseChildren(methodCall);
- }
- }
-
- #endregion
-
- }
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs
deleted file mode 100644
index a5ed9cf3..00000000
--- a/BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Microsoft.Cci.MutableCodeModel;
-
-namespace BytecodeTranslator.Phone {
- class PhoneBackKeyCallbackTraverser : CodeTraverser {
- private ITypeReference typeBeingTraversed;
- private IMetadataHost host;
-
- public PhoneBackKeyCallbackTraverser(IMetadataHost host) {
- this.host = host;
- }
-
- public override void TraverseChildren(ITypeDefinition typeDef) {
- typeBeingTraversed = typeDef;
- base.TraverseChildren(typeDef);
- }
-
- public override void TraverseChildren(IMethodCall methodCall) {
- if (methodCall.MethodToCall.ResolvedMethod.IsSpecialName && methodCall.MethodToCall.Name.Value == "add_BackKeyPress") {
- // check if it is a back key handler and if it is...
- // NAVIGATION TODO this only catches really locally delegate expressions. If it is created before, we see it as a BoundExpression
- // NAVIGATION TODO and need (again) data flow analysis
- bool delegateIsIdentified= false;
- bool delegateIsAnonymous = false;
- PhoneCodeHelper.instance().OnBackKeyPressOverriden = true;
- IBlockStatement delegateBody = null;
- IMethodDefinition delegateMethodRef= null;
- if (methodCall.Arguments.Count() == 1) {
- IExpression delegateArg= methodCall.Arguments.First();
- ICreateDelegateInstance localDelegate = delegateArg as ICreateDelegateInstance;
- if (localDelegate != null) {
- delegateIsIdentified = true;
- delegateMethodRef = localDelegate.MethodToCallViaDelegate.ResolvedMethod;
- SourceMethodBody body= delegateMethodRef.Body as SourceMethodBody;
- if (body != null)
- delegateBody = body.Block;
-
- PhoneCodeHelper.instance().KnownBackKeyHandlers.Add(delegateMethodRef);
- }
-
- AnonymousDelegate anonDelegate = delegateArg as AnonymousDelegate;
- if (anonDelegate != null) {
- delegateIsIdentified = true;
- delegateIsAnonymous = true;
- delegateBody = anonDelegate.Body;
- }
-
- // NAVIGATION TODO what if it has no body?
- if (delegateBody != null) {
- bool navigates= false, cancelsNav= false;
- ICollection<string> navTargets;
- parseBlockForNavigation(delegateBody, out navigates, out navTargets);
- if (navigates) {
- ICollection<Tuple<IMethodReference,string>> targets = null;
- if (!PhoneCodeHelper.instance().BackKeyNavigatingOffenders.TryGetValue(typeBeingTraversed, out targets)) {
- targets = new HashSet<Tuple<IMethodReference,string>>();
- }
-
- foreach (string tgt in navTargets) {
- IMethodReference dummyRef=null;
- if (delegateIsAnonymous) {
- dummyRef = new Microsoft.Cci.MutableCodeModel.MethodReference();
- (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).ContainingType= typeBeingTraversed;
- (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).Name = Dummy.Name;
- }
- targets.Add(Tuple.Create<IMethodReference, string>((delegateIsAnonymous ? dummyRef : delegateMethodRef), "\"" + tgt + "\""));
- }
-
- PhoneCodeHelper.instance().BackKeyNavigatingOffenders[typeBeingTraversed] = targets;
- }
-
- parseBlockForEventCancellation(delegateBody, out cancelsNav);
- if (cancelsNav) {
- string reason= "(via delegate ";
- if (delegateIsIdentified)
- reason += delegateMethodRef.ContainingType.ToString() + "." + delegateMethodRef.Name.Value;
- else
- reason += "anonymous";
- reason += ")";
- PhoneCodeHelper.instance().BackKeyCancellingOffenders.Add(Tuple.Create<ITypeReference,string>(typeBeingTraversed, reason));
- }
- }
- }
-
- if (!delegateIsIdentified) {
- PhoneCodeHelper.instance().BackKeyHandlerOverridenByUnknownDelegate = true;
- PhoneCodeHelper.instance().BackKeyUnknownDelegateOffenders.Add(typeBeingTraversed);
- }
- }
- base.TraverseChildren(methodCall);
- }
-
- private void parseBlockForNavigation(IBlockStatement block, out bool navigates, out ICollection<string> navTargets) {
- PhoneNavigationCallsTraverser traverser = new PhoneNavigationCallsTraverser(host);
- traverser.Traverse(block);
- navigates = traverser.CodeDoesNavigation;
- navTargets = traverser.NavigationTargets;
- }
-
- private void parseBlockForEventCancellation(IBlockStatement block, out bool cancels) {
- PhoneNavigationCallsTraverser traverser = new PhoneNavigationCallsTraverser(host);
- traverser.Traverse(block);
- cancels = traverser.CancelsEvents;
- }
- }
-
- public class PhoneNavigationCallsTraverser : CodeTraverser {
- private IMetadataHost host;
-
- public bool CancelsEvents { get; private set; }
- public bool CodeDoesNavigation { get; private set; }
- public ICollection<string> NavigationTargets { get; private set; }
- public PhoneNavigationCallsTraverser(IMetadataHost host) {
- CancelsEvents = CodeDoesNavigation = false;
- NavigationTargets = new HashSet<string>();
- this.host = host;
- }
-
- public override void TraverseChildren(IMethodCall call) {
- checkMethodCallForEventCancellation(call);
- checkMethodCallForNavigation(call);
- }
-
- private void checkMethodCallForEventCancellation(IMethodCall call) {
- // NAVIGATION TODO this code is duplicated from PhoneNavigationTraverser, refactor that
- if (!call.MethodToCall.Name.Value.StartsWith("set_Cancel"))
- return;
-
- if (call.Arguments.Count() != 1 || call.Arguments.ToList()[0].Type != host.PlatformType.SystemBoolean)
- return;
-
- ICompileTimeConstant constant = call.Arguments.ToList()[0] as ICompileTimeConstant;
- if (constant != null && constant.Value != null) {
- CompileTimeConstant falseConstant = new CompileTimeConstant() {
- Type = host.PlatformType.SystemBoolean,
- Value = false,
- };
- if (constant.Value == falseConstant.Value)
- return;
- }
-
- CancelsEvents = true;
- }
-
- private void checkMethodCallForNavigation(IMethodCall call) {
- // NAVIGATION TODO this code is duplicated from PhoneNavigationTraverser, refactor that
- string targetUri = null;
- if (!call.MethodToCall.ContainingType.isNavigationServiceClass(host))
- return;
-
- if (!PhoneCodeHelper.NAV_CALLS.Contains(call.MethodToCall.Name.Value) || call.MethodToCall.Name.Value == "GoBack") // back is actually ok
- return;
-
- if (call.MethodToCall.Name.Value == "Navigate") {
- try {
- IExpression expr = call.Arguments.First();
- bool isStatic = UriHelper.isArgumentURILocallyCreatedStatic(expr, host, out targetUri) ||
- UriHelper.isArgumentURILocallyCreatedStaticRoot(expr, host, out targetUri);
- if (!isStatic)
- targetUri = "--Other non inferrable target--";
- else
- targetUri = UriHelper.getURIBase(targetUri);
- } catch (InvalidOperationException) {
- }
- }
- CodeDoesNavigation= true;
- NavigationTargets.Add(targetUri);
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs b/BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs
deleted file mode 100644
index 98727b1e..00000000
--- a/BCT/BytecodeTranslator/Phone/PhoneCodeHelper.cs
+++ /dev/null
@@ -1,865 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Bpl=Microsoft.Boogie;
-using TranslationPlugins;
-using Microsoft.Cci.MutableCodeModel;
-using System.IO;
-using ILGarbageCollect;
-
-namespace BytecodeTranslator.Phone {
- public static class UriHelper {
- /// <summary>
- /// uri is a valid URI but possibly partial (incomplete ?arg= values) and overspecified (complete ?arg=values)
- /// This method returns a base URI
- /// </summary>
- /// <param name="uri"></param>
- /// <returns></returns>
- public static string getURIBase(string uri) {
- // I need to build an absolute URI just to call getComponents() ...
- Uri mockBaseUri = new Uri("mock://mock/", UriKind.RelativeOrAbsolute);
- Uri realUri;
- try {
- realUri = new Uri(uri, UriKind.Absolute);
- } catch (UriFormatException) {
- // uri string is relative
- realUri = new Uri(mockBaseUri, uri);
- }
-
- string str = realUri.GetComponents(UriComponents.Path | UriComponents.StrongAuthority | UriComponents.Scheme, UriFormat.UriEscaped);
- Uri mockStrippedUri = new Uri(str);
- /*
- Uri relativeUri = mockBaseUri.MakeRelativeUri(mockStrippedUri);
- return relativeUri.ToString();
- */
- // TODO PATCH this works for now because we are ignoring non-flat XAML structures
- return mockStrippedUri.Segments.Last();
- }
-
- /// <summary>
- /// checks if argument is locally created URI with static URI target
- /// </summary>
- /// <param name="arg"></param>
- /// <returns></returns>
- public static bool isArgumentURILocallyCreatedStatic(IExpression arg, IMetadataHost host, out string uri) {
- uri = null;
- ICreateObjectInstance creationSite = arg as ICreateObjectInstance;
- if (creationSite == null)
- return false;
-
- if (!arg.Type.isURIClass(host))
- return false;
-
- IExpression uriTargetArg = creationSite.Arguments.First();
-
- if (!uriTargetArg.Type.isStringClass(host))
- return false;
-
- ICompileTimeConstant staticURITarget = uriTargetArg as ICompileTimeConstant;
- if (staticURITarget == null)
- return false;
-
- uri= staticURITarget.Value as string;
- return true;
- }
-
- /// <summary>
- /// checks if argument is locally created URI where target has statically created URI root
- /// </summary>
- /// <param name="arg"></param>
- /// <returns></returns>
- public static bool isArgumentURILocallyCreatedStaticRoot(IExpression arg, IMetadataHost host, out string uri) {
- // Pre: !isArgumentURILocallyCreatedStatic
- uri = null;
- ICreateObjectInstance creationSite = arg as ICreateObjectInstance;
- if (creationSite == null)
- return false;
-
- if (!arg.Type.isURIClass(host))
- return false;
-
- IExpression uriTargetArg = creationSite.Arguments.First();
-
- if (!uriTargetArg.Type.isStringClass(host))
- return false;
-
- if (!uriTargetArg.IsStaticURIRootExtractable(out uri))
- return false;
-
- return true;
- }
-
-
- /// <summary>
- /// checks whether a static URI root (a definite page base) can be extracted from the expression
- /// </summary>
- /// <param name="expr"></param>
- /// <returns></returns>
- public static bool IsStaticURIRootExtractable(this IExpression expr, out string uri) {
- // Pre expr.type == string
- IMethodCall stringConcatExpr = expr as IMethodCall;
- uri = null;
- if (stringConcatExpr == null)
- return false;
-
- if (stringConcatExpr.MethodToCall.Name.Value != "Concat")
- return false;
-
- IList<string> constantStrings = new List<string>();
-
- // TODO this misses so many "static" strings, but let's start with this for now
- IExpression leftOp = stringConcatExpr.Arguments.FirstOrDefault();
- while (leftOp != null && leftOp is ICompileTimeConstant) {
- ICompileTimeConstant strConst = leftOp as ICompileTimeConstant;
- constantStrings.Add(strConst.Value as string);
- if (stringConcatExpr.Arguments.ToList()[1] is IMethodCall) {
- stringConcatExpr = stringConcatExpr.Arguments.ToList()[1] as IMethodCall;
- leftOp = stringConcatExpr.Arguments.FirstOrDefault();
- } else if (stringConcatExpr.Arguments.ToList()[1] is ICompileTimeConstant) {
- constantStrings.Add((stringConcatExpr.Arguments.ToList()[1] as ICompileTimeConstant).Value as string);
- break;
- } else {
- break;
- }
- }
-
- if (constantStrings.Count > 0) {
- uri = constantStrings.Aggregate((aggr, elem) => aggr + elem);
- return Uri.IsWellFormedUriString(uri, UriKind.RelativeOrAbsolute);
- } else {
- return false;
- }
- }
- }
-
- public static class PhoneTypeHelper {
- public static IAssemblyReference getSystemAssemblyReference(IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- IAssemblyReference coreAssemblyRef = platform.CoreAssemblyRef;
- AssemblyIdentity MSPhoneSystemAssemblyId =
- new AssemblyIdentity(host.NameTable.GetNameFor("System"), coreAssemblyRef.Culture, coreAssemblyRef.Version,
- coreAssemblyRef.PublicKeyToken, "");
- return host.FindAssembly(MSPhoneSystemAssemblyId);
- }
-
- public static IAssemblyReference getCoreAssemblyReference(IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- return platform.CoreAssemblyRef;
- }
-
- public static IAssemblyReference getSystemWindowsAssemblyReference(IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- IAssemblyReference coreAssemblyRef = platform.CoreAssemblyRef;
- AssemblyIdentity MSPhoneSystemWindowsAssemblyId =
- new AssemblyIdentity(host.NameTable.GetNameFor("System.Windows"), coreAssemblyRef.Culture, coreAssemblyRef.Version,
- coreAssemblyRef.PublicKeyToken, "");
- return host.FindAssembly(MSPhoneSystemWindowsAssemblyId);
- }
-
- public static IAssemblyReference getPhoneAssemblyReference(IMetadataHost host) {
- AssemblyIdentity MSPhoneAssemblyId =
- new AssemblyIdentity(host.NameTable.GetNameFor("Microsoft.Phone"), "", new Version("7.0.0.0"),
- new byte[] { 0x24, 0xEE, 0xC0, 0xD8, 0xC8, 0x6C, 0xDA, 0x1E }, "");
- return host.FindAssembly(MSPhoneAssemblyId);
- }
-
- public static bool isCancelEventArgsClass(this ITypeReference typeRef, IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- IAssemblyReference systemAssembly = getSystemAssemblyReference(host);
- ITypeReference cancelEventArgsClass = platform.CreateReference(systemAssembly, "System", "ComponentModel", "CancelEventArgs");
- return typeRef.isClass(cancelEventArgsClass);
- }
-
- public static bool isPhoneApplicationClass(this ITypeReference typeRef, IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- IAssemblyReference systemAssembly = PhoneTypeHelper.getSystemWindowsAssemblyReference(host);
- ITypeReference applicationClass = platform.CreateReference(systemAssembly, "System", "Windows", "Application");
- return typeRef.isClass(applicationClass);
- }
-
- public static bool isPhoneApplicationPageClass(this ITypeReference typeRef, IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- IAssemblyReference phoneAssembly = PhoneTypeHelper.getPhoneAssemblyReference(host);
- ITypeReference phoneApplicationPageTypeRef = platform.CreateReference(phoneAssembly, "Microsoft", "Phone", "Controls", "PhoneApplicationPage");
-
- return typeRef.isClass(phoneApplicationPageTypeRef);
- }
-
- public static bool isClass(this ITypeReference typeRef, ITypeReference targetTypeRef) {
- while (typeRef != null) {
- if (typeRef.ResolvedType.Equals(targetTypeRef.ResolvedType))
- return true;
-
- typeRef = typeRef.ResolvedType.BaseClasses.FirstOrDefault();
- }
-
- return false;
- }
-
- public static bool isStringClass(this ITypeReference typeRef, IMetadataHost host) {
- ITypeReference targetType = host.PlatformType.SystemString;
- return typeRef.isClass(targetType);
- }
-
- public static bool isURIClass(this ITypeReference typeRef, IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platformType = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- if (platformType == null)
- return false;
-
- IAssemblyReference coreRef = platformType.CoreAssemblyRef;
- AssemblyIdentity systemAssemblyId = new AssemblyIdentity(host.NameTable.GetNameFor("System"), "", coreRef.Version, coreRef.PublicKeyToken, "");
- IAssemblyReference systemAssembly = host.FindAssembly(systemAssemblyId);
-
- ITypeReference uriTypeRef = platformType.CreateReference(systemAssembly, "System", "Uri");
- return typeRef.isClass(uriTypeRef);
- }
-
- public static bool isNavigationServiceClass(this ITypeReference typeRef, IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- IAssemblyReference phoneAssembly = getPhoneAssemblyReference(host);
- ITypeReference phoneApplicationPageTypeRef = platform.CreateReference(phoneAssembly, "System", "Windows", "Navigation", "NavigationService");
-
- return typeRef.isClass(phoneApplicationPageTypeRef);
- }
-
- public static bool isRoutedEventHandlerClass(this ITypeReference typeRef, IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType; ;
- IAssemblyReference systemAssembly = getSystemWindowsAssemblyReference(host);
- ITypeReference routedEvHandlerType = platform.CreateReference(systemAssembly, "System", "Windows", "RoutedEventHandler");
- return typeRef.isClass(routedEvHandlerType);
-
- }
-
- public static bool isMessageBoxClass(this ITypeReference typeRef, IMetadataHost host) {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType; ;
- IAssemblyReference systemAssembly = getSystemWindowsAssemblyReference(host);
- ITypeReference mbType = platform.CreateReference(systemAssembly, "System", "Windows", "MessageBox");
- return typeRef.isClass(mbType);
- }
-
- }
-
- public enum StaticURIMode {
- NOT_STATIC, STATIC_URI_CREATION_ONSITE, STATIC_URI_ROOT_CREATION_ONSITE,
- }
-
- public class PhoneCodeHelper {
- // TODO refactor into Feedbakc and Navigation specific code, this is already a mess
- private const string IL_BOOGIE_VAR_PREFIX = "@__BOOGIE_";
- private const string BOOGIE_VAR_PREFIX = "__BOOGIE_";
- public const string IL_CURRENT_NAVIGATION_URI_VARIABLE = IL_BOOGIE_VAR_PREFIX + "CurrentNavigationURI__";
- public const string BOOGIE_CONTINUE_ON_PAGE_VARIABLE = BOOGIE_VAR_PREFIX + "ContinueOnPage__";
- public const string BOOGIE_NAVIGATION_CHECK_VARIABLE = BOOGIE_VAR_PREFIX + "Navigated__";
- public const string BOOGIE_STARTING_URI_PLACEHOLDER = "BOOGIE_STARTING_URI_PLACEHOLDER";
- public const string BOOGIE_ENDING_URI_PLACEHOLDER= "BOOGIE_ENDING_URI_PLACEHOLDER";
-
- public static readonly string[] NAV_CALLS = { /*"GoBack", "GoForward", "Navigate", "StopLoading"*/ "Navigate", "GoBack" };
-
- public bool OnBackKeyPressOverriden { get; set; }
- public bool BackKeyPressHandlerCancels { get { return BackKeyCancellingOffenders.Count > 0; } }
- public bool BackKeyPressNavigates { get { return BackKeyNavigatingOffenders.Keys.Count > 0; } }
- public bool BackKeyHandlerOverridenByUnknownDelegate { get; set; }
- public ICollection<Tuple<ITypeReference,string>> BackKeyCancellingOffenders { get; set; }
- public ICollection<ITypeReference> BackKeyUnknownDelegateOffenders { get; set; }
- public Dictionary<ITypeReference, ICollection<Tuple<IMethodReference,string>>> BackKeyNavigatingOffenders { get; set; }
- public ICollection<IMethodReference> KnownBackKeyHandlers { get; set; }
- public ICollection<IMethodReference> KnownNavigatingMethods { get; set; }
- public ICollection<IMethodReference> KnownEventCancellingMethods { get; set; }
-
- private Dictionary<string, string[]> PHONE_UI_CHANGER_METHODS;
-
- private static IMetadataHost host;
- private Microsoft.Cci.Immutable.PlatformType platform;
- private static PhoneCodeHelper _instance;
- private static bool initialized= false;
-
- public static void initialize(IMetadataHost host) {
- if (initialized)
- return;
-
- PhoneCodeHelper.host = host;
- initialized = true;
- }
-
- public static PhoneCodeHelper instance() {
- if (_instance == null) {
- _instance = new PhoneCodeHelper(host);
- }
-
- return _instance;
- }
-
- private PhoneCodeHelper(IMetadataHost host) {
- if (host != null) {
- platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- initializeKnownUIChangers();
-
- BackKeyCancellingOffenders= new HashSet<Tuple<ITypeReference,string>>();
- BackKeyUnknownDelegateOffenders = new HashSet<ITypeReference>();
- BackKeyNavigatingOffenders = new Dictionary<ITypeReference, ICollection<Tuple<IMethodReference,string>>>();
- KnownBackKeyHandlers = new HashSet<IMethodReference>();
- KnownNavigatingMethods = new HashSet<IMethodReference>();
- KnownEventCancellingMethods = new HashSet<IMethodReference>();
- }
- }
-
- private void initializeKnownUIChangers() {
- PHONE_UI_CHANGER_METHODS= new Dictionary<string,string[]>();
- IAssemblyReference systemAssembly = PhoneTypeHelper.getSystemAssemblyReference(host);
- IAssemblyReference systemWinAssembly = PhoneTypeHelper.getSystemWindowsAssemblyReference(host);
- IAssemblyReference phoneAssembly = PhoneTypeHelper.getPhoneAssemblyReference(host);
-
- ITypeReference textBoxType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "TextBox");
- PHONE_UI_CHANGER_METHODS[textBoxType.ToString()] =
- new string[] {"set_BaselineOffset", "set_CaretBrush", "set_FontSource", "set_HorizontalScrollBarVisibility", "set_IsReadOnly", "set_LineHeight",
- "set_LineStackingStrategy", "set_MaxLength", "set_SelectedText", "set_SelectionBackground", "set_SelectionForeground", "set_SelectionLength",
- "set_SelectionStart", "set_Text", "set_TextAlignment", "set_TextWrapping", "set_VerticalScrollBarVisibility", "set_Watermark",
- };
-
- ITypeReference textBlockType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "TextBlock");
- PHONE_UI_CHANGER_METHODS[textBlockType.ToString()] =
- new string[] {"set_BaselineOffset", "set_FontFamily", "set_FontSize", "set_FontSource", "set_FontStretch", "set_FontStyle", "set_FontWeight", "set_Foreground",
- "set_CharacterSpacing", "set_LineHeight", "set_LineStackingStrategy", "set_Padding", "set_Text", "set_TextAlignment", "set_TextDecorations",
- "set_TextTrimming", "set_TextWrapping",
- };
-
- ITypeReference uiElementType = platform.CreateReference(systemAssembly, "System", "Windows", "UIElement");
- PHONE_UI_CHANGER_METHODS[uiElementType.ToString()] =
- new string[] {"set_Clip", "set_Opacity", "set_OpacityMask", "set_Projection", "set_RenderTransform",
- "set_RenderTransformOrigin", "set_Visibility", "Arrange", "InvalidateArrange", "InvalidateMeasure", "SetValue", "ClearValue", // Set/ClearValue are quite unsafe
- "UpdateLayout", "Measure",
- };
-
- ITypeReference frameworkElementType = platform.CreateReference(systemAssembly, "System", "Windows", "FrameworkElement");
- PHONE_UI_CHANGER_METHODS[frameworkElementType.ToString()] =
- new string[] {"set_FlowDirection", "set_Height", "set_HorizontalAlignment", "set_Language", "set_Margin", "set_MaxHeight", "set_MaxWidth",
- "set_MinHeight", "set_MinWidth", "set_Style", "set_VerticalAlignment", "set_Width", "set_Cursor",
- };
-
- ITypeReference borderType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Border");
- PHONE_UI_CHANGER_METHODS[borderType.ToString()] =
- new string[] {"set_Background", "set_BorderBrush", "set_BorderThickness", "set_CornerRadius", "set_Padding",
- };
-
- ITypeReference controlType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Control");
- PHONE_UI_CHANGER_METHODS[controlType.ToString()] =
- new string[] {"set_Background", "set_BorderBrush", "set_BorderThickness", "set_CharacterSpacing", "set_FontFamily", "set_FontSize", "set_FontStretch",
- "set_FontStyle", "set_FontWeight", "set_Foreground", "set_HorizontalContentAlignment", "set_IsEnabled", "set_Padding", "set_VerticalContentAlignment",
- };
-
- ITypeReference contentControlType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "ContentControl");
- PHONE_UI_CHANGER_METHODS[contentControlType.ToString()] = new string[] { "set_Content", };
-
- ITypeReference panelType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Panel");
- PHONE_UI_CHANGER_METHODS[panelType.ToString()] = new string[] { "set_Background", };
-
- ITypeReference canvasType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Canvas");
- PHONE_UI_CHANGER_METHODS[canvasType.ToString()] = new string[] { "set_Left", "set_Top", "set_ZIndex", };
-
- ITypeReference toggleButtonType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Primitives", "ToggleButton");
- PHONE_UI_CHANGER_METHODS[toggleButtonType.ToString()] = new string[] { "set_IsChecked", };
-
- ITypeReference gridType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Grid");
- PHONE_UI_CHANGER_METHODS[gridType.ToString()] = new string[] { "set_ShowGridLines", "set_Column", "set_ColumnSpan", "set_Row", "set_RowSpan", };
-
- ITypeReference imageType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Image");
- PHONE_UI_CHANGER_METHODS[imageType.ToString()] = new string[] { "set_Source", "set_Stretch", };
-
- ITypeReference inkPresenterType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "InkPresenter");
- PHONE_UI_CHANGER_METHODS[inkPresenterType.ToString()] = new string[] { "set_Strokes", };
-
- ITypeReference itemsControlType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "ItemsControl");
- PHONE_UI_CHANGER_METHODS[itemsControlType.ToString()] = new string[] { "set_DisplayMemberPath", "set_ItemsSource", "set_ItemTemplate", };
-
- ITypeReference selectorType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Primitives", "Selector");
- PHONE_UI_CHANGER_METHODS[selectorType.ToString()] =
- new string[] { "set_SelectedIndex", "set_SelectedItem", "set_SelectedValue", "set_SelectedValuePath", };
-
- ITypeReference listBoxType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "ListBox");
- PHONE_UI_CHANGER_METHODS[listBoxType.ToString()] = new string[] { "set_ItemContainerStyle", };
-
- ITypeReference passwordBoxType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "PasswordBox");
- PHONE_UI_CHANGER_METHODS[passwordBoxType.ToString()] =
- new string[] { "set_CaretBrush", "set_FontSource", "set_MaxLength", "set_Password", "set_PasswordChar",
- "set_SelectionBackground", "set_SelectionForeground",
- };
-
- ITypeReference rangeBaseType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Primitives", "RangeBase");
- PHONE_UI_CHANGER_METHODS[rangeBaseType.ToString()] = new string[] { "set_LargeChange", "set_Maximum", "set_Minimum", "set_SmallChange", "set_Value", };
-
- ITypeReference progressBarType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "ProgressBar");
- PHONE_UI_CHANGER_METHODS[progressBarType.ToString()] = new string[] { "set_IsIndeterminate", };
-
- ITypeReference sliderType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "Slider");
- PHONE_UI_CHANGER_METHODS[sliderType.ToString()] = new string[] { "set_IsDirectionReversed", "set_Orientation", };
-
- ITypeReference stackPanelType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "StackPanel");
- PHONE_UI_CHANGER_METHODS[stackPanelType.ToString()] = new string[] { "set_Orientation", };
-
- ITypeReference richTextBoxType = platform.CreateReference(systemAssembly, "System", "Windows", "Controls", "RichTextBox");
- PHONE_UI_CHANGER_METHODS[richTextBoxType.ToString()] =
- new string[] { "set_BaselineOffset", "set_CaretBrush", "set_HorizontalScrollBartVisibility", "set_LineHeight", "set_LineStackingStrategy",
- "set_TextAlignment", "set_TextWrapping", "set_VerticalScrollBarVisibility", "set_Xaml", };
-
- ITypeReference webBrowserTaskType = platform.CreateReference(phoneAssembly, "Microsoft", "Phone", "Tasks", "WebBrowserTask");
- PHONE_UI_CHANGER_METHODS[webBrowserTaskType.ToString()] = new string[] { "Show", };
-
- ITypeReference appBarIconButtonType = platform.CreateReference(phoneAssembly, "Microsoft", "Phone", "Shell", "ApplicationBarIconButton");
- PHONE_UI_CHANGER_METHODS[appBarIconButtonType.ToString()] = new string[] { "set_IsEnabled", "set_IconUri", "set_Text", };
-
- ITypeReference appBarMenuItemType = platform.CreateReference(phoneAssembly, "Microsoft", "Phone", "Shell", "ApplicationBarMenuItem");
- PHONE_UI_CHANGER_METHODS[appBarMenuItemType.ToString()] = new string[] { "set_IsEnabled", "set_Text", };
-
- ITypeReference emailComposeTaskType = platform.CreateReference(phoneAssembly, "Microsoft", "Phone", "Tasks", "EmailComposeTask");
- PHONE_UI_CHANGER_METHODS[emailComposeTaskType.ToString()] = new string[] { "Show", };
-
- ITypeReference scaleTransformType = platform.CreateReference(systemWinAssembly, "System", "Windows", "Media", "ScaleTransform");
- PHONE_UI_CHANGER_METHODS[scaleTransformType.ToString()] = new string[] { "set_CenterX", "set_CenterY", "set_ScaleX", "set_ScaleY", };
- }
-
- // TODO externalize strings
- public static readonly string[] IgnoredEvents =
- { "Loaded",
- };
-
- // awful hack. want to insert a nonexisting method call while traversing CCI AST, deferring it to Boogie translation
- public const string BOOGIE_DO_HAVOC_CURRENTURI = BOOGIE_VAR_PREFIX + "Havoc_CurrentURI__";
-
- public PhoneControlsPlugin PhonePlugin { get; set; }
- private IDictionary<string, Bpl.NamedDeclaration> boogieObjects = new Dictionary<string, Bpl.NamedDeclaration>();
-
- public Bpl.Variable getBoogieVariableForName(string varName) {
- Bpl.Variable boogieVar = null;
- try {
- boogieVar = boogieObjects[varName] as Bpl.Variable;
- } catch (KeyNotFoundException) {
- }
-
- if (boogieVar == null)
- throw new ArgumentException("The boogie variable " + varName + " is not defined.");
-
- return boogieVar;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="name"></param>
- /// <param name="bplObject"></param>
- /// <returns>true if defining a new name, false if replacing</returns>
- public bool setBoogieObjectForName(string name, Bpl.NamedDeclaration bplObject) {
- bool ret = true;
- if (boogieObjects.ContainsKey(name))
- ret = false;
-
- boogieObjects[name] = bplObject;
- return ret;
- }
-
- private bool isPhoneUIChangerClass(ITypeReference typeRef) {
- return PHONE_UI_CHANGER_METHODS.Keys.Contains(typeRef.ToString());
- }
-
- public bool isNavigationCall(IMethodCall call) {
- ITypeReference callType = call.MethodToCall.ContainingType;
- if (!callType.isNavigationServiceClass(host))
- return false;
-
- return NAV_CALLS.Contains(call.MethodToCall.Name.Value);
- }
-
- private ITypeReference mainAppTypeRef;
- public void setMainAppTypeReference(ITypeReference appType) {
- mainAppTypeRef = appType;
- }
-
- public ITypeReference getMainAppTypeReference() {
- return mainAppTypeRef;
- }
-
- public void setBoogieNavigationVariable(string var) {
- PhonePlugin.setBoogieNavigationVariable(var);
- }
-
- public string getBoogieNavigationVariable() {
- return PhonePlugin.getBoogieNavigationVariable();
- }
-
- public string getXAMLForPage(string pageClass) {
- return PhonePlugin.getXAMLForPage(pageClass);
- }
-
- public void setBoogieStringPageNameForPageClass(string pageClass, string boogieStringName) {
- PhonePlugin.setBoogieStringPageNameForPageClass(pageClass, boogieStringName);
- }
-
- public void setMainAppTypeName(string fullyQualifiedName) {
- PhonePlugin.setMainAppTypeName(fullyQualifiedName);
- }
-
- public string getMainAppTypeName() {
- return PhonePlugin.getMainAppTypeName();
- }
-
- public Bpl.AssignCmd createBoogieNavigationUpdateCmd(Sink sink) {
- // the block is a potential page changer
- List<Bpl.AssignLhs> lhs = new List<Bpl.AssignLhs>();
- List<Bpl.Expr> rhs = new List<Bpl.Expr>();
- Bpl.Expr value = new Bpl.LiteralExpr(Bpl.Token.NoToken, false);
- rhs.Add(value);
- Bpl.SimpleAssignLhs assignee =
- new Bpl.SimpleAssignLhs(Bpl.Token.NoToken,
- new Bpl.IdentifierExpr(Bpl.Token.NoToken,
- sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_CONTINUE_ON_PAGE_VARIABLE, Bpl.Type.Bool)));
- lhs.Add(assignee);
- Bpl.AssignCmd assignCmd = new Bpl.AssignCmd(Bpl.Token.NoToken, lhs, rhs);
- return assignCmd;
- }
-
- // TODO do away with these whenever it is possible to make repeated passes at the translator, and handle from Program
- public bool PhoneNavigationToggled { get; set; }
- public bool PhoneFeedbackToggled { get; set; }
-
- public bool isMethodInputHandlerOrFeedbackOverride(IMethodDefinition method) {
- // FEEDBACK TODO: This is extremely coarse. There must be quite a few non-UI routed/non-routed events
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType; ;
- IAssemblyReference coreAssembly= PhoneTypeHelper.getCoreAssemblyReference(host);
- ITypeReference eventArgsType= platform.CreateReference(coreAssembly, "System", "EventArgs");
- foreach (IParameterDefinition paramDef in method.Parameters) {
- if (paramDef.Type.isClass(eventArgsType))
- return true;
- }
-
- return false;
- }
-
- public bool isMethodKnownUIChanger(IMethodCall methodCall) {
- // FEEDBACK TODO join these two with the others
- if (methodCall.MethodToCall.ContainingType.isNavigationServiceClass(host)) {
- return NAV_CALLS.Contains(methodCall.MethodToCall.Name.Value);
- } else if (methodCall.IsStaticCall && methodCall.MethodToCall.ContainingType.isMessageBoxClass(host) &&
- methodCall.MethodToCall.Name.Value == "Show") {
- return true;
- }
-
- // otherwise, it must be a control input call
- // before any method call checks, make sure the receiving object is a Control
- IExpression callee = methodCall.ThisArgument;
- if (callee == null)
- return false;
-
- ITypeReference calleeType = callee.Type;
- while (calleeType.ResolvedType.BaseClasses.Any()) {
- if (isPhoneUIChangerClass(calleeType) && isKnownUIChanger(calleeType, methodCall)) {
- return true;
- }
-
- calleeType = calleeType.ResolvedType.BaseClasses.First();
- }
-
- return false;
- }
-
- private bool isKnownUIChanger(ITypeReference typeRef, IMethodCall call) {
- string methodName= call.MethodToCall.Name.Value;
- IEnumerable<String> methodsForType = PHONE_UI_CHANGER_METHODS[typeRef.ToString()];
- return methodsForType != null && methodsForType.Contains(methodName);
- }
-
- private HashSet<string> ignoredHandlers = new HashSet<string>();
- public void ignoreEventHandler(string fullyQualifiedEventHandler) {
- ignoredHandlers.Add(fullyQualifiedEventHandler);
- }
-
- public bool isMethodIgnoredForFeedback(IMethodDefinition methodTranslated) {
- INamespaceTypeDefinition type= methodTranslated.ContainingType.ResolvedType as INamespaceTypeDefinition;
-
- if (type == null)
- return false;
-
- string methodName = type.ContainingUnitNamespace.Name.Value + "." + type.Name + "." + methodTranslated.Name.Value;
- return ignoredHandlers.Contains(methodName);
- }
-
- private HashSet<Bpl.Procedure> callableMethods = new HashSet<Bpl.Procedure>();
- public void trackCallableMethod(Bpl.Procedure proc) {
- callableMethods.Add(proc);
- }
-
- public IEnumerable<Bpl.Procedure> getCallableMethods() {
- return callableMethods;
- }
-
- public void CreateFeedbackCallingMethods(Sink sink) {
- Bpl.Program translatedProgram= sink.TranslatedProgram;
- foreach (Bpl.Procedure proc in callableMethods) {
- addMethodCalling(proc, translatedProgram, sink);
- }
- }
-
- private void addMethodCalling(Bpl.Procedure proc, Bpl.Program program, Sink sink) {
- Bpl.Procedure callingProc= new Bpl.Procedure(Bpl.Token.NoToken, "__BOOGIE_CALL_" + proc.Name, new Bpl.TypeVariableSeq(), new Bpl.VariableSeq(),
- new Bpl.VariableSeq(), new Bpl.RequiresSeq(), new Bpl.IdentifierExprSeq(), new Bpl.EnsuresSeq());
- sink.TranslatedProgram.TopLevelDeclarations.Add(callingProc);
-
- Bpl.StmtListBuilder codeBuilder = new Bpl.StmtListBuilder();
- Bpl.VariableSeq localVars = new Bpl.VariableSeq(proc.InParams);
- Bpl.IdentifierExprSeq identVars= new Bpl.IdentifierExprSeq();
-
- for (int i = 0; i < localVars.Length; i++) {
- identVars.Add(new Bpl.IdentifierExpr(Bpl.Token.NoToken, localVars[i]));
- }
- codeBuilder.Add(new Bpl.HavocCmd(Bpl.Token.NoToken, identVars));
-
- // FEEDBACK TODO this is possibly too much, I'm guessing sometimes this args might well be null
- Bpl.Expr notNullExpr;
- foreach (Bpl.IdentifierExpr idExpr in identVars) {
- if (idExpr.Type.Equals(sink.Heap.RefType)) {
- notNullExpr= Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, idExpr, Bpl.Expr.Ident(sink.Heap.NullRef));
- codeBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, notNullExpr));
- }
- }
-
- Bpl.ExprSeq callParams = new Bpl.ExprSeq();
- for (int i = 0; i < identVars.Length; i++) {
- callParams.Add(identVars[i]);
- }
- Bpl.CallCmd callCmd = new Bpl.CallCmd(Bpl.Token.NoToken, proc.Name, callParams, new Bpl.IdentifierExprSeq());
- codeBuilder.Add(callCmd);
- Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, callingProc.Name, new Bpl.TypeVariableSeq(), new Bpl.VariableSeq(),
- new Bpl.VariableSeq(), localVars, codeBuilder.Collect(Bpl.Token.NoToken));
- sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
- }
-
- public bool isBackKeyPressOverride(IMethodDefinition method) {
- if (!method.IsVirtual || method.Name.Value != "OnBackKeyPress" || !method.ContainingType.isPhoneApplicationPageClass(host) ||
- method.ParameterCount != 1 || !method.Parameters.ToList()[0].Type.isCancelEventArgsClass(host))
- return false;
- else
- return true;
- }
-
- public bool mustInlineMethod(IMethodDefinition method) {
- if (PhoneFeedbackToggled) {
- // FEEDBACK TODO this may be too coarse
- // top level inlined methods are feedback relevant ones. For now, this is basically everything that has EventArgs as parameters
- if (isMethodInputHandlerOrFeedbackOverride(method))
- return true;
- }
-
- if (PhoneNavigationToggled) {
- // NAVIGATION TODO this may be too coarse
- // for now, assume any method in a PhoneApplicationPage is potentially interesting to navigation inlining
- ITypeReference methodContainer = method.ContainingType;
- if (PhoneTypeHelper.isPhoneApplicationClass(methodContainer, host) || PhoneTypeHelper.isPhoneApplicationPageClass(methodContainer, host))
- return true;
- }
-
- return false;
- }
-
- public void createQueriesBatchFile(Sink sink, string sourceBPLFile) {
- StreamWriter outputStream = new StreamWriter("createQueries.bat");
- IEnumerable<string> xamls= PhonePlugin.getPageXAMLFilenames();
- string startURI= sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER).Name;
- string endURI = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER).Name;
- foreach (string x1 in xamls) {
- string startURIVar= sink.FindOrCreateConstant(x1).Name.ToLower();
- foreach (string x2 in xamls) {
- string resultFile = sourceBPLFile + "_$$" + x1 + "$$_$$" + x2 + "$$.bpl";
- string endURIVar= sink.FindOrCreateConstant(x2).Name.ToLower();
- outputStream.WriteLine("sed s/" + startURI + ";/" + startURIVar + ";/g " + sourceBPLFile + "> " + resultFile);
- outputStream.WriteLine("sed -i s/" + endURI + ";/" + endURIVar + ";/g " + resultFile);
- }
- }
-
- outputStream.Close();
- }
-
-
- public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def) {
- MethodBody callerBody = new MethodBody();
- MethodDefinition callerDef = new MethodDefinition() {
- InternFactory = (def as MethodDefinition).InternFactory,
- ContainingTypeDefinition = def.ContainingTypeDefinition,
- IsStatic = true,
- Name = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value),
- Type = sink.host.PlatformType.SystemVoid,
- Body = callerBody,
- };
- callerBody.MethodDefinition = callerDef;
- Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(def);
- Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef);
-
- Bpl.LocalVariable[] localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Length];
- Bpl.IdentifierExpr[] varExpr = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Length];
- for (int i = 0; i < procInfo.Decl.InParams.Length; i++) {
- Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken,
- new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(),
- procInfo.Decl.InParams[i].TypedIdent.Type));
- localVars[i] = loc;
- varExpr[i] = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc);
- }
-
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- builder.Add(getResetNavigationCheck(sink));
-
- string pageXaml= PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString());
- Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition);
- Bpl.Constant boogieXamlConstant;
- if (pageXaml != null)
- boogieXamlConstant = sink.FindOrCreateConstant(pageXaml);
- else
- boogieXamlConstant = null;
- // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler
- // NAVIGATION TODO: ie, a network event handler
- if (boogieXamlConstant != null) {
- Bpl.AssumeCmd assumeCurrentPage =
- new Bpl.AssumeCmd(Bpl.Token.NoToken,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
- new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
- builder.Add(assumeCurrentPage);
- }
-
- // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed
- boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER);
- Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
- new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
- builder.Add(assumeStartPage);
- builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new Bpl.ExprSeq(varExpr), new Bpl.IdentifierExprSeq()));
- boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER);
- Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
- new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
-
- Bpl.Expr guard= new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool));
- Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder();
- thenBuilder.Add(assertEndPage);
- Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken));
-
- builder.Add(ifNavigated);
- Bpl.Implementation impl =
- new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new Bpl.TypeVariableSeq(), new Bpl.VariableSeq(),
- new Bpl.VariableSeq(), new Bpl.VariableSeq(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors());
-
- sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
- return impl.Proc;
- }
-
- public static void updateInlinedMethods(Sink sink, IEnumerable<IMethodDefinition> doInline) {
- foreach (IMethodDefinition method in doInline) {
- Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(method);
- procInfo.Decl.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE));
- }
- }
-
- public static FieldDefinition CurrentURIFieldDefinition {get; set;}
-
- public void addNavigationUriHavocer(Sink sink) {
- Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(getUriHavocerMethod(sink).ResolvedMethod);
- procInfo.Decl.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE));
- Bpl.StmtListBuilder builder= new Bpl.StmtListBuilder();
- Bpl.HavocCmd havoc=
- new Bpl.HavocCmd(Bpl.Token.NoToken,
- new Bpl.IdentifierExprSeq(new Bpl.IdentifierExprSeq(new Bpl.IdentifierExpr(Bpl.Token.NoToken,
- sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition)))));
- builder.Add(havoc);
- Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, procInfo.Decl.Name, new Bpl.TypeVariableSeq(),
- new Bpl.VariableSeq(), new Bpl.VariableSeq(), new Bpl.VariableSeq(),
- builder.Collect(Bpl.Token.NoToken));
- sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
-
- }
-
- private IMethodReference uriHavocMethod=null;
- public IMethodReference getUriHavocerMethod(Sink sink) {
- if (uriHavocMethod == null) {
- MethodBody body = new MethodBody();
- MethodDefinition havocDef = new MethodDefinition() {
- InternFactory = host.InternFactory,
- ContainingTypeDefinition = PhoneCodeHelper.instance().getMainAppTypeReference().ResolvedType,
- IsStatic = true,
- Name = sink.host.NameTable.GetNameFor(PhoneCodeHelper.BOOGIE_DO_HAVOC_CURRENTURI),
- Type = sink.host.PlatformType.SystemVoid,
- Body = body,
- };
- body.MethodDefinition = havocDef;
- uriHavocMethod = havocDef;
- }
-
- return uriHavocMethod;
- }
-
- public Bpl.Cmd getResetNavigationCheck(Sink sink) {
- return getNavigationCheckAssign(sink, false);
- }
-
- public Bpl.Cmd getAddNavigationCheck(Sink sink) {
- return getNavigationCheckAssign(sink, true);
- }
-
- private Bpl.Cmd getNavigationCheckAssign(Sink sink, bool value) {
- List<Bpl.AssignLhs> lhs = new List<Bpl.AssignLhs>();
- List<Bpl.Expr> rhs = new List<Bpl.Expr>();
- Bpl.AssignLhs assignee = new Bpl.SimpleAssignLhs(Bpl.Token.NoToken, new Bpl.IdentifierExpr(Bpl.Token.NoToken,
- sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool)));
- lhs.Add(assignee);
- rhs.Add(value ? Bpl.IdentifierExpr.True : Bpl.IdentifierExpr.False);
- Bpl.AssignCmd assignCmd = new Bpl.AssignCmd(Bpl.Token.NoToken, lhs, rhs);
- return assignCmd;
- }
-
- public bool isKnownBackKeyOverride(IMethodReference method) {
- return isBackKeyPressOverride(method.ResolvedMethod) ||
- KnownBackKeyHandlers.Contains(method);
- }
-
- internal IEnumerable<IMethodDefinition> getIndirectNavigators(IEnumerable<IModule> modules, IMethodReference method) {
- IEnumerable<IMethodDefinition> reachable = getReachableMethodsFromMethod(method, modules);
- reachable= reachable.Except(new IMethodDefinition[] { method.ResolvedMethod });
- return getResolvedMethods(KnownNavigatingMethods).Intersect(reachable);
- }
-
- internal IEnumerable<IMethodDefinition> getIndirectCancellations(IEnumerable<IModule> modules, IMethodReference method) {
- IEnumerable<IMethodDefinition> reachable = getReachableMethodsFromMethod(method, modules);
- reachable = reachable.Except(new IMethodDefinition[] { method.ResolvedMethod });
- return getResolvedMethods(KnownEventCancellingMethods).Intersect(reachable);
- }
-
- internal IEnumerable<IMethodDefinition> getReachableMethodsFromMethod(IMethodReference method, IEnumerable<IModule> modules) {
- IEnumerable<IAssembly> assemblies = getAssembliesFromModules(modules);
- Microsoft.Cci.MetadataReaderHost readerHost = host as Microsoft.Cci.MetadataReaderHost;
-
- if (readerHost == null)
- return new List<IMethodDefinition>(); //?
-
- ILGarbageCollect.Mark.WholeProgram program = new ILGarbageCollect.Mark.WholeProgram(assemblies, readerHost);
- RapidTypeAnalysis analyzer = new RapidTypeAnalysis(program, TargetProfile.Phone);
- analyzer.Run(new IMethodReference[] { method });
- return analyzer.ReachableMethods();
- }
-
- internal IEnumerable<IAssembly> getAssembliesFromModules(IEnumerable<IModule> modules) {
- IList<IAssembly> assemblies = new List<IAssembly>();
- foreach (IModule module in modules) {
- IAssembly assembly = module as IAssembly;
- if (assembly != null)
- assemblies.Add(assembly);
- }
-
- return assemblies;
- }
-
- internal IEnumerable<IMethodDefinition> getResolvedMethods(IEnumerable<IMethodReference> methRefs) {
- IList<IMethodDefinition> methDefs = new List<IMethodDefinition>();
- foreach (IMethodReference methRef in methRefs) {
- methDefs.Add(methRef.ResolvedMethod);
- }
-
- return methDefs;
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs
deleted file mode 100644
index 0ed9270c..00000000
--- a/BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Microsoft.Cci.MutableCodeModel;
-
-namespace BytecodeTranslator.Phone {
- class PhoneControlFeedbackCodeTraverser : CodeTraverser {
- private IMetadataReaderHost host;
-
- public PhoneControlFeedbackCodeTraverser(IMetadataReaderHost host) : base() {
- this.host = host;
- }
-
- public override void TraverseChildren(IMethodCall methodCall) {
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
- // check for handlers we do not wish to add feedback checks to
- if (methodCall.MethodToCall.Name.Value.StartsWith("add_")) {
- string eventName = methodCall.MethodToCall.Name.Value.Remove(0, "add_".Length);
- if (PhoneCodeHelper.IgnoredEvents.Contains(eventName)) {
- IMethodReference eventHandler = null;
- foreach (IExpression arg in methodCall.Arguments) {
- ICreateDelegateInstance createDelegate = arg as ICreateDelegateInstance;
- if (createDelegate == null)
- continue;
-
- ITypeReference typeRef = createDelegate.Type;
- if (!typeRef.isRoutedEventHandlerClass(host))
- continue;
-
- eventHandler = createDelegate.MethodToCallViaDelegate;
- break;
- }
-
- if (eventHandler != null) {
- INamespaceTypeReference namedType = eventHandler.ContainingType.ResolvedType as INamespaceTypeReference;
- if (namedType != null) {
- INamespaceTypeDefinition namedTypeDef = namedType.ResolvedType;
- if (namedTypeDef != null) {
- PhoneCodeHelper.instance().ignoreEventHandler(namedTypeDef.ContainingUnitNamespace.Name + "." + namedTypeDef.Name + "." + eventHandler.Name);
- }
- }
- }
- }
- }
- }
- }
-
- }
-
- class PhoneControlFeedbackMetadataTraverser : MetadataTraverser {
- private IMetadataReaderHost host;
-
- public PhoneControlFeedbackMetadataTraverser(IMetadataReaderHost host) : base() {
- this.host = host;
- }
-
- public override void TraverseChildren(IMethodDefinition method) {
- PhoneControlFeedbackCodeTraverser codeTraverser = new PhoneControlFeedbackCodeTraverser(host);
- codeTraverser.TraverseChildren(method);
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs
deleted file mode 100644
index db1aac4c..00000000
--- a/BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs
+++ /dev/null
@@ -1,377 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics.Contracts;
-using TranslationPlugins;
-
-
-namespace BytecodeTranslator.Phone {
-
- /// <summary>
- /// Traverse code looking for phone specific points of interest, possibly injecting necessary code in-between
- /// </summary>
- public class PhoneInitializationCodeTraverser : CodeTraverser {
- private readonly IMethodDefinition methodBeingTraversed;
- private static bool initializationFound= false;
- private MetadataReaderHost host;
-
- private IAssemblyReference coreAssemblyRef;
- private IAssemblyReference phoneAssembly;
- private IAssemblyReference phoneSystemWindowsAssembly;
- private IAssemblyReference MSPhoneControlsAssembly;
- private INamespaceTypeReference appBarIconButtonType;
- private INamespaceTypeReference appBarMenuItemType;
- private INamespaceTypeReference checkBoxType;
- private INamespaceTypeReference radioButtonType;
- private INamespaceTypeReference buttonType;
- private INamespaceTypeReference buttonBaseType;
- private INamespaceTypeReference toggleButtonType;
- private INamespaceTypeReference controlType;
- private INamespaceTypeReference uiElementType;
- private INamespaceTypeReference pivotType;
- private INamespaceTypeReference listBoxType;
-
- private CompileTimeConstant trueConstant;
- private CompileTimeConstant falseConstant;
-
- private IMethodReference isEnabledSetter;
- private IMethodReference isEnabledGetter;
- private IMethodReference isCheckedSetter;
- private IMethodReference isCheckedGetter;
- private IMethodReference visibilitySetter;
- private IMethodReference visibilityGetter;
- private IMethodReference clickHandlerAdder;
- private IMethodReference clickHandlerRemover;
- private IMethodReference checkedHandlerAdder;
- private IMethodReference checkedHandlerRemover;
- private IMethodReference uncheckedHandlerAdder;
- private IMethodReference uncheckedHandlerRemover;
-
- private ITypeReference getTypeForClassname(String classname) {
- if (classname == "Button") {
- return buttonType;
- } else if (classname == "RadioButton") {
- return radioButtonType;
- } else if (classname == "CheckBox") {
- return checkBoxType;
- } else if (classname == "ApplicationBarIconButton") {
- return appBarIconButtonType;
- } else if (classname == "ApplicationBarMenuItem") {
- return appBarMenuItemType;
- } else if (classname == "Pivot") {
- return pivotType;
- } else if (classname == "ListBox") {
- return listBoxType;
- } else if (classname == "DummyType") {
- // return Dummy.Type;
- return host.PlatformType.SystemObject;
- } else {
- // TODO avoid throwing exceptions, just log
- throw new NotImplementedException("Type " + classname + " is not being monitored yet for phone controls");
- }
- }
-
- public PhoneInitializationCodeTraverser(MetadataReaderHost host, IMethodDefinition traversedMethod) : base() {
- this.methodBeingTraversed = traversedMethod;
- this.host = host;
- InitializeTraverser();
- }
-
- private void InitializeTraverser() {
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
- coreAssemblyRef = platform.CoreAssemblyRef;
-
- // TODO obtain version, culture and signature data dynamically
- AssemblyIdentity MSPhoneAssemblyId =
- new AssemblyIdentity(host.NameTable.GetNameFor("Microsoft.Phone"), "", new Version("7.0.0.0"),
- new byte[] { 0x24, 0xEE, 0xC0, 0xD8, 0xC8, 0x6C, 0xDA, 0x1E }, "");
- AssemblyIdentity MSPhoneControlsAssemblyId=
- new AssemblyIdentity(host.NameTable.GetNameFor("Microsoft.Phone.Controls"), "", new Version("7.0.0.0"),
- new byte[] { 0x24, 0xEE, 0xC0, 0xD8, 0xC8, 0x6C, 0xDA, 0x1E }, "");
-
- AssemblyIdentity MSPhoneSystemWindowsAssemblyId =
- new AssemblyIdentity(host.NameTable.GetNameFor("System.Windows"), coreAssemblyRef.Culture, coreAssemblyRef.Version,
- coreAssemblyRef.PublicKeyToken, "");
-
- phoneAssembly = host.FindAssembly(MSPhoneAssemblyId);
- phoneSystemWindowsAssembly = host.FindAssembly(MSPhoneSystemWindowsAssemblyId);
- MSPhoneControlsAssembly= host.FindAssembly(MSPhoneControlsAssemblyId);
- // TODO BUG / XAML DEPENDENCE If a control is declared in XAML, it may be one from a library *not* linked! So, assemblies could be dummy here
-
- // TODO determine the needed types dynamically
- if (phoneAssembly != Dummy.Assembly) {
- appBarIconButtonType = platform.CreateReference(phoneAssembly, "Microsoft", "Phone", "Shell", "ApplicationBarIconButton");
- appBarMenuItemType = platform.CreateReference(phoneAssembly, "Microsoft", "Phone", "Shell", "ApplicationBarMenuItem");
- } else {
- appBarIconButtonType = host.PlatformType.SystemObject;
- appBarMenuItemType = host.PlatformType.SystemObject;
- }
-
- if (phoneSystemWindowsAssembly != Dummy.Assembly) {
- checkBoxType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Controls", "CheckBox");
- radioButtonType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Controls", "RadioButton");
- buttonType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Controls", "Button");
- buttonBaseType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Controls", "Primitives", "ButtonBase");
- toggleButtonType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Controls", "Primitives", "ToggleButton");
- controlType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Controls", "Control");
- uiElementType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "UIElement");
- listBoxType = platform.CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Controls", "ListBox");
- } else {
- checkBoxType = host.PlatformType.SystemObject;
- radioButtonType = host.PlatformType.SystemObject;
- buttonType = host.PlatformType.SystemObject;
- buttonBaseType = host.PlatformType.SystemObject;
- toggleButtonType = host.PlatformType.SystemObject;
- controlType = host.PlatformType.SystemObject;
- uiElementType = host.PlatformType.SystemObject;
- listBoxType = host.PlatformType.SystemObject;
- }
-
- if (MSPhoneControlsAssembly != Dummy.Assembly) {
- pivotType = platform.CreateReference(MSPhoneControlsAssembly, "Microsoft", "Phone", "Controls", "Pivot");
- } else {
- pivotType = host.PlatformType.SystemObject;
- }
-
-
-
- trueConstant = new CompileTimeConstant() {
- Type = platform.SystemBoolean,
- Value = true
- };
- falseConstant = new CompileTimeConstant() {
- Type = platform.SystemBoolean,
- Value = false
- };
-
- IEnumerable<IPropertyDefinition> controlProperties = controlType.ResolvedType.Properties;
- IEnumerable<IPropertyDefinition> toggleButtonProperties = toggleButtonType.ResolvedType.Properties;
- IEnumerable<IPropertyDefinition> uiElementProperties = uiElementType.ResolvedType.Properties;
-
- IPropertyDefinition prop = controlProperties.Single(p => p.Name.Value == "IsEnabled");
- isEnabledSetter = prop.Setter;
- isEnabledGetter = prop.Getter;
- prop = toggleButtonProperties.Single(p => p.Name.Value == "IsChecked");
- isCheckedSetter = prop.Setter;
- isCheckedGetter = prop.Getter;
- prop = uiElementProperties.Single(p => p.Name.Value == "Visibility");
- visibilitySetter = prop.Setter;
- visibilityGetter = prop.Getter;
-
- IEnumerable<IEventDefinition> buttonBaseEvents = buttonBaseType.ResolvedType.Events;
- IEnumerable<IEventDefinition> toggleButtonEvents = toggleButtonType.ResolvedType.Events;
- IEventDefinition evt = buttonBaseEvents.Single(e => e.Name.Value == "Click");
- clickHandlerAdder = evt.Adder;
- clickHandlerRemover = evt.Remover;
- evt = toggleButtonEvents.Single(e => e.Name.Value == "Checked");
- checkedHandlerAdder = evt.Adder;
- checkedHandlerRemover = evt.Remover;
- evt = toggleButtonEvents.Single(e => e.Name.Value == "Unchecked");
- uncheckedHandlerAdder = evt.Adder;
- uncheckedHandlerRemover = evt.Remover;
- }
-
- public void injectPhoneControlsCode(BlockStatement block) {
- this.Traverse(block);
- }
-
- private void injectPhoneInitializationCode(BlockStatement block, Statement statementAfter) {
- // TODO check page name against container name
- IEnumerable<ControlInfoStructure> controls = PhoneCodeHelper.instance().PhonePlugin.getControlsForPage(methodBeingTraversed.Container.ToString());
- IEnumerable<IStatement> injectedStatements = new List<IStatement>();
- if (controls != null) {
- foreach (ControlInfoStructure controlInfo in controls) {
- injectedStatements = injectedStatements.Concat(getCodeForSettingEnabledness(controlInfo));
- injectedStatements = injectedStatements.Concat(getCodeForSettingCheckedState(controlInfo));
- injectedStatements = injectedStatements.Concat(getCodeForSettingVisibility(controlInfo));
- }
-
- int stmtPos = block.Statements.IndexOf(statementAfter);
- block.Statements.InsertRange(stmtPos + 1, injectedStatements);
- }
- }
-
- private BoundExpression makeBoundControlFromControlInfo(ControlInfoStructure controlInfo) {
- return new BoundExpression() {
- Definition = new FieldDefinition() {
- ContainingTypeDefinition = methodBeingTraversed.Container,
- Name = host.NameTable.GetNameFor(controlInfo.Name),
- Type = getTypeForClassname(controlInfo.ClassName),
- IsStatic = false,
- },
- Instance = new ThisReference() { Type = methodBeingTraversed.Container },
- Type=getTypeForClassname(controlInfo.ClassName),
- };
- }
-
- private IEnumerable<IStatement> getCodeForSettingVisibility(ControlInfoStructure controlInfo) {
- // TODO I do not want to import System.Windows into this project...and using the underlying uint won't work for dependency properties
- /*
- IList<IStatement> code = new List<IStatement>();
- BoundExpression boundControl = makeBoundControlFromControlInfo(controlInfo);
- MethodCall setVisibilityCall= new MethodCall() {
- IsStaticCall = false,
- IsVirtualCall = true,
- IsTailCall = false,
- Type = ((Microsoft.Cci.Immutable.PlatformType) host.PlatformType).SystemVoid,
- MethodToCall = visibilitySetter,
- ThisArgument = boundControl,
- };
-
- ITypeReference visibilityType= ((Microsoft.Cci.Immutable.PlatformType) host.PlatformType).CreateReference(phoneSystemWindowsAssembly, "System", "Windows", "Visibility");
-
- switch (controlInfo.Visible) {
- case Visibility.Visible:
- setVisibilityCall.Arguments.Add(new CompileTimeConstant() {
- Type = visibilityType,
- Value = 0,
- } ); // Visible
- break;
- case Visibility.Collapsed:
- setVisibilityCall.Arguments.Add(new CompileTimeConstant() {
- Type = visibilityType,
- Value = 1,
- } ); // Collapsed
- break;
- default:
- throw new ArgumentException("Invalid visibility value for control " + controlInfo.Name + ": " + controlInfo.Visible);
- }
-
- ExpressionStatement callStmt = new ExpressionStatement() {
- Expression = setVisibilityCall,
- };
- code.Add(callStmt);
- return code;
- * */
- return new List<IStatement>();
- }
-
- private IEnumerable<IStatement> getCodeForSettingEnabledness(ControlInfoStructure controlInfo) {
- IList<IStatement> code = new List<IStatement>();
- BoundExpression boundControl = makeBoundControlFromControlInfo(controlInfo);
- MethodCall setEnablednessCall = new MethodCall() {
- IsStaticCall = false,
- IsVirtualCall = true,
- IsTailCall = false,
- Type = ((Microsoft.Cci.Immutable.PlatformType) host.PlatformType).SystemVoid,
- MethodToCall = isEnabledSetter,
- ThisArgument = boundControl,
- };
-
- setEnablednessCall.Arguments.Add(controlInfo.IsEnabled ? trueConstant : falseConstant);
- ExpressionStatement callStmt = new ExpressionStatement() {
- Expression = setEnablednessCall,
- };
- code.Add(callStmt);
- return code;
- }
-
- private IEnumerable<IStatement> getCodeForSettingCheckedState(ControlInfoStructure controlInfo) {
- // IList<IStatement> code = new List<IStatement>();
- // BoundExpression boundControl = makeBoundControlFromControlInfo(controlInfo);
- // MethodCall setCheckStateCall= new MethodCall() {
- // IsStaticCall = false,
- // IsVirtualCall = true,
- // IsTailCall = false,
- // Type = ((Microsoft.Cci.Immutable.PlatformType) host.PlatformType).SystemVoid,
- // MethodToCall = isCheckedSetter,
- // ThisArgument = boundControl,
- // };
-
- // setCheckStateCall.Arguments.Add(controlInfo.IsChecked ? trueConstant : falseConstant);
- // ExpressionStatement callStmt = new ExpressionStatement() {
- // Expression = setCheckStateCall,
- // };
- // code.Add(callStmt);
- // return code;
- return new List<IStatement>();
- }
-
- public override void TraverseChildren(IBlockStatement block) {
- foreach (IStatement statement in block.Statements) {
- this.Traverse(statement);
- if (initializationFound) {
- injectPhoneInitializationCode(block as BlockStatement, statement as Statement);
- initializationFound = false;
- break;
- }
- }
- }
-
- public override void TraverseChildren(IMethodCall methodCall) {
- if (methodCall.IsStaticCall ||
- !methodCall.MethodToCall.ContainingType.ResolvedType.Equals(methodBeingTraversed.Container) ||
- methodCall.MethodToCall.Name.Value != "InitializeComponent" ||
- methodCall.Arguments.Any())
- return;
-
- initializationFound= true;
- }
- }
-
- /// <summary>
- /// Traverse metadata looking only for PhoneApplicationPage's constructors
- /// </summary>
- public class PhoneInitializationMetadataTraverser : MetadataTraverser {
- private MetadataReaderHost host;
-
- public PhoneInitializationMetadataTraverser(MetadataReaderHost host)
- : base() {
- this.host = host;
- }
-
- public override void TraverseChildren(IModule module) {
- base.TraverseChildren(module);
- }
-
- public override void TraverseChildren(IAssembly assembly) {
- base.TraverseChildren(assembly);
- }
-
- /// <summary>
- /// Check if the type being defined is a PhoneApplicationPage, uninteresting otherwise
- /// </summary>
- ///
- public override void TraverseChildren(ITypeDefinition typeDefinition) {
- if (typeDefinition.isPhoneApplicationClass(host)) {
- PhoneCodeHelper.instance().setMainAppTypeReference(typeDefinition);
- } else if (typeDefinition.isPhoneApplicationPageClass(host)) {
- base.TraverseChildren(typeDefinition);
- }
- }
-
- /// <summary>
- /// Check if it is traversing a constructor. If so, place necessary code after InitializeComponent() call
- /// </summary>
- public override void TraverseChildren(IMethodDefinition method) {
- if (!method.IsConstructor)
- return;
-
- PhoneInitializationCodeTraverser codeTraverser = new PhoneInitializationCodeTraverser(host, method);
- var methodBody = method.Body as SourceMethodBody;
- if (methodBody == null)
- return;
- var block = methodBody.Block as BlockStatement;
- codeTraverser.injectPhoneControlsCode(block);
- }
-
- public void InjectPhoneCodeAssemblies(IEnumerable<IUnit> assemblies) {
- foreach (var a in assemblies) {
- this.Traverse((IAssembly)a);
- }
- }
- }
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs
deleted file mode 100644
index 1957c2fa..00000000
--- a/BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-
-namespace BytecodeTranslator.Phone {
- public class PhoneMethodInliningMetadataTraverser : MetadataTraverser {
- private HashSet<IMethodDefinition> methodsToInline;
- private HashSet<IMethodDefinition> iterMethodsToInline;
- private PhoneCodeHelper phoneHelper;
- private bool firstPassDone = false;
- private bool changedOnLastPass = false;
- private IAssemblyReference assemblyBeingTranslated;
-
- public int TotalMethodsCount { get; private set; }
- public int InlinedMethodsCount { get { return methodsToInline.Count(); } }
-
- public PhoneMethodInliningMetadataTraverser(PhoneCodeHelper phoneHelper) {
- methodsToInline = new HashSet<IMethodDefinition>();
- iterMethodsToInline = new HashSet<IMethodDefinition>();
- this.phoneHelper = phoneHelper;
- TotalMethodsCount = 0;
- }
-
- public override void TraverseChildren(IAssembly assembly) {
- foreach (IModule module in assembly.MemberModules) {
- assemblyBeingTranslated = module.ContainingAssembly;
- this.Traverse(module);
- }
- firstPassDone = true;
- }
-
- public override void TraverseChildren(IMethodDefinition method) {
- if (!firstPassDone)
- TotalMethodsCount++;
-
- if (iterMethodsToInline.Contains(method) || (!firstPassDone && phoneHelper.mustInlineMethod(method))) {
- PhoneMethodInliningCodeTraverser codeTraverser= new PhoneMethodInliningCodeTraverser();
- codeTraverser.TraverseChildren(method);
- foreach (IMethodDefinition newMethodDef in codeTraverser.getMethodsFound()) {
- bool isExtern = this.assemblyBeingTranslated != null &&
- !TypeHelper.GetDefiningUnitReference(newMethodDef.ContainingType).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity);
- if (!methodsToInline.Contains(newMethodDef) && !isExtern) {
- iterMethodsToInline.Add(newMethodDef);
- changedOnLastPass = true;
- }
- }
- methodsToInline.Add(method);
- iterMethodsToInline.Remove(method);
- }
- }
-
- public IEnumerable<IMethodDefinition> getMethodsToInline() {
- return methodsToInline;
- }
-
- public bool isFinished() {
- return firstPassDone && !changedOnLastPass;
- }
-
- public void findAllMethodsToInline(List<IModule> modules) {
- while (!isFinished()) {
- changedOnLastPass = false;
- this.Traverse(modules);
- }
- }
- }
-
- class PhoneMethodInliningCodeTraverser : CodeTraverser {
- private HashSet<IMethodDefinition> foundMethods = new HashSet<IMethodDefinition>();
-
- public override void TraverseChildren(IMethodCall methodCall) {
- foundMethods.Add(methodCall.MethodToCall.ResolvedMethod);
- }
-
- public IEnumerable<IMethodDefinition> getMethodsFound() {
- return foundMethods;
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
deleted file mode 100644
index 0fa4a884..00000000
--- a/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
+++ /dev/null
@@ -1,375 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Microsoft.Cci.MutableCodeModel;
-using TranslationPlugins;
-
-namespace BytecodeTranslator.Phone {
- public class PhoneNavigationCodeTraverser : CodeTraverser {
- private MetadataReaderHost host;
- private ITypeReference navigationSvcType;
- private ITypeReference cancelEventArgsType;
- private ITypeReference typeTraversed;
- private IMethodDefinition methodTraversed;
- private static HashSet<IMethodDefinition> navCallers= new HashSet<IMethodDefinition>();
- public static IEnumerable<IMethodDefinition> NavCallers { get { return navCallers; } }
-
- private HashSet<IMethodReference> navigationCallers;
- public IEnumerable<IMethodReference> NavigationCallers { get { return NavigationCallers; } }
-
- public PhoneNavigationCodeTraverser(MetadataReaderHost host, IEnumerable<IAssemblyReference> assemblies) : base() {
- this.host = host;
- List<IAssembly> assembliesTraversed = new List<IAssembly>();
- foreach (IAssemblyReference asmRef in assemblies) {
- assembliesTraversed.Add(asmRef.ResolvedAssembly);
- }
-
- Microsoft.Cci.Immutable.PlatformType platform = host.PlatformType as Microsoft.Cci.Immutable.PlatformType;
-
- // TODO obtain version, culture and signature data dynamically
- IAssemblyReference assembly= PhoneTypeHelper.getPhoneAssemblyReference(host);
- // TODO determine the needed types dynamically
- navigationSvcType = platform.CreateReference(assembly, "System", "Windows", "Navigation", "NavigationService");
-
- assembly = PhoneTypeHelper.getSystemAssemblyReference(host);
- cancelEventArgsType = platform.CreateReference(assembly, "System", "ComponentModel", "CancelEventArgs");
- navigationCallers = new HashSet<IMethodReference>();
- }
-
- public override void TraverseChildren(ITypeDefinition typeDef) {
- this.typeTraversed = typeDef;
- base.TraverseChildren(typeDef);
- }
-
- public override void TraverseChildren(IMethodDefinition method) {
- this.methodTraversed = method;
- if (method.IsConstructor && PhoneTypeHelper.isPhoneApplicationClass(typeTraversed, host)) {
- navigationCallers.Add(method);
- string mainPageUri = PhoneCodeHelper.instance().PhonePlugin.getMainPageXAML();
- SourceMethodBody sourceBody = method.Body as SourceMethodBody;
- if (sourceBody != null) {
- BlockStatement bodyBlock = sourceBody.Block as BlockStatement;
- if (bodyBlock != null) {
- Assignment uriInitAssign = new Assignment() {
- Source = new CompileTimeConstant() {
- Type = host.PlatformType.SystemString,
- Value = UriHelper.getURIBase(mainPageUri),
- },
- Type = host.PlatformType.SystemString,
- Target = new TargetExpression() {
- Type = host.PlatformType.SystemString,
- // TODO unify code for current uri fieldreference
- Definition = new FieldReference() {
- ContainingType = PhoneCodeHelper.instance().getMainAppTypeReference(),
- IsStatic=true,
- Type=host.PlatformType.SystemString,
- Name=host.NameTable.GetNameFor(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE),
- InternFactory= host.InternFactory,
- },
- },
- };
- Statement uriInitStmt= new ExpressionStatement() {
- Expression= uriInitAssign,
- };
- bodyBlock.Statements.Insert(0, uriInitStmt);
- }
- }
- }
- base.TraverseChildren(method);
- }
-
-
- private bool navCallFound=false;
- private bool navCallIsStatic = false;
- private bool navCallIsBack = false;
- private StaticURIMode currentStaticMode= StaticURIMode.NOT_STATIC;
- private string unpurifiedFoundURI="";
-
- public override void TraverseChildren(IBlockStatement block) {
- IList<Tuple<IStatement,StaticURIMode,string>> staticNavStmts = new List<Tuple<IStatement,StaticURIMode,string>>();
- IList<IStatement> nonStaticNavStmts = new List<IStatement>();
- foreach (IStatement statement in block.Statements) {
- navCallFound = false;
- navCallIsStatic = false;
- navCallIsBack = false;
- this.Traverse(statement);
- if (navCallFound) {
- navCallers.Add(methodTraversed);
- if (navCallIsStatic) {
- staticNavStmts.Add(new Tuple<IStatement, StaticURIMode, string>(statement, currentStaticMode, unpurifiedFoundURI));
- } else if (!navCallIsBack) {
- nonStaticNavStmts.Add(statement);
- }
- }
- }
-
- injectNavigationUpdateCode(block, staticNavStmts, nonStaticNavStmts);
- }
-
- private bool isNavigationOnBackKeyPressHandler(IMethodCall call, out string target) {
- target = null;
- if (!PhoneCodeHelper.instance().isBackKeyPressOverride(methodTraversed.ResolvedMethod))
- return false;
-
- if (!call.MethodToCall.ContainingType.isNavigationServiceClass(host))
- return false;
-
- if (!PhoneCodeHelper.NAV_CALLS.Contains(call.MethodToCall.Name.Value) || call.MethodToCall.Name.Value == "GoBack") // back is actually ok
- return false;
-
- if (call.MethodToCall.Name.Value == "Navigate") {
- try {
- IExpression expr = call.Arguments.First();
- bool isStatic = UriHelper.isArgumentURILocallyCreatedStatic(expr, host, out target) ||
- UriHelper.isArgumentURILocallyCreatedStaticRoot(expr, host, out target);
- if (!isStatic)
- target = "--Other non inferrable target--";
- else
- target = UriHelper.getURIBase(target);
- } catch (InvalidOperationException) {
- }
- }
-
- return true;
- }
-
- private bool isCancelOnBackKeyPressHandler(IMethodCall call) {
- if (!PhoneCodeHelper.instance().isBackKeyPressOverride(methodTraversed.ResolvedMethod))
- return false;
-
- return isEventCancellationMethodCall(call);
- }
-
- private bool isEventCancellationMethodCall(IMethodCall call) {
- if (!call.MethodToCall.Name.Value.StartsWith("set_Cancel"))
- return false;
-
- if (call.Arguments.Count() != 1 || call.Arguments.ToList()[0].Type != host.PlatformType.SystemBoolean)
- return false;
-
- if (call.ThisArgument == null || !call.ThisArgument.Type.isCancelEventArgsClass(host))
- return false;
-
- ICompileTimeConstant constant = call.Arguments.ToList()[0] as ICompileTimeConstant;
- if (constant != null && constant.Value != null) {
- CompileTimeConstant falseConstant = new CompileTimeConstant() {
- Type = host.PlatformType.SystemBoolean,
- Value = false,
- };
- if (constant.Value == falseConstant.Value)
- return false;
- }
-
- return true;
- }
-
- public override void TraverseChildren(IMethodCall methodCall) {
- string target;
- if (isNavigationOnBackKeyPressHandler(methodCall, out target)) {
- ICollection<Tuple<IMethodReference,string>> targets;
- try {
- targets= PhoneCodeHelper.instance().BackKeyNavigatingOffenders[typeTraversed];
- } catch (KeyNotFoundException) {
- targets = new HashSet<Tuple<IMethodReference,string>>();
- }
- targets.Add(Tuple.Create<IMethodReference,string>(methodTraversed, "\"" + target + "\""));
- PhoneCodeHelper.instance().BackKeyNavigatingOffenders[typeTraversed]= targets;
- } else if (isCancelOnBackKeyPressHandler(methodCall)) {
- PhoneCodeHelper.instance().BackKeyCancellingOffenders.Add(Tuple.Create<ITypeReference, string>(typeTraversed,""));
- }
-
- // re-check whether it is an event cancellation call
- if (isEventCancellationMethodCall(methodCall)) {
- PhoneCodeHelper.instance().KnownEventCancellingMethods.Add(methodTraversed);
- }
-
- // check whether it is a NavigationService call
- IMethodReference methodToCall= methodCall.MethodToCall;
- ITypeReference callType= methodToCall.ContainingType;
- if (!callType.ResolvedType.Equals(navigationSvcType.ResolvedType))
- return;
-
- string methodToCallName= methodToCall.Name.Value;
- if (!PhoneCodeHelper.NAV_CALLS.Contains(methodToCallName))
- return;
-
- navCallFound = true;
- // TODO check what to do with these
- if (methodToCallName == "GoForward" || methodToCallName == "StopLoading") {
- // TODO forward navigation is not supported by the phone
- // TODO StopLoading is very async, I don't think we may verify this behaviour
- // TODO possibly log
- return;
- } else {
- currentStaticMode = StaticURIMode.NOT_STATIC;
- if (methodToCallName == "GoBack") {
- navCallIsStatic = false;
- navCallIsBack = true;
- } else { // Navigate()
- navCallIsBack = false;
-
- // check for different static patterns that we may be able to verify
- IExpression uriArg = methodCall.Arguments.First();
- if (UriHelper.isArgumentURILocallyCreatedStatic(uriArg, host, out unpurifiedFoundURI)) {
- navCallIsStatic = true;
- currentStaticMode = StaticURIMode.STATIC_URI_CREATION_ONSITE;
- } else if (UriHelper.isArgumentURILocallyCreatedStaticRoot(uriArg, host, out unpurifiedFoundURI)) {
- navCallIsStatic = true;
- currentStaticMode = StaticURIMode.STATIC_URI_ROOT_CREATION_ONSITE;
- } else {
- // get reason
- //ICreateObjectInstance creationSite = methodCall.Arguments.First() as ICreateObjectInstance;
- //if (creationSite == null)
- // notStaticReason = "URI not created at call site";
- //else
- // notStaticReason = "URI not initialized as a static string";
- }
- }
-
- if (navCallFound && !navCallIsBack) {
- // check this method as a navigation method
- PhoneCodeHelper.instance().KnownNavigatingMethods.Add(methodTraversed);
- }
-
- //Console.Write("Page navigation event found. Target is static? " + (isStatic ? "YES" : "NO"));
- //if (!isStatic) {
- // Console.WriteLine(" -- Reason: " + notStaticReason);
- //} else {
- // Console.WriteLine("");
- //}
- }
- }
-
- private void injectNavigationUpdateCode(IBlockStatement block, IEnumerable<Tuple<IStatement,StaticURIMode, string>> staticStmts, IEnumerable<IStatement> nonStaticStmts) {
- // TODO Here there is the STRONG assumption that a given method will only navigate at most once per method call
- // TODO (or at most will re-navigate to the same page). Quick "page flipping" on the same method
- // TODO would not be captured correctly
- Microsoft.Cci.MutableCodeModel.BlockStatement mutableBlock = block as Microsoft.Cci.MutableCodeModel.BlockStatement;
-
- foreach (IStatement stmt in nonStaticStmts) {
- int ndx = mutableBlock.Statements.ToList().IndexOf(stmt);
- if (ndx == -1) {
- // can't be
- throw new IndexOutOfRangeException("Statement must exist in original block");
- }
-
- Assignment currentURIAssign = new Assignment() {
- Source = new CompileTimeConstant() {
- Type = host.PlatformType.SystemString,
- Value = PhoneCodeHelper.BOOGIE_DO_HAVOC_CURRENTURI,
- },
- Type = host.PlatformType.SystemString,
- Target = new TargetExpression() {
- Type = host.PlatformType.SystemString,
- // TODO unify code for current uri fieldreference
- Definition = new FieldReference() {
- ContainingType = PhoneCodeHelper.instance().getMainAppTypeReference(),
- IsStatic= true,
- Type = host.PlatformType.SystemString,
- Name = host.NameTable.GetNameFor(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE),
- InternFactory=host.InternFactory,
- },
- },
- };
- Statement uriInitStmt = new ExpressionStatement() {
- Expression = currentURIAssign,
- };
- mutableBlock.Statements.Insert(ndx + 1, uriInitStmt);
- }
-
-
- foreach (Tuple<IStatement, StaticURIMode, string> entry in staticStmts) {
- int ndx= mutableBlock.Statements.ToList().IndexOf(entry.Item1);
- if (ndx == -1) {
- // can't be
- throw new IndexOutOfRangeException("Statement must exist in original block");
- }
-
- Assignment currentURIAssign = new Assignment() {
- Source = new CompileTimeConstant() {
- Type = host.PlatformType.SystemString,
- Value = UriHelper.getURIBase(entry.Item3).ToLower(),
- },
- Type = host.PlatformType.SystemString,
- Target = new TargetExpression() {
- Type = host.PlatformType.SystemString,
- // TODO unify code for current uri fieldreference
- Definition = new FieldReference() {
- ContainingType = PhoneCodeHelper.instance().getMainAppTypeReference(),
- IsStatic= true,
- Type = host.PlatformType.SystemString,
- Name = host.NameTable.GetNameFor(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE),
- InternFactory=host.InternFactory,
- },
- },
- };
- Statement uriInitStmt = new ExpressionStatement() {
- Expression = currentURIAssign,
- };
- mutableBlock.Statements.Insert(ndx+1, uriInitStmt);
- }
- }
- }
-
- /// <summary>
- /// Traverse metadata looking only for PhoneApplicationPage's constructors
- /// </summary>
- public class PhoneNavigationMetadataTraverser : MetadataTraverser {
- private MetadataReaderHost host;
- private ITypeDefinition typeBeingTraversed;
- private PhoneNavigationCodeTraverser codeTraverser;
-
- public PhoneNavigationMetadataTraverser(MetadataReaderHost host)
- : base() {
- this.host = host;
- }
-
- public override void TraverseChildren(IModule module) {
- codeTraverser = new PhoneNavigationCodeTraverser(host, module.AssemblyReferences);
- base.Traverse(module.AssemblyReferences);
- base.TraverseChildren(module);
- }
-
-
- // TODO can we avoid visiting every type? Are there only a few, identifiable, types that may perform navigation?
- public override void TraverseChildren(ITypeDefinition typeDefinition) {
- typeBeingTraversed = typeDefinition;
- if (typeDefinition.isPhoneApplicationClass(host)) {
- NamespaceTypeDefinition mutableTypeDef = typeDefinition as NamespaceTypeDefinition;
- if (mutableTypeDef != null) {
- // TODO unify code for current uri fieldreference
- FieldDefinition fieldDef = new FieldDefinition() {
- ContainingTypeDefinition= mutableTypeDef,
- InternFactory= host.InternFactory,
- IsStatic= true,
- Name= host.NameTable.GetNameFor(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE),
- Type= host.PlatformType.SystemString,
- Visibility= TypeMemberVisibility.Public,
- };
- PhoneCodeHelper.CurrentURIFieldDefinition = fieldDef;
- mutableTypeDef.Fields.Add(fieldDef);
- }
- }
-
- codeTraverser.Traverse(typeDefinition);
- base.TraverseChildren(typeDefinition);
- }
-
- // TODO same here. Are there specific methods (and ways to identfy those) that can perform navigation?
- public override void TraverseChildren(IMethodDefinition method) {
- if (PhoneCodeHelper.instance().isBackKeyPressOverride(method)) {
- PhoneCodeHelper.instance().KnownBackKeyHandlers.Add(method);
- PhoneCodeHelper.instance().OnBackKeyPressOverriden = true;
- }
- base.TraverseChildren(method);
- }
-
- public void InjectPhoneCodeAssemblies(IEnumerable<IUnit> assemblies) {
- foreach (var a in assemblies) {
- this.Traverse((IAssembly)a);
- }
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/Phone/stubs.bpl b/BCT/BytecodeTranslator/Phone/stubs.bpl
deleted file mode 100644
index ae97e03f..00000000
--- a/BCT/BytecodeTranslator/Phone/stubs.bpl
+++ /dev/null
@@ -1,41 +0,0 @@
-function isControlEnabled(Ref) : bool;
-function isControlChecked(Ref) : bool;
-
-procedure System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-procedure System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-
-implementation System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool) {
- $result := (a$in == b$in);
-}
-
-implementation System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool) {
- $result := (a$in != b$in);
-}
-
-procedure System.Windows.Controls.Control.set_IsEnabled$System.Boolean($this: Ref, value$in: bool);
-implementation System.Windows.Controls.Control.set_IsEnabled$System.Boolean($this: Ref, value$in: bool) {
- assume isControlEnabled($this) == value$in;
-}
-
-procedure System.Windows.Controls.Control.get_IsEnabled($this: Ref) returns ($result: Ref);
-implementation System.Windows.Controls.Control.get_IsEnabled($this: Ref) returns ($result: Ref) {
- var enabledness: bool;
- enabledness := isControlEnabled($this);
- $result := Box2Ref(Bool2Box(enabledness));
-}
-
-procedure System.Windows.Controls.Primitives.ToggleButton.set_IsChecked$System.Nullable$System.Boolean$($this: Ref, value$in: Ref);
-implementation System.Windows.Controls.Primitives.ToggleButton.set_IsChecked$System.Nullable$System.Boolean$($this: Ref, value$in: Ref) {
- var check: bool;
-
- check := Box2Bool(Ref2Box(value$in));
- assume isControlChecked($this) == check;
-}
-
-procedure System.Windows.Controls.Primitives.ToggleButton.get_IsChecked($this: Ref) returns ($result: Ref);
-implementation System.Windows.Controls.Primitives.ToggleButton.get_IsChecked($this: Ref) returns ($result: Ref) {
- var isChecked: bool;
- isChecked := isControlChecked($this);
- $result := Box2Ref(Bool2Box(isChecked));
-}
-
diff --git a/BCT/BytecodeTranslator/Prelude.cs b/BCT/BytecodeTranslator/Prelude.cs
deleted file mode 100644
index 2ccddfdb..00000000
--- a/BCT/BytecodeTranslator/Prelude.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace BytecodeTranslator {
- public class Prelude {
-
- /// <summary>
- /// Prelude that is shared by all translated programs, no matter
- /// what the heap representation is.
- /// </summary>
- public static void Emit(Microsoft.Boogie.TokenTextWriter wr) {
- wr.Write(@"// Copyright (c) 2010, Microsoft Corp.
-// Bytecode Translator prelude
-
-");
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/Program.cs b/BCT/BytecodeTranslator/Program.cs
deleted file mode 100644
index 403067be..00000000
--- a/BCT/BytecodeTranslator/Program.cs
+++ /dev/null
@@ -1,894 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-
-using System;
-using System.Linq;
-using System.IO;
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using System.Collections.Generic;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-using Microsoft.Cci.MutableContracts;
-
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics.Contracts;
-using Microsoft.Cci.MutableCodeModel.Contracts;
-using TranslationPlugins;
-using BytecodeTranslator.Phone;
-using System.Text.RegularExpressions;
-using BytecodeTranslator.TranslationPlugins;
-using BytecodeTranslator.TranslationPlugins.BytecodeTranslator;
-using BytecodeTranslator.TranslationPlugins.PhoneTranslator;
-
-namespace BytecodeTranslator {
-
- public class Options : OptionParsing {
-
- [OptionDescription("The names of the assemblies to use as input", ShortForm = "a")]
- public List<string> assemblies = null;
-
- [OptionDescription("Break into debugger", ShortForm = "break")]
- public bool breakIntoDebugger = false;
-
- [OptionDescription("Emit a 'capture state' directive after each statement, (default: false)", ShortForm = "c")]
- public bool captureState = false;
-
- [OptionDescription("Model exceptional control flow, (0: none, 1: explicit exceptions, 2: conservatively, default: 2)", ShortForm = "e")]
- public int modelExceptions = 2;
-
- [OptionDescription("Translation should be done for Get Me Here functionality, (default: false)", ShortForm = "gmh")]
- public bool getMeHere = false;
-
- [OptionDescription("Search paths for assembly dependencies.", ShortForm = "lib")]
- public List<string> libpaths = new List<string>();
-
- public enum HeapRepresentation { splitFields, twoDInt, twoDBox, general }
- [OptionDescription("Heap representation to use", ShortForm = "heap")]
- public HeapRepresentation heapRepresentation = HeapRepresentation.general;
-
- [OptionDescription("Translate using whole-program assumptions", ShortForm = "whole")]
- public bool wholeProgram = false;
-
- [OptionDescription("Stub assembly", ShortForm = "s")]
- public List<string>/*?*/ stub = null;
-
- [OptionDescription("Phone translation controls configuration")]
- public string phoneControls = null;
-
- [OptionDescription("Add phone navigation code on translation. Requires /phoneControls. Default false", ShortForm = "wpnav")]
- public bool phoneNavigationCode= false;
-
- [OptionDescription("Add phone feedback code on translation. Requires /phoneControls. Default false", ShortForm = "wpfb")]
- public bool phoneFeedbackCode = false;
-
- [OptionDescription("File containing white/black list (optionally end file name with + for white list, - for black list, default is white list", ShortForm = "exempt")]
- public string exemptionFile = "";
-
- [OptionDescription("Instrument branches with unique counter values", ShortForm = "ib")]
- public bool instrumentBranches = false;
-
- [OptionDescription("Add free ensures that express heap monotonicity", ShortForm = "heapM")]
- public bool monotonicHeap = false;
-
- public enum Dereference { Assert, Assume, None, }
- [OptionDescription("Assert/Assume on all object dereferences", ShortForm = "deref")]
- public Dereference dereference = Dereference.Assume;
-
- }
-
- public class BCT {
-
- public static IMetadataHost Host;
-
- static int Main(string[] args)
- {
- int errorReturnValue = -1;
-
- #region Parse options and check for errors
- var options = new Options();
- options.Parse(args);
- if (options.HelpRequested) {
- options.PrintOptions("");
- return errorReturnValue;
- }
- if (options.HasErrors) {
- options.PrintErrorsAndExit(Console.Out);
- }
- if (!String.IsNullOrWhiteSpace(options.exemptionFile)) {
- string fileName = options.exemptionFile;
- var c = fileName[fileName.Length - 1];
- if (c == '+' || c == '-') fileName = options.exemptionFile.Remove(fileName.Length - 1);
- if (!File.Exists(fileName)) {
- Console.WriteLine("Specified exemption file '{0}' not found.", fileName);
- }
- }
- if (options.stub != null) {
- Console.WriteLine("/s is no longer used to specify stub assemblies");
- return errorReturnValue;
- }
-
- if (options.modelExceptions == 1 && !options.wholeProgram) {
- Console.WriteLine("can specify a precise modeling of exceptions only when doing whole program analysis");
- return errorReturnValue;
- }
-
- if (options.breakIntoDebugger) {
- System.Diagnostics.Debugger.Break();
- }
-
- #endregion
-
- var assemblyNames = options.assemblies;
- if (assemblyNames == null || assemblyNames.Count == 0) {
- assemblyNames = new List<string>();
- foreach (var g in options.GeneralArguments) {
- assemblyNames.Add(g);
- }
- }
-
- #region If an exclusion file has been specified, read in each line as a regular expression
- List<Regex> exemptionList = null;
- bool whiteList = false;
- if (!String.IsNullOrWhiteSpace(options.exemptionFile)) {
- int i = 0;
- exemptionList = new List<Regex>();
- string fileName = options.exemptionFile;
- var c = fileName[fileName.Length - 1];
- whiteList = true;
- if (c == '+' || c == '-') {
- fileName = options.exemptionFile.Remove(fileName.Length - 1);
- if (c == '-') whiteList = false;
- }
- try {
- // Create an instance of StreamReader to read from a file.
- // The using statement also closes the StreamReader.
- using (StreamReader sr = new StreamReader(fileName)) {
- String line;
- // Read and display lines from the file until the end of
- // the file is reached.
- while ((line = sr.ReadLine()) != null) {
- exemptionList.Add(new Regex(line));
- i++;
- }
- //Console.WriteLine("Read {0} lines from the exclusion file '{1}'.",
- // i, options.exemptionFile);
- }
- } catch (Exception e) {
- Console.WriteLine("Something went wrong reading the exclusion file '{0}'; read in {1} lines, continuing processing.",
- fileName, i);
- Console.WriteLine(e.Message);
- }
- }
- #endregion
-
- try {
- HeapFactory heap;
- switch (options.heapRepresentation) {
- case Options.HeapRepresentation.splitFields:
- heap = new SplitFieldsHeap();
- break;
- case Options.HeapRepresentation.general:
- heap = new GeneralHeap();
- break;
- default:
- Console.WriteLine("Unknown setting for /heap");
- return 1;
- }
-
- if ((options.phoneFeedbackCode || options.phoneNavigationCode) && (options.phoneControls == null || options.phoneControls == "")) {
- Console.WriteLine("Options /phoneNavigationCode and /phoneFeedbackCode need /phoneControls option set.");
- return 1;
- }
-
- var pgm = TranslateAssembly(assemblyNames, heap, options, exemptionList, whiteList);
- var fileName = assemblyNames[0];
- fileName = Path.GetFileNameWithoutExtension(fileName);
- string outputFileName = fileName + ".bpl";
- Microsoft.Boogie.TokenTextWriter writer = new Microsoft.Boogie.TokenTextWriter("_" + outputFileName);
- Prelude.Emit(writer);
- pgm.Emit(writer);
- writer.Close();
- return Inline(outputFileName);
- } catch (Exception e) { // swallow everything and just return an error code
- Console.WriteLine("The byte-code translator failed: {0}", e.Message);
- // Console.WriteLine("Stack trace: {0}", e.StackTrace);
- return -1;
- }
- }
-
- private static List<IModule> modules;
-
- public static int Inline(string bplFileName) {
- Bpl.CommandLineOptions options = new Bpl.CommandLineOptions();
- Bpl.CommandLineOptions.Install(options);
- Bpl.CommandLineOptions.Clo.DoModSetAnalysis = true;
- Bpl.Program program;
- string _bplFileName = "_" + bplFileName;
-
- Bpl.Parser.Parse(_bplFileName, new List<string>(), out program);
- int errorCount = program.Resolve();
- if (errorCount != 0) {
- Console.WriteLine("{0} name resolution errors detected in {1}", errorCount, _bplFileName);
- return -1;
- }
- errorCount = program.Typecheck();
- if (errorCount != 0) {
- Console.WriteLine("{0} type checking errors detected in {1}", errorCount, _bplFileName);
- return -1;
- }
- bool inline = false;
- foreach (var d in program.TopLevelDeclarations) {
- if (d.FindExprAttribute("inline") != null) {
- inline = true;
- }
- }
- if (inline) {
- foreach (var d in program.TopLevelDeclarations) {
- var impl = d as Bpl.Implementation;
- if (impl != null) {
- impl.OriginalBlocks = impl.Blocks;
- impl.OriginalLocVars = impl.LocVars;
- }
- }
- foreach (var d in program.TopLevelDeclarations) {
- var impl = d as Bpl.Implementation;
- if (impl != null && !impl.SkipVerification) {
- Bpl.Inliner.ProcessImplementation(program, impl);
- }
- }
- foreach (var d in program.TopLevelDeclarations) {
- var impl = d as Bpl.Implementation;
- if (impl != null) {
- impl.OriginalBlocks = null;
- impl.OriginalLocVars = null;
- }
- }
- }
- Microsoft.Boogie.TokenTextWriter writer = new Microsoft.Boogie.TokenTextWriter(bplFileName);
- options.PrintInstrumented = true;
- program.Emit(writer);
- writer.Close();
- return 0;
- }
-
- public static int TranslateAssemblyAndWriteOutput(List<string> assemblyNames, HeapFactory heapFactory, Options options, List<Regex> exemptionList, bool whiteList) {
- Contract.Requires(assemblyNames != null);
- Contract.Requires(heapFactory != null);
- try {
- var pgm = TranslateAssembly(assemblyNames, heapFactory, options, exemptionList, whiteList);
- var fileName = assemblyNames[0];
- fileName = Path.GetFileNameWithoutExtension(fileName);
- string outputFileName = fileName + ".bpl";
- using (var writer = new Microsoft.Boogie.TokenTextWriter(outputFileName)) {
- Prelude.Emit(writer);
- pgm.Emit(writer);
- writer.Close();
- }
- return 0; // success
- } catch (Exception e) { // swallow everything and just return an error code
- Console.WriteLine("The byte-code translator failed: {0}", e.Message);
- // Console.WriteLine("Stack trace: {0}", e.StackTrace);
- return -1;
- }
- }
-
- public static Bpl.Program/*?*/ TranslateAssembly(List<string> assemblyNames, HeapFactory heapFactory, Options options, List<Regex> exemptionList, bool whiteList) {
- Contract.Requires(assemblyNames != null);
- Contract.Requires(heapFactory != null);
-
- var libPaths = options.libpaths;
- var wholeProgram = options.wholeProgram;
- var/*?*/ stubAssemblies = options.stub;
- var phoneControlsConfigFile = options.phoneControls;
- var doPhoneNav = options.phoneNavigationCode;
- var doPhoneFeedback = options.phoneFeedbackCode;
-
- var host = new CodeContractAwareHostEnvironment(libPaths != null ? libPaths : Enumerable<string>.Empty, true, true);
- Host = host;
-
- Bpl.CommandLineOptions.Install(new Bpl.CommandLineOptions());
-
- #region Assemlies to translate (via cmd line)
- modules = new List<IModule>();
- var contractExtractors = new Dictionary<IUnit, IContractProvider>();
- var pdbReaders = new Dictionary<IUnit, PdbReader>();
- #region Load *all* of the assemblies before doing anything else so that they can all vote on unification matters
- foreach (var a in assemblyNames) {
- var module = host.LoadUnitFrom(a) as IModule;
- if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
- Console.WriteLine(a + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
- Console.WriteLine("Skipping it, continuing with other input assemblies");
- continue;
- }
- modules.Add(module);
- }
- #endregion
- #region Decompile all of the assemblies
- var decompiledModules = new List<IModule>();
- foreach (var m in modules) {
- PdbReader/*?*/ pdbReader = null;
- string pdbFile = Path.ChangeExtension(m.Location, "pdb");
- if (File.Exists(pdbFile)) {
- Stream pdbStream = File.OpenRead(pdbFile);
- pdbReader = new PdbReader(pdbStream, host);
- }
- var m2 = Decompiler.GetCodeModelFromMetadataModel(host, m, pdbReader) as IModule;
- // The decompiler does not turn calls to Assert/Assume into Code Model nodes
- m2 = new Microsoft.Cci.MutableContracts.ContractExtractor.AssertAssumeExtractor(host, pdbReader).Rewrite(m2);
- decompiledModules.Add(m2);
- host.RegisterAsLatest(m2);
- contractExtractors.Add(m2, host.GetContractExtractor(m2.UnitIdentity));
- pdbReaders.Add(m2, pdbReader);
- }
- modules = decompiledModules;
- #endregion
- #endregion
-
- #region Assemblies to translate (stubs)
- if (stubAssemblies != null) {
- foreach (var s in stubAssemblies) {
- var module = host.LoadUnitFrom(s) as IModule;
- if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
- Console.WriteLine(s + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
- Console.WriteLine("Skipping it, continuing with other input assemblies");
- }
- PdbReader/*?*/ pdbReader = null;
- string pdbFile = Path.ChangeExtension(module.Location, "pdb");
- if (File.Exists(pdbFile)) {
- Stream pdbStream = File.OpenRead(pdbFile);
- pdbReader = new PdbReader(pdbStream, host);
- }
- module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader) as IModule;
-
- var copier = new CodeDeepCopier(host);
- var mutableModule = copier.Copy(module);
-
- var mscorlib = TypeHelper.GetDefiningUnit(host.PlatformType.SystemObject.ResolvedType);
-
- //var mutator = new ReparentModule(host, mscorlib, mutableModule);
- //module = mutator.Rewrite(mutableModule);
- //modules.Add(Tuple.Create(module, pdbReader));
-
- RewriteUnitReferences renamer = new RewriteUnitReferences(host, mutableModule);
- var mscorlibAssembly = (IAssembly)mscorlib;
- renamer.targetAssembly = mscorlibAssembly;
- renamer.originalAssemblyIdentity = mscorlibAssembly.AssemblyIdentity;
- renamer.RewriteChildren(mutableModule);
- modules.Add((IModule)mutableModule);
- contractExtractors.Add(module, host.GetContractExtractor(module.UnitIdentity));
- pdbReaders.Add(module, pdbReader);
- }
- }
- #endregion
-
- if (modules.Count == 0) {
- throw new TranslationException("No input assemblies to translate.");
- }
-
- var primaryModule = modules[0];
- Sink sink= new Sink(host, heapFactory, options, exemptionList, whiteList);
- TranslationHelper.tmpVarCounter = 0;
-
- // TODO move away, get all plugin and translators from a config file or alike
- #region Plugged translators
- List<Translator> translatorsPlugged = new List<Translator>();
- ITranslationPlugin bctPlugin= new BytecodeTranslatorPlugin(wholeProgram);
- Translator bcTranslator = bctPlugin.getTranslator(sink, contractExtractors, pdbReaders);
- translatorsPlugged.Add(bcTranslator);
-
- if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") {
- // TODO this should be part of the translator initialziation
- PhoneCodeHelper.initialize(host);
- PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile);
-
- if (doPhoneNav) {
- // TODO this should be part of the translator initialziation
- PhoneCodeHelper.instance().PhoneNavigationToggled = true;
-
- ITranslationPlugin phoneInitPlugin = new PhoneInitializationPlugin();
- ITranslationPlugin phoneNavPlugin = new PhoneNavigationPlugin();
- Translator phInitTranslator = phoneInitPlugin.getTranslator(sink, contractExtractors, pdbReaders);
- Translator phNavTranslator = phoneNavPlugin.getTranslator(sink, contractExtractors, pdbReaders);
- translatorsPlugged.Add(phInitTranslator);
- translatorsPlugged.Add(phNavTranslator);
- }
-
- if (doPhoneFeedback) {
- // TODO this should be part of the translator initialziation
- PhoneCodeHelper.instance().PhoneFeedbackToggled = true;
-
- ITranslationPlugin phoneFeedbackPlugin = new PhoneFeedbackPlugin();
- Translator phFeedbackTranslator = phoneFeedbackPlugin.getTranslator(sink, contractExtractors, pdbReaders);
- translatorsPlugged.Add(phFeedbackTranslator);
- }
- }
- #endregion
- sink.TranslationPlugins = translatorsPlugged;
-
- /*
- if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") {
- // TODO send this all way to initialization of phone plugin translator
- PhoneCodeHelper.initialize(host);
- PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile);
-
- // TODO these parameters will eventually form part of plugin configuration
- if (doPhoneNav) {
- PhoneCodeHelper.instance().PhoneNavigationToggled = true;
- PhoneInitializationMetadataTraverser initTr = new PhoneInitializationMetadataTraverser(host);
- initTr.InjectPhoneCodeAssemblies(modules);
- PhoneNavigationMetadataTraverser navTr = new PhoneNavigationMetadataTraverser(host);
- navTr.InjectPhoneCodeAssemblies(modules);
- }
-
- if (doPhoneFeedback) {
- PhoneCodeHelper.instance().PhoneFeedbackToggled = true;
- PhoneControlFeedbackMetadataTraverser fbMetaDataTraverser= new PhoneControlFeedbackMetadataTraverser(host);
- fbMetaDataTraverser.Visit(modules);
- }
- }
- */
-
- // TODO replace the whole translation by a translator initialization and an orchestrator calling back for each element
- // TODO for the current BC translator it will possibly just implement onMetadataElement(IModule)
- // TODO refactor this away, handle priorities between plugged translators
- IOrderedEnumerable<Translator> prioritizedTranslators = translatorsPlugged.OrderBy(t => t.getPriority());
- foreach (Translator t in prioritizedTranslators) {
- t.initialize();
- if (t.isOneShot())
- t.TranslateAssemblies(modules);
- }
-
- foreach (var pair in sink.delegateTypeToDelegates.Values) {
- CreateDispatchMethod(sink, pair.Item1, pair.Item2);
- }
-
- string outputFileName = primaryModule.Name + ".bpl";
- callPostTranslationTraversers(modules, sink, phoneControlsConfigFile, outputFileName);
- if (PhoneCodeHelper.instance().PhoneNavigationToggled) {
- finalizeNavigationAnalysisAndBoogieCode(phoneControlsConfigFile, sink, outputFileName);
- }
-
- //sink.CreateIdentifierCorrespondenceTable(primaryModule.Name.Value);
-
- //var rc = new Bpl.ResolutionContext((Bpl.IErrorSink)null);
- //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
- // decl.Register(rc);
- //}
- //sink.TranslatedProgram.Resolve(rc);
- //var goodDecls = new List<Bpl.Declaration>();
- //var tc = new Bpl.TypecheckingContext(null);
- //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
- // var impl = decl as Bpl.Implementation;
- // if (impl == null) {
- // goodDecls.Add(decl);
- // continue;
- // }
- // try {
- // //var tc = new Bpl.TypecheckingContext(null);
- // impl.Typecheck(tc);
- // goodDecls.Add(impl);
- // } catch {
- // Console.WriteLine("Deleting implementation for: " + impl.Name);
- // // nothing to do, just continue
- // }
- //}
- //sink.TranslatedProgram.TopLevelDeclarations = goodDecls;
- return sink.TranslatedProgram;
- }
-
-
- private static void finalizeNavigationAnalysisAndBoogieCode(string phoneControlsConfigFile, Sink sink, string outputFileName) {
- outputBoogieTrackedControlConfiguration(phoneControlsConfigFile);
- checkTransitivelyCalledBackKeyNavigations(modules);
- createPhoneBoogieCallStubs(sink);
- PhoneCodeHelper.instance().createQueriesBatchFile(sink, outputFileName);
- outputBackKeyWarnings();
- }
-
- private static void callPostTranslationTraversers(List<IModule> modules, Sink sink, string phoneControlsConfigFile, string outputFileName) {
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
- PhoneCodeHelper.instance().CreateFeedbackCallingMethods(sink);
- }
-
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled || PhoneCodeHelper.instance().PhoneNavigationToggled) {
- PhoneMethodInliningMetadataTraverser inlineTraverser =
- new PhoneMethodInliningMetadataTraverser(PhoneCodeHelper.instance());
- inlineTraverser.findAllMethodsToInline(modules);
- PhoneCodeHelper.updateInlinedMethods(sink, inlineTraverser.getMethodsToInline());
- System.Console.WriteLine("Total methods seen: {0}, inlined: {1}", inlineTraverser.TotalMethodsCount, inlineTraverser.InlinedMethodsCount);
-
- PhoneBackKeyCallbackTraverser traverser = new PhoneBackKeyCallbackTraverser(sink.host);
- traverser.Traverse(modules);
-
- }
- }
-
- private static void outputBoogieTrackedControlConfiguration(string phoneControlsConfigFile) {
- string outputConfigFile = Path.ChangeExtension(phoneControlsConfigFile, "bplout");
- StreamWriter outputStream = new StreamWriter(outputConfigFile);
- PhoneCodeHelper.instance().PhonePlugin.DumpControlStructure(outputStream);
- outputStream.Close();
- }
-
- private static void outputBackKeyWarnings() {
- // NAVIGATION TODO for now I console this out
- if (!PhoneCodeHelper.instance().OnBackKeyPressOverriden) {
- Console.Out.WriteLine("No back navigation issues, OnBackKeyPress is not overriden");
- } else if (PhoneCodeHelper.instance().BackKeyHandlerOverridenByUnknownDelegate) {
- Console.Out.WriteLine("Back navigation ISSUE: BackKeyPress is overriden by unidentified delegate and may perform illegal navigation");
- Console.Out.WriteLine("Offending pages:");
- foreach (ITypeReference type in PhoneCodeHelper.instance().BackKeyUnknownDelegateOffenders) {
- Console.WriteLine("\t" + type.ToString());
- }
- } else if (!PhoneCodeHelper.instance().BackKeyPressHandlerCancels && !PhoneCodeHelper.instance().BackKeyPressNavigates) {
- Console.Out.WriteLine("No back navigation issues, BackKeyPress overrides do not alter navigation");
- } else {
- if (PhoneCodeHelper.instance().BackKeyPressNavigates) {
- Console.Out.WriteLine("Back navigation ISSUE: back key press may navigate to pages not in backstack! From pages:");
- foreach (ITypeReference type in PhoneCodeHelper.instance().BackKeyNavigatingOffenders.Keys) {
- ICollection<Tuple<IMethodReference, string>> targets = PhoneCodeHelper.instance().BackKeyNavigatingOffenders[type];
- Console.WriteLine("\t" + type.ToString() + " may navigate to ");
- foreach (Tuple<IMethodReference, string> target in targets) {
- Console.WriteLine("\t\t" + target.Item2 + " via " +
- (target.Item1.Name == Dummy.Name ? "anonymous delegate" : target.Item1.ContainingType.ToString() + "." + target.Item1.Name.Value));
- }
- }
- }
-
- if (PhoneCodeHelper.instance().BackKeyPressHandlerCancels) {
- Console.Out.WriteLine("Back navigation ISSUE: back key press default behaviour may be cancelled! From pages:");
- foreach (Tuple<ITypeReference, string> cancellation in PhoneCodeHelper.instance().BackKeyCancellingOffenders) {
- Console.WriteLine("\t" + cancellation.Item1.ToString() + " via " + cancellation.Item2);
- }
- }
- }
- }
-
- private static void createPhoneBoogieCallStubs(Sink sink) {
- foreach (IMethodDefinition def in PhoneNavigationCodeTraverser.NavCallers) {
- if (!PhoneCodeHelper.instance().isKnownBackKeyOverride(def))
- PhoneCodeHelper.instance().addHandlerStubCaller(sink, def);
- }
- PhoneCodeHelper.instance().addNavigationUriHavocer(sink);
- }
-
- private static void checkTransitivelyCalledBackKeyNavigations(List<IModule> modules) {
- foreach (IMethodReference navMethod in PhoneCodeHelper.instance().KnownBackKeyHandlers) {
- // right now we traversed everything so we can see reachability
- IEnumerable<IMethodDefinition> indirects = PhoneCodeHelper.instance().getIndirectNavigators(modules, navMethod);
- if (indirects.Count() > 0) {
- ICollection<Tuple<IMethodReference, string>> targets = null;
- PhoneCodeHelper.instance().BackKeyNavigatingOffenders.TryGetValue(navMethod.ContainingType, out targets);
- if (targets == null) {
- targets = new HashSet<Tuple<IMethodReference, string>>();
- }
- string indirectTargeting = "<unknown indirect navigation> via (";
- foreach (IMethodDefinition methDef in indirects) {
- indirectTargeting += methDef.ContainingType.ToString() + "." + methDef.Name.Value + ", ";
- }
- indirectTargeting += ")";
- targets.Add(Tuple.Create<IMethodReference, string>(navMethod, indirectTargeting));
- PhoneCodeHelper.instance().BackKeyNavigatingOffenders[navMethod.ContainingType] = targets;
- }
-
- indirects = PhoneCodeHelper.instance().getIndirectCancellations(modules, navMethod);
- if (indirects.Count() > 0) {
- string indirectTargeting = "(";
- foreach (IMethodDefinition methDef in indirects) {
- indirectTargeting += methDef.ContainingType.ToString() + "." + methDef.Name.Value + ", ";
- }
- indirectTargeting += ")";
- PhoneCodeHelper.instance().BackKeyCancellingOffenders.Add(Tuple.Create<ITypeReference, string>(navMethod.ContainingType, indirectTargeting));
- }
- }
- }
-
- private static string NameUpToFirstPeriod(string name) {
- var i = name.IndexOf('.');
- if (i == -1)
- return name;
- else
- return name.Substring(0, i);
- }
-
- private class ReparentModule : CodeRewriter {
- private IUnit targetUnit;
- private IUnit sourceUnit;
- public ReparentModule(IMetadataHost host, IUnit targetUnit, IUnit sourceUnit)
- : base(host) {
- this.targetUnit = targetUnit;
- this.sourceUnit = sourceUnit;
- }
-
- public override void RewriteChildren(RootUnitNamespace rootUnitNamespace) {
- if (rootUnitNamespace.Unit.UnitIdentity.Equals(this.sourceUnit.UnitIdentity))
- rootUnitNamespace.Unit = this.targetUnit;
- base.RewriteChildren(rootUnitNamespace);
- }
- }
-
- private static Bpl.IfCmd BuildIfCmd(Bpl.Expr b, Bpl.Cmd cmd, Bpl.IfCmd ifCmd) {
- Bpl.StmtListBuilder ifStmtBuilder;
- ifStmtBuilder = new Bpl.StmtListBuilder();
- ifStmtBuilder.Add(cmd);
- return new Bpl.IfCmd(b.tok, b, ifStmtBuilder.Collect(b.tok), ifCmd, null);
- }
- private static Bpl.IfCmd BuildReturnCmd(Bpl.Expr b) {
- Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder();
- ifStmtBuilder.Add(new Bpl.ReturnCmd(b.tok));
- return new Bpl.IfCmd(b.tok, b, ifStmtBuilder.Collect(b.tok), null, null);
- }
- private static void BuildAssignment(Sink sink, Bpl.StmtListBuilder stmtBuilder, List<Bpl.Variable> lvars, List<Bpl.Variable> rvars) {
- for (int i = 0; i < lvars.Count; i++) {
- Bpl.Variable lvar = lvars[i];
- Bpl.Type ltype = lvar.TypedIdent.Type;
- Bpl.Variable rvar = rvars[i];
- Bpl.Type rtype = rvar.TypedIdent.Type;
- Bpl.IdentifierExpr lexpr = Bpl.Expr.Ident(lvar);
- Bpl.Expr rexpr = Bpl.Expr.Ident(rvar);
- if (rtype == ltype) {
- // do nothing
- } else if (ltype == sink.Heap.UnionType) {
- rexpr = sink.Heap.ToUnion(Bpl.Token.NoToken, rtype, rexpr);
- }
- else if (rtype == sink.Heap.UnionType) {
- rexpr = sink.Heap.FromUnion(Bpl.Token.NoToken, ltype, rexpr);
- }
- else {
- System.Diagnostics.Debug.Assert(false);
- }
- stmtBuilder.Add(TranslationHelper.BuildAssignCmd(lexpr, rexpr));
- }
- }
-
- private static void GenerateInAndOutExprs(Bpl.Expr e, Bpl.VariableSeq invars, Bpl.VariableSeq outvars, out Bpl.ExprSeq inExprs, out Bpl.IdentifierExprSeq outExprs) {
- inExprs = new Bpl.ExprSeq();
- inExprs.Add(e);
- for (int i = 1; i < invars.Length; i++) {
- Bpl.Variable f = invars[i];
- inExprs.Add(Bpl.Expr.Ident(f));
- }
- outExprs = new Bpl.IdentifierExprSeq();
- foreach (Bpl.Formal f in outvars) {
- outExprs.Add(Bpl.Expr.Ident(f));
- }
- }
-
- private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates) {
- Contract.Assert(type.IsDelegate);
- IMethodDefinition invokeMethod = null;
- foreach (IMethodDefinition m in type.Methods) {
- if (m.Name.Value == "Invoke") {
- invokeMethod = m;
- break;
- }
- }
-
- try {
- IMethodDefinition unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod;
- Bpl.Procedure invokeProcedure = (Bpl.Procedure) sink.FindOrCreateProcedure(unspecializedInvokeMethod).Decl;
- invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1));
- var invars = invokeProcedure.InParams;
- var outvars = invokeProcedure.OutParams;
-
- Bpl.IToken token = invokeMethod.Token();
-
- Bpl.Formal delegateVariable = new Bpl.Formal(token, new Bpl.TypedIdent(token, "delegate", sink.Heap.DelegateType), true);
- Bpl.VariableSeq dispatchProcInvars = new Bpl.VariableSeq();
- List<Bpl.Variable> dispatchProcInExprs = new List<Bpl.Variable>();
- dispatchProcInvars.Add(delegateVariable);
- for (int i = 1; i < invars.Length; i++) {
- Bpl.Variable v = invars[i];
- Bpl.Formal f = new Bpl.Formal(token, new Bpl.TypedIdent(token, v.Name, v.TypedIdent.Type), true);
- dispatchProcInvars.Add(f);
- dispatchProcInExprs.Add(f);
- }
- Bpl.VariableSeq dispatchProcOutvars = new Bpl.VariableSeq();
- List<Bpl.Variable> dispatchProcOutExprs = new List<Bpl.Variable>();
- foreach (Bpl.Variable v in outvars) {
- Bpl.Formal f = new Bpl.Formal(token, new Bpl.TypedIdent(token, v.Name, v.TypedIdent.Type), false);
- dispatchProcOutvars.Add(f);
- dispatchProcOutExprs.Add(f);
- }
- Bpl.Procedure dispatchProcedure =
- new Bpl.Procedure(token,
- "DispatchOne." + invokeProcedure.Name,
- new Bpl.TypeVariableSeq(),
- dispatchProcInvars,
- dispatchProcOutvars,
- new Bpl.RequiresSeq(),
- new Bpl.IdentifierExprSeq(),
- new Bpl.EnsuresSeq());
- dispatchProcedure.AddAttribute("inline", Bpl.Expr.Literal(1));
- sink.TranslatedProgram.TopLevelDeclarations.Add(dispatchProcedure);
-
- Bpl.LocalVariable method = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "method", Bpl.Type.Int));
- Bpl.LocalVariable receiver = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "receiver", sink.Heap.RefType));
- Bpl.LocalVariable typeParameter = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "typeParameter", sink.Heap.TypeType));
- Bpl.VariableSeq localVariables = new Bpl.VariableSeq();
- localVariables.Add(method);
- localVariables.Add(receiver);
- localVariables.Add(typeParameter);
-
- Bpl.IfCmd ifCmd = BuildIfCmd(Bpl.Expr.True, new Bpl.AssumeCmd(token, Bpl.Expr.False), null);
- int localCounter = 0;
- foreach (IMethodDefinition defn in delegates) {
- Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn);
- Bpl.Procedure delegateProcedure = (Bpl.Procedure) delegateProcedureInfo.Decl;
- Bpl.Formal thisVariable = delegateProcedureInfo.ThisVariable;
- int numArguments = defn.ParameterCount;
-
- List<Bpl.Variable> tempInputs = new List<Bpl.Variable>();
- List<Bpl.Variable> tempOutputs = new List<Bpl.Variable>();
-
- for (int i = 0; i < defn.ParameterCount; i++) {
- Bpl.Variable v = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i];
- Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
- new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
- localVariables.Add(localVariable);
- tempInputs.Add(localVariable);
- }
-
- for (int i = 0; i < delegateProcedure.OutParams.Length; i++) {
- Bpl.Variable v = delegateProcedure.OutParams[i];
- Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
- new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
- localVariables.Add(localVariable);
- tempOutputs.Add(localVariable);
- }
-
- Bpl.ExprSeq ins = new Bpl.ExprSeq();
- Bpl.IdentifierExprSeq outs = new Bpl.IdentifierExprSeq();
- if (!defn.IsStatic)
- ins.Add(Bpl.Expr.Ident(receiver));
- for (int i = 0; i < tempInputs.Count; i++) {
- ins.Add(Bpl.Expr.Ident(tempInputs[i]));
- }
- if (defn.IsGeneric) {
- for (int i = 0; i < defn.GenericParameterCount; i++) {
- ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
- new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
- new Bpl.ExprSeq(Bpl.Expr.Ident(typeParameter))));
- }
- }
- if (defn.IsStatic) {
- int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType);
- for (int i = 0; i < numTypeParameters; i++) {
- ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
- new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
- new Bpl.ExprSeq(Bpl.Expr.Ident(typeParameter))));
- }
- }
- for (int i = 0; i < tempOutputs.Count; i++) {
- outs.Add(Bpl.Expr.Ident(tempOutputs[i]));
- }
- Bpl.Constant c = sink.FindOrCreateDelegateMethodConstant(defn);
- Bpl.Expr bexpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, Bpl.Expr.Ident(method), Bpl.Expr.Ident(c));
- Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder();
- System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count);
- if (tempInputs.Count > 0) {
- BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs);
- }
- ifStmtBuilder.Add(EmitDummySourceContext());
- ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs));
- System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count);
- if (tempOutputs.Count > 0) {
- BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs);
- }
- ifCmd = new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), ifCmd, null);
- }
- Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
- stmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(method),
- sink.ReadMethod(Bpl.Expr.Ident(delegateVariable))));
- stmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(receiver),
- sink.ReadReceiver(Bpl.Expr.Ident(delegateVariable))));
- stmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(typeParameter),
- sink.ReadTypeParameters(Bpl.Expr.Ident(delegateVariable))));
- stmtBuilder.Add(ifCmd);
-
- Bpl.Implementation dispatchImpl =
- new Bpl.Implementation(token,
- dispatchProcedure.Name,
- new Bpl.TypeVariableSeq(),
- dispatchProcedure.InParams,
- dispatchProcedure.OutParams,
- localVariables,
- stmtBuilder.Collect(token)
- );
- dispatchImpl.Proc = dispatchProcedure;
- sink.TranslatedProgram.TopLevelDeclarations.Add(dispatchImpl);
-
- Bpl.ExprSeq inExprs;
- Bpl.IdentifierExprSeq outExprs;
-
- Bpl.LocalVariable iter = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "iter", sink.Heap.DelegateMultisetType));
- Bpl.LocalVariable d = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "d", sink.Heap.DelegateType));
- Bpl.LocalVariable all = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "all", sink.Heap.DelegateMultisetType));
-
- Bpl.StmtListBuilder implStmtBuilder = new Bpl.StmtListBuilder();
- implStmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Neq(Bpl.Expr.Ident(invars[0]), Bpl.Expr.Ident(sink.Heap.NullRef))));
- GenerateInAndOutExprs(sink.ReadDelegate(Bpl.Expr.Ident(invars[0])), invars, outvars, out inExprs, out outExprs);
- implStmtBuilder.Add(new Bpl.CallCmd(token, dispatchProcedure.Name, inExprs, outExprs));
- implStmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(all), sink.ReadDelegateMultiset(Bpl.Expr.Ident(invars[0]))));
- implStmtBuilder.Add(
- TranslationHelper.BuildAssignCmd(
- Bpl.Expr.Ident(iter),
- new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.Heap.MultisetSingleton), new Bpl.ExprSeq(sink.ReadDelegate(Bpl.Expr.Ident(invars[0]))))));
-
- Bpl.StmtListBuilder whileStmtBuilder = new Bpl.StmtListBuilder();
- whileStmtBuilder.Add(BuildReturnCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, Bpl.Expr.Ident(iter), Bpl.Expr.Ident(all))));
- whileStmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Gt, Bpl.Expr.Select(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.Heap.MultisetMinus), new Bpl.ExprSeq(Bpl.Expr.Ident(all), Bpl.Expr.Ident(iter))), Bpl.Expr.Ident(d)), new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(0)))));
-
- whileStmtBuilder.Add(EmitDummySourceContext());
- GenerateInAndOutExprs(Bpl.Expr.Ident(d), invars, outvars, out inExprs, out outExprs);
- whileStmtBuilder.Add(new Bpl.CallCmd(token, dispatchProcedure.Name, inExprs, outExprs));
- whileStmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(iter), new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.Heap.MultisetPlus), new Bpl.ExprSeq(Bpl.Expr.Ident(iter), new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.Heap.MultisetSingleton), new Bpl.ExprSeq(Bpl.Expr.Ident(d)))))));
- whileStmtBuilder.Add(new Bpl.HavocCmd(Bpl.Token.NoToken, new Bpl.IdentifierExprSeq(Bpl.Expr.Ident(d))));
- Bpl.WhileCmd whileCmd = new Bpl.WhileCmd(token, Bpl.Expr.True, new List<Bpl.PredicateCmd>(), whileStmtBuilder.Collect(token));
-
- implStmtBuilder.Add(whileCmd);
-
- Bpl.Implementation impl =
- new Bpl.Implementation(token,
- invokeProcedure.Name,
- new Bpl.TypeVariableSeq(),
- invars,
- outvars,
- new Bpl.VariableSeq(iter, d, all),
- implStmtBuilder.Collect(token)
- );
- impl.Proc = invokeProcedure;
- sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
- } catch (TranslationException te) {
- throw new NotImplementedException(te.ToString());
- } catch {
- throw;
- } finally {
- // Maybe this is a good place to add the procedure to the toplevel declarations
- }
- }
-
- private static Bpl.AssertCmd EmitDummySourceContext() {
- string fileName = "BCTAutoGenerated";
- int lineNumber = 0;
- var tok = Bpl.Token.NoToken;
- var attrib = new Bpl.QKeyValue(tok, "sourceLine", new List<object> { Bpl.Expr.Literal((int)lineNumber) }, null);
- attrib = new Bpl.QKeyValue(tok, "sourceFile", new List<object> { fileName }, attrib);
- return new Bpl.AssertCmd(tok, Bpl.Expr.True, attrib);
- }
-
- private class RewriteUnitReferences : MetadataRewriter {
- private UnitIdentity sourceUnitIdentity = null;
- internal IAssembly/*?*/ targetAssembly = null;
- internal AssemblyIdentity/*?*/ originalAssemblyIdentity = null;
-
- Dictionary<uint, bool> internedKeys = new Dictionary<uint, bool>();
-
- public RewriteUnitReferences(IMetadataHost host, Module sourceUnit)
- : base(host) {
- this.sourceUnitIdentity = sourceUnit.UnitIdentity;
- }
-
- public override IModuleReference Rewrite(IModuleReference moduleReference) {
- if (this.sourceUnitIdentity.Equals(moduleReference.UnitIdentity)) {
- return this.targetAssembly;
- }
- return base.Rewrite(moduleReference);
- }
- public override IAssemblyReference Rewrite(IAssemblyReference assemblyReference) {
- if (this.sourceUnitIdentity.Equals(assemblyReference.UnitIdentity)) {
- return this.targetAssembly;
- }
- return base.Rewrite(assemblyReference);
- }
-
- }
-
- }
-
-}
diff --git a/BCT/BytecodeTranslator/Readme.txt b/BCT/BytecodeTranslator/Readme.txt
deleted file mode 100644
index 64cb820d..00000000
--- a/BCT/BytecodeTranslator/Readme.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Current Issues:
-
-- The ordering of out params in a method call might be wrong // should be correct by now
-
-- Testing the svn \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/Sink.cs b/BCT/BytecodeTranslator/Sink.cs
deleted file mode 100644
index 19949297..00000000
--- a/BCT/BytecodeTranslator/Sink.cs
+++ /dev/null
@@ -1,1437 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-using System.Diagnostics.Contracts;
-
-using Bpl = Microsoft.Boogie;
-using BytecodeTranslator.TranslationPlugins;
-using System.IO;
-
-
-namespace BytecodeTranslator {
-
- public class Sink {
-
- public IEnumerable<Translator> TranslationPlugins {
- get { return this.translationPlugins; }
- set { this.translationPlugins= value; }
- }
- private IEnumerable<Translator> translationPlugins;
- private readonly Options options;
- readonly bool whiteList;
- readonly List<Regex> exemptionList;
-
-
- public Sink(IContractAwareHost host, HeapFactory heapFactory, Options options, List<Regex> exemptionList, bool whiteList) {
- Contract.Requires(host != null);
- Contract.Requires(heapFactory != null);
- this.host = host;
- var b = heapFactory.MakeHeap(this, out this.heap, out this.TranslatedProgram); // TODO: what if it returns false?
- this.options = options;
- this.exemptionList = exemptionList;
- this.whiteList = whiteList;
- if (this.TranslatedProgram == null) {
- this.TranslatedProgram = new Bpl.Program();
- }
- else {
- foreach (var d in this.TranslatedProgram.TopLevelDeclarations) {
- var p = d as Bpl.Procedure;
- if (p != null) {
- if (Bpl.QKeyValue.FindBoolAttribute(p.Attributes, "extern")) continue;
- this.initiallyDeclaredProcedures.Add(p.Name, new ProcedureInfo(p));
- }
- }
- }
- this.uniqueNumberSeed = 0;
- }
-
- public Options Options { get { return this.options; } }
-
- public Heap Heap {
- get { return this.heap; }
- }
- readonly Heap heap;
-
- public Bpl.Formal ThisVariable {
- get {
- return this.thisVariable;
- //ProcedureInfo info = FindOrCreateProcedure(this.methodBeingTranslated);
- //return info.ThisVariable;
- }
- }
- private Bpl.Formal thisVariable;
-
- public Bpl.Formal ReturnVariable {
- get {
- ProcedureInfo info = FindOrCreateProcedure(this.methodBeingTranslated);
- return info.ReturnVariable;
- }
- }
- public Bpl.LocalVariable LocalExcVariable {
- get {
- ProcedureInfo info = FindOrCreateProcedure(this.methodBeingTranslated);
- return info.LocalExcVariable;
- }
- }
- public Bpl.LocalVariable LabelVariable {
- get {
- ProcedureInfo info = FindOrCreateProcedure(this.methodBeingTranslated);
- return info.LabelVariable;
- }
- }
-
- public readonly string AllocationMethodName = "Alloc";
- public readonly string StaticFieldFunction = "ClassRepr";
- public readonly string ReferenceTypeName = "Ref";
-
- public readonly string DelegateCreateName = "DelegateCreate";
- public readonly string DelegateAddName = "DelegateAdd";
- public readonly string DelegateRemoveName = "DelegateRemove";
-
- public Bpl.Expr ReadDelegateMultiset(Bpl.Expr delegateReference) {
- return new Bpl.NAryExpr(delegateReference.tok, new Bpl.FunctionCall(Heap.RefToDelegateMultiset), new Bpl.ExprSeq(delegateReference));
- }
-
- public Bpl.Expr ReadDelegate(Bpl.Expr delegateReference) {
- return new Bpl.NAryExpr(delegateReference.tok, new Bpl.FunctionCall(Heap.RefToDelegate), new Bpl.ExprSeq(delegateReference));
- }
-
- public Bpl.Expr ReadMethod(Bpl.Expr delegateExpr) {
- return new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.heap.DelegateMethod), new Bpl.ExprSeq(delegateExpr));
- }
-
- public Bpl.Expr ReadReceiver(Bpl.Expr delegateExpr) {
- return new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.heap.DelegateReceiver), new Bpl.ExprSeq(delegateExpr));
- }
-
- public Bpl.Expr ReadTypeParameters(Bpl.Expr delegateExpr) {
- return new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.heap.DelegateTypeParameters), new Bpl.ExprSeq(delegateExpr));
- }
-
- public Bpl.Expr CreateDelegate(Bpl.Expr methodExpr, Bpl.Expr instanceExpr, Bpl.Expr typeParameterExpr) {
- return new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.heap.DelegateCons),
- new Bpl.ExprSeq(methodExpr, instanceExpr, typeParameterExpr));
- }
-
- public readonly Bpl.Program TranslatedProgram;
-
- public Bpl.Type CciTypeToBoogie(ITypeReference type) {
- if (TypeHelper.TypesAreEquivalent(type, type.PlatformType.SystemBoolean))
- return Bpl.Type.Bool;
- else if (type.TypeCode == PrimitiveTypeCode.UIntPtr || type.TypeCode == PrimitiveTypeCode.IntPtr)
- return Bpl.Type.Int;
- else if (TypeHelper.IsPrimitiveInteger(type))
- return Bpl.Type.Int;
- else if (type.TypeCode == PrimitiveTypeCode.Float32 || type.TypeCode == PrimitiveTypeCode.Float64)
- return heap.RealType;
- else if (type.ResolvedType.IsStruct)
- return heap.RefType; // structs are kept on the heap with special rules about assignment
- else if (type.IsEnum)
- return Bpl.Type.Int; // The underlying type of an enum is always some kind of integer
- else if (type is IGenericParameterReference) {
- var gp = type.ResolvedType as IGenericParameter;
- if (gp.MustBeReferenceType)// || gp.MustBeValueType)
- return heap.RefType;
- foreach (var c in gp.Constraints) {
- if (TypeHelper.TypesAreEquivalent(c, type.PlatformType.SystemValueType)) continue;
- return CciTypeToBoogie(c);
- }
- return heap.UnionType;
- } else
- return heap.RefType;
- }
-
- /// <summary>
- /// Creates a fresh local var of the given Type and adds it to the
- /// Bpl Implementation
- /// </summary>
- /// <param name="typeReference"> The type of the new variable </param>
- /// <returns> A fresh Variable with automatic generated name and location </returns>
- public Bpl.Variable CreateFreshLocal(ITypeReference typeReference) {
- Bpl.IToken loc = Bpl.Token.NoToken; // Helper Variables do not have a location
- Bpl.Type t = CciTypeToBoogie(typeReference);
- var localName = TranslationHelper.GenerateTempVarName();
- Bpl.LocalVariable v = new Bpl.LocalVariable(loc, new Bpl.TypedIdent(loc, localName, t));
- ILocalDefinition dummy = new LocalDefinition(); // Creates a dummy entry for the Dict, since only locals in the dict are translated to boogie
- localVarMap.Add(localName, v);
- return v;
- }
-
- public Bpl.Variable CreateFreshLocal(Bpl.Type t) {
- Bpl.IToken loc = Bpl.Token.NoToken; // Helper Variables do not have a location
- var localName = TranslationHelper.GenerateTempVarName();
- Bpl.LocalVariable v = new Bpl.LocalVariable(loc, new Bpl.TypedIdent(loc, localName, t));
- ILocalDefinition dummy = new LocalDefinition(); // Creates a dummy entry for the Dict, since only locals in the dict are translated to boogie
- localVarMap.Add(localName, v);
- return v;
- }
-
- /// <summary>
- /// There are no global variables in code, but it may be useful to have global Boogie vars in the translation
- ///
- /// This should be just the same as the encoding for a static field, but I'm being
- /// IL-unaware here...not sure if this is 100% right
- /// </summary>
- private IDictionary<string, Bpl.Variable> globalVariables = new Dictionary<string, Bpl.Variable>();
- public Bpl.Variable FindOrCreateGlobalVariable(string globalVarName, Bpl.Type type) {
- Bpl.Variable globalVar;
- // assuming globalVarName is a valid identifier. Possible name clashing issues too
- if (!globalVariables.TryGetValue(globalVarName, out globalVar)) {
- globalVar = new Bpl.GlobalVariable(null, new Bpl.TypedIdent(null, globalVarName, type));
- }
-
- return globalVar;
- }
-
-
- /// <summary>
- /// State that gets re-initialized per method
- /// Keys are the mangled names to avoid name clashes.
- /// </summary>
- private Dictionary<string, Bpl.LocalVariable> localVarMap = null;
- public Dictionary<string, Bpl.LocalVariable> LocalVarMap {
- get { return this.localVarMap; }
- }
- private int localCounter;
- public int LocalCounter { get { return this.localCounter++; } }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="local"></param>
- /// <returns></returns>
- public Bpl.Variable FindOrCreateLocalVariable(ILocalDefinition local) {
- Bpl.LocalVariable v;
- Bpl.IToken tok = local.Token();
- Bpl.Type t = CciTypeToBoogie(local.Type.ResolvedType);
- var name = local.Name.Value;
- name = TranslationHelper.TurnStringIntoValidIdentifier(name);
- var typeName = t.ToString();
- typeName = TranslationHelper.TurnStringIntoValidIdentifier(typeName);
- var mangledName = String.Format("{0}_{1}", name, typeName);
- if (!localVarMap.TryGetValue(mangledName, out v)) {
- v = new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, mangledName, t));
- localVarMap.Add(mangledName, v);
- }
- return v;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="param"></param>
- /// <remarks>STUB</remarks>
- /// <returns></returns>
- public Bpl.Variable FindParameterVariable(IParameterDefinition param, bool contractContext) {
- MethodParameter mp;
- ProcedureInfo procAndFormalMap;
- var sig = param.ContainingSignature;
- // BUGBUG: If param's signature is not a method reference, then it can't be used as a key.
- // The declaredMethods table needs to use ISignature for its keys.
- var key = ((IMethodReference)sig);
- this.declaredMethods.TryGetValue(key, out procAndFormalMap);
- var formalMap = procAndFormalMap.FormalMap;
- mp = formalMap[param.Index];
- return contractContext ? mp.inParameterCopy : mp.outParameterCopy;
- }
-
- public Bpl.Variable FindOrCreateFieldVariable(IFieldReference field) {
- // The Heap has to decide how to represent the field (i.e., its type),
- // all the Sink cares about is adding a declaration for it.
- Bpl.Variable v;
- var specializedField = field as ISpecializedFieldReference;
- if (specializedField != null)
- field = specializedField.UnspecializedVersion;
- if (!this.declaredFields.TryGetValue(field, out v)) {
- v = this.Heap.CreateFieldVariable(field);
-
- var isExtern = this.assemblyBeingTranslated != null &&
- !TypeHelper.GetDefiningUnitReference(field.ContainingType).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity);
- if (isExtern) {
- var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "extern", new List<object>(1), null);
- v.Attributes = attrib;
- }
-
- this.declaredFields.Add(field, v);
- this.TranslatedProgram.TopLevelDeclarations.Add(v);
- }
- return v;
- }
-
- class FieldComparer : IEqualityComparer<IFieldReference> {
- public bool Equals(IFieldReference x, IFieldReference y) {
- return x.InternedKey == y.InternedKey;
- }
-
- public int GetHashCode(IFieldReference obj) {
- return (int)obj.InternedKey;
- }
- }
-
- /// <summary>
- /// The keys to the table are the fields themselves, but the equality of keys is via their interned keys.
- /// </summary>
- private Dictionary<IFieldReference, Bpl.Variable> declaredFields = new Dictionary<IFieldReference, Bpl.Variable>(new FieldComparer());
-
- public Bpl.Variable FindOrCreateEventVariable(IEventDefinition e) {
- Bpl.Variable v;
- if (!this.declaredEvents.TryGetValue(e, out v)) {
- v = null;
-
- // First, see if the compiler generated a field (which happens when the event did not explicitly
- // define an adder and remover. If so, then just use the variable that corresponds to that field.
- foreach (var f in e.ContainingTypeDefinition.Fields) {
- if (e.Name == f.Name) {
- v = this.FindOrCreateFieldVariable(f);
- break;
- }
- }
-
- if (v == null) {
- v = this.Heap.CreateEventVariable(e);
-
- var isExtern = this.assemblyBeingTranslated != null &&
- !TypeHelper.GetDefiningUnitReference(e.ContainingType).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity);
- if (isExtern) {
- var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "extern", new List<object>(1), null);
- v.Attributes = attrib;
- }
-
- this.TranslatedProgram.TopLevelDeclarations.Add(v);
- }
- this.declaredEvents.Add(e, v);
- }
- return v;
- }
-
- private Dictionary<IEventDefinition, Bpl.Variable> declaredEvents = new Dictionary<IEventDefinition, Bpl.Variable>();
-
- public Bpl.Variable FindOrCreatePropertyVariable(IPropertyDefinition p) {
- return null;
- }
-
- public Bpl.Constant FindOrCreateConstant(string str) {
- str = str.Replace("\n", "\\n");
- str = str.Replace("\r", "\\r");
- str = str.Replace("\"", "\\\"");
- Bpl.Constant c;
- if (!this.declaredStringConstants.TryGetValue(str, out c)) {
- var tok = Bpl.Token.NoToken;
- var t = Heap.RefType;
- var name = "$string_literal_" + TranslationHelper.TurnStringIntoValidIdentifier(str) + "_" + declaredStringConstants.Count;
- var tident = new Bpl.TypedIdent(tok, name, t);
- c = new Bpl.Constant(tok, tident, true);
- var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "value", new List<object> { str, }, null);
- c.Attributes = attrib;
- this.declaredStringConstants.Add(str, c);
- this.TranslatedProgram.TopLevelDeclarations.Add(c);
- }
- return c;
- }
- private Dictionary<string, Bpl.Constant> declaredStringConstants = new Dictionary<string, Bpl.Constant>();
-
- public Bpl.Constant FindOrCreateConstant(double d) {
- Bpl.Constant c;
- var str = d.ToString();
- if (!this.declaredRealConstants.TryGetValue(str, out c)) {
- var tok = Bpl.Token.NoToken;
- var t = Heap.RealType;
- var name = "$real_literal_" + TranslationHelper.TurnStringIntoValidIdentifier(str) + "_" + declaredStringConstants.Count;
- var tident = new Bpl.TypedIdent(tok, name, t);
- c = new Bpl.Constant(tok, tident, true);
- this.declaredRealConstants.Add(str, c);
- this.TranslatedProgram.TopLevelDeclarations.Add(c);
- }
- return c;
- }
- public Bpl.Constant FindOrCreateConstant(float f) {
- Bpl.Constant c;
- var str = f.ToString();
- if (!this.declaredRealConstants.TryGetValue(str, out c)) {
- var tok = Bpl.Token.NoToken;
- var t = Heap.RealType;
- var name = "$real_literal_" + TranslationHelper.TurnStringIntoValidIdentifier(str) + "_" + declaredStringConstants.Count;
- var tident = new Bpl.TypedIdent(tok, name, t);
- c = new Bpl.Constant(tok, tident, true);
- this.declaredRealConstants.Add(str, c);
- this.TranslatedProgram.TopLevelDeclarations.Add(c);
- }
- return c;
- }
- private Dictionary<string, Bpl.Constant> declaredRealConstants = new Dictionary<string, Bpl.Constant>();
-
- private Dictionary<IPropertyDefinition, Bpl.Variable> declaredProperties = new Dictionary<IPropertyDefinition, Bpl.Variable>();
-
- private List<Bpl.Function> projectionFunctions = new List<Bpl.Function>();
- private Dictionary<int, Bpl.Function> arityToNaryIntFunctions = new Dictionary<int, Bpl.Function>();
- public Bpl.Function FindOrCreateNaryIntFunction(int arity) {
- Bpl.Function f;
- if (!this.arityToNaryIntFunctions.TryGetValue(arity, out f)) {
- Bpl.VariableSeq vseq = new Bpl.VariableSeq();
- for (int i = 0; i < arity; i++) {
- vseq.Add(new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, Bpl.Type.Int), true));
- }
- f = new Bpl.Function(Bpl.Token.NoToken, "Int" + arity, vseq, new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "result", Bpl.Type.Int), false));
- this.arityToNaryIntFunctions.Add(arity, f);
- TranslatedProgram.TopLevelDeclarations.Add(f);
- if (arity > projectionFunctions.Count) {
- for (int i = projectionFunctions.Count; i < arity; i++) {
- Bpl.Variable input = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "in", Bpl.Type.Int), true);
- Bpl.Variable output = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "out", Bpl.Type.Int), false);
- Bpl.Function g = new Bpl.Function(Bpl.Token.NoToken, "Proj" + i, new Bpl.VariableSeq(input), output);
- TranslatedProgram.TopLevelDeclarations.Add(g);
- projectionFunctions.Add(g);
- }
- }
- Bpl.VariableSeq qvars = new Bpl.VariableSeq();
- Bpl.ExprSeq exprs = new Bpl.ExprSeq();
- for (int i = 0; i < arity; i++) {
- Bpl.Variable v = new Bpl.Constant(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, Bpl.Type.Int));
- qvars.Add(v);
- exprs.Add(Bpl.Expr.Ident(v));
- }
- Bpl.Expr e = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f), exprs);
- for (int i = 0; i < arity; i++) {
- Bpl.Expr appl = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(projectionFunctions[i]), new Bpl.ExprSeq(e));
- Bpl.Trigger trigger = new Bpl.Trigger(Bpl.Token.NoToken, true, new Bpl.ExprSeq(e));
- Bpl.Expr qexpr = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, Bpl.Expr.Eq(appl, Bpl.Expr.Ident(qvars[i])));
- TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, qexpr));
- }
- }
- return f;
- }
-
- private List<Bpl.Function> typeParameterFunctions = new List<Bpl.Function>();
- private Dictionary<int, Bpl.Function> arityToNaryTypeFunctions = new Dictionary<int, Bpl.Function>();
- public Bpl.Function FindOrCreateNaryTypeFunction(int arity) {
- Bpl.Function f;
- if (!this.arityToNaryTypeFunctions.TryGetValue(arity, out f)) {
- Bpl.VariableSeq vseq = new Bpl.VariableSeq();
- for (int i = 0; i < arity; i++) {
- vseq.Add(new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, this.Heap.TypeType), true));
- }
- f = new Bpl.Function(Bpl.Token.NoToken, "Type" + arity, vseq, new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "result", this.Heap.TypeType), false));
- this.arityToNaryTypeFunctions.Add(arity, f);
- TranslatedProgram.TopLevelDeclarations.Add(f);
- if (arity > typeParameterFunctions.Count) {
- for (int i = typeParameterFunctions.Count; i < arity; i++) {
- Bpl.Variable input = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "in", this.Heap.TypeType), true);
- Bpl.Variable output = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "out", this.Heap.TypeType), false);
- Bpl.Function g = new Bpl.Function(Bpl.Token.NoToken, "TypeProj" + i, new Bpl.VariableSeq(input), output);
- TranslatedProgram.TopLevelDeclarations.Add(g);
- typeParameterFunctions.Add(g);
- }
- }
- Bpl.VariableSeq qvars = new Bpl.VariableSeq();
- Bpl.ExprSeq exprs = new Bpl.ExprSeq();
- for (int i = 0; i < arity; i++) {
- Bpl.Variable v = new Bpl.Constant(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, this.Heap.TypeType));
- qvars.Add(v);
- exprs.Add(Bpl.Expr.Ident(v));
- }
- Bpl.Expr e = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f), exprs);
- for (int i = 0; i < arity; i++) {
- Bpl.Expr appl = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(typeParameterFunctions[i]), new Bpl.ExprSeq(e));
- Bpl.Trigger trigger = new Bpl.Trigger(Bpl.Token.NoToken, true, new Bpl.ExprSeq(e));
- Bpl.Expr qexpr = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, Bpl.Expr.Eq(appl, Bpl.Expr.Ident(qvars[i])));
- TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, qexpr));
- }
- }
- return f;
- }
- public Bpl.Function FindOrCreateTypeParameterFunction(int id) {
- FindOrCreateNaryTypeFunction(id + 1);
- return typeParameterFunctions[id];
- }
-
- public struct ProcedureInfo {
- private Bpl.DeclWithFormals decl;
- private MethodParameter[] formalMap; // maps parameter index to formal
- private Bpl.Formal thisVariable;
- private Bpl.Formal returnVariable;
- private Bpl.LocalVariable localExcVariable;
- private Bpl.LocalVariable labelVariable;
- private List<Bpl.Formal> typeParameters;
- private List<Bpl.Formal> methodParameters;
-
- public ProcedureInfo(Bpl.DeclWithFormals decl) {
- this.decl = decl;
- this.formalMap = null;
- this.returnVariable = null;
- this.thisVariable = null;
- this.localExcVariable = null;
- this.labelVariable = null;
- this.typeParameters = null;
- this.methodParameters = null;
- }
- public ProcedureInfo(
- Bpl.DeclWithFormals decl,
- MethodParameter[] formalMap)
- : this(decl) {
- this.formalMap = formalMap;
- }
- public ProcedureInfo(
- Bpl.DeclWithFormals decl,
- MethodParameter[] formalMap,
- Bpl.Formal returnVariable)
- : this(decl, formalMap) {
- this.returnVariable = returnVariable;
- }
- public ProcedureInfo(
- Bpl.DeclWithFormals decl,
- MethodParameter[] formalMap,
- Bpl.Formal returnVariable,
- Bpl.Formal thisVariable,
- Bpl.LocalVariable localExcVariable,
- Bpl.LocalVariable labelVariable,
- List<Bpl.Formal> typeParameters,
- List<Bpl.Formal> methodParameters)
- : this(decl, formalMap, returnVariable) {
- this.thisVariable = thisVariable;
- this.localExcVariable = localExcVariable;
- this.labelVariable = labelVariable;
- this.typeParameters = typeParameters;
- this.methodParameters = methodParameters;
- }
-
- public Bpl.DeclWithFormals Decl { get { return decl; } }
- public MethodParameter[] FormalMap { get { return formalMap; } }
- public Bpl.Formal ThisVariable { get { return thisVariable; } }
- public Bpl.Formal ReturnVariable { get { return returnVariable; } }
- public Bpl.LocalVariable LocalExcVariable { get { return localExcVariable; } }
- public Bpl.LocalVariable LabelVariable { get { return labelVariable; } }
- public Bpl.Formal TypeParameter(int index) { return typeParameters[index]; }
- public Bpl.Formal MethodParameter(int index) { return methodParameters[index]; }
- }
-
- public ProcedureInfo FindOrCreateProcedure(IMethodDefinition method) {
- ProcedureInfo procInfo;
- var key = method;
-
- if (!this.declaredMethods.TryGetValue(key, out procInfo)) {
- string MethodName = TranslationHelper.CreateUniqueMethodName(method);
-
- if (this.initiallyDeclaredProcedures.TryGetValue(MethodName, out procInfo)) return procInfo;
-
- Bpl.Formal thisVariable = null;
- Bpl.Formal retVariable = null;
- Bpl.LocalVariable localExcVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "$localExc", this.Heap.RefType));
- Bpl.LocalVariable labelVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "$label", Bpl.Type.Int));
-
- int in_count = 0;
- int out_count = 0;
- MethodParameter mp;
- var formalMap = new MethodParameter[IteratorHelper.EnumerableCount(method.Parameters)];
- foreach (IParameterDefinition formal in method.Parameters) {
- mp = new MethodParameter(formal, this.CciTypeToBoogie(formal.Type));
- if (mp.inParameterCopy != null) in_count++;
- if (mp.outParameterCopy != null && formal.IsByReference)
- out_count++;
- formalMap[formal.Index] = mp;
- }
-
- if (method.Type.TypeCode != PrimitiveTypeCode.Void) {
- Bpl.Type rettype = CciTypeToBoogie(method.Type);
- out_count++;
- retVariable = new Bpl.Formal(method.Token(), new Bpl.TypedIdent(method.Type.Token(), "$result", rettype), false);
- }
-
- if (!method.IsStatic) {
- var selfType = CciTypeToBoogie(method.ContainingType);
- in_count++;
- thisVariable = new Bpl.Formal(method.Token(), new Bpl.TypedIdent(method.Type.Token(), "$this", selfType), true);
- }
-
- List<Bpl.Formal> typeParameters = new List<Bpl.Formal>();
- ITypeDefinition containingType = method.ContainingType.ResolvedType;
- while (true) {
- int paramIndex = 0;
- foreach (IGenericTypeParameter gtp in containingType.GenericParameters) {
- Bpl.Formal f = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, gtp.Name.Value, this.Heap.TypeType), true);
- typeParameters.Insert(paramIndex, f);
- if (method.IsStatic) in_count++;
- paramIndex++;
- }
- INestedTypeDefinition ntd = containingType as INestedTypeDefinition;
- if (ntd == null) break;
- containingType = ntd.ContainingType.ResolvedType;
- }
-
- List<Bpl.Formal> methodParameters = new List<Bpl.Formal>();
- foreach (IGenericMethodParameter gmp in method.GenericParameters) {
- Bpl.Formal f = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, gmp.Name.Value, this.Heap.TypeType), true);
- methodParameters.Add(f);
- in_count++;
- }
-
- Bpl.Variable[] invars = new Bpl.Formal[in_count];
- Bpl.Variable[] outvars = new Bpl.Formal[out_count];
-
- int i = 0;
- int j = 0;
-
- if (thisVariable != null)
- invars[i++] = thisVariable;
-
- foreach (MethodParameter mparam in formalMap) {
- if (mparam.inParameterCopy != null) {
- invars[i++] = mparam.inParameterCopy;
- }
- if (mparam.outParameterCopy != null) {
- if (mparam.underlyingParameter.IsByReference)
- outvars[j++] = mparam.outParameterCopy;
- }
- }
-
- if (method.IsStatic) {
- foreach (Bpl.Formal f in typeParameters) {
- invars[i++] = f;
- }
- }
- foreach (Bpl.Formal f in methodParameters) {
- invars[i++] = f;
- }
-
- if (retVariable != null) outvars[j++] = retVariable;
-
- var tok = method.Token();
- Bpl.RequiresSeq boogiePrecondition = new Bpl.RequiresSeq();
- Bpl.EnsuresSeq boogiePostcondition = new Bpl.EnsuresSeq();
- Bpl.IdentifierExprSeq boogieModifies = new Bpl.IdentifierExprSeq();
-
- Bpl.DeclWithFormals decl;
- if (IsPure(method)) {
- var func = new Bpl.Function(tok,
- MethodName,
- new Bpl.VariableSeq(invars),
- retVariable);
- decl = func;
- }
- else {
- var proc = new Bpl.Procedure(tok,
- MethodName,
- new Bpl.TypeVariableSeq(),
- new Bpl.VariableSeq(invars),
- new Bpl.VariableSeq(outvars),
- boogiePrecondition,
- boogieModifies,
- boogiePostcondition);
- decl = proc;
- }
- if (this.assemblyBeingTranslated != null && !TypeHelper.GetDefiningUnitReference(method.ContainingType).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity)) {
- var attrib = new Bpl.QKeyValue(tok, "extern", new List<object>(1), null);
- decl.Attributes = attrib;
- }
-
- string newName = null;
- if (IsStubMethod(method, out newName)) {
- if (newName != null) {
- decl.Name = newName;
- }
- }
- else {
- this.TranslatedProgram.TopLevelDeclarations.Add(decl);
- }
- procInfo = new ProcedureInfo(decl, formalMap, retVariable, thisVariable, localExcVariable, labelVariable, typeParameters, methodParameters);
- this.declaredMethods.Add(key, procInfo);
-
- // Can't visit the method's contracts until the formalMap and procedure are added to the
- // table because information in them might be needed (e.g., if a parameter is mentioned
- // in a contract.
- #region Translate the method's contracts
-
- var possiblyUnspecializedMethod = Unspecialize(method);
-
- var contract = Microsoft.Cci.MutableContracts.ContractHelper.GetMethodContractFor(this.host, possiblyUnspecializedMethod.ResolvedMethod);
-
- if (contract != null) {
- try {
- foreach (Translator translatorPlugin in translationPlugins) {
- ContractAwareTranslator translator = translatorPlugin as ContractAwareTranslator;
- if (translator != null) {
- IEnumerable<Bpl.Requires> preConds = translator.getPreconditionTranslation(contract);
- foreach (Bpl.Requires preExpr in preConds) {
- boogiePrecondition.Add(preExpr);
- }
-
- IEnumerable<Bpl.Ensures> ensures = translator.getPostconditionTranslation(contract);
- foreach (Bpl.Ensures ensuring in ensures) {
- boogiePostcondition.Add(ensuring);
- }
-
- IEnumerable<Bpl.IdentifierExpr> modifiedExpr = translator.getModifiedIdentifiers(contract);
- foreach (Bpl.IdentifierExpr ident in modifiedExpr) {
- boogieModifies.Add(ident);
- }
- }
- }
- }
- catch (TranslationException te) {
- throw new NotImplementedException("Cannot Handle Errors in Method Contract: " + te.ToString());
- }
- catch {
- throw;
- }
- }
-
- #endregion
-
- #region Add disjointness contracts for any struct values passed by value
- var paramList = new List<IParameterDefinition>(method.Parameters);
- for (int p1index = 0; p1index < method.ParameterCount; p1index++) {
- var p1 = paramList[p1index];
- if (p1.IsByReference) continue;
- if (!TranslationHelper.IsStruct(p1.Type)) continue;
- for (int p2index = p1index + 1; p2index < method.ParameterCount; p2index++) {
- var p2 = paramList[p2index];
- if (p2.IsByReference) continue;
- if (!TranslationHelper.IsStruct(p2.Type)) continue;
- if (!TypeHelper.TypesAreEquivalent(p1.Type, p2.Type)) continue;
- var req = new Bpl.Requires(true, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq,
- Bpl.Expr.Ident(formalMap[p1.Index].inParameterCopy), Bpl.Expr.Ident(formalMap[p2.Index].inParameterCopy)));
- boogiePrecondition.Add(req);
- }
- }
- #endregion
-
- if (options.monotonicHeap) {
- #region Add free ensures for allocatedness of result (for methods that return references)
- if (retVariable != null && retVariable.TypedIdent.Type == this.Heap.RefType) {
- var ens = new Bpl.Ensures(true,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
- Bpl.Expr.Ident(retVariable), Bpl.Expr.Ident(this.Heap.NullRef)),
- Bpl.Expr.Select(Bpl.Expr.Ident(this.Heap.AllocVariable), Bpl.Expr.Ident(retVariable))
- ));
- boogiePostcondition.Add(ens);
- }
- #endregion
- #region Add free ensures for preservation of allocatedness: AllocMapImplies(old($Alloc), $Alloc) == AllocMapConst(true)
- var preserveAlloc = new Bpl.Ensures(true,
- Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
- new Bpl.NAryExpr(
- Bpl.Token.NoToken,
- new Bpl.FunctionCall(this.Heap.AllocImplies),
- new Bpl.ExprSeq(
- new Bpl.OldExpr(Bpl.Token.NoToken, Bpl.Expr.Ident(this.Heap.AllocVariable)),
- Bpl.Expr.Ident(this.Heap.AllocVariable))),
- new Bpl.NAryExpr(
- Bpl.Token.NoToken,
- new Bpl.FunctionCall(this.Heap.AllocConstBool),
- new Bpl.ExprSeq(Bpl.Expr.True))
- ));
- boogiePostcondition.Add(preserveAlloc);
- #endregion
- }
-
- }
- return procInfo;
- }
-
- /// <summary>
- /// The keys are the mangled names for the ctors. That is avoid generating name conflicts in the translated
- /// program. This is needed for things like System.Drawing.Rect, which was referenced in both System.Drawing v2
- /// as well as System.Drawing v4. Since those assemblies are not unified, the two types are distinct, but
- /// the (generated) name for the default struct ctors clash.
- /// NB: This means that if there are two different types with the same full name (minus the assembly name),
- /// then this will implicitly unify them. This could lead to big trouble!
- /// </summary>
- private Dictionary<string, ProcedureInfo> declaredStructDefaultCtors = new Dictionary<string, ProcedureInfo>();
- /// <summary>
- /// Struct "creation" (source code that looks like "new S()" for a struct type S) is modeled
- /// by a call to the nullary "ctor" that initializes all of the structs fields to zero-
- /// equivalent values. Note that the generated procedure has no contract. So if the struct
- /// is defined in an assembly that is not being translated, then its behavior is unspecified.
- /// </summary>
- /// <param name="structType">A type reference to the value type for which the ctor should be returned.</param>
- /// <returns>A unary procedure (i.e., it takes the struct value as its parameter) that initializes
- /// its parameter of type <paramref name="structType"/>.
- /// </returns>
- public Bpl.DeclWithFormals FindOrCreateProcedureForDefaultStructCtor(ITypeReference structType) {
- Contract.Requires(structType.IsValueType);
-
- ProcedureInfo procAndFormalMap;
- var typename = TranslationHelper.TurnStringIntoValidIdentifier(TypeHelper.GetTypeName(structType));
- var procName = typename + ".#default_ctor";
- if (!this.declaredStructDefaultCtors.TryGetValue(procName, out procAndFormalMap)) {
- var tok = structType.Token();
- var selfType = this.CciTypeToBoogie(structType); //new Bpl.MapType(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(Heap.FieldType), Heap.BoxType);
- var selfIn = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "$this", selfType), true);
- var invars = new Bpl.Formal[] { selfIn };
- var proc = new Bpl.Procedure(Bpl.Token.NoToken, procName,
- new Bpl.TypeVariableSeq(),
- new Bpl.VariableSeq(invars),
- new Bpl.VariableSeq(), // out
- new Bpl.RequiresSeq(),
- new Bpl.IdentifierExprSeq(), // modifies
- new Bpl.EnsuresSeq()
- );
- this.TranslatedProgram.TopLevelDeclarations.Add(proc);
- procAndFormalMap = new ProcedureInfo(proc, new MethodParameter[0]);
- this.declaredStructDefaultCtors.Add(procName, procAndFormalMap);
- }
- return procAndFormalMap.Decl;
- }
-
- /// <summary>
- /// The keys are the mangled names for the ctors. That is avoid generating name conflicts in the translated
- /// program. This is needed for things like System.Drawing.Rect, which was referenced in both System.Drawing v2
- /// as well as System.Drawing v4. Since those assemblies are not unified, the two types are distinct, but
- /// the (generated) name for the default struct ctors clash.
- /// NB: This means that if there are two different types with the same full name (minus the assembly name),
- /// then this will implicitly unify them. This could lead to big trouble!
- /// </summary>
- private Dictionary<string, ProcedureInfo> declaredStructCopyCtors = new Dictionary<string, ProcedureInfo>();
- private Dictionary<uint, ProcedureInfo> declaredStructEqualityOperators = new Dictionary<uint, ProcedureInfo>();
- /// <summary>
- /// The assignment of one struct value to another is modeled by a method that makes a field-by-field
- /// copy of the source of the assignment.
- /// Note that the generated procedure has no contract. So if the struct
- /// is defined in an assembly that is not being translated, then its behavior is unspecified.
- /// </summary>
- /// <param name="structType">A type reference to the value type for which the procedure should be returned.</param>
- /// <returns>A binary procedure (i.e., it takes the two struct values as its parameters).
- /// </returns>
- public Bpl.DeclWithFormals FindOrCreateProcedureForStructCopy(ITypeReference structType) {
- Contract.Requires(structType.IsValueType);
-
- ProcedureInfo procAndFormalMap;
- var typename = TranslationHelper.TurnStringIntoValidIdentifier(TypeHelper.GetTypeName(structType));
- var procName = typename + ".#copy_ctor";
- if (!this.declaredStructCopyCtors.TryGetValue(procName, out procAndFormalMap)) {
- var tok = structType.Token();
- var selfType = this.CciTypeToBoogie(structType); //new Bpl.MapType(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(Heap.FieldType), Heap.BoxType);
- var selfIn = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "this", selfType), true);
- var otherOut = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "other", selfType), true);
- var invars = new Bpl.Formal[] { selfIn, };
- var outvars = new Bpl.Formal[] { otherOut, };
- var selfInExpr = Bpl.Expr.Ident(selfIn);
- var otherInExpr = Bpl.Expr.Ident(otherOut);
- //var req = new Bpl.Requires(true, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, selfInExpr, otherInExpr));
- var ens = new Bpl.Ensures(true, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, selfInExpr, otherInExpr));
-
- var proc = new Bpl.Procedure(Bpl.Token.NoToken, procName,
- new Bpl.TypeVariableSeq(),
- new Bpl.VariableSeq(invars),
- new Bpl.VariableSeq(outvars),
- new Bpl.RequiresSeq(/*req*/),
- new Bpl.IdentifierExprSeq(), // modifies
- new Bpl.EnsuresSeq(ens)
- );
- this.TranslatedProgram.TopLevelDeclarations.Add(proc);
- procAndFormalMap = new ProcedureInfo(proc, new MethodParameter[0]);
- this.declaredStructCopyCtors.Add(procName, procAndFormalMap);
- }
- return procAndFormalMap.Decl;
- }
-
- // TODO: Fix test to return true iff method is marked with the "real" [Pure] attribute
- // also, should it return true for properties and all of the other things the tools
- // consider pure?
- private bool IsPure(IMethodDefinition method) {
- // TODO:
- // This needs to wait until we get function bodies sorted out.
- //bool isPropertyGetter = method.IsSpecialName && method.Name.Value.StartsWith("get_");
- //if (isPropertyGetter) return true;
-
- foreach (var a in method.Attributes) {
- if (TypeHelper.GetTypeName(a.Type).EndsWith("PureAttribute")) {
- return true;
- }
- }
- return false;
- }
-
- // TODO: check method's containing type in case the entire type is a stub type.
- // TODO: do a type test, not a string test for the attribute
- private bool IsStubMethod(IMethodReference method, out string/*?*/ newName) {
- newName = null;
- var methodDefinition = method.ResolvedMethod;
- foreach (var a in methodDefinition.Attributes) {
- if (TypeHelper.GetTypeName(a.Type).EndsWith("StubAttribute")) {
- foreach (var c in a.Arguments) {
- var mdc = c as IMetadataConstant;
- if (mdc != null && mdc.Type.TypeCode == PrimitiveTypeCode.String) {
- newName = (string)(mdc.Value);
- break;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- public static IMethodReference Unspecialize(IMethodReference method) {
- IMethodReference result = method;
- var gmir = result as IGenericMethodInstanceReference;
- if (gmir != null) {
- result = gmir.GenericMethod;
- }
- var smr = result as ISpecializedMethodReference;
- if (smr != null) {
- result = smr.UnspecializedVersion;
- }
- // Temporary hack until ISpecializedMethodDefinition implements ISpecializedMethodReference
- var smd = result as ISpecializedMethodDefinition;
- if (smd != null) {
- result = smd.UnspecializedVersion;
- }
- return result;
- }
-
- public static ushort ConsolidatedGenericParameterCount(ITypeReference typeReference) {
- Contract.Requires(typeReference != null);
-
- var typeDefinition = typeReference.ResolvedType;
- var totalNumberOfParameters = typeDefinition.GenericParameterCount;
- var nestedTypeDefinition = typeDefinition as INestedTypeDefinition;
- while (nestedTypeDefinition != null) {
- var containingType = nestedTypeDefinition.ContainingType.ResolvedType;
- totalNumberOfParameters += containingType.GenericParameterCount;
- nestedTypeDefinition = containingType as INestedTypeDefinition;
- }
- return totalNumberOfParameters;
- }
-
- public static ITypeReference GetUninstantiatedGenericType(ITypeReference typeReference) {
- IGenericTypeInstanceReference/*?*/ genericTypeInstanceReference = typeReference as IGenericTypeInstanceReference;
- if (genericTypeInstanceReference != null) return GetUninstantiatedGenericType(genericTypeInstanceReference.GenericType);
- INestedTypeReference/*?*/ nestedTypeReference = typeReference as INestedTypeReference;
- if (nestedTypeReference != null) {
- ISpecializedNestedTypeReference/*?*/ specializedNestedType = nestedTypeReference as ISpecializedNestedTypeReference;
- if (specializedNestedType != null) return specializedNestedType.UnspecializedVersion;
- return nestedTypeReference;
- }
- return typeReference;
- }
-
- public static void GetConsolidatedTypeArguments(List<ITypeReference> consolidatedTypeArguments, ITypeReference typeReference) {
- IGenericTypeInstanceReference/*?*/ genTypeInstance = typeReference as IGenericTypeInstanceReference;
- if (genTypeInstance != null) {
- GetConsolidatedTypeArguments(consolidatedTypeArguments, genTypeInstance.GenericType);
- consolidatedTypeArguments.AddRange(genTypeInstance.GenericArguments);
- return;
- }
- INestedTypeReference/*?*/ nestedTypeReference = typeReference as INestedTypeReference;
- if (nestedTypeReference != null) GetConsolidatedTypeArguments(consolidatedTypeArguments, nestedTypeReference.ContainingType);
- }
-
- [Obsolete]
- public static int GetNumberTypeParameters(IMethodDefinition method) {
- return method.GenericParameterCount + ConsolidatedGenericParameterCount(method.ContainingType);
- }
-
- /// <summary>
- /// Creates a fresh variable that represents the type of
- /// <paramref name="type"/> in the Bpl program. I.e., its
- /// value represents the expression "typeof(type)".
- /// </summary>
- public Bpl.Expr FindOrCreateTypeReference(ITypeReference type, bool codeContext = false) {
-
- var gtir = type as IGenericTypeInstanceReference;
- if (gtir != null) {
- var genericType = FindOrDefineType(gtir.GenericType.ResolvedType);
- var gArgs = new Bpl.ExprSeq();
- foreach (var a in gtir.GenericArguments) {
- var a_prime = FindOrCreateTypeReference(a, codeContext);
- gArgs.Add(a_prime);
- }
- var typeExpression = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(genericType), gArgs);
- return typeExpression;
- }
-
- IGenericTypeParameter gtp = type as IGenericTypeParameter;
- if (gtp != null) {
- if (codeContext) {
- var selectorName = gtp.Name.Value;
- selectorName = TranslationHelper.TurnStringIntoValidIdentifier(selectorName);
- var typeName = TypeHelper.GetTypeName(gtp.DefiningType, NameFormattingOptions.DocumentationId);
- typeName = TranslationHelper.TurnStringIntoValidIdentifier(typeName);
- var funcName = String.Format("{0}#{1}", selectorName, typeName);
- Bpl.IToken tok = Bpl.Token.NoToken;
- var identExpr = Bpl.Expr.Ident(new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, funcName, this.Heap.TypeType)));
- var funcCall = new Bpl.FunctionCall(identExpr);
- var thisArg = new Bpl.IdentifierExpr(tok, this.ThisVariable);
- var dynType = this.Heap.DynamicType(thisArg);
- var nary = new Bpl.NAryExpr(Bpl.Token.NoToken, funcCall, new Bpl.ExprSeq(dynType));
- return nary;
-
- } else {
- var formal = FindOrDefineTypeParameter(gtp);
- return Bpl.Expr.Ident(formal);
- }
- }
-
- IGenericMethodParameter gmp = type as IGenericMethodParameter;
- if (gmp != null) {
- ProcedureInfo info = FindOrCreateProcedure(methodBeingTranslated);
- return Bpl.Expr.Ident(info.MethodParameter(gmp.Index));
- }
-
- ITypeReference uninstantiatedGenericType = GetUninstantiatedGenericType(type);
-
- // Corner case: type might be a reference to the uninstantiated generic type.
- // This happens, e.g., with "typeof(Dictionary<,>)".
- // In that case, need to create a constant for it (because Boogie doesn't allow
- // overloading by arity on functions
- if (type.ResolvedType.IsGeneric && type == uninstantiatedGenericType) {
- return FindOrDefineTypeConstant(type);
- }
-
- List<ITypeReference> consolidatedTypeArguments = new List<ITypeReference>();
- GetConsolidatedTypeArguments(consolidatedTypeArguments, type);
-
- if (consolidatedTypeArguments.Count > 0) {
- this.FindOrCreateTypeReference(uninstantiatedGenericType);
- var k = uninstantiatedGenericType.InternedKey;
- var f2 = this.declaredTypeFunctions[k];
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- foreach (ITypeReference p in consolidatedTypeArguments) {
- args.Add(FindOrCreateTypeReference(p, codeContext));
- }
- Bpl.Expr naryExpr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f2), args);
- return naryExpr;
- }
-
- var f = FindOrDefineType(type.ResolvedType);
- var fCall = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f), new Bpl.ExprSeq());
- return fCall;
- }
-
- /// <summary>
- /// Constants of type "Type" that represent the uninstantiated type of a generic type.
- /// E.g. "Dictionary&lt;,&gt;".
- /// </summary>
- private Dictionary<uint, Bpl.Constant> declaredTypeConstants = new Dictionary<uint, Bpl.Constant>();
- private Bpl.Expr FindOrDefineTypeConstant(ITypeReference type) {
- Bpl.Constant c;
- var k = type.InternedKey;
- if (!this.declaredTypeConstants.TryGetValue(k, out c)) {
- var typeName = TypeHelper.GetTypeName(type);
- var i = typeName.IndexOf('`');
- // assume there is just one occurrence
- if (i != -1) {
- typeName = typeName.Substring(0, i);
- }
- typeName = TranslationHelper.TurnStringIntoValidIdentifier(typeName);
- var typedIdent = new Bpl.TypedIdent(Bpl.Token.NoToken, typeName, this.Heap.TypeType);
- c = new Bpl.Constant(Bpl.Token.NoToken, typedIdent, true);
- this.declaredTypeConstants.Add(k, c);
- this.TranslatedProgram.TopLevelDeclarations.Add(c);
- }
- return Bpl.Expr.Ident(c);
- }
-
- private Dictionary<IGenericParameter, Bpl.Formal> declaredTypeParameters = new Dictionary<IGenericParameter, Bpl.Formal>();
- public Bpl.Formal FindOrDefineTypeParameter(IGenericParameter genericParameter) {
- Bpl.Formal formal;
- if (!this.declaredTypeParameters.TryGetValue(genericParameter, out formal)) {
- var n = genericParameter.Name.Value;
- var n2 = TranslationHelper.TurnStringIntoValidIdentifier(n);
- formal = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, n2, this.Heap.TypeType), true);
- }
- return formal;
- }
-
- /// <summary>
- /// Every type is represented as a function.
- /// Non-generic types are nullary functions.
- /// Generic types are n-ary functions, where n is the number of generic parameters.
- /// </summary>
- public Bpl.Function FindOrDefineType(ITypeDefinition type) {
-
- Bpl.Function f;
-
- var key = type.InternedKey;
- if (this.declaredTypeFunctions.TryGetValue(key, out f))
- return f;
-
- var numParameters = ConsolidatedGenericParameterCount(type);
-
- //f = this.Heap.CreateTypeFunction(type, numParameters);
-
- string typename = TypeHelper.GetTypeName(type, NameFormattingOptions.DocumentationId);
- typename = TranslationHelper.TurnStringIntoValidIdentifier(typename);
- var tok = type.Token();
- var inputs = new Bpl.VariableSeq();
- foreach (var t in TranslationHelper.ConsolidatedGenericParameters(type)) {
- var formal = FindOrDefineTypeParameter(t);
- inputs.Add(formal);
- }
- Bpl.Variable output = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "result", this.Heap.TypeType), false);
- Bpl.Function func = new Bpl.Function(tok, typename, inputs, output);
- func.Attributes = new Bpl.QKeyValue(Bpl.Token.NoToken, "constructor", new List<object>(1), null);
- f = func;
-
- this.declaredTypeFunctions.Add(key, f);
- this.TranslatedProgram.TopLevelDeclarations.Add(f);
- DeclareParentsNew(type, f);
-
- bool isExtern = this.assemblyBeingTranslated != null &&
- !TypeHelper.GetDefiningUnitReference(type).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity);
- if (isExtern) {
- var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "extern", new List<object>(1), null);
- f.Attributes.AddLast(attrib);
- }
- return f;
- }
-
- private void DeclareParentsNew(ITypeDefinition typeDefinition, Bpl.Function typeDefinitionAsBplFunction) {
- List<Bpl.Expr> superTypeExprs = new List<Bpl.Expr>();
- foreach (var p in typeDefinition.BaseClasses) {
- superTypeExprs.Add(FindOrCreateTypeReference(p));
- }
- foreach (var j in typeDefinition.Interfaces) {
- superTypeExprs.Add(FindOrCreateTypeReference(j));
- }
-
- var numberOfGenericParameters = typeDefinitionAsBplFunction.InParams.Length;
-
- var qvars = new Bpl.VariableSeq();
- var exprs1 = new Bpl.ExprSeq();
- var exprs2 = new Bpl.ExprSeq();
- var exprs3 = new Bpl.ExprSeq();
- for (int i = 0; i < numberOfGenericParameters; i++) {
- var t = typeDefinitionAsBplFunction.InParams[i];
- qvars.Add(t);
- exprs1.Add(Bpl.Expr.Ident(t));
- exprs2.Add(Bpl.Expr.Ident(t));
- exprs3.Add(Bpl.Expr.Ident(t));
- }
-
- // G(t,u)
- var callToG1 = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(typeDefinitionAsBplFunction), exprs1);
- var callToG2 = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(typeDefinitionAsBplFunction), exprs2);
- var callToG3 = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(typeDefinitionAsBplFunction), exprs3);
-
- // T
- Bpl.BoundVariable boundTypeVar = new Bpl.BoundVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "$T", this.Heap.TypeType));
- qvars.Add(boundTypeVar);
- var lhs = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.Heap.Subtype), new Bpl.ExprSeq(callToG1, Bpl.Expr.Ident(boundTypeVar)));
- var rhs = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, callToG2, Bpl.Expr.Ident(boundTypeVar));
- foreach (var superTypeExpr in superTypeExprs) {
- var subtype = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.Heap.Subtype), new Bpl.ExprSeq(superTypeExpr, Bpl.Expr.Ident(boundTypeVar)));
- rhs = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, rhs, subtype);
- }
- var trigger = new Bpl.Trigger(Bpl.Token.NoToken, true, new Bpl.ExprSeq(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.Heap.Subtype), new Bpl.ExprSeq(callToG3, Bpl.Expr.Ident(boundTypeVar)))));
- var forall = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, lhs, rhs));
- this.TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, forall));
- }
-
- private void DeclareParents(ITypeDefinition typeDefinition, Bpl.Function typeDefinitionAsBplFunction) {
- foreach (var p in typeDefinition.BaseClasses) {
- DeclareSuperType(typeDefinitionAsBplFunction, p);
- }
- foreach (var j in typeDefinition.Interfaces) {
- DeclareSuperType(typeDefinitionAsBplFunction, j);
- }
- return;
- }
- private void DeclareSuperType(Bpl.Function typeDefinitionAsBplFunction, ITypeReference superType) {
- var superTypeExpr = FindOrCreateTypeReference(superType);
- var numberOfGenericParameters = typeDefinitionAsBplFunction.InParams.Length;
-
- var qvars = new Bpl.VariableSeq();
- var exprs = new Bpl.ExprSeq();
- for (int i = 0; i < numberOfGenericParameters; i++) {
- var t = typeDefinitionAsBplFunction.InParams[i];
- qvars.Add(t);
- var identForT = Bpl.Expr.Ident(t);
- exprs.Add(identForT);
- }
-
- // G(t,u)
- var callToG = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(typeDefinitionAsBplFunction), exprs);
- // Subtype(G(t,u), super)
- Bpl.Expr subtype = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.Heap.Subtype), new Bpl.ExprSeq(callToG, superTypeExpr));
- Bpl.Expr disjointSubtree = null;
- var isDisjoint = !superType.ResolvedType.IsInterface;
- if (isDisjoint) {
- // DisjointSubtree(G(t,u), super)
- disjointSubtree = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.Heap.DisjointSubtree), new Bpl.ExprSeq(callToG, superTypeExpr));
- }
-
- if (0 < numberOfGenericParameters) {
-
- // (forall t : Type, u : Type :: { G(t,u) } Subtype(G(t,u), super))
- var trigger = new Bpl.Trigger(Bpl.Token.NoToken, true, new Bpl.ExprSeq(callToG));
- var forall = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, subtype);
- subtype = forall;
-
- if (isDisjoint) {
- // (forall t : Type, u : Type :: { G(t,u) } DisjointSubtree(G(t,u), super))
- disjointSubtree = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, disjointSubtree);
- }
- }
-
- this.TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, subtype));
- if (isDisjoint) {
- this.TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, disjointSubtree));
- }
-
- }
-
- private List<Bpl.ConstantParent> GetParents(ITypeDefinition typeDefinition, out List<ITypeReference> structuralParents) {
- var parents = new List<Bpl.ConstantParent>();
- structuralParents = new List<ITypeReference>();
- foreach (var p in typeDefinition.BaseClasses) {
- if (p is IGenericTypeInstanceReference) {
- structuralParents.Add(p);
- }
- else {
- var v = (Bpl.IdentifierExpr)FindOrCreateTypeReference(p);
- parents.Add(new Bpl.ConstantParent(v, true));
- }
- }
- foreach (var j in typeDefinition.Interfaces) {
- if (j is IGenericTypeInstanceReference) {
- structuralParents.Add(j);
- }
- else {
- var v = (Bpl.IdentifierExpr)FindOrCreateTypeReference(j);
- parents.Add(new Bpl.ConstantParent(v, false));
- }
- }
- return parents;
- }
-
- /// <summary>
- /// The keys to the table are the interned key of the type.
- /// </summary>
- private Dictionary<uint, Bpl.Function> declaredTypeFunctions = new Dictionary<uint, Bpl.Function>();
- private List<Bpl.Function> childFunctions = new List<Bpl.Function>();
-
-
- class MethodComparer : IEqualityComparer<IMethodReference> {
- public bool Equals(IMethodReference x, IMethodReference y) {
- return x.InternedKey == y.InternedKey;
- }
-
- public int GetHashCode(IMethodReference obj) {
- return (int)obj.InternedKey;
- }
- }
-
- /// <summary>
- /// The keys to the table are the methods. (Equality on keys is determined by their InternedKey.)
- /// The values are pairs: first element is the procedure,
- /// second element is the formal map for the procedure
- /// </summary>
- private Dictionary<IMethodReference, ProcedureInfo> declaredMethods = new Dictionary<IMethodReference, ProcedureInfo>(new MethodComparer());
-
- /// <summary>
- /// The values in this table are the procedures
- /// defined in the program created by the heap in the Sink's ctor.
- /// </summary>
- public Dictionary<string, ProcedureInfo> initiallyDeclaredProcedures = new Dictionary<string, ProcedureInfo>();
-
- public void BeginMethod(ITypeReference containingType) {
- this.localVarMap = new Dictionary<string, Bpl.LocalVariable>();
- this.localCounter = 0;
- this.methodBeingTranslated = null;
- var selfType = CciTypeToBoogie(containingType);
- this.thisVariable = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "$this", selfType), true);
- }
-
- public Dictionary<IName, int> cciLabels;
- public int FindOrCreateCciLabelIdentifier(IName label) {
- int v;
- if (!cciLabels.TryGetValue(label, out v)) {
- v = cciLabels.Count;
- cciLabels[label] = v;
- }
- return v;
- }
- public Dictionary<ITryCatchFinallyStatement, int> tryCatchFinallyIdentifiers;
- public string FindOrCreateCatchLabel(ITryCatchFinallyStatement stmt) {
- int id;
- if (!tryCatchFinallyIdentifiers.TryGetValue(stmt, out id)) {
- id = tryCatchFinallyIdentifiers.Count;
- tryCatchFinallyIdentifiers[stmt] = id;
- }
- return "catch" + id;
- }
- public string FindOrCreateFinallyLabel(ITryCatchFinallyStatement stmt) {
- int id;
- if (!tryCatchFinallyIdentifiers.TryGetValue(stmt, out id)) {
- id = tryCatchFinallyIdentifiers.Count;
- tryCatchFinallyIdentifiers[stmt] = id;
- }
- return "finally" + id;
- }
- public string FindOrCreateContinuationLabel(ITryCatchFinallyStatement stmt) {
- int id;
- if (!tryCatchFinallyIdentifiers.TryGetValue(stmt, out id)) {
- id = tryCatchFinallyIdentifiers.Count;
- tryCatchFinallyIdentifiers[stmt] = id;
- }
- return "continuation" + id;
- }
- MostNestedTryStatementTraverser mostNestedTryStatementTraverser;
- public ITryCatchFinallyStatement MostNestedTryStatement(IName label) {
- return mostNestedTryStatementTraverser.MostNestedTryStatement(label);
- }
- Dictionary<ITryCatchFinallyStatement, List<string>> escapingGotoEdges;
- public void AddEscapingEdge(ITryCatchFinallyStatement tryCatchFinallyStatement, out int labelId, out string label) {
- List<string> edges = null;
- if (!escapingGotoEdges.ContainsKey(tryCatchFinallyStatement)) {
- escapingGotoEdges[tryCatchFinallyStatement] = new List<string>();
- }
- edges = escapingGotoEdges[tryCatchFinallyStatement];
- label = this.FindOrCreateFinallyLabel(tryCatchFinallyStatement) + "_" + edges.Count;
- labelId = edges.Count;
- edges.Add(label);
- }
- public List<string> EscapingEdges(ITryCatchFinallyStatement tryCatchFinallyStatement) {
- if (!escapingGotoEdges.ContainsKey(tryCatchFinallyStatement)) {
- escapingGotoEdges[tryCatchFinallyStatement] = new List<string>();
- }
- return escapingGotoEdges[tryCatchFinallyStatement];
- }
- public enum TryCatchFinallyContext { InTry, InCatch, InFinally };
- public List<Tuple<ITryCatchFinallyStatement, TryCatchFinallyContext>> nestedTryCatchFinallyStatements;
-
- IMethodDefinition methodBeingTranslated;
-
- public IMethodDefinition getMethodBeingTranslated() {
- return methodBeingTranslated;
- }
-
- public void BeginMethod(IMethodDefinition method) {
- TranslationHelper.tmpVarCounter = 0;
- this.BeginMethod(method.ContainingType);
- this.methodBeingTranslated = method;
- this.cciLabels = new Dictionary<IName, int>();
- this.tryCatchFinallyIdentifiers = new Dictionary<ITryCatchFinallyStatement, int>();
- mostNestedTryStatementTraverser = new MostNestedTryStatementTraverser();
- escapingGotoEdges = new Dictionary<ITryCatchFinallyStatement, List<string>>();
- nestedTryCatchFinallyStatements = new List<Tuple<ITryCatchFinallyStatement, TryCatchFinallyContext>>();
- mostNestedTryStatementTraverser.Traverse(method.Body);
- this.operandStack.Clear();
- }
-
- public void BeginAssembly(IAssembly assembly) {
- this.assemblyBeingTranslated = assembly;
- }
-
- public void EndAssembly(IAssembly assembly) {
- this.assemblyBeingTranslated = null;
- }
- private IAssembly/*?*/ assemblyBeingTranslated;
-
- public Dictionary<uint, Tuple<ITypeDefinition, HashSet<IMethodDefinition>>> delegateTypeToDelegates =
- new Dictionary<uint, Tuple<ITypeDefinition, HashSet<IMethodDefinition>>>();
-
- public void AddDelegate(ITypeDefinition type, IMethodDefinition defn) {
- if (type == Dummy.Type) {
- }
- uint key = type.InternedKey;
- if (!delegateTypeToDelegates.ContainsKey(key))
- delegateTypeToDelegates[key] = new Tuple<ITypeDefinition, HashSet<IMethodDefinition>>(type, new HashSet<IMethodDefinition>());
- FindOrCreateProcedure(defn);
- delegateTypeToDelegates[key].Item2.Add(defn);
- }
-
- public void AddDelegateType(ITypeDefinition type) {
- if (type == Dummy.Type) {
- }
- uint key = type.InternedKey;
- if (!delegateTypeToDelegates.ContainsKey(key))
- delegateTypeToDelegates[key] = new Tuple<ITypeDefinition, HashSet<IMethodDefinition>>(type, new HashSet<IMethodDefinition>());
- }
-
- private Dictionary<IMethodDefinition, Bpl.Constant> delegateMethods = new Dictionary<IMethodDefinition, Bpl.Constant>();
- internal IContractAwareHost host;
-
- public Bpl.Constant FindOrCreateDelegateMethodConstant(IMethodDefinition defn) {
- if (delegateMethods.ContainsKey(defn))
- return delegateMethods[defn];
- string methodName = TranslationHelper.CreateUniqueMethodName(defn);
- var typedIdent = new Bpl.TypedIdent(Bpl.Token.NoToken, methodName, Bpl.Type.Int);
- var constant = new Bpl.Constant(Bpl.Token.NoToken, typedIdent, true);
- this.TranslatedProgram.TopLevelDeclarations.Add(constant);
- delegateMethods[defn] = constant;
- return constant;
- }
-
- public bool TranslateType(ITypeReference t) {
- if (this.exemptionList == null)
- return !this.whiteList;
- var fullName = TypeHelper.GetTypeName(t);
- var fullerName = "[" + TypeHelper.GetDefiningUnitReference(t).Name.Value + "]" + fullName;
- foreach (Regex r in this.exemptionList) {
- Match m = r.Match(fullName);
- if (m.Success)
- return this.whiteList;
- m = r.Match(fullerName);
- if (m.Success)
- return this.whiteList;
- }
- return !this.whiteList;
- }
-
- // TODO: get full namespace name from a namespace definition
- //public bool TranslateNamespace(INamespaceDefinition nameSpace) {
- // if (this.exemptionList == null)
- // return !this.whiteList;
- // var fullName = TypeHelper.GetNamespaceName(nameSpace, NameFormattingOptions.None);
- // foreach (Regex r in this.exemptionList) {
- // Match m = r.Match(fullName);
- // if (m.Success)
- // return this.whiteList;
- // }
- // return !this.whiteList;
- //}
-
-
- internal void CreateIdentifierCorrespondenceTable(string baseFileName) {
- using (var writer = new StreamWriter(baseFileName + "_names.txt")) {
- foreach (var pair in this.declaredMethods) {
- var m = pair.Key;
- var mName = MemberHelper.GetMethodSignature(m, NameFormattingOptions.DocumentationId);
- var proc = pair.Value;
- writer.WriteLine("{0}\t\t\t{1}", mName, proc.Decl.Name);
- }
- foreach (var pair in this.declaredFields) {
- var f = pair.Key;
- var fName = MemberHelper.GetMemberSignature(f, NameFormattingOptions.DocumentationId);
- var variable = pair.Value;
- writer.WriteLine("{0}\t\t\t{1}", fName, variable.Name);
- }
- }
- }
-
- private int uniqueNumberSeed;
- public int UniqueNumberAcrossAllAssemblies {
- get {
- return uniqueNumberSeed++;
- }
- }
-
-
- public Predicate<IMethodDefinition> MethodThrowsExceptions = m => false;
-
- /// <summary>
- /// Moved from the statement traverser since it needs to be shared among the different statement
- /// traversers, e.g., from before a conditional down into the branches. Really the whole idea
- /// of having different statement traversers needs to be rethought, as does the use of this
- /// operand stack to hold push and dup values...
- /// </summary>
- internal readonly Stack<Bpl.Expr> operandStack = new Stack<Bpl.Expr>();
-
- }
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/StatementTraverser.cs b/BCT/BytecodeTranslator/StatementTraverser.cs
deleted file mode 100644
index 4b328a67..00000000
--- a/BCT/BytecodeTranslator/StatementTraverser.cs
+++ /dev/null
@@ -1,599 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics.Contracts;
-using TranslationPlugins;
-using BytecodeTranslator.Phone;
-
-
-namespace BytecodeTranslator
-{
- public class MostNestedTryStatementTraverser : CodeTraverser {
- Dictionary<IName, ITryCatchFinallyStatement> mostNestedTryStatement = new Dictionary<IName, ITryCatchFinallyStatement>();
- ITryCatchFinallyStatement currStatement = null;
- public override void TraverseChildren(ILabeledStatement labeledStatement) {
- if (currStatement != null)
- mostNestedTryStatement.Add(labeledStatement.Label, currStatement);
- base.TraverseChildren(labeledStatement);
- }
- public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement) {
- ITryCatchFinallyStatement savedStatement = currStatement;
- currStatement = tryCatchFinallyStatement;
- base.TraverseChildren(tryCatchFinallyStatement);
- currStatement = savedStatement;
- }
- public ITryCatchFinallyStatement MostNestedTryStatement(IName label) {
- if (!mostNestedTryStatement.ContainsKey(label))
- return null;
- return mostNestedTryStatement[label];
- }
- }
-
- public class StatementTraverser : CodeTraverser {
-
- public readonly TraverserFactory factory;
-
- readonly Sink sink;
-
- public readonly PdbReader/*?*/ PdbReader;
-
- public readonly Bpl.StmtListBuilder StmtBuilder = new Bpl.StmtListBuilder();
- private bool contractContext;
- private bool captureState;
- private static int captureStateCounter = 0;
- public IPrimarySourceLocation lastSourceLocation;
-
- #region Constructors
- public StatementTraverser(Sink sink, PdbReader/*?*/ pdbReader, bool contractContext, TraverserFactory factory) {
- this.sink = sink;
- this.factory = factory;
- PdbReader = pdbReader;
- this.contractContext = contractContext;
- this.captureState = sink.Options.captureState;
- this.PreorderVisitor = new SourceContextEmitter(this);
- }
- #endregion
-
- #region Helper Methods
-
- Bpl.Expr ExpressionFor(IExpression expression) {
- ExpressionTraverser etrav = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- etrav.Traverse(expression);
- Contract.Assert(etrav.TranslatedExpressions.Count == 1);
- return etrav.TranslatedExpressions.Pop();
- }
-
- public ICollection<ITypeDefinition>/*?*/ TranslateMethod(IMethodDefinition method) {
- var methodBody = method.Body as ISourceMethodBody;
- if (methodBody == null) return null;
- var block = methodBody.Block as BlockStatement;
- // TODO: Error if cast fails?
-
- ICollection<ITypeDefinition> newTypes = null;
- if (block != null) {
- var remover = new AnonymousDelegateRemover(this.sink.host, this.PdbReader);
- newTypes = remover.RemoveAnonymousDelegates(methodBody.MethodDefinition, block);
- }
- StmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)));
- this.Traverse(methodBody);
- return newTypes;
- }
- #endregion
-
- #region Helper Classes
- class SourceContextEmitter : CodeVisitor {
- StatementTraverser parent;
- public SourceContextEmitter(StatementTraverser parent) {
- this.parent = parent;
- }
-
- public override void Visit(IStatement statement) {
- EmitSourceContext(statement);
- if (this.parent.sink.Options.captureState) {
- var tok = statement.Token();
- var state = String.Format("s{0}", StatementTraverser.captureStateCounter++);
- var attrib = new Bpl.QKeyValue(tok, "captureState ", new List<object> { state }, null);
- this.parent.StmtBuilder.Add(
- new Bpl.AssumeCmd(tok, Bpl.Expr.True, attrib)
- );
- }
- }
-
- private void EmitSourceContext(IStatement statement) {
- if (statement is IEmptyStatement) return;
- var tok = statement.Token();
- string fileName = null;
- int lineNumber = 0;
- if (this.parent.PdbReader != null) {
- var slocs = this.parent.PdbReader.GetClosestPrimarySourceLocationsFor(statement.Locations);
- foreach (var sloc in slocs) {
- fileName = sloc.Document.Location;
- lineNumber = sloc.StartLine;
-
- this.parent.lastSourceLocation = sloc;
- break;
- }
- if (fileName != null) {
- var attrib = new Bpl.QKeyValue(tok, "sourceLine", new List<object> { Bpl.Expr.Literal((int)lineNumber) }, null);
- attrib = new Bpl.QKeyValue(tok, "sourceFile", new List<object> { fileName }, attrib);
- attrib = new Bpl.QKeyValue(tok, "first", new List<object>(), attrib);
- this.parent.StmtBuilder.Add(
- new Bpl.AssertCmd(tok, Bpl.Expr.True, attrib)
- );
- }
- }
- }
- }
- #endregion
-
- //public override void Visit(ISourceMethodBody methodBody) {
- // var block = methodBody.Block as BlockStatement;
- // // TODO: Error if cast fails?
-
- // if (block != null) {
- // var remover = new AnonymousDelegateRemover(this.sink.host, this.PdbReader);
- // var newTypes = remover.RemoveAnonymousDelegates(methodBody.MethodDefinition, block);
- // }
- // base.Visit(methodBody);
- //}
-
- public override void TraverseChildren(IBlockStatement block) {
- foreach (var s in block.Statements) {
- this.Traverse(s);
- }
- }
-
- #region Basic Statements
-
- public override void TraverseChildren(IAssertStatement assertStatement) {
- Bpl.Expr conditionExpr = ExpressionFor(assertStatement.Condition);
- Bpl.Type conditionType = this.sink.CciTypeToBoogie(assertStatement.Condition.Type);
- if (conditionType == this.sink.Heap.RefType) {
- conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef));
- }
- else if (conditionType == Bpl.Type.Int) {
- conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0));
- }
- else {
- System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool);
- }
- if (this.sink.Options.getMeHere) {
- StmtBuilder.Add(new Bpl.AssumeCmd(assertStatement.Token(), conditionExpr));
- } else {
- StmtBuilder.Add(new Bpl.AssertCmd(assertStatement.Token(), conditionExpr));
- }
- }
-
- public override void TraverseChildren(IAssumeStatement assumeStatement) {
- Bpl.Expr conditionExpr = ExpressionFor(assumeStatement.Condition);
- Bpl.Type conditionType = this.sink.CciTypeToBoogie(assumeStatement.Condition.Type);
- if (conditionType == this.sink.Heap.RefType) {
- conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef));
- }
- else if (conditionType == Bpl.Type.Int) {
- conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0));
- }
- else {
- System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool);
- }
- StmtBuilder.Add(new Bpl.AssumeCmd(assumeStatement.Token(), conditionExpr));
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <remarks>(mschaef) Works, but still a stub</remarks>
- /// <param name="conditionalStatement"></param>
- public override void TraverseChildren(IConditionalStatement conditionalStatement) {
- StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
- StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
- ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
-
- if (this.sink.Options.instrumentBranches) {
- var tok = conditionalStatement.Token();
- thenTraverser.StmtBuilder.Add(
- new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null))
- );
- elseTraverser.StmtBuilder.Add(
- new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null))
- );
- }
-
- condTraverser.Traverse(conditionalStatement.Condition);
- thenTraverser.Traverse(conditionalStatement.TrueBranch);
- elseTraverser.Traverse(conditionalStatement.FalseBranch);
-
- Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop();
- Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type);
- if (conditionType == this.sink.Heap.RefType) {
- conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef));
- }
- else if (conditionType == Bpl.Type.Int) {
- conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0));
- }
- else {
- System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool);
- }
-
- Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(),
- conditionExpr,
- thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()),
- null,
- elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token())
- );
-
- StmtBuilder.Add(ifcmd);
-
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="expressionStatement"></param>
- /// <remarks> TODO: might be wrong for the general case</remarks>
- public override void TraverseChildren(IExpressionStatement expressionStatement) {
-
- var expressionIsOpAssignStatement = false;
- var binOp = expressionStatement.Expression as IBinaryOperation;
- if (binOp != null && binOp.LeftOperand is ITargetExpression)
- expressionIsOpAssignStatement = true;
-
- ExpressionTraverser etrav = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext, expressionIsOpAssignStatement);
- etrav.Traverse(expressionStatement.Expression);
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <remarks>(mschaef) Not Implemented</remarks>
- /// <param name="breakStatement"></param>
- public override void TraverseChildren(IBreakStatement breakStatement) {
- throw new TranslationException("Break statements are not handled");
- //StmtBuilder.Add(new Bpl.BreakCmd(breakStatement.Token(), "I dont know"));
- }
-
- public override void TraverseChildren(IContinueStatement continueStatement) {
- throw new TranslationException("Continue statements are not handled");
- }
-
- public override void TraverseChildren(ISwitchStatement switchStatement) {
- var eTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- eTraverser.Traverse(switchStatement.Expression);
- var conditionExpr = eTraverser.TranslatedExpressions.Pop();
-
- // Can't depend on default case existing or its index in the collection.
- var switchCases = new List<ISwitchCase>();
- ISwitchCase defaultCase = null;
- foreach (var switchCase in switchStatement.Cases) {
- if (switchCase.IsDefault) {
- defaultCase = switchCase;
- } else {
- switchCases.Add(switchCase);
- }
- }
- Bpl.StmtList defaultStmts = null;
- if (defaultCase != null) {
- var defaultBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
- defaultBodyTraverser.Traverse(defaultCase.Body);
- defaultStmts = defaultBodyTraverser.StmtBuilder.Collect(defaultCase.Token());
- }
-
- Bpl.IfCmd ifCmd = null;
-
- for (int i = switchCases.Count-1; 0 <= i; i--) {
-
- var switchCase = switchCases[i];
-
- var scTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- scTraverser.Traverse(switchCase.Expression);
- var scConditionExpr = scTraverser.TranslatedExpressions.Pop();
- var condition = Bpl.Expr.Eq(conditionExpr, scConditionExpr);
-
- var scBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
- scBodyTraverser.Traverse(switchCase.Body);
-
- ifCmd = new Bpl.IfCmd(switchCase.Token(),
- condition,
- scBodyTraverser.StmtBuilder.Collect(switchCase.Token()),
- ifCmd,
- defaultStmts);
- defaultStmts = null; // default body goes only into the innermost if-then-else
-
- }
- StmtBuilder.Add(ifCmd);
- }
-
- /// <summary>
- /// If the local declaration has an initial value, then generate the
- /// statement "loc := e" from it.
- /// Special case: if "loc" is a struct, then treat it as a call to
- /// the default ctor.
- /// Otherwise ignore it.
- /// </summary>
- public override void TraverseChildren(ILocalDeclarationStatement localDeclarationStatement) {
- var initVal = localDeclarationStatement.InitialValue;
- var typ = localDeclarationStatement.LocalVariable.Type;
- var isStruct = TranslationHelper.IsStruct(typ);
- if (initVal == null && !isStruct)
- return;
- var boogieLocal = this.sink.FindOrCreateLocalVariable(localDeclarationStatement.LocalVariable);
- var boogieLocalExpr = Bpl.Expr.Ident(boogieLocal);
- var tok = localDeclarationStatement.Token();
- Bpl.Expr e = null;
-
-
- var structCopy = isStruct && initVal != null && !(initVal is IDefaultValue);
- // then a struct value of type S is being assigned: "lhs := s"
- // model this as the statement "call lhs := S..#copy_ctor(s)" that does the bit-wise copying
- if (isStruct) {
- if (!structCopy) {
- var defaultValue = new DefaultValue() {
- DefaultValueType = typ,
- Locations = new List<ILocation>(localDeclarationStatement.Locations),
- Type = typ,
- };
- var e2 = ExpressionFor(defaultValue);
- StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, boogieLocalExpr, e2));
- } else
- /*if (structCopy) */{
- var proc = this.sink.FindOrCreateProcedureForStructCopy(typ);
- e = ExpressionFor(initVal);
- StmtBuilder.Add(new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr> { e, }, new List<Bpl.IdentifierExpr>{ boogieLocalExpr, }));
- }
- } else {
- e = ExpressionFor(initVal);
- StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, boogieLocalExpr, e));
- }
- return;
- }
-
- public override void TraverseChildren(IPushStatement pushStatement) {
- var tok = pushStatement.Token();
- var val = pushStatement.ValueToPush;
- var e = ExpressionFor(val);
- this.sink.operandStack.Push(e);
- return;
- }
-
- /// <summary>
- ///
- /// </summary>
- public override void TraverseChildren(IReturnStatement returnStatement) {
- Bpl.IToken tok = returnStatement.Token();
-
- if (returnStatement.Expression != null) {
- ExpressionTraverser etrav = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- etrav.Traverse(returnStatement.Expression);
-
- if (this.sink.ReturnVariable == null || etrav.TranslatedExpressions.Count < 1) {
- throw new TranslationException(String.Format("{0} returns a value that is not supported by the function", returnStatement.ToString()));
- }
-
- StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok,
- new Bpl.IdentifierExpr(tok, this.sink.ReturnVariable), etrav.TranslatedExpressions.Pop()));
- }
-
-
- // FEEDBACK TODO extract into a method
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
- IMethodDefinition methodTranslated = sink.getMethodBeingTranslated();
- if (methodTranslated != null && PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(methodTranslated) &&
- !PhoneCodeHelper.instance().isMethodIgnoredForFeedback(methodTranslated)) {
- Bpl.AssertCmd falseAssertion = new Bpl.AssertCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False);
- StmtBuilder.Add(falseAssertion);
- }
- }
-
- StmtBuilder.Add(new Bpl.ReturnCmd(returnStatement.Token()));
- }
- #endregion
-
- #region Goto and Labels
-
- public override void TraverseChildren(IGotoStatement gotoStatement) {
- IName target = gotoStatement.TargetStatement.Label;
- ITryCatchFinallyStatement targetStatement = this.sink.MostNestedTryStatement(target);
- int count = 0;
- while (count < this.sink.nestedTryCatchFinallyStatements.Count) {
- int index = this.sink.nestedTryCatchFinallyStatements.Count - count - 1;
- ITryCatchFinallyStatement nestedStatement = this.sink.nestedTryCatchFinallyStatements[index].Item1;
- if (targetStatement == nestedStatement)
- break;
- int labelId;
- string label;
- this.sink.AddEscapingEdge(nestedStatement, out labelId, out label);
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(labelId)));
- string finallyLabel = this.sink.FindOrCreateFinallyLabel(nestedStatement);
- StmtBuilder.Add(new Bpl.GotoCmd(gotoStatement.Token(), new Bpl.StringSeq(finallyLabel)));
- StmtBuilder.AddLabelCmd(label);
- count++;
- }
- StmtBuilder.Add(new Bpl.GotoCmd(gotoStatement.Token(), new Bpl.StringSeq(target.Value)));
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <remarks> (mschaef) not sure if there is more work to do</remarks>
- /// <param name="labeledStatement"></param>
- public override void TraverseChildren(ILabeledStatement labeledStatement) {
- StmtBuilder.AddLabelCmd(labeledStatement.Label.Value);
- base.Traverse(labeledStatement.Statement);
- }
-
- #endregion
-
- #region Looping Statements
-
- public override void TraverseChildren(IWhileDoStatement whileDoStatement) {
- throw new TranslationException("WhileDo statements are not handled");
- }
-
- public override void TraverseChildren(IForEachStatement forEachStatement) {
- throw new TranslationException("ForEach statements are not handled");
- }
-
- public override void TraverseChildren(IForStatement forStatement) {
- throw new TranslationException("For statements are not handled");
- }
-
- public override void TraverseChildren(IDoUntilStatement doUntilStatement) {
- throw new TranslationException("DoUntil statements are not handled");
- }
- #endregion
-
- public void GenerateDispatchContinuation(ITryCatchFinallyStatement tryCatchFinallyStatement) {
- string continuationLabel = this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement);
- Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(true),
- TranslationHelper.BuildStmtList(new Bpl.GotoCmd(Bpl.Token.NoToken, new Bpl.StringSeq(continuationLabel))), null, null);
- List<string> edges = sink.EscapingEdges(tryCatchFinallyStatement);
- Bpl.IdentifierExpr labelExpr = Bpl.Expr.Ident(this.sink.LabelVariable);
- for (int i = 0; i < edges.Count; i++) {
- string label = edges[i];
- Bpl.GotoCmd gotoCmd = new Bpl.GotoCmd(Bpl.Token.NoToken, new Bpl.StringSeq(label));
- Bpl.Expr targetExpr = Bpl.Expr.Literal(i);
- elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, labelExpr, targetExpr),
- TranslationHelper.BuildStmtList(gotoCmd), elseIfCmd, null);
- }
- this.StmtBuilder.Add(elseIfCmd);
- }
-
- private void RaiseExceptionHelper(Bpl.StmtListBuilder builder) {
- int count = this.sink.nestedTryCatchFinallyStatements.Count;
- if (count == 0) {
- // FEEDBACK TODO unfortunately return statements are created here too
- // FEEDBACK TODO extract into a method
- if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
- IMethodDefinition methodTranslated = sink.getMethodBeingTranslated();
- if (methodTranslated != null && PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(methodTranslated) &&
- !PhoneCodeHelper.instance().isMethodIgnoredForFeedback(methodTranslated)) {
- Bpl.AssertCmd falseAssertion = new Bpl.AssertCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False);
- builder.Add(falseAssertion);
- }
- }
-
- builder.Add(new Bpl.ReturnCmd(Bpl.Token.NoToken));
- }
- else {
- Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext> topOfStack = this.sink.nestedTryCatchFinallyStatements[count - 1];
- string exceptionTarget;
- if (topOfStack.Item2 == Sink.TryCatchFinallyContext.InTry) {
- exceptionTarget = this.sink.FindOrCreateCatchLabel(topOfStack.Item1);
- }
- else if (topOfStack.Item2 == Sink.TryCatchFinallyContext.InCatch) {
- builder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
- exceptionTarget = this.sink.FindOrCreateFinallyLabel(topOfStack.Item1);
- }
- else {
- exceptionTarget = this.sink.FindOrCreateContinuationLabel(topOfStack.Item1);
- }
- builder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new Bpl.StringSeq(exceptionTarget)));
- }
- }
-
- public void RaiseException() {
- RaiseExceptionHelper(StmtBuilder);
- }
-
- public void RaiseException(Bpl.Expr e) {
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- RaiseExceptionHelper(builder);
- Bpl.IfCmd ifCmd = new Bpl.IfCmd(Bpl.Token.NoToken, e, builder.Collect(Bpl.Token.NoToken), null, null);
- StmtBuilder.Add(ifCmd);
- }
-
- public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement) {
-
- if (this.sink.Options.modelExceptions == 0) {
- this.Traverse(tryCatchFinallyStatement.TryBody);
- if (tryCatchFinallyStatement.FinallyBody != null)
- this.Traverse(tryCatchFinallyStatement.FinallyBody);
- return;
- }
-
- this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InTry));
- this.Traverse(tryCatchFinallyStatement.TryBody);
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
- StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new Bpl.StringSeq(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement))));
- this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);
-
- StmtBuilder.AddLabelCmd(this.sink.FindOrCreateCatchLabel(tryCatchFinallyStatement));
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LocalExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)));
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)));
- List<Bpl.StmtList> catchStatements = new List<Bpl.StmtList>();
- List<Bpl.Expr> typeReferences = new List<Bpl.Expr>();
- this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InCatch));
- foreach (ICatchClause catchClause in tryCatchFinallyStatement.CatchClauses) {
- typeReferences.Insert(0, this.sink.FindOrCreateTypeReference(catchClause.ExceptionType, true));
- StatementTraverser catchTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
- if (catchClause.ExceptionContainer != Dummy.LocalVariable) {
- Bpl.Variable catchClauseVariable = this.sink.FindOrCreateLocalVariable(catchClause.ExceptionContainer);
- catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(catchClauseVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
- }
- catchTraverser.Traverse(catchClause.Body);
- catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
- catchTraverser.StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new Bpl.StringSeq(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement))));
- catchStatements.Insert(0, catchTraverser.StmtBuilder.Collect(catchClause.Token()));
- }
- Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(false), TranslationHelper.BuildStmtList(new Bpl.ReturnCmd(Bpl.Token.NoToken)), null, null);
- Bpl.Expr dynTypeOfOperand = this.sink.Heap.DynamicType(Bpl.Expr.Ident(this.sink.LocalExcVariable));
- for (int i = 0; i < catchStatements.Count; i++) {
- Bpl.Expr expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Subtype), new Bpl.ExprSeq(dynTypeOfOperand, typeReferences[i]));
- elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, expr, catchStatements[i], elseIfCmd, null);
- }
- this.StmtBuilder.Add(elseIfCmd);
- this.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
- RaiseException();
- this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);
-
- this.StmtBuilder.AddLabelCmd(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement));
- if (tryCatchFinallyStatement.FinallyBody != null) {
- this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InFinally));
- Bpl.Variable savedExcVariable = this.sink.CreateFreshLocal(this.sink.Heap.RefType);
- Bpl.Variable savedLabelVariable = this.sink.CreateFreshLocal(Bpl.Type.Int);
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)));
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedLabelVariable), Bpl.Expr.Ident(this.sink.LabelVariable)));
- this.Traverse(tryCatchFinallyStatement.FinallyBody);
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(savedExcVariable)));
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Ident(savedLabelVariable)));
- this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);
- }
- GenerateDispatchContinuation(tryCatchFinallyStatement);
- StmtBuilder.AddLabelCmd(this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement));
- Bpl.Expr raiseExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef));
- RaiseException(raiseExpr);
- }
-
- public override void TraverseChildren(IThrowStatement throwStatement) {
- if (this.sink.Options.modelExceptions == 0) {
- StmtBuilder.Add(new Bpl.AssumeCmd(throwStatement.Token(), Bpl.Expr.False));
- return;
- }
- ExpressionTraverser exceptionTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- exceptionTraverser.Traverse(throwStatement.Exception);
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), exceptionTraverser.TranslatedExpressions.Pop()));
- RaiseException();
- }
-
- public override void TraverseChildren(IRethrowStatement rethrowStatement) {
- StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
- RaiseException();
- }
-
- }
-
-}
diff --git a/BCT/BytecodeTranslator/TranslationException.cs b/BCT/BytecodeTranslator/TranslationException.cs
deleted file mode 100644
index c62d78c5..00000000
--- a/BCT/BytecodeTranslator/TranslationException.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BytecodeTranslator {
- public enum ExceptionType {
- UnresolvedMethod,
- UnresolvedType,
- };
-
- public class TranslationException : Exception {
-
- public TranslationException(string reason) : base(reason) {
- }
-
- public TranslationException(ExceptionType eType, string message)
- : base(eType.ToString() + ": " + message) {
- }
-
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationHelper.cs b/BCT/BytecodeTranslator/TranslationHelper.cs
deleted file mode 100644
index 2862a520..00000000
--- a/BCT/BytecodeTranslator/TranslationHelper.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using System.Text.RegularExpressions;
-using System.Diagnostics.Contracts;
-
-namespace BytecodeTranslator {
-
- public class MethodParameter {
-
- /// <summary>
- /// All parameters of the method get an associated in parameter
- /// in the Boogie procedure except for out parameters.
- /// </summary>
- public Bpl.Formal/*?*/ inParameterCopy;
-
- /// <summary>
- /// A local variable when the underlyingParameter is an in parameter
- /// and a formal (out) parameter when the underlyingParameter is
- /// a ref or out parameter.
- /// </summary>
- public Bpl.Variable outParameterCopy;
-
- public IParameterDefinition underlyingParameter;
-
- public MethodParameter(IParameterDefinition parameterDefinition, Bpl.Type ptype) {
- this.underlyingParameter = parameterDefinition;
-
- var parameterToken = parameterDefinition.Token();
- var typeToken = parameterDefinition.Type.Token();
- var parameterName = TranslationHelper.TurnStringIntoValidIdentifier(parameterDefinition.Name.Value);
- if (String.IsNullOrWhiteSpace(parameterName)) parameterName = "P" + parameterDefinition.Index.ToString();
-
- this.inParameterCopy = new Bpl.Formal(parameterToken, new Bpl.TypedIdent(typeToken, parameterName + "$in", ptype), true);
- if (parameterDefinition.IsByReference) {
- this.outParameterCopy = new Bpl.Formal(parameterToken, new Bpl.TypedIdent(typeToken, parameterName + "$out", ptype), false);
- } else {
- this.outParameterCopy = new Bpl.LocalVariable(parameterToken, new Bpl.TypedIdent(typeToken, parameterName, ptype));
- }
- }
-
- public override string ToString() {
- return this.underlyingParameter.Name.Value;
- }
- }
-
- /// <summary>
- /// Class containing several static helper functions to convert
- /// from Cci to Boogie
- /// </summary>
- static class TranslationHelper {
- public static Bpl.StmtList BuildStmtList(Bpl.Cmd cmd, Bpl.TransferCmd tcmd) {
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- builder.Add(cmd);
- builder.Add(tcmd);
- return builder.Collect(Bpl.Token.NoToken);
- }
-
- public static Bpl.StmtList BuildStmtList(Bpl.TransferCmd tcmd) {
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- builder.Add(tcmd);
- return builder.Collect(Bpl.Token.NoToken);
- }
-
- public static Bpl.StmtList BuildStmtList(params Bpl.Cmd[] cmds) {
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- foreach (Bpl.Cmd cmd in cmds)
- builder.Add(cmd);
- return builder.Collect(Bpl.Token.NoToken);
- }
-
- public static Bpl.AssignCmd BuildAssignCmd(Bpl.IdentifierExpr lhs, Bpl.Expr rhs)
- {
- List<Bpl.AssignLhs> lhss = new List<Bpl.AssignLhs>();
- lhss.Add(new Bpl.SimpleAssignLhs(lhs.tok, lhs));
- List<Bpl.Expr> rhss = new List<Bpl.Expr>();
- rhss.Add(rhs);
- return new Bpl.AssignCmd(lhs.tok, lhss, rhss);
- }
-
- public static Bpl.AssignCmd BuildAssignCmd(List<Bpl.IdentifierExpr> lexprs, List<Bpl.Expr> rexprs) {
- List<Bpl.AssignLhs> lhss = new List<Bpl.AssignLhs>();
- foreach (Bpl.IdentifierExpr lexpr in lexprs) {
- lhss.Add(new Bpl.SimpleAssignLhs(lexpr.tok, lexpr));
- }
- List<Bpl.Expr> rhss = new List<Bpl.Expr>();
- return new Bpl.AssignCmd(Bpl.Token.NoToken, lhss, rexprs);
- }
-
- public static Bpl.IToken Token(this IObjectWithLocations objectWithLocations) {
- //TODO: use objectWithLocations.Locations!
- Bpl.IToken tok = Bpl.Token.NoToken;
- return tok;
- }
-
- internal static int tmpVarCounter = 0;
- public static string GenerateTempVarName() {
- return "$tmp" + (tmpVarCounter++).ToString();
- }
-
- internal static int catchClauseCounter = 0;
- public static string GenerateCatchClauseName() {
- return "catch" + (catchClauseCounter++).ToString();
- }
-
- internal static int finallyClauseCounter = 0;
- public static string GenerateFinallyClauseName() {
- return "finally" + (finallyClauseCounter++).ToString();
- }
-
- public static List<IGenericTypeParameter> ConsolidatedGenericParameters(ITypeReference typeReference) {
- Contract.Requires(typeReference != null);
-
- var typeDefinition = typeReference.ResolvedType;
- var totalParameters = new List<IGenericTypeParameter>();
- ConsolidatedGenericParameters(typeDefinition, totalParameters);
- return totalParameters;
-
- //var nestedTypeDefinition = typeDefinition as INestedTypeDefinition;
- //while (nestedTypeDefinition != null) {
- // var containingType = nestedTypeDefinition.ContainingType.ResolvedType;
- // totalParameters.AddRange(containingType.GenericParameters);
- // nestedTypeDefinition = containingType as INestedTypeDefinition;
- //}
- //totalParameters.AddRange(typeDefinition.GenericParameters);
- //return totalParameters;
- }
- private static void ConsolidatedGenericParameters(ITypeDefinition typeDefinition, List<IGenericTypeParameter> consolidatedParameters){
- var nestedTypeDefinition = typeDefinition as INestedTypeDefinition;
- if (nestedTypeDefinition != null){
- ConsolidatedGenericParameters(nestedTypeDefinition.ContainingTypeDefinition, consolidatedParameters);
- }
- consolidatedParameters.AddRange(typeDefinition.GenericParameters);
- }
-
- public static string CreateUniqueMethodName(IMethodReference method) {
- var containingTypeName = TypeHelper.GetTypeName(method.ContainingType, NameFormattingOptions.None);
- var s = MemberHelper.GetMethodSignature(method, NameFormattingOptions.DocumentationId);
- s = s.Substring(2);
- s = s.TrimEnd(')');
- s = TurnStringIntoValidIdentifier(s);
- return s;
- }
-
- public static string TurnStringIntoValidIdentifier(string s) {
-
- // Do this specially just to make the resulting string a little bit more readable.
- // REVIEW: Just let the main replacement take care of it?
- s = s.Replace("[0:,0:]", "2DArray"); // TODO: Do this programmatically to handle arbitrary arity
- s = s.Replace("[0:,0:,0:]", "3DArray");
- s = s.Replace("[0:,0:,0:,0:]", "4DArray");
- s = s.Replace("[0:,0:,0:,0:,0:]", "5DArray");
- s = s.Replace("[]", "array");
-
- // The definition of a Boogie identifier is from BoogiePL.atg.
- // Just negate that to get which characters should be replaced with a dollar sign.
-
- // letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
- // digit = "0123456789".
- // special = "'~#$^_.?`".
- // nondigit = letter + special.
- // ident = [ '\\' ] nondigit {nondigit | digit}.
-
- s = Regex.Replace(s, "[^A-Za-z0-9'~#$^_.?`]", "$");
-
- s = GetRidOfSurrogateCharacters(s);
- return s;
- }
-
- /// <summary>
- /// Unicode surrogates cannot be handled by Boogie.
- /// http://msdn.microsoft.com/en-us/library/dd374069(v=VS.85).aspx
- /// </summary>
- private static string GetRidOfSurrogateCharacters(string s) {
- // TODO this is not enough! Actually Boogie cannot support UTF8
- var cs = s.ToCharArray();
- var okayChars = new char[cs.Length];
- for (int i = 0, j = 0; i < cs.Length; i++) {
- if (Char.IsSurrogate(cs[i])) continue;
- okayChars[j++] = cs[i];
- }
- var raw = String.Concat(okayChars);
- return raw.Trim(new char[] { '\0' });
- }
-
- public static bool IsStruct(ITypeReference typ) {
- return typ.IsValueType && !typ.IsEnum && typ.TypeCode == PrimitiveTypeCode.NotPrimitive;
- }
-
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/BytecodeTranslator/BytecodeTranslatorPlugin.cs b/BCT/BytecodeTranslator/TranslationPlugins/BytecodeTranslator/BytecodeTranslatorPlugin.cs
deleted file mode 100644
index a7b00f63..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/BytecodeTranslator/BytecodeTranslatorPlugin.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Microsoft.Cci.Contracts;
-
-namespace BytecodeTranslator.TranslationPlugins.BytecodeTranslator {
- internal class BytecodeTranslatorPlugin : ITranslationPlugin {
- private bool isWholeProgram = false;
-
- public BytecodeTranslatorPlugin(Boolean isWholeProgram) {
- this.isWholeProgram = isWholeProgram;
- }
-
- public Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
- TraverserFactory factory;
- if (isWholeProgram)
- factory= new WholeProgram();
- else
- factory= new CLRSemantics();
- // Translator translator= factory.MakeMetadataTraverser(sink, contractProviders, pdbReaders);
- Translator translator= factory.getTranslator(sink, contractProviders, pdbReaders);
- return translator;
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/ContractAwareTranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/ContractAwareTranslator.cs
deleted file mode 100644
index ceb8ca0a..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/ContractAwareTranslator.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Bpl= Microsoft.Boogie;
-using Microsoft.Cci.Contracts;
-
-namespace BytecodeTranslator.TranslationPlugins {
- public abstract class ContractAwareTranslator : Translator {
- public virtual IEnumerable<Bpl.Requires> getPreconditionTranslation(IMethodContract contract) {return new List<Bpl.Requires>(); }
- public virtual IEnumerable<Bpl.Ensures> getPostconditionTranslation(IMethodContract contract) { return new List<Bpl.Ensures>(); }
- public virtual IEnumerable<Bpl.IdentifierExpr> getModifiedIdentifiers(IMethodContract contract) { return new List<Bpl.IdentifierExpr>(); }
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/IContractAwareTranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/IContractAwareTranslator.cs
deleted file mode 100644
index e1079e5d..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/IContractAwareTranslator.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Bpl= Microsoft.Boogie;
-using Microsoft.Cci.Contracts;
-
-namespace BytecodeTranslator.TranslationPlugins {
- interface IContractAwareTranslator : ITranslator {
- IEnumerable<Bpl.Expr> getPreconditionTranslation(IMethodContract contract);
- IEnumerable<Bpl.Expr> getPostconditionTranslation(IMethodContract contract);
- IEnumerable<Bpl.IdentifierExpr> getModifiedIdentifiers(IMethodContract contract);
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/ITranslationPlugin.cs b/BCT/BytecodeTranslator/TranslationPlugins/ITranslationPlugin.cs
deleted file mode 100644
index 9cf895fd..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/ITranslationPlugin.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Microsoft.Cci.Contracts;
-
-namespace BytecodeTranslator.TranslationPlugins {
- public interface ITranslationPlugin {
- Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractExtractors=null, IDictionary<IUnit, PdbReader> pdbReaders=null);
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/ITranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/ITranslator.cs
deleted file mode 100644
index 302794b5..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/ITranslator.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-
-namespace BytecodeTranslator.TranslationPlugins {
- interface ITranslator {
- void TranslateAssemblies(IEnumerable<IUnit> assemblies);
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneFeedbackPlugin.cs b/BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneFeedbackPlugin.cs
deleted file mode 100644
index c6d9b24a..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneFeedbackPlugin.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Microsoft.Cci.Contracts;
-using BytecodeTranslator.TranslationPlugins.Translators;
-
-namespace BytecodeTranslator.TranslationPlugins.PhoneTranslator {
- class PhoneFeedbackPlugin : ITranslationPlugin {
- public Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
- return new PhoneFeedbackTranslator(sink);
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneInitializationPlugin.cs b/BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneInitializationPlugin.cs
deleted file mode 100644
index 98282faa..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/PhoneTranslator/PhoneInitializationPlugin.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-using Microsoft.Cci.Contracts;
-using BytecodeTranslator.TranslationPlugins.Translators;
-
-namespace BytecodeTranslator.TranslationPlugins.PhoneTranslator {
- class PhoneInitializationPlugin : ITranslationPlugin {
- public Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
- return new PhoneInitializationTranslator(sink);
- }
- }
-
- class PhoneNavigationPlugin : ITranslationPlugin {
- public Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
- return new PhoneNavigationTranslator(sink);
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/Translator.cs b/BCT/BytecodeTranslator/TranslationPlugins/Translator.cs
deleted file mode 100644
index 60d7e2f6..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/Translator.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.Cci;
-
-namespace BytecodeTranslator.TranslationPlugins {
- public abstract class Translator {
- public abstract void initialize();
- public abstract bool isOneShot();
- public abstract int getPriority();
-
- public virtual void TranslateAssemblies(IEnumerable<IUnit> assemblies) { }
-
- // Each plugged translator may choose to implement some action on each metadata / AST element
- public virtual void onMetadataElement(IArrayTypeReference arrayTypeReference) { }
- public virtual void onMetadataElement(IAssembly assembly) { }
- public virtual void onMetadataElement(IAssemblyReference assemblyReference) { }
- public virtual void onMetadataElement(ICustomAttribute customAttribute) { }
- public virtual void onMetadataElement(ICustomModifier customModifier) { }
- public virtual void onMetadataElement(IEventDefinition eventDefinition) { }
- public virtual void onMetadataElement(IFieldDefinition fieldDefinition) { }
- public virtual void onMetadataElement(IFieldReference fieldReference) { }
- public virtual void onMetadataElement(IFileReference fileReference) { }
- public virtual void onMetadataElement(IFunctionPointerTypeReference functionPointerTypeReference) { }
- public virtual void onMetadataElement(IGenericMethodInstanceReference genericMethodInstanceReference) { }
- public virtual void onMetadataElement(IGenericMethodParameter genericMethodParameter) { }
- public virtual void onMetadataElement(IGenericMethodParameterReference genericMethodParameterReference) { }
- public virtual void onMetadataElement(IGlobalFieldDefinition globalFieldDefinition) { }
- public virtual void onMetadataElement(IGlobalMethodDefinition globalMethodDefinition) { }
- public virtual void onMetadataElement(IGenericTypeInstanceReference genericTypeInstanceReference) { }
- public virtual void onMetadataElement(IGenericTypeParameter genericTypeParameter) { }
- public virtual void onMetadataElement(IGenericTypeParameterReference genericTypeParameterReference) { }
- public virtual void onMetadataElement(ILocalDefinition localDefinition) { }
- public virtual void onMetadataElement(IManagedPointerTypeReference managedPointerTypeReference) { }
- public virtual void onMetadataElement(IMarshallingInformation marshallingInformation) { }
- public virtual void onMetadataElement(IMetadataConstant constant) { }
- public virtual void onMetadataElement(IMetadataCreateArray createArray) { }
- public virtual void onMetadataElement(IMetadataExpression expression) { }
- public virtual void onMetadataElement(IMetadataNamedArgument namedArgument) { }
- public virtual void onMetadataElement(IMetadataTypeOf typeOf) { }
- public virtual void onMetadataElement(IMethodBody methodBody) { }
- public virtual void onMetadataElement(IMethodDefinition method) { }
- public virtual void onMetadataElement(IMethodImplementation methodImplementation) { }
- public virtual void onMetadataElement(IMethodReference methodReference) { }
- public virtual void onMetadataElement(IModifiedTypeReference modifiedTypeReference) { }
- public virtual void onMetadataElement(IModule module) { }
- public virtual void onMetadataElement(IModuleReference moduleReference) { }
- public virtual void onMetadataElement(INamespaceAliasForType namespaceAliasForType) { }
- public virtual void onMetadataElement(INamespaceTypeDefinition namespaceTypeDefinition) { }
- public virtual void onMetadataElement(INamespaceTypeReference namespaceTypeReference) { }
- public virtual void onMetadataElement(INestedAliasForType nestedAliasForType) { }
- public virtual void onMetadataElement(INestedTypeDefinition nestedTypeDefinition) { }
- public virtual void onMetadataElement(INestedTypeReference nestedTypeReference) { }
- public virtual void onMetadataElement(INestedUnitNamespace nestedUnitNamespace) { }
- public virtual void onMetadataElement(INestedUnitNamespaceReference nestedUnitNamespaceReference) { }
- public virtual void onMetadataElement(INestedUnitSetNamespace nestedUnitSetNamespace) { }
- public virtual void onMetadataElement(IOperation operation) { }
- public virtual void onMetadataElement(IOperationExceptionInformation operationExceptionInformation) { }
- public virtual void onMetadataElement(IParameterDefinition parameterDefinition) { }
- public virtual void onMetadataElement(IParameterTypeInformation parameterTypeInformation) { }
- public virtual void onMetadataElement(IPESection peSection) { }
- public virtual void onMetadataElement(IPlatformInvokeInformation platformInvokeInformation) { }
- public virtual void onMetadataElement(IPointerTypeReference pointerTypeReference) { }
- public virtual void onMetadataElement(IPropertyDefinition propertyDefinition) { }
- public virtual void onMetadataElement(IResourceReference resourceReference) { }
- public virtual void onMetadataElement(IRootUnitNamespace rootUnitNamespace) { }
- public virtual void onMetadataElement(IRootUnitNamespaceReference rootUnitNamespaceReference) { }
- public virtual void onMetadataElement(IRootUnitSetNamespace rootUnitSetNamespace) { }
- public virtual void onMetadataElement(ISecurityAttribute securityAttribute) { }
- public virtual void onMetadataElement(ISpecializedEventDefinition specializedEventDefinition) { }
- public virtual void onMetadataElement(ISpecializedFieldDefinition specializedFieldDefinition) { }
- public virtual void onMetadataElement(ISpecializedFieldReference specializedFieldReference) { }
- public virtual void onMetadataElement(ISpecializedMethodDefinition specializedMethodDefinition) { }
- public virtual void onMetadataElement(ISpecializedMethodReference specializedMethodReference) { }
- public virtual void onMetadataElement(ISpecializedPropertyDefinition specializedPropertyDefinition) { }
- public virtual void onMetadataElement(ISpecializedNestedTypeDefinition specializedNestedTypeDefinition) { }
- public virtual void onMetadataElement(ISpecializedNestedTypeReference specializedNestedTypeReference) { }
- public virtual void onMetadataElement(IUnitSet unitSet) { }
- public virtual void onMetadataElement(IWin32Resource win32Resource) { }
-
- public virtual void onASTElement(IAddition addition) { }
- public virtual void onASTElement(IAddressableExpression addressableExpression) { }
- public virtual void onASTElement(IAddressDereference addressDereference) { }
- public virtual void onASTElement(IAddressOf addressOf) { }
- public virtual void onASTElement(IAnonymousDelegate anonymousDelegate) { }
- public virtual void onASTElement(IArrayIndexer arrayIndexer) { }
- public virtual void onASTElement(IAssertStatement assertStatement) { }
- public virtual void onASTElement(IAssignment assignment) { }
- public virtual void onASTElement(IAssumeStatement assumeStatement) { }
- public virtual void onASTElement(IBitwiseAnd bitwiseAnd) { }
- public virtual void onASTElement(IBitwiseOr bitwiseOr) { }
- public virtual void onASTElement(IBlockExpression blockExpression) { }
- public virtual void onASTElement(IBlockStatement block) { }
- public virtual void onASTElement(IBreakStatement breakStatement) { }
- public virtual void onASTElement(IBoundExpression boundExpression) { }
- public virtual void onASTElement(ICastIfPossible castIfPossible) { }
- public virtual void onASTElement(ICatchClause catchClause) { }
- public virtual void onASTElement(ICheckIfInstance checkIfInstance) { }
- public virtual void onASTElement(ICompileTimeConstant constant) { }
- public virtual void onASTElement(IConversion conversion) { }
- public virtual void onASTElement(IConditional conditional) { }
- public virtual void onASTElement(IConditionalStatement conditionalStatement) { }
- public virtual void onASTElement(IContinueStatement continueStatement) { }
- public virtual void onASTElement(ICreateArray createArray) { }
- public virtual void onASTElement(ICreateDelegateInstance createDelegateInstance) { }
- public virtual void onASTElement(ICreateObjectInstance createObjectInstance) { }
- public virtual void onASTElement(IDebuggerBreakStatement debuggerBreakStatement) { }
- public virtual void onASTElement(IDefaultValue defaultValue) { }
- public virtual void onASTElement(IDivision division) { }
- public virtual void onASTElement(IDoUntilStatement doUntilStatement) { }
- public virtual void onASTElement(IDupValue dupValue) { }
- public virtual void onASTElement(IEmptyStatement emptyStatement) { }
- public virtual void onASTElement(IEquality equality) { }
- public virtual void onASTElement(IExclusiveOr exclusiveOr) { }
- public virtual void onASTElement(IExpressionStatement expressionStatement) { }
- public virtual void onASTElement(IForEachStatement forEachStatement) { }
- public virtual void onASTElement(IForStatement forStatement) { }
- public virtual void onASTElement(IGotoStatement gotoStatement) { }
- public virtual void onASTElement(IGotoSwitchCaseStatement gotoSwitchCaseStatement) { }
- public virtual void onASTElement(IGetTypeOfTypedReference getTypeOfTypedReference) { }
- public virtual void onASTElement(IGetValueOfTypedReference getValueOfTypedReference) { }
- public virtual void onASTElement(IGreaterThan greaterThan) { }
- public virtual void onASTElement(IGreaterThanOrEqual greaterThanOrEqual) { }
- public virtual void onASTElement(ILabeledStatement labeledStatement) { }
- public virtual void onASTElement(ILeftShift leftShift) { }
- public virtual void onASTElement(ILessThan lessThan) { }
- public virtual void onASTElement(ILessThanOrEqual lessThanOrEqual) { }
- public virtual void onASTElement(ILocalDeclarationStatement localDeclarationStatement) { }
- public virtual void onASTElement(ILockStatement lockStatement) { }
- public virtual void onASTElement(ILogicalNot logicalNot) { }
- public virtual void onASTElement(IMakeTypedReference makeTypedReference) { }
- public virtual void onASTElement(IMethodCall methodCall) { }
- public virtual void onASTElement(IModulus modulus) { }
- public virtual void onASTElement(IMultiplication multiplication) { }
- public virtual void onASTElement(INamedArgument namedArgument) { }
- public virtual void onASTElement(INotEquality notEquality) { }
- public virtual void onASTElement(IOldValue oldValue) { }
- public virtual void onASTElement(IOnesComplement onesComplement) { }
- public virtual void onASTElement(IOutArgument outArgument) { }
- public virtual void onASTElement(IPointerCall pointerCall) { }
- public virtual void onASTElement(IPopValue popValue) { }
- public virtual void onASTElement(IPushStatement pushStatement) { }
- public virtual void onASTElement(IRefArgument refArgument) { }
- public virtual void onASTElement(IResourceUseStatement resourceUseStatement) { }
- public virtual void onASTElement(IReturnValue returnValue) { }
- public virtual void onASTElement(IRethrowStatement rethrowStatement) { }
- public virtual void onASTElement(IReturnStatement returnStatement) { }
- public virtual void onASTElement(IRightShift rightShift) { }
- public virtual void onASTElement(IRuntimeArgumentHandleExpression runtimeArgumentHandleExpression) { }
- public virtual void onASTElement(ISizeOf sizeOf) { }
- public virtual void onASTElement(IStackArrayCreate stackArrayCreate) { }
- public virtual void onASTElement(ISubtraction subtraction) { }
- public virtual void onASTElement(ISwitchCase switchCase) { }
- public virtual void onASTElement(ISwitchStatement switchStatement) { }
- public virtual void onASTElement(ITargetExpression targetExpression) { }
- public virtual void onASTElement(IThisReference thisReference) { }
- public virtual void onASTElement(IThrowStatement throwStatement) { }
- public virtual void onASTElement(ITryCatchFinallyStatement tryCatchFilterFinallyStatement) { }
- public virtual void onASTElement(ITokenOf tokenOf) { }
- public virtual void onASTElement(ITypeOf typeOf) { }
- public virtual void onASTElement(IUnaryNegation unaryNegation) { }
- public virtual void onASTElement(IUnaryPlus unaryPlus) { }
- public virtual void onASTElement(IVectorLength vectorLength) { }
- public virtual void onASTElement(IWhileDoStatement whileDoStatement) { }
- public virtual void onASTElement(IYieldBreakStatement yieldBreakStatement) { }
- public virtual void onASTElement(IYieldReturnStatement yieldReturnStatement) { }
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs
deleted file mode 100644
index 1ceb7902..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using BytecodeTranslator.TranslationPlugins;
-using Microsoft.Cci;
-using Microsoft.Cci.Contracts;
-
-namespace BytecodeTranslator {
- class BaseTranslator : ContractAwareTranslator {
- public TraverserFactory Factory;
- private Sink sink;
- private IDictionary<IUnit, IContractProvider> contractProviders;
- private IDictionary<IUnit, PdbReader> pdbReaders;
- private BCTMetadataTraverser traverser;
-
- public BaseTranslator(TraverserFactory factory, Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
- Factory = factory;
- this.sink = sink;
- this.contractProviders = contractProviders;
- this.pdbReaders = pdbReaders;
- }
-
- public override void initialize() {
- traverser = Factory.MakeMetadataTraverser(sink, contractProviders, pdbReaders);
- }
-
- public override bool isOneShot() {
- return true;
- }
-
- public override int getPriority() {
- // TODO make configurable from outside
- return 10;
- }
-
- public override void TranslateAssemblies(IEnumerable<Microsoft.Cci.IUnit> assemblies) {
- traverser.TranslateAssemblies(assemblies);
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs
deleted file mode 100644
index ffd6fe52..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using BytecodeTranslator.Phone;
-using Microsoft.Cci;
-
-namespace BytecodeTranslator.TranslationPlugins.Translators {
- class PhoneFeedbackTranslator : Translator {
- private Sink sink;
- PhoneControlFeedbackMetadataTraverser traverser;
-
- public PhoneFeedbackTranslator(Sink sink) {
- this.sink = sink;
- }
-
- public override void initialize() {
- traverser = new PhoneControlFeedbackMetadataTraverser(sink.host as MetadataReaderHost);
- }
-
- public override bool isOneShot() {
- return true;
- }
-
- public override int getPriority() {
- // TODO make configurable from outside
- return 3;
- }
-
- public override void TranslateAssemblies(IEnumerable<Microsoft.Cci.IUnit> assemblies) {
- foreach (var a in assemblies) {
- traverser.Traverse((IAssembly)a);
- }
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneInitializationTranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneInitializationTranslator.cs
deleted file mode 100644
index 7cd35b44..00000000
--- a/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneInitializationTranslator.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using BytecodeTranslator.Phone;
-using Microsoft.Cci;
-
-namespace BytecodeTranslator.TranslationPlugins.Translators {
- class PhoneInitializationTranslator : Translator {
- private Sink sink;
- PhoneInitializationMetadataTraverser traverser;
-
- public PhoneInitializationTranslator(Sink sink) {
- this.sink = sink;
- }
-
- public override void initialize() {
- traverser = new PhoneInitializationMetadataTraverser(sink.host as MetadataReaderHost);
- }
-
- public override bool isOneShot() {
- return true;
- }
-
- public override int getPriority() {
- // TODO make configurable from outside
- return 1;
- }
-
- public override void TranslateAssemblies(IEnumerable<Microsoft.Cci.IUnit> assemblies) {
- traverser.InjectPhoneCodeAssemblies(assemblies);
- }
- }
-
- class PhoneNavigationTranslator : Translator {
- private Sink sink;
- PhoneNavigationMetadataTraverser traverser;
-
- public PhoneNavigationTranslator(Sink sink) {
- this.sink = sink;
- }
-
- public override void initialize() {
- traverser = new PhoneNavigationMetadataTraverser(sink.host as MetadataReaderHost);
- }
-
- public override bool isOneShot() {
- return true;
- }
-
- public override int getPriority() {
- // TODO make configurable from outside
- return 2;
- }
-
- public override void TranslateAssemblies(IEnumerable<Microsoft.Cci.IUnit> assemblies) {
- traverser.InjectPhoneCodeAssemblies(assemblies);
- }
- }
-}
diff --git a/BCT/BytecodeTranslator/TraverserFactory.cs b/BCT/BytecodeTranslator/TraverserFactory.cs
deleted file mode 100644
index e6778c46..00000000
--- a/BCT/BytecodeTranslator/TraverserFactory.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using TranslationPlugins;
-
-using Bpl = Microsoft.Boogie;
-using BytecodeTranslator.TranslationPlugins;
-
-namespace BytecodeTranslator {
- public abstract class TraverserFactory {
- public int Priority { get; set; }
-
- public abstract Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> reader);
-
- public virtual BCTMetadataTraverser MakeMetadataTraverser(Sink sink,
- IDictionary<IUnit, IContractProvider> contractProviders, // TODO: remove this parameter?
- IDictionary<IUnit, PdbReader> sourceLocationProviders)
- {
- return new BCTMetadataTraverser(sink, sourceLocationProviders, this);
- }
- public virtual StatementTraverser MakeStatementTraverser(Sink sink, PdbReader/*?*/ pdbReader, bool contractContext) {
- return new StatementTraverser(sink, pdbReader, contractContext, this);
- }
-
- public virtual ExpressionTraverser MakeExpressionTraverser(Sink sink, StatementTraverser/*?*/ statementTraverser, bool contractContext, bool expressionIsOpAssignStatement = false) {
- return new ExpressionTraverser(sink, statementTraverser, contractContext, expressionIsOpAssignStatement);
- }
- }
-} \ No newline at end of file
diff --git a/BCT/BytecodeTranslator/WholeProgram.cs b/BCT/BytecodeTranslator/WholeProgram.cs
deleted file mode 100644
index 91761cb2..00000000
--- a/BCT/BytecodeTranslator/WholeProgram.cs
+++ /dev/null
@@ -1,338 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics.Contracts;
-
-namespace BytecodeTranslator {
- class WholeProgram : TraverserFactory {
-
- public override TranslationPlugins.Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
- BaseTranslator translator = new BaseTranslator(this, sink, contractProviders, pdbReaders);
- return translator;
- }
-
- /// <summary>
- /// Table to be filled by the metadata traverser before visiting any assemblies.
- ///
- /// The table lists the direct supertypes of all type definitions that it encounters during the
- /// traversal. (But the table is organized so that subTypes[T] is the list of type definitions
- /// that are direct subtypes of T.)
- /// </summary>
- readonly public Dictionary<ITypeReference, List<ITypeReference>> subTypes = new Dictionary<ITypeReference, List<ITypeReference>>();
-
- public override BCTMetadataTraverser MakeMetadataTraverser(Sink sink,
- IDictionary<IUnit, IContractProvider> contractProviders, // TODO: remove this parameter?
- IDictionary<IUnit, PdbReader> pdbReaders) {
- return new WholeProgramMetadataSemantics(this, sink, pdbReaders, this);
- }
-
- public class WholeProgramMetadataSemantics : BCTMetadataTraverser {
-
- readonly WholeProgram parent;
- readonly Sink sink;
-
- readonly Dictionary<IUnit, bool> codeUnderAnalysis = new Dictionary<IUnit, bool>();
-
- public WholeProgramMetadataSemantics(WholeProgram parent, Sink sink, IDictionary<IUnit, PdbReader> pdbReaders, TraverserFactory factory)
- : base(sink, pdbReaders, factory) {
- this.parent = parent;
- this.sink = sink;
- }
-
- public override void TranslateAssemblies(IEnumerable<IUnit> assemblies) {
- #region traverse all of the units gathering type information
- var typeRecorder = new RecordSubtypes(this.parent.subTypes);
- foreach (var a in assemblies) {
- this.codeUnderAnalysis.Add(a, true);
- typeRecorder.Traverse((IAssembly)a);
- }
- #endregion
- #region Possibly gather exception information
- if (sink.Options.modelExceptions == 1) {
- this.sink.MethodThrowsExceptions = ExceptionAnalyzer.ComputeExplicitlyThrownExceptions(assemblies);
- }
-
- #endregion
-
- base.TranslateAssemblies(assemblies);
- }
-
- class RecordSubtypes : MetadataTraverser {
-
- Dictionary<ITypeReference, List<ITypeReference>> subTypes;
-
- public RecordSubtypes(Dictionary<ITypeReference, List<ITypeReference>> subTypes) {
- this.subTypes = subTypes;
- }
-
- public override void TraverseChildren(ITypeDefinition typeDefinition) {
- foreach (var baseClass in typeDefinition.BaseClasses) {
- if (!this.subTypes.ContainsKey(baseClass)) {
- this.subTypes[baseClass] = new List<ITypeReference>();
- }
- this.subTypes[baseClass].Add(typeDefinition);
- }
-
- foreach (var iface in typeDefinition.Interfaces) {
- if (!this.subTypes.ContainsKey(iface)) {
- this.subTypes[iface] = new List<ITypeReference>();
- }
- this.subTypes[iface].Add(typeDefinition);
- }
- base.TraverseChildren(typeDefinition);
- }
- }
-
- }
-
- public override ExpressionTraverser MakeExpressionTraverser(Sink sink, StatementTraverser/*?*/ statementTraverser, bool contractContext, bool expressionIsStatement) {
- return new WholeProgramExpressionSemantics(this, sink, statementTraverser, contractContext, expressionIsStatement);
- }
-
- /// <summary>
- /// implement virtual method calls to methods defined in the CUA (code under analysis, i.e.,
- /// the set of assemblies being translated) by a "switch statement" that dispatches to the
- /// most derived type's method. I.e., make explicit the dynamic dispatch mechanism.
- /// </summary>
- public class WholeProgramExpressionSemantics : CLRSemantics.CLRExpressionSemantics {
-
- readonly WholeProgram parent;
- readonly public Dictionary<ITypeReference, List<ITypeReference>> subTypes;
-
- public WholeProgramExpressionSemantics(WholeProgram parent, Sink sink, StatementTraverser/*?*/ statementTraverser, bool contractContext, bool expressionIsStatement)
- : base(sink, statementTraverser, contractContext, expressionIsStatement) {
- this.parent = parent;
- this.subTypes = parent.subTypes;
- }
-
- public override void TraverseChildren(IMethodCall methodCall) {
- var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod;
-
- var methodName = Microsoft.Cci.MemberHelper.GetMethodSignature(resolvedMethod);
- if (methodName.Equals("System.Object.GetHashCode") || methodName.Equals("System.Object.ToString")) {
- base.TraverseChildren(methodCall);
- return;
- }
-
- bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
- bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");
- if (isEventAdd || isEventRemove) {
- base.TraverseChildren(methodCall);
- return;
- }
-
- if (!methodCall.IsVirtualCall) {
- base.TraverseChildren(methodCall);
- return;
- }
- var containingType = methodCall.MethodToCall.ContainingType;
- List<ITypeReference> subTypesOfContainingType;
- if (!this.subTypes.TryGetValue(containingType, out subTypesOfContainingType)) {
- base.TraverseChildren(methodCall);
- return;
- }
- Contract.Assert(0 < subTypesOfContainingType.Count);
- Contract.Assert(!methodCall.IsStaticCall);
- Contract.Assert(!resolvedMethod.IsConstructor);
- var overrides = FindOverrides(containingType, resolvedMethod);
- bool same = true;
- foreach (var o in overrides) {
- IMethodDefinition resolvedOverride = Sink.Unspecialize(o.Item2).ResolvedMethod;
- if (resolvedOverride != resolvedMethod)
- same = false;
- }
- if (!(containingType.ResolvedType.IsInterface) && (0 == overrides.Count || same)) {
- base.TraverseChildren(methodCall);
- return;
- }
-
- Contract.Assume(1 <= overrides.Count);
-
- var getType = new Microsoft.Cci.MethodReference(
- this.sink.host,
- this.sink.host.PlatformType.SystemObject,
- CallingConvention.HasThis,
- this.sink.host.PlatformType.SystemType,
- this.sink.host.NameTable.GetNameFor("GetType"), 0);
- var op_Type_Equality = new Microsoft.Cci.MethodReference(
- this.sink.host,
- this.sink.host.PlatformType.SystemType,
- CallingConvention.Default,
- this.sink.host.PlatformType.SystemBoolean,
- this.sink.host.NameTable.GetNameFor("op_Equality"),
- 0,
- this.sink.host.PlatformType.SystemType,
- this.sink.host.PlatformType.SystemType);
-
- // Depending on whether the method is a void method or not
- // Turn into expression:
- // (o.GetType() == typeof(T1)) ? ((T1)o).M(...) : ( (o.GetType() == typeof(T2)) ? ((T2)o).M(...) : ...
- // Or turn into statements:
- // if (o.GetType() == typeof(T1)) ((T1)o).M(...) else if ...
- var turnIntoStatements = resolvedMethod.Type.TypeCode == PrimitiveTypeCode.Void;
- IStatement elseStatement = null;
-
- IExpression elseValue = new MethodCall() {
- Arguments = new List<IExpression>(methodCall.Arguments),
- IsStaticCall = false,
- IsVirtualCall = false,
- MethodToCall = methodCall.MethodToCall,
- ThisArgument = methodCall.ThisArgument,
- Type = methodCall.Type,
- };
- if (turnIntoStatements)
- elseStatement = new ExpressionStatement() { Expression = elseValue, };
-
- Conditional ifConditional = null;
- ConditionalStatement ifStatement = null;
-
- foreach (var typeMethodPair in overrides) {
- var t = typeMethodPair.Item1;
- var m = typeMethodPair.Item2;
-
- if (m.IsGeneric) {
- var baseMethod = m.ResolvedMethod;
- m = new GenericMethodInstanceReference() {
- CallingConvention = baseMethod.CallingConvention,
- ContainingType = baseMethod.ContainingTypeDefinition,
- GenericArguments = new List<ITypeReference>(IteratorHelper.GetConversionEnumerable<IGenericMethodParameter, ITypeReference>(baseMethod.GenericParameters)),
- GenericMethod = baseMethod,
- InternFactory = this.sink.host.InternFactory,
- Name = baseMethod.Name,
- Parameters = baseMethod.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(baseMethod.Parameters),
- Type = baseMethod.Type,
- };
- }
-
- var cond = new MethodCall() {
- Arguments = new List<IExpression>(){
- new MethodCall() {
- Arguments = new List<IExpression>(),
- IsStaticCall = false,
- IsVirtualCall = false,
- MethodToCall = getType,
- ThisArgument = methodCall.ThisArgument,
- },
- new TypeOf() {
- TypeToGet = t,
- },
- },
- IsStaticCall = true,
- IsVirtualCall = false,
- MethodToCall = op_Type_Equality,
- Type = this.sink.host.PlatformType.SystemBoolean,
- };
- var thenValue = new MethodCall() {
- Arguments = new List<IExpression>(methodCall.Arguments),
- IsStaticCall = false,
- IsVirtualCall = false,
- MethodToCall = m,
- ThisArgument = methodCall.ThisArgument,
- Type = t,
- };
- if (turnIntoStatements) {
- ifStatement = new ConditionalStatement() {
- Condition = cond,
- FalseBranch = elseStatement,
- TrueBranch = new ExpressionStatement() { Expression = thenValue, },
- };
- elseStatement = ifStatement;
- } else {
- ifConditional = new Conditional() {
- Condition = cond,
- ResultIfFalse = elseValue,
- ResultIfTrue = thenValue,
- };
- elseValue = ifConditional;
- }
- }
- if (turnIntoStatements) {
- Contract.Assume(ifStatement != null);
- this.StmtTraverser.Traverse(ifStatement);
- } else {
- Contract.Assume(ifConditional != null);
- base.Traverse(ifConditional);
- }
-
- return;
- }
-
- /// <summary>
- /// Modifies <paramref name="overrides"/> as side-effect.
- /// </summary>
- private List<Tuple<ITypeReference, IMethodReference>> FindOverrides(ITypeReference type, IMethodDefinition resolvedMethod) {
- Contract.Requires(type != null);
- Contract.Requires(resolvedMethod != null);
- var overrides = new List<Tuple<ITypeReference, IMethodReference>>();
- if (type.ResolvedType.IsInterface) {
- foreach (var subType in this.subTypes[type]) {
- var def = subType.ResolvedType;
- var foundSome = false; // prefer explicit, since if both are there, only the implicit get called through the iface pointer.
- foreach (var implementingMethod in GetExplicitlyImplementedMethods(def, resolvedMethod)) {
- overrides.Add(Tuple.Create<ITypeReference, IMethodReference>(subType, implementingMethod));
- foundSome = true;
- }
- if (!foundSome) { // look for implicit
- var mems = def.GetMatchingMembersNamed(resolvedMethod.Name, true,
- tdm => {
- var m = tdm as IMethodDefinition;
- if (m == null) return false;
- return TypeHelper.ParameterListsAreEquivalentAssumingGenericMethodParametersAreEquivalentIfTheirIndicesMatch(
- m.Parameters, resolvedMethod.Parameters);
- });
- foreach (var mem in mems) {
- var methodDef = mem as IMethodDefinition;
- if (methodDef == null) continue;
- overrides.Add(Tuple.Create<ITypeReference, IMethodReference>(subType, methodDef));
-
- }
- }
- }
- } else {
- foreach (var subType in this.subTypes[type]) {
- var overridingMethod = MemberHelper.GetImplicitlyOverridingDerivedClassMethod(resolvedMethod, subType.ResolvedType);
- if (overridingMethod != Dummy.Method) {
- resolvedMethod = overridingMethod;
- }
- overrides.Add(Tuple.Create<ITypeReference, IMethodReference>(subType, resolvedMethod));
- if (this.subTypes.ContainsKey(subType)) {
- overrides.AddRange(FindOverrides(subType, resolvedMethod));
- }
- }
- }
- return overrides;
- }
-
- /// <summary>
- /// Returns zero or more explicit implementations of an interface method that are defined in the given type definition.
- /// </summary>
- /// <remarks>
- /// IMethodReferences are returned (as opposed to IMethodDefinitions) because the references are directly available:
- /// no resolving is needed to find them.
- /// </remarks>
- public static IEnumerable<IMethodReference> GetExplicitlyImplementedMethods(ITypeDefinition typeDefinition, IMethodDefinition ifaceMethod) {
- Contract.Requires(ifaceMethod != null);
- Contract.Ensures(Contract.Result<IEnumerable<IMethodReference>>() != null);
- Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<IMethodReference>>(), x => x != null));
-
- foreach (IMethodImplementation methodImplementation in typeDefinition.ExplicitImplementationOverrides) {
- if (ifaceMethod.InternedKey == methodImplementation.ImplementedMethod.InternedKey)
- yield return methodImplementation.ImplementingMethod;
- }
- var mems = TypeHelper.GetMethod(typeDefinition, ifaceMethod.Name, ifaceMethod.Parameters.Select(p => p.Type).ToArray());
- }
-
-
- }
-
- }
-}
diff --git a/BCT/BytecodeTranslator/app.config b/BCT/BytecodeTranslator/app.config
deleted file mode 100644
index cb2586be..00000000
--- a/BCT/BytecodeTranslator/app.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<configuration>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
diff --git a/BCT/GetMeHere/AssertionInjector/AssertionInjector.csproj b/BCT/GetMeHere/AssertionInjector/AssertionInjector.csproj
deleted file mode 100644
index 37d95a5e..00000000
--- a/BCT/GetMeHere/AssertionInjector/AssertionInjector.csproj
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{F55B9215-F618-4DCD-AD4C-2DB72CAE5A99}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>AssertionInjector</RootNamespace>
- <AssemblyName>AssertionInjector</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <TargetFrameworkProfile>Client</TargetFrameworkProfile>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
- <PlatformTarget>x86</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <PlatformTarget>x86</PlatformTarget>
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="AIFramework">
- <HintPath>..\..\..\Binaries\AIFramework.dll</HintPath>
- </Reference>
- <Reference Include="Core">
- <HintPath>..\..\..\Binaries\Core.dll</HintPath>
- </Reference>
- <Reference Include="ParserHelper, Version=2.2.30705.1126, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\Binaries\ParserHelper.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\..\..\CCICodeBox\Converters\ILGenerator\ILGenerator.csproj">
- <Project>{08156C78-403A-4112-AD81-8646AC51CD2F}</Project>
- <Name>ILGenerator</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\CoreObjectModel\MetadataHelper\MetadataHelper.csproj">
- <Project>{4A34A3C5-6176-49D7-A4C5-B2B671247F8F}</Project>
- <Name>MetadataHelper</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\CoreObjectModel\MetadataModel\MetadataModel.csproj">
- <Project>{33CAB640-0D03-43DF-81BD-22CDC6C0A597}</Project>
- <Name>MetadataModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\CoreObjectModel\MutableMetadataModel\MutableMetadataModel.csproj">
- <Project>{319E151C-8F33-49E7-81C9-30F02F9BA90A}</Project>
- <Name>MutableMetadataModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\CoreObjectModel\SourceModel\SourceModel.csproj">
- <Project>{4B0054FD-124A-4037-9965-BDB55E6BF389}</Project>
- <Name>SourceModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\PDBReaderAndWriter\PdbReader\PdbReader.csproj">
- <Project>{A6A31B03-7C3D-4DE6-AA73-BE88116BC40A}</Project>
- <Name>PdbReader</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\PDBReaderAndWriter\PdbWriter\PdbWriter.csproj">
- <Project>{6D83F687-ABB5-40B3-915E-CA53DA0EB7F3}</Project>
- <Name>PdbWriter</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\PEReaderAndWriter\PEReader\PeReader.csproj">
- <Project>{34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}</Project>
- <Name>PeReader</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodeBox\PEReaderAndWriter\PEWriter\PeWriter.csproj">
- <Project>{304A8B0B-851B-4AA6-A17D-5F87F39C5E5C}</Project>
- <Name>PeWriter</Name>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/BCT/GetMeHere/AssertionInjector/Program.cs b/BCT/GetMeHere/AssertionInjector/Program.cs
deleted file mode 100644
index 4cdcf137..00000000
--- a/BCT/GetMeHere/AssertionInjector/Program.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (c) Microsoft. All rights reserved.
-// This code is licensed under the Microsoft Public License.
-// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.Serialization; // needed for defining exception .ctors
-using Microsoft.Cci;
-using Microsoft.Cci.MutableCodeModel;
-using Bpl = Microsoft.Boogie;
-using System.Diagnostics;
-
-namespace AssertionInjector {
-
- class Program {
- const int errorValue = -1;
- static int Main(string[] args) {
- if (args == null || args.Length < 4) {
- Console.WriteLine("Usage: AssertionInjector <assembly> <filename+extension> <line number> <column number> [<outputPath>]");
- return errorValue;
- }
-
- int lineNumber;
- if (!Int32.TryParse(args[2], out lineNumber)) {
- Console.WriteLine("Error: couldn't parse '{0}' as an integer to use as a line number", args[2]);
- return errorValue;
- }
- int columnNumber;
- if (!Int32.TryParse(args[3], out columnNumber)) {
- Console.WriteLine("Error: couldn't parse '{0}' as an integer to use as a column number", args[3]);
- return errorValue;
- }
-
- return InjectAssertionInBpl(args[0], args[1], lineNumber, columnNumber);
- }
-
- static int InjectAssertionInBpl(string bplFileName, string fileName, int lineNumber, int columnNumber) {
- Bpl.CommandLineOptions.Install(new Bpl.CommandLineOptions());
- Bpl.CommandLineOptions.Clo.DoModSetAnalysis = true;
- var returnValue = errorValue;
- Bpl.Program program;
- Bpl.Parser.Parse(bplFileName, new List<string>(), out program);
- int errorCount = program.Resolve();
- if (errorCount != 0) {
- Console.WriteLine("{0} name resolution errors detected in {1}", errorCount, bplFileName);
- return returnValue;
- }
- errorCount = program.Typecheck();
- if (errorCount != 0) {
- Console.WriteLine("{0} type checking errors detected in {1}", errorCount, bplFileName);
- return returnValue;
- }
-
- GetMeHereBplInjector bplInjector = new GetMeHereBplInjector(fileName, lineNumber, columnNumber);
- bplInjector.Visit(program);
- using (Bpl.TokenTextWriter writer = new Bpl.TokenTextWriter(bplFileName)) {
- Bpl.CommandLineOptions.Clo.PrintInstrumented = true;
- program.Emit(writer);
- }
- return returnValue;
- }
- }
-
- public class GetMeHereBplInjector : Bpl.StandardVisitor {
- string fileName;
- int lineNumber;
- int columnNumber;
-
- public GetMeHereBplInjector(string fileName, int lineNumber, int columnNumber) {
- this.fileName = fileName;
- this.lineNumber = lineNumber;
- this.columnNumber = columnNumber;
- }
-
- public override Bpl.CmdSeq VisitCmdSeq(Bpl.CmdSeq cmdSeq) {
- Bpl.CmdSeq newCmdSeq = new Bpl.CmdSeq();
- for (int i = 0; i < cmdSeq.Length; i++) {
- Bpl.Cmd cmd = cmdSeq[i];
- if (IsRelevant(cmd))
- newCmdSeq.Add(new Bpl.AssertCmd(cmd.tok, Bpl.Expr.False));
- newCmdSeq.Add(cmd);
- }
- return newCmdSeq;
- }
-
- private bool IsRelevant(Bpl.Cmd cmd) {
- Bpl.AssertCmd assertCmd = cmd as Bpl.AssertCmd;
- if (assertCmd == null)
- return false;
- string sourceFile = Bpl.QKeyValue.FindStringAttribute(assertCmd.Attributes, "sourceFile");
- if (sourceFile == null)
- return false;
- string[] ds = sourceFile.Split('\\');
- if (sourceFile != fileName && ds[ds.Length - 1] != fileName)
- return false;
- int sourceLine = Bpl.QKeyValue.FindIntAttribute(assertCmd.Attributes, "sourceLine", -1);
- Debug.Assert(sourceLine != -1);
- if (sourceLine != lineNumber)
- return false;
- return true;
- }
- }
-
-}
diff --git a/BCT/GetMeHere/AssertionInjector/Properties/AssemblyInfo.cs b/BCT/GetMeHere/AssertionInjector/Properties/AssemblyInfo.cs
deleted file mode 100644
index e58cc425..00000000
--- a/BCT/GetMeHere/AssertionInjector/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("AssertionInjector")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("AssertionInjector")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f39cb052-3add-469f-9b89-6fdd7f5b1ec4")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/Local.testsettings b/BCT/Local.testsettings
deleted file mode 100644
index f63e9b16..00000000
--- a/BCT/Local.testsettings
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<TestSettings name="Local" id="f898dc7f-7e79-4656-a1cd-5ca50fff2b5d" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
- <Description>These are default test settings for a local test run.</Description>
- <Execution>
- <TestTypeSpecific>
- <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b">
- <AssemblyResolution>
- <TestDirectory useLoadContext="true" />
- </AssemblyResolution>
- </UnitTestRunConfig>
- <WebTestRunConfiguration testTypeId="4e7599fa-5ecb-43e9-a887-cd63cf72d207">
- <Browser name="Internet Explorer 7.0">
- <Headers>
- <Header name="User-Agent" value="Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" />
- <Header name="Accept" value="*/*" />
- <Header name="Accept-Language" value="{{$IEAcceptLanguage}}" />
- <Header name="Accept-Encoding" value="GZIP" />
- </Headers>
- </Browser>
- </WebTestRunConfiguration>
- </TestTypeSpecific>
- <AgentRule name="LocalMachineDefaultRole">
- <DataCollectors>
- <DataCollector uri="datacollector://microsoft/CodeCoverage/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.CodeCoverage.CoveragePlugIn, Microsoft.VisualStudio.QualityTools.Plugins.CodeCoverage, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Code Coverage">
- </DataCollector>
- <DataCollector uri="datacollector://microsoft/TestImpact/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.TestImpactDataCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Test Impact">
- </DataCollector>
- </DataCollectors>
- </AgentRule>
- </Execution>
-</TestSettings> \ No newline at end of file
diff --git a/BCT/PhoneControlsExtractor/MS Phone App Analysis doc.docx b/BCT/PhoneControlsExtractor/MS Phone App Analysis doc.docx
deleted file mode 100644
index c202b9b9..00000000
--- a/BCT/PhoneControlsExtractor/MS Phone App Analysis doc.docx
+++ /dev/null
Binary files differ
diff --git a/BCT/PhoneControlsExtractor/NavGraphBuilder.README.txt b/BCT/PhoneControlsExtractor/NavGraphBuilder.README.txt
deleted file mode 100644
index 1217e0b2..00000000
--- a/BCT/PhoneControlsExtractor/NavGraphBuilder.README.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Navigation graph builder
-------------------------
-
-A few points must be taken into account
-- you need the XAML files for the application, and they must reside (flat) in the same directory as the app file. If flatting results in name clashes, rename one of those files clashing
-- if you don't have the XAML files, they usually reside in some form in the resources of the .dll. I am not automatically extracting this yet.
-- the graph building may fail at any step. Usually, it is the bytecode translator that fails to produce a valid Boogie file. For this, there is a hidden ooption --build/-b
- this option receives a string, where each character encodes an action to take. If the character is present (or no build option is passed), the action takes place.
- c: extract control information
- i: inject and translate (if BCT gives you problems, correct .bpl by hand and run *without* this step)
- t: test the resulting boogie file, useful to see whether to skip 'i' or not
- b: create the boogie queries. You may choose to skip this if you built them already and it takes too long. I need to optimize this.
- q: run the queries
- g: build the graph. It won't work if you don't include 'q' as the intermediate step is not saved yet
diff --git a/BCT/PhoneControlsExtractor/PhoneBoogieCodeGenerator.py b/BCT/PhoneControlsExtractor/PhoneBoogieCodeGenerator.py
deleted file mode 100644
index 053b9322..00000000
--- a/BCT/PhoneControlsExtractor/PhoneBoogieCodeGenerator.py
+++ /dev/null
@@ -1,288 +0,0 @@
-import sys
-import getopt
-import os
-from xml.dom import minidom
-from itertools import product
-import xml.dom
-
-CONTROL_NAMES= ["Button", "CheckBox", "RadioButton", "ApplicationBarIconButton", "Pivot"]
-CONTAINER_CONTROL_NAMES= ["Canvas", "Grid", "StackPanel"]
-
-# TODO externalize strings, share with C# code
-CONTINUEONPAGE_VAR= "__BOOGIE_ContinueOnPage__"
-
-staticControlsMap= {}
-mainPageXAML= None
-mainAppClassname= None
-appVarName = "__BOOGIE_APP_VAR"
-currentNavigationVariable= None
-originalPageVars= []
-boogiePageVars= []
-boogiePageClasses= []
-dummyPageVar= "dummyBoogieStringPageName"
-anonymousControlCount= 0;
-ANONYMOUS_CONTROL_PREFIX= "__BOOGIE_ANONYMOUS_CONTROL_"
-unrolls= 0
-
-def showUsage():
- print "PhoneBoogieCodeGenerator -- create boilerplate code for Boogie verification of Phone apps"
- print "Usage:"
- print "\tPhoneBoogieCodeGenerator --staticUnroll <n> --controls <app_control_info_file> --output <code_output_file>\n"
- print "Options:"
- print "\t--staticUnroll <n>: Do not generate loops, unroll up to n times. If not set generates loops (default). Short form: -u"
- print "\t--controls <app_control_info_file>: Phone app control info. See PhoneControlsExtractor. Short form: -c"
- print "\t--output <code_output_file>: file to write with boilerplate code. Short form: -o\n"
-
-def isAnonymousControl(control):
- name= control["bplName"]
- return name.find(ANONYMOUS_CONTROL_PREFIX) != -1
-
-def loadControlInfo(infoMap, controlClass, controlName, enabled, visible, clickHandler, checkedHandler, uncheckedHandler, selectionChangedHandler, bplName):
- global anonymousControlCount
- global ANONYMOUS_CONTROL_PREFIX
-
- newControl={}
- newControl["class"]= controlClass
- newControl["enabled"]= enabled
- newControl["visible"]= visible
- newControl["clickHandler"]= clickHandler
- newControl["checkedHandler"]= checkedHandler
- newControl["uncheckedHandler"]= uncheckedHandler
- newControl["selectionChangedHandler"]= selectionChangedHandler
- if (bplName == ""):
- # anonymous control, need a dummy boogie var, but we cannot know how it got initialized
- bplName= ANONYMOUS_CONTROL_PREFIX + str(anonymousControlCount)
- anonymousControlCount= anonymousControlCount+1
- newControl["bplName"]=bplName
- infoMap[controlName]= newControl
-
-def outputPageVariables(file):
- global originalPageVars
- global boogiePageVars
- global boogiePageClasses
-
- file.write("var " + appVarName + ": Ref;\n")
- for entry in staticControlsMap.keys():
- pageVarName= "__BOOGIE_PAGE_VAR_" + entry
- originalPageVars.append(entry)
- pageInfo={}
- pageInfo["name"]=pageVarName
- pageInfo["boogieStringName"]= staticControlsMap[entry]["boogieStringName"]
- boogiePageVars.append(pageInfo)
- boogiePageClasses.append(staticControlsMap[entry]["class"])
- pageVar= "var " + pageVarName + ": Ref;\n"
- file.write(pageVar)
-
-def outputMainProcedures(file, batFile):
- for i,j in product(range(0, len(boogiePageVars)),repeat=2):
- if i == j:
- continue
- if (boogiePageVars[i]["boogieStringName"] == dummyPageVar):
- continue
- if (boogiePageVars[j]["boogieStringName"] == dummyPageVar):
- continue
-
- file.write("procedure {:inline 1} __BOOGIE_VERIFICATION_PROCEDURE_" + str(i) + "_" + str(j) + "();\n")
- file.write("implementation __BOOGIE_VERIFICATION_PROCEDURE_" + str(i) + "_" + str(j) + "() {\n")
- file.write("\tvar $doWork: bool;\n")
- file.write("\tvar $activeControl: int;\n")
- file.write("\tvar $isEnabledRef: Ref;\n")
- file.write("\tvar $isEnabled: bool;\n")
- file.write("\tvar $control: Ref;\n\n")
-
- file.write("\tcall " + mainAppClassname + ".#ctor(" + appVarName + ");\n")
- for k in range(0,len(boogiePageVars)):
- file.write("\tcall " + boogiePageClasses[k] + ".#ctor(" + boogiePageVars[k]["name"] + ");\n")
-
- file.write("\t//TODO still need to call Loaded handler on main page.\n")
- if (unrolls == 0):
- file.write("\thavoc $doWork;\n")
- file.write("\twhile ($doWork) {\n")
- file.write("\t\tcall DriveControls();\n")
- file.write("\t\thavoc $doWork;\n")
- file.write("\t}\n")
- else:
- for unr in range(unrolls):
- file.write("\t\tcall DriveControls();\n")
-
- file.write("\tassume " + currentNavigationVariable + " == " + boogiePageVars[i]["boogieStringName"] + ";\n")
- file.write("\tcall DriveControls();\n")
- file.write("\tassume " + currentNavigationVariable + " == " + boogiePageVars[j]["boogieStringName"] + ";\n")
- file.write("\tassert false;\n");
- file.write("}\n")
-
- batFile.write("type BOOGIE_PARTIAL.bpl > BOOGIE_PLACEHOLDER.bpl\n")
- batFile.write("type BOOGIE_BOILERPLATE.bpl >> BOOGIE_PLACEHOLDER.bpl\n")
- batFile.write("%POIROT_ROOT%\Corral\BctCleanup.exe BOOGIE_PLACEHOLDER.bpl BOOGIE_PLACEHOLDER_Clean.bpl /main:__BOOGIE_VERIFICATION_PROCEDURE_" + str(i) + "_" + str(j) +"\n");
- batFile.write("del corral_out_trace.txt\n")
- batFile.write("%POIROT_ROOT%\corral\corral.exe /k:1 /recursionBound:20 /main:__BOOGIE_VERIFICATION_PROCEDURE_" + str(i) +"_" + str(j) + " BOOGIE_PLACEHOLDER_Clean_" + str(i) + "_" + str(j) + ".bpl\n")
- batFile.write("if exist corral_out_trace.txt move corral_out_trace.txt corral_out_trace_" + str(i) + "_" + str(j) + ".txt\n")
-
-def outputPageControlDriver(file, originalPageName, boogiePageName):
- file.write("procedure {:inline 1} drive" + boogiePageName + "Controls();\n")
- file.write("implementation drive" + boogiePageName + "Controls() {\n")
- file.write("\tvar $activeControl: int;\n")
- file.write("\tvar $control: Ref;\n")
- file.write("\tvar $isEnabledRef: Ref;\n")
- file.write("\tvar $isEnabled: bool;\n")
- file.write("\tvar $handlerToActivate: int;\n")
-
- file.write("\t" + CONTINUEONPAGE_VAR +":=true;\n")
- file.write("\thavoc $activeControl;\n")
-
- file.write("\twhile (" + CONTINUEONPAGE_VAR + ") {\n")
- activeControl=0
- ifInitialized= False
- for entry in staticControlsMap[originalPageName]["controls"].keys():
- controlInfo= staticControlsMap[originalPageName]["controls"][entry]
- if controlInfo["bplName"] == "":
- continue;
- if not ifInitialized:
- file.write("\t\tif ($activeControl == " + str(activeControl) + ") {\n")
- ifInitialized= True
- else:
- file.write("\t\telse if ($activeControl == " + str(activeControl) + ") {\n")
-
- file.write("\t\t\t$control := " + controlInfo["bplName"] + "[" + boogiePageName + "];\n")
- file.write("\t\t\tcall $isEnabledRef := System.Windows.Controls.Control.get_IsEnabled($control);\n")
- file.write("\t\t\t$isEnabled := Box2Bool(Ref2Box($isEnabledRef));\n")
- file.write("\t\t\tif ($isEnabled) {\n")
- file.write("\t\t\t\thavoc $handlerToActivate;\n")
- if not controlInfo["clickHandler"] == "":
- file.write("\t\t\t\tif ($handlerToActivate == 0) {\n")
- file.write("\t\t\t\t\tcall " + staticControlsMap[originalPageName]["class"] + "." + controlInfo["clickHandler"] + "$System.Object$System.Windows.RoutedEventArgs(" + controlInfo["bplName"] + "[" + boogiePageName + "],null,null);\n")
- file.write("\t\t\t\t}\n")
- if not controlInfo["checkedHandler"] == "":
- file.write("\t\t\t\tif ($handlerToActivate == 1) {\n")
- file.write("\t\t\t\t\tcall " + staticControlsMap[originalPageName]["class"] + "." + controlInfo["checkedHandler"] + "$System.Object$System.Windows.RoutedEventArgs(" + controlInfo["bplName"] + "[" + boogiePageName + "],null,null);\n")
- file.write("\t\t\t\t}\n")
- if not controlInfo["uncheckedHandler"] == "":
- file.write("\t\t\t\tif ($handlerToActivate == 2) {\n")
- file.write("\t\t\t\t\tcall " + staticControlsMap[originalPageName]["class"] + "." + controlInfo["uncheckedHandler"] + "$System.Object$System.Windows.RoutedEventArgs(" + controlInfo["bplName"] + "[" + boogiePageName + "],null,null);\n")
- file.write("\t\t\t\t}\n")
- if not controlInfo["selectionChangedHandler"] == "":
- file.write("\t\t\t\tif ($handlerToActivate == 3) {\n")
- file.write("\t\t\t\t\tcall " + staticControlsMap[originalPageName]["class"] + "." + controlInfo["selectionChangedHandler"] + "$System.Object$System.Windows.RoutedEventArgs(" + controlInfo["bplName"] + "[" + boogiePageName + "],null,null);\n")
- file.write("\t\t\t\t}\n")
-
- file.write("\t\t\t}\n")
- file.write("\t\t}\n")
- activeControl= activeControl+1
- file.write("\t}\n")
- file.write("}\n")
-
-
-def outputControlDrivers(file, batFile):
- for i in range(0,len(boogiePageVars)):
- outputPageControlDriver(file, originalPageVars[i],boogiePageVars[i]["name"])
-
- file.write("procedure {:inline 1} DriveControls();\n")
- file.write("implementation DriveControls() {\n")
- for i in range(0,len(boogiePageVars)):
- file.write("\tvar isCurrent" + boogiePageVars[i]["name"] + ": bool;\n")
- file.write("\n")
-
- for i in range(0,len(boogiePageVars)):
- if boogiePageVars[i]["boogieStringName"] == dummyPageVar:
- file.write("\tisCurrent" + boogiePageVars[i]["name"] + " := false;\n")
- else:
- file.write("\tcall isCurrent" + boogiePageVars[i]["name"] + " := System.String.op_Equality$System.String$System.String(" + currentNavigationVariable + "," + boogiePageVars[i]["boogieStringName"] + ");\n")
-
- firstTime= True
- for i in range(0,len(boogiePageVars)):
- if firstTime:
- file.write("\tif")
- firstTime= False
- else:
- file.write("\telse if")
-
- file.write(" (isCurrent" + boogiePageVars[i]["name"] + ") {\n")
- file.write("\t\t call drive" + boogiePageVars[i]["name"] + "Controls();\n\t}\n")
- file.write("}\n")
-
-def outputURIHavocProcedure(file):
- file.write("procedure {:inline 1} __BOOGIE_Havoc_CurrentURI__();\n")
- file.write("implementation __BOOGIE_Havoc_CurrentURI__() {\n")
- # file.write("\thavoc " + currentNavigationVariable + ";\n")
- file.write("// TODO write assume statements to filter havoc'd variable to either of all pages\n")
- # file.write("\tassume )
- file.write("}\n")
-
-#build a batch file for test running at the same time
-def outputBoilerplate(outputFile, cmdFile):
- file= open(outputFile,"w")
- batFile= open(cmdFile, "w")
- batFile.write("del corral_out_trace.txt")
- outputPageVariables(file)
- outputURIHavocProcedure(file)
- outputControlDrivers(file, batFile)
- outputMainProcedures(file, batFile)
- file.close()
- batFile.close()
-
-def buildControlInfo(controlInfoFileName):
- global mainPageXAML
- global mainAppClassname
- global currentNavigationVariable
- global staticControlsMap
-
- file = open(controlInfoFileName, "r")
- # Info file format is first line containing only the main page, another line with boogie's current navigation variable and then one line per
- # <pageClassName>,<page.xaml file>,<xaml boogie string representation>,<controlClassName>,<controlName (as in field name)>,<IsEnabledValue>,<VisibilityValue>,<ClickValue>,<CheckedValue>,<UncheckedValue>,<SelectionChangedValue>,<BoogieName>
- mainPageXAML= file.readline().strip()
- currentNavigationVariable= file.readline().strip()
- mainAppClassname= file.readline().strip()
-
- infoLine= file.readline().strip()
- while not infoLine == "":
- pageClass, pageName, pageBoogieStringName, controlClass, controlName, enabled, visible, clickHandler, checkedHandler, uncheckedHandler, selectionChangedHandler, bplName= infoLine.split(",")
- pageInfo={}
- pageInfo["class"]=pageClass
- try:
- pageInfo= staticControlsMap[pageName]
- except KeyError:
- staticControlsMap[pageName]=pageInfo
-
- pageInfo["boogieStringName"]= pageBoogieStringName
- pageControlInfo={}
- try:
- pageControlInfo= pageInfo["controls"]
- except KeyError:
- pageInfo["controls"]=pageControlInfo
- loadControlInfo(pageControlInfo, controlClass, controlName, enabled, visible, clickHandler, checkedHandler, uncheckedHandler, selectionChangedHandler, bplName)
- pageInfo["controls"]= pageControlInfo
- staticControlsMap[pageName]=pageInfo
-
- infoLine=file.readline().strip()
- file.close()
-
-def main():
- global unrolls
- controlFile= ""
- outputFile= ""
-
- try:
- opts, args= getopt.getopt(sys.argv[1:], "c:o:u:", ["controls=","output=","staticUnroll="])
- except getopt.error, msg:
- print msg
- showUsage()
- sys.exit(2)
-
- if not len(opts) >= 2:
- print "Missing options"
- showUsage()
- sys.exit(2)
-
- for o, a in opts:
- if o in ["-c","--controls"]:
- controlFile= a
- if o in ["-o", "--output"]:
- outputFile= a
- if o in ["-u", "--staticUnroll"]:
- unrolls= int(a)
-
- buildControlInfo(controlFile)
- outputBoilerplate(outputFile, outputFile + ".bat")
-
-if __name__ == "__main__":
- main() \ No newline at end of file
diff --git a/BCT/PhoneControlsExtractor/PhoneControlsExtractor.py b/BCT/PhoneControlsExtractor/PhoneControlsExtractor.py
deleted file mode 100644
index 475c221f..00000000
--- a/BCT/PhoneControlsExtractor/PhoneControlsExtractor.py
+++ /dev/null
@@ -1,248 +0,0 @@
-import sys
-import getopt
-import os
-from xml.dom import minidom
-import xml.dom
-
-CONTROL_NAMES= ["Button", "CheckBox", "RadioButton", "ApplicationBarIconButton", "ApplicationBarMenuItem", "Pivot", "ListBox"]
-
-# TODO maybe a control is enabled but its parent is not, must take this into account
-# TODO a possible solution is to tie the enabled value to that of the parent in the app until it is either overriden
-# TODO (by directly manipulating the control's enabled value) or the parent becomes enabled
-
-CONTAINER_CONTROL_NAMES= ["Canvas", "Grid", "StackPanel", "ApplicationBar"]
-COMMA_REPLACEMENT="###"
-
-staticControlsMap= {}
-mainPageXAML= None
-
-def showUsage():
- print "PhoneControlsExtractor -- extract control information from phone application pages"
- print "Usage:"
- print "\tPhoneControlsExtractor --pages <application_directory> --output <info_output_file>\n"
- print "Options:"
- print "\t--pages <application_directory>: point to location of .xaml files detailing pages. Short form: -p"
- print "\t--output <info_output_file>: file to write with control info. Short form: -o\n"
-
-def isPageFile(file):
- # not the best way, find out the actual exceptions
- try:
- minidom.parse(file)
- file.seek(0)
- return True
- except Exception:
- return False
-
-def removeBlankElements(xmlNode):
- blankNodes= []
- for child in xmlNode.childNodes:
- if child.nodeType == xml.dom.Node.TEXT_NODE and child.data.strip() == "":
- blankNodes.append(child)
- elif child.hasChildNodes():
- removeBlankElements(child)
-
- for node in blankNodes:
- node.parentNode.removeChild(node)
- node.unlink()
-
-def getControlNodes(xmlNode):
- controlNodes= []
- if (xmlNode.nodeType == xml.dom.Node.ELEMENT_NODE and xmlNode.localName in CONTROL_NAMES):
- controlNodes.insert(0,xmlNode)
-
- for child in xmlNode.childNodes:
- controlNodes= controlNodes + getControlNodes(child)
-
- return controlNodes
-
-def addDummyControlToMap(pageXAML, parentPage):
- pageControls=[]
- newControl={}
- try:
- pageControls= staticControlsMap[parentPage]
- except KeyError:
- pass
-
- newControl["Type"]= "DummyType"
- newControl["Name"]= "DummyName"
- newControl["IsEnabled"]= "false"
- newControl["Visibility"]= "Collapsed"
- newControl["Click"] = ""
- newControl["Checked"] = ""
- newControl["Unchecked"] = ""
- newControl["SelectionChanged"]= ""
- newControl["XAML"]= pageXAML
- pageControls.append(newControl)
- staticControlsMap[parentPage]= pageControls
-
-def addControlToMap(pageXAML, parentPage, controlNode):
- pageControls=[]
- newControl={}
- try:
- pageControls= staticControlsMap[parentPage]
- except KeyError:
- pass
-
- newControl["Type"]= controlNode.localName
- newControl["Name"]= controlNode.getAttribute("Name").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- if (controlNode.hasAttribute("IsEnabled")):
- newControl["IsEnabled"]= controlNode.getAttribute("IsEnabled").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- else:
- newControl["IsEnabled"]= "true"
-
- if (controlNode.hasAttribute("Visibility")):
- newControl["Visibility"]= controlNode.getAttribute("Visibility").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- else:
- newControl["Visibility"]= "Visible"
-
- # TODO it is possible that more events are of interest, we should add as we discover them in existing applications
- newControl["Click"] = controlNode.getAttribute("Click").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- newControl["Checked"] = controlNode.getAttribute("Checked").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- newControl["Unchecked"] = controlNode.getAttribute("Unchecked").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- newControl["SelectionChanged"] = controlNode.getAttribute("SelectionChanged").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- newControl["XAML"]= pageXAML
- pageControls.append(newControl)
- staticControlsMap[parentPage]= pageControls
-
-def isPageXAML(pageXAML):
- pageFile= open(pageXAML, "r")
- if not isPageFile(pageFile):
- return False
- pageFileXML= minidom.parse(pageFile)
- pageFile.close()
- return pageFileXML.childNodes[0].nodeName.find("Page") != -1
-
-def getPageNode(pageXML):
-# should be the top element one, ignore otherwise
- if (pageXML.nodeType == xml.dom.Node.ELEMENT_NODE and pageXML.localName.find("PhoneApplicationPage") != -1):
- return pageXML
- else:
- return None
-
-
-
-
-def extractPhoneControlsFromPage(pageXAML):
- # maybe it is not a page file
- print "extracting from " + pageXAML
- pageFile= open(pageXAML, "r")
- if not isPageFile(pageFile):
- return
- pageFileXML= minidom.parse(pageFile)
- pageFile.close()
- removeBlankElements(pageFileXML)
- pageNode= getPageNode(pageFileXML)
- controls= getControlNodes(pageFileXML)
- ownerPage = getOwnerPage(pageFileXML)
- if (ownerPage != None):
- print pageXAML + " is not none"
- if (len(controls) == 0):
- # it is either a page with no controls, or controls that are dynamically created, or controls we do not track yet
- # in any case, just add a dummy control so as not to lose the page
- if (not isPageXAML(pageXAML)):
- addDummyControlToMap(pageXAML, ownerPage + "__dummy")
- else:
- addDummyControlToMap(pageXAML, ownerPage)
- else:
- for control in controls:
- parent= control
- while not parent == None and ownerPage == None:
- parent= parent.parentNode
- addControlToMap(pageXAML, ownerPage, control)
-
-def getOwnerPage(xmlNode):
- ownerPage= None
- if (xmlNode.nodeType == xml.dom.Node.ELEMENT_NODE):
- ownerPage= xmlNode.getAttribute("x:Class").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
- if ownerPage == "":
- ownerPage= None
- else:
- for child in xmlNode.childNodes:
- ownerPage= getOwnerPage(child)
- if (ownerPage != None):
- break
-
- return ownerPage
-
-
-def outputPhoneControls(outputFileName):
- outputFile= open(outputFileName, "w")
-
- # Output format is first line containing only the main page, then line containing boogie navigation variable, and then one line per
- # <pageClassName>,<page.xaml file>,<boogie string page name>,<controlClassName>,<controlName (as in field name)>,<IsEnabledValue>,<VisibilityValue>,<ClickValue>,<CheckedValue>,<UncheckedValue>,<SelChangedValue>
- outputFile.write(mainPageXAML + "\n")
- outputFile.write("dummyNavigationVariable_unknown\n")
- outputFile.write("dummyMainAppName_unknown\n") # I could possibly deduce it from WMAppManifest.xml, but I'm unsure. Doing it later is safe anyway
- for page in staticControlsMap.keys():
- for control in staticControlsMap[page]:
- # TODO we still cannot handle bindings, and those we identified through commas and equality signs
- isEnabled= control["IsEnabled"]
- if (isEnabled.find(COMMA_REPLACEMENT) != -1):
- isEnabled= ""
- visibility= control["Visibility"]
- if (visibility.find(COMMA_REPLACEMENT) != -1):
- visibility= ""
- click= control["Click"]
- if (click.find(COMMA_REPLACEMENT) != -1):
- click= ""
- checked= control["Checked"]
- if (checked.find(COMMA_REPLACEMENT) != -1):
- checked= ""
- unchecked= control["Unchecked"]
- if (unchecked.find(COMMA_REPLACEMENT) != -1):
- unchecked= ""
- selectionChanged= control["SelectionChanged"]
- if (selectionChanged.find(COMMA_REPLACEMENT) != -1):
- selectionChanged= ""
- pageXAML= control["XAML"]
- # last comma is to account for bpl translation name, that is unknown for now
- # boogie string page name is unknown for now
- outputFile.write(page + "," + os.path.basename(pageXAML) + ",dummyBoogieStringPageName," + control["Type"] + "," + control["Name"] + \
- "," + isEnabled + "," + visibility + "," + click + "," + checked + "," + unchecked + "," + selectionChanged + ",\n")
-
- outputFile.close()
-
-def getMainPageXAMLFromManifest(filename):
- file= open(filename, "r");
- manifest= minidom.parse(file)
- file.close()
- # interesting XPath location /App/Tasks/DefaultTask/@NavigationPage
- return manifest.getElementsByTagName("DefaultTask")[0].getAttribute("NavigationPage").replace(",",COMMA_REPLACEMENT).replace("=",COMMA_REPLACEMENT)
-
-def extractPhoneControls(sourceDir):
- global mainPageXAML
- fileList= [os.path.join(sourceDir, fileName) for fileName in os.listdir(sourceDir) if os.path.splitext(fileName)[1] == ".xaml" or os.path.splitext(fileName)[1] == ".xml"]
- for fileName in fileList:
- if os.path.splitext(fileName)[1].lower() == ".xml" and os.path.splitext(os.path.split(fileName)[1])[0].lower() == "wmappmanifest":
- mainPageXAML= getMainPageXAMLFromManifest(fileName)
- break
-
- for fileName in fileList:
- extractPhoneControlsFromPage(fileName)
-
-def main():
- pagesDir= ""
- outputFile= ""
- try:
- opts, args= getopt.getopt(sys.argv[1:], "p:o:", ["pages=","output="])
- except getopt.error, msg:
- print msg
- showUsage()
- sys.exit(2)
-
- if not len(opts) == 2:
- print "Missing options"
- showUsage()
- sys.exit(2)
-
- for o, a in opts:
- if o in ["-p","--pages"]:
- pagesDir= a
- if o in ["-o", "--output"]:
- outputFile= a
-
- extractPhoneControls(pagesDir)
- outputPhoneControls(outputFile)
-
-if __name__ == "__main__":
- main() \ No newline at end of file
diff --git a/BCT/PhoneControlsExtractor/market_apps_analyses.xlsx b/BCT/PhoneControlsExtractor/market_apps_analyses.xlsx
deleted file mode 100644
index 752eaab1..00000000
--- a/BCT/PhoneControlsExtractor/market_apps_analyses.xlsx
+++ /dev/null
Binary files differ
diff --git a/BCT/PhoneControlsExtractor/navGraphBuilder.py b/BCT/PhoneControlsExtractor/navGraphBuilder.py
deleted file mode 100644
index 8d72c785..00000000
--- a/BCT/PhoneControlsExtractor/navGraphBuilder.py
+++ /dev/null
@@ -1,299 +0,0 @@
-import sys
-import getopt
-import os
-import time
-
-BOOGIE_PATH= "%boogie%"
-BCT_PATH="%boogie_bct%"
-CONTROL_EXTRACTOR_PATH="%phonecontrolextractor%"
-WPLIB_PATH="%wplib%"
-DOT_PATH="%dotpath%"
-
-CONTROL_CREATION_TIME=0
-INJECTION_TIME=0
-TEST_TIME=0
-QUERY_CREATION_TIME=0
-QUERY_RUN_TIME=0
-GRAPH_CREATION_TIME=0
-BOOGIE_QUERY_COUNT=0
-PAGE_COUNT=0
-EDGE_COUNT=0
-
-navigation_graph = {}
-
-def createStatsNode(appFile):
- global CONTROL_CREATION_TIME
- global INJECTION_TIME
- global TEST_TIME
- global QUERY_CREATION_TIME
- global QUERY_RUN_TIME
- global GRAPH_CREATION_TIME
- global BOOGIE_QUERY_COUNT
- global PAGE_COUNT
- global EDGE_COUNT
-
- total= CONTROL_CREATION_TIME + INJECTION_TIME + TEST_TIME + QUERY_CREATION_TIME + QUERY_RUN_TIME + GRAPH_CREATION_TIME
- statsNode= "node [shape=plaintext, label=" + \
- "<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">" + \
- "<TR><TD COLSPAN=\"2\" BGCOLOR=\"lightskyblue\">" + os.path.basename(appFile) + "</TD></TR>" + \
- "<TR><TD>Control extraction time</TD><TD>" + str(CONTROL_CREATION_TIME) + " s.</TD></TR>" + \
- "<TR><TD>Injection and translation time</TD><TD>" + str(INJECTION_TIME) + " s.</TD></TR>" + \
- "<TR><TD>Boogie test time</TD><TD>" + str(TEST_TIME) + " s.</TD></TR>" + \
- "<TR><TD>Query creation time</TD><TD>" + str(QUERY_CREATION_TIME) + " s.</TD></TR>" + \
- "<TR><TD>Boogie query run time (" + str(BOOGIE_QUERY_COUNT) + " queries)</TD><TD>" + str(QUERY_RUN_TIME) + " s.</TD></TR>" + \
- "<TR><TD>Graph creation time</TD><TD>" + str(GRAPH_CREATION_TIME) + " s.</TD></TR>" + \
- "<TR><TD BGCOLOR=\"olivedrab\">Graph sparseness</TD><TD BGCOLOR=\"olivedrab\">" + str(EDGE_COUNT) + " over " + str(PAGE_COUNT*PAGE_COUNT) + " possible</TD></TR>" + \
- "<TR><TD BGCOLOR=\"olivedrab\">Total time</TD><TD BGCOLOR=\"olivedrab\">" + str(total) + " s.</TD></TR>" + \
- "</TABLE>>" + \
- "] statsNode;"
- # statsNode= statsNode.replace(".","&#47;")
- return statsNode
-
-def checkEnv():
- retVal= True
- os.system("echo " + DOT_PATH + " > checkEnv")
- check= open("checkEnv", "r")
- if check.readline().strip() == DOT_PATH:
- print DOT_PATH + " not set"
- retVal= False
-
- os.system("echo " + WPLIB_PATH + " > checkEnv")
- check= open("checkEnv", "r")
- if check.readline().strip() == WPLIB_PATH:
- print WPLIB_PATH + " not set"
- retVal= False
-
- os.system("echo " + BOOGIE_PATH + " > checkEnv")
- check= open("checkEnv", "r")
- if check.readline().strip() == BOOGIE_PATH:
- print BOOGIE_PATH + " not set"
- retVal= False
-
- os.system("echo " + BCT_PATH + " > checkEnv")
- check= open("checkEnv", "r")
- if check.readline().strip() == BCT_PATH:
- print BCT_PATH +" not set"
- retVal= False
-
- os.system("echo " + CONTROL_EXTRACTOR_PATH + " > checkEnv")
- check= open("checkEnv", "r")
- if check.readline().strip() == CONTROL_EXTRACTOR_PATH:
- print CONTROL_EXTRACTOR_PATH + " not set"
- retVal= False
-
- check.close()
- os.remove("checkEnv")
- return retVal
-
-def createAppControlsFile(appFile, outputFile, format):
- error = os.system(CONTROL_EXTRACTOR_PATH + " -p \"" + os.path.dirname(appFile) + "\" -o \"" + os.path.splitext(appFile)[0] + ".controls\" > nul")
- if error != 0 or not os.path.exists(os.path.splitext(appFile)[0] + ".controls"):
- return False
- return True
-
-def bctAppFile(appFile, outputFile, format):
- error = os.system(BCT_PATH + " /heap:splitFields /lib:\"" + WPLIB_PATH + "\" /wpnav /phoneControls:\"" + \
- os.path.splitext(appFile)[0] + ".controls\" \"" + appFile + "\" > NavigationReport")
- if error != 0 or not os.path.exists(os.path.splitext(appFile)[0] + ".bpl"):
- return False
- return True
-
-def testBoogieOutput(appFile, outputFile, format):
- error = os.system(BOOGIE_PATH + " /doModSetAnalysis /noVerify \"" + os.path.splitext(appFile)[0] + ".bpl\" > testBpl")
- testBpl= open("testBpl", "r")
- output= testBpl.read()
- testBpl.close()
- os.remove("testBpl")
- if error != 0 or output.find("Error:") != -1:
- return False
- return True
-
-def cleanupQueriesTempFiles():
- for tempFile in [os.path.abspath(filename) for filename in os.listdir(".") if filename.startswith("sed") and os.path.splitext(filename)[1]==""]:
- os.remove(tempFile)
-
-def createBoogieQueries(appFile, outputFile, format):
- cmd ="\"" + os.path.dirname(appFile) + "\\createQueries.bat\" > nul"
- error = os.system(cmd)
- cleanupQueriesTempFiles()
- if error != 0:
- return False
- return True
-
-def runBoogieQueries(appFile, outputFile, format):
- global navigation_graph
- global BOOGIE_QUERY_COUNT
- global EDGE_COUNT
- global PAGE_COUNT
-
- queryFiles= [os.path.abspath(filename) for filename in os.listdir(".") if filename.find("$$") != -1 and os.path.splitext(filename)[1]==".bpl"]
- BOOGIE_QUERY_COUNT= len(queryFiles)
- for filename in queryFiles:
- start= os.path.splitext(filename.split("$$")[1])[0]
- end= os.path.splitext(filename.split("$$")[3])[0]
- try:
- dests= navigation_graph[start]
- except KeyError:
- PAGE_COUNT=PAGE_COUNT+1
- dests= []
- navigation_graph[start]= []
- error = os.system(BOOGIE_PATH + " /doModSetAnalysis /prover:SMTLib \"" + filename +"\" > testBpl")
- testBpl= open("testBpl", "r")
- output= testBpl.read()
- testBpl.close()
- os.remove("testBpl")
- if error != 0 or output.find("Error:") != -1:
- return False
- if output.find("might not hold") != -1:
- dests.append(end)
- navigation_graph[start]= dests
- EDGE_COUNT=EDGE_COUNT+1
- return True
-
-def buildNavigationGraph(appFile, outputFile, format):
- global GRAPH_CREATION_TIME
- global navigation_graph
- GRAPH_CREATION_TIME= time.clock()
- nameToNode= {}
- dotFile= open(os.path.splitext(appFile)[0] + ".dot","w")
- graphName= os.path.basename(os.path.splitext(appFile)[0])
- dotFile.write("digraph " + graphName + "{\n")
- dotFile.write("\tnode [style=\"invisible\", label=\"\"] n0;\n")
- nextNode=1
- for pagename in navigation_graph.keys():
- dotFile.write("\tnode [style=\"rounded\", shape=\"box\", label=\"" + pagename + "\"] n"+ str(nextNode) + ";\n")
- nameToNode[pagename]=nextNode
- nextNode= nextNode + 1
-
- dotFile.write("\n")
- for pagename in navigation_graph.keys():
- startNode= nameToNode[pagename]
- for dest in navigation_graph[pagename]:
- destNode = nameToNode[dest]
- dotFile.write("\tn" + str(startNode) + " -> n" + str(destNode) + ";\n")
-
- # Try and see if we know the start page
- controls= open(os.path.splitext(appFile)[0] + ".controls", "r")
- mainpage= os.path.splitext(controls.readline().strip().lower())[0]
- try:
- globalStart= nameToNode[mainpage]
- dotFile.write("\tn0 -> n" + str(globalStart) + ";\n")
- except KeyError:
- pass
- GRAPH_CREATION_TIME= time.clock() - GRAPH_CREATION_TIME
- statsNode= createStatsNode(appFile)
- dotFile.write("\t" + statsNode + "\n")
- dotFile.write("}")
- dotFile.close()
-
- if format != "dot":
- os.system(DOT_PATH + " -T" + format + " -o \"" + outputFile + "\" \"" + os.path.splitext(appFile)[0] + ".dot\" > nul")
- else:
- os.rename("\"" + os.path.splitext(appFile)[0] + ".dot\"", "\"" + outputFile + "\"")
- return True
-
-def showUsage():
- print "NavGraphBuilder -- builds the navigation graph from a phone app. See caveats in NavGraphBuilder.README"
- print "Usage:"
- print "\tNavGraphBuilder --app <PhoneApp.dll> --output <graph file> --format <graph format>"
- print "Options:"
- print "\t--app <PhoneApp.dll>: point to location of main application .dll. Short form: -a. Required."
- print "\t--output <graph file>: file to write graph to. Short form: -o. Optional, defaults to name of phone app and selected format."
- print "\t--format <graph format>: format to draw the graph into. Short form: -f. Optional, accepts dot output formats, defaults to pdf.\n"
-
-def main():
- global CONTROL_CREATION_TIME
- global INJECTION_TIME
- global TEST_TIME
- global QUERY_CREATION_TIME
- global QUERY_RUN_TIME
- global GRAPH_CREATION_TIME
-
- if (not checkEnv()):
- sys.exit(1)
-
- try:
- opts, args= getopt.getopt(sys.argv[1:], "a:o:f:b:", ["app=","output=","format=","build="])
- except getopt.error, msg:
- print msg
- showUsage()
- sys.exit(2)
-
- if len(opts) < 1:
- print "Missing options"
- showUsage()
- sys.exit(2)
-
- appFile=""
- outputFile=""
- format=""
- build=""
- for o, a in opts:
- if o in ["-a","--app"]:
- appFile= a
- if o in ["-o", "--output"]:
- outputFile= a
- if o in ["-f", "--format"]:
- format= a.lower()
- if o in ["-b", "--build"]:
- build= a
-
- if format=="":
- format= "pdf"
-
- appFile = os.path.abspath(appFile)
- if outputFile=="":
- outputFile= os.path.splitext(appFile)[0] + "." + format
- outputFile= os.path.abspath(outputFile)
-
- if build=="" or build.find("c") != -1:
- CONTROL_CREATION_TIME= time.clock();
- print "Extracting control information..."
- if (not createAppControlsFile(appFile, outputFile, format)):
- print "Failed to create app controls file"
- sys.exit(1)
- CONTROL_CREATION_TIME= time.clock() - CONTROL_CREATION_TIME
-
- if build=="" or build.find("i") != -1:
- INJECTION_TIME= time.clock()
- print "Injecting and translating application binary..."
- if (not bctAppFile(appFile, outputFile, format)):
- print "Failed to translate application library"
- sys.exit(1)
- INJECTION_TIME= time.clock() - INJECTION_TIME
-
- if build=="" or build.find("t") != -1:
- TEST_TIME= time.clock()
- print "Testing boogie file..."
- if (not testBoogieOutput(appFile, outputFile, format)):
- print "ByteCode Translator produced erroneous or ambiguous boogie file"
- sys.exit(1)
- TEST_TIME= time.clock() - TEST_TIME
-
- if build=="" or build.find("b") != -1:
- QUERY_CREATION_TIME= time.clock()
- print "Creating boogie queries..."
- if (not createBoogieQueries(appFile, outputFile, format)):
- print "Error creating boogie queries"
- sys.exit(1)
- QUERY_CREATION_TIME= time.clock() - QUERY_CREATION_TIME
-
- if build=="" or build.find("q") != -1:
- QUERY_RUN_TIME= time.clock()
- print "Running boogie queries..."
- if (not runBoogieQueries(appFile, outputFile, format)):
- print "Error running boogie queries"
- sys.exit(1)
- QUERY_RUN_TIME= time.clock() - QUERY_RUN_TIME
-
- if build=="" or build.find("g") != -1:
- print "Building graph..."
- if (not buildNavigationGraph(appFile, outputFile, format)):
- print "Error creating navigation graph"
- sys.exit(1)
-
- print "Success!"
- sys.exit(0)
-
-if __name__ == "__main__":
- main() \ No newline at end of file
diff --git a/BCT/RegressionTests/RegressionTestInput/Class1.cs b/BCT/RegressionTests/RegressionTestInput/Class1.cs
deleted file mode 100644
index 51a4ba86..00000000
--- a/BCT/RegressionTests/RegressionTestInput/Class1.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics.Contracts;
-
-namespace RegressionTestInput {
-
- [AttributeUsage(AttributeTargets.Method)]
- public class AsyncAttribute : Attribute { }
-
- public class Class0 {
-
- static int StaticInt;
-
- static int StaticMethod(int x) {
- return x + 1;
- }
-
- void M(int x) {
- int y = (5 / x) + (x = 3);
- Contract.Assert(x == 3 && y <= 8);
- StaticInt = y;
- Contract.Assert(y == StaticInt);
- }
-
- // Test to make sure we generate unique procedure names
- void M(int x, int y) { }
- void M(bool b) { }
- void M(Class0 c) { }
-
- int NonVoid() {
- return 3 + StaticInt + StaticMethod(3);
- }
-
- int OutParam(out int x) {
- x = 3 + StaticInt;
- return x;
- }
-
- int RefParam(ref int x) {
- x = x + 1;
- StaticInt = x;
- return x;
- }
-
- int AssignToInParam(int x) {
- x = x + 1;
- StaticInt = x;
- return x;
- }
-
- [AsyncAttribute]
- int MethodThatRepresentsAnAynchronousMethod(int x) {
- return x;
- }
-
- int CallAsyncMethod(int y) {
- return MethodThatRepresentsAnAynchronousMethod(y);
- }
-
-
- }
- class ClassWithBoolTypes {
- static bool staticB;
- bool b;
-
- static bool M(int x, int y) {
- return x < y;
- }
-
- public ClassWithBoolTypes(bool z) {
- this.b = z;
- if (z) ClassWithBoolTypes.staticB = z;
- }
-
- public static void Main() {
- ClassWithBoolTypes.M(3, 4);
- }
- }
-
- class ClassWithArrayTypes
- {
- public static void Main1()
- {
- int[] s = new int[5];
- s[0] = 2;
- Contract.Assert(s[0] == 2);
-
- int[] t = new int[4];
- t[0] = 1;
- Contract.Assert(t[0] == 1);
-
- Contract.Assert(s[0] == 2);
- }
-
- public static int[] s;
- public static void Main2()
- {
- s = new int[5];
- s[0] = 2;
- Contract.Assert(s[0] == 2);
-
- int[] t = new int[4];
- t[0] = 1;
- Contract.Assert(t[0] == 1);
-
- Contract.Assert(s[0] == 2);
- }
-
- public int[] a;
- public void Main3(int x)
- {
- a[x] = 42;
- a[x + 1] = 43;
- Contract.Assert(a[x + 1] == a[x] + 1);
- }
-
- public void Main4(int[] xs) {
- if (xs != null && xs.Length > 0) {
- a[0] = xs[0];
- }
- }
- }
-
- public class WriteToTheHeapAValueReadFromTheHeap {
- int x;
- int y;
- public void M() {
- this.y = this.x;
- }
- }
-
- public struct S {
- public int x;
- public bool b;
- }
-
- public class CreateStruct {
- public S Create() {
- var s = new S();
- Contract.Assert(s.x == 0);
- Contract.Assert(s.b == false);
- return s;
- }
- S AssignThreeToSDotX(S s) {
- s.x = 3;
- Contract.Assert(s.x == 3);
- return s;
- }
-
- }
-
- public class RefParameters {
- public static void M(ref int x) {
- x++;
- }
- }
-
- public class RealNumbers {
- public void WriteDouble(double d) {
- Console.WriteLine(d);
- }
- public void ObjectToDouble(object o) {
- WriteDouble((double)o);
- }
- public void RealOperations() {
- double d = 3.0;
- double d2 = 4.0;
- WriteDouble(d + d2);
- WriteDouble(d - d2);
- WriteDouble(d * d2);
- WriteDouble(d / d2);
- }
- }
-
- public class BitwiseOperations {
- public int BitwiseAnd(int x, int y) { return x & y; }
- public int BitwiseOr(int x, int y) { return x | y; }
- public int ExclusiveOr(int x, int y) { return x ^ y; }
- public int BitwiseNegation(int x) { return ~x; }
- }
-
- public class NestedGeneric {
- public class C {
- public class G<T> where T : new() {
- public G(int x) {
- var y = new T(); // test to make sure index is calculated correctly for type function
- }
- }
- }
- }
- public class TestForClassesDifferingOnlyInBeingGeneric {
- public int x;
- }
-
- public class TestForClassesDifferingOnlyInBeingGeneric<T> {
- public int x;
- }
-
- public struct StructContainingStruct {
- public double d;
- public S s;
-
- public StructContainingStruct ReturnCopy(StructContainingStruct s) {
- StructContainingStruct t = s;
- return t;
- }
-
- }
-
-}
diff --git a/BCT/RegressionTests/RegressionTestInput/Properties/AssemblyInfo.cs b/BCT/RegressionTests/RegressionTestInput/Properties/AssemblyInfo.cs
deleted file mode 100644
index b3cc080a..00000000
--- a/BCT/RegressionTests/RegressionTestInput/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("RegressionTestInput")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("RegressionTestInput")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("dc8e9afb-ef4e-4954-8f86-1a79bb0d77e4")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/RegressionTests/RegressionTestInput/RegressionTestInput.csproj b/BCT/RegressionTests/RegressionTestInput/RegressionTestInput.csproj
deleted file mode 100644
index 6cf94c40..00000000
--- a/BCT/RegressionTests/RegressionTestInput/RegressionTestInput.csproj
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{3D13D2CC-6387-46FA-BDC2-4BEEFC460118}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>RegressionTestInput</RootNamespace>
- <AssemblyName>RegressionTestInput</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Class1.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt b/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
deleted file mode 100644
index 0a2a515a..00000000
--- a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
+++ /dev/null
@@ -1,1893 +0,0 @@
-// Copyright (c) 2010, Microsoft Corp.
-// Bytecode Translator prelude
-
-type HeapType = [Ref][Field]Union;
-
-procedure {:inline 1} Alloc() returns (x: Ref);
- modifies $Alloc;
-
-
-
-implementation {:inline 1} Alloc() returns (x: Ref)
-{
- assume $Alloc[x] == false && x != null;
- $Alloc[x] := true;
-}
-
-
-
-function {:builtin "MapAdd"} DelegateMapadd([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapSub"} DelegateMapsub([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapMul"} DelegateMapmul([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapDiv"} DelegateMapdiv([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapMod"} DelegateMapmod([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapConst"} DelegateMapconstint(int) : [Delegate]int;
-
-function {:builtin "MapConst"} DelegateMapconstbool(bool) : [Delegate]bool;
-
-function {:builtin "MapAnd"} DelegateMapand([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapOr"} DelegateMapor([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapNot"} DelegateMapnot([Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapIte"} DelegateMapiteint([Delegate]bool, [Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapIte"} DelegateMapitebool([Delegate]bool, [Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapLe"} DelegateMaple([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapLt"} DelegateMaplt([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapGe"} DelegateMapge([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapGt"} DelegateMapgt([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapEq"} DelegateMapeq([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapIff"} DelegateMapiff([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapImp"} DelegateMapimp([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-axiom MultisetEmpty == DelegateMapconstint(0);
-
-function IsRef(u: Union) : bool;
-
-axiom (forall x: bool :: { Bool2Union(x) } Union2Bool(Bool2Union(x)) == x && !IsRef(Bool2Union(x)));
-
-axiom (forall x: int :: { Int2Union(x) } Union2Int(Int2Union(x)) == x && !IsRef(Int2Union(x)));
-
-axiom (forall x: Real :: { Real2Union(x) } Union2Real(Real2Union(x)) == x && !IsRef(Real2Union(x)));
-
-axiom (forall x: Ref :: { Ref2Union(x) } Union2Ref(Ref2Union(x)) == x && IsRef(Ref2Union(x)));
-
-axiom (forall x: Ref :: { Struct2Union(x) } Union2Struct(Struct2Union(x)) == x && !IsRef(Struct2Union(x)));
-
-function $TypeOfInv(Ref) : Type;
-
-axiom (forall t: Type :: { $TypeOf(t) } $TypeOfInv($TypeOf(t)) == t);
-
-procedure {:inline 1} System.Object.GetType(this: Ref) returns ($result: Ref);
-
-
-
-implementation {:inline 1} System.Object.GetType(this: Ref) returns ($result: Ref)
-{
- $result := $TypeOf($DynamicType(this));
-}
-
-
-
-axiom Union2Int($DefaultHeapValue) == 0;
-
-axiom Union2Bool($DefaultHeapValue) == false;
-
-axiom Union2Ref($DefaultHeapValue) == null;
-
-function $ThreadDelegate(Ref) : Ref;
-
-procedure {:inline 1} System.Threading.Thread.#ctor$System.Threading.ParameterizedThreadStart(this: Ref, start$in: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.#ctor$System.Threading.ParameterizedThreadStart(this: Ref, start$in: Ref)
-{
- assume $ThreadDelegate(this) == start$in;
-}
-
-
-
-procedure {:inline 1} System.Threading.Thread.Start$System.Object(this: Ref, parameter$in: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.Start$System.Object(this: Ref, parameter$in: Ref)
-{
- call {:async} Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object($ThreadDelegate(this), parameter$in);
-}
-
-
-
-procedure Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref);
-
-
-
-implementation Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref)
-{
- $Exception := null;
- call System.Threading.ParameterizedThreadStart.Invoke$System.Object(this, obj$in);
-}
-
-
-
-procedure {:extern} System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref);
-
-
-
-procedure {:inline 1} System.Threading.Thread.#ctor$System.Threading.ThreadStart(this: Ref, start$in: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.#ctor$System.Threading.ThreadStart(this: Ref, start$in: Ref)
-{
- assume $ThreadDelegate(this) == start$in;
-}
-
-
-
-procedure {:inline 1} System.Threading.Thread.Start(this: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.Start(this: Ref)
-{
- call {:async} Wrapper_System.Threading.ThreadStart.Invoke($ThreadDelegate(this));
-}
-
-
-
-procedure Wrapper_System.Threading.ThreadStart.Invoke(this: Ref);
-
-
-
-implementation Wrapper_System.Threading.ThreadStart.Invoke(this: Ref)
-{
- $Exception := null;
- call System.Threading.ThreadStart.Invoke(this);
-}
-
-
-
-procedure {:extern} System.Threading.ThreadStart.Invoke(this: Ref);
-
-
-
-procedure {:inline 1} DelegateAdd(a: Ref, b: Ref) returns (c: Ref);
-
-
-
-implementation {:inline 1} DelegateAdd(a: Ref, b: Ref) returns (c: Ref)
-{
- var d: Delegate;
-
- if (a == null)
- {
- c := b;
- }
- else if (b == null)
- {
- c := a;
- }
- else
- {
- call c := Alloc();
- assume $RefToDelegate(c) == $RefToDelegate(a) || $RefToDelegate(c) == $RefToDelegate(b);
- assume $RefToDelegateMultiset(c) == MultisetPlus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b));
- }
-}
-
-
-
-procedure {:inline 1} DelegateRemove(a: Ref, b: Ref) returns (c: Ref);
-
-
-
-implementation {:inline 1} DelegateRemove(a: Ref, b: Ref) returns (c: Ref)
-{
- var d: Delegate;
-
- if (a == null)
- {
- c := null;
- }
- else if (b == null)
- {
- c := a;
- }
- else if (MultisetMinus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b)) == MultisetEmpty)
- {
- c := null;
- }
- else
- {
- call c := Alloc();
- assume $RefToDelegateMultiset(c) == MultisetMinus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b));
- assume $RefToDelegateMultiset(c)[$RefToDelegate(c)] > 0;
- }
-}
-
-
-
-procedure {:inline 1} DelegateCreate(d: Delegate) returns (c: Ref);
-
-
-
-implementation {:inline 1} DelegateCreate(d: Delegate) returns (c: Ref)
-{
- call c := Alloc();
- assume $RefToDelegate(c) == d;
- assume $RefToDelegateMultiset(c) == MultisetSingleton(d);
-}
-
-
-
-procedure {:inline 1} System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-
-
-
-procedure {:inline 1} System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-
-
-
-implementation System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool)
-{
- $result := a$in == b$in;
-}
-
-
-
-implementation System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool)
-{
- $result := a$in != b$in;
-}
-
-
-
-var $Heap: HeapType;
-
-function {:inline true} Read(H: HeapType, o: Ref, f: Field) : Union
-{
- H[o][f]
-}
-
-function {:inline true} Write(H: HeapType, o: Ref, f: Field, v: Union) : HeapType
-{
- H[o := H[o][f := v]]
-}
-
-var $ArrayContents: [Ref][int]Union;
-
-function $ArrayLength(Ref) : int;
-
-type {:datatype} Delegate;
-
-type DelegateMultiset = [Delegate]int;
-
-const unique MultisetEmpty: DelegateMultiset;
-
-function {:inline true} MultisetSingleton(x: Delegate) : DelegateMultiset
-{
- MultisetEmpty[x := 1]
-}
-
-function {:inline true} MultisetPlus(x: DelegateMultiset, y: DelegateMultiset) : DelegateMultiset
-{
- DelegateMapadd(x, y)
-}
-
-function {:inline true} MultisetMinus(x: DelegateMultiset, y: DelegateMultiset) : DelegateMultiset
-{
- DelegateMapiteint(DelegateMapgt(x, y), DelegateMapsub(x, y), DelegateMapconstint(0))
-}
-
-type Field;
-
-type Union;
-
-const unique $DefaultHeapValue: Union;
-
-type Ref;
-
-const unique null: Ref;
-
-type {:datatype} Type;
-
-type Real;
-
-const unique $DefaultReal: Real;
-
-procedure {:inline 1} $BoxFromBool(b: bool) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromBool(b: bool) returns (r: Ref)
-{
- call r := Alloc();
- assume $BoxedValue(r) == Bool2Union(b);
-}
-
-
-
-procedure {:inline 1} $BoxFromInt(i: int) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromInt(i: int) returns (r: Ref)
-{
- call r := Alloc();
- assume $BoxedValue(r) == Int2Union(i);
-}
-
-
-
-procedure {:inline 1} $BoxFromReal(r: Real) returns (rf: Ref);
-
-
-
-implementation {:inline 1} $BoxFromReal(r: Real) returns (rf: Ref)
-{
- call rf := Alloc();
- assume $BoxedValue(rf) == Real2Union(r);
-}
-
-
-
-procedure {:inline 1} $BoxFromStruct(s: Ref) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromStruct(s: Ref) returns (r: Ref)
-{
- call r := Alloc();
- assume $BoxedValue(r) == Struct2Union(s);
-}
-
-
-
-procedure {:inline 1} $BoxFromUnion(u: Union) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromUnion(u: Union) returns (r: Ref)
-{
- if (IsRef(u))
- {
- r := Union2Ref(u);
- }
- else
- {
- call r := Alloc();
- assume $BoxedValue(r) == u;
- }
-}
-
-
-
-function $BoxedValue(r: Ref) : Union;
-
-function {:inline true} $Unbox2Bool(r: Ref) : bool
-{
- Union2Bool($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Int(r: Ref) : int
-{
- Union2Int($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Real(r: Ref) : Real
-{
- Union2Real($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Struct(r: Ref) : Ref
-{
- Union2Struct($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Union(r: Ref) : Union
-{
- $BoxedValue(r)
-}
-
-function Union2Bool(u: Union) : bool;
-
-function Union2Int(u: Union) : int;
-
-function Union2Ref(u: Union) : Ref;
-
-function Union2Real(u: Union) : Real;
-
-function Union2Struct(u: Union) : Ref;
-
-function Bool2Union(boolValue: bool) : Union;
-
-function Int2Union(intValue: int) : Union;
-
-function Ref2Union(refValue: Ref) : Union;
-
-function Real2Union(realValue: Real) : Union;
-
-function Struct2Union(structValue: Ref) : Union;
-
-function {:inline true} Union2Union(u: Union) : Union
-{
- u
-}
-
-function Int2Real(int) : Real;
-
-function Real2Int(Real) : int;
-
-function RealPlus(Real, Real) : Real;
-
-function RealMinus(Real, Real) : Real;
-
-function RealTimes(Real, Real) : Real;
-
-function RealDivide(Real, Real) : Real;
-
-function RealModulus(Real, Real) : Real;
-
-function RealLessThan(Real, Real) : bool;
-
-function RealLessThanOrEqual(Real, Real) : bool;
-
-function RealGreaterThan(Real, Real) : bool;
-
-function RealGreaterThanOrEqual(Real, Real) : bool;
-
-function BitwiseAnd(int, int) : int;
-
-function BitwiseOr(int, int) : int;
-
-function BitwiseExclusiveOr(int, int) : int;
-
-function BitwiseNegation(int) : int;
-
-function RightShift(int, int) : int;
-
-function LeftShift(int, int) : int;
-
-function $DynamicType(Ref) : Type;
-
-function $TypeOf(Type) : Ref;
-
-function $As(Ref, Type) : Ref;
-
-function $Subtype(Type, Type) : bool;
-
-function $DisjointSubtree(Type, Type) : bool;
-
-var $Alloc: [Ref]bool;
-
-function {:builtin "MapImp"} $allocImp([Ref]bool, [Ref]bool) : [Ref]bool;
-
-function {:builtin "MapConst"} $allocConstBool(bool) : [Ref]bool;
-
-function $RefToDelegate(Ref) : Delegate;
-
-function $RefToDelegateMultiset(Ref) : DelegateMultiset;
-
-function {:constructor} $RefToDelegateMultisetCons($Method: int, $Receiver: Ref, $TypeParameters: Type) : Delegate;
-
-var {:thread_local} $Exception: Ref;
-
-
-
-
-
-function {:constructor} T$RegressionTestInput.StructContainingStruct() : Type;
-
-function {:constructor} {:extern} T$System.ValueType() : Type;
-
-function {:constructor} {:extern} T$System.Object() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$System.Object(), $T) } $Subtype(T$System.Object(), $T) <==> T$System.Object() == $T);
-
-axiom (forall $T: Type :: { $Subtype(T$System.ValueType(), $T) } $Subtype(T$System.ValueType(), $T) <==> T$System.ValueType() == $T || $Subtype(T$System.Object(), $T));
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.StructContainingStruct(), $T) } $Subtype(T$RegressionTestInput.StructContainingStruct(), $T) <==> T$RegressionTestInput.StructContainingStruct() == $T || $Subtype(T$System.ValueType(), $T));
-
-procedure RegressionTestInput.StructContainingStruct.#default_ctor($this: Ref);
-
-
-
-const unique F$RegressionTestInput.StructContainingStruct.d: Field;
-
-procedure RegressionTestInput.S.#default_ctor($this: Ref);
-
-
-
-function {:constructor} T$RegressionTestInput.S() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.S(), $T) } $Subtype(T$RegressionTestInput.S(), $T) <==> T$RegressionTestInput.S() == $T || $Subtype(T$System.ValueType(), $T));
-
-const unique F$RegressionTestInput.StructContainingStruct.s: Field;
-
-implementation {:inline 1} RegressionTestInput.StructContainingStruct.#default_ctor($this: Ref)
-{
- var $tmp0: Ref;
-
- $Heap := Write($Heap, $this, F$RegressionTestInput.StructContainingStruct.d, Real2Union($DefaultReal));
- call $tmp0 := Alloc();
- call RegressionTestInput.S.#default_ctor($tmp0);
- assume $DynamicType($tmp0) == T$RegressionTestInput.S();
- $Heap := Write($Heap, $this, F$RegressionTestInput.StructContainingStruct.s, Ref2Union($tmp0));
-}
-
-
-
-procedure RegressionTestInput.StructContainingStruct.#copy_ctor(this: Ref) returns (other: Ref);
- free ensures this != other;
-
-
-
-procedure RegressionTestInput.S.#copy_ctor(this: Ref) returns (other: Ref);
- free ensures this != other;
-
-
-
-implementation {:inline 1} RegressionTestInput.StructContainingStruct.#copy_ctor(this: Ref) returns (other: Ref)
-{
- var $tmp1: Ref;
-
- call other := Alloc();
- assume $DynamicType(other) == T$RegressionTestInput.StructContainingStruct();
- $Heap := Write($Heap, other, F$RegressionTestInput.StructContainingStruct.d, Real2Union(Union2Real(Read($Heap, this, F$RegressionTestInput.StructContainingStruct.d))));
- call $tmp1 := RegressionTestInput.S.#copy_ctor(Union2Ref(Read($Heap, this, F$RegressionTestInput.StructContainingStruct.s)));
- $Heap := Write($Heap, other, F$RegressionTestInput.StructContainingStruct.s, Ref2Union($tmp1));
-}
-
-
-
-procedure RegressionTestInput.StructContainingStruct.ReturnCopy$RegressionTestInput.StructContainingStruct($this: Ref, s$in: Ref) returns ($result: Ref);
- free ensures $result == null || $Alloc[$result];
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.StructContainingStruct.ReturnCopy$RegressionTestInput.StructContainingStruct($this: Ref, s$in: Ref) returns ($result: Ref)
-{
- var s: Ref;
- var t_Ref: Ref;
- var $localExc: Ref;
- var $label: int;
-
- s := s$in;
- assume {:breadcrumb 0} true;
- call t_Ref := RegressionTestInput.StructContainingStruct.#copy_ctor(s);
- $result := t_Ref;
- return;
-}
-
-
-
-function {:constructor} T$RegressionTestInput.RealNumbers() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.RealNumbers(), $T) } $Subtype(T$RegressionTestInput.RealNumbers(), $T) <==> T$RegressionTestInput.RealNumbers() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.RealNumbers.WriteDouble$System.Double($this: Ref, d$in: Real);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Console.WriteLine$System.Double(value$in: Real);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RealNumbers.WriteDouble$System.Double($this: Ref, d$in: Real)
-{
- var d: Real;
- var $localExc: Ref;
- var $label: int;
-
- d := d$in;
- assume {:breadcrumb 1} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 162} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 162} true;
- call System.Console.WriteLine$System.Double(d);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure RegressionTestInput.RealNumbers.ObjectToDouble$System.Object($this: Ref, o$in: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RealNumbers.ObjectToDouble$System.Object($this: Ref, o$in: Ref)
-{
- var o: Ref;
- var $localExc: Ref;
- var $label: int;
-
- o := o$in;
- assume {:breadcrumb 2} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 165} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 165} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, $Unbox2Real(o));
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure RegressionTestInput.RealNumbers.RealOperations($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-const unique $real_literal_3_0: Real;
-
-const unique $real_literal_4_0: Real;
-
-implementation RegressionTestInput.RealNumbers.RealOperations($this: Ref)
-{
- var d_Real: Real;
- var d2_Real: Real;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 3} true;
- d_Real := $real_literal_3_0;
- d2_Real := $real_literal_4_0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 170} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 170} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealPlus(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 171} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 171} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealMinus(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 172} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 172} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealTimes(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 173} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 173} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealDivide(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure RegressionTestInput.RealNumbers.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Object.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RealNumbers.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 4} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.RealNumbers.#cctor();
-
-
-
-implementation T$RegressionTestInput.RealNumbers.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), $T) } $Subtype(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), $T) <==> T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap() == $T || $Subtype(T$System.Object(), $T));
-
-const unique F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: Field;
-
-const unique F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y: Field;
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 5} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 130} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 130} true;
- assume $this != null;
- $Heap := Write($Heap, $this, F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y, Int2Union(Union2Int(Read($Heap, $this, F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x))));
-}
-
-
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- $Heap := Write($Heap, $this, F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x, Int2Union(0));
- $Heap := Write($Heap, $this, F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y, Int2Union(0));
- assume {:breadcrumb 6} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor();
-
-
-
-implementation T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.CreateStruct() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.CreateStruct(), $T) } $Subtype(T$RegressionTestInput.CreateStruct(), $T) <==> T$RegressionTestInput.CreateStruct() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.CreateStruct.Create($this: Ref) returns ($result: Ref);
- free ensures $result == null || $Alloc[$result];
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-const unique F$RegressionTestInput.S.x: Field;
-
-const unique F$RegressionTestInput.S.b: Field;
-
-implementation RegressionTestInput.CreateStruct.Create($this: Ref) returns ($result: Ref)
-{
- var s_Ref: Ref;
- var $tmp0: Ref;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 7} true;
- call $tmp0 := Alloc();
- call RegressionTestInput.S.#default_ctor($tmp0);
- assume $DynamicType($tmp0) == T$RegressionTestInput.S();
- s_Ref := $tmp0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 142} true;
- assume s_Ref != null;
- assert Union2Int(Read($Heap, s_Ref, F$RegressionTestInput.S.x)) == 0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 143} true;
- assume s_Ref != null;
- assert !Union2Bool(Read($Heap, s_Ref, F$RegressionTestInput.S.b));
- $result := s_Ref;
- return;
-}
-
-
-
-procedure RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S($this: Ref, s$in: Ref) returns ($result: Ref);
- free ensures $result == null || $Alloc[$result];
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S($this: Ref, s$in: Ref) returns ($result: Ref)
-{
- var s: Ref;
- var $localExc: Ref;
- var $label: int;
-
- s := s$in;
- assume {:breadcrumb 8} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 147} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 147} true;
- $Heap := Write($Heap, s, F$RegressionTestInput.S.x, Int2Union(3));
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 148} true;
- assume s != null;
- assert Union2Int(Read($Heap, s, F$RegressionTestInput.S.x)) == 3;
- $result := s;
- return;
-}
-
-
-
-procedure RegressionTestInput.CreateStruct.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.CreateStruct.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 9} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.CreateStruct.#cctor();
-
-
-
-implementation T$RegressionTestInput.CreateStruct.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.ClassWithArrayTypes() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.ClassWithArrayTypes(), $T) } $Subtype(T$RegressionTestInput.ClassWithArrayTypes(), $T) <==> T$RegressionTestInput.ClassWithArrayTypes() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.ClassWithArrayTypes.s: Ref;
-
-const unique F$RegressionTestInput.ClassWithArrayTypes.a: Field;
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main1();
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main1()
-{
- var s_Ref: Ref;
- var $tmp0: Ref;
- var t_Ref: Ref;
- var $tmp1: Ref;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 10} true;
- call $tmp0 := Alloc();
- assume $ArrayLength($tmp0) == 1 * 5;
- s_Ref := $tmp0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 88} true;
- assume s_Ref != null;
- assert Union2Int($ArrayContents[s_Ref][0]) == 2;
- call $tmp1 := Alloc();
- assume $ArrayLength($tmp1) == 1 * 4;
- t_Ref := $tmp1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 92} true;
- assume t_Ref != null;
- assert Union2Int($ArrayContents[t_Ref][0]) == 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 94} true;
- assume s_Ref != null;
- assert Union2Int($ArrayContents[s_Ref][0]) == 2;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main2();
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main2()
-{
- var $tmp0: Ref;
- var t_Ref: Ref;
- var $tmp1: Ref;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 11} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 100} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 100} true;
- call $tmp0 := Alloc();
- assume $ArrayLength($tmp0) == 1 * 5;
- F$RegressionTestInput.ClassWithArrayTypes.s := $tmp0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 101} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 101} true;
- $ArrayContents := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s][0 := Int2Union(2)]];
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 102} true;
- assume F$RegressionTestInput.ClassWithArrayTypes.s != null;
- assert Union2Int($ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s][0]) == 2;
- call $tmp1 := Alloc();
- assume $ArrayLength($tmp1) == 1 * 4;
- t_Ref := $tmp1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 106} true;
- assume t_Ref != null;
- assert Union2Int($ArrayContents[t_Ref][0]) == 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 108} true;
- assume F$RegressionTestInput.ClassWithArrayTypes.s != null;
- assert Union2Int($ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s][0]) == 2;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32($this: Ref, x$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32($this: Ref, x$in: int)
-{
- var x: int;
- var $tmp0: Ref;
- var $tmp1: Ref;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 12} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 114} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 114} true;
- assume $this != null;
- $ArrayContents := $ArrayContents[Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a)) := $ArrayContents[Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a))][x := Int2Union(42)]];
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 115} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 115} true;
- assume $this != null;
- $ArrayContents := $ArrayContents[Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a)) := $ArrayContents[Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a))][x + 1 := Int2Union(43)]];
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 116} true;
- assume $this != null;
- $tmp0 := Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a));
- assume $tmp0 != null;
- assume $this != null;
- $tmp1 := Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a));
- assume $tmp1 != null;
- assert Union2Int($ArrayContents[$tmp0][x + 1]) == Union2Int($ArrayContents[$tmp1][x]) + 1;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array($this: Ref, xs$in: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array($this: Ref, xs$in: Ref)
-{
- var xs: Ref;
- var $localExc: Ref;
- var $label: int;
-
- xs := xs$in;
- assume {:breadcrumb 13} true;
- if (xs != null)
- {
- }
- else
- {
- }
-
- if ((if xs != null then $ArrayLength(xs) > 0 else false))
- {
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 121} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 121} true;
- assume $this != null;
- assume xs != null;
- $ArrayContents := $ArrayContents[Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a)) := $ArrayContents[Union2Ref(Read($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a))][0 := Int2Union(Union2Int($ArrayContents[xs][0]))]];
- }
- else
- {
- }
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- $Heap := Write($Heap, $this, F$RegressionTestInput.ClassWithArrayTypes.a, Ref2Union(null));
- assume {:breadcrumb 14} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.ClassWithArrayTypes.#cctor();
-
-
-
-implementation T$RegressionTestInput.ClassWithArrayTypes.#cctor()
-{
- F$RegressionTestInput.ClassWithArrayTypes.s := null;
-}
-
-
-
-function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T: Type) : Type;
-
-axiom (forall T: Type, $T: Type :: { $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), $T) } $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), $T) <==> T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T) == $T || $Subtype(T$System.Object(), $T));
-
-const unique F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.x: Field;
-
-procedure RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- $Heap := Write($Heap, $this, F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.x, Int2Union(0));
- assume {:breadcrumb 15} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#cctor();
-
-
-
-implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.BitwiseOperations() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.BitwiseOperations(), $T) } $Subtype(T$RegressionTestInput.BitwiseOperations(), $T) <==> T$RegressionTestInput.BitwiseOperations() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.BitwiseOperations.BitwiseAnd$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.BitwiseAnd$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 16} true;
- $result := BitwiseAnd(x, y);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.BitwiseOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.BitwiseOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 17} true;
- $result := BitwiseOr(x, y);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.ExclusiveOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.ExclusiveOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 18} true;
- $result := BitwiseExclusiveOr(x, y);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.BitwiseNegation$System.Int32($this: Ref, x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.BitwiseNegation$System.Int32($this: Ref, x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 19} true;
- $result := BitwiseNegation(x);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 20} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.BitwiseOperations.#cctor();
-
-
-
-implementation T$RegressionTestInput.BitwiseOperations.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.AsyncAttribute() : Type;
-
-function {:constructor} {:extern} T$System.Attribute() : Type;
-
-function {:constructor} {:extern} T$System.Runtime.InteropServices._Attribute() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$System.Runtime.InteropServices._Attribute(), $T) } $Subtype(T$System.Runtime.InteropServices._Attribute(), $T) <==> T$System.Runtime.InteropServices._Attribute() == $T);
-
-axiom (forall $T: Type :: { $Subtype(T$System.Attribute(), $T) } $Subtype(T$System.Attribute(), $T) <==> T$System.Attribute() == $T || $Subtype(T$System.Object(), $T) || $Subtype(T$System.Runtime.InteropServices._Attribute(), $T));
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.AsyncAttribute(), $T) } $Subtype(T$RegressionTestInput.AsyncAttribute(), $T) <==> T$RegressionTestInput.AsyncAttribute() == $T || $Subtype(T$System.Attribute(), $T));
-
-procedure RegressionTestInput.AsyncAttribute.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Attribute.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.AsyncAttribute.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 21} true;
- call System.Attribute.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.AsyncAttribute.#cctor();
-
-
-
-implementation T$RegressionTestInput.AsyncAttribute.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.RefParameters() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.RefParameters(), $T) } $Subtype(T$RegressionTestInput.RefParameters(), $T) <==> T$RegressionTestInput.RefParameters() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int)
-{
- var $localExc: Ref;
- var $label: int;
-
- x$out := x$in;
- assume {:breadcrumb 22} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 156} true;
- x$out := x$out + 1;
-}
-
-
-
-procedure RegressionTestInput.RefParameters.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RefParameters.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 23} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.RefParameters.#cctor();
-
-
-
-implementation T$RegressionTestInput.RefParameters.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.NestedGeneric() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.NestedGeneric(), $T) } $Subtype(T$RegressionTestInput.NestedGeneric(), $T) <==> T$RegressionTestInput.NestedGeneric() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.NestedGeneric.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.NestedGeneric.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 24} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-function {:constructor} T$RegressionTestInput.NestedGeneric.C() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.NestedGeneric.C(), $T) } $Subtype(T$RegressionTestInput.NestedGeneric.C(), $T) <==> T$RegressionTestInput.NestedGeneric.C() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.NestedGeneric.C.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.NestedGeneric.C.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 25} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-function {:constructor} T$RegressionTestInput.NestedGeneric.C.G`1(T: Type) : Type;
-
-axiom (forall T: Type, $T: Type :: { $Subtype(T$RegressionTestInput.NestedGeneric.C.G`1(T), $T) } $Subtype(T$RegressionTestInput.NestedGeneric.C.G`1(T), $T) <==> T$RegressionTestInput.NestedGeneric.C.G`1(T) == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this: Ref, x$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Activator.CreateInstance``1(T: Type) returns ($result: Union);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this: Ref, x$in: int)
-{
- var x: int;
- var CS$0$0000_Union: Union;
- var $tmp0: Union;
- var $tmp1: Union;
- var $tmp2: Ref;
- var y_Union: Union;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 26} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 187} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 187} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- CS$0$0000_Union := $DefaultHeapValue;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- call $tmp2 := $BoxFromUnion(CS$0$0000_Union);
- if ($tmp2 != null)
- {
- }
- else
- {
- call $tmp1 := System.Activator.CreateInstance``1(T#T$RegressionTestInput.NestedGeneric.C.G`1($DynamicType($this)));
- $tmp0 := Union2Union($tmp1);
- if ($Exception != null)
- {
- return;
- }
- }
-
- y_Union := (if $tmp2 != null then $DefaultHeapValue else $tmp0);
-}
-
-
-
-procedure T$RegressionTestInput.NestedGeneric.C.G`1.#cctor();
-
-
-
-implementation T$RegressionTestInput.NestedGeneric.C.G`1.#cctor()
-{
-}
-
-
-
-procedure T$RegressionTestInput.NestedGeneric.C.#cctor();
-
-
-
-implementation T$RegressionTestInput.NestedGeneric.C.#cctor()
-{
-}
-
-
-
-procedure T$RegressionTestInput.NestedGeneric.#cctor();
-
-
-
-implementation T$RegressionTestInput.NestedGeneric.#cctor()
-{
-}
-
-
-
-implementation {:inline 1} RegressionTestInput.S.#default_ctor($this: Ref)
-{
- $Heap := Write($Heap, $this, F$RegressionTestInput.S.x, Int2Union(0));
- $Heap := Write($Heap, $this, F$RegressionTestInput.S.b, Bool2Union(false));
-}
-
-
-
-implementation {:inline 1} RegressionTestInput.S.#copy_ctor(this: Ref) returns (other: Ref)
-{
- call other := Alloc();
- assume $DynamicType(other) == T$RegressionTestInput.S();
- $Heap := Write($Heap, other, F$RegressionTestInput.S.x, Int2Union(Union2Int(Read($Heap, this, F$RegressionTestInput.S.x))));
- $Heap := Write($Heap, other, F$RegressionTestInput.S.b, Bool2Union(Union2Bool(Read($Heap, this, F$RegressionTestInput.S.b))));
-}
-
-
-
-function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), $T) } $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), $T) <==> T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric() == $T || $Subtype(T$System.Object(), $T));
-
-const unique F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.x: Field;
-
-procedure RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- $Heap := Write($Heap, $this, F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.x, Int2Union(0));
- assume {:breadcrumb 27} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#cctor();
-
-
-
-implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.Class0() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.Class0(), $T) } $Subtype(T$RegressionTestInput.Class0(), $T) <==> T$RegressionTestInput.Class0() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.Class0.StaticInt: int;
-
-procedure RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 28} true;
- $result := x + 1;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32($this: Ref, x$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32($this: Ref, x$in: int)
-{
- var x: int;
- var y_int: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 29} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 21} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 21} true;
- x := 3;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 21} true;
- y_int := 3 + 5 / x;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 22} true;
- if (x != 3)
- {
- }
- else
- {
- }
-
- assert (if x != 3 then false else !(y_int > 8));
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 23} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 23} true;
- F$RegressionTestInput.Class0.StaticInt := y_int;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 24} true;
- assert y_int == F$RegressionTestInput.Class0.StaticInt;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 30} true;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Boolean($this: Ref, b$in: bool);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Boolean($this: Ref, b$in: bool)
-{
- var b: bool;
- var $localExc: Ref;
- var $label: int;
-
- b := b$in;
- assume {:breadcrumb 31} true;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0($this: Ref, c$in: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0($this: Ref, c$in: Ref)
-{
- var c: Ref;
- var $localExc: Ref;
- var $label: int;
-
- c := c$in;
- assume {:breadcrumb 32} true;
-}
-
-
-
-procedure RegressionTestInput.Class0.NonVoid($this: Ref) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.NonVoid($this: Ref) returns ($result: int)
-{
- var $tmp0: int;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 33} true;
- call $tmp0 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
- if ($Exception != null)
- {
- return;
- }
-
- $result := 3 + F$RegressionTestInput.Class0.StaticInt + $tmp0;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.OutParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.OutParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int)
-{
- var $localExc: Ref;
- var $label: int;
-
- x$out := x$in;
- assume {:breadcrumb 34} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 37} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 37} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 37} true;
- x$out := 3 + F$RegressionTestInput.Class0.StaticInt;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.RefParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.RefParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int)
-{
- var $localExc: Ref;
- var $label: int;
-
- x$out := x$in;
- assume {:breadcrumb 35} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 42} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 42} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 42} true;
- x$out := x$out + 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 43} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 43} true;
- F$RegressionTestInput.Class0.StaticInt := x$out;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.AssignToInParam$System.Int32($this: Ref, x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.AssignToInParam$System.Int32($this: Ref, x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 36} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 48} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 48} true;
- x := x + 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 49} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 49} true;
- F$RegressionTestInput.Class0.StaticInt := x;
- $result := x;
- return;
-}
-
-
-
-procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32($this: Ref, x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32($this: Ref, x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 37} true;
- $result := x;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32($this: Ref, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32($this: Ref, y$in: int) returns ($result: int)
-{
- var y: int;
- var $tmp0: int;
- var $localExc: Ref;
- var $label: int;
-
- y := y$in;
- assume {:breadcrumb 38} true;
- call {:async} $tmp0 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32($this, y);
- if ($Exception != null)
- {
- return;
- }
-
- $result := $tmp0;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 39} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.Class0.#cctor();
-
-
-
-implementation T$RegressionTestInput.Class0.#cctor()
-{
- F$RegressionTestInput.Class0.StaticInt := 0;
-}
-
-
-
-function {:constructor} T$RegressionTestInput.ClassWithBoolTypes() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.ClassWithBoolTypes(), $T) } $Subtype(T$RegressionTestInput.ClassWithBoolTypes(), $T) <==> T$RegressionTestInput.ClassWithBoolTypes() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.ClassWithBoolTypes.staticB: bool;
-
-const unique F$RegressionTestInput.ClassWithBoolTypes.b: Field;
-
-procedure RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 40} true;
- $result := x < y;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean($this: Ref, z$in: bool);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean($this: Ref, z$in: bool)
-{
- var z: bool;
- var $localExc: Ref;
- var $label: int;
-
- z := z$in;
- $Heap := Write($Heap, $this, F$RegressionTestInput.ClassWithBoolTypes.b, Bool2Union(false));
- assume {:breadcrumb 41} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 72} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 72} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 73} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 73} true;
- $Heap := Write($Heap, $this, F$RegressionTestInput.ClassWithBoolTypes.b, Bool2Union(z));
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 74} true;
- if (z)
- {
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 74} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 74} true;
- F$RegressionTestInput.ClassWithBoolTypes.staticB := z;
- }
- else
- {
- }
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.Main();
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.Main()
-{
- var $tmp0: bool;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 42} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 78} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 78} true;
- call $tmp0 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.ClassWithBoolTypes.#cctor();
-
-
-
-implementation T$RegressionTestInput.ClassWithBoolTypes.#cctor()
-{
- F$RegressionTestInput.ClassWithBoolTypes.staticB := false;
-}
-
-
diff --git a/BCT/RegressionTests/TranslationTest/Properties/AssemblyInfo.cs b/BCT/RegressionTests/TranslationTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index a0fd3275..00000000
--- a/BCT/RegressionTests/TranslationTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TranslationTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("TranslationTest")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f448ac99-c5e7-424c-8bdb-243e8276d4d7")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt b/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
deleted file mode 100644
index b552ee36..00000000
--- a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
+++ /dev/null
@@ -1,1879 +0,0 @@
-// Copyright (c) 2010, Microsoft Corp.
-// Bytecode Translator prelude
-
-procedure {:inline 1} Alloc() returns (x: Ref);
- modifies $Alloc;
-
-
-
-implementation {:inline 1} Alloc() returns (x: Ref)
-{
- assume $Alloc[x] == false && x != null;
- $Alloc[x] := true;
-}
-
-
-
-function {:builtin "MapAdd"} DelegateMapadd([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapSub"} DelegateMapsub([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapMul"} DelegateMapmul([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapDiv"} DelegateMapdiv([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapMod"} DelegateMapmod([Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapConst"} DelegateMapconstint(int) : [Delegate]int;
-
-function {:builtin "MapConst"} DelegateMapconstbool(bool) : [Delegate]bool;
-
-function {:builtin "MapAnd"} DelegateMapand([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapOr"} DelegateMapor([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapNot"} DelegateMapnot([Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapIte"} DelegateMapiteint([Delegate]bool, [Delegate]int, [Delegate]int) : [Delegate]int;
-
-function {:builtin "MapIte"} DelegateMapitebool([Delegate]bool, [Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapLe"} DelegateMaple([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapLt"} DelegateMaplt([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapGe"} DelegateMapge([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapGt"} DelegateMapgt([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapEq"} DelegateMapeq([Delegate]int, [Delegate]int) : [Delegate]bool;
-
-function {:builtin "MapIff"} DelegateMapiff([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-function {:builtin "MapImp"} DelegateMapimp([Delegate]bool, [Delegate]bool) : [Delegate]bool;
-
-axiom MultisetEmpty == DelegateMapconstint(0);
-
-function IsRef(u: Union) : bool;
-
-axiom (forall x: bool :: { Bool2Union(x) } Union2Bool(Bool2Union(x)) == x && !IsRef(Bool2Union(x)));
-
-axiom (forall x: int :: { Int2Union(x) } Union2Int(Int2Union(x)) == x && !IsRef(Int2Union(x)));
-
-axiom (forall x: Real :: { Real2Union(x) } Union2Real(Real2Union(x)) == x && !IsRef(Real2Union(x)));
-
-axiom (forall x: Ref :: { Ref2Union(x) } Union2Ref(Ref2Union(x)) == x && IsRef(Ref2Union(x)));
-
-axiom (forall x: Ref :: { Struct2Union(x) } Union2Struct(Struct2Union(x)) == x && !IsRef(Struct2Union(x)));
-
-function $TypeOfInv(Ref) : Type;
-
-axiom (forall t: Type :: { $TypeOf(t) } $TypeOfInv($TypeOf(t)) == t);
-
-procedure {:inline 1} System.Object.GetType(this: Ref) returns ($result: Ref);
-
-
-
-implementation {:inline 1} System.Object.GetType(this: Ref) returns ($result: Ref)
-{
- $result := $TypeOf($DynamicType(this));
-}
-
-
-
-axiom Union2Int($DefaultHeapValue) == 0;
-
-axiom Union2Bool($DefaultHeapValue) == false;
-
-axiom Union2Ref($DefaultHeapValue) == null;
-
-function $ThreadDelegate(Ref) : Ref;
-
-procedure {:inline 1} System.Threading.Thread.#ctor$System.Threading.ParameterizedThreadStart(this: Ref, start$in: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.#ctor$System.Threading.ParameterizedThreadStart(this: Ref, start$in: Ref)
-{
- assume $ThreadDelegate(this) == start$in;
-}
-
-
-
-procedure {:inline 1} System.Threading.Thread.Start$System.Object(this: Ref, parameter$in: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.Start$System.Object(this: Ref, parameter$in: Ref)
-{
- call {:async} Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object($ThreadDelegate(this), parameter$in);
-}
-
-
-
-procedure Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref);
-
-
-
-implementation Wrapper_System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref)
-{
- $Exception := null;
- call System.Threading.ParameterizedThreadStart.Invoke$System.Object(this, obj$in);
-}
-
-
-
-procedure {:extern} System.Threading.ParameterizedThreadStart.Invoke$System.Object(this: Ref, obj$in: Ref);
-
-
-
-procedure {:inline 1} System.Threading.Thread.#ctor$System.Threading.ThreadStart(this: Ref, start$in: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.#ctor$System.Threading.ThreadStart(this: Ref, start$in: Ref)
-{
- assume $ThreadDelegate(this) == start$in;
-}
-
-
-
-procedure {:inline 1} System.Threading.Thread.Start(this: Ref);
-
-
-
-implementation {:inline 1} System.Threading.Thread.Start(this: Ref)
-{
- call {:async} Wrapper_System.Threading.ThreadStart.Invoke($ThreadDelegate(this));
-}
-
-
-
-procedure Wrapper_System.Threading.ThreadStart.Invoke(this: Ref);
-
-
-
-implementation Wrapper_System.Threading.ThreadStart.Invoke(this: Ref)
-{
- $Exception := null;
- call System.Threading.ThreadStart.Invoke(this);
-}
-
-
-
-procedure {:extern} System.Threading.ThreadStart.Invoke(this: Ref);
-
-
-
-procedure {:inline 1} DelegateAdd(a: Ref, b: Ref) returns (c: Ref);
-
-
-
-implementation {:inline 1} DelegateAdd(a: Ref, b: Ref) returns (c: Ref)
-{
- var d: Delegate;
-
- if (a == null)
- {
- c := b;
- }
- else if (b == null)
- {
- c := a;
- }
- else
- {
- call c := Alloc();
- assume $RefToDelegate(c) == $RefToDelegate(a) || $RefToDelegate(c) == $RefToDelegate(b);
- assume $RefToDelegateMultiset(c) == MultisetPlus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b));
- }
-}
-
-
-
-procedure {:inline 1} DelegateRemove(a: Ref, b: Ref) returns (c: Ref);
-
-
-
-implementation {:inline 1} DelegateRemove(a: Ref, b: Ref) returns (c: Ref)
-{
- var d: Delegate;
-
- if (a == null)
- {
- c := null;
- }
- else if (b == null)
- {
- c := a;
- }
- else if (MultisetMinus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b)) == MultisetEmpty)
- {
- c := null;
- }
- else
- {
- call c := Alloc();
- assume $RefToDelegateMultiset(c) == MultisetMinus($RefToDelegateMultiset(a), $RefToDelegateMultiset(b));
- assume $RefToDelegateMultiset(c)[$RefToDelegate(c)] > 0;
- }
-}
-
-
-
-procedure {:inline 1} DelegateCreate(d: Delegate) returns (c: Ref);
-
-
-
-implementation {:inline 1} DelegateCreate(d: Delegate) returns (c: Ref)
-{
- call c := Alloc();
- assume $RefToDelegate(c) == d;
- assume $RefToDelegateMultiset(c) == MultisetSingleton(d);
-}
-
-
-
-procedure {:inline 1} System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-
-
-
-procedure {:inline 1} System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool);
-
-
-
-implementation System.String.op_Equality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool)
-{
- $result := a$in == b$in;
-}
-
-
-
-implementation System.String.op_Inequality$System.String$System.String(a$in: Ref, b$in: Ref) returns ($result: bool)
-{
- $result := a$in != b$in;
-}
-
-
-
-var $ArrayContents: [Ref][int]Union;
-
-function $ArrayLength(Ref) : int;
-
-type {:datatype} Delegate;
-
-type DelegateMultiset = [Delegate]int;
-
-const unique MultisetEmpty: DelegateMultiset;
-
-function {:inline true} MultisetSingleton(x: Delegate) : DelegateMultiset
-{
- MultisetEmpty[x := 1]
-}
-
-function {:inline true} MultisetPlus(x: DelegateMultiset, y: DelegateMultiset) : DelegateMultiset
-{
- DelegateMapadd(x, y)
-}
-
-function {:inline true} MultisetMinus(x: DelegateMultiset, y: DelegateMultiset) : DelegateMultiset
-{
- DelegateMapiteint(DelegateMapgt(x, y), DelegateMapsub(x, y), DelegateMapconstint(0))
-}
-
-type Field;
-
-type Union;
-
-const unique $DefaultHeapValue: Union;
-
-type Ref;
-
-const unique null: Ref;
-
-type {:datatype} Type;
-
-type Real;
-
-const unique $DefaultReal: Real;
-
-procedure {:inline 1} $BoxFromBool(b: bool) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromBool(b: bool) returns (r: Ref)
-{
- call r := Alloc();
- assume $BoxedValue(r) == Bool2Union(b);
-}
-
-
-
-procedure {:inline 1} $BoxFromInt(i: int) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromInt(i: int) returns (r: Ref)
-{
- call r := Alloc();
- assume $BoxedValue(r) == Int2Union(i);
-}
-
-
-
-procedure {:inline 1} $BoxFromReal(r: Real) returns (rf: Ref);
-
-
-
-implementation {:inline 1} $BoxFromReal(r: Real) returns (rf: Ref)
-{
- call rf := Alloc();
- assume $BoxedValue(rf) == Real2Union(r);
-}
-
-
-
-procedure {:inline 1} $BoxFromStruct(s: Ref) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromStruct(s: Ref) returns (r: Ref)
-{
- call r := Alloc();
- assume $BoxedValue(r) == Struct2Union(s);
-}
-
-
-
-procedure {:inline 1} $BoxFromUnion(u: Union) returns (r: Ref);
-
-
-
-implementation {:inline 1} $BoxFromUnion(u: Union) returns (r: Ref)
-{
- if (IsRef(u))
- {
- r := Union2Ref(u);
- }
- else
- {
- call r := Alloc();
- assume $BoxedValue(r) == u;
- }
-}
-
-
-
-function $BoxedValue(r: Ref) : Union;
-
-function {:inline true} $Unbox2Bool(r: Ref) : bool
-{
- Union2Bool($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Int(r: Ref) : int
-{
- Union2Int($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Real(r: Ref) : Real
-{
- Union2Real($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Struct(r: Ref) : Ref
-{
- Union2Struct($BoxedValue(r))
-}
-
-function {:inline true} $Unbox2Union(r: Ref) : Union
-{
- $BoxedValue(r)
-}
-
-function Union2Bool(u: Union) : bool;
-
-function Union2Int(u: Union) : int;
-
-function Union2Ref(u: Union) : Ref;
-
-function Union2Real(u: Union) : Real;
-
-function Union2Struct(u: Union) : Ref;
-
-function Bool2Union(boolValue: bool) : Union;
-
-function Int2Union(intValue: int) : Union;
-
-function Ref2Union(refValue: Ref) : Union;
-
-function Real2Union(realValue: Real) : Union;
-
-function Struct2Union(structValue: Ref) : Union;
-
-function {:inline true} Union2Union(u: Union) : Union
-{
- u
-}
-
-function Int2Real(int) : Real;
-
-function Real2Int(Real) : int;
-
-function RealPlus(Real, Real) : Real;
-
-function RealMinus(Real, Real) : Real;
-
-function RealTimes(Real, Real) : Real;
-
-function RealDivide(Real, Real) : Real;
-
-function RealModulus(Real, Real) : Real;
-
-function RealLessThan(Real, Real) : bool;
-
-function RealLessThanOrEqual(Real, Real) : bool;
-
-function RealGreaterThan(Real, Real) : bool;
-
-function RealGreaterThanOrEqual(Real, Real) : bool;
-
-function BitwiseAnd(int, int) : int;
-
-function BitwiseOr(int, int) : int;
-
-function BitwiseExclusiveOr(int, int) : int;
-
-function BitwiseNegation(int) : int;
-
-function RightShift(int, int) : int;
-
-function LeftShift(int, int) : int;
-
-function $DynamicType(Ref) : Type;
-
-function $TypeOf(Type) : Ref;
-
-function $As(Ref, Type) : Ref;
-
-function $Subtype(Type, Type) : bool;
-
-function $DisjointSubtree(Type, Type) : bool;
-
-var $Alloc: [Ref]bool;
-
-function {:builtin "MapImp"} $allocImp([Ref]bool, [Ref]bool) : [Ref]bool;
-
-function {:builtin "MapConst"} $allocConstBool(bool) : [Ref]bool;
-
-function $RefToDelegate(Ref) : Delegate;
-
-function $RefToDelegateMultiset(Ref) : DelegateMultiset;
-
-function {:constructor} $RefToDelegateMultisetCons($Method: int, $Receiver: Ref, $TypeParameters: Type) : Delegate;
-
-var {:thread_local} $Exception: Ref;
-
-
-
-
-
-function {:constructor} T$RegressionTestInput.StructContainingStruct() : Type;
-
-function {:constructor} {:extern} T$System.ValueType() : Type;
-
-function {:constructor} {:extern} T$System.Object() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$System.Object(), $T) } $Subtype(T$System.Object(), $T) <==> T$System.Object() == $T);
-
-axiom (forall $T: Type :: { $Subtype(T$System.ValueType(), $T) } $Subtype(T$System.ValueType(), $T) <==> T$System.ValueType() == $T || $Subtype(T$System.Object(), $T));
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.StructContainingStruct(), $T) } $Subtype(T$RegressionTestInput.StructContainingStruct(), $T) <==> T$RegressionTestInput.StructContainingStruct() == $T || $Subtype(T$System.ValueType(), $T));
-
-procedure RegressionTestInput.StructContainingStruct.#default_ctor($this: Ref);
-
-
-
-var F$RegressionTestInput.StructContainingStruct.d: [Ref]Real;
-
-procedure RegressionTestInput.S.#default_ctor($this: Ref);
-
-
-
-function {:constructor} T$RegressionTestInput.S() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.S(), $T) } $Subtype(T$RegressionTestInput.S(), $T) <==> T$RegressionTestInput.S() == $T || $Subtype(T$System.ValueType(), $T));
-
-var F$RegressionTestInput.StructContainingStruct.s: [Ref]Ref;
-
-implementation {:inline 1} RegressionTestInput.StructContainingStruct.#default_ctor($this: Ref)
-{
- var $tmp0: Ref;
-
- F$RegressionTestInput.StructContainingStruct.d[$this] := $DefaultReal;
- call $tmp0 := Alloc();
- call RegressionTestInput.S.#default_ctor($tmp0);
- assume $DynamicType($tmp0) == T$RegressionTestInput.S();
- F$RegressionTestInput.StructContainingStruct.s[$this] := $tmp0;
-}
-
-
-
-procedure RegressionTestInput.StructContainingStruct.#copy_ctor(this: Ref) returns (other: Ref);
- free ensures this != other;
-
-
-
-procedure RegressionTestInput.S.#copy_ctor(this: Ref) returns (other: Ref);
- free ensures this != other;
-
-
-
-implementation {:inline 1} RegressionTestInput.StructContainingStruct.#copy_ctor(this: Ref) returns (other: Ref)
-{
- var $tmp1: Ref;
-
- call other := Alloc();
- assume $DynamicType(other) == T$RegressionTestInput.StructContainingStruct();
- F$RegressionTestInput.StructContainingStruct.d[other] := F$RegressionTestInput.StructContainingStruct.d[this];
- call $tmp1 := RegressionTestInput.S.#copy_ctor(F$RegressionTestInput.StructContainingStruct.s[this]);
- F$RegressionTestInput.StructContainingStruct.s[other] := $tmp1;
-}
-
-
-
-procedure RegressionTestInput.StructContainingStruct.ReturnCopy$RegressionTestInput.StructContainingStruct($this: Ref, s$in: Ref) returns ($result: Ref);
- free ensures $result == null || $Alloc[$result];
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.StructContainingStruct.ReturnCopy$RegressionTestInput.StructContainingStruct($this: Ref, s$in: Ref) returns ($result: Ref)
-{
- var s: Ref;
- var t_Ref: Ref;
- var $localExc: Ref;
- var $label: int;
-
- s := s$in;
- assume {:breadcrumb 0} true;
- call t_Ref := RegressionTestInput.StructContainingStruct.#copy_ctor(s);
- $result := t_Ref;
- return;
-}
-
-
-
-function {:constructor} T$RegressionTestInput.RealNumbers() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.RealNumbers(), $T) } $Subtype(T$RegressionTestInput.RealNumbers(), $T) <==> T$RegressionTestInput.RealNumbers() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.RealNumbers.WriteDouble$System.Double($this: Ref, d$in: Real);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Console.WriteLine$System.Double(value$in: Real);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RealNumbers.WriteDouble$System.Double($this: Ref, d$in: Real)
-{
- var d: Real;
- var $localExc: Ref;
- var $label: int;
-
- d := d$in;
- assume {:breadcrumb 1} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 162} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 162} true;
- call System.Console.WriteLine$System.Double(d);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure RegressionTestInput.RealNumbers.ObjectToDouble$System.Object($this: Ref, o$in: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RealNumbers.ObjectToDouble$System.Object($this: Ref, o$in: Ref)
-{
- var o: Ref;
- var $localExc: Ref;
- var $label: int;
-
- o := o$in;
- assume {:breadcrumb 2} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 165} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 165} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, $Unbox2Real(o));
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure RegressionTestInput.RealNumbers.RealOperations($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-const unique $real_literal_3_0: Real;
-
-const unique $real_literal_4_0: Real;
-
-implementation RegressionTestInput.RealNumbers.RealOperations($this: Ref)
-{
- var d_Real: Real;
- var d2_Real: Real;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 3} true;
- d_Real := $real_literal_3_0;
- d2_Real := $real_literal_4_0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 170} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 170} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealPlus(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 171} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 171} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealMinus(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 172} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 172} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealTimes(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 173} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 173} true;
- call RegressionTestInput.RealNumbers.WriteDouble$System.Double($this, RealDivide(d_Real, d2_Real));
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure RegressionTestInput.RealNumbers.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Object.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RealNumbers.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 4} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.RealNumbers.#cctor();
-
-
-
-implementation T$RegressionTestInput.RealNumbers.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), $T) } $Subtype(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), $T) <==> T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: [Ref]int;
-
-var F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y: [Ref]int;
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 5} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 130} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 130} true;
- assume $this != null;
- F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y[$this] := F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x[$this];
-}
-
-
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x[$this] := 0;
- F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y[$this] := 0;
- assume {:breadcrumb 6} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor();
-
-
-
-implementation T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.CreateStruct() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.CreateStruct(), $T) } $Subtype(T$RegressionTestInput.CreateStruct(), $T) <==> T$RegressionTestInput.CreateStruct() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.CreateStruct.Create($this: Ref) returns ($result: Ref);
- free ensures $result == null || $Alloc[$result];
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-var F$RegressionTestInput.S.x: [Ref]int;
-
-var F$RegressionTestInput.S.b: [Ref]bool;
-
-implementation RegressionTestInput.CreateStruct.Create($this: Ref) returns ($result: Ref)
-{
- var s_Ref: Ref;
- var $tmp0: Ref;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 7} true;
- call $tmp0 := Alloc();
- call RegressionTestInput.S.#default_ctor($tmp0);
- assume $DynamicType($tmp0) == T$RegressionTestInput.S();
- s_Ref := $tmp0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 142} true;
- assume s_Ref != null;
- assert F$RegressionTestInput.S.x[s_Ref] == 0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 143} true;
- assume s_Ref != null;
- assert !F$RegressionTestInput.S.b[s_Ref];
- $result := s_Ref;
- return;
-}
-
-
-
-procedure RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S($this: Ref, s$in: Ref) returns ($result: Ref);
- free ensures $result == null || $Alloc[$result];
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S($this: Ref, s$in: Ref) returns ($result: Ref)
-{
- var s: Ref;
- var $localExc: Ref;
- var $label: int;
-
- s := s$in;
- assume {:breadcrumb 8} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 147} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 147} true;
- F$RegressionTestInput.S.x[s] := 3;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 148} true;
- assume s != null;
- assert F$RegressionTestInput.S.x[s] == 3;
- $result := s;
- return;
-}
-
-
-
-procedure RegressionTestInput.CreateStruct.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.CreateStruct.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 9} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.CreateStruct.#cctor();
-
-
-
-implementation T$RegressionTestInput.CreateStruct.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.ClassWithArrayTypes() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.ClassWithArrayTypes(), $T) } $Subtype(T$RegressionTestInput.ClassWithArrayTypes(), $T) <==> T$RegressionTestInput.ClassWithArrayTypes() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.ClassWithArrayTypes.s: Ref;
-
-var F$RegressionTestInput.ClassWithArrayTypes.a: [Ref]Ref;
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main1();
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main1()
-{
- var s_Ref: Ref;
- var $tmp0: Ref;
- var t_Ref: Ref;
- var $tmp1: Ref;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 10} true;
- call $tmp0 := Alloc();
- assume $ArrayLength($tmp0) == 1 * 5;
- s_Ref := $tmp0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 88} true;
- assume s_Ref != null;
- assert Union2Int($ArrayContents[s_Ref][0]) == 2;
- call $tmp1 := Alloc();
- assume $ArrayLength($tmp1) == 1 * 4;
- t_Ref := $tmp1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 92} true;
- assume t_Ref != null;
- assert Union2Int($ArrayContents[t_Ref][0]) == 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 94} true;
- assume s_Ref != null;
- assert Union2Int($ArrayContents[s_Ref][0]) == 2;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main2();
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main2()
-{
- var $tmp0: Ref;
- var t_Ref: Ref;
- var $tmp1: Ref;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 11} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 100} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 100} true;
- call $tmp0 := Alloc();
- assume $ArrayLength($tmp0) == 1 * 5;
- F$RegressionTestInput.ClassWithArrayTypes.s := $tmp0;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 101} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 101} true;
- $ArrayContents := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s][0 := Int2Union(2)]];
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 102} true;
- assume F$RegressionTestInput.ClassWithArrayTypes.s != null;
- assert Union2Int($ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s][0]) == 2;
- call $tmp1 := Alloc();
- assume $ArrayLength($tmp1) == 1 * 4;
- t_Ref := $tmp1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 106} true;
- assume t_Ref != null;
- assert Union2Int($ArrayContents[t_Ref][0]) == 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 108} true;
- assume F$RegressionTestInput.ClassWithArrayTypes.s != null;
- assert Union2Int($ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.s][0]) == 2;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32($this: Ref, x$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32($this: Ref, x$in: int)
-{
- var x: int;
- var $tmp0: Ref;
- var $tmp1: Ref;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 12} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 114} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 114} true;
- assume $this != null;
- $ArrayContents := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.a[$this] := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.a[$this]][x := Int2Union(42)]];
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 115} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 115} true;
- assume $this != null;
- $ArrayContents := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.a[$this] := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.a[$this]][x + 1 := Int2Union(43)]];
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 116} true;
- assume $this != null;
- $tmp0 := F$RegressionTestInput.ClassWithArrayTypes.a[$this];
- assume $tmp0 != null;
- assume $this != null;
- $tmp1 := F$RegressionTestInput.ClassWithArrayTypes.a[$this];
- assume $tmp1 != null;
- assert Union2Int($ArrayContents[$tmp0][x + 1]) == Union2Int($ArrayContents[$tmp1][x]) + 1;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array($this: Ref, xs$in: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array($this: Ref, xs$in: Ref)
-{
- var xs: Ref;
- var $localExc: Ref;
- var $label: int;
-
- xs := xs$in;
- assume {:breadcrumb 13} true;
- if (xs != null)
- {
- }
- else
- {
- }
-
- if ((if xs != null then $ArrayLength(xs) > 0 else false))
- {
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 121} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 121} true;
- assume $this != null;
- assume xs != null;
- $ArrayContents := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.a[$this] := $ArrayContents[F$RegressionTestInput.ClassWithArrayTypes.a[$this]][0 := Int2Union(Union2Int($ArrayContents[xs][0]))]];
- }
- else
- {
- }
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- F$RegressionTestInput.ClassWithArrayTypes.a[$this] := null;
- assume {:breadcrumb 14} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.ClassWithArrayTypes.#cctor();
-
-
-
-implementation T$RegressionTestInput.ClassWithArrayTypes.#cctor()
-{
- F$RegressionTestInput.ClassWithArrayTypes.s := null;
-}
-
-
-
-function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T: Type) : Type;
-
-axiom (forall T: Type, $T: Type :: { $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), $T) } $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), $T) <==> T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T) == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.x: [Ref]int;
-
-procedure RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.x[$this] := 0;
- assume {:breadcrumb 15} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#cctor();
-
-
-
-implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.BitwiseOperations() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.BitwiseOperations(), $T) } $Subtype(T$RegressionTestInput.BitwiseOperations(), $T) <==> T$RegressionTestInput.BitwiseOperations() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.BitwiseOperations.BitwiseAnd$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.BitwiseAnd$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 16} true;
- $result := BitwiseAnd(x, y);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.BitwiseOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.BitwiseOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 17} true;
- $result := BitwiseOr(x, y);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.ExclusiveOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.ExclusiveOr$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 18} true;
- $result := BitwiseExclusiveOr(x, y);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.BitwiseNegation$System.Int32($this: Ref, x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.BitwiseNegation$System.Int32($this: Ref, x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 19} true;
- $result := BitwiseNegation(x);
- return;
-}
-
-
-
-procedure RegressionTestInput.BitwiseOperations.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.BitwiseOperations.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 20} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.BitwiseOperations.#cctor();
-
-
-
-implementation T$RegressionTestInput.BitwiseOperations.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.AsyncAttribute() : Type;
-
-function {:constructor} {:extern} T$System.Attribute() : Type;
-
-function {:constructor} {:extern} T$System.Runtime.InteropServices._Attribute() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$System.Runtime.InteropServices._Attribute(), $T) } $Subtype(T$System.Runtime.InteropServices._Attribute(), $T) <==> T$System.Runtime.InteropServices._Attribute() == $T);
-
-axiom (forall $T: Type :: { $Subtype(T$System.Attribute(), $T) } $Subtype(T$System.Attribute(), $T) <==> T$System.Attribute() == $T || $Subtype(T$System.Object(), $T) || $Subtype(T$System.Runtime.InteropServices._Attribute(), $T));
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.AsyncAttribute(), $T) } $Subtype(T$RegressionTestInput.AsyncAttribute(), $T) <==> T$RegressionTestInput.AsyncAttribute() == $T || $Subtype(T$System.Attribute(), $T));
-
-procedure RegressionTestInput.AsyncAttribute.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Attribute.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.AsyncAttribute.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 21} true;
- call System.Attribute.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.AsyncAttribute.#cctor();
-
-
-
-implementation T$RegressionTestInput.AsyncAttribute.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.RefParameters() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.RefParameters(), $T) } $Subtype(T$RegressionTestInput.RefParameters(), $T) <==> T$RegressionTestInput.RefParameters() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int)
-{
- var $localExc: Ref;
- var $label: int;
-
- x$out := x$in;
- assume {:breadcrumb 22} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 156} true;
- x$out := x$out + 1;
-}
-
-
-
-procedure RegressionTestInput.RefParameters.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.RefParameters.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 23} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.RefParameters.#cctor();
-
-
-
-implementation T$RegressionTestInput.RefParameters.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.NestedGeneric() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.NestedGeneric(), $T) } $Subtype(T$RegressionTestInput.NestedGeneric(), $T) <==> T$RegressionTestInput.NestedGeneric() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.NestedGeneric.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.NestedGeneric.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 24} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-function {:constructor} T$RegressionTestInput.NestedGeneric.C() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.NestedGeneric.C(), $T) } $Subtype(T$RegressionTestInput.NestedGeneric.C(), $T) <==> T$RegressionTestInput.NestedGeneric.C() == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.NestedGeneric.C.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.NestedGeneric.C.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 25} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-function {:constructor} T$RegressionTestInput.NestedGeneric.C.G`1(T: Type) : Type;
-
-axiom (forall T: Type, $T: Type :: { $Subtype(T$RegressionTestInput.NestedGeneric.C.G`1(T), $T) } $Subtype(T$RegressionTestInput.NestedGeneric.C.G`1(T), $T) <==> T$RegressionTestInput.NestedGeneric.C.G`1(T) == $T || $Subtype(T$System.Object(), $T));
-
-procedure RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this: Ref, x$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-procedure {:extern} System.Activator.CreateInstance``1(T: Type) returns ($result: Union);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this: Ref, x$in: int)
-{
- var x: int;
- var CS$0$0000_Union: Union;
- var $tmp0: Union;
- var $tmp1: Union;
- var $tmp2: Ref;
- var y_Union: Union;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 26} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 187} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 187} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- CS$0$0000_Union := $DefaultHeapValue;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 188} true;
- call $tmp2 := $BoxFromUnion(CS$0$0000_Union);
- if ($tmp2 != null)
- {
- }
- else
- {
- call $tmp1 := System.Activator.CreateInstance``1(T#T$RegressionTestInput.NestedGeneric.C.G`1($DynamicType($this)));
- $tmp0 := Union2Union($tmp1);
- if ($Exception != null)
- {
- return;
- }
- }
-
- y_Union := (if $tmp2 != null then $DefaultHeapValue else $tmp0);
-}
-
-
-
-procedure T$RegressionTestInput.NestedGeneric.C.G`1.#cctor();
-
-
-
-implementation T$RegressionTestInput.NestedGeneric.C.G`1.#cctor()
-{
-}
-
-
-
-procedure T$RegressionTestInput.NestedGeneric.C.#cctor();
-
-
-
-implementation T$RegressionTestInput.NestedGeneric.C.#cctor()
-{
-}
-
-
-
-procedure T$RegressionTestInput.NestedGeneric.#cctor();
-
-
-
-implementation T$RegressionTestInput.NestedGeneric.#cctor()
-{
-}
-
-
-
-implementation {:inline 1} RegressionTestInput.S.#default_ctor($this: Ref)
-{
- F$RegressionTestInput.S.x[$this] := 0;
- F$RegressionTestInput.S.b[$this] := false;
-}
-
-
-
-implementation {:inline 1} RegressionTestInput.S.#copy_ctor(this: Ref) returns (other: Ref)
-{
- call other := Alloc();
- assume $DynamicType(other) == T$RegressionTestInput.S();
- F$RegressionTestInput.S.x[other] := F$RegressionTestInput.S.x[this];
- F$RegressionTestInput.S.b[other] := F$RegressionTestInput.S.b[this];
-}
-
-
-
-function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), $T) } $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), $T) <==> T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.x: [Ref]int;
-
-procedure RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.x[$this] := 0;
- assume {:breadcrumb 27} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#cctor();
-
-
-
-implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#cctor()
-{
-}
-
-
-
-function {:constructor} T$RegressionTestInput.Class0() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.Class0(), $T) } $Subtype(T$RegressionTestInput.Class0(), $T) <==> T$RegressionTestInput.Class0() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.Class0.StaticInt: int;
-
-procedure RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 28} true;
- $result := x + 1;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32($this: Ref, x$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32($this: Ref, x$in: int)
-{
- var x: int;
- var y_int: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 29} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 21} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 21} true;
- x := 3;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 21} true;
- y_int := 3 + 5 / x;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 22} true;
- if (x != 3)
- {
- }
- else
- {
- }
-
- assert (if x != 3 then false else !(y_int > 8));
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 23} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 23} true;
- F$RegressionTestInput.Class0.StaticInt := y_int;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 24} true;
- assert y_int == F$RegressionTestInput.Class0.StaticInt;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 30} true;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Boolean($this: Ref, b$in: bool);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Boolean($this: Ref, b$in: bool)
-{
- var b: bool;
- var $localExc: Ref;
- var $label: int;
-
- b := b$in;
- assume {:breadcrumb 31} true;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0($this: Ref, c$in: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0($this: Ref, c$in: Ref)
-{
- var c: Ref;
- var $localExc: Ref;
- var $label: int;
-
- c := c$in;
- assume {:breadcrumb 32} true;
-}
-
-
-
-procedure RegressionTestInput.Class0.NonVoid($this: Ref) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.NonVoid($this: Ref) returns ($result: int)
-{
- var $tmp0: int;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 33} true;
- call $tmp0 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
- if ($Exception != null)
- {
- return;
- }
-
- $result := 3 + F$RegressionTestInput.Class0.StaticInt + $tmp0;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.OutParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.OutParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int)
-{
- var $localExc: Ref;
- var $label: int;
-
- x$out := x$in;
- assume {:breadcrumb 34} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 37} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 37} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 37} true;
- x$out := 3 + F$RegressionTestInput.Class0.StaticInt;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.RefParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.RefParam$System.Int32$($this: Ref, x$in: int) returns (x$out: int, $result: int)
-{
- var $localExc: Ref;
- var $label: int;
-
- x$out := x$in;
- assume {:breadcrumb 35} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 42} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 42} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 42} true;
- x$out := x$out + 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 43} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 43} true;
- F$RegressionTestInput.Class0.StaticInt := x$out;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.AssignToInParam$System.Int32($this: Ref, x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.AssignToInParam$System.Int32($this: Ref, x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 36} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 48} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 48} true;
- x := x + 1;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 49} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 49} true;
- F$RegressionTestInput.Class0.StaticInt := x;
- $result := x;
- return;
-}
-
-
-
-procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32($this: Ref, x$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32($this: Ref, x$in: int) returns ($result: int)
-{
- var x: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- assume {:breadcrumb 37} true;
- $result := x;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32($this: Ref, y$in: int) returns ($result: int);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32($this: Ref, y$in: int) returns ($result: int)
-{
- var y: int;
- var $tmp0: int;
- var $localExc: Ref;
- var $label: int;
-
- y := y$in;
- assume {:breadcrumb 38} true;
- call {:async} $tmp0 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32($this, y);
- if ($Exception != null)
- {
- return;
- }
-
- $result := $tmp0;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.#ctor($this: Ref);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.Class0.#ctor($this: Ref)
-{
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 39} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.Class0.#cctor();
-
-
-
-implementation T$RegressionTestInput.Class0.#cctor()
-{
- F$RegressionTestInput.Class0.StaticInt := 0;
-}
-
-
-
-function {:constructor} T$RegressionTestInput.ClassWithBoolTypes() : Type;
-
-axiom (forall $T: Type :: { $Subtype(T$RegressionTestInput.ClassWithBoolTypes(), $T) } $Subtype(T$RegressionTestInput.ClassWithBoolTypes(), $T) <==> T$RegressionTestInput.ClassWithBoolTypes() == $T || $Subtype(T$System.Object(), $T));
-
-var F$RegressionTestInput.ClassWithBoolTypes.staticB: bool;
-
-var F$RegressionTestInput.ClassWithBoolTypes.b: [Ref]bool;
-
-procedure RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool)
-{
- var x: int;
- var y: int;
- var $localExc: Ref;
- var $label: int;
-
- x := x$in;
- y := y$in;
- assume {:breadcrumb 40} true;
- $result := x < y;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean($this: Ref, z$in: bool);
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean($this: Ref, z$in: bool)
-{
- var z: bool;
- var $localExc: Ref;
- var $label: int;
-
- z := z$in;
- F$RegressionTestInput.ClassWithBoolTypes.b[$this] := false;
- assume {:breadcrumb 41} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 72} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 72} true;
- call System.Object.#ctor($this);
- if ($Exception != null)
- {
- return;
- }
-
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 73} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 73} true;
- F$RegressionTestInput.ClassWithBoolTypes.b[$this] := z;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 74} true;
- if (z)
- {
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 74} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 74} true;
- F$RegressionTestInput.ClassWithBoolTypes.staticB := z;
- }
- else
- {
- }
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.Main();
- free ensures $allocImp(old($Alloc), $Alloc) == $allocConstBool(true);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.Main()
-{
- var $tmp0: bool;
- var $localExc: Ref;
- var $label: int;
-
- assume {:breadcrumb 42} true;
- assert {:first} {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 78} true;
- assert {:sourceFile "C:\dev\Boogie\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 78} true;
- call $tmp0 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
- if ($Exception != null)
- {
- return;
- }
-}
-
-
-
-procedure T$RegressionTestInput.ClassWithBoolTypes.#cctor();
-
-
-
-implementation T$RegressionTestInput.ClassWithBoolTypes.#cctor()
-{
- F$RegressionTestInput.ClassWithBoolTypes.staticB := false;
-}
-
-
diff --git a/BCT/RegressionTests/TranslationTest/TranslationTest.csproj b/BCT/RegressionTests/TranslationTest/TranslationTest.csproj
deleted file mode 100644
index 446c23b2..00000000
--- a/BCT/RegressionTests/TranslationTest/TranslationTest.csproj
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>
- </ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{A112AFBA-D6F6-44A4-A683-C3D458A68D84}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>TranslationTest</RootNamespace>
- <AssemblyName>TranslationTest</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Core">
- <HintPath>..\..\Binaries\Core.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
- <Reference Include="System" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="UnitTest0.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\..\..\CCICodePlex\Ast\Metadata\Sources\MetadataHelper\MetadataHelper.csproj">
- <Project>{4A34A3C5-6176-49D7-A4C5-B2B671247F8F}</Project>
- <Name>MetadataHelper</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodePlex\Ast\Metadata\Sources\PeReader\PeReader.csproj">
- <Project>{34B9A0CE-DF18-4CBC-8F7A-90C2B74338D5}</Project>
- <Name>PeReader</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodePlex\Ast\Sources\CodeModel\CodeModel.csproj">
- <Project>{035FEA7F-0D36-4AE4-B694-EC45191B9AF2}</Project>
- <Name>CodeModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodePlex\Ast\Sources\MutableCodeModel\MutableCodeModel.csproj">
- <Project>{319E150C-8F33-49E7-81CA-30F02F9BA90A}</Project>
- <Name>MutableCodeModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\..\..\CCICodePlex\Ast\Sources\NewILToCodeModel\NewILToCodeModel.csproj">
- <Project>{A555D4CB-F16F-4049-A8CF-180B8A05C755}</Project>
- <Name>NewILToCodeModel</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\BytecodeTranslator\BytecodeTranslator.csproj">
- <Project>{9C8E4D74-0251-479D-ADAC-A9A469977301}</Project>
- <Name>BytecodeTranslator</Name>
- </ProjectReference>
- <ProjectReference Include="..\RegressionTestInput\RegressionTestInput.csproj">
- <Project>{3D13D2CC-6387-46FA-BDC2-4BEEFC460118}</Project>
- <Name>RegressionTestInput</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="SplitFieldsHeapInput.txt" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="GeneralHeapInput.txt" />
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/BCT/RegressionTests/TranslationTest/UnitTest0.cs b/BCT/RegressionTests/TranslationTest/UnitTest0.cs
deleted file mode 100644
index 62ce9155..00000000
--- a/BCT/RegressionTests/TranslationTest/UnitTest0.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using System;
-using System.Text;
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.IO;
-using Microsoft.Cci;
-using Microsoft.Cci.MetadataReader;
-using Microsoft.Cci.MutableCodeModel;
-using Microsoft.Cci.Contracts;
-using Microsoft.Cci.ILToCodeModel;
-using BytecodeTranslator;
-
-namespace TranslationTest {
- /// <summary>
- /// Summary description for UnitTest0
- /// </summary>
- [TestClass]
- public class UnitTest0 {
- public UnitTest0() {
- //
- // TODO: Add constructor logic here
- //
- }
-
- private TestContext testContextInstance;
-
- /// <summary>
- ///Gets or sets the test context which provides
- ///information about and functionality for the current test run.
- ///</summary>
- public TestContext TestContext {
- get {
- return testContextInstance;
- }
- set {
- testContextInstance = value;
- }
- }
-
- #region Additional test attributes
- //
- // You can use the following additional attributes as you write your tests:
- //
- // Use ClassInitialize to run code before running the first test in the class
- // [ClassInitialize()]
- // public static void MyClassInitialize(TestContext testContext) { }
- //
- // Use ClassCleanup to run code after all tests in a class have run
- // [ClassCleanup()]
- // public static void MyClassCleanup() { }
- //
- // Use TestInitialize to run code before running each test
- // [TestInitialize()]
- // public void MyTestInitialize() { }
- //
- // Use TestCleanup to run code after each test has run
- // [TestCleanup()]
- // public void MyTestCleanup() { }
- //
- #endregion
-
- private string ExecuteTest(string assemblyName, HeapFactory heapFactory) {
- var options = new Options();
- options.monotonicHeap = true;
- options.dereference = Options.Dereference.Assume;
- BCT.TranslateAssemblyAndWriteOutput(new List<string> { assemblyName }, heapFactory, options, null, false);
- var fileName = Path.ChangeExtension(assemblyName, "bpl");
- var s = File.ReadAllText(fileName);
- return s;
- }
-
- [TestMethod]
- public void SplitFieldsHeap() {
- string dir = TestContext.DeploymentDirectory;
- var fullPath = Path.Combine(dir, "RegressionTestInput.dll");
- Stream resource = typeof(UnitTest0).Assembly.GetManifestResourceStream("TranslationTest.SplitFieldsHeapInput.txt");
- StreamReader reader = new StreamReader(resource);
- string expected = reader.ReadToEnd();
- var result = ExecuteTest(fullPath, new SplitFieldsHeap());
- if (result != expected) {
- string resultFile = Path.GetFullPath("SplitFieldsHeapOutput.txt");
- File.WriteAllText(resultFile, result);
- var msg = String.Format("Output didn't match: SplitFieldsHeapInput.txt \"{0}\"", resultFile);
- Assert.Fail(msg);
- }
- }
-
- [TestMethod]
- public void GeneralHeap() {
- string dir = TestContext.DeploymentDirectory;
- var fullPath = Path.Combine(dir, "RegressionTestInput.dll");
- Stream resource = typeof(UnitTest0).Assembly.GetManifestResourceStream("TranslationTest.GeneralHeapInput.txt");
- StreamReader reader = new StreamReader(resource);
- string expected = reader.ReadToEnd();
- var result = ExecuteTest(fullPath, new GeneralHeap());
- if (result != expected) {
- string resultFile = Path.GetFullPath("GeneralHeapOutput.txt");
- File.WriteAllText(resultFile, result);
- var msg = String.Format("Output didn't match: GeneralHeapInput.txt \"{0}\"", resultFile);
- Assert.Fail(msg);
- }
- }
-
- }
-}
- \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/codecounter.sln b/BCT/Samples/CodeCounter/codecounter.sln
deleted file mode 100644
index 8869bd4f..00000000
--- a/BCT/Samples/CodeCounter/codecounter.sln
+++ /dev/null
@@ -1,51 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCounter", "console\CodeCounter.csproj", "{7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "codecounterlibrary", "library\codecounterlibrary.csproj", "{A055DCC3-3C6A-123C-82F8-AD10A8B313F7}"
-EndProject
-Global
- GlobalSection(TeamFoundationVersionControl) = preSolution
- SccNumberOfProjects = 4
- SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs09
- SccLocalPath0 = .
- SccProjectUniqueName1 = console\\CodeCounter.csproj
- SccProjectName1 = console
- SccLocalPath1 = console
- SccProjectUniqueName2 = library\\codecounterlibrary.csproj
- SccProjectName2 = library
- SccLocalPath2 = library
- SccProjectUniqueName3 = Extensions\\vbcounter\\VBCodeCountingLogic\\VBCodeCountingLogic.vbproj
- SccProjectName3 = Extensions/vbcounter/VBCodeCountingLogic
- SccLocalPath3 = Extensions\\vbcounter\\VBCodeCountingLogic
- EndGlobalSection
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- DEBUG ALL|Any CPU = DEBUG ALL|Any CPU
- Debug|Any CPU = Debug|Any CPU
- RELEASE ALL|Any CPU = RELEASE ALL|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.DEBUG ALL|Any CPU.ActiveCfg = Debug|Any CPU
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.DEBUG ALL|Any CPU.Build.0 = Debug|Any CPU
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.RELEASE ALL|Any CPU.ActiveCfg = Release|Any CPU
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.RELEASE ALL|Any CPU.Build.0 = Release|Any CPU
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Release|Any CPU.Build.0 = Release|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.DEBUG ALL|Any CPU.ActiveCfg = DEBUG ALL|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.DEBUG ALL|Any CPU.Build.0 = DEBUG ALL|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.RELEASE ALL|Any CPU.ActiveCfg = RELEASE ALL|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.RELEASE ALL|Any CPU.Build.0 = RELEASE ALL|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/BCT/Samples/CodeCounter/codecounter.suo b/BCT/Samples/CodeCounter/codecounter.suo
deleted file mode 100644
index 84ae5e2a..00000000
--- a/BCT/Samples/CodeCounter/codecounter.suo
+++ /dev/null
Binary files differ
diff --git a/BCT/Samples/CodeCounter/codecounter.vssscc b/BCT/Samples/CodeCounter/codecounter.vssscc
deleted file mode 100644
index 794f014c..00000000
--- a/BCT/Samples/CodeCounter/codecounter.vssscc
+++ /dev/null
@@ -1,10 +0,0 @@
-""
-{
-"FILE_VERSION" = "9237"
-"ENLISTMENT_CHOICE" = "NEVER"
-"PROJECT_FILE_RELATIVE_PATH" = ""
-"NUMBER_OF_EXCLUDED_FILES" = "0"
-"ORIGINAL_PROJECT_FILE_PATH" = ""
-"NUMBER_OF_NESTED_PROJECTS" = "0"
-"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
-}
diff --git a/BCT/Samples/CodeCounter/console/App.config b/BCT/Samples/CodeCounter/console/App.config
deleted file mode 100644
index 5f8ec848..00000000
--- a/BCT/Samples/CodeCounter/console/App.config
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
- <configSections>
- <section
- name="codeCounters"
- type="CodeCounter.Library.CodeCounterTypesConfigurationSection, CodeCounter.Library"
- requirePermission="false"
- />
- </configSections>
- <codeCounters>
- <counterImplementations>
- <logic key="CS"
- assemblyInformation="CSharpCodeCounterLogic, CodeCounter.Library.CSharpCodeCounterLogic, CodeCounter.Library.dll"/>
- <logic key="MSSQL" assemblyInformation="SqlCodeCounterLogic, CodeCounter.Library.SqlCodeCounterLogic, CodeCounter.Library.dll"/>
- <logic key="XAML" assemblyInformation="XamlCodeCounterLogic, CodeCounter.Library.XamlCodeCounterLogic, CodeCounter.Library.dll"/>
- </counterImplementations>
- </codeCounters>
-</configuration> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/console/CodeCounter.csproj b/BCT/Samples/CodeCounter/console/CodeCounter.csproj
deleted file mode 100644
index d8accbbd..00000000
--- a/BCT/Samples/CodeCounter/console/CodeCounter.csproj
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>CodeCounter</RootNamespace>
- <AssemblyName>CodeCounter</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <SccProjectName>SAK</SccProjectName>
- <SccLocalPath>SAK</SccLocalPath>
- <SccAuxPath>SAK</SccAuxPath>
- <SccProvider>SAK</SccProvider>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- <OldToolsVersion>3.5</OldToolsVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Big Woo.NET, Version=3.0.3287.30089, Culture=neutral, PublicKeyToken=b8a13bcc86eb719e, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\dependencies\Big Woo.NET.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.configuration" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Xml.Linq">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data.DataSetExtensions">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="CodeCounterEngine.cs" />
- <Compile Include="CountCounterEvents.cs" />
- <Compile Include="FileTypes.cs" />
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\library\codecounterlibrary.csproj">
- <Project>{A055DCC3-3C6A-123C-82F8-AD10A8B313F7}</Project>
- <Name>codecounterlibrary</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <None Include="App.config" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/console/CodeCounter.csproj.user b/BCT/Samples/CodeCounter/console/CodeCounter.csproj.user
deleted file mode 100644
index f83e497d..00000000
--- a/BCT/Samples/CodeCounter/console/CodeCounter.csproj.user
+++ /dev/null
@@ -1,6 +0,0 @@
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <StartArguments>-about</StartArguments>
- <StartWorkingDirectory>C:\src\toolkit\CodeCounter\library\</StartWorkingDirectory>
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc b/BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc
deleted file mode 100644
index bfa5cf9c..00000000
--- a/BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc
+++ /dev/null
@@ -1,10 +0,0 @@
-""
-{
-"FILE_VERSION" = "9237"
-"ENLISTMENT_CHOICE" = "NEVER"
-"PROJECT_FILE_RELATIVE_PATH" = "relative:toolkit\\CodeCounter"
-"NUMBER_OF_EXCLUDED_FILES" = "0"
-"ORIGINAL_PROJECT_FILE_PATH" = ""
-"NUMBER_OF_NESTED_PROJECTS" = "0"
-"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
-}
diff --git a/BCT/Samples/CodeCounter/console/CodeCounterEngine.cs b/BCT/Samples/CodeCounter/console/CodeCounterEngine.cs
deleted file mode 100644
index 2cf1748f..00000000
--- a/BCT/Samples/CodeCounter/console/CodeCounterEngine.cs
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.IO;
-using System.Security.AccessControl;
-using CodeCounter.Library;
-#endregion
-
-namespace CodeCounter
-{
- /// <summary>
- /// This is the class that processes a file. If manages the "conversation" with the
- /// ICodeCounterLogic implementation occuring during reading through the file.
- /// </summary>
- public class CodeCounterEngine
- {
- #region private data
- private FileInfo _fileInfo = null;
- private long _statementLines = 0L;
- private long _totalLines = 0L;
- private long _codeLines = 0L;
- private long _commentLines = 0L;
- private long _errors = 0L;
- private CodeCounterLogicImplementerList _implementerList = null;
- #endregion
-
- #region properties
- /// <summary>
- /// FileInfo instance of the file we want to count code.
- /// </summary>
- public FileInfo File
- {
- get { return _fileInfo; }
- set { _fileInfo = value; }
- }
- #endregion
-
- #region event firing helpers
- /// <summary>
- /// Fires the OnStartEvent if there are listeners. This
- /// event is fired once per file.
- /// </summary>
- /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
- private void FireOnStartEvent(CodeCounterUpdateEventArgs startArgs)
- {
- if (null != OnStart)
- {
- OnStart(this, startArgs);
- }
- }
-
- /// <summary>
- /// Fires OnUpdate event if there are listeners. This event
- /// is fired approx every 250 lines read in the file.
- /// </summary>
- /// <param name="updateArgs">CodeCounterUpdateEventArgs</param>
- private void FireOnUpdateEvent(CodeCounterUpdateEventArgs updateArgs)
- {
- if (null != OnUpdate)
- OnUpdate(this, updateArgs);
- }
-
- /// <summary>
- /// Fires OnFinish event if there are listeners. This event
- /// is fired once per file
- /// </summary>
- /// <param name="finishedArgs">CodeCounterFinishedEventArgs</param>
- private void FireOnFinishedEvent(CodeCounterFinishedEventArgs finishedArgs)
- {
- if (null != OnFinish)
- OnFinish(this, finishedArgs);
- }
- #endregion
-
- #region private methods
- /// <summary>
- /// Find the ICodeCounterLogic implementation that can work with the file type we
- /// have found.
- /// </summary>
- /// <exception cref="FileTypeNotSupportedException">Thrown if no logic is found for the given file type</exception>
- /// <exception cref="ConfigurationFileException">Thrown if no logic is defined in the config file</exception>
- /// <returns>ICodeCounterLogic</returns>
- private ICodeCounterLogic GetFileProcessor(FileInfo info)
- {
- if (null == _implementerList)
- {
- _implementerList = CodeCounterLogicImplementerList.LoadFromConfigFile();
- if (0 == _implementerList.Count)
- throw new ConfigurationFileException("No code counter logic found.");
- }
-
- ICodeCounterLogic handler = null;
-
- foreach (CodeCounterLogicImplementer implementer in _implementerList)
- {
- ICodeCounterLogic potentialHandler = implementer.Implementer;
-
- if (true == potentialHandler.CanProcessFile(info.Name))
- {
- handler = potentialHandler;
- break;
- }
- }
-
- if (null == handler)
- throw FileTypeNotSupportedException.CreateException(info);
-
- return handler;
- }
-
- /// <summary>
- /// Each count is file specific. It is up to the consumer to process
- /// those values
- /// </summary>
- private void InitializeCounters()
- {
- _statementLines = 0L;
- _totalLines = 0L;
- _codeLines = 0L;
- _commentLines = 0L;
- _errors = 0L;
- }
- #endregion
-
- #region public methods
- /// <summary>
- /// The heart of the counting of lines
- /// </summary>
- public void Count()
- {
- // nothing to process if we have no file name
- if (null == _fileInfo)
- return;
-
- // ensures member data is reset to default
- InitializeCounters();
- long linesRead = 0L;
-
- // event arg initialization
- CodeCounterFinishedEventArgs finishedArgs = new CodeCounterFinishedEventArgs(_fileInfo, CodeCounterFunctionTypes.Error);
- CodeCounterUpdateEventArgs startArgs = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);
- CodeCounterUpdateEventArgs updateEventArg = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);
-
- try
- {
- // let console know we found a file
- FireOnStartEvent(startArgs);
-
- // find the appropriate handler for the type
- ICodeCounterLogic processor = GetFileProcessor(_fileInfo);
- bool _processorDeterminesEmpty = processor.EngineCanDetermineBlankLines();
-
- // allow the ICodeCounterLogic implementation a chance to
- // do something with the file
- processor.PrefileProcessing(_fileInfo.FullName);
-
- // now we can read through each line and count what it contains
- using (TextReader fileReader = _fileInfo.OpenText())
- {
- string line = "";
-
- while (null != (line = fileReader.ReadLine()))
- {
- linesRead++;
-
- long mod = (linesRead % 250L);
-
- if (0L == mod)
- {
- updateEventArg.Lines = linesRead;
- FireOnUpdateEvent(updateEventArg);
- }
-
- string trimmed = line.Trim();
-
- // when the processor does not know or care how empty lines are determined
- // we will do it by testing for null or empty line.
- if ((true == _processorDeterminesEmpty) && (true == string.IsNullOrEmpty(trimmed)))
- continue;
-
- // now we are ready to let the implemention decide what the line is
- CodeCounterLineType lineType = processor.LineType(trimmed);
-
- switch (lineType)
- {
- case CodeCounterLineType.Statement:
- case CodeCounterLineType.Code:
- _codeLines++;
- break;
- case CodeCounterLineType.StatementAndComment:
- case CodeCounterLineType.CodeAndComment:
- _codeLines++;
- _commentLines++;
- break;
- case CodeCounterLineType.CommentOnly:
- _commentLines++;
- break;
- default:
- break;
- }
-
- if (CodeCounterLineType.EmptyLine != lineType)
- _totalLines++;
- }
-
- // yay we are done
- fileReader.Close();
-
- // allow the counter implemenation any final moments
- processor.PostfileProcessing(_fileInfo.FullName);
-
- finishedArgs.Function = CodeCounterFunctionTypes.Summarizing;
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- finishedArgs.Function = CodeCounterFunctionTypes.Error;
- finishedArgs.AdditionalData = ex;
- }
- finally
- {
- finishedArgs.FileInfo = _fileInfo;
- finishedArgs.CodeLines = _codeLines;
- finishedArgs.CommentLines = _commentLines;
- finishedArgs.StatementLines = _statementLines;
- finishedArgs.Lines = _totalLines;
- _fileInfo = null;
-
- FireOnFinishedEvent(finishedArgs);
- }
- }
- #endregion
-
- #region event member delcaration
- public event CodeCounterUpdateEvent OnStart;
- public event CodeCounterUpdateEvent OnUpdate;
- public event CodeCounterFinishedEvent OnFinish;
- #endregion
- }
-}
diff --git a/BCT/Samples/CodeCounter/console/CountCounterEvents.cs b/BCT/Samples/CodeCounter/console/CountCounterEvents.cs
deleted file mode 100644
index 5bc24136..00000000
--- a/BCT/Samples/CodeCounter/console/CountCounterEvents.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.IO;
-#endregion
-
-namespace CodeCounter
-{
- #region CodeCounterFunctionTypes enumeration
- /// <summary>
- ///
- /// </summary>
- public enum CodeCounterFunctionTypes
- {
- NA,
- ListingFiles,
- ProcessingFiles,
- Summarizing,
- Error
- }
- #endregion
-
- #region base Event Arg class
- /// <summary>
- ///
- /// </summary>
- public class BaseCodeCounterEventArgs : EventArgs
- {
- private FileInfo _fileInfo = null;
-
- public FileInfo FileInfo
- {
- get { return _fileInfo; }
- set { _fileInfo = value; }
- }
-
- protected BaseCodeCounterEventArgs() { }
-
- protected BaseCodeCounterEventArgs(FileInfo fileInfo)
- {
- _fileInfo = fileInfo;
- }
- }
- #endregion
-
- #region CodeCounterUpdateEventArgs implementation
- /// <summary>
- ///
- /// </summary>
- public class CodeCounterUpdateEventArgs : BaseCodeCounterEventArgs
- {
- private CodeCounterFunctionTypes _function = CodeCounterFunctionTypes.NA;
- private long _lines = 0;
-
- public long Lines
- {
- get { return _lines; }
- set { _lines = value; }
- }
-
- public CodeCounterFunctionTypes Function
- {
- get { return _function; }
- set { _function = value; }
- }
-
- protected CodeCounterUpdateEventArgs() { }
-
- public CodeCounterUpdateEventArgs(FileInfo fileInfo, CodeCounterFunctionTypes function)
- : base(fileInfo)
- {
- _function = function;
- }
- }
- #endregion
-
- #region CodeCounterFinishedEventArgs declaration
- /// <summary>
- ///
- /// </summary>
- public class CodeCounterFinishedEventArgs : BaseCodeCounterEventArgs
- {
- private CodeCounterFunctionTypes _function = CodeCounterFunctionTypes.NA;
- private long _totalLines = 0L;
- private long _codeLines = 0L;
- private long _commentLines = 0L;
- private long _statementLines = 0L;
- private object _additionalData = null;
-
- public object AdditionalData
- {
- get { return _additionalData; }
- set { _additionalData = value; }
- }
-
- public CodeCounterFunctionTypes Function
- {
- get { return _function; }
- set { _function = value; }
- }
-
- public long StatementLines
- {
- get { return _statementLines; }
- set { _statementLines = value; }
- }
-
- public long Lines
- {
- get { return _totalLines; }
- set { _totalLines = value; }
- }
-
- public long CodeLines
- {
- get { return _codeLines; }
- set { _codeLines = value; }
- }
-
- public long CommentLines
- {
- get { return _commentLines; }
- set { _commentLines = value; }
- }
-
- public CodeCounterFinishedEventArgs(FileInfo fileInfo, CodeCounterFunctionTypes function)
- : base(fileInfo)
- {
- _function = function;
- }
-
- }
- #endregion
-
- #region event declarations
- public delegate void CodeCounterUpdateEvent(object sender, CodeCounterUpdateEventArgs args);
- public delegate void CodeCounterFinishedEvent(object sender, CodeCounterFinishedEventArgs args);
- #endregion
-
-}
diff --git a/BCT/Samples/CodeCounter/console/FileTypes.cs b/BCT/Samples/CodeCounter/console/FileTypes.cs
deleted file mode 100644
index 3b614eb0..00000000
--- a/BCT/Samples/CodeCounter/console/FileTypes.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.IO;
-#endregion
-
-namespace CodeCounter
-{
- /// <summary>
- ///
- /// </summary>
- public interface IFileType
- {
- string Extension { get; }
- bool HandlesFile(File file);
- string[] Comments { get; }
- }
-}
diff --git a/BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC b/BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC
deleted file mode 100644
index ec58105e..00000000
--- a/BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC
+++ /dev/null
@@ -1,5 +0,0 @@
-SCC = This is a source code control file
-
-[CodeCounter.csproj]
-SCC_Aux_Path = "P4SCC#bigwoo:1666##matt##MediumWoo"
-SCC_Project_Name = Perforce Project
diff --git a/BCT/Samples/CodeCounter/console/Program.cs b/BCT/Samples/CodeCounter/console/Program.cs
deleted file mode 100644
index 1815170c..00000000
--- a/BCT/Samples/CodeCounter/console/Program.cs
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using BigWoo.NET.ApplicationSupport;
-using BigWoo.NET.Utility;
-using System.IO;
-using BigWoo.Utility;
-using CodeCounter.Library;
-#endregion
-
-namespace CodeCounter
-{
- /// <summary>
- /// The main control loop for the code counter program. Evaulates command line arguments
- /// spins up file searches and code counting implmentations to count the code in the file
- /// </summary>
- class Program
- {
- private class PrintHelpException : Exception { }
-
- private class ShowAboutWebPageException : Exception { }
-
- #region private data
-
- private const string COMMAND_VERBOSE = "-verbose";
- private const string COMMAND_RECURSE = "-recurse";
- private const string COMMAND_SUPPORTED = "-supportedTypes";
- private const string COMMAND_SHOWABOUTWEBPAGE = "-about";
-
- private const string WEBSITE = "www.mattraffel.com/aboutme.aspx";
-
- private char[] _spinner = new char[] { '|', '/', '-', '\\', '|', '/', '-', '\\' };
- private char[] _osWildCards = new char[] { '*', '?' };
- private object _lockObject = new object();
-
- private List<string> _fileArgs = new List<string>();
- private ScanResultsList _listOfFiles = new ScanResultsList();
- private ScanForFiles _fileScanner = new ScanForFiles();
-
- private bool _quiet = true;
- private bool _recursive = false;
- private bool _detailedHelp = false;
-
- private AutoResetEvent _eventReset = null;
- private int _erasableTextLengh = 0;
- private int _spinnerPosition = 0;
- private string _lastDirectoryProcessed = string.Empty;
-
- private long _filesCounted = 0L;
- private long _totalLines = 0L;
- private long _codeLines = 0L;
- private long _commentLines = 0L;
- private long _statementLines = 0L;
- private long _errors = 0L;
- #endregion
-
- #region private methods
- /// <summary>
- /// Draws what might appear to some as a spinner in the console window to
- /// show that the program is functioning and not hung
- /// </summary>
- private void DrawSpinner()
- {
- // move cursor back to starting position, ignoring if we muck up
- ConsoleBackspace(_erasableTextLengh);
-
- if (_spinnerPosition >= _spinner.Length)
- _spinnerPosition = 0;
-
- string outputText = string.Format("{0}", _spinner[_spinnerPosition]);
- Console.Write(outputText);
-
- _erasableTextLengh = outputText.Length;
-
- _spinnerPosition++;
-
- }
-
- /// <summary>
- /// Erases "spaces" by moving the cursor left by "spaces"
- /// Exceptions are ignored
- /// </summary>
- /// <param name="spaces">int, the number of spaces to backspace</param>
- private void ConsoleBackspace(int spaces)
- {
- try
- {
- if (0 < spaces)
- {
- int move = spaces;
-
- if (spaces > Console.CursorLeft)
- move = Console.CursorLeft;
-
- Console.CursorLeft -= move;
- }
- }
- catch(Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
-
- /// <summary>
- /// processes the command line arguments. We expect no more than
- /// -quiet
- /// -recurse
- /// -help
- /// -supportedTypes
- /// {filename}
- ///
- /// FileName can be full filename or partial with wild card
- /// </summary>
- /// <param name="args">string[]</param>
- private void ProcessCommandLineArgs(string[] args)
- {
- foreach (string arg in args)
- {
- if (('-' == arg[0]) || (('/' == arg[0])))
- {
- if (0 == arg.CompareTo(COMMAND_VERBOSE))
- _quiet = false;
- else if (0 == arg.CompareTo(COMMAND_RECURSE))
- _recursive = true;
- else if (0 == arg.CompareTo(COMMAND_SUPPORTED))
- {
- _detailedHelp = true;
- throw new PrintHelpException();
- }
- else if (0 == arg.CompareTo(COMMAND_SHOWABOUTWEBPAGE))
- throw new ShowAboutWebPageException();
- else
- throw new PrintHelpException();
- }
- else
- _fileArgs.Add(arg);
- }
-
- if (0 == _fileArgs.Count)
- throw new PrintHelpException();
- }
-
- /// <summary>
- /// Using a mask, look for files matching the mask, digging recursively
- /// into sub-directories if recursive is true. While this code can work
- /// for files without a wildcard, for performance reasons the expectation
- /// is this method is only called when fileMask has a wildcard in it,
- /// or recursive is true.
- /// </summary>
- /// <param name="fileMask">string</param>
- private void BuildFileListForMask(string fileMask)
- {
- Console.Write(string.Format("scanning for {0}.", fileMask));
-
- _fileScanner.FilesList = new ScanResultsList();
- _fileScanner.IsRecursive = _recursive;
- _fileScanner.RootDir = Environment.CurrentDirectory;
- _fileScanner.FileMask = fileMask;
- _fileScanner.Scan();
-
- _listOfFiles.AddRange(_fileScanner.FilesList.ToArray());
-
- ConsoleBackspace(_erasableTextLengh);
- _erasableTextLengh = 0;
-
- if (false == _quiet)
- Console.WriteLine("..done");
- else
- Console.WriteLine("");
-
- }
-
- /// <summary>
- /// Called when recursive is true, scan for all matches in fileMask
- /// input received from the commandline
- /// </summary>
- private void BuildFileListViaScanner()
- {
- // for each input that "appears" to be a file mask (either a file name or a file wildcard)
- // gather the file names)
- foreach (string fileMask in _fileArgs)
- {
- BuildFileListForMask(fileMask);
- }
- }
-
- /// <summary>
- /// Called when recursive is false, evaluates the input to see if search is really
- /// required or not, only using the file scanner when a wildcard is present in the
- /// input
- /// </summary>
- private void BuildFileListIntelligently()
- {
- // for each input that "appears" to be a file mask (either a file name or a file wildcard)
- // gather the file names)
- foreach (string fileMask in _fileArgs)
- {
- if (-1 < fileMask.IndexOfAny(_osWildCards))
- {
- BuildFileListForMask(fileMask);
- }
- else
- {
- DefaultScanForFilesData nextFile = new DefaultScanForFilesData();
- nextFile.FileInfo = new FileInfo(fileMask);
- _listOfFiles.Add(nextFile);
- }
- }
- }
-
- /// <summary>
- /// optimized building of the file list....if recursive is not true
- /// additional code checks the input and determines how to add files
- /// to the list
- /// </summary>
- private void BuildFileList()
- {
- _listOfFiles.Clear();
-
- // go ahead and hook up the event handler for file found
- // in case we do end up using the scanner
- _fileScanner.OnFileFound += new FileFoundEvent(OnFileFound);
- _fileScanner.OnDirectoryFound += new ScanningDirectoryEvent(OnDirectoryFound);
-
- // since recursive is true, it really doesnt matter if
- // a wild card is in the input, just start scanning
- if (true == _recursive)
- {
- BuildFileListViaScanner();
- }
- else
- {
- BuildFileListIntelligently();
- }
- }
-
- /// <summary>
- /// File list has been built, now its time to crack open each file
- /// and count the code
- /// </summary>
- private void ProcessFileList()
- {
- // now we are ready to count the files
- CodeCounterEngine codeCounterEngine = new CodeCounterEngine();
- _eventReset = new AutoResetEvent(false);
- object lockObject = new object();
-
- // hook up finished even handler (required)
- codeCounterEngine.OnFinish += new CodeCounterFinishedEvent(OnCodeCountingFinished);
-
- if (0 < _listOfFiles.Count)
- Console.WriteLine(string.Format("counting {0} possible files", _listOfFiles.Count));
-
- // only add these event handlers if the user wanted output
- if (false == _quiet)
- {
- codeCounterEngine.OnStart += new CodeCounterUpdateEvent(OnCodeCountingStart);
- codeCounterEngine.OnUpdate += new CodeCounterUpdateEvent(OnCodeCountingUpdate);
- }
-
- // for each file in the array
- foreach (IScanForFilesData file in _listOfFiles)
- {
- try
- {
- codeCounterEngine.File = file.FileInfo;
-
- // clean everything up
- while (true == Console.KeyAvailable)
- Console.Read();
-
- _spinnerPosition = 0;
- _erasableTextLengh = 0;
- _eventReset.Reset();
-
- // make erasure execute on a separate thread
- ThreadStart codeCountThreadStart = new ThreadStart(codeCounterEngine.Count);
- Thread codeCountThread = new Thread(codeCountThreadStart);
- codeCountThread.Name = "codeCountingThread worker";
- codeCountThread.Start();
-
- _eventReset.WaitOne();
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- Console.WriteLine(ex.Message);
- }
- }
- }
-
- /// <summary>
- /// Prints help to console
- /// </summary>
- private void PrintHelp()
- {
- Console.WriteLine("");
- Console.WriteLine("\t-verbose");
- Console.WriteLine("\t-recurse");
- Console.WriteLine("\t-supportedTypes");
- Console.WriteLine("\t-help");
- Console.WriteLine("\t-about (opens www.mattraffel.com)");
- Console.WriteLine("\t{filename}");
- Console.WriteLine("");
- Console.WriteLine("FileName can be full filename or partial with wild card");
-
- // _detailedHelp is set to true when -supportedTypes is found in the command line
- // this means we show information from each of the code counter implmentations
- if (true == _detailedHelp)
- {
- Console.WriteLine("");
- CodeCounterLogicImplementerList list = CodeCounterLogicImplementerList.LoadFromConfigFile();
- if (0 == list.Count)
- {
- Console.WriteLine("No code types supported. Check the config file.");
- return;
- }
-
- Console.WriteLine("File formats supported:");
-
- foreach (CodeCounterLogicImplementer implementor in list)
- {
- string[] fileTypeList = implementor.Implementer.FileTypesHandled();
- foreach (string fileType in fileTypeList)
- {
- // most file types are short so we will make a fair assumption
- // that it is ok to right justify fileType by 10 chars....
- string details = string.Format("{0,10} by {1}", fileType, implementor.ImplementerType.Name);
- Console.WriteLine(details);
- }
- }
-
- }
- }
-
- /// <summary>
- /// Prints the results of counting code lines
- /// </summary>
- private void PrintSummaryReport()
- {
- if (false == _quiet)
- Console.WriteLine("");
-
- Console.WriteLine(string.Format("Files {0,10:#,##0}", _filesCounted));
- if (0 < _codeLines)
- Console.WriteLine(string.Format("Code Lines {0,10:#,##0}", _codeLines));
-
- if (0 < _statementLines)
- Console.WriteLine(string.Format("Statment Lines {0,10:#,##0}", _statementLines));
-
- Console.WriteLine(string.Format("Comment Lines {0,10:#,##0}", _commentLines));
-
- if (0 < _filesCounted)
- Console.WriteLine(string.Format("Avg Lines/File {0,10:#,##0}", _totalLines / _filesCounted));
-
- if (0 < _errors)
- {
- Console.WriteLine(string.Format("Error Files {0,10:#,##0}", _errors));
- if (true == _quiet)
- Console.WriteLine(" ==> to see details about the errors run with -verbose");
- }
-
- Console.WriteLine("");
- }
-
- /// <summary>
- /// A little extra self boasting.....
- /// </summary>
- private void ShowAboutWebPage()
- {
- try
- {
- Console.WriteLine("");
- Console.WriteLine(string.Format("ok to open {0} in your browser (Y/n)?", WEBSITE));
- ConsoleKeyInfo keyInfo = Console.ReadKey();
- char input = keyInfo.KeyChar;
-
- if (('y' == input) || ('Y' == input) || ('\r' == input))
- System.Diagnostics.Process.Start(string.Format("http://{0}", WEBSITE));
-
- //if ('y' != input)
- // System.Diagnostics.Process.Start(string.Format("http://{0}", WEBSITE));
- }
- catch
- {
- Console.WriteLine(string.Format("Error trying to open url. Please visit http://{0} when you have a moment.", WEBSITE));
- }
- }
-
- /// <summary>
- /// Prints a standard bit of header information every time
- /// </summary>
- private void PrintHeader()
- {
- Console.WriteLine("CodeCounter by matt raffel");
- Console.WriteLine("(c) 2009 - matt.raffel@mindspring.com");
- }
-
- /// <summary>
- /// This is the main function of this class
- /// it runs through the command line parameters
- /// sets up the FileErasure object and lets it do
- /// its business
- /// </summary>
- /// <param name="args">string[], command line arguments</param>
- private void Run(string[] args)
- {
- PrintHeader();
-
- try
- {
- // process input
- ProcessCommandLineArgs(args);
-
- // now we should know what files to count or what mask to use
- // to get the files to count so build a definitive list
- // of files
- BuildFileList();
-
- // now count the code
- ProcessFileList();
-
- // and print out the results
- PrintSummaryReport();
- }
- catch (PrintHelpException)
- {
- PrintHelp();
- }
- catch (ShowAboutWebPageException)
- {
- ShowAboutWebPage();
- }
- catch (Exception error)
- {
- Console.WriteLine("");
- Console.WriteLine("Application Exception:");
- Console.WriteLine(error.Message);
- Console.WriteLine(error.StackTrace);
- }
- finally
- {
- }
- }
- #endregion
-
- #region event methods
- /// <summary>
- /// Provide simple UI updates on scanning
- /// </summary>
- /// <param name="directoryName">string</param>
- private void OnDirectoryFound(string directoryName)
- {
- if (false == _quiet)
- DrawSpinner();
- }
-
- /// <summary>
- /// Provide simple UI updates on scanning
- /// </summary>
- /// <param name="fileData">string</param>
- private void OnFileFound(IScanForFilesData fileData)
- {
- if (false == _quiet)
- DrawSpinner();
- }
-
- /// <summary>
- /// Finished counting lines in a file, now its time to note it
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="counterFinishedArgs">CodeCounterFinishedEventArgs</param>
- private void OnCodeCountingFinished(object sender, CodeCounterFinishedEventArgs counterFinishedArgs)
- {
- lock (_lockObject)
- {
- try
- {
-
- if (CodeCounterFunctionTypes.Summarizing == counterFinishedArgs.Function)
- {
- if (false == _quiet)
- {
- // move cursor back to starting position, ignoring if we muck up
- ConsoleBackspace(_erasableTextLengh);
- string spaces = new string(' ', _erasableTextLengh);
- Console.Write(spaces);
- Console.WriteLine("");
- }
-
- // only files we succeeding in counting are part of the file count
- // error files are not included in the value
- _filesCounted++;
-
- _codeLines += counterFinishedArgs.CodeLines;
- _totalLines += counterFinishedArgs.Lines;
- _commentLines += counterFinishedArgs.CommentLines;
- _statementLines += counterFinishedArgs.StatementLines;
-
- }
- else
- {
- _errors++;
-
- if ((counterFinishedArgs.AdditionalData is ConfigurationFileException) ||
- (counterFinishedArgs.AdditionalData is FileTypeNotSupportedException))
- {
- if (false == _quiet)
- {
- // move cursor back to starting position, ignoring if we muck up
- ConsoleBackspace(_erasableTextLengh);
- Console.Write("...file type not supported");
- Console.WriteLine("");
- }
- }
- }
-
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- finally
- {
- _spinnerPosition = 0;
- _erasableTextLengh = 0;
- _eventReset.Set();
-
- }
- }
- }
-
- /// <summary>
- /// Updates from the code counter as it evaluates a file
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="erasureArgs">CodeCounterUpdateEventArgs</param>
- private void OnCodeCountingUpdate(object sender, CodeCounterUpdateEventArgs erasureArgs)
- {
- lock (_lockObject)
- {
- try
- {
- // move cursor back to starting position, ignoring if we muck up
- DrawSpinner();
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- }
-
- /// <summary>
- /// Indicates a file has been found that matches our criteria for counting the lines
- /// of code in the file
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
- private void OnCodeCountingStart(object sender, CodeCounterUpdateEventArgs startArgs)
- {
- try
- {
- System.Diagnostics.Debug.Assert(0 == _erasableTextLengh);
-
- if (0 != _lastDirectoryProcessed.CompareTo(startArgs.FileInfo.DirectoryName))
- {
- _lastDirectoryProcessed = startArgs.FileInfo.DirectoryName;
- string directory = string.Format("{0}:", _lastDirectoryProcessed);
- Console.WriteLine(directory);
- }
-
- _spinnerPosition = 0;
- _erasableTextLengh = 0;
- string fileName = string.Format("\t{0}: ", startArgs.FileInfo.Name);
- Console.Write(fileName);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- #endregion
-
- #region ctor
- /// <summary>
- ///
- /// </summary>
- internal Program()
- {
- }
- #endregion
-
- #region startup entry method
- /// <summary>
- ///
- /// </summary>
- /// <param name="args">string[]</param>
- static void Main(string[] args)
- {
- Program go = new Program();
- go.Run(args);
-
- if (true == System.Diagnostics.Debugger.IsAttached)
- {
- Console.WriteLine("press a key....");
- Console.Read();
- }
- }
- #endregion
- }
-}
diff --git a/BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs b/BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs
deleted file mode 100644
index 10081080..00000000
--- a/BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("CodeCounter")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("CodeCounter")]
-[assembly: AssemblyCopyright("Copyright © 2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("d6e0a218-ddd1-436c-8405-4be8d7616bfb")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dll b/BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dll
deleted file mode 100644
index 9110f2cb..00000000
--- a/BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dll
+++ /dev/null
Binary files differ
diff --git a/BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs
deleted file mode 100644
index 83f90d9a..00000000
--- a/BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Configuration;
-using System.IO;
-#endregion
-
-namespace CodeCounter.Library
-{
- /// <summary>
- /// Provides the logic for counting lines of code and comments
- /// </summary>
- public class CSharpCodeCounterLogic : ICodeCounterLogic
- {
- private bool _isInComment = false;
-
- /// <summary>
- /// Performs all the evaluations while are stepping through
- /// a multi line comment
- /// </summary>
- /// <param name="line">string</param>
- /// <returns>CodeCounterLineType</returns>
- private CodeCounterLineType EvaluateWhileInComment(string line)
- {
- if (false == string.IsNullOrEmpty(line))
- {
- if (true == line.Contains("*/"))
- {
- _isInComment = false;
-
- int endOfCommentIndex = line.IndexOf("*/");
-
- endOfCommentIndex += 2;
-
- if (endOfCommentIndex < line.Length)
- return CodeCounterLineType.CodeAndComment;
- }
- }
-
- return CodeCounterLineType.CommentOnly;
- }
-
- /// <summary>
- /// Evaluates a line
- /// </summary>
- /// <param name="line">string</param>
- /// <returns>CodeCounterLineType</returns>
- private CodeCounterLineType Evaluate(string line)
- {
- // this one is real simple a line starts with // so
- // know there is no code after and we know the next line
- // could be anything
- if (true == line.StartsWith("//"))
- return CodeCounterLineType.CommentOnly;
-
- if (true == line.StartsWith("/*"))
- {
- _isInComment = true;
-
- // because it is possible the comment terminates
- // in this same line and to ensure that we count code after the comment
- // terminates, use our EvaluateWhileInComment to determine
- // return value
- return EvaluateWhileInComment(line);
- }
-
- if (true == line.Contains("//"))
- return CodeCounterLineType.CodeAndComment;
-
- if (true == line.Contains("/*"))
- {
- _isInComment = true;
-
- // because it is possible the comment terminates
- // in this same line and to ensure that we count code after the comment
- // terminates, use our EvaluateWhileInComment to determine
- // if the comment has finished. we will ignore its return
- // value as the only possible legal value for this case is
- // CodeCounterLineType.CodeAndComment
- EvaluateWhileInComment(line);
-
- return CodeCounterLineType.CodeAndComment;
- }
-
- return CodeCounterLineType.Code;
- }
-
- #region ICodeCounterLogic Members
- /// <summary>
- ///
- /// </summary>
- /// <param name="line"></param>
- /// <returns></returns>
- public CodeCounterLineType LineType(string line)
- {
- if (true == string.IsNullOrEmpty(line))
- return CodeCounterLineType.EmptyLine;
-
- string trimmed = line.Trim();
-
- if (true == string.IsNullOrEmpty(line))
- return CodeCounterLineType.EmptyLine;
-
- if (true == _isInComment)
- return EvaluateWhileInComment(trimmed);
- else
- return Evaluate(trimmed);
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public bool EngineCanDetermineBlankLines()
- {
- return true;
- }
-
- /// <summary>
- /// should return something like cs or vb or sql etc
- /// </summary>
- /// <returns>string[]</returns>
- public string[] FileTypesHandled()
- {
- return new string[] {"cs"};
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="fileName"></param>
- /// <returns></returns>
- public bool CanProcessFile(string file)
- {
- FileInfo info = new FileInfo(file);
- string fileExtension = info.Extension.ToLower();
- if (".cs" == fileExtension)
- return true;
-
- return false;
- }
-
- public void PrefileProcessing(string fileName) {}
-
- public void PostfileProcessing(string fileName) {}
-
- #endregion
- }
-}
diff --git a/BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs b/BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs
deleted file mode 100644
index 245571d3..00000000
--- a/BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Configuration;
-using System.IO;
-using BigWoo.Utility;
-#endregion
-
-namespace CodeCounter.Library
-{
- /// <summary>
- ///
- /// </summary>
- public class CodeCounterLogicImplementer
- {
- private string _className = string.Empty;
- private string _fullClassName = string.Empty;
- private string _assemblyName = "CodeCounter.Library.dll";
- private Type _implementer = null;
- private ICodeCounterLogic _logic = null;
-
- private Type GetImplementerTypeInstance()
- {
- if (null == _implementer)
- {
- if (true == string.IsNullOrEmpty(_assemblyName))
- throw new ConfigurationFileException("codeCounters not configured correctly");
-
- if (true == string.IsNullOrEmpty(_fullClassName))
- throw new ConfigurationFileException("codeCounters not configured correctly");
-
- _implementer = AssemblyUtility.GetTypeFromFile(_assemblyName, _fullClassName);
-
- if (false == AssemblyUtility.HasInterface(typeof(ICodeCounterLogic), _implementer))
- throw new ConfigurationFileException("codeCounters not implemented correctly");
- }
-
- return _implementer;
- }
-
- private ICodeCounterLogic GetImplementerInstance()
- {
- if (null == _logic)
- {
- _logic = AssemblyUtility.InvokeDefaultCtor(ImplementerType) as ICodeCounterLogic;
- }
-
- return _logic;
- }
-
- public Type ImplementerType
- {
- get { return GetImplementerTypeInstance(); }
- }
-
- public ICodeCounterLogic Implementer
- {
- get { return GetImplementerInstance(); }
- }
-
- protected CodeCounterLogicImplementer() { }
-
- public static CodeCounterLogicImplementer FromConfigElement(CodeCounterLogicElement element)
- {
- CodeCounterLogicImplementer implementer = new CodeCounterLogicImplementer();
- string[] typeParts = element.AssemblyInformation.Split(new char[] { ',' });
-
- if (null != typeParts)
- {
- if (1 <= typeParts.Length)
- implementer._className = typeParts[0].Trim();
-
- if (2 <= typeParts.Length)
- implementer._fullClassName = typeParts[1].Trim();
-
- if (3 <= typeParts.Length)
- implementer._assemblyName = typeParts[2].Trim();
- }
- return implementer;
- }
- }
-
- /// <summary>
- ///
- /// </summary>
- public class CodeCounterLogicImplementerList : List<CodeCounterLogicImplementer>
- {
- protected CodeCounterLogicImplementerList() { }
-
- public static CodeCounterLogicImplementerList LoadFromConfigFile()
- {
- CodeCounterLogicImplementerList list = new CodeCounterLogicImplementerList();
-
- CodeCounterTypesConfigurationSection section = ConfigurationManager.GetSection("codeCounters") as CodeCounterTypesConfigurationSection;
-
- if (null == section)
- throw new ConfigurationFileException("codeCounters section is missing");
-
- foreach (CodeCounterLogicElement element in section.CounterImplementations)
- {
- CodeCounterLogicImplementer implementer = CodeCounterLogicImplementer.FromConfigElement(element);
- list.Add(implementer);
- }
-
- return list;
- }
- }
-}
diff --git a/BCT/Samples/CodeCounter/library/ConfigFileSections.cs b/BCT/Samples/CodeCounter/library/ConfigFileSections.cs
deleted file mode 100644
index 70bc5917..00000000
--- a/BCT/Samples/CodeCounter/library/ConfigFileSections.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Configuration;
-#endregion
-
-namespace CodeCounter.Library
-{
- /// <summary>
- ///
- /// </summary>
- public class CodeCounterTypesConfigurationSection : ConfigurationSection
- {
- [ConfigurationProperty("counterImplementations")]
- public CodeCounterLogicCollection CounterImplementations
- {
- get { return ((CodeCounterLogicCollection)(base["counterImplementations"])); }
- }
- }
-
- /// <summary>
- ///
- /// </summary>
- [ConfigurationCollection(typeof(CodeCounterLogicElement), AddItemName = "logic")]
- public class CodeCounterLogicCollection : ConfigurationElementCollection
- {
- /// <summary>
- /// for creating new elements
- /// </summary>
- /// <returns>AssemblyElement</returns>
- protected override ConfigurationElement CreateNewElement()
- {
- return new CodeCounterLogicElement();
- }
-
- /// <summary>
- /// searchs the collection for a given AssemblyElement based on its key
- /// </summary>
- /// <param name="element">AssemblyElement</param>
- /// <returns>CodeCounterType</returns>
- protected override object GetElementKey(ConfigurationElement element)
- {
- return (element as CodeCounterLogicElement).AssemblyInformation;
- }
-
- /// <summary>
- /// Indexor into the array
- /// </summary>
- /// <param name="idx">int</param>
- /// <returns>CodeCounterType</returns>
- public CodeCounterLogicElement this[int idx]
- {
- get
- {
- return BaseGet(idx) as CodeCounterLogicElement;
- }
- }
- }
-
- /// <summary>
- ///
- /// </summary>
- public class CodeCounterLogicElement : ConfigurationElement
- {
- [ConfigurationProperty("assemblyInformation", IsKey = false, IsRequired = true)]
- public string AssemblyInformation
- {
- get
- {
- // assemblyInformation="CSharpCodeCounterLogic, CodeCounter.Library.CSharpCodeCounterLogic, CodeCounter.Library.dll"
- string assemblyInformation = (string) base["assemblyInformation"];
- return assemblyInformation;
- }
-
- set
- {
- base["assemblyInformation"] = value;
- }
- }
-
- [ConfigurationProperty("key", IsKey = true, IsRequired = true)]
- public string Key
- {
- get
- {
- string key = (string) base["key"];
- return key;
- }
- set { base["key"] = value; }
- }
- }
-
-
-}
diff --git a/BCT/Samples/CodeCounter/library/CustomExceptions.cs b/BCT/Samples/CodeCounter/library/CustomExceptions.cs
deleted file mode 100644
index b4ee7100..00000000
--- a/BCT/Samples/CodeCounter/library/CustomExceptions.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Configuration;
-using System.IO;
-#endregion
-
-
-namespace CodeCounter.Library
-{
- /// <summary>
- ///
- /// </summary>
- public class ConfigurationFileException : Exception
- {
- public ConfigurationFileException(string msg) : base(msg) { }
- }
-
- /// <summary>
- ///
- /// </summary>
- public class FileTypeNotSupportedException : Exception
- {
- public FileTypeNotSupportedException(string msg) : base(msg) { }
-
- public static FileTypeNotSupportedException CreateException(FileInfo info)
- {
- string msg = string.Format("{0} was not counted as no implemention for type {1} was found", info.Name, info.Extension);
- return new FileTypeNotSupportedException(msg);
- }
- }
-}
diff --git a/BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs
deleted file mode 100644
index 9e37ed59..00000000
--- a/BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-#endregion
-
-namespace CodeCounter.Library
-{
- /// <summary>
- /// Used by ICodeCounterLogic implementations to inform the the code counting engine
- /// the type of line read.
- /// </summary>
- public enum CodeCounterLineType
- {
- /// <summary>
- /// a blank line
- /// </summary>
- EmptyLine,
- /// <summary>
- /// this line contains code only
- /// </summary>
- Code,
- /// <summary>
- /// this line contains code and comments
- /// </summary>
- CodeAndComment,
- /// <summary>
- /// line line is part of a comment and no code
- /// </summary>
- CommentOnly,
- /// <summary>
- /// a complete code statement (like in cs a statement ends with ;)
- /// </summary>
- Statement,
- /// <summary>
- /// this line contains a completed code statement and comments
- /// </summary>
- StatementAndComment,
- }
-
- /// <summary>
- /// Interface that defines the methods required by implementtions that provide
- /// the code counting functions
- /// </summary>
- public interface ICodeCounterLogic
- {
- /// <summary>
- /// Evaluates input and determines what the line contains: nothing,
- /// code, code and comments or comment only, statement etc...
- /// </summary>
- /// <param name="line">string, typically one line a source file</param>
- /// <returns>CodeCounterLineType</returns>
- CodeCounterLineType LineType(string line);
-
- /// <summary>
- /// should return something like cs or vb or sql etc. No need to return .cs just cs
- /// Typically used to display the supported types during command line help command
- /// </summary>
- /// <returns>string[]</returns>
- string[] FileTypesHandled();
-
- /// <summary>
- /// Called by the engine to ask the implementation if it can count the lines in the file
- /// </summary>
- /// <param name="fileName"></param>
- /// <returns>bool, true if the file can be processed</returns>
- bool CanProcessFile(string file);
-
- /// <summary>
- /// Determines who is responsible for identifying an empty line. An empty line
- /// being a line that contains no comments and no code. (Currently unused)
- /// </summary>
- /// <returns>true, the engine will determine what constitues a blank line
- /// other wise the ICodeCounterLogic Implmentation makes that decision</returns>
- bool EngineCanDetermineBlankLines();
-
- /// <summary>
- /// opportunity to do some processing prior to counting. If your code
- /// grabs a system handle to this file, make sure you release it before
- /// the function terminates or counting fails.
- /// </summary>
- /// <param name="fileName">string, full path to the file</param>
- void PrefileProcessing(string fileName);
-
- /// <summary>
- /// opportunity to do some processing after counting
- /// </summary>
- /// <param name="fileName">string, full path to the file</param>
- void PostfileProcessing(string fileName);
-
- }
-}
diff --git a/BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC b/BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC
deleted file mode 100644
index 76e63471..00000000
--- a/BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC
+++ /dev/null
@@ -1,5 +0,0 @@
-SCC = This is a source code control file
-
-[codecounterlibrary.csproj]
-SCC_Aux_Path = "P4SCC#bigwoo:1666##matt##MediumWoo"
-SCC_Project_Name = Perforce Project
diff --git a/BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs b/BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs
deleted file mode 100644
index 6df524f7..00000000
--- a/BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-//
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-//
-[assembly: AssemblyTitle("CodeCounterLib")]
-[assembly: AssemblyDescription("Assortment of Mananged utilities")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("mattraffel.com")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("See GNU license included")]
-[assembly: AssemblyTrademark("See GNU license included")]
-[assembly: AssemblyCulture("")]
-
-//
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly: AssemblyVersion("1.0.*")]
-
-//
-// In order to sign your assembly you must specify a key to use. Refer to the
-// Microsoft .NET Framework documentation for more information on assembly signing.
-//
-// Use the attributes below to control which key is used for signing.
-//
-// Notes:
-// (*) If no key is specified, the assembly is not signed.
-// (*) KeyName refers to a key that has been installed in the Crypto Service
-// Provider (CSP) on your machine. KeyFile refers to a file which contains
-// a key.
-// (*) If the KeyFile and the KeyName values are both specified, the
-// following processing occurs:
-// (1) If the KeyName can be found in the CSP, that key is used.
-// (2) If the KeyName does not exist and the KeyFile does exist, the key
-// in the KeyFile is installed into the CSP and used.
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
-// When specifying the KeyFile, the location of the KeyFile should be
-// relative to the project output directory which is
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
-// located in the project directory, you would specify the AssemblyKeyFile
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
-// documentation for more information on this.
-//
-[assembly: AssemblyDelaySign(false)]
-
diff --git a/BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs
deleted file mode 100644
index e8581fee..00000000
--- a/BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Configuration;
-using System.IO;
-#endregion
-
-namespace CodeCounter.Library
-{
- /// <summary>
- ///
- /// </summary>
- public class SqlCodeCounterLogic : ICodeCounterLogic
- {
- private bool _isInComment = false;
-
- /// <summary>
- /// Performs all the evaluations while are stepping through
- /// a multi line comment
- /// </summary>
- /// <param name="line">string</param>
- /// <returns>CodeCounterLineType</returns>
- private CodeCounterLineType EvaluateWhileInComment(string line)
- {
- if (false == string.IsNullOrEmpty(line))
- {
- if (true == line.Contains("*/"))
- {
- _isInComment = false;
-
- int endOfCommentIndex = line.IndexOf("*/");
-
- endOfCommentIndex += 2;
-
- if (endOfCommentIndex < line.Length)
- return CodeCounterLineType.CodeAndComment;
- }
- }
-
- return CodeCounterLineType.CommentOnly;
- }
-
- /// <summary>
- /// Evaluates a line
- /// </summary>
- /// <param name="line">string</param>
- /// <returns>CodeCounterLineType</returns>
- private CodeCounterLineType Evaluate(string line)
- {
- // this one is real simple a line starts with // so
- // know there is no code after and we know the next line
- // could be anything
- if (true == line.StartsWith("--"))
- return CodeCounterLineType.CommentOnly;
-
- if (true == line.StartsWith("/*"))
- {
- _isInComment = true;
-
- // because it is possible the comment terminates
- // in this same line and to ensure that we count code after the comment
- // terminates, use our EvaluateWhileInComment to determine
- // return value
- return EvaluateWhileInComment(line);
- }
-
- if (true == line.Contains("--"))
- return CodeCounterLineType.CodeAndComment;
-
- if (true == line.Contains("/*"))
- {
- _isInComment = true;
-
- // because it is possible the comment terminates
- // in this same line and to ensure that we count code after the comment
- // terminates, use our EvaluateWhileInComment to determine
- // if the comment has finished. we will ignore its return
- // value as the only possible legal value for this case is
- // CodeCounterLineType.CodeAndComment
- EvaluateWhileInComment(line);
-
- return CodeCounterLineType.CodeAndComment;
- }
-
- return CodeCounterLineType.Code;
- }
-
- #region ICodeCounterLogic Members
- /// <summary>
- ///
- /// </summary>
- /// <param name="line"></param>
- /// <returns></returns>
- public CodeCounterLineType LineType(string line)
- {
- if (true == string.IsNullOrEmpty(line))
- return CodeCounterLineType.EmptyLine;
-
- string trimmed = line.Trim();
-
- if (true == string.IsNullOrEmpty(line))
- return CodeCounterLineType.EmptyLine;
-
- if (true == _isInComment)
- return EvaluateWhileInComment(trimmed);
- else
- return Evaluate(trimmed);
- }
-
- /// <summary>
- /// should return something like cs or vb or sql etc
- /// </summary>
- /// <returns>string[]</returns>
- public string[] FileTypesHandled()
- {
- return new string[] { "sql" };
- }
-
-
- public bool CanProcessFile(string file)
- {
- FileInfo info = new FileInfo(file);
- string fileExtension = info.Extension.ToLower();
- if (".sql" == fileExtension)
- return true;
-
- return false;
- }
-
- public bool EngineCanDetermineBlankLines()
- {
- return true;
- }
-
- public void PrefileProcessing(string fileName) { }
-
- public void PostfileProcessing(string fileName) {}
-
- #endregion
- }
-}
diff --git a/BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs
deleted file mode 100644
index 60ece6fb..00000000
--- a/BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- ******************************************************************************
- This file is part of BigWoo.NET.
-
- BigWoo.NET is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- BigWoo.NET is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BigWoo.NET; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- architected and written by
- matt raffel
- matt.raffel@mindspring.com
-
- copyright (c) 2008 by matt raffel unless noted otherwise
-
- ******************************************************************************
-*/
-#region using statements
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Configuration;
-using System.IO;
-#endregion
-
-namespace CodeCounter.Library
-{
- /// <summary>
- /// XamlCodeCounterLogic
- /// </summary>
- public class XamlCodeCounterLogic : ICodeCounterLogic
- {
- private bool _isInComment = false;
-
- /// <summary>
- /// Performs all the evaluations while are stepping through
- /// a multi line comment
- /// </summary>
- /// <param name="line">string</param>
- /// <returns>CodeCounterLineType</returns>
- private CodeCounterLineType EvaluateWhileInComment(string line)
- {
- if (false == string.IsNullOrEmpty(line))
- {
- if (true == line.Contains("-->"))
- {
- _isInComment = false;
-
- int endOfCommentIndex = line.IndexOf("-->");
-
- endOfCommentIndex += 3;
-
- if (endOfCommentIndex < line.Length)
- return CodeCounterLineType.CodeAndComment;
- }
- }
-
- return CodeCounterLineType.CommentOnly;
- }
-
- /// <summary>
- /// Evaluates a line
- /// </summary>
- /// <param name="line">string</param>
- /// <returns>CodeCounterLineType</returns>
- private CodeCounterLineType Evaluate(string line)
- {
- if (true == line.StartsWith("<!--"))
- {
- _isInComment = true;
-
- // because it is possible the comment terminates
- // in this same line and to ensure that we count code after the comment
- // terminates, use our EvaluateWhileInComment to determine
- // return value
- return EvaluateWhileInComment(line);
- }
-
- if (true == line.Contains("<!--"))
- {
- _isInComment = true;
-
- // because it is possible the comment terminates
- // in this same line and to ensure that we count code after the comment
- // terminates, use our EvaluateWhileInComment to determine
- // if the comment has finished. we will ignore its return
- // value as the only possible legal value for this case is
- // CodeCounterLineType.CodeAndComment
- EvaluateWhileInComment(line);
-
- return CodeCounterLineType.CodeAndComment;
- }
-
- return CodeCounterLineType.Code;
- }
-
- #region ICodeCounterLogic Members
- /// <summary>
- ///
- /// </summary>
- /// <param name="line"></param>
- /// <returns></returns>
- public CodeCounterLineType LineType(string line)
- {
- if (true == string.IsNullOrEmpty(line))
- return CodeCounterLineType.EmptyLine;
-
- string trimmed = line.Trim();
-
- if (true == string.IsNullOrEmpty(line))
- return CodeCounterLineType.EmptyLine;
-
- if (true == _isInComment)
- return EvaluateWhileInComment(trimmed);
- else
- return Evaluate(trimmed);
- }
-
- /// <summary>
- /// should return something like cs or vb or sql etc
- /// </summary>
- /// <returns>string[]</returns>
- public string[] FileTypesHandled()
- {
- return new string[] { "xaml" };
- }
-
-
- public bool CanProcessFile(string file)
- {
- FileInfo info = new FileInfo(file);
- string fileExtension = info.Extension.ToLower();
- if (".xaml" == fileExtension)
- return true;
-
- return false;
- }
-
- public bool EngineCanDetermineBlankLines()
- {
- return true;
- }
-
- public void PrefileProcessing(string fileName) { }
-
- public void PostfileProcessing(string fileName) { }
-
- #endregion
- }
-
-}
diff --git a/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj b/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj
deleted file mode 100644
index 53193b57..00000000
--- a/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
- <PropertyGroup>
- <ProjectType>Local</ProjectType>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{A055DCC3-3C6A-123C-82F8-AD10A8B313F7}</ProjectGuid>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <AssemblyName>CodeCounter.Library</AssemblyName>
- <DefaultClientScript>JScript</DefaultClientScript>
- <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
- <DefaultTargetSchema>IE50</DefaultTargetSchema>
- <DelaySign>false</DelaySign>
- <OutputType>Library</OutputType>
- <RootNamespace>CodeCounter.Library</RootNamespace>
- <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- <OldToolsVersion>3.5</OldToolsVersion>
- <SccProjectName>SAK</SccProjectName>
- <SccLocalPath>SAK</SccLocalPath>
- <SccAuxPath>SAK</SccAuxPath>
- <SccProvider>SAK</SccProvider>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <OutputPath>bin\dll\Debug\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugSymbols>true</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <Optimize>false</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- <DebugType>full</DebugType>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <OutputPath>bin\dll\release\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <DefineConstants>TRACE</DefineConstants>
- <DebugSymbols>false</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <Optimize>true</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- <DebugType>none</DebugType>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DEBUG ALL|AnyCPU' ">
- <OutputPath>bin\DEBUG ALL\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <DebugSymbols>true</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <Optimize>false</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>1</WarningLevel>
- <DebugType>full</DebugType>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RELEASE ALL|AnyCPU' ">
- <OutputPath>bin\dll\release\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <DefineConstants>TRACE</DefineConstants>
- <DebugSymbols>false</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <Optimize>true</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- <DebugType>none</DebugType>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Big Woo.NET, Version=3.0.3287.30089, Culture=neutral, PublicKeyToken=b8a13bcc86eb719e, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\dependencies\Big Woo.NET.dll</HintPath>
- </Reference>
- <Reference Include="System">
- <Name>System</Name>
- </Reference>
- <Reference Include="System.configuration" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data">
- <Name>System.Data</Name>
- </Reference>
- <Reference Include="System.Drawing">
- <Name>System.Drawing</Name>
- </Reference>
- <Reference Include="System.Security">
- <Name>System.Security</Name>
- </Reference>
- <Reference Include="System.Windows.Forms">
- <Name>System.Windows.Forms</Name>
- </Reference>
- <Reference Include="System.Xml">
- <Name>System.XML</Name>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="CodeCounterLogicImplementers.cs" />
- <Compile Include="ConfigFileSections.cs" />
- <Compile Include="CSharpCodeCounterLogic.cs" />
- <Compile Include="CustomExceptions.cs" />
- <Compile Include="ICodeCounterLogic.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="SqlCodeCounterLogic.cs" />
- <Compile Include="XamlCodeCounterLogic.cs" />
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-</Project> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc b/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc
deleted file mode 100644
index feffdeca..00000000
--- a/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc
+++ /dev/null
@@ -1,10 +0,0 @@
-""
-{
-"FILE_VERSION" = "9237"
-"ENLISTMENT_CHOICE" = "NEVER"
-"PROJECT_FILE_RELATIVE_PATH" = ""
-"NUMBER_OF_EXCLUDED_FILES" = "0"
-"ORIGINAL_PROJECT_FILE_PATH" = ""
-"NUMBER_OF_NESTED_PROJECTS" = "0"
-"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
-}
diff --git a/BCT/Samples/Exceptions/ExceptionsExample.cs b/BCT/Samples/Exceptions/ExceptionsExample.cs
deleted file mode 100644
index 5efb69b7..00000000
--- a/BCT/Samples/Exceptions/ExceptionsExample.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-using System.Threading;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Linq;
-using System.Text;
-
-/* Simple example of exception support needed by Poirot */
-
-class PoirotMain
-{
-
- public static void foo()
- {
- throw new Exception("Error");
- }
-
- public static void Main()
- {
- int x = 5;
- try
- {
- foo();
- x = 17;
- }
- catch (Exception e)
- {
- x = 34;
- }
- Contract.Assert(x == 35);
- }
-}
-
-
-
diff --git a/BCT/Samples/Generics/GenericsExample.cs b/BCT/Samples/Generics/GenericsExample.cs
deleted file mode 100644
index c7016ceb..00000000
--- a/BCT/Samples/Generics/GenericsExample.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Linq;
-using System.Text;
-
-/* Simple example of generics/dictionary support needed by Poirot */
-class GenericsExample
-{
- public static void Main()
- {
- Dictionary<String, String> dict = new Dictionary<String, String>();
- dict["foo"] = "bar";
- Contract.Assert(dict.ContainsKey("foo"));
- Contract.Assert(dict.ContainsValue("bar"));
- Contract.Assert(dict["foo"] == "bar");
- dict.Remove("foo");
- Contract.Assert(dict["foo"] == "bar"); // should fail
- }
-} \ No newline at end of file
diff --git a/BCT/Samples/Strings/StringsExample.cs b/BCT/Samples/Strings/StringsExample.cs
deleted file mode 100644
index a04fc9a0..00000000
--- a/BCT/Samples/Strings/StringsExample.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Linq;
-using System.Text;
-
-/* Example of string functionality needed by Poirot: concatenation and equality */
-class StringsExample
-{
- public static void Main()
- {
- string foo = "delicious";
- string bar = "cake";
- Contract.Assert(!foo.Equals(bar));
- string foo_bar = foo + bar;
- Contract.Assert(foo_bar.Equals("deliciouscake"));
- string delish = "delicious";
- Contract.Assert(foo.Equals(delish));
- }
-} \ No newline at end of file
diff --git a/BCT/Test/BCTClassTest/Answer b/BCT/Test/BCTClassTest/Answer
deleted file mode 100644
index e69de29b..00000000
--- a/BCT/Test/BCTClassTest/Answer
+++ /dev/null
diff --git a/BCT/Test/BCTClassTest/BCTClassTest.sln b/BCT/Test/BCTClassTest/BCTClassTest.sln
deleted file mode 100644
index 0e70049b..00000000
--- a/BCT/Test/BCTClassTest/BCTClassTest.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BCTClassTest", "BCTClassTest\BCTClassTest.csproj", "{D0CC551E-9C5D-48D4-B048-A7B2F03FB1AE}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {D0CC551E-9C5D-48D4-B048-A7B2F03FB1AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D0CC551E-9C5D-48D4-B048-A7B2F03FB1AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D0CC551E-9C5D-48D4-B048-A7B2F03FB1AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D0CC551E-9C5D-48D4-B048-A7B2F03FB1AE}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/BCT/Test/BCTClassTest/BCTClassTest/BCTClassTest.csproj b/BCT/Test/BCTClassTest/BCTClassTest/BCTClassTest.csproj
deleted file mode 100644
index 0999556f..00000000
--- a/BCT/Test/BCTClassTest/BCTClassTest/BCTClassTest.csproj
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.21022</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{D0CC551E-9C5D-48D4-B048-A7B2F03FB1AE}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>BCTClassTest</RootNamespace>
- <AssemblyName>BCTClassTest</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>..\Binaries\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Xml.Linq">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data.DataSetExtensions">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/BCT/Test/BCTClassTest/BCTClassTest/Program.cs b/BCT/Test/BCTClassTest/BCTClassTest/Program.cs
deleted file mode 100644
index 7b5d8799..00000000
--- a/BCT/Test/BCTClassTest/BCTClassTest/Program.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BCTClassTest
-{
- abstract class BCTClassTest
- {
- public BCTClassTest()
- {
- }
-
- public abstract void AbstractMethod();
-
- public virtual int VirturalMethod(int j)
- {
- return j;
- }
-
- protected void ProtectedMethod(int j)
- {
- int i = j;
- i++;
- }
- }
-
- internal class InheritTest : BCTClassTest
- {
- public InheritTest() { }
-
- public override void AbstractMethod()
- {
- throw new NotImplementedException();
- }
-
- public override int VirturalMethod(int j)
- {
- ProtectedMethod(j);
- return base.VirturalMethod(j);
- }
- }
-
-
- class Program
- {
- static void Main(string[] args)
- {
- }
- }
-}
diff --git a/BCT/Test/BCTClassTest/BCTClassTest/Properties/AssemblyInfo.cs b/BCT/Test/BCTClassTest/BCTClassTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index f5aac42a..00000000
--- a/BCT/Test/BCTClassTest/BCTClassTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("BCTClassTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("BCTClassTest")]
-[assembly: AssemblyCopyright("Copyright © 2009")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("1e85b688-8b64-407b-8c7d-da72545d1804")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/Test/BCTClassTest/runtest.bat b/BCT/Test/BCTClassTest/runtest.bat
deleted file mode 100644
index 3c864ad0..00000000
--- a/BCT/Test/BCTClassTest/runtest.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@echo off
-setlocal
-
-set BCTDIR=..\..\Binaries
-set BEXE=%BCTDIR%\BytecodeTranslator.exe
-set TESTDIR=Binaries
-set TESTEXE=%TESTDIR%\BCTClassTest.exe
-
-for %%f in (%TESTEXE%) do (
- echo -------------------- %%f --------------------
- %BEXE% %* %%f
-)
-
diff --git a/BCT/Test/BCTStmtTest/Answer b/BCT/Test/BCTStmtTest/Answer
deleted file mode 100644
index e69de29b..00000000
--- a/BCT/Test/BCTStmtTest/Answer
+++ /dev/null
diff --git a/BCT/Test/BCTStmtTest/BCTStmtTest.sln b/BCT/Test/BCTStmtTest/BCTStmtTest.sln
deleted file mode 100644
index 1035b5eb..00000000
--- a/BCT/Test/BCTStmtTest/BCTStmtTest.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BCTStmtTest", "BCTStmtTest\BCTStmtTest.csproj", "{1016C04A-1854-4EB1-991F-64F40D1183AB}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {1016C04A-1854-4EB1-991F-64F40D1183AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1016C04A-1854-4EB1-991F-64F40D1183AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1016C04A-1854-4EB1-991F-64F40D1183AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1016C04A-1854-4EB1-991F-64F40D1183AB}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/BCT/Test/BCTStmtTest/BCTStmtTest/BCTStmtTest.csproj b/BCT/Test/BCTStmtTest/BCTStmtTest/BCTStmtTest.csproj
deleted file mode 100644
index 42f427c7..00000000
--- a/BCT/Test/BCTStmtTest/BCTStmtTest/BCTStmtTest.csproj
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.21022</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{1016C04A-1854-4EB1-991F-64F40D1183AB}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>BCTStmtTest</RootNamespace>
- <AssemblyName>BCTStmtTest</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>..\Binaries\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>..\Binaries\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Xml.Linq">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data.DataSetExtensions">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/BCT/Test/BCTStmtTest/BCTStmtTest/Program.cs b/BCT/Test/BCTStmtTest/BCTStmtTest/Program.cs
deleted file mode 100644
index a4c5e223..00000000
--- a/BCT/Test/BCTStmtTest/BCTStmtTest/Program.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BCTStmtTest
-{
- class Program
- {
- private int i;
-
- void BCTAssignments(int j)
- {
- i = 7;
- int k;
- k = i + 20;
- i = k / j;
- }
-
- int BCTConditional(int k)
- {
- int i=0;
- if (k > 5) // ite
- {
- return 7;
- }
- else
- {
- i = k / 2;
- }
-
- if (i < k) //if without else
- {
- i = 2;
- }
-
- if (k > 5) // else if
- {
- return 7;
- }
- else if (k < 5)
- {
- i = k / 2;
- }
- else
- {
- return 100;
- }
- return 0;
- }
-
- static void Main(string[] args)
- {
-
- }
- }
-}
diff --git a/BCT/Test/BCTStmtTest/BCTStmtTest/Properties/AssemblyInfo.cs b/BCT/Test/BCTStmtTest/BCTStmtTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index 402d34a8..00000000
--- a/BCT/Test/BCTStmtTest/BCTStmtTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("BCTStmtTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("BCTStmtTest")]
-[assembly: AssemblyCopyright("Copyright © 2009")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("9f9c2dec-8857-439e-8b6c-136d253cec34")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/Test/BCTStmtTest/runtest.bat b/BCT/Test/BCTStmtTest/runtest.bat
deleted file mode 100644
index 4d11e03f..00000000
--- a/BCT/Test/BCTStmtTest/runtest.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@echo off
-setlocal
-
-set BCTDIR=..\..\Binaries
-set BEXE=%BCTDIR%\BytecodeTranslator.exe
-set TESTDIR=Binaries
-set TESTEXE=%TESTDIR%\BCTStmtTest.exe
-
-for %%f in (%TESTEXE%) do (
- echo -------------------- %%f --------------------
- %BEXE% %* %%f
-)
-
diff --git a/BCT/Test/alltests.txt b/BCT/Test/alltests.txt
deleted file mode 100644
index 0c01ab99..00000000
--- a/BCT/Test/alltests.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-test0 Use Translation of Statements
-test1 Use Some simple verification tests
diff --git a/BCT/Test/build.bat b/BCT/Test/build.bat
deleted file mode 100644
index d4808ac8..00000000
--- a/BCT/Test/build.bat
+++ /dev/null
@@ -1,46 +0,0 @@
-@echo off
-setlocal
-
-set BCTDIR=..\..\Binaries
-set BEXE=%BCTDIR%\BytecodeTranslator.exe
-set TESTDIR=Binaries
-set TESTEXE=%TESTDIR%\BCTStmtTest.exe
-
-for %%f in (%TESTEXE%) do (
- echo -------------------- %%f --------------------
- call Devenv.exe MySolution.sln /build Release
-
-)
-
-@echo off
-rem Usage: runtest.bat <dir>
-if "%1" == "" goto noDirSpecified
-if not exist %1\nul goto noDirExists
-echo ----- Running regression test %1
-pushd %1
-if not exist runtest.bat goto noRunTest
-call Devenv.exe %1.sln /build Debug
-
-:passTest
-echo Succeeded
-goto end
-
-:noDirSpecified
-echo runtest: Error: Syntax: runtest testDirectory [ additionalTestArguments ... ]
-goto errorEnd
-
-:noDirExists
-echo runtest: Error: There is no test directory %1
-goto errorEnd
-
-:noRunTest
-echo runtest: Error: no runtest.bat found in test directory %1
-goto errorEnd
-
-:errorEnd
-popd
-exit /b 1
-
-:end
-popd
-exit /b 0
diff --git a/BCT/Test/buildall.bat b/BCT/Test/buildall.bat
deleted file mode 100644
index 298adae9..00000000
--- a/BCT/Test/buildall.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-@echo off
-setlocal
-
-set errors=0
-
-if "%1" == "short" goto UseShort
-
-set IncludeLong=True
-goto Loop
-
-:UseShort
-set IncludeLong=False
-shift
-goto Loop
-
-:Loop
-for /F "eol=; tokens=1,2,3*" %%i in (alltests.txt) do if %%j==Use call build.bat %%i %1 %2 %3 %4 %5 %6 %7 %8 %9 || set errors=1
-
-if not %IncludeLong%==True goto End
-
-for /F "eol=; tokens=1,2,3*" %%i in (alltests.txt) do if %%j==Long call build.bat %%i %1 %2 %3 %4 %5 %6 %7 %8 %9 || set errors=1
-
-:End
-exit /b %errors% \ No newline at end of file
diff --git a/BCT/Test/runtest.bat b/BCT/Test/runtest.bat
deleted file mode 100644
index 5002d0b3..00000000
--- a/BCT/Test/runtest.bat
+++ /dev/null
@@ -1,36 +0,0 @@
-@echo off
-rem Usage: runtest.bat <dir>
-if "%1" == "" goto noDirSpecified
-if not exist %1\nul goto noDirExists
-echo ----- Running regression test %1
-pushd %1
-if not exist runtest.bat goto noRunTest
-call runtest.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
-fc /W Answer Output.txt > nul
-:: if not errorlevel 1 goto passTest
-:: echo FAILED
-:: goto errorEnd
-
-:passTest
-echo Succeeded
-goto end
-
-:noDirSpecified
-echo runtest: Error: Syntax: runtest testDirectory [ additionalTestArguments ... ]
-goto errorEnd
-
-:noDirExists
-echo runtest: Error: There is no test directory %1
-goto errorEnd
-
-:noRunTest
-echo runtest: Error: no runtest.bat found in test directory %1
-goto errorEnd
-
-:errorEnd
-popd
-exit /b 1
-
-:end
-popd
-exit /b 0
diff --git a/BCT/Test/runtestall.bat b/BCT/Test/runtestall.bat
deleted file mode 100644
index 207bb030..00000000
--- a/BCT/Test/runtestall.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-@echo off
-setlocal
-
-set errors=0
-
-if "%1" == "short" goto UseShort
-
-set IncludeLong=True
-goto Loop
-
-:UseShort
-set IncludeLong=False
-shift
-goto Loop
-
-:Loop
-for /F "eol=; tokens=1,2,3*" %%i in (alltests.txt) do if %%j==Use call runtest.bat %%i %1 %2 %3 %4 %5 %6 %7 %8 %9 || set errors=1
-
-if not %IncludeLong%==True goto End
-
-for /F "eol=; tokens=1,2,3*" %%i in (alltests.txt) do if %%j==Long call runtest.bat %%i %1 %2 %3 %4 %5 %6 %7 %8 %9 || set errors=1
-
-:End
-exit /b %errors% \ No newline at end of file
diff --git a/BCT/Test/test0/Answer b/BCT/Test/test0/Answer
deleted file mode 100644
index 14fd2430..00000000
--- a/BCT/Test/test0/Answer
+++ /dev/null
@@ -1,99 +0,0 @@
-const unique BCTStmtTest.Program.i: int;
-
-procedure BCTStmtTest.Program.BCTAssignments$System.Void($inst: int, j$in: int);
-
-
-
-implementation BCTStmtTest.Program.BCTAssignments$System.Void($inst: int, j$in: int)
-{
- var local_0: int;
- var j: int;
-
- j := j$in;
- $heap[$this, BCTStmtTest.Program.i] := 7;
- $heap[$this, BCTStmtTest.Program.i] := local_0 / j;
- return;
-}
-
-
-
-procedure BCTStmtTest.Program.BCTConditional$System.Int32($inst: int, k$in: int) returns ($result: int);
-
-
-
-implementation BCTStmtTest.Program.BCTConditional$System.Int32($inst: int, k$in: int) returns ($result: int)
-{
- var local_1: int;
- var local_0: int;
- var k: int;
-
- k := k$in;
- if (k > 5)
- {
- local_1 := 7;
- goto IL_0055;
- }
- else
- {
- }
-
- local_0 := k / 2;
- if (local_0 < k)
- {
- local_0 := 2;
- }
- else
- {
- }
-
- if (k > 5)
- {
- local_1 := 7;
- goto IL_0055;
- }
- else
- {
- }
-
- if (k < 5)
- {
- local_0 := k / 2;
- }
- else
- {
- local_1 := 100;
- goto IL_0055;
- }
-
- IL_0055:
- $result := local_1;
- return;
-}
-
-
-
-procedure BCTStmtTest.Program.Main$System.Void($inst: int, args$in: int);
-
-
-
-implementation BCTStmtTest.Program.Main$System.Void($inst: int, args$in: int)
-{
- var args: int;
-
- args := args$in;
- return;
-}
-
-
-
-procedure BCTStmtTest.Program..ctor$System.Void($inst: int);
-
-
-
-implementation BCTStmtTest.Program..ctor$System.Void($inst: int)
-{
- return;
-}
-
-
-;ENDE
diff --git a/BCT/Test/test0/runtest.bat b/BCT/Test/test0/runtest.bat
deleted file mode 100644
index f9b744f0..00000000
--- a/BCT/Test/test0/runtest.bat
+++ /dev/null
@@ -1,19 +0,0 @@
-@echo off
-setlocal
-
-set BCTDIR=..\..\Binaries
-set BEXE=%BCTDIR%\BytecodeTranslator.exe
-
-if not exist Output.txt goto justRunTest
-del Output.txt
-
-:justRunTest
-for %%f in (*.cs) do (
- echo -------------------- %%f --------------------
- csc /nologo /t:library /debug %%~nf.cs
- %BEXE% %%~nf.dll
- type %%~nf.bpl >> Output.txt
-)
-
-
-
diff --git a/BCT/Test/test0/stmts.cs b/BCT/Test/test0/stmts.cs
deleted file mode 100644
index a4c5e223..00000000
--- a/BCT/Test/test0/stmts.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BCTStmtTest
-{
- class Program
- {
- private int i;
-
- void BCTAssignments(int j)
- {
- i = 7;
- int k;
- k = i + 20;
- i = k / j;
- }
-
- int BCTConditional(int k)
- {
- int i=0;
- if (k > 5) // ite
- {
- return 7;
- }
- else
- {
- i = k / 2;
- }
-
- if (i < k) //if without else
- {
- i = 2;
- }
-
- if (k > 5) // else if
- {
- return 7;
- }
- else if (k < 5)
- {
- i = k / 2;
- }
- else
- {
- return 100;
- }
- return 0;
- }
-
- static void Main(string[] args)
- {
-
- }
- }
-}
diff --git a/BCT/Test/test1/Answer b/BCT/Test/test1/Answer
deleted file mode 100644
index e69de29b..00000000
--- a/BCT/Test/test1/Answer
+++ /dev/null
diff --git a/BCT/Test/test1/Locals.cs b/BCT/Test/test1/Locals.cs
deleted file mode 100644
index f07c0e3f..00000000
--- a/BCT/Test/test1/Locals.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-//using System.Diagnostics.Contracts;
-
-class Program
-{
- private int i;
-
- void M0(int j) {
- i = 7;
- int k;
- k = i + 20;
- i = k / j; // error: possible division by zero
- }
-
- void M1(int j) {
- // Contract.Requires(0 < j);
- if (!(0 < j)) throw new Exception();
- i = 7;
- int k = i + 20;
- i = k / j;
- }
-}
diff --git a/BCT/Test/test1/runtest.bat b/BCT/Test/test1/runtest.bat
deleted file mode 100644
index cff01f44..00000000
--- a/BCT/Test/test1/runtest.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-@echo off
-setlocal
-
-set BCTDIR=..\..\Binaries
-set BEXE=%BCTDIR%\BytecodeTranslator.exe
-set BOOGIE=..\..\..\Binaries\Boogie.exe
-
-if not exist Output.txt goto justRunTest
-del Output.txt
-
-:justRunTest
-for %%f in (*.cs) do (
- echo -------------------- %%f --------------------
- csc /nologo /t:library /debug %%~nf.cs
- %BEXE% %%~nf.dll
- %BOOGIE% %%~nf.bpl >> Output.txt
-)
diff --git a/BCT/TraceAndTestImpact.testsettings b/BCT/TraceAndTestImpact.testsettings
deleted file mode 100644
index a6b85f3a..00000000
--- a/BCT/TraceAndTestImpact.testsettings
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<TestSettings name="Trace and Test Impact" id="cadf610f-d4f6-4ea8-9e0b-470bc35c9956" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
- <Description>These are test settings for Trace and Test Impact.</Description>
- <Execution>
- <TestTypeSpecific />
- <AgentRule name="Execution Agents">
- <DataCollectors>
- <DataCollector uri="datacollector://microsoft/SystemInfo/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo.SystemInfoDataCollector, Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="System Information">
- </DataCollector>
- <DataCollector uri="datacollector://microsoft/ActionLog/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.ManualTest.ActionLog.ActionLogPlugin, Microsoft.VisualStudio.TestTools.ManualTest.ActionLog, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Actions">
- </DataCollector>
- <DataCollector uri="datacollector://microsoft/HttpProxy/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.HttpProxyCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="ASP.NET Client Proxy for IntelliTrace and Test Impact">
- </DataCollector>
- <DataCollector uri="datacollector://microsoft/TestImpact/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.TestImpactDataCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Test Impact">
- </DataCollector>
- <DataCollector uri="datacollector://microsoft/TraceDebugger/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.TraceDebuggerDataCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="IntelliTrace">
- </DataCollector>
- </DataCollectors>
- </AgentRule>
- </Execution>
-</TestSettings> \ No newline at end of file
diff --git a/BCT/TranslationPlugins/PhoneControlsPlugin.cs b/BCT/TranslationPlugins/PhoneControlsPlugin.cs
deleted file mode 100644
index 845431ac..00000000
--- a/BCT/TranslationPlugins/PhoneControlsPlugin.cs
+++ /dev/null
@@ -1,404 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.IO;
-
-namespace TranslationPlugins {
- public enum Visibility { Visible, Collapsed };
-
- public enum Event { Click, Checked, Unchecked, SelectionChanged };
-
- public class HandlerSignature {
- public static string[] getParameterTypesForHandler(Event controlEvent) {
- switch (controlEvent) {
- case Event.Checked:
- case Event.Unchecked:
- case Event.Click:
- case Event.SelectionChanged:
- return new string[] { "object", "System.WindowsRoutedventArgs" };
- default:
- throw new NotImplementedException("Handlers for event: " + controlEvent + " not supported yet");
- }
- }
- // TODO it would be nice to be dynamic on handler names and parameters
- // TODO for now you just have to know the handler signature for each event at load time, and for now we only handle a handful of default control events
- public string Name;
- public string[] ParameterTypes;
- }
-
- public class ControlInfoStructure {
- public string Name { get; set; }
- public string ClassName { get; set; }
- public bool IsEnabled { get; set; }
- public Visibility Visible { get; set; }
- public string BplName { get; set; }
-
- private IDictionary<Event, IList<HandlerSignature>> handlers;
-
- public ControlInfoStructure() {
- handlers = new Dictionary<Event, IList<HandlerSignature>>();
- }
-
- public void setHandler(Event p, string handler) {
- IList<HandlerSignature> eventHandlers;
- try {
- eventHandlers = handlers[p];
- } catch (KeyNotFoundException) {
- eventHandlers= new List<HandlerSignature>();
- handlers[p] = eventHandlers;
- }
-
- HandlerSignature newHandler= new HandlerSignature();
- newHandler.Name= handler;
- newHandler.ParameterTypes= HandlerSignature.getParameterTypesForHandler(p);
- eventHandlers.Add(newHandler);
- }
-
- public IList<HandlerSignature> getHandlers(Event p) {
- try {
- return handlers[p];
- } catch (KeyNotFoundException) {
- return new List<HandlerSignature>();
- }
- }
- }
-
- class PageStructure {
- public PageStructure() {
- controlsInfo = new Dictionary<string, ControlInfoStructure>();
- }
-
- public string PageBoogieName { get; set; }
- public string PageClassName { get; set; }
- public string PageXAML { get; set; }
- public bool IsMainPage { get; set; }
-
- private IDictionary<string, ControlInfoStructure> controlsInfo;
- public ControlInfoStructure getControlInfo(string controlName) {
- try {
- return controlsInfo[controlName];
- } catch (KeyNotFoundException) {
- return null;
- }
- }
-
- public void setControlInfo(string controlName, ControlInfoStructure controlInfo) {
- controlsInfo[controlName] = controlInfo;
- }
-
- public IEnumerable<ControlInfoStructure> getAllControlsInfo() {
- return controlsInfo.Values.AsEnumerable();
- }
- }
-
- public class PhoneControlsPlugin : TranslationPlugin {
- // TODO this will probably need a complete rewrite once it is event based, and make it more push than pull
- // TODO but it doesn't make sense right now to make it BCT or CCI aware
- private static int CONFIG_LINE_FIELDS= 12;
- private static int PAGE_CLASS_FIELD= 0;
- private static int PAGE_XAML_FIELD= 1;
- private static int PAGE_BOOGIE_STRING_FIELD = 2;
- private static int CONTROL_CLASS_FIELD= 3;
- private static int CONTROL_NAME_FIELD= 4;
- private static int ENABLED_FIELD= 5;
- private static int VISIBILITY_FIELD= 6;
- private static int CLICK_HANDLER_FIELD= 7;
- private static int CHECKED_HANDLER_FIELD= 8;
- private static int UNCHECKED_HANDLER_FIELD = 9;
- private static int SELECTIONCHANGED_HANDLER_FIELD = 10;
- private static int BPL_NAME_FIELD = 11;
-
- public const string BOOGIE_DUMMY_CONTROL = "__BOOGIE_DUMMY_CONTROLNAME_";
-
- private IDictionary<string, PageStructure> pageStructureInfo;
-
- public static string getURILastPath(string uri) {
- // I need to build an absolute URI just to call getComponents() ...
- Uri mockBaseUri = new Uri("mock://mock/", UriKind.RelativeOrAbsolute);
- Uri realUri;
- try {
- realUri = new Uri(uri, UriKind.Absolute);
- } catch (UriFormatException) {
- // uri string is relative
- realUri = new Uri(mockBaseUri, uri);
- }
-
- string str = realUri.GetComponents(UriComponents.Path | UriComponents.StrongAuthority | UriComponents.Scheme, UriFormat.UriEscaped);
- Uri mockStrippedUri = new Uri(str);
- return mockBaseUri.MakeRelativeUri(mockStrippedUri).ToString();
- }
-
- //public static string getFullyQualifiedControlClass(string controlClass) {
- // // TODO do an actual API discovery. The problem will be differencing 7.0 apps from 7.1 apps
- // return "System.Windows.Controls." + controlClass;
- //}
-
- public PhoneControlsPlugin(string configFile) {
- pageStructureInfo = new Dictionary<string, PageStructure>();
- StreamReader fileStream = null;
- try {
- fileStream = new StreamReader(configFile);
- } catch (Exception e) {
- if (e is DirectoryNotFoundException || e is FileNotFoundException || e is IOException) {
- // TODO log, I don't want to terminate BCT because of this
- throw;
- } else if (e is ArgumentException || e is ArgumentNullException) {
- // TODO log, I don't want to terminate BCT because of this
- throw;
- } else {
- throw;
- }
- }
-
- LoadControlStructure(fileStream);
-
- if (fileStream != null)
- fileStream.Close();
- }
-
- public string getMainPageXAML() {
- KeyValuePair<string, PageStructure> entry= pageStructureInfo.FirstOrDefault(keyValue => keyValue.Value.IsMainPage);
- return entry.Value.PageXAML;
- }
-
- private string boogieCurrentNavigationVariable;
- public string getBoogieNavigationVariable() {
- return boogieCurrentNavigationVariable;
- }
-
- public void setBoogieNavigationVariable(string var) {
- boogieCurrentNavigationVariable = var;
- }
-
- private void setPageAsMainPage(string pageXAML) {
- pageXAML = pageXAML.ToLower();
- int lastDirPos= pageXAML.LastIndexOf('/');
- if (lastDirPos != -1)
- pageXAML = pageXAML.Substring(lastDirPos+1);
- KeyValuePair<string,PageStructure> mainPageClass= pageStructureInfo.FirstOrDefault(keyValue => keyValue.Value.PageXAML.ToLower() == pageXAML.ToLower());
- if (mainPageClass.Equals(default(KeyValuePair<string, PageStructure>))) {
- // the main page doesn't exist because it has no tracked controls. While we cannot track those controls, create a page struct for it
- } else {
- mainPageClass.Value.IsMainPage = true;
- }
- }
-
- private string mainAppTypeName;
- public void setMainAppTypeName(string typeName) {
- mainAppTypeName= typeName;
- }
-
- public string getMainAppTypeName() {
- return mainAppTypeName;
- }
-
- public void DumpControlStructure(StreamWriter outputStream) {
- // maintain same format as input format
- string pageClass, pageXAML, pageBoogieStringName, controlClass, controlName, enabled, visibility, clickHandler,
- checkedHandler, uncheckedHandler, selectionChangedHandler, bplName;
- outputStream.WriteLine(getMainPageXAML());
- outputStream.WriteLine(getBoogieNavigationVariable());
- outputStream.WriteLine(getMainAppTypeName());
-
- foreach (KeyValuePair<string, PageStructure> entry in this.pageStructureInfo) {
- pageClass = entry.Key;
- pageXAML = entry.Value.PageXAML.ToLower();
- pageBoogieStringName = entry.Value.PageBoogieName;
- foreach (ControlInfoStructure controlInfo in entry.Value.getAllControlsInfo()) {
- controlClass= controlInfo.ClassName;
- controlName = controlInfo.Name;
- enabled= controlInfo.IsEnabled ? "true" : "false";
- switch (controlInfo.Visible) {
- case Visibility.Collapsed:
- visibility = "Collapsed";
- break;
- default:
- visibility = "Visible";
- break;
- }
- IEnumerable<HandlerSignature> handlers= controlInfo.getHandlers(Event.Click);
- if (handlers.Any()) {
- clickHandler = handlers.First().Name;
- } else {
- clickHandler = "";
- }
-
- handlers = controlInfo.getHandlers(Event.Checked);
- if (handlers.Any()) {
- checkedHandler = handlers.First().Name;
- } else {
- checkedHandler = "";
- }
-
- handlers = controlInfo.getHandlers(Event.Unchecked);
- if (handlers.Any()) {
- uncheckedHandler = handlers.First().Name;
- } else {
- uncheckedHandler = "";
- }
-
- handlers = controlInfo.getHandlers(Event.SelectionChanged);
- if (handlers.Any()) {
- selectionChangedHandler= handlers.First().Name;
- } else {
- selectionChangedHandler = "";
- }
- bplName = controlInfo.BplName;
- outputStream.WriteLine(pageClass + "," + pageXAML.ToLower() + "," + pageBoogieStringName + "," + controlClass + "," + controlName + "," + enabled + "," +
- visibility + "," + clickHandler + "," + checkedHandler + "," + uncheckedHandler + "," + selectionChangedHandler + "," +
- bplName);
- }
- }
- }
-
- public void setBoogieStringPageNameForPageClass(string pageClass, string boogieStringPageName) {
- pageStructureInfo[pageClass].PageBoogieName = boogieStringPageName;
- }
-
- private static int dummyControlNameIndex = 0;
- private void LoadControlStructure(StreamReader configStream) {
- // FEEDBACK TODO. Easy check on Feedback issue: Button and HyperLinkButton MUST have a Click handler, if not, it is obvious there is no feedback
-
- // TODO it would be nice to have some kind of dynamic definition of config format
- // TODO for now remember that config format is CSV
- // TODO each line is <pageClassName>,<pageXAMLPath>,<pageBoogieStringName>,<controlClassName>,<controlName>,<IsEnabledValue>,<VisibilityValue>,<ClickValue>,<CheckedValue>,<UncheckedValue>,<BPL control name>
- // TODO BPL control name will most probably be empty, but it is useful to be able to dump it
- // TODO check PhoneControlsExtractor.py and PhoneBoogieCodeCreator.py
-
- // TODO the page.xaml value is saved with no directory information: if two pages exist with same name but different directories it will treat them as the same
- // TODO I'm not handling this for now, and I won't be handling relative/absolute URI either for now
-
- string pageClass, pageXAML, pageBoogieStringName, controlClass, controlName, enabled, visibility, clickHandler, checkedHandler,
- uncheckedHandler, selectionChangedHandler, bplName;
- string configLine = configStream.ReadLine();
- string[] inputLine;
- PageStructure pageStr;
- ControlInfoStructure controlInfoStr;
-
- // first line just states the main page xaml
- string mainPageXAML= configLine.Trim().ToLower();
- configLine = configStream.ReadLine();
-
- // second line states boogie current nav variable, possibly dummy value
- setBoogieNavigationVariable(configLine.Trim());
- configLine= configStream.ReadLine();
-
- // third line is main phone app type, possibly dummy;
- setMainAppTypeName(configLine.Trim());
- configLine = configStream.ReadLine();
-
- while (configLine != null) {
- if (configLine.Trim().Equals(string.Empty)) {
- configLine = configStream.ReadLine();
- continue;
- }
- inputLine = configLine.Split(',');
-
- if (inputLine.Length != CONFIG_LINE_FIELDS)
- throw new ArgumentException("Config input line contains wrong number of fields: " + inputLine.Length + ", expected " + CONFIG_LINE_FIELDS);
-
- pageClass = inputLine[PAGE_CLASS_FIELD].Trim();
- pageXAML = inputLine[PAGE_XAML_FIELD].Trim().ToLower();
- pageBoogieStringName = inputLine[PAGE_BOOGIE_STRING_FIELD].Trim();
- controlClass = inputLine[CONTROL_CLASS_FIELD].Trim();
- controlName = inputLine[CONTROL_NAME_FIELD].Trim();
- if (string.IsNullOrEmpty(controlName))
- controlName = BOOGIE_DUMMY_CONTROL + dummyControlNameIndex++;
-
- enabled = inputLine[ENABLED_FIELD].Trim();
- visibility = inputLine[VISIBILITY_FIELD].Trim();
- clickHandler = inputLine[CLICK_HANDLER_FIELD].Trim();
- checkedHandler = inputLine[CHECKED_HANDLER_FIELD].Trim();
- uncheckedHandler = inputLine[UNCHECKED_HANDLER_FIELD].Trim();
- selectionChangedHandler = inputLine[SELECTIONCHANGED_HANDLER_FIELD].Trim();
- bplName = inputLine[BPL_NAME_FIELD].Trim();
-
- try {
- pageStr = pageStructureInfo[pageClass];
- } catch (KeyNotFoundException) {
- pageStr = new PageStructure();
- pageStr.PageClassName = pageClass;
- pageStr.PageXAML = pageXAML;
- pageStr.PageBoogieName = pageBoogieStringName;
- pageStr.IsMainPage = false;
- }
-
- controlInfoStr= pageStr.getControlInfo(controlName);
- if (controlInfoStr == null) {
- controlInfoStr = new ControlInfoStructure();
- controlInfoStr.Name = controlName;
- controlInfoStr.ClassName = controlClass;
- controlInfoStr.BplName = bplName;
- }
- controlInfoStr.IsEnabled = enabled.ToLower() == "false" ? false : true;
- controlInfoStr.Visible = visibility == "Collapsed" ? Visibility.Collapsed : Visibility.Visible;
- controlInfoStr.setHandler(Event.Click, clickHandler);
- controlInfoStr.setHandler(Event.Checked, checkedHandler);
- controlInfoStr.setHandler(Event.Unchecked, uncheckedHandler);
- controlInfoStr.setHandler(Event.SelectionChanged, selectionChangedHandler);
-
- pageStr.setControlInfo(controlName, controlInfoStr);
- pageStructureInfo[pageClass] = pageStr;
- configLine = configStream.ReadLine();
- }
-
- setPageAsMainPage(mainPageXAML);
- }
-
- public IEnumerable<ControlInfoStructure> getControlsForPage(string pageClass) {
- try {
- return pageStructureInfo[pageClass].getAllControlsInfo();
- } catch (KeyNotFoundException) {
- return null;
- }
- }
-
- public string getXAMLForPage(string pageClass) {
- try {
- return pageStructureInfo[pageClass].PageXAML;
- } catch (KeyNotFoundException) {
- return null;
- }
- }
-
- public bool getIsEnabled(string pageClass, string controlName) {
- try {
- return pageStructureInfo[pageClass].getControlInfo(controlName).IsEnabled;
- } catch (KeyNotFoundException) {
- //TODO not really correct
- return false;
- }
- }
-
- public Visibility getVisibility(string pageClass, string controlName) {
- try {
- return pageStructureInfo[pageClass].getControlInfo(controlName).Visible;
- } catch (KeyNotFoundException) {
- // TODO not really correct
- return default(Visibility);
- }
- }
-
- public IList<HandlerSignature> getHandlers(string pageClass, string controlName, string eventName) {
- if (eventName != "Checked" && eventName != "Unchecked" && eventName != "Click")
- throw new NotImplementedException("Event " + eventName + " is not translated or defined for control " + controlName + " in page " + pageClass);
-
- try {
- return pageStructureInfo[pageClass].getControlInfo(controlName).getHandlers((Event) Event.Parse(typeof(Event), eventName));
- } catch (KeyNotFoundException) {
- return null;
- }
- }
-
- public IEnumerable<string> getPageXAMLFilenames() {
- HashSet<string> pageXAMLs = new HashSet<string>();
- foreach (string name in this.pageStructureInfo.Keys) {
- if (!name.EndsWith("__dummy"))
- pageXAMLs.Add(pageStructureInfo[name].PageXAML);
- }
-
- return pageXAMLs;
- }
- }
-}
diff --git a/BCT/TranslationPlugins/Properties/AssemblyInfo.cs b/BCT/TranslationPlugins/Properties/AssemblyInfo.cs
deleted file mode 100644
index 8158eb08..00000000
--- a/BCT/TranslationPlugins/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TranslationPlugins")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("TranslationPlugins")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("c26f68f2-14fb-4a47-8707-b7de569865cc")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/TranslationPlugins/TranslationPlugin.cs b/BCT/TranslationPlugins/TranslationPlugin.cs
deleted file mode 100644
index e8907a09..00000000
--- a/BCT/TranslationPlugins/TranslationPlugin.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace TranslationPlugins {
- public class TranslationPlugin {
- // TODO ideally these should really work as plugins, possibly registering as callbacks to some BCT events.
- }
-}
diff --git a/BCT/TranslationPlugins/TranslationPlugins.csproj b/BCT/TranslationPlugins/TranslationPlugins.csproj
deleted file mode 100644
index 9a27e949..00000000
--- a/BCT/TranslationPlugins/TranslationPlugins.csproj
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{8C242D42-9714-440F-884D-F64F09E78C7B}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>TranslationPlugins</RootNamespace>
- <AssemblyName>TranslationPlugins</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="PhoneControlsPlugin.cs" />
- <Compile Include="TranslationPlugin.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/Binaries/PrepareBoogieZip.bat b/Binaries/PrepareBoogieZip.bat
index ff0dace1..5a1b267f 100644
--- a/Binaries/PrepareBoogieZip.bat
+++ b/Binaries/PrepareBoogieZip.bat
@@ -2,8 +2,6 @@
setlocal
set DEST_DIR=export
-set DAFNY_ROOT=..\..\dafny
-set DAFNY_BIN=%DAFNY_ROOT%\Binaries
if exist %DEST_DIR% del /q %DEST_DIR%\*
if not exist %DEST_DIR% mkdir %DEST_DIR%
@@ -25,15 +23,10 @@ for %%f in (
UnivBackPred2.smt UnivBackPred2.smt2
VCExpr.dll VCExpr.pdb
VCGeneration.dll VCGeneration.pdb
- "%DAFNY_BIN%\Dafny.exe" "%DAFNY_BIN%\Dafny.pdb"
- "%DAFNY_BIN%\DafnyPrelude.bpl" "%DAFNY_BIN%\DafnyRuntime.cs"
- "%DAFNY_BIN%\DafnyPipeline.dll" "%DAFNY_BIN%\DafnyPipeline.pdb"
- "%DAFNY_ROOT%\Source\DafnyExtension\bin\Debug\DafnyLanguageService.vsix"
) do (
copy %%f %DEST_DIR%
)
xcopy /E /I /Y CodeContracts "%DEST_DIR%/CodeContracts"
-xcopy /E /I /Y "%DAFNY_BIN%\CodeContracts" "%DEST_DIR%/CodeContracts"
echo Done. Now, manually put the contents of the %DEST_DIR% directory into Boogie.zip
diff --git a/Chalice/build.sbt b/Chalice/build.sbt
deleted file mode 100644
index ea32574f..00000000
--- a/Chalice/build.sbt
+++ /dev/null
@@ -1,10 +0,0 @@
-
-name := "Chalice"
-
-version := "1.0"
-
-scalaVersion := "2.9.2"
-
-scalacOptions += "-deprecation"
-
-libraryDependencies += "org.scalatest" %% "scalatest" % "1.7.1" % "test"
diff --git a/Chalice/chalice.bat b/Chalice/chalice.bat
deleted file mode 100644
index 66dc095c..00000000
--- a/Chalice/chalice.bat
+++ /dev/null
@@ -1,55 +0,0 @@
-@echo off
-SetLocal EnableDelayedExpansion
-
-set ROOT_DIR=%~dp0
-set JAVA_EXE=java
-
-REM Attention: 'where' might not be available on all Windows versions
-call where %JAVA_EXE% > NUL
-if not %ERRORLEVEL%==0 (
- echo Java could not be started.
- goto :exit_with_error
-)
-
-
-set SCALA_DIR=scala-2.9.2
-
-REM Set classpath elements
-set __CP.SCALA_LIB="%ROOT_DIR%project\boot\%SCALA_DIR%\lib\scala-library.jar"
-set __CP.CHALICE="%ROOT_DIR%target\%SCALA_DIR%\classes"
-
-REM Assemble classpath and check if all classpath elements exist
-set CP=
-for /f "tokens=2* delims=.=" %%A in ('set __CP.') do (
- REM echo %%A %%B
- if not exist %%B (
- echo %%B does not exist.
- goto :exit_with_error
- ) else (
- set CP=!CP!;%%B
- )
-)
-
-REM Chalice main class
-set CHALICE_MAIN=chalice.Chalice
-
-REM Chalice command line options
-set CHALICE_OPTS=
-set CHALICE_OPTS=%CHALICE_OPTS% /boogieOpt:nologo
-set CHALICE_OPTS=%CHALICE_OPTS% /boogieOpt:noinfer
-set CHALICE_OPTS=%CHALICE_OPTS% %*
-
-REM Assemble main command
-set CMD=%JAVA_EXE% -cp %CP% -Xss16M %CHALICE_MAIN% %CHALICE_OPTS%
-
-REM echo.
-REM echo %CMD%
-REM echo.
-
-call %CMD%
-
-exit /B 0
-
-
-:exit_with_error
-exit /B 1
diff --git a/Chalice/doc/ast_2010-11-13.pdf b/Chalice/doc/ast_2010-11-13.pdf
deleted file mode 100644
index ec4b81ba..00000000
--- a/Chalice/doc/ast_2010-11-13.pdf
+++ /dev/null
Binary files differ
diff --git a/Chalice/doc/ast_a3tiles_2010-11-13.pdf b/Chalice/doc/ast_a3tiles_2010-11-13.pdf
deleted file mode 100644
index 2338a0fd..00000000
--- a/Chalice/doc/ast_a3tiles_2010-11-13.pdf
+++ /dev/null
Binary files differ
diff --git a/Chalice/readme.txt b/Chalice/readme.txt
deleted file mode 100644
index f282da3c..00000000
--- a/Chalice/readme.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-Chalice - Verification of Concurrent Software
-=============================================
-
-Compiling Chalice: sbt compile
-Running Chalice: chalice.bat <file.chalice> [-params]
- By default, chalice looks for Boogie in C:\Boogie\Binaries. If your
- Boogie executable is located elsewhere, you can edit chalice.bat
- to indicate the appropriate location such as
- REM Chalice command line options
- set CHALICE_OPTS=/boogie:"C:\Boogie-CodePlex\Binaries\Boogie.exe"
-Running the tests for Chalice: see tests/readme.txt
-
-Chalice is built using Simple Build Tool (https://github.com/harrah/xsbt/wiki/Setup)
-
-Note: You might have to increase the stack size of the JVM to avoid a stack
-overflow, for instance by changing scala.bat by adding "-Xss16M" to the
-JAVA_OPTS:
- if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=-Xmx256M -Xms32M -Xss16M
diff --git a/Chalice/sbt b/Chalice/sbt
deleted file mode 100755
index b1dee4bb..00000000
--- a/Chalice/sbt
+++ /dev/null
@@ -1 +0,0 @@
-java -XX:MaxPermSize=256m -Xmx512M -Xss2M -jar `dirname $0`/sbt-launch.jar "$@" \ No newline at end of file
diff --git a/Chalice/sbt-launch.jar b/Chalice/sbt-launch.jar
deleted file mode 100644
index 673495f7..00000000
--- a/Chalice/sbt-launch.jar
+++ /dev/null
Binary files differ
diff --git a/Chalice/sbt.bat b/Chalice/sbt.bat
deleted file mode 100644
index 4c92a4b3..00000000
--- a/Chalice/sbt.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-@ECHO OFF
-SetLocal
-
-set SCRIPT_DIR=%~dp0
-java %JAVA_OPTS% -XX:MaxPermSize=256m -Xmx512M -Xss2M -jar "%SCRIPT_DIR%sbt-launch.jar" %*
diff --git a/Chalice/scripts/create_release/README.TXT b/Chalice/scripts/create_release/README.TXT
deleted file mode 100644
index b416a241..00000000
--- a/Chalice/scripts/create_release/README.TXT
+++ /dev/null
@@ -1,3 +0,0 @@
-This script is invoked by Aste (the build tool creating Chalice nightlies). Hence, don't move it to another location!
-
-The script will be replaced with an sbt action sooner or later anyway. \ No newline at end of file
diff --git a/Chalice/scripts/create_release/create_release.bat b/Chalice/scripts/create_release/create_release.bat
deleted file mode 100644
index 5aadd36e..00000000
--- a/Chalice/scripts/create_release/create_release.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-@echo off
-SetLocal
-
-set BASE_DIR=%~dp0\..\..
-
-set RELEASE_DIR_SRC=%~dp0\files
-set RELEASE_DIR_DST=%~dp0\release
-
-set CHALICE_JAR_SRC=%BASE_DIR%\target\scala-2.9.2\chalice_2.9.2-1.0.jar
-set CHALICE_JAR_DST=%RELEASE_DIR_DST%\chalice.jar
-
-pushd %BASE_DIR%
-call sbt.bat package
-
-popd
-
-if exist "%RELEASE_DIR_DST%" rmdir /S /Q "%RELEASE_DIR_DST%"
-mkdir "%RELEASE_DIR_DST%"
-
-copy "%CHALICE_JAR_SRC%" "%CHALICE_JAR_DST%"
-copy "%RELEASE_DIR_SRC%\*.*" "%RELEASE_DIR_DST%"
-copy "%RELEASE_DIR_SRC%\*.*" "%RELEASE_DIR_DST%"
-
-xcopy %BASE_DIR%\tests\examples %RELEASE_DIR_DST%\examples\ \ No newline at end of file
diff --git a/Chalice/scripts/create_release/files/chalice.bat b/Chalice/scripts/create_release/files/chalice.bat
deleted file mode 100644
index d70d05b8..00000000
--- a/Chalice/scripts/create_release/files/chalice.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-@echo off
-
-call scala -cp chalice.jar chalice.Chalice /boogieOpt:nologo %*
-
-exit /B 0
diff --git a/Chalice/src/main/scala/Ast.scala b/Chalice/src/main/scala/Ast.scala
deleted file mode 100644
index b8a92f7c..00000000
--- a/Chalice/src/main/scala/Ast.scala
+++ /dev/null
@@ -1,953 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-import scala.util.parsing.input.Position
-import scala.util.parsing.input.NoPosition
-import scala.util.parsing.input.Positional
-
-trait ASTNode extends Positional
-
-/**
- * Classes and types
- */
-
-sealed abstract class TopLevelDecl(val id: String) extends ASTNode
-
-sealed case class Class(classId: String, parameters: List[Class], module: String, members: List[Member]) extends TopLevelDecl(classId) {
- def IsInt: Boolean = false
- def IsBool: Boolean = false
- def IsRef: Boolean = true
- def IsNull: Boolean = false
- def IsString: Boolean = false
- def IsMu: Boolean = false
- def IsSeq: Boolean = false
- def IsToken: Boolean = false
- def IsChannel: Boolean = false
- def IsState: Boolean = false
- def IsNormalClass = true
- def IsPermission = false
-
- lazy val DeclaredFields = members flatMap {case x: Field => List(x); case _ => Nil}
- lazy val MentionableFields = Fields filter {x => ! x.Hidden}
- lazy val MonitorInvariants = members flatMap {case x: MonitorInvariant => List(x); case _ => Nil}
- lazy val Fields:List[Field] = DeclaredFields ++ (if (IsRefinement) refines.Fields else Nil)
-
- private lazy val id2member:Map[String,NamedMember] = Map() ++ {
- val named = members flatMap {case x: NamedMember => List(x); case _ => Nil};
- (named map {x => x.Id}) zip named
- }
- def LookupMember(id: String): Option[NamedMember] = {
- if (id2member contains id)
- Some(id2member(id))
- else if (IsRefinement)
- refines.LookupMember(id)
- else if (IsRef && this != RootClass) {
- // check with root class
- RootClass LookupMember id match {
- case Some(m) if (! m.Hidden) => Some(m)
- case _ => None
- }
- } else
- None
- }
- def FullName: String = if(parameters.isEmpty) id else id + "<" + parameters.tail.foldLeft(parameters.head.FullName){(a, b) => a + ", " + b.FullName} + ">"
- override def toString = FullName
-
- // Says whether or not to compile the class (compilation ignores external classes)
- var IsExternal = false
-
- // Refinement extension
- var IsRefinement = false
- var refinesId: String = null
- var refines: Class = null
- lazy val CouplingInvariants = members flatMap {case x: CouplingInvariant => List(x); case _ => Nil}
- lazy val Replaces: List[Field] = CouplingInvariants flatMap (_.fields)
-}
-
-sealed case class Channel(channelId: String, parameters: List[Variable], private val rawWhere: Expression) extends TopLevelDecl(channelId) {
- lazy val where: Expression = rawWhere.transform {
- case Epsilon | MethodEpsilon => Some(ChannelEpsilon(None))
- case _ => None
- }
-}
-
-sealed case class SeqClass(parameter: Class) extends Class("seq", List(parameter), "default", Nil) {
- override def IsRef = false;
- override def IsSeq = true;
- override def IsNormalClass = false
-}
-object PermClass extends Class("$Permission", Nil, "default", Nil) {
- override def IsRef = false
- override def IsPermission = true
- override def IsNormalClass = false
-}
-object IntClass extends Class("int", Nil, "default", Nil) {
- override def IsRef = false
- override def IsInt = true
- override def IsNormalClass = false
-}
-object BoolClass extends Class("bool", Nil, "default", Nil) {
- override def IsRef = false
- override def IsBool = true
- override def IsNormalClass = false
-}
-object NullClass extends Class("null", Nil, "default", Nil) {
- override def IsNull = true
- override def IsNormalClass = false
-}
-object StringClass extends Class("string", Nil, "default", Nil) {
- override def IsRef = false
- override def IsString = true
- override def IsNormalClass = false
-}
-object MuClass extends Class("$Mu", Nil, "default", Nil) {
- override def IsRef = false
- override def IsMu = true
- override def IsNormalClass = false
-}
-case class TokenClass(c: Type, m: String) extends Class("token", Nil, "default", List(
- new SpecialField("joinable", new Type(BoolClass), false)
-))
-{
- var method = null: Method
- override def IsRef = true
- override def IsToken = true
- override def IsNormalClass = false
- override def FullName: String = "token<" + c.FullName + "." + m + ">"
-}
-case class ChannelClass(ch: Channel) extends Class(ch.id, Nil, "default", Nil) {
- override def IsRef = true
- override def IsChannel = true
- override def IsNormalClass = false
-}
-
-object RootClass extends Class("$root", Nil, "default", List(
- new SpecialField("mu", new Type(MuClass), false),
- new SpecialField("held", new Type(BoolClass), true),
- new SpecialField("rdheld", new Type(BoolClass), true)
- )) // joinable and held are bool in Chalice, but translated into an int in Boogie
-
-sealed case class Type(id: String, params: List[Type]) extends ASTNode { // denotes the use of a type
- if (id equals "seq") TranslatorPrelude.addComponent(AxiomatizationOfSequencesPL) // include sequence axioms if necessary
- var typ: Class = null
- def this(id: String) = { this(id, Nil); }
- def this(cl: Class) = { this(cl.id); typ = cl }
- def FullName: String = if(params.isEmpty) id else id + "<" + params.tail.foldLeft(params.head.FullName){(a, b) => a + ", " + b.FullName} + ">"
-}
-
-sealed case class TokenType(C: Type, m: String) extends Type("token", Nil) { // denotes the use of a type
- typ = TokenClass(C, m);
- var method = null : Method;
-
- override def FullName: String = "token<" + C.FullName + "." + m + ">"
-}
-
-/**
- * Members
- */
-
-sealed abstract class Member extends ASTNode {
- val Hidden: Boolean = false // hidden means not mentionable in source
-}
-case class MonitorInvariant(private val rawE: Expression) extends Member {
- lazy val e: Expression = rawE.transform {
- case Epsilon | MethodEpsilon => Some(MonitorEpsilon(None))
- case _ => None
- }
-}
-
-sealed abstract class NamedMember(id: String) extends Member {
- val Id = id
- var Parent: Class = null
- def FullName = Parent.id + "." + Id
-}
-case class Field(id: String, typ: Type, isGhost: Boolean) extends NamedMember(id)
-case class SpecialField(name: String, tp: Type, hidden: Boolean) extends Field(name, tp, false) { // direct assignments are not allowed to a SpecialField
- override def FullName = id
- override val Hidden = hidden
-}
-sealed abstract class Callable(id: String) extends NamedMember(id) {
- def Spec:List[Specification]
- def Body:List[Statement]
- def Ins:List[Variable]
- def Outs:List[Variable]
-}
-case class Method(id: String, ins: List[Variable], outs: List[Variable], spec: List[Specification], body: List[Statement]) extends Callable(id) {
- override def Spec = spec
- override def Body = body
- override def Ins = ins
- override def Outs = outs
-}
-case class Predicate(id: String, private val rawDefinition: Expression) extends NamedMember(id) {
- TranslatorPrelude.addPredicate(this)
- lazy val definition: Expression = rawDefinition.transform {
- case Epsilon | MethodEpsilon => Some(PredicateEpsilon(None))
- case _ => None
- }
-}
-case class Function(id: String, ins: List[Variable], out: Type, spec: List[Specification], definition: Option[Expression]) extends NamedMember(id) {
- // list of predicates that this function possibly depends on (that is, predicates
- // that are mentioned in the functions precondition)
- def dependentPredicates: List[Predicate] = {
- var predicates: List[Predicate] = List()
- spec foreach {
- case Precondition(e) =>
- e visit {_ match {
- case pred@MemberAccess(e, p) if pred.isPredicate =>
- predicates = pred.predicate :: predicates
- case _ =>}
- }
- case _ =>
- }
- predicates
- }
- def apply(rec: Expression, args: List[Expression]): FunctionApplication = {
- val result = FunctionApplication(rec, id, args);
- result.f = this;
- result
- }
- var isUnlimited = false
- var isStatic = false
- var isRecursive = false
- var SCC: List[Function] = Nil
- // the 'height' of this function is determined by a topological sort of the
- // condensation of the call graph; mutually recursive functions get the same
- // height.
- var height: Int = -1
-}
-case class Condition(id: String, where: Option[Expression]) extends NamedMember(id)
-case class Variable(id: String, t: Type, isGhost: Boolean, isImmutable: Boolean) extends ASTNode {
- val UniqueName = {
- val n = S_Variable.VariableCount
- S_Variable.VariableCount = S_Variable.VariableCount + 1
- id + "#" + n
- }
- val Id = id;
- def this(name: String, typ: Type) = this(name,typ,false,false);
- override def toString = (if (isGhost) "ghost " else "") + (if (isImmutable) "const " else "var ") + id;
-}
-object S_Variable { var VariableCount = 0 }
-case class SpecialVariable(name: String, typ: Type) extends Variable(name, typ, false, false) {
- override val UniqueName = name
-}
-sealed abstract class Specification extends ASTNode
-case class Precondition(e: Expression) extends Specification
-case class Postcondition(e: Expression) extends Specification
-case class LockChange(ee: List[Expression]) extends Specification
-
-/**
- * Refinement members
- */
-
-case class CouplingInvariant(ids: List[String], e: Expression) extends Member {
- assert(ids.size > 0)
- var fields: List[Field] = Nil
- /* Distribute 100 between fields */
- def fraction(field: Field): Permission = {
- val k = fields.indexOf(field)
- assert (0 <= k && k < fields.size)
- val part: Int = 100 / fields.size
- if (k == fields.size - 1)
- Frac(IntLiteral(100 - part * k))
- else
- Frac(IntLiteral(part) )
- }
-}
-case class MethodTransform(id: String, ins: List[Variable], outs: List[Variable], spec: List[Specification], trans: Transform) extends Callable(id) {
- var refines = null: Callable
- var body = null:List[Statement]
- def Spec = {assert(refines != null); refines.Spec ++ spec}
- def Body = {
- assert(body != null);
- // make sure the body appears as if it is from a normal method
- def concretize(ss: List[Statement]): List[Statement] = ss flatMap {
- case r @ RefinementBlock(con, abs) =>
- con :::
- (for ((a,c) <- (r.during._1 zip r.during._2)) yield LocalVar(a, Some(new VariableExpr(c))))
- case BlockStmt(ss) => List(BlockStmt(concretize(ss)))
- case IfStmt(guard, BlockStmt(thn), None) => List(IfStmt(guard, BlockStmt(concretize(thn)), None))
- case IfStmt(guard, BlockStmt(thn), Some(els)) => List(IfStmt(guard, BlockStmt(concretize(thn)), Some(BlockStmt(concretize(List(els))))))
- case WhileStmt(guard, oi, ni, lks, BlockStmt(ss)) => List(WhileStmt(guard, oi ++ ni, Nil, lks, BlockStmt(concretize(ss))))
- case s => List(s)
- }
- concretize(body)
- }
- def Ins = {assert(refines != null); refines.Ins}
- def Outs = {assert(refines != null); refines.Outs ++ outs.drop(refines.Outs.size)}
-}
-
-sealed abstract class Transform extends ASTNode
-/** Pattern matching within a block (zero or more) over deterministic statements */
-case class BlockPat() extends Transform {
- def matches(s: Statement) = s match {
- case _:Assert => true
- case _:Assume => true
- case _:Assign => true
- case _:FieldUpdate => true
- case _:LocalVar => true
- case _ => false
- }
-}
-/** Matches any block of code (greedily) and acts as identity */
-case class SkipPat() extends Transform
-/** Replacement pattern for arbitrary block */
-case class ProgramPat(code: List[Statement]) extends Transform {
- if (code.size > 0) pos = code.head.pos
-}
-case class IfPat(thn: Transform, els: Option[Transform]) extends Transform
-case class WhilePat(invs: List[Expression], body: Transform) extends Transform
-case class NonDetPat(is: List[String], code: List[Statement]) extends Transform {
- def matches(s: Statement) = s match {
- case _:Call => true
- case _:SpecStmt => true
- case _ => false
- }
-}
-case class InsertPat(code: List[Statement]) extends Transform
-case class SeqPat(pats: List[Transform]) extends Transform {
- assert(pats.size > 0)
- pos = pats.head.pos;
-}
-case class RefinementBlock(con: List[Statement], abs: List[Statement]) extends Statement {
- if (con.size > 0) pos = con.head.pos
- // local variables in context at the beginning of the block
- var before: List[Variable] = null
- // shared declared local variables (mapping between abstract and concrete)
- lazy val during: (List[Variable], List[Variable]) = {
- val a = for (v <- abs.flatMap(s => s.Declares)) yield v;
- val c = for (v <- a) yield con.flatMap(s => s.Declares).find(_ == v).get
- (a,c)
- }
- override def Declares = con flatMap {_.Declares}
- override def Targets = (con ++ abs :\ Set[Variable]()) { (s, vars) => vars ++ s.Targets}
-}
-
-/**
- * Statements
- */
-
-sealed abstract class Statement extends ASTNode {
- def Declares: List[Variable] = Nil // call after resolution
- def Targets: Set[Variable] = Set() // assigned local variables
-}
-case class Assert(e: Expression) extends Statement {
- var smokeErrorNr: Option[Int] = None
-}
-case class Assume(e: Expression) extends Statement
-case class BlockStmt(ss: List[Statement]) extends Statement {
- override def Targets = (ss :\ Set[Variable]()) { (s, vars) => vars ++ s.Targets}
-}
-case class IfStmt(guard: Expression, thn: BlockStmt, els: Option[Statement]) extends Statement {
- override def Targets = thn.Targets ++ (els match {case None => Set(); case Some(els) => els.Targets})
-}
-case class WhileStmt(guard: Expression,
- oldInvs: List[Expression], newInvs: List[Expression], lkch: List[Expression],
- body: BlockStmt) extends Statement {
- val Invs = oldInvs ++ newInvs
- var LoopTargets: List[Variable] = Nil
- override def Targets = body.Targets
-}
-case class Assign(lhs: VariableExpr, rhs: RValue) extends Statement {
- override def Targets = if (lhs.v != null) Set(lhs.v) else Set()
-}
-case class FieldUpdate(lhs: MemberAccess, rhs: RValue) extends Statement
-case class LocalVar(v: Variable, rhs: Option[RValue]) extends Statement {
- override def Declares = List(v)
- override def Targets = rhs match {case None => Set(); case Some(_) => Set(v)}
-}
-case class Call(declaresLocal: List[Boolean], lhs: List[VariableExpr], obj: Expression, id: String, args: List[Expression]) extends Statement {
- var locals = List[Variable]()
- var m: Callable = null
- override def Declares = locals
- override def Targets = (lhs :\ Set[Variable]()) { (ve, vars) => if (ve.v != null) vars + ve.v else vars }
-}
-case class SpecStmt(lhs: List[VariableExpr], locals:List[Variable], pre: Expression, post: Expression) extends Statement {
- override def Declares = locals
- override def Targets = (lhs :\ Set[Variable]()) { (ve, vars) => if (ve.v != null) vars + ve.v else vars }
-}
-case class Install(obj: Expression, lowerBounds: List[Expression], upperBounds: List[Expression]) extends Statement
-case class Share(obj: Expression, lowerBounds: List[Expression], upperBounds: List[Expression]) extends Statement
-case class Unshare(obj: Expression) extends Statement
-case class Acquire(obj: Expression) extends Statement
-case class Release(obj: Expression) extends Statement
-case class RdAcquire(obj: Expression) extends Statement
-case class RdRelease(obj: Expression) extends Statement
-case class Downgrade(obj: Expression) extends Statement
-case class Lock(obj: Expression, b: BlockStmt, rdLock: Boolean) extends Statement {
- override def Targets = b.Targets
-}
-case class Free(obj: Expression) extends Statement
-case class CallAsync(declaresLocal: Boolean, lhs: VariableExpr, obj: Expression, id: String, args: List[Expression]) extends Statement {
- var local: Variable = null
- var m: Method = null
- override def Declares = if (local != null) List(local) else Nil
- override def Targets = if (lhs != null && lhs.v != null) Set(lhs.v) else Set()
-}
-case class JoinAsync(lhs: List[VariableExpr], token: Expression) extends Statement {
- var m: Method = null
-}
-case class Wait(obj: Expression, id: String) extends Statement {
- var c: Condition = null
-}
-case class Signal(obj: Expression, id: String, all: Boolean) extends Statement {
- var c: Condition = null
-}
-case class Send(ch: Expression, args: List[Expression]) extends Statement {
-}
-case class Receive(declaresLocal: List[Boolean], ch: Expression, outs: List[VariableExpr]) extends Statement {
- var locals = List[Variable]()
- override def Declares = locals
- override def Targets = (outs :\ Set[Variable]()) { (ve, vars) => if (ve.v != null) vars + ve.v else vars }
-}
-case class Fold(pred: Access) extends Statement
-case class Unfold(pred: Access) extends Statement
-
-/**
- * Expressions
- */
-
-sealed abstract class RValue extends ASTNode {
- var typ: Class = null
-}
-case class NewRhs(id: String, initialization: List[Init], lowerBounds: List[Expression], upperBounds: List[Expression]) extends RValue
-case class Init(id: String, e: Expression) extends ASTNode {
- var f: Field = null;
-}
-sealed abstract class Expression extends RValue {
- def transform(f: Expression => Option[Expression]) = AST.transform(this, f)
- def visit(f: RValue => Unit) = AST.visit(this, f)
- def visitOpt(f: RValue => Boolean) = AST.visitOpt(this, f)
-}
-sealed abstract class Literal extends Expression
-case class IntLiteral(n: Int) extends Literal
-case class BoolLiteral(b: Boolean) extends Literal
-case class NullLiteral() extends Literal
-case class StringLiteral(s: String) extends Literal
-case class MaxLockLiteral() extends Literal
-case class LockBottomLiteral() extends Literal
-case class VariableExpr(id: String) extends Expression {
- var v: Variable = null
- def this(vr: Variable) = { this(vr.id); v = vr; typ = vr.t.typ }
- def Resolve(vr: Variable) = { v = vr; typ = vr.t.typ }
-}
-// hack to allow boogie expressions in the Chalice AST during transformation
-case class BoogieExpr(expr: Boogie.Expr) extends Expression {
- override def toString = "BoogieExpr("+expr+")"
-}
-case class Result() extends Expression
-sealed abstract class ThisExpr extends Expression
-case class ExplicitThisExpr() extends ThisExpr {
- override def hashCode = 0
- override def equals(other: Any) = other.isInstanceOf[ThisExpr]
-}
-case class ImplicitThisExpr() extends ThisExpr {
- override def hashCode = 0
- override def equals(other: Any) = other.isInstanceOf[ThisExpr]
-}
-case class MemberAccess(e: Expression, id: String) extends Expression {
- var isPredicate: Boolean = false
- var f: Field = null
- var predicate: Predicate = null
-}
-case class IfThenElse(con: Expression, then: Expression, els: Expression) extends Expression
-
-object PermissionType extends Enumeration {
- type PermissionType = Value
- val Fraction, Epsilons, Mixed = Value
-}
-import PermissionType._
-sealed abstract class Permission extends Expression {
- typ = PermClass
- def permissionType: PermissionType
-}
-sealed abstract class Write extends Permission {
- override def permissionType = PermissionType.Fraction
-}
-object Full extends Write // None
-case class Frac(n: Expression) extends Write // Some(n)
-sealed abstract class Read extends Permission {
- override def permissionType = PermissionType.Epsilons
-}
-object Epsilon extends Write // None
-// we use Option for the argument of the next three classes as follows:
-// the argument is Some(_) if the exression originates from the user (e.g. if he used acc(x,rd(monitor))),
-// and None otherwise. If Some(_) is used, we have additional checks to ensure that we have read access
-// to _ and _ is not null.
-case class PredicateEpsilon(predicate: Option[Expression]) extends Write
-case class MonitorEpsilon(monitor: Option[Expression]) extends Write
-case class ChannelEpsilon(channel: Option[Expression]) extends Write
-object MethodEpsilon extends Write
-case class ForkEpsilon(token: Expression) extends Write
-object Star extends Write // Some(None)
-case class Epsilons(n: Expression) extends Read // Some(Some(n))
-
-sealed abstract class ArithmeticPermission extends Permission
-case class PermTimes(val lhs: Permission, val rhs: Permission) extends ArithmeticPermission {
- override def permissionType = {
- if (lhs.permissionType == rhs.permissionType) lhs.permissionType
- else Mixed
- }
-}
-case class IntPermTimes(val lhs: Expression, val rhs: Permission) extends ArithmeticPermission {
- override def permissionType = rhs.permissionType
-}
-case class PermPlus(val lhs: Permission, val rhs: Permission) extends ArithmeticPermission {
- override def permissionType = {
- if (lhs.permissionType == rhs.permissionType) lhs.permissionType
- else Mixed
- }
-}
-case class PermMinus(val lhs: Permission, val rhs: Permission) extends ArithmeticPermission {
- override def permissionType = {
- if (lhs.permissionType == rhs.permissionType) lhs.permissionType
- else Mixed
- }
-}
-
-
-sealed abstract class PermissionExpr(perm: Permission) extends Expression
-sealed abstract class WildCardPermission(perm: Permission) extends PermissionExpr(perm)
-case class Access(ma: MemberAccess, var perm: Permission) extends PermissionExpr(perm)
-case class AccessAll(obj: Expression, var perm: Permission) extends WildCardPermission(perm)
-case class AccessSeq(s: Expression, f: Option[MemberAccess], var perm: Permission) extends WildCardPermission(perm)
-
-case class Credit(e: Expression, n: Option[Expression]) extends Expression {
- val N = n match { case None => IntLiteral(1) case Some(n) => n }
-}
-
-case class Holds(e: Expression) extends Expression
-case class RdHolds(e: Expression) extends Expression
-case class Assigned(id: String) extends Expression {
- var v: Variable = null
-}
-case class Old(e: Expression) extends Expression
-case class Not(e: Expression) extends Expression
-case class FunctionApplication(obj: Expression, id: String, args: List[Expression]) extends Expression {
- var f: Function = null
-}
-case class Unfolding(pred: Access, in: Expression) extends Expression
-sealed abstract class BinaryExpr(e0: Expression, e1: Expression) extends Expression {
- val E0 = e0
- val E1 = e1
- val ExpectedLhsType: Class = BoolClass // sometimes undefined
- val ExpectedRhsType: Class = BoolClass // sometimes undefined
- val ResultType: Class = BoolClass
- val OpName: String
-}
-case class Iff(e0: Expression, e1: Expression) extends BinaryExpr(e0,e1) {
- override val OpName = "<==>"
-}
-case class Implies(e0: Expression, e1: Expression) extends BinaryExpr(e0,e1) {
- override val OpName = "==>"
-}
-case class And(e0: Expression, e1: Expression) extends BinaryExpr(e0,e1) {
- override val OpName = "&&"
-}
-case class Or(e0: Expression, e1: Expression) extends BinaryExpr(e0,e1) {
- override val OpName = "||"
-}
-sealed abstract class ArithmeticExpr(e0: Expression, e1: Expression) extends BinaryExpr(e0,e1) {
- override val ExpectedLhsType = IntClass
- override val ExpectedRhsType = IntClass
- override val ResultType = IntClass
-}
-case class Plus(e0: Expression, e1: Expression) extends ArithmeticExpr(e0,e1) {
- override val OpName = "+"
-}
-case class Minus(e0: Expression, e1: Expression) extends ArithmeticExpr(e0,e1) {
- override val OpName = "-"
-}
-case class Times(e0: Expression, e1: Expression) extends ArithmeticExpr(e0,e1) {
- override val OpName = "*"
-}
-case class Div(e0: Expression, e1: Expression) extends ArithmeticExpr(e0,e1) {
- override val OpName = "/"
-}
-case class Mod(e0: Expression, e1: Expression) extends ArithmeticExpr(e0,e1) {
- override val OpName = "%"
-}
-sealed abstract class CompareExpr(e0: Expression, e1: Expression) extends BinaryExpr(e0,e1) {
- override val ExpectedLhsType = IntClass
- override val ExpectedRhsType = IntClass
-}
-sealed abstract class EqualityCompareExpr(e0: Expression, e1: Expression) extends CompareExpr(e0,e1) {
- override val ExpectedLhsType = null;
- override val ExpectedRhsType = null;
-}
-case class Eq(e0: Expression, e1: Expression) extends EqualityCompareExpr(e0,e1) {
- override val OpName = "=="
-}
-case class Neq(e0: Expression, e1: Expression) extends EqualityCompareExpr(e0,e1) {
- override val OpName = "!="
-}
-case class Less(e0: Expression, e1: Expression) extends CompareExpr(e0,e1) {
- override val OpName = "<"
-}
-case class AtMost(e0: Expression, e1: Expression) extends CompareExpr(e0,e1) {
- override val OpName = "<="
-}
-case class AtLeast(e0: Expression, e1: Expression) extends CompareExpr(e0,e1) {
- override val OpName = ">="
-}
-case class Greater(e0: Expression, e1: Expression) extends CompareExpr(e0,e1) {
- override val OpName = ">"
-}
-case class LockBelow(e0: Expression, e1: Expression) extends CompareExpr(e0,e1) {
- override val ExpectedLhsType = null;
- override val ExpectedRhsType = null;
- override val OpName = "<<"
-}
-
-/**
- * Expressions: quantifiers
- */
-
-trait Quant
-object Forall extends Quant
-object Exists extends Quant
-
-sealed abstract class Quantification(q: Quant, is: List[String], e: Expression) extends Expression {
- val Q = q;
- val Is = is;
- val E = e;
- var variables = null: List[Variable]; // resolved by type checker
-}
-case class SeqQuantification(q: Quant, is: List[String], seq: Expression, e: Expression) extends Quantification(q, is, e) {
- TranslatorPrelude.addComponent(AxiomatizationOfSequencesPL) // include sequence axioms if necessary
-}
-// The minmax field stores the minimum and maximum of a range if the TypeQuantification originates from
-// a SeqQuantification (e.g. from "forall i in [0..2] :: ..". This is later needed in isDefined to
-// assert that min <= max
-case class TypeQuantification(q: Quant, is: List[String], t: Type, e: Expression, minmax: (Expression, Expression)) extends Quantification(q, is, e) {
- def this(q: Quant, is: List[String], t: Type, e: Expression) = this(q, is, t, e, null)
-}
-
-/**
- * Expressions: sequences
- */
-
-case class EmptySeq(t: Type) extends Literal
-case class ExplicitSeq(elems: List[Expression]) extends Expression
-case class Range(min: Expression, max: Expression /* non-inclusive*/) extends Expression
-case class Append(s0: Expression, s1: Expression) extends SeqAccess(s0, s1) {
- override val OpName = "++"
-}
-sealed abstract class SeqAccess(e0: Expression, e1: Expression) extends BinaryExpr(e0, e1) {
- override val ExpectedLhsType = null
- override val ExpectedRhsType = null
- override val ResultType = null
-}
-case class Length(e: Expression) extends Expression
-case class At(s: Expression, n: Expression) extends SeqAccess(s, n) {
- override val OpName = ""
-}
-case class Drop(s: Expression, n: Expression) extends SeqAccess(s, n) {
- override val OpName = ""
-}
-case class Take(s: Expression, n: Expression) extends SeqAccess(s, n) {
- override val OpName = ""
-}
-case class Contains(n: Expression, s: Expression) extends SeqAccess(n, s) {
- override val OpName = "in"
-}
-
-// eval
-
-case class Eval(h: EvalState, e: Expression) extends Expression
-sealed abstract class EvalState {
- def target(): Expression;
-}
-case class AcquireState(obj: Expression) extends EvalState {
- def target() = obj
-}
-case class ReleaseState(obj: Expression) extends EvalState {
- def target() = obj
-}
-case class CallState(token: Expression, obj: Expression, id: String, args: List[Expression]) extends EvalState {
- var m = null: Method;
- def target() = token;
-}
-
-/**
- * AST operations
- */
-
-object AST {
- /**
- * Flattens sequences of transforms and merges consecutive block patterns
- */
- def normalize(trans: Transform): Transform = trans match {
- case IfPat(thn, Some(els)) => IfPat(normalize(thn), Some(normalize(els)))
- case IfPat(thn, None) => IfPat(normalize(thn), None)
- case SeqPat(pats) =>
- val rec = pats flatMap {pat => normalize(pat) match {
- case SeqPat(pats) => pats;
- case x => List(x)
- }}
- def noTwoBlocks: List[Transform] => List[Transform] = {
- case BlockPat() :: (bp @ BlockPat()) :: l => noTwoBlocks(bp :: l)
- case x :: l => x :: noTwoBlocks(l)
- case Nil => Nil
- }
- SeqPat(noTwoBlocks(rec))
- case _ => trans
- }
-
- sealed abstract class TransformMatch
- case class Matched(ss: List[Statement]) extends TransformMatch {
- def this(s: Statement) = this(List(s))
- }
- case class Unmatched(t: Transform) extends TransformMatch
-
- /**
- * Matches a proper block to a transform.
- * Effects: some statements might be replaced by refinements blocks; Loops might have new invariants.
- * Requires: transform is normalized
- */
- def refine:(List[Statement], Transform) => TransformMatch = {
- // order is important!
- // reduction of base cases
- case (l, SeqPat(List(t))) => refine(l, t)
- case (List(BlockStmt(ss)), t) => refine(ss, t)
- // whole program
- case (l, ProgramPat(code)) => new Matched(RefinementBlock(code, l))
- case (l, SkipPat()) => Matched(l)
- // if pattern
- case (List(IfStmt(guard, thn, None)), t @ IfPat(thnT, None)) =>
- refine(thn.ss, thnT) match {
- case Matched(thn0) => new Matched(IfStmt(guard, BlockStmt(thn0), None))
- case _ => Unmatched(t)
- }
- case (List(IfStmt(guard, thn, Some(els))), t @ IfPat(thnT, Some(elsT))) =>
- (refine(thn.ss, thnT), refine(List(els), elsT)) match {
- case (Matched(thn0), Matched(els0)) => new Matched(IfStmt(guard, BlockStmt(thn0), Some(BlockStmt(els0))))
- case _ => Unmatched(t)
- }
- // while pattern
- case (List(WhileStmt(guard, oi, Nil, lks, body)), wp @ WhilePat(l, t)) =>
- refine(body.ss, t) match {
- case Matched(body0) => new Matched(WhileStmt(guard, oi, l, lks, BlockStmt(body0)))
- case _ => Unmatched(wp)
- }
- // non det pat
- case (l @ List(_: Call), NonDetPat(_, code)) => new Matched(RefinementBlock(code, l))
- case (l @ List(_: SpecStmt), NonDetPat(_, code)) => new Matched(RefinementBlock(code, l))
- // insert pat
- case (Nil, InsertPat(code)) => new Matched(RefinementBlock(code, Nil))
- // block pattern (greedy matching)
- case (l, bp @ BlockPat()) if (l forall {s => bp matches s}) => Matched(l)
- case (s :: ss, t @ SeqPat((bp @ BlockPat()) :: _)) if (bp matches s) =>
- refine(ss, t) match {
- case Matched(l) => Matched(s :: l)
- case x => x
- }
- case (l, SeqPat((bp @ BlockPat()) :: ts)) if (l.size == 0 || !(bp matches l.head)) =>
- refine(l, SeqPat(ts))
- // sequence pattern
- case (s :: ss, SeqPat((np: NonDetPat) :: ts)) =>
- (refine(List(s), np), refine(ss, SeqPat(ts))) match {
- case (Matched(a), Matched(b)) => Matched(a ::: b)
- case _ => Unmatched(np)
- }
- case (s :: ss, SeqPat((ip: IfPat) :: ts)) =>
- (refine(List(s), ip), refine(ss, SeqPat(ts))) match {
- case (Matched(a), Matched(b)) => Matched(a ::: b)
- case _ => Unmatched(ip)
- }
- case (l, SeqPat(InsertPat(code) :: ts)) =>
- refine(l, SeqPat(ts)) match {
- case Matched(a) => Matched(RefinementBlock(code, Nil) :: a)
- case x => x
- }
- case (s :: ss, SeqPat((wp: WhilePat) :: ts)) =>
- (refine(List(s), wp), refine(ss, SeqPat(ts))) match {
- case (Matched(a), Matched(b)) => Matched(a ::: b)
- case _ => Unmatched(wp)
- }
- case (_, t) => Unmatched(t)
- }
-
- /**
- * Transforms an expression using f. f must produce expressions of the appropriate type (e.g. not replace int literal with a bool literal)
- * Ensures that mutable fields of expressions are carried over. f must make sure that mutable fields of its value are filled in.
- */
- def transform(expr: Expression, f: Expression => Option[Expression]):Expression = {
- val func = (e:Expression) => transform(e, f);
- val x = f(expr);
- // apply recursively
- val result = if (x isDefined) x.get else expr match {
- case _:Literal => expr
- case _:ThisExpr => expr
- case _:Result => expr
- case _:VariableExpr => expr
- case _:BoogieExpr => expr
- case ma@MemberAccess(e, id) =>
- val g = MemberAccess(func(e), id);
- g.f = ma.f;
- g.predicate = ma.predicate;
- g.isPredicate = ma.isPredicate;
- g
- case ForkEpsilon(token) => ForkEpsilon(func(token))
- case MonitorEpsilon(Some(monitor)) => MonitorEpsilon(Some(func(monitor)))
- case ChannelEpsilon(Some(channel)) => ChannelEpsilon(Some(func(channel)))
- case PredicateEpsilon(Some(predicate)) => PredicateEpsilon(Some(func(predicate)))
- case ChannelEpsilon(None) | MonitorEpsilon(None) | PredicateEpsilon(None) => expr
- case Full | Star | Epsilon | MethodEpsilon => expr
- case Frac(perm) => Frac(func(perm))
- case Epsilons(perm) => Epsilons(func(perm))
- case PermTimes(lhs, rhs) => PermTimes(func(lhs).asInstanceOf[Permission], func(rhs).asInstanceOf[Permission])
- case IntPermTimes(lhs, rhs) => IntPermTimes(func(lhs), func(rhs).asInstanceOf[Permission])
- case PermPlus(lhs, rhs) => PermPlus(func(lhs).asInstanceOf[Permission], func(rhs).asInstanceOf[Permission])
- case PermMinus(lhs, rhs) => PermMinus(func(lhs).asInstanceOf[Permission], func(rhs).asInstanceOf[Permission])
- case Access(e, perm) => Access(func(e).asInstanceOf[MemberAccess], func(perm).asInstanceOf[Permission]);
- case AccessAll(obj, perm) => AccessAll(func(obj), func(perm).asInstanceOf[Permission]);
- case AccessSeq(s, None, perm) => AccessSeq(func(s), None, func(perm).asInstanceOf[Permission])
- case AccessSeq(s, Some(f), perm) => AccessSeq(func(s), Some(func(f).asInstanceOf[MemberAccess]), func(perm).asInstanceOf[Permission])
- case Credit(e, None) => Credit(func(e), None)
- case Credit(e, Some(n)) => Credit(func(e), Some(func(n)))
- case Holds(e) => Holds(func(e))
- case RdHolds(e) => RdHolds(func(e))
- case _: Assigned => expr
- case Old(e) => Old(func(e))
- case IfThenElse(con, then, els) => IfThenElse(func(con), func(then), func(els))
- case Not(e) => Not(func(e))
- case funapp@FunctionApplication(obj, id, args) =>
- val appl = FunctionApplication(func(obj), id, args map { arg => func(arg)});
- appl.f = funapp.f;
- appl
- case Unfolding(pred, e) =>
- Unfolding(func(pred).asInstanceOf[Access], func(e))
- case Iff(e0,e1) => Iff(func(e0), func(e1))
- case Implies(e0,e1) => Implies(func(e0), func(e1))
- case And(e0,e1) => And(func(e0), func(e1))
- case Or(e0,e1) => Or(func(e0), func(e1))
- case Eq(e0,e1) => Eq(func(e0), func(e1))
- case Neq(e0,e1) => Neq(func(e0), func(e1))
- case Less(e0,e1) => Less(func(e0), func(e1))
- case AtMost(e0,e1) => AtMost(func(e0), func(e1))
- case AtLeast(e0,e1) => AtLeast(func(e0), func(e1))
- case Greater(e0,e1) => Greater(func(e0), func(e1))
- case LockBelow(e0,e1) => LockBelow(func(e0), func(e1))
- case Plus(e0,e1) => Plus(func(e0), func(e1))
- case Minus(e0,e1) => Minus(func(e0), func(e1))
- case Times(e0,e1) => Times(func(e0), func(e1))
- case Div(e0,e1) => Div(func(e0), func(e1))
- case Mod(e0,e1) => Mod(func(e0), func(e1))
- case ExplicitSeq(es) => ExplicitSeq(es map { e => func(e) })
- case Range(min, max)=> Range(func(min), func(max))
- case Append(e0, e1) => Append(func(e0), func(e1))
- case At(e0, e1) => At(func(e0), func(e1))
- case Drop(e0, e1) => Drop(func(e0), func(e1))
- case Take(e0, e1) => Take(func(e0), func(e1))
- case Length(e) => Length(func(e))
- case Contains(e0, e1) => Contains(func(e0), func(e1))
- case qe @ SeqQuantification(q, is, seq, e) =>
- val result = SeqQuantification(q, is, func(seq), func(e));
- result.variables = qe.variables;
- result;
- case qe @ TypeQuantification(q, is, t, e, (min, max)) =>
- val result = TypeQuantification(q, is, t, func(e), (func(min),func(max)));
- result.variables = qe.variables;
- result;
- case qe @ TypeQuantification(q, is, t, e, null) =>
- val result = new TypeQuantification(q, is, t, func(e));
- result.variables = qe.variables;
- result;
- case Eval(h, e) =>
- Eval(h match {
- case AcquireState(obj) => AcquireState(func(obj))
- case ReleaseState(obj) => ReleaseState(func(obj))
- case cs @ CallState(token, obj, i, args) =>
- val result = CallState(func(token), func(obj), i, args map { a => func(a)});
- result.m = cs.m;
- result;
- }, func(e))
- };
-
- // preserve type
- if (result.typ == null) result.typ = expr.typ;
- // preserve position
- if (result.pos == NoPosition) result.pos = expr.pos
- result
- }
-
- // Applies recursively the function f first to the expression and then to its subexpressions (that is members of type RValue)
- def visit(expr: RValue, f: RValue => Unit) = visitOpt(expr, r => {f(r); true})
- // Applies recursively the function f first to the expression and, if f returns true, then to its subexpressions
- def visitOpt(expr: RValue, f: RValue => Boolean) {
- if (f(expr)) {
- expr match {
- case _:Literal => ;
- case _:ThisExpr => ;
- case _:Result => ;
- case _:VariableExpr => ;
- case _:BoogieExpr => ;
- case MemberAccess(e, _) =>
- visitOpt(e, f);
-
- case Frac(p) => visitOpt(p, f);
- case Epsilons(p) => visitOpt(p, f);
- case Full | Epsilon | Star | MethodEpsilon =>;
- case ChannelEpsilon(None) | PredicateEpsilon(None) | MonitorEpsilon(None) =>;
- case ChannelEpsilon(Some(e)) => visitOpt(e, f);
- case PredicateEpsilon(Some(e)) => visitOpt(e, f);
- case MonitorEpsilon(Some(e)) => visitOpt(e, f);
- case ForkEpsilon(tk) => visitOpt(tk, f);
- case IntPermTimes(n, p) =>
- visitOpt(n, f); visitOpt(p, f);
- case PermTimes(e0, e1) =>
- visitOpt(e0, f); visitOpt(e1, f);
- case PermPlus(e0, e1) =>
- visitOpt(e0, f); visitOpt(e1, f);
- case PermMinus(e0, e1) =>
- visitOpt(e0, f); visitOpt(e1, f);
- case Access(e, perm) =>
- visitOpt(e, f); visitOpt(perm, f);
- case AccessAll(obj, perm) =>
- visitOpt(obj, f); visitOpt(perm, f);
- case AccessSeq(s, _, perm) =>
- visitOpt(s, f); visitOpt(perm, f);
-
- case Credit(e, n) =>
- visitOpt(e, f); n match { case Some(n) => visitOpt(n, f); case _ => }
- case Holds(e) => visitOpt(e, f);
- case RdHolds(e) => visitOpt(e, f);
-
- case e: BinaryExpr =>
- visitOpt(e.E0, f); visitOpt(e.E1, f);
- case Range(min, max) =>
- visitOpt(min, f); visitOpt(max, f);
- case e: Assigned => e
- case Old(e) => visitOpt(e, f);
- case IfThenElse(con, then, els) => visitOpt(con, f); visitOpt(then, f); visitOpt(els, f);
- case Not(e) => visitOpt(e, f);
- case funapp@FunctionApplication(obj, id, args) =>
- visitOpt(obj, f); args foreach { arg => visitOpt(arg, f) };
- case Unfolding(pred, e) =>
- visitOpt(pred, f); visitOpt(e, f);
-
- case SeqQuantification(_, _, seq, e) => visitOpt(seq, f); visitOpt(e, f);
- case TypeQuantification(_, _, _, e, (min,max)) => visitOpt(e, f); visitOpt(min, f); visitOpt(max, f);
- case TypeQuantification(_, _, _, e, _) => visitOpt(e, f);
- case ExplicitSeq(es) =>
- es foreach { e => visitOpt(e, f) }
- case Length(e) =>
- visitOpt(e, f)
- case Eval(h, e) =>
- h match {
- case AcquireState(obj) => visitOpt(obj, f);
- case ReleaseState(obj) => visitOpt(obj, f);
- case CallState(token, obj, id, args) =>
- visitOpt(token, f); visitOpt(obj, f); args foreach {a : Expression => visitOpt(a, f)};
- }
- visitOpt(e, f);
- case NewRhs(_, init, lowerBounds, upperBounds) =>
- lowerBounds foreach { e => visitOpt(e, f)};
- upperBounds foreach { e => visitOpt(e, f)};
- }
- }
- }
-}
diff --git a/Chalice/src/main/scala/Boogie.scala b/Chalice/src/main/scala/Boogie.scala
deleted file mode 100644
index e775b688..00000000
--- a/Chalice/src/main/scala/Boogie.scala
+++ /dev/null
@@ -1,310 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-import scala.util.parsing.input.Position
-import scala.util.parsing.input.NoPosition
-
-object Boogie {
-
- sealed abstract class Decl
- case class Const(id: String, unique: Boolean, t: BType) extends Decl
- case class Proc(id: String, ins: List[BVar], outs: List[BVar],
- mod: List[String], PrePost: List[String],
- body: List[Stmt]) extends Decl
- case class Function(id: String, ins: List[BVar], out: BVar) extends Decl
- case class Axiom(expr: Expr) extends Decl
-
- sealed abstract class BType
- case class NamedType(s: String) extends BType
- case class IndexedType(id: String, t: BType) extends BType
-
- case class Tag(s: String)
- sealed abstract class Stmt {
- def Locals = List[BVar]()
- var tags: List[Tag] = Nil
- }
- case class Comment(comment: String) extends Stmt
- case class Assert(e: Expr) extends Stmt {
- def this(e: Expr, p: Position, txt: String) = { this(e); this.pos = p; this.message = txt; this }
- def this(e: Expr, p: Position, txt: String, subsumption: Int) = { this(e, p, txt); this.subsumption = Some(subsumption); this }
- var pos = NoPosition : Position
- var message = "" : String
- var subsumption = None: Option[Int]
- }
- case class Assume(e: Expr) extends Stmt
- case class Assign(lhs: Expr, rhs: Expr) extends Stmt
- case class AssignMap(lhs: Expr, index: Expr, rhs: Expr) extends Stmt
- case class Havoc(x: Expr) extends Stmt
- case class MapUpdate(map: Expr, arg0: Expr, arg1: Option[Expr], rhs: Expr) extends Stmt {
- def this(map: Expr, arg0: Expr, rhs: Expr) = this(map, arg0, None, rhs)
- def this(map: Expr, arg0: Expr, arg1: Expr, rhs: Expr) = this(map, arg0, Some(arg1), rhs)
- }
- case class If(guard: Expr, thn: List[Stmt], els: List[Stmt]) extends Stmt {
- override def Locals = (thn flatMap (_.Locals)) ::: (els flatMap (_.Locals))
- }
- case class LocalVar(x: BVar) extends Stmt {
- def this(id: String, tp: BType) = this(BVar(id, tp))
- override def Locals = List(x)
- }
-
- sealed abstract class Expr {
- def &&(that: Expr) = BinaryExpr("&&", this, that)
- def ||(that: Expr) = BinaryExpr("||", this, that)
- def ==@(that: Expr) = BinaryExpr("==", this, that)
- def !=@(that: Expr) = BinaryExpr("!=", this, that)
- def Equals(that: Expr) = BinaryExpr("==", this, that)
- def ==>(that: Expr) = BinaryExpr("==>", this, that)
- def <==>(that: Expr) = BinaryExpr("<==>", this, that)
- def unary_! = UnaryExpr("!", this)
- def <=(that: Expr) = BinaryExpr("<=", this, that)
- def <(that: Expr) = BinaryExpr("<", this, that)
- def >=(that: Expr) = BinaryExpr(">=", this, that)
- def >(that: Expr) = BinaryExpr(">", this, that)
- def +(that: Expr) = BinaryExpr("+", this, that)
- def -(that: Expr) = BinaryExpr("-", this, that)
- def *(that: Expr) = BinaryExpr("*", this, that)
- def /(that: Expr) = BinaryExpr("div", this, that)
- def %(that: Expr) = BinaryExpr("mod", this, that)
- def := (that: Expr) = Assign(this, that)
- def apply(e: Expr, f: Expr) = new MapSelect(this, e, Some(f))
- def apply(e: Expr) = new MapSelect(this, e, None)
- def thenElse(thenE: Expr, elseE: Expr) = new Ite(this, thenE, elseE)
- def select(e: Expr, s: String) = new MapSelect(this, e, s) // useful for working on heap
- def forall(x: BVar) = new Forall(x, this)
- def exists(x: BVar) = new Exists(x, this)
- def store(e: Expr, f: Expr, rhs: Expr) = MapUpdate(this, e, Some(f), rhs)
- }
- case class IntLiteral(n: Int) extends Expr
- case class RealLiteral(d: Double) extends Expr
- case class BoolLiteral(b: Boolean) extends Expr
- case class Null() extends Expr
- case class VarExpr(id: String) extends Expr {
- def this(v: BVar) = this(v.id)
- }
- case class MapSelect(map: Expr, arg0: Expr, arg1: Option[Expr]) extends Expr {
- def this(map: Expr, arg0: Expr) = this(map, arg0, None) // for one-dimensional maps
- def this(map: Expr, arg0: Expr, arg1: String) = this(map, arg0, Some(VarExpr(arg1)))
- def this(map: Expr, arg0: Expr, arg1: String, arg2: String) = // for 3-dimensional maps
- this(MapSelect(map, arg0, Some(VarExpr(arg1))), VarExpr(arg2), None)
- }
- case class MapStore(map: Expr, arg0: Expr, rhs: Expr) extends Expr
- case class Old(e: Expr) extends Expr
- case class UnaryExpr(op: String, e: Expr) extends Expr
- case class BinaryExpr(op: String, e0: Expr, e1: Expr) extends Expr
- case class FunctionApp(f: String, args: List[Expr]) extends Expr {
- def this(f: String, a0: Expr) = this(f, List(a0))
- def this(f: String, a0: Expr, a1: Expr) = this(f, List(a0, a1))
- def this(f: String, a0: Expr, a1: Expr, a2: Expr) = this(f, List(a0, a1, a2))
- }
- case class Trigger(ts: List[Expr]) extends Expr {
- def this(t: Expr) = this(List(t))
- }
- case class Forall(ta: List[TVar], xs: List[BVar], triggers: List[Trigger], body: Expr) extends Expr {
- def this(x: BVar, body: Expr) = this(Nil, List(x), Nil, body)
- def this(xs: List[BVar], trigger: Trigger, body: Expr) = this(Nil, xs, List(trigger), body)
- def this(t: TVar, x: BVar, body: Expr) = this(List(t), List(x), Nil, body)
- }
- case class Exists(ta: List[TVar], xs: List[BVar], triggers: List[Trigger], body: Expr) extends Expr {
- def this(x: BVar, body: Expr) = this(Nil, List(x), List(), body)
- def this(xs: List[BVar], trigger: Trigger, body: Expr) = this(Nil, xs, List(trigger), body)
- }
- case class Lambda(ta: List[TVar], xs: List[BVar], body: Expr) extends Expr
-
- case class Ite(con: Expr, then: Expr, els: Expr) extends Expr
-
- case class BVar(id: String, t: BType) {
- def this(id: String, t: BType, uniquifyName: Boolean) =
- this(if (uniquifyName) {
- val n = S_BVar.VariableCount
- S_BVar.VariableCount = S_BVar.VariableCount + 1
- id + "#_" + n
- } else {
- id
- }, t)
- val where: Expr = null
- }
- object S_BVar { var VariableCount = 0 }
- def NewBVar(id: String, t: BType, uniquifyName: Boolean) = {
- val v = new Boogie.BVar(id, t, uniquifyName)
- val e = new Boogie.VarExpr(v)
- (v,e)
- }
- case class TVar(id: String) {
- def this(id: String, uniquifyName: Boolean) =
- this(if (uniquifyName) {
- val n = S_TVar.VariableCount
- S_TVar.VariableCount = S_TVar.VariableCount + 1
- id + "#_" + n
- } else {
- id
- })
- val where: Expr = null
- }
- object S_TVar { var VariableCount = 0 }
- def NewTVar(id: String) = {
- val v = new Boogie.TVar(id, true)
- val e = new Boogie.NamedType(v.id)
- (v,e)
- }
-
- // def out(s: String) = Console.out.print(s)
- private var indentLevel = 1
- def indent: String = {
- def doIndent(i: Int): String = {
- if(i==0) { "" } else { " " + doIndent(i-1) }
- }
- doIndent(indentLevel);
- }
-
- def IndentMore(what: => String) = {
- val prev = indentLevel
- indentLevel = indentLevel + 1
- val result = what
- indentLevel = prev
- result
- }
- private val nl = System.getProperty("line.separator");
-
- def Print[T](list: List[T], sep: String, p: T => String): String = list match {
- case Nil => ""
- case x :: Nil => p(x)
- case x :: xs => p(x) + sep + Print(xs, sep, p)
- }
- def PrintType(t: BType): String = t match {
- case nt@ NamedType(s) =>
- s
- case IndexedType(id,t) =>
- id + " (" + PrintType(t) + ")"
- }
- def Print(d: Decl): String = d match {
- case Const(id, u, t) =>
- "const " + (if (u) "unique " else "" ) + id + ": " + PrintType(t) + ";" + nl
- case p: Proc =>
- "procedure " + p.id +
- "(" + Print(p.ins, ", ", PrintVar) + ")" +
- " returns (" + Print(p.outs, ", ", PrintVar) + ")" + nl +
- (p.mod match {
- case Nil => ""
- case x :: xs =>
- indent + "modifies " +
- Print(p.mod, ", ", { s: String => s }) +
- ";" + nl
- }) +
- Print(p.PrePost, nl, { spec: String => indent + spec }) + nl +
- "{" + nl +
- Print(p.body flatMap (_.Locals), "", { v:BVar => indent + "var " + PrintVar(v) + ";" + nl}) +
- Print(p.body, "", PrintStmt) +
- "}" + nl
- case Function(id, ins, out) =>
- "function " + id + "(" + Print(ins, ", ", PrintVar) + ") returns (" + PrintVar(out) + ");" + nl
- case Axiom(e) =>
- "axiom " + PrintExpr(e) + ";" + nl
- }
- def PrintVar(v: BVar): String = {
- v.id + ": " + PrintType(v.t) +
- (if (v.where != null) {" where " + PrintExpr(v.where) } else { "" })
- }
- def PrintStmt(s: Stmt): String = s match {
- case Comment(msg) => indent + "// " + msg + nl
- case assert@Assert(e) =>
- val pos = if (Chalice.vsMode) {
- val r = assert.pos.line;
- val c = assert.pos.column;
- r + "," + c + "," + r + "," + (c+5) + ":"
- } else if (Chalice.rise4funMode) {
- val (r,c) = (assert.pos.line, assert.pos.column)
- Chalice.InputFilename + "(" + r + "," + c + "): Error: "
- } else {
- " " + assert.pos + ": "
- }
- indent + "assert " + "{:msg \"" + pos + assert.message + "\"}" + (assert.subsumption match {case Some(n) => "{:subsumption " + n + "}"; case None => ""}) + " " + PrintExpr(e) + ";" + nl
- case Assume(e) => indent + "assume " + PrintExpr(e) + ";" + nl
- case If(guard, thn, els) =>
- if (thn == Nil && els == Nil) "" else
- indent + "if (" +
- (if (guard == null) "*" else PrintExpr(guard)) +
- ") {" + nl +
- IndentMore { Print(thn, "", PrintStmt) } +
- indent + "}" +
- (if (els == Nil) nl else
- " else {" + nl +
- IndentMore { Print(els, "", PrintStmt) } +
- indent + "}" + nl
- )
- case Assign(lhs, rhs) =>
- indent + PrintExpr(lhs) + " := " + PrintExpr(rhs) + ";" + nl
- case AssignMap(lhs, index, rhs) =>
- indent + PrintExpr(lhs) + "[" + PrintExpr(index) + "] := " + PrintExpr(rhs) + ";" + nl
- case Havoc(lhs) =>
- indent + "havoc " + PrintExpr(lhs) + ";" + nl
- case MapUpdate(map, a0, a1, rhs) =>
- indent + PrintExpr(map) + "[" +
- PrintExpr(a0) +
- (a1 match { case Some(e) => { ", " + PrintExpr(e) }; case None => { "" }}) +
- "] := " +
- PrintExpr(rhs) + ";" + nl
- case _:LocalVar => "" /* print nothing */
- }
- def PrintExpr(e: Expr): String = {
- PrintExpr(e, false)
- }
- def PrintExpr(e: Expr, useParens: Boolean): String = e match {
- case IntLiteral(n) => n.toString
- case RealLiteral(d) => d.toString
- case BoolLiteral(b) => b.toString
- case Null() => "null"
- case VarExpr(id) => id
- case MapSelect(map, arg0, arg1) =>
- PrintExpr(map) + "[" + PrintExpr(arg0, false) +
- (arg1 match {case Some(e) => { ", " + PrintExpr(e) }; case None => { "" }}) +
- "]"
- case MapStore(map, arg0, rhs) =>
- PrintExpr(map) + "[" + PrintExpr(arg0) + " := " + PrintExpr(rhs, false) + "]"
- case Old(e) => "old(" + PrintExpr(e, false) + ")"
- case UnaryExpr(op, e) =>
- (if (useParens) { "(" } else "") +
- op + PrintExpr(e, true) +
- (if (useParens) ")" else "" )
- case BinaryExpr(op, e0, e1) =>
- // reduce parentheses in a special common case:
- val binIsAndImpIff = op=="&&" || op=="==>" || op=="<==>";
- def IsAnd(e: Expr) = e match { case BinaryExpr(op,_,_) if op=="&&" => true case _ => false }
- (if (useParens) "(" else "") + PrintExpr(e0, !(binIsAndImpIff && IsAnd(e0))) +
- " " + op + " " +
- PrintExpr(e1, !(binIsAndImpIff && IsAnd(e1))) +
- (if (useParens) ")" else "")
- case FunctionApp(f, args) =>
- f + "(" +
- Print(args, ", ", { e: Expr => PrintExpr(e, false) }) +
- ")"
- case Ite(con, then, els) =>
- "ite(" + PrintExpr(con) + ", " + PrintExpr(then) + ", " + PrintExpr(els) + ")"
- case Trigger(ts) => Print(ts,", ", PrintExpr)
- case Forall(ts, xs, triggers, body) =>
- "(forall" +
- (if (ts.length == 0) " " else "<" + Print(ts, ", ", { x: TVar => x.id }) + "> ") +
- Print(xs, ", ", { x: BVar => x.id + ": " + PrintType(x.t) }) +
- " :: " +
- Print(triggers , "", { t: Trigger => "{" + PrintExpr(t) + "} " }) +
- PrintExpr(body) +
- ")"
- case Exists(ts, xs, triggers, body) =>
- "(exists " +
- (if (ts.length == 0) " " else "<" + Print(ts, ", ", { x: TVar => x.id }) + "> ") +
- Print(xs, ", ", { x: BVar => x.id + ": " + PrintType(x.t) }) +
- " :: " +
- Print(triggers , "", { t: Trigger => "{" + PrintExpr(t) + "} " }) +
- PrintExpr(body) +
- ")"
- case Lambda(ts, xs, body) =>
- "(lambda" +
- (if (ts.length == 0) " " else "<" + Print(ts, ", ", { x: TVar => x.id }) + "> ") +
- Print(xs, ", ", { x: BVar => x.id + ": " + PrintType(x.t) }) +
- " :: " +
- PrintExpr(body) +
- ")"
- }
-}
diff --git a/Chalice/src/main/scala/Chalice.cs b/Chalice/src/main/scala/Chalice.cs
deleted file mode 100644
index 0b26e1f2..00000000
--- a/Chalice/src/main/scala/Chalice.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-
-namespace Chalice
-{
- public class ImmutableList<E>
- {
- private List<E> list;
-
- public ImmutableList()
- {
- list = new List<E>();
- }
-
- public ImmutableList(IEnumerable<E> elems)
- {
- list = new List<E>(elems);
- }
-
- public ImmutableList<E> Append(ImmutableList<E> other)
- {
- var res = new ImmutableList<E>();
- res.list.AddRange(list);
- res.list.AddRange(other.list);
- return res;
- }
-
- public E At(int index)
- {
- return list[index];
- }
-
- public ImmutableList<E> Take(int howMany)
- {
- var res = new ImmutableList<E>(this.list.Take(howMany));
- return res;
- }
-
- public ImmutableList<E> Drop(int howMany)
- {
- var res = new ImmutableList<E>(this.list.Skip(howMany));
- return res;
- }
-
- public int Length
- {
- get
- {
- return list.Count;
- }
- }
-
- public static ImmutableList<int> Range(int min, int max)
- {
- ImmutableList<int> l = new ImmutableList<int>();
- for (int i = min; i < max; i++)
- {
- l.list.Add(i);
- }
- return l;
- }
- }
-
- public class ChannelBuffer<E>
- {
- private Queue<E> contents = new Queue<E>();
-
- public void Add(E e)
- {
- lock (this)
- {
- contents.Enqueue(e);
- Monitor.Pulse(this);
- }
- }
-
- public E Remove()
- {
- lock (this)
- {
- while (contents.Count == 0)
- {
- Monitor.Wait(this);
- }
- E e = contents.Dequeue();
- return e;
- }
- }
- }
-
- public class ChalicePrint
- {
- public void Int(int x)
- {
- System.Console.WriteLine(x);
- }
- public void Bool(bool x)
- {
- System.Console.WriteLine(x);
- }
- }
-}
diff --git a/Chalice/src/main/scala/Chalice.scala b/Chalice/src/main/scala/Chalice.scala
deleted file mode 100644
index 60f5f443..00000000
--- a/Chalice/src/main/scala/Chalice.scala
+++ /dev/null
@@ -1,500 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-import java.io.BufferedReader
-import java.io.InputStreamReader
-import java.io.File
-import java.io.FileWriter
-import scala.util.parsing.input.Position
-import scala.util.parsing.input.NoPosition
-import collection.mutable.ListBuffer
-
-object Chalice {
- /**
- * Reporting options
- */
- private[chalice] var vsMode = false;
- private[chalice] var rise4funMode = false;
- private[chalice] var InputFilename = ""; // the name of the last input file mentioned on the command line, or "" if none
-
- /**
- * Translation options
- */
- // level 0 or below: no defaults
- // level 1: unfold predicates with receiver this in pre and postconditions
- // level 2: unfold predicates and functions with receiver this in pre and postconditions
- // level 3 or above: level 2 + autoMagic\
- private[chalice] var defaults = 0: Int;
- private[chalice] var autoFold = false: Boolean;
- private[chalice] var checkLeaks = false: Boolean;
- private[chalice] var autoMagic = false: Boolean;
- private[chalice] var skipDeadlockChecks = false: Boolean;
- private[chalice] var skipTermination = false: Boolean;
- private[chalice] var noFreeAssume = false: Boolean;
- private[chalice] var percentageSupport = 0;
- private[chalice] var smoke = false;
- private[chalice] var smokeAll = false;
- private[chalice] var timingVerbosity = 1;
-
- /**
- * Holds all command line arguments not stored in fields of Chalice.
- * Can only be created parseCommandLine.
- */
- sealed abstract class CommandLineParameters {
- val boogiePath: String
- val files: List[File]
- val printProgram: Boolean
- val doTypecheck: Boolean
- val doTranslate: Boolean
- val boogieArgs: String
- val gen: Boolean
- val showFullStackTrace: Boolean
- val noBplFile: Boolean
- val bplFile: String
- def getHelp(): String
- }
-
- def parseCommandLine(args: Array[String]): Option[CommandLineParameters] = {
- // help texts and closures for boolean command line options
- // closures should be idempotent
- import scala.collection.immutable.ListMap
-
- var aBoogiePath = "C:\\boogie\\Binaries\\Boogie.exe"
- val inputs = new ListBuffer[String]()
- var aPrintProgram = false
- var aDoTypecheck = true
- var aDoTranslate = true
- var aNoBplFile = true
- var aBplFile = "out.bpl"
- var aBoogieArgs = " "
- var aGen = false;
- var aShowFullStackTrace = false
-
- val options = ListMap[String,(() => Unit, String)](
- "help" -> (
- {() => },
- "print this message"),
- "print" -> ({() => aNoBplFile = false},"output the Boogie program used for verification to 'out.bpl'"),
- "printIntermediate" -> ({() => aPrintProgram = true},"print intermediate versions of the Chalice program"),
- "noTranslate" -> (
- {() => aDoTranslate = false},
- "do not translate the program to Boogie (only parse and typecheck)"),
- "noTypecheck"-> (
- {() => aDoTypecheck = false},
- "do not typecheck the program (only parse). Implies /noTranslate."),
- "vs" -> (
- {() => vsMode = true},
- "Microsoft Visual Studio mode (special error reporting for Visual Studio; requires an existing, writable directory at C:\\tmp)"),
- "rise4fun" -> (
- {() => rise4funMode = true},
- "rise4fun mode (generates error messages in a format expected by the rise4fun harness"),
- "checkLeaks" -> (
- {() => checkLeaks = true},
- "(no description available)"),
- "noDeadlockChecks" -> (
- {() => skipDeadlockChecks = true},
- "skip all lock ordering checks"),
- "noTermination" -> (
- {() => skipTermination = true},
- "skip the termination checks for functions"),
- "defaults" -> (
- {() => defaults = 3},
- null),
- "gen" -> (
- {() => aGen = true},
- "generate C# code from the Chalice program"),
- "autoFold" -> (
- {() => autoFold = true},
- "automatically fold predicates whenever necessary"),
- "autoMagic" -> (
- {() => autoMagic = true},
- "automatically try to infer accessibility predicates and non-nullness checks in specifications"),
- "noFreeAssume" -> (
- {() => noFreeAssume = true},
- "(no description available)"),
- "showFullStackTrace" -> (
- {() => aShowFullStackTrace = true},
- "show the full stack trace if an exception is encountered"),
- "smoke" -> (
- {() => smoke = true},
- "smoke testing; try to find unreachable code, preconditions/invariants/predicates that are equivalent to false and assumptions that introduce contradictions, by trying to prove 'false' at various positions."),
- "smokeAll" -> (
- {() => smokeAll = true; smoke = true},
- "aggressive smoke testing; try to prove false after every statement."),
- "time" -> (
- {() => timingVerbosity = 2},
- "sets /time:2")
- )
- // help text for options with arguments
- val nonBooleanOptions = ListMap(
- "boogie:<file>" -> "use the executable of Boogie at <file>",
- "print:<file>" -> "print the Boogie program used for verification into file <file>",
- "time:<n>" -> ("output timing information\n"+
- "0: no information is included\n"+
- "1: the overall verification time is output (default)\n"+
- "2: detailed timings for each phase of the verification are output\n"+
- "3: (used for testing only) output the overall verification time on stderr"),
- "defaults:<level>" -> ("defaults to reduce specification overhead\n"+
- "level 0 or below: no defaults\n"+
- "level 1: unfold predicates with receiver this in pre and postconditions\n"+
- "level 2: unfold predicates and functions with receiver this in pre and postconditions\n"+
- "level 3 or above: level 2 + autoMagic"),
- "percentageSupport:<n>" -> ("determin how percentage permissions are translated to Boogie\n"+
- "0: use multiplication directly (default)\n"+
- "1: use a function and provide some (redundant) axioms")+
- "boogieOpt:<arg>, /bo:<arg>" -> "specify additional Boogie options"
- )
- lazy val help = {
- val maxLength = math.min((nonBooleanOptions.keys++options.keys).map(s => s.length+1).max,14)
- val printOptionHelp = (param: String, help: String) => "\n /" + param + (" "*(maxLength-param.length-1)) +
- ": " + help.split("\n").map(h => " "*(maxLength+2+2)+wordWrap(h, 80-2-2-math.max(maxLength,param.length+1)," "*(maxLength+2+2))).mkString("\n").substring(maxLength+2+2)
-
- "Chalice concurrent program verifier.\nUsage: chalice [option] <filename>+\n"+
- " where <option> is one of"+
- options.foldLeft("")((acc, v) => acc + (if (v._2._2 == null) "" else printOptionHelp(v._1, v._2._2)))+
- nonBooleanOptions.foldLeft("")((acc, v) => acc + printOptionHelp(v._1, v._2))
- }
-
- for (a <- args) {
- if (a == "/help" || a == "-help") {Console.out.println(help); return None}
- else if ((a.startsWith("-") || a.startsWith("/")) && (options contains a.substring(1))) options(a.substring(1))._1()
- else if (a.startsWith("/print:") || a.startsWith("-print:")) {aBplFile = a.substring(7); aNoBplFile = false}
- else if (a.startsWith("/boogie:") || a.startsWith("-boogie:")) aBoogiePath = a.substring(8)
- else if (a.startsWith("/defaults:") || a.startsWith("-defaults:")) {
- try {
- defaults = Integer.parseInt(a.substring(10));
- if (3<=defaults) { autoMagic = true; }
- } catch { case _ => CommandLineError("-defaults takes integer argument", help); }
- }
- else if (a.startsWith("/percentageSupport:") || a.startsWith("-percentageSupport:")) {
- try {
- val in = Integer.parseInt(a.substring(19));
- if (in < 0 || in > 1) CommandLineError("/percentageSupport takes only values 0 or 1", help)
- else percentageSupport = in
- } catch { case _ => CommandLineError("/percentageSupport takes integer argument", help); }
- }
- else if (a.startsWith("/time:") || a.startsWith("-time:")) {
- try {
- val in = Integer.parseInt(a.substring(6));
- if (in < 0 || in > 3) CommandLineError("/time takes only values 0, 1, 2 or 3", help)
- else timingVerbosity = in
- } catch { case _ => CommandLineError("/time takes integer argument", help); }
- }
- else if (a.startsWith("-boogieOpt:") || a.startsWith("/boogieOpt:"))
- aBoogieArgs += ("\"/" + a.substring(11) + "\"" + " ")
- else if (a.startsWith("-bo:") || a.startsWith("/bo:"))
- aBoogieArgs += ("\"/" + a.substring(4) + "\"" + " ")
- /* [MHS] Quote whole argument to not confuse Boogie with arguments that
- * contain spaces, e.g. if Chalice is invoked as
- * chalice -z3exe:"C:\Program Files\z3\z3.exe" program.chalice
- */
- else if (a.startsWith("-z3opt:") || a.startsWith("/z3opt:"))
- aBoogieArgs += ("\"/z3opt:" + a.substring(7) + "\"" + " ")
- else if (a.startsWith("-") || a.startsWith("/")) {
- CommandLineError("unknown command line parameter: "+a.substring(1), help)
- return None
- }
- else inputs += a
- }
-
- // for smoke testing, we want to see all failing assertions, so we use no
- // error limit (or a very high one), and turn the subsumption option off
- if (smoke) {
- aBoogieArgs += ("\"-errorLimit:10000\" ")
- }
-
- percentageSupport match {
- case 0 => TranslatorPrelude.addComponent(PercentageStandardPL)
- case 1 => TranslatorPrelude.addComponent(PercentageFunctionPL)
- }
-
- // check that input files exist
- var aFiles = for (input <- inputs.toList) yield {
- val file = new File(input);
- if(! file.exists) {
- CommandLineError("input file " + file.getName() + " could not be found", help);
- return None;
- }
- InputFilename = input
- file;
- }
-
- Some(new CommandLineParameters{
- val boogiePath = aBoogiePath
- val files = aFiles
- val printProgram = aPrintProgram
- val doTypecheck = aDoTypecheck
- val doTranslate = aDoTranslate
- val boogieArgs = aBoogieArgs
- val gen = aGen
- val showFullStackTrace = aShowFullStackTrace
- val noBplFile = aNoBplFile
- val bplFile = aBplFile
- def getHelp(): String = help
- })
- }
-
- def parsePrograms(params: CommandLineParameters): Option[List[TopLevelDecl]] = {
- val files = params.files;
- val printProgram = params.printProgram;
-
- // parse programs
- val parser = new Parser();
- val parseResults = if (files.isEmpty) {
- if (!vsMode) println("No input file provided. Use 'chalice /help' for a list of all available command line options. Reading from stdin...")
- List(parser.parseStdin)
- } else for (file <- files) yield {
- parser.parseFile(file)
- }
-
- // report errors and merge declarations
- assert(parseResults.size > 0)
- var parseErrors = false;
- val program:List[TopLevelDecl] = parseResults.map(result => result match {
- case e:parser.NoSuccess =>
- parseErrors = true;
- if (vsMode)
- ReportError(e.next.pos, e.msg);
- else
- Console.out.println("Error: " + e);
- Nil
- case parser.Success(prog, _) =>
- val pprog = if (smoke) SmokeTest.smokeProgram(prog) else prog
- if (printProgram) PrintProgram.P(pprog)
- pprog
- }).flatten;
- if (parseErrors)
- None
- else
- Some(program)
- }
-
- def typecheckProgram(params: CommandLineParameters, program: List[TopLevelDecl]): Boolean = {
- // typecheck program
- Resolver.Resolve(program) match {
- case Resolver.Errors(msgs) =>
- if (!vsMode) Console.out.println("The program did not typecheck.");
- msgs foreach { msg => ReportError(msg._1, msg._2) };
- false;
- case Resolver.Success() =>
- true
- }
- }
-
- object VerificationSteps extends Enumeration {
- type VerificationSteps = Value
- val Init = Value("Init")
- val Parse = Value("Parse")
- val TypeCheck = Value("TypeCheck")
- val PrintProgram = Value("PrintProgram")
- val Translate = Value("Translate")
- val Boogie = Value("Boogie")
- val GenerateCode = Value("GenerateCode")
- }
-
- def main(args: Array[String]): Unit = {
-
- var timings = scala.collection.immutable.ListMap[VerificationSteps.Value, Long]()
- for (step <- VerificationSteps.values) timings += (step -> 0)
- var startTime = System.nanoTime
- var tmpTime = startTime
-
- //Parse command line arguments
- val params = parseCommandLine(args) match {
- case Some(p) => p
- case None => return //invalid arguments, help has been displayed
- }
-
- timings += (VerificationSteps.Init -> (System.nanoTime - tmpTime))
- tmpTime = System.nanoTime
-
- try {
-
- val program = parsePrograms(params) match {
- case Some(p) => p
- case None => return //illegal program, errors have already been displayed
- }
-
- timings += (VerificationSteps.Parse -> (System.nanoTime - tmpTime))
- tmpTime = System.nanoTime
-
- if(!params.doTypecheck || !typecheckProgram(params, program))
- return ;
-
- timings += (VerificationSteps.TypeCheck -> (System.nanoTime - tmpTime))
- tmpTime = System.nanoTime
-
- if (params.printProgram) {
- Console.out.println("Program after type checking: ");
- PrintProgram.P(program)
- }
-
- timings += (VerificationSteps.PrintProgram -> (System.nanoTime - tmpTime))
- tmpTime = System.nanoTime
-
- if(!params.doTranslate)
- return;
-
- // checking if Boogie.exe exists (on non-Linux machine)
- val boogieFile = new File(params.boogiePath);
- if(! boogieFile.exists() || ! boogieFile.isFile()
- && (System.getProperty("os.name") != "Linux")) {
- CommandLineError("Boogie.exe not found at " + params.boogiePath, params.getHelp());
- return;
- }
-
- val boogiePath = params.boogiePath
- val boogieArgs = params.boogieArgs
-
- // translate program to Boogie
- val translator = new Translator();
- var bplProg: List[Boogie.Decl] = Nil
- bplProg = translator.translateProgram(program);
-
- timings += (VerificationSteps.Translate -> (System.nanoTime - tmpTime))
- tmpTime = System.nanoTime
-
- // write to out.bpl
- val bplText = TranslatorPrelude.P + (bplProg map Boogie.Print).foldLeft(""){ (a, b) => a + b };
- val bplFilename = if (vsMode) "c:\\tmp\\out.bpl" else (if (params.noBplFile) "stdin.bpl" else params.bplFile)
- if (!params.noBplFile) writeFile(bplFilename, bplText);
- // run Boogie.exe on out.bpl
- val boogie = Runtime.getRuntime.exec(boogiePath + " /errorTrace:0 " + boogieArgs + "stdin.bpl");
- val output = boogie.getOutputStream()
- output.write(bplText.getBytes)
- output.close
- // terminate boogie if interrupted
- Runtime.getRuntime.addShutdownHook(new Thread(new Runnable() {
- def run {
- boogie.destroy
- }
- }))
- // the process blocks until we exhaust input and error streams
- new Thread(new Runnable() {
- def run {
- val err = new BufferedReader(new InputStreamReader(boogie.getErrorStream));
- var line = err.readLine;
- while(line!=null) {Console.err.println(line); Console.err.flush}
- }
- }).start;
- val input = new BufferedReader(new InputStreamReader(boogie.getInputStream));
- var line = input.readLine();
- var previous_line = null: String;
- val boogieOutput: ListBuffer[String] = new ListBuffer()
- while (line!=null){
- if (!smoke) {
- if (previous_line != null) Console.out.println
- Console.out.print(line);
- Console.out.flush;
- }
- boogieOutput += line
- previous_line = line;
- line = input.readLine();
- }
- boogie.waitFor;
- input.close;
-
- timings += (VerificationSteps.Boogie -> (System.nanoTime - tmpTime))
- tmpTime = System.nanoTime
-
- // smoke test output
- if (smoke) {
- val output = SmokeTest.processBoogieOutput(boogieOutput.toList)
- Console.out.print(output);
- Console.out.flush;
- }
-
- // generate code
- if(params.gen && (previous_line != null) && previous_line.endsWith(" 0 errors")) { // hack
- generateCSharpCode(params, program)
- }
-
- timings += (VerificationSteps.GenerateCode -> (System.nanoTime - tmpTime))
- tmpTime = System.nanoTime
- } catch {
- case e:InternalErrorException => {
- if (params.showFullStackTrace) {
- e.printStackTrace()
- Console.err.println()
- Console.err.println()
- }
- CommandLineError("Internal error: " + e.msg, params.getHelp())
- return
- }
- case e:NotSupportedException => {
- if (params.showFullStackTrace) {
- e.printStackTrace()
- Console.err.println()
- Console.err.println()
- }
- CommandLineError("Not supported: " + e.msg, params.getHelp())
- return
- }
- }
-
- val time = System.nanoTime - startTime
- if (timingVerbosity == 1) {
- Console.out.println(" in " + ("%1.3f" format (time / 1000000000.0)) + " seconds")
- } else if (timingVerbosity == 2) {
- Console.out.println; Console.out.println
- Console.out.println("Timings Information")
- val max = (timings.keySet.toList.map(a => a.toString.length).sortWith( (a, b) => a > b )).head
- for ((step, time) <- timings) {
- Console.out.println(" " + step + ": " + (" "*(max - step.toString.length)) + ("%1.3f" format (time / 1000000000.0)) + " seconds")
- }
- } else {
- Console.out.println
- }
- if (timingVerbosity == 3) {
- Console.err.println(("%1.3f" format (time / 1000000000.0)))
- }
- }
-
- def generateCSharpCode(params: CommandLineParameters, program: List[TopLevelDecl]): Unit = {
- val converter = new ChaliceToCSharp();
- println("Code generated in out.cs.");
- writeFile("out.cs", converter.convertProgram(program));
- }
-
- def writeFile(filename: String, text: String) {
- val writer = new FileWriter(new File(filename));
- writer.write(text);
- writer.flush();
- writer.close();
- }
-
- def CommandLineError(msg: String, help: String) = {
- Console.out.println("Error: " + msg)
- }
-
- def ReportError(pos: Position, msg: String) = {
- if (vsMode) {
- val (r,c) = (pos.line, pos.column)
- Console.out.println(r + "," + c + "," + r + "," + (c+5) + ":" + msg);
- } else {
- Console.out.println(pos + ": " + msg)
- }
- }
-
- def wordWrap(s: String, l: Int, indent: String): String = {
- var prefix = s.takeWhile(c => c == ' ').length
- if (prefix == 0) prefix = if (s.indexOf(": ") > 0) s.indexOf(": ")+2 else 0;
- val words = s.split(" ")
- var c = 0
- var result = ""
- var first = 0
- for (word <- words) {
- c += word.length + 1
- if (c-1 > l-first*prefix) { result += "\n"; c = word.length + 1; first = 1}
- result += word + " "
- }
- result.substring(0, result.length-1).replace("\n", "\n" + (" "*prefix) + indent).replace(" \n","\n")
- }
-}
-
-class InternalErrorException(val msg: String) extends Throwable
-class NotSupportedException(val msg: String) extends Throwable
-
diff --git a/Chalice/src/main/scala/ChaliceToCSharp.scala b/Chalice/src/main/scala/ChaliceToCSharp.scala
deleted file mode 100644
index 0df6fe6e..00000000
--- a/Chalice/src/main/scala/ChaliceToCSharp.scala
+++ /dev/null
@@ -1,266 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-class ChaliceToCSharp {
-
- def convertProgram(decls: List[TopLevelDecl]): String = {
- "using Chalice;" + nl + nl +
- rep(decls map convertTopLevelDecl)
- }
-
- def convertTopLevelDecl(decl: TopLevelDecl): String = {
- decl match {
- case cl: Class => convertClass(cl)
- case ch: Channel => convertChannel(ch)
- }
- }
-
- def convertChannel(ch: Channel): String = {
- "public class " + ch.channelId + " {" + nl +
- indentMore {
- indent + "class " + ch.channelId + "_args " + "{" + nl +
- indentMore {
- repsep(ch.parameters map { variable => indent + "internal " + convertType(variable.t) + " " + variable.id + ";"}, nl)
- } + nl + indent + "}" + nl +
- indent + "ChannelBuffer<" + ch.channelId + "_args" + ">" + " buffer = new ChannelBuffer<" + ch.channelId + "_args" + ">();" + nl +
- indent + "public void Send(" + repsep(ch.parameters map { variable => convertType(variable.t) + " " + variable.id }, ", ") + ") {" + nl +
- indentMore {
- indent + ch.channelId + "_args " + "entry = new " + ch.channelId + "_args" + "();" + nl +
- repsep(ch.parameters map { p => indent + "entry." + p.id + " = " + p.id + ";"}, nl) + nl +
- indent + "buffer.Add(entry);" + nl
- } +
- indent + "}" + nl +
- indent + "public void Receive(" + repsep(ch.parameters map { variable => "out " + convertType(variable.t) + " " + variable.id }, ", ") + ") {" + nl +
- indentMore {
- indent + ch.channelId + "_args " + "entry = buffer.Remove();" + nl +
- repsep(ch.parameters map { p => indent + p.id + " = entry." + p.id + ";"}, nl) + nl
- } +
- indent + "}" + nl
- } +
- "}" + nl + nl
- }
-
- def convertClass(cl: Class): String = if (cl.IsExternal) "" else {
- "public class " + cl.id + " {" + nl +
- indentMore { indent + "public " + cl.id + "() " + "{" + nl + indent + "}" } + nl + nl +
- (if(0 < cl.Fields.length) {
- indentMore { indent + "public " + cl.id + "(" + repsep(cl.Fields map { f => convertType(f.typ) + " " + f.Id }, ", ") + ") " + "{" + nl +
- indentMore { rep(cl.Fields map { f => indent + "this." + f.Id + " = " + f.Id + ";" + nl}) } +
- indent + "}" } + nl + nl
- } else "") +
- indentMore { repsep(cl.members map convertMember, nl) } +
- "}" + nl + nl
- }
-
- def convertMember(member: Member): String = {
- member match {
- case Field(id, tp, false) =>
- indent + "public " + convertType(tp) + " " + id + ";" + nl
- case meth@Method(id, ins, outs, spec, body) =>
- var csharpmain = if(id.equals("Start") && ins.length == 0 && outs.length == 0) {
- indent + "public static void Main() { " + nl +
- indentMore {
- indent + meth.Parent.id + " newObject = new " + meth.Parent.id + "();" + nl +
- indent + "newObject.Start();" + nl
- } +
- indent + "}" + nl + nl
- } else { "" };
- var params = repsep(ins map { variable => convertType(variable.t) + " " + variable.id }, ", ") + (if(ins.length > 0 && outs.length > 0) ", " else "") +
- repsep(outs map { variable => "out " + convertType(variable.t) + " " + variable.id }, ", ");
- csharpmain +
- indent + "public " + "void " + id + "(" + params + ") " + "{" + nl +
- indentMore {
- rep(outs map { x => indent + x.id + " = " + defaultValue(x.t) + ";" + nl } ) +
- rep(body map convertStatement)
- } +
- indent + "}" + nl + nl +
- indent + "public delegate " + "void " + id + "_delegate" + "(" + params + ");" + nl + nl +
- indent + "public class " + "Token_" + id + " { " + nl +
- (indentMore {
- indent + "public " + id + "_delegate " + "del;" + nl +
- indent + "public " + "System.IAsyncResult " + "async;" + nl +
- (rep(outs map { o: Variable => indent + "public " + convertType(o.t) + " " + o.id + ";" + nl }))
- }) +
- indent + "}" + nl
- case Function(id, ins, out, spec, definition) if definition.isDefined =>
- indent + "public " + convertType(out) + " " + id + "(" +
- repsep(ins map { variable => convertType(variable.t) + " " + variable.id }, ", ") +
- ") " + "{" + nl +
- indentMore { indent + "return " + convertExpression(definition.get) + ";" + nl } +
- indent + "}" + nl
- case MonitorInvariant(_) => indent + "// monitor invariant" + nl
- case Predicate(_, _) => indent + "//predicate" + nl
- case _ => throw new NotSupportedException("unsupportet construct")
- }
- }
-
- def convertStatement(statement: Statement): String = {
- statement match {
- case Assert(e) => indent + "// assert" + nl
- case Assume(e) => indent + {e match {
- case BoolLiteral(false) => "assert false;" + nl // abort since we made a wrong choice...
- case _ => // TODO: what to do with assume expressions that contain old, result, ghost variables, etc.
- "// assume" + nl}}
- case BlockStmt(ss) => indent + "{" + nl + (indentMore { rep(ss map convertStatement) }) + indent + "}" + nl
- case IfStmt(guard, thn, els) => indent + "if (" + convertExpression(guard) + ")" + nl + convertStatement(thn) +
- (if(els.isDefined) (indent + "else" + nl + convertStatement(els.get)) else { "" }) + nl
- case LocalVar(v, rhs) =>
- indent + convertType(v.t) + " " + v.id + " = " +
- (if(rhs.isDefined) convertExpression(rhs.get) else defaultValue(v.t)) +
- ";" + nl
- case FieldUpdate(MemberAccess(target, f), rhs) =>
- indent + convertExpression(target) + "." + f + " = " + convertExpression(rhs) + ";" + nl
- case Assign(VariableExpr(x), rhs) =>
- indent + x + " = " + convertExpression(rhs) + ";" + nl
- case WhileStmt(guard, _, _, _, body) =>
- indent + "while (" + convertExpression(guard) + ")" + nl + convertStatement(body) + nl
- case c@Call(_, lhs, target, id, args) =>
- declareLocals(c.locals) +
- indent + convertExpression(target) + "." + id + "(" +
- repsep(args map convertExpression, ", ") +
- (if(args.length > 0 && lhs.length > 0) ", " else "") +
- repsep(lhs map { l => "out " + convertExpression(l) }, ", ") +
- ")" + ";" + nl
- case Install(_, _, _) => indent + "// install" + nl
- case Share(_, _, _) => indent + "// share" + nl
- case Unshare(_) => indent + "// unshare" + nl
- case Downgrade(_) => indent + "// downgrade" + nl
- case Acquire(obj) => indent + "System.Threading.Monitor.Enter(" + convertExpression(obj) + ")" + ";" + nl
- case Release(obj) => indent + "System.Threading.Monitor.Exit(" + convertExpression(obj) + ")" + ";" + nl
- case Lock(obj, body, false) => indent + "lock(" + convertExpression(obj) + ") " + nl + convertStatement(body) + nl
- case Free(_) => indent + "// free" + nl
- case Fold(_) => indent + "// fold" + nl
- case Unfold(_) => indent + "// unfold" + nl
- case RdAcquire(obj) => assert(false); ""
- case RdRelease(obj) => assert(false); ""
- case Lock(_, _, true) => assert(false); ""
- case ca@CallAsync(declaresLocal, lhs, obj, id, args) =>
- val tokenName = if(declaresLocal) lhs.id else { uniqueInt += 1; "tok_" + uniqueInt };
- val call = convertExpression(obj) + "." + id;
- val tokenClass = ca.m.Parent.id + ".Token_" + id;
- val delegateName = ca.m.Parent.id + "." + id + "_delegate";
- indent + tokenClass + " " + tokenName + " = new " + tokenClass + "();" + nl +
- indent + tokenName + "." + "del" + " = new " + delegateName + "(" + call + ");" + nl +
- indent + tokenName + "." + "async" + " = " + tokenName + "." + "del" + "." + "BeginInvoke(" + repsep(args map convertExpression, ", ") +
- (if(args.length > 0 && ca.m.outs.length > 0) ", " else "") + repsep(ca.m.outs map { o => "out " + tokenName + "." + o.id }, ", ") +
- (if(args.length > 0 || ca.m.outs.length > 0) ", " else "") + "null, null" +
- ");" + nl
- case ja@JoinAsync(lhs, token) =>
- indent + convertExpression(token) + "." + "del.EndInvoke(" +
- repsep(lhs map { x => "out " + x.id}, ", ") +
- (if(lhs.length > 0) ", " else "") + convertExpression(token) + "." + "async" + ");" + nl
- case s@Send(ch, args) =>
- indent + convertExpression(ch) + ".Send(" + repsep(args map convertExpression, ", ") + ")" + ";" + nl
- case r@Receive(_, ch, outs) =>
- declareLocals(r.locals) +
- indent + convertExpression(ch) + ".Receive(" + repsep(outs map { out => "out " + convertExpression(out)}, ", ") + ")" + ";" + nl
- case _ => throw new NotSupportedException("unsupportet construct")
- }
- }
-
- def declareLocals(locals: List[Variable]) = {
- var s = ""
- for (v <- locals)
- s = s + indent + convertType(v.t) + " " + v.id + ";" + nl
- s
- }
-
- def convertExpression(expression: RValue): String = {
- expression match {
- case IntLiteral(n) => "" + n
- case BoolLiteral(b) => "" + b
- case NullLiteral() => "null"
- case StringLiteral(s) => "\"" + s + "\""
- case th: ThisExpr => "this"
- case VariableExpr(id) => id
- case MemberAccess(target, f) => convertExpression(target) + "." + f
- case newrhs@NewRhs(c, initialization, lower, upper) =>
- if(initialization.length == 0) { "new " + c + "()" } else {
- val init = repsep(newrhs.typ.Fields map { f => (initialization.find { i => i.f == f}) match {
- case None => defaultValue(f.typ)
- case Some(init) => convertExpression(init.e);
- }
- }, ", ");
- "new " + c + "(" + init + ")";
- }
- case At(s, i) => convertExpression(s) + ".At(" + convertExpression(i) + ")"
- case Append(s1, s2) => convertExpression(s1) + ".Append(" + convertExpression(s2) + ")"
- case Take(s, i) => convertExpression(s) + ".Take(" + convertExpression(i) + ")"
- case Drop(s, i) => convertExpression(s) + ".Drop(" + convertExpression(i) + ")"
- case LockBelow(_, _) => "true"
- case bin: BinaryExpr => "(" + convertExpression(bin.E0) + " " + bin.OpName + " " + convertExpression(bin.E1) + ")"// todo: <==> and ==>
- case Unfolding(p, e) => convertExpression(e)
- case FunctionApplication(target, id, args) => convertExpression(target) + "." + id + "(" + repsep(args map convertExpression, ", ") + ")"
- case Not(e) => "(! " + convertExpression(e) + ")"
- case EmptySeq(tp) => "new Chalice.ImmutableList<" + convertType(tp) + ">()"
- case es@ExplicitSeq(elems) =>
- val elemType = new Type(es.typ.asInstanceOf[SeqClass].parameter);
- "new Chalice.ImmutableList<" + convertType(elemType) + ">(" +
- "new " + convertType(elemType) + "[] {" + repsep(elems map convertExpression, ", ") + "}" +
- ")"
- case Range(min, max) => "Chalice.ImmutableList.Range(" + convertExpression(min) + ", " + convertExpression(max) + ")"
- case Length(s) => convertExpression(s) + ".Length"
- case IfThenElse(c, thn, els) => "(" + convertExpression(c) + " ? " + convertExpression(thn) + " : " + convertExpression(els) + ")"
- case _ => throw new NotSupportedException("Expression not supported yet!");
- }
- }
-
- def convertType(tp: Type): String = {
- tp.typ match {
- case t: TokenClass => t.c.FullName + ".Token_" + t.m
- case s: SeqClass => "Chalice.ImmutableList<" + convertType(new Type(s.parameter)) + ">"
- case IntClass => "int"
- case BoolClass => "bool"
- case NullClass => "object"
- case StringClass => "string"
- case Class(id, _, _, _) => id
- }
- }
-
- def defaultValue(tp: Type) = {
- tp.typ match {
- case t: TokenClass => "null"
- case s: SeqClass => "new Chalice.ImmutableList<" + convertType(new Type(s.parameter)) + ">()"
- case IntClass => "0"
- case BoolClass => "false"
- case NullClass => "null"
- case Class(id, _, _, _) => "null"
- }
- }
-
- // utility methods below
-
- var uniqueInt: Int = 0;
- val nl = System.getProperty("line.separator");
- var indentLevel = 0
-
- def rep(strings: List[String]): String = {
- strings.foldLeft("")({ (a, b) => a + b })
- }
-
- def repsep(strings: List[String], separator: String): String = {
- if(strings.length == 0) {
- ""
- } else {
- strings.reduceLeft({ (a, b) => a + separator + b })
- }
- }
-
- def indent: String = {
- def doIndent(i: Int): String = {
- if(i==0) { "" } else { " " + doIndent(i-1) }
- }
- doIndent(indentLevel);
- }
-
- def indentMore(what: => String) = {
- val prev = indentLevel
- indentLevel = indentLevel + 1
- val result = what
- indentLevel = prev
- result
- }
-}
diff --git a/Chalice/src/main/scala/Graph.scala b/Chalice/src/main/scala/Graph.scala
deleted file mode 100644
index f6790911..00000000
--- a/Chalice/src/main/scala/Graph.scala
+++ /dev/null
@@ -1,166 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-
-/**
- * Graph algorithms
- */
-package chalice;
-import scala.collection.mutable;
-import scala.collection.immutable;
-
-// Directed simple graph on T. Payload of nodes (of type T) should remain immutable while in graph.
-class DiGraph[T] {
- private class Node[T](t: T) {
- val data: T = t;
- var children = mutable.Set.empty[Node[T]];
-
- // temporary variables
- var index = -1;
- var lowlink = -1;
- var onstack = false;
- }
-
- private var rep = mutable.Map.empty[T, Node[T]];
-
- def addNode(t: T) = {
- if (hasNode(t))
- false;
- else {
- rep(t) = new Node(t);
- true;
- }
- }
-
- def addEdge(a: T, b: T) = {
- assert (hasNode(a));
- assert (hasNode(b));
- if (rep(a).children.contains(rep(b)))
- false
- else {
- rep(a).children += rep(b);
- true;
- }
- }
-
- def hasNode(a: T) = rep contains a;
-
- def nodes: immutable.Set[T] =
- immutable.Set() ++ rep.keys
-
- def children(t: T): immutable.Set[T] = {
- assert (rep contains t);
- immutable.Set() ++ (rep(t).children map {x => x.data})
- }
-
- // Compute topological sort (edges point in forward direction in the list)
- // Terminates but incorrect if not a DAG.
- def computeTopologicalSort: List[T] = {
- rep.values foreach {v => assert(!v.onstack)}
- var l: List[T] = Nil;
-
- def tarjan(v: Node[T]) {
- if (! v.onstack) {
- v.onstack = true;
- for (w <- v.children) tarjan(w)
- l = v.data :: l;
- }
- }
-
- rep.values foreach {v => tarjan(v)}
- rep.values foreach {v => assert(v.onstack); v.onstack = false;}
- l
- }
-
- // Compute condensation of the digraph.
- // The resulting digraph has no self loops
- def computeSCC: (DiGraph[List[T]],mutable.Map[T,List[T]]) = {
- // Tarjan's algorithm for finding strongly connected components
- // http://algowiki.net/wiki/index.php/Tarjan%27s_algorithm
- rep.values foreach {x => assert(x.index == -1 && x.lowlink == -1 && !x.onstack)};
-
- // morphism
- val result = new DiGraph[List[T]];
- val map = mutable.Map.empty[T,List[T]];
-
- // algorithm
- var index = 0;
- var S:List[Node[T]] = Nil;
-
- def tarjan(v: Node[T]) {
- v.index = index;
- v.lowlink = index;
- index = index + 1;
- S = v :: S; v.onstack = true;
- for (w <- v.children) {
- if (w.index == -1) {
- tarjan(w);
- v.lowlink = scala.math.min(v.lowlink, w.lowlink);
- } else if (w.onstack)
- v.lowlink = scala.math.min(v.lowlink, w.index);
- }
-
- if (v.lowlink == v.index) {
- var scc:List[T] = Nil;
- var w: Node[T] = null;
- while (v != w) {
- w = S.head;
- S = S.tail; w.onstack = false;
- scc = w.data :: scc;
- }
- result.addNode(scc);
- scc foreach {t => map(t) = scc}
- }
- }
-
- // compute SCCs
- rep.values foreach {n => if(n.index == -1) tarjan(n)};
-
- // compute SCCs edges
- rep.values foreach {n => n.children foreach {m =>
- if (map(n.data) != map(m.data))
- result.addEdge(map(n.data), map(m.data))
- }
- }
-
- // clean-up
- rep.values foreach {x => x.index = -1; x.lowlink = -1; x.onstack = false};
- (result,map);
- }
-}
-
-object Test {
- def main(args: Array[String]) {
- val g = new DiGraph[Int];
- assert(g.addNode(0));
- assert(!g.addNode(0));
- assert(g.addNode(1));
- assert(g.addNode(2));
- assert(g.addNode(3));
- assert(g.addNode(4));
- assert(g.addNode(5));
- g.addEdge(0,1);
- g.addEdge(0,1);
- g.addEdge(0,2);
- assert(g.children(0) == Set(1,2));
- g.addEdge(1,1);
- g.addEdge(2,3);
- g.addEdge(3,4);
- g.addEdge(3,5);
- g.addEdge(5,4);
- g.addEdge(4,2);
- g.computeSCC;
- val (d, h) = g.computeSCC;
- assert(h.get(0).get == List(0));
- assert(h.get(1).get == List(1));
- assert(h.get(2).get.size == 4);
- assert(h.get(3).get.size == 4);
- assert(h.get(4).get.size == 4);
- assert(h.get(5).get.size == 4);
- assert(d.children(h.get(0).get) == Set(h.get(1).get, h.get(2).get));
- assert(d.children(h.get(1).get) == Set());
- assert(d.children(h.get(2).get) == Set());
- }
-} \ No newline at end of file
diff --git a/Chalice/src/main/scala/Parser.scala b/Chalice/src/main/scala/Parser.scala
deleted file mode 100644
index 9a4cd272..00000000
--- a/Chalice/src/main/scala/Parser.scala
+++ /dev/null
@@ -1,645 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-import scala.util.parsing.combinator.syntactical.StandardTokenParsers
-import scala.util.parsing.combinator.lexical.StdLexical
-import scala.util.parsing.combinator._
-import scala.util.parsing.input.PagedSeqReader
-import scala.collection.immutable.PagedSeq
-import scala.util.parsing.input.Position
-import scala.util.parsing.input.Positional
-import scala.util.parsing.input.NoPosition
-import java.io.File
-
-class Parser extends StandardTokenParsers {
-
- def parseStdin = phrase(programUnit)(new lexical.Scanner(new PagedSeqReader(PagedSeq fromReader Console.in)))
- def parseFile(file: File) = phrase(programUnit)(new lexical.Scanner(new PagedSeqReader(PagedSeq fromFile file)))
-
- case class PositionedString(v: String) extends Positional
-
- // handle comments already in lexer
- override val lexical = new StdLexical {
- def rp: RegexParsers = new RegexParsers {}
- override val whitespace: Parser[Any] = rp.regex("""(\s|//.*|(?m)/\*(\*(?!/)|[^*])*\*/)*""".r).asInstanceOf[Parser[Any]]
- }
-
- lexical.reserved += ("class", "ghost", "var", "const", "method", "channel", "condition",
- "assert", "assume", "new", "this", "reorder",
- "between", "and", "above", "below", "share", "unshare", "acquire", "release", "downgrade",
- "lock", "fork", "join", "rd", "acc", "credit", "holds", "old", "assigned",
- "call", "if", "else", "while", "invariant", "lockchange",
- "returns", "requires", "ensures", "where", "static",
- "int", "bool", "false", "true", "null", "string", "waitlevel", "lockbottom",
- "module", "external",
- "predicate", "function", "free", "send", "receive",
- "ite", "fold", "unfold", "unfolding", "in", "forall", "exists",
- "seq", "nil", "result", "eval", "token",
- "wait", "signal", "unlimited",
- "refines", "transforms", "replaces", "by", "spec", "_", "*"
- )
- // todo: can we remove "nil"?
- lexical.delimiters += ("(", ")", "{", "}", "[[", "]]",
- "<==>", "==>", "&&", "||",
- "==", "!=", "<", "<=", ">=", ">", "<<", "in", "!in",
- "+", "-", "*", "/", "%", "!", ".", "..",
- ";", ":", ":=", ",", "?", "|", "[", "]", "++", "::"
- )
-
- def programUnit = (classDecl | channelDecl)*
- def Semi = ";" ?
- var currentLocalVariables = Set[String]() // used in the method context
- var assumeAllLocals = false;
- var insidePermission = false;
-
- /**
- * Top level declarations
- */
-
- def classDecl =
- positioned(("external" ?) ~ ("class" ~> ident) ~ opt("module" ~> ident) ~ opt("refines" ~> ident) ~
- ("{" ~> (memberDecl*) <~ "}") ^^ {
- case ext ~ id ~ module ~ refines ~ members =>
- val cl = Class(id, Nil, module.getOrElse("default"), members)
- if (ext.isDefined) cl.IsExternal = true
- if (refines.isDefined) {cl.IsRefinement = true; cl.refinesId = refines.get}
- cl
- })
- def channelDecl =
- positioned("channel" ~> ident ~ formalParameters(true) ~ ("where" ~> expression ?) <~ Semi ^^ {
- case id ~ ins ~ None => Channel(id, ins, BoolLiteral(true))
- case id ~ ins ~ Some(e) => Channel(id, ins, e)
- })
-
- /**
- * Member declarations
- */
-
- def memberDecl = {
- positioned(fieldDecl | invariantDecl | methodDecl | conditionDecl | predicateDecl | functionDecl | couplingDecl | transformDecl) // important that last one is transformDecl
- }
- def fieldDecl = {
- currentLocalVariables = Set[String]();
- ( "var" ~> idType <~ Semi ^^ { case (id,t) => Field(id.v, t, false) }
- | "ghost" ~> "var" ~> idType <~ Semi ^^ { case (id,t) => Field(id.v, t, true) }
- )
- }
- def invariantDecl = {
- currentLocalVariables = Set[String]();
- "invariant" ~> expression <~ Semi ^^ MonitorInvariant
- }
- def methodDecl = {
- currentLocalVariables = Set[String]();
- "method" ~> ident ~ formalParameters(true) ~ ("returns" ~> formalParameters(false) ?) ~
- (methodSpec*) ~ blockStatement ^^ {
- case id ~ ins ~ outs ~ spec ~ body =>
- Method(id, ins, outs match {case None => Nil; case Some(outs) => outs}, spec, body)
- }
- }
- def predicateDecl: Parser[Predicate] = {
- currentLocalVariables = Set[String]();
- ("predicate" ~> ident) ~ ("{" ~> expression <~ "}") ^^ { case id ~ definition => Predicate(id, definition) }
- }
- def functionDecl = {
- currentLocalVariables = Set[String]();
- ("unlimited" ?) ~ ("static" ?) ~ ("function" ~> ident) ~ formalParameters(true) ~ (":" ~> typeDecl) ~ (methodSpec*) ~ opt("{" ~> expression <~ "}") ^^ {
- case u ~ s ~ id ~ ins ~ out ~ specs ~ body => {
- val f = Function(id, ins, out, specs, body);
- if (u.isDefined) f.isUnlimited = true;
- if (s.isDefined) f.isStatic = true;
- f
- }
- }
- }
- def conditionDecl = {
- currentLocalVariables = Set[String]();
- "condition" ~> ident ~ ("where" ~> expression ?) <~ Semi ^^ {
- case id ~ optE => Condition(id, optE) }
- }
- def transformDecl = {
- currentLocalVariables = Set[String]();
- ( "refines" ~> ident ~ formalParameters(true) ~ ("returns" ~> formalParameters(false) ?) ~ (methodSpec*) ~ blockStatement ^^ {
- case id ~ ins ~outs ~ spec ~ body =>
- MethodTransform(id, ins, outs match {case None => Nil; case Some(outs) => outs}, spec, ProgramPat(body)) }).|(
- "transforms" ~> ident ~ formalParameters(true) ~ ("returns" ~> formalParameters(false) ?) ~ (methodSpec*) into {case id ~ ins ~ outs ~ spec =>
- assumeAllLocals = true;
- "{" ~> transform <~ "}" ^^ {
- trans =>
- assumeAllLocals = false;
- MethodTransform(id, ins, outs match {case None => Nil; case Some(outs) => outs}, spec, AST.normalize(trans))
- }
- })
- }
- def couplingDecl = {
- currentLocalVariables = Set[String]();
- ("replaces" ~> rep1sep(ident, ",") <~ "by") ~ expression <~ Semi ^^ {case ids ~ e => CouplingInvariant(ids, e)}
- }
-
- def formalParameters(immutable: Boolean) =
- "(" ~> (formalList(immutable) ?) <~ ")" ^^ {
- case None => Nil
- case Some(ids) => ids }
- def formalList(immutable: Boolean) = repsep(formal(immutable), ",")
- def formal(immutable: Boolean): Parser[Variable] =
- idType ^^ {case (id,t) =>
- currentLocalVariables = currentLocalVariables + id.v;
- new Variable(id.v,t,false,immutable)
- }
- def Ident = positioned(ident ^^ PositionedString)
- def idType = idTypeOpt ^^ {
- case (id, None) => (id, Type("int", Nil)) // todo: this feature was once convenient to make some Chalice programs look cleaner, but now that Chalice has grown up a bit, it's a feature that is better removed (or replaced by some type inference)
- case (id, Some(t)) => (id, t) }
- def idTypeOpt =
- Ident ~ (":" ~> typeDecl ?) ^^ { case id ~ optT => (id, optT) }
- def typeDecl: Parser[Type] =
- positioned(("int" | "bool" | ident | "string" | "seq") ~ opt("<" ~> repsep(typeDecl, ",") <~ ">") ^^ { case t ~ parameters => Type(t, parameters.getOrElse(Nil)) }
- | ("token" ~ "<") ~> (typeDecl <~ ".") ~ ident <~ ">" ^^ { case c ~ m => TokenType(c, m) }
- )
-
- /**
- * Pre and post conditions
- */
-
- def methodSpec =
- positioned( "requires" ~> expression <~ Semi ^^ Precondition
- | "ensures" ~> expression <~ Semi ^^ Postcondition
- | "lockchange" ~> expressionList <~ Semi ^^ LockChange
- )
-
- /**
- * Statements
- */
-
- def blockStatement: Parser[List[Statement]] = "{" ~> blockStatementBody <~ "}"
- def blockStatementBody: Parser[List[Statement]] = {
- val prev = currentLocalVariables
- (statement*) ^^ {
- case x => currentLocalVariables = prev; x }
- }
- def statement: Parser[Statement] =
- positioned( "assert" ~> expression <~ Semi ^^ Assert
- | "assume" ~> expression <~ Semi ^^ Assume
- | blockStatement ^^ BlockStmt
- | "var" ~> localVarStmt(false, false)
- | "spec" ~> localVarStmt(false, false)
- | "const" ~> localVarStmt(true, false)
- | "ghost" ~> "const" ~> localVarStmt(true, true)
- | "ghost" ~> "var" ~> localVarStmt(false, true)
- | "call" ~> callStmt
- | "if" ~> ifStmtThen
- | "while" ~> "(" ~> expression ~ ")" ~ loopSpec ~ blockStatement ^^ {
- case guard ~ _ ~ lSpec ~ body =>
- lSpec match { case (invs,lkch) => WhileStmt(guard, invs, Nil, lkch, BlockStmt(body)) }}
- | "reorder" ~> expression ~ (installBounds ?) <~ Semi ^^ {
- case obj ~ None => Install(obj, List(), List())
- case obj ~ Some(bounds) => Install(obj, bounds._1, bounds._2) }
- | "share" ~> expression ~ (installBounds ?) <~ Semi ^^ {
- case obj ~ None => Share(obj, List(), List())
- case obj ~ Some(bounds) => Share(obj, bounds._1, bounds._2) }
- | "unshare" ~> expression <~ Semi ^^ Unshare
- | "acquire" ~> expression <~ Semi ^^ Acquire
- | "release" ~> expression <~ Semi ^^ Release
- | "lock" ~> "(" ~> expression ~ ")" ~ blockStatement ^^ {
- case e ~ _ ~ b => Lock(e, BlockStmt(b), false) }
- | "[[" ~> blockStatementBody <~ "]]" ^^ {
- case b => Lock(ExplicitThisExpr(), BlockStmt(b), false) }
- | "rd" ~>
- ( "lock" ~> "(" ~> expression ~ ")" ~ blockStatement ^^ {
- case e ~ _ ~ b => Lock(e, BlockStmt(b), true) }
- | "acquire" ~> expression <~ Semi ^^ RdAcquire
- | "release" ~> expression <~ Semi ^^ RdRelease
- )
- | "downgrade" ~> expression <~ Semi ^^ Downgrade
- | "free" ~> expression <~ Semi ^^ Free
- | Ident ~ ":=" ~ Rhs <~ Semi ^^ {
- case lhs ~ _ ~ rhs =>
- if ((currentLocalVariables contains lhs.v) || assumeAllLocals) {
- val varExpr = VariableExpr(lhs.v); varExpr.pos = lhs.pos;
- Assign(varExpr, rhs)
- } else {
- val implicitThis = ImplicitThisExpr();
- val select = MemberAccess(implicitThis, lhs.v);
- implicitThis.pos = lhs.pos;
- select.pos = lhs.pos;
- FieldUpdate(select, rhs)
- }}
- | selectExprFerSure ~ ":=" ~ Rhs <~ Semi ^^ {
- case lhs ~ _ ~ rhs => FieldUpdate(lhs, rhs) }
- | ("fold" ~> expression <~ Semi) ^? {
- case pred: MemberAccess => Fold(Access(pred, Full))
- case perm: Access => Fold(perm)
- }
- | ("unfold" ~> expression <~ Semi) ^? {
- case pred: MemberAccess => Unfold(Access(pred, Full))
- case perm: Access => Unfold(perm)
- }
- | ("fork") ~> callSignature ^? ({
- case None ~ target ~ args =>
- val (receiver, name) = target match {
- case VariableExpr(id) => (new ImplicitThisExpr, id)
- case MemberAccess(obj, id) => (obj, id)
- }
- CallAsync(false, null, receiver, name, args)
- case Some(List(tok)) ~ target ~ args =>
- val (receiver, name) = target match {
- case VariableExpr(id) => (new ImplicitThisExpr, id)
- case MemberAccess(obj, id) => (obj, id)
- }
- if (currentLocalVariables contains tok.id) {
- CallAsync(false, tok, receiver, name, args)
- } else {
- currentLocalVariables = currentLocalVariables + tok.id;
- CallAsync(true, tok, receiver, name, args)
- }
- }, t => "fork statement cannot take more than 1 left-hand side")
- | (("join") ~> ( identList <~ ":=" ?)) ~ expression <~ Semi ^^
- { case results ~ token => JoinAsync(ExtractList(results), token) }
- | "wait" ~> memberAccess <~ Semi ^^ {
- case MemberAccess(obj, id) => Wait(obj, id) }
- | "signal" ~> ("forall" ?) ~ memberAccess <~ Semi ^^ {
- case None ~ MemberAccess(obj, id) => Signal(obj, id, false)
- case _ ~ MemberAccess(obj, id) => Signal(obj, id, true) }
- | ("send" ~> suffixPlusExpr into { e => e match {
- case FunctionApplication(obj, name, args) => Semi ^^^ Send(MemberAccess(obj,name), args)
- case e => "(" ~> expressionList <~ ")" <~ Semi ^^ { case args => Send(e, args) }}})
- | ("send" ~> atom into { e => e match {
- case fa@FunctionApplication(ImplicitThisExpr(), name, args) => Semi ^^^ {val va = VariableExpr(name); va.pos = fa.pos; Send(va, args)}
- case e => "(" ~> expressionList <~ ")" <~ Semi ^^ { case args => Send(e, args) }}})
- | "receive" ~> (identList <~ ":=" ?) ~ expression <~ Semi ^^ {
- case outs ~ e =>
- val lhs = ExtractList(outs)
- Receive(declareImplicitLocals(lhs), e, lhs) }
- )
- // this could be slightly changed to make it LL(1)
- def localVarStmt(const: Boolean, ghost: Boolean) =
- ( (rep1sep(idType, ",") into {decls:List[(PositionedString,Type)] => {
- val locals = for ((id, t) <- decls; if (! currentLocalVariables.contains(id.v))) yield {
- currentLocalVariables = currentLocalVariables + id.v
- new Variable(id.v, t, ghost, const)
- }
- val lhs = for ((id, _) <- decls) yield {
- val v = VariableExpr(id.v); v.pos = id.pos; v
- }
- "[" ~> opt(expression <~ ",") ~ expression <~ "]" <~ Semi ^^ {
- case Some(pre) ~ post => SpecStmt(lhs, locals, pre, post)
- case None ~ post => SpecStmt(lhs, locals, BoolLiteral(true), post)
- };
- } })
- | idTypeOpt ~ (":=" ~> Rhs ?) <~ Semi ^^ {
- case (id,optT) ~ rhs =>
- currentLocalVariables = currentLocalVariables + id.v
- val v = Variable(id.v,
- optT match {
- case Some(t) => t
- case None =>
- // do a cheap (and hokey) type inference of the RHS
- rhs match {
- case Some(NewRhs(tid, _, _, _)) => Type(tid, Nil)
- case Some(BoolLiteral(b)) => Type("bool", Nil)
- case Some(StringLiteral(s)) => Type("string", Nil)
- case Some(x:BinaryExpr) if x.ResultType != null => new Type(x.ResultType);
- case Some(x:Contains) => Type("bool", Nil)
- case Some(x:Quantification) => Type("bool", Nil)
- case _ => Type("int", Nil)
- }
- }, ghost, const)
- LocalVar(v, rhs) }
- )
- def ifStmtThen: Parser[IfStmt] =
- "(" ~> expression ~ ")" ~ blockStatement ~ ("else" ~> ifStmtElse ?) ^^ {
- case guard ~ _ ~ thenClause ~ elseClause => IfStmt(guard, BlockStmt(thenClause), elseClause) }
- def ifStmtElse =
- ( "if" ~> ifStmtThen
- | statement
- )
- def loopSpec: Parser[(List[Expression], List[Expression])] =
- (loopSpecX *) ^^ {
- case pp => (pp :\ (List[Expression](), List[Expression]())) ( (p,list) =>
- (p,list) match {
- case ((null,ee),(e0,e1)) => (e0, ee ++ e1)
- case ((e,ee),(e0,e1)) => (e :: e0, ee ++ e1)
- })
- }
- def loopSpecX =
- ( "invariant" ~> expression <~ Semi ^^ { case e => (e,Nil) }
- | "lockchange" ~> expressionList <~ Semi ^^ { case ee => (null,ee) }
- )
- def declareImplicitLocals(lhs: List[VariableExpr]) =
- for (v <- lhs) yield
- if (currentLocalVariables contains v.id)
- false
- else {
- currentLocalVariables = currentLocalVariables + v.id
- true
- }
- def callStmt =
- callSignature ^? ({
- case outs ~ VariableExpr(id) ~ args =>
- val lhs = ExtractList(outs)
- Call(declareImplicitLocals(lhs), lhs, new ImplicitThisExpr, id, args)
- case outs ~ MemberAccess(obj,id) ~ args =>
- val lhs = ExtractList(outs)
- Call(declareImplicitLocals(lhs), lhs, obj, id, args)
- }, t => "bad call statement")
- def callSignature =
- (identList <~ ":=" ?) ~ callTarget ~ expressionList <~ ")" <~ Semi
- def callTarget = // returns a VariableExpr or a FieldSelect
- ( ident <~ "(" ^^ VariableExpr
- | selectExprFerSure <~ "("
- )
- def memberAccess = // returns a MemberAccess
- ( selectExprFerSure
- | ident ^^ { case id => MemberAccess(ImplicitThisExpr(), id) }
- )
- def ExtractList[T](a: Option[List[T]]): List[T] = a match {
- case None => Nil
- case Some(list) => list }
- def identList =
- ( Ident ^^ { case t => val v = VariableExpr(t.v); v.pos = t.pos; v }) ~
- (("," ~> Ident ^^ { case t => val v = VariableExpr(t.v); v.pos = t.pos; v }) *) ^^ { case e ~ ee => e::ee }
- def Rhs : Parser[RValue] =
- positioned(
- "new" ~> ident ~ opt("{" ~> repsep(FieldInit, ",") <~ "}") ~ opt(installBounds) ^^ {
- case id ~ None ~ None => NewRhs(id, Nil, Nil, Nil)
- case id ~ Some(inits) ~ None => NewRhs(id, inits, Nil, Nil)
- case id ~ None ~ Some(bounds) => NewRhs(id, Nil, bounds._1, bounds._2)
- case id ~ Some(inits) ~ Some(bounds) => NewRhs(id, inits, bounds._1, bounds._2)
- }
- | expression
- )
- def FieldInit: Parser[Init] =
- positioned( (ident <~ ":=") ~ expression ^^ { case id ~ e => Init(id, e) } )
- def installBounds: Parser[(List[Expression], List[Expression])] =
- ( "between" ~> expressionList ~ "and" ~ expressionList ^^ { case l ~ _ ~ u => (l,u) }
- | "below" ~> expressionList ~ ("above" ~> expressionList ?) ^^ {
- case u ~ None => (Nil,u)
- case u ~ Some(l) => (l,u) }
- | "above" ~> expressionList ~ ("below" ~> expressionList ?) ^^ {
- case l ~ None => (l,Nil)
- case l ~ Some(u) => (l,u) }
- )
-
- /**
- * Expressions
- */
-
- def expressionList =
- repsep(expression, ",")
- def expression = positioned(iteExpr)
-
- def partialExpressionList =
- repsep(expression | ("_" ^^^ VariableExpr("?")), ",")
-
- def iteExpr: Parser[Expression] =
- positioned(iffExpr ~ (("?" ~> iteExpr) ~ (":" ~> iteExpr) ?) ^^ {
- case e ~ None => e
- case e0 ~ Some(e1 ~ e2) => IfThenElse(e0,e1,e2) })
- def iffExpr: Parser[Expression] =
- positioned(implExpr ~ ("<==>" ~> iffExpr ?) ^^ {
- case e ~ None => e
- case e0 ~ Some(e1) => Iff(e0,e1) })
- def implExpr: Parser[Expression] =
- positioned(logicalExpr ~ ("==>" ~> implExpr ?) ^^ {
- case e ~ None => e
- case e0 ~ Some(e1) => Implies(e0,e1) })
- def logicalExpr =
- positioned(cmpExpr ~ (( ("&&" ~ cmpExpr +) | ("||" ~ cmpExpr +) )?) ^^ {
- case e ~ None => e
- case e0 ~ Some(rest) => (rest foldLeft e0) {
- case (a, "&&" ~ b) => And(a,b)
- case (a, "||" ~ b) => Or(a,b) }})
- def cmpExpr =
- positioned(concatExpr ~ ((CompareOp ~ concatExpr)?) ^^ {
- case e ~ None => e
- case e0 ~ Some("==" ~ e1) => Eq(e0,e1)
- case e0 ~ Some("!=" ~ e1) => Neq(e0,e1)
- case e0 ~ Some("<" ~ e1) => Less(e0,e1)
- case e0 ~ Some("<=" ~ e1) => AtMost(e0,e1)
- case e0 ~ Some(">=" ~ e1) => AtLeast(e0,e1)
- case e0 ~ Some(">" ~ e1) => Greater(e0,e1)
- case e0 ~ Some("<<" ~ e1) => LockBelow(e0,e1)
- case e0 ~ Some("in" ~ e1) => Contains(e0, e1)
- case e0 ~ Some("!in" ~ e1) => val c = Contains(e0, e1); c.pos = e0.pos; Not(c)
- })
- def CompareOp = "==" | "!=" | "<" | "<=" | ">=" | ">" | "<<" | "in" | "!in"
- def concatExpr =
- positioned(addExpr ~ ("++" ~> addExpr *) ^^ {
- case e0 ~ rest => (rest foldLeft e0) {
- case (a, b) => Append(a, b) }})
- def addExpr =
- positioned(multExpr ~ (AddOp ~ multExpr *) ^^ {
- case e0 ~ rest => (rest foldLeft e0) {
- case (a, "+" ~ b) => Plus(a,b)
- case (a, "-" ~ b) => Minus(a,b) }})
- def AddOp = "+" | "-"
- def multExpr: Parser[Expression] =
- unaryExpr ~ (MulOp ~ unaryExpr *) ^^ {
- case e0 ~ rest => (rest foldLeft e0) {
- case (a, "*" ~ b) => Times(a,b)
- case (a, "/" ~ b) => Div(a,b)
- case (a, "%" ~ b) => Mod(a,b) }}
- def MulOp = "*" | "/" | "%"
- def unaryExpr: Parser[Expression] =
- ( "!" ~> unaryExpr ^^ Not
- | "-" ~> unaryExpr ^^ { Minus(IntLiteral(0),_) }
- | suffixExpr
- )
- def suffixExpr =
- atom ~ (suffixThing *) ^^ {
- case e ~ sfxs => sfxs.foldLeft(e) { (t, a) => val result = a(t); result.pos = t.pos; result } }
- def suffixPlusExpr =
- atom ~ (suffixThing +) ^^ {
- case e ~ sfxs => sfxs.foldLeft(e) { (t, a) => val result = a(t); result.pos = t.pos; result } }
- def suffixThing: Parser[(Expression => Expression)] =
- ( "[" ~> expression <~ "]" ^^ { case e1 => { e0: Expression => At(e0, e1) }}
- | "[" ~> expression <~ (".." ~ "]") ^^ { case e1 => { e0: Expression => Drop(e0, e1)}}
- | "[" ~> ".." ~> expression <~ "]" ^^ { case e1 => { e0: Expression => Take(e0, e1)}}
- | "[" ~> (expression <~ "..") ~ expression <~ "]" ^^ {
- case e1 ~ e2 => {e0: Expression => val tak = Take(e0, e2); tak.pos = e0.pos; Drop(tak, e1)} }
- | "." ~> ident ~ opt("(" ~> expressionList <~ ")") ^^ {
- case name ~ None => { e0: Expression => MemberAccess(e0, name) }
- case name ~ Some(es) => { e0: Expression => FunctionApplication(e0, name, es) } }
- | "." ~> "acquire" ~> exprBody ^^ { case eb => { e0: Expression => Eval(AcquireState(e0), eb) }}
- | "." ~> "release" ~> exprBody ^^ { case eb => { e0: Expression => Eval(ReleaseState(e0), eb) }}
- | "." ~> "fork" ~> (callTarget ~ partialExpressionList <~ ")") ~ exprBody ^^ {
- case MemberAccess(obj,id) ~ args ~ eb => { e0: Expression => Eval(CallState(e0, obj, id, args), eb) }}
- )
- def exprBody =
- "{" ~> expression <~ "}"
-
- def selectExprFerSure: Parser[MemberAccess] =
- positioned(atom ~ "." ~ ident ~ ("." ~> ident *) ^^ {
- case e ~ _ ~ field ~ moreFields =>
- (moreFields foldLeft MemberAccess(e,field)) { (target, f) =>
- val result = MemberAccess(target, f); result.pos = target.pos; result }})
- def selectExprFerSureX: Parser[MemberAccess] =
- positioned(atom ~ identOrSpecial ~ ("." ~> ident *) ^^ {
- case e ~ field ~ moreFields =>
- (moreFields foldLeft MemberAccess(e,field)) { (target, f) =>
- val result = MemberAccess(target, f); result.pos = target.pos; result }})
- def identOrSpecial: Parser[String] =
- ( "." ~> ident ^^ { case s => s }
- | "." ~> "acquire" ^^^ "acquire"
- | "." ~> "release" ^^^ "release"
- | "." ~> "fork" ^^^ "fork"
- | "." ~> "*" ^^^ "*"
- | "["~"*"~"]"~"."~"*" ^^^ "[*].*"
- | "["~"*"~"]" ^^^ "[*]"
- )
-
- def atom : Parser[Expression] =
- positioned(
- numericLit ^^ { case n => IntLiteral(n.toInt) }
- | "false" ^^^ BoolLiteral(false)
- | "true" ^^^ BoolLiteral(true)
- | "null" ^^^ NullLiteral()
- | stringLit ^^ { case s => StringLiteral(s) }
- | "waitlevel" ^^^ MaxLockLiteral()
- | "lockbottom" ^^^ LockBottomLiteral()
- | "this" ^^^ ExplicitThisExpr()
- | "result" ^^^ Result()
- | positioned(Ident) ~ opt("(" ~> expressionList <~ ")") ^^ {
- case id ~ None =>
- val r =
- if ((currentLocalVariables contains id.v) || assumeAllLocals) {
- VariableExpr(id.v)
- } else {
- val implicitThis = ImplicitThisExpr(); implicitThis.pos = id.pos
- MemberAccess(implicitThis, id.v)
- }
- r.pos = id.pos; r
- case id ~ Some(args) =>
- val implicitThis = ImplicitThisExpr(); implicitThis.pos = id.pos
- val r = FunctionApplication(implicitThis, id.v, args)
- r.pos = id.pos; r
- }
- | "rd" ~> "(" ~>
- ( // note: depending on the context where rd occurs, we parse it wrongly (e.g. acc(x,rd(n)) is parsed to
- // Access(MemberAccess(ImplicitThisExpr(),x),Frac(Access(MemberAccess(ImplicitThisExpr(),n),Epsilon))) ).
- // This might seem completely wrong (and it is), but we correct this later, see the comment before
- // method ResolvePermissionExpr in the resolver.
- (( (Ident ^^ (e => { val result = MemberAccess(ImplicitThisExpr(),e.v); result.pos = e.pos; result})) ~ rdPermArg <~ ")"
- | selectExprFerSureX ~ rdPermArg <~ ")"
- ) ^^ {
- case MemberAccess(obj, "*") ~ p => AccessAll(obj, p);
- case MemberAccess(obj, "[*].*") ~ p => AccessSeq(obj, None, p);
- case MemberAccess(MemberAccess(obj, "[*]"), f) ~ p => AccessSeq(obj, Some(MemberAccess(At(obj, IntLiteral(0)), f)), p);
- case e ~ p => Access(e, p)
- })
- | expression <~ ")" ^^ {
- case e => val eps = Epsilons(e); eps.pos = e.pos; eps
- }
- | "*" ~> ")" ~ err("This syntax is not supported any longer. For the starred read permission, use rd*(o.f).") ^^^ Star
- )
- | "rd" ~> "*" ~> "(" ~>
- (
- (( (Ident ^^ (e => { val result = MemberAccess(ImplicitThisExpr(),e.v); result.pos = e.pos; result})) <~ ")"
- | selectExprFerSureX <~ ")"
- ) ^^ {
- case MemberAccess(obj, "*") => AccessAll(obj, Star);
- case MemberAccess(obj, "[*].*") => AccessSeq(obj, None, Star);
- case MemberAccess(MemberAccess(obj, "[*]"), f) => AccessSeq(obj, Some(MemberAccess(At(obj, IntLiteral(0)), f)), Star);
- case e => Access(e, Star)
- })
- )
- | "acc" ~> "(" ~>
- ( (Ident ^^ (e => { val result = MemberAccess(ImplicitThisExpr(),e.v); result.pos = e.pos; result} )) ~ accPermArg <~ ")"
- | selectExprFerSureX ~ accPermArg <~ ")"
- ) ^^ {
- case MemberAccess(obj, "*") ~ p => AccessAll(obj, p);
- case MemberAccess(obj, "[*].*") ~ p => AccessSeq(obj, None, p);
- case MemberAccess(MemberAccess(obj, "[*]"), f) ~ p => AccessSeq(obj, Some(MemberAccess(At(obj, IntLiteral(0)), f)), p);
- case e ~ p => Access(e, p)
- }
- | "credit" ~> "(" ~> expression ~ ("," ~> expression ?) <~ ")" ^^ {
- case ch ~ n => Credit(ch, n) }
- | "holds" ~> "(" ~> expression <~ ")" ^^ Holds
- | "rd" ~> "holds" ~> "(" ~> expression <~ ")" ^^ RdHolds
- | "rd" ^^ (_ => MethodEpsilon)
- | "assigned" ~> "(" ~> ident <~ ")" ^^ Assigned
- | "old" ~> "(" ~> expression <~ ")" ^^ Old
- | ("unfolding" ~> suffixExpr <~ "in") ~ expression ^? {
- case (pred: MemberAccess) ~ e => val acc = Access(pred, Full); acc.pos = pred.pos; Unfolding(acc, e)
- case (perm: Access) ~ e => Unfolding(perm, e)
- }
- | "|" ~> expression <~ "|" ^^ Length
- | ("eval" ~ "(") ~> (evalstate <~ ",") ~ (expression <~ ")") ^^ { case h ~ e => Eval(h, e) }
- | ("ite" ~> "(" ~> expression <~ ",") ~ (expression <~ ",") ~ (expression <~ ")") ^^ {
- case con ~ then ~ els => IfThenElse (con, then, els) }
- | "(" ~> expression <~ ")"
- | quantifierType
- | quantifierSeq
- | ("[" ~> expression) ~ (".." ~> expression <~ "]") ^^ { case from ~ to => Range(from, to) }
- | ("nil" ~> "<") ~> (typeDecl <~ ">") ^^ EmptySeq
- | ("[" ~> expressionList <~ "]") ^^ { case es => ExplicitSeq(es) }
- )
-
- def quantifierSeq: Parser[Quantification] =
- (quant ~ repsep(ident, ",")) into {case q ~ is => quantifierSeqBody(q, is)}
- def quantifierSeqBody(q: Quant, is: List[String]) : Parser[Quantification] =
- (("in" ~> expression <~ "::") ~ (exprWithLocals(is))) ^^
- { case seq ~ e =>
- currentLocalVariables = currentLocalVariables -- is;
- SeqQuantification(q, is, seq, e);
- }
- def quantifierType: Parser[Quantification] =
- (quant ~ repsep(ident, ",")) into {case q ~ is => quantifierTypeBody(q, is)}
- def quantifierTypeBody(q: Quant, is: List[String]) : Parser[Quantification] =
- ((":" ~> typeDecl <~ "::") ~ (exprWithLocals(is))) ^^
- { case t ~ e =>
- currentLocalVariables = currentLocalVariables -- is;
- new TypeQuantification(q, is, t, e);
- }
- def quant: Parser[Quant] =
- ( "forall" ^^^ Forall | "exists" ^^^ Exists)
-
- def exprWithLocals(i: List[String]) : Parser[Expression] = {
- currentLocalVariables = currentLocalVariables ++ i;
- val result = ((expression) ^^ { case e => e});
- result
- }
-
- def evalstate: Parser[EvalState] =
- (suffixExpr <~ ".") into { e =>
- ( "acquire" ^^^ AcquireState(e)
- | "release" ^^^ ReleaseState(e)
- | "fork" ~> callTarget ~ partialExpressionList <~ ")" ^^ {
- case MemberAccess(obj,id) ~ args => CallState(e, obj, id, args) }
- )}
-
- def rdPermArg : Parser[Permission] =
- opt( "," ~> "*" ~ err("This syntax is not supported any longer. For the starred read permission, use rd*(o.f).") ^^^ Star
- | "," ~> expression ^^ { case e => val eps = Epsilons(e); eps.pos = e.pos; eps }) ^^ { case None => Epsilon; case Some(p) => p}
-
- def accPermArg : Parser[Write] =
- opt( "," ~> expression ^^ { case e => val f: Frac = Frac(e); f.pos = e.pos; f }) ^^ { case None => Full; case Some(p) => p}
-
- /**
- * Transforms
- */
-
- def transform: Parser[Transform] = rep1(transformAtom) ^^ SeqPat
- def transformAtom: Parser[Transform] = positioned(
- "_" ~ Semi ^^^ BlockPat()
- | "*" ~ Semi ^^^ SkipPat()
- | "if" ~> ifTransform
- | "while" ~> rep("invariant" ~> expression <~ Semi) ~ ("{" ~> transform <~ "}") ^^ {case ee ~ body => WhilePat(ee, body)}
- | "replaces" ~> "*" ~> "by" ~> blockStatement ^^ ProgramPat
- | "replaces" ~> rep1sep(Ident,",") ~ ("by" ~> blockStatement) ^^ {
- case ids ~ code => NonDetPat(ids map {x => x.v}, code)
- }
- | rep1(statement) ^^ {case s => InsertPat(s)}
- )
- def ifTransform: Parser[IfPat] =
- ("{" ~> transform <~ "}") ~ ("else" ~> ifTransformElse ?) ^^ {
- case thn ~ els => IfPat(thn, els)
- }
- def ifTransformElse = (
- "if" ~> ifTransform
- | "{" ~> transform <~ "}"
- )
-
-}
diff --git a/Chalice/src/main/scala/Prelude.scala b/Chalice/src/main/scala/Prelude.scala
deleted file mode 100644
index 4a333f8e..00000000
--- a/Chalice/src/main/scala/Prelude.scala
+++ /dev/null
@@ -1,432 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-import scala.collection.mutable.Set;
-
-/*
-This object computes the Boogie prelude for the translator, which consists of different
-components (objects that are subtypes of PreludeComponent). It is possible to include
-such components only on demand, when they are actually needed. For instance, the sequence
-axiomatization is only included if sequences are used in the program at hand.
-*/
-object TranslatorPrelude {
-
- // adds component c to the prelude. has no effect if c is already present.
- def addComponent(c: PreludeComponent*): Unit = {
- components ++= c
- }
-
- // removes a component from the prelude. use with great care, as other parts of
- // the system could depend on the component c being present in the prelude.
- def removeComponent(c: PreludeComponent*): Unit = {
- components --= c
- }
-
- // records that a predicate occurs in the program (used for generating the
- // correct triggers for an axiom in the prelude)
- def addPredicate(p: Predicate*): Unit = {
- predicates ++= p
- }
- val predicates: Set[Predicate] = Set()
-
- // default components
- private val components: Set[PreludeComponent] = Set(CopyrightPL, TypesPL, PermissionTypesAndConstantsPL, CreditsAndMuPL, PermissionFunctionsAndAxiomsPL, IfThenElsePL, StringPL)
-
- // get the prelude (with all components currently included)
- def P: String = {
- val l = components.toList.sortWith((a,b) => a compare b)
- l.foldLeft("")((s:String,a:PreludeComponent) => s + "\n" + (a text)) +
-"""
-
-// ---------------------------------------------------------------
-// -- End of prelude ---------------------------------------------
-// ---------------------------------------------------------------
-
-"""
- }
-
-}
-
-sealed abstract class PreludeComponent {
- // determines the order in which the components are output
- def compare(that: PreludeComponent): Boolean = {
- val order: List[PreludeComponent] = List(CopyrightPL, TypesPL, PermissionTypesAndConstantsPL, PercentageFunctionPL, CreditsAndMuPL, PermissionFunctionsAndAxiomsPL, IfThenElsePL, StringPL, AxiomatizationOfSequencesPL)
- if (!order.contains(this)) false
- else order.indexOf(this) < order.indexOf(that)
- }
- def text: String
-}
-
-object CopyrightPL extends PreludeComponent {
- val text = "// Copyright (c) 2008, Microsoft"
-}
-object TypesPL extends PreludeComponent {
- val text = """
-type Field a;
-type HeapType = <a>[ref,Field a]a;
-type MaskType = <a>[ref,Field a][PermissionComponent]real;
-type PMaskType = <a>[ref,Field a]bool;
-type CreditsType = [ref]int;
-type ref;
-const null: ref;
-
-var Heap: HeapType;"""
-}
-object PermissionTypesAndConstantsPL extends PreludeComponent {
- val text = """
-type PermissionComponent;
-const unique perm$R: PermissionComponent;
-const unique perm$N: PermissionComponent;
-var Mask: MaskType where IsGoodMask(Mask);
-var SecMask: MaskType where IsGoodMask(SecMask);
-const Permission$denominator: real;
-axiom Permission$denominator == 1.0;
-const Permission$FullFraction: real;
-const Permission$Zero: [PermissionComponent]real;
-axiom Permission$Zero[perm$R] == 0.0 && Permission$Zero[perm$N] == 0.0;
-const Permission$Full: [PermissionComponent]real;
-axiom Permission$Full[perm$R] == Permission$FullFraction && Permission$Full[perm$N] == 0.0;
-const ZeroMask: MaskType;
-axiom (forall<T> o: ref, f: Field T, pc: PermissionComponent :: ZeroMask[o,f][pc] == 0.0);
-const ZeroPMask: PMaskType;
-axiom (forall<T> o: ref, f: Field T :: ZeroPMask[o,f] == false);
-axiom IsGoodMask(ZeroMask);
-const unique joinable: Field int;
-axiom NonPredicateField(joinable);
-const unique token#t: TypeName;
-const unique forkK: Field real;
-axiom NonPredicateField(forkK);
-const channelK: real;
-const monitorK: real;
-const predicateK: real;"""
-}
-object PercentageStandardPL extends PreludeComponent {
- val text = """
-axiom Permission$FullFraction == 1.0;
-axiom 0.0 < channelK && 1000.0*channelK < 0.01;
-axiom 0.0 < monitorK && 1000.0*monitorK < 0.01;
-axiom 0.0 < predicateK && 1000.0*predicateK < 0.01;
-axiom predicateK == channelK && channelK == monitorK;"""
-}
-object PercentageFunctionPL extends PreludeComponent {
- val text = """
-function Fractions(n: int) returns (real)
-{
- n / 100.0
-}
-axiom (forall x,y: int :: 0.0 <= real(x) && real(x) <= real(y) ==> Fractions(x) <= Fractions(y));
-
-axiom Permission$FullFraction == Fractions(100);
-axiom 0.0 < channelK && 1000.0*channelK < Fractions(1);
-axiom 0.0 < monitorK && 1000.0*monitorK < Fractions(1);
-axiom 0.0 < predicateK && 1000.0*predicateK < Fractions(1);
-axiom predicateK == channelK && channelK == monitorK;"""
-}
-object CreditsAndMuPL extends PreludeComponent {
- def text = {
- val base = """
-var Credits: CreditsType;
-
-function combine(PartialHeapType, PartialHeapType) returns (PartialHeapType);
-function heapFragment<T>(T) returns (PartialHeapType);
-type PartialHeapType;
-const emptyPartialHeap: PartialHeapType;
-
-type ModuleName;
-const CurrentModule: ModuleName;
-type TypeName;
-function dtype(ref) returns (TypeName);
-const CanAssumeFunctionDefs: bool;
-const FunctionContextHeight: int;
-
-type Mu;
-const unique mu: Field Mu;
-axiom NonPredicateField(mu);
-function MuBelow(Mu, Mu) returns (bool); // strict partial order
-axiom (forall m: Mu, n: Mu ::
- { MuBelow(m,n), MuBelow(n,m) }
- !(MuBelow(m,n) && MuBelow(n,m)));
-axiom (forall m: Mu, n: Mu, o: Mu ::
- { MuBelow(m,n), MuBelow(n,o) }
- MuBelow(m,n) && MuBelow(n,o) ==> MuBelow(m,o));
-const $LockBottom: Mu;
-axiom (forall m, n: Mu :: MuBelow(m, n) ==> n != $LockBottom);
-
-const unique held: Field int;
-function Acquire$Heap(int) returns (HeapType);
-function Acquire$Mask(int) returns (MaskType);
-function Acquire$SecMask(int) returns (MaskType);
-function Acquire$Credits(int) returns (CreditsType);
-axiom NonPredicateField(held);
-
-function LastSeen$Heap(Mu, int) returns (HeapType);
-function LastSeen$Mask(Mu, int) returns (MaskType);
-function LastSeen$SecMask(Mu, int) returns (MaskType);
-function LastSeen$Credits(Mu, int) returns (CreditsType);
-
-const unique rdheld: Field bool;
-axiom NonPredicateField(rdheld);
-function wf(h: HeapType, m: MaskType, sm: MaskType) returns (bool);
-
-function IsGoodInhaleState(ih: HeapType, h: HeapType,
- m: MaskType, sm: MaskType) returns (bool)
-{
- (forall<T> o: ref, f: Field T :: { ih[o, f] } CanRead(m, sm, o, f) ==> ih[o, f] == h[o, f]) &&
- (forall o: ref :: { ih[o, held] } (0<ih[o, held]) == (0<h[o, held])) &&
- (forall o: ref :: { ih[o, rdheld] } ih[o, rdheld] == h[o, rdheld]) &&
- (forall o: ref :: { h[o, held] } (0<h[o, held]) ==> ih[o, mu] == h[o, mu]) &&
- (forall o: ref :: { h[o, rdheld] } h[o, rdheld] ==> ih[o, mu] == h[o, mu])
-}
-function IsGoodExhalePredicateState(eh: HeapType, h: HeapType, pm: PMaskType) returns (bool)
-{
- (forall<T> o: ref, f: Field T :: { eh[o, f] } pm[o, f] ==> eh[o, f] == h[o, f])
-}
-function predicateMaskField<T>(f: Field T): Field PMaskType;
-function IsGoodExhaleState(eh: HeapType, h: HeapType,
- m: MaskType, sm: MaskType) returns (bool)
-{
- (forall<T> o: ref, f: Field T :: { eh[o, f] } CanRead(m, sm, o, f) ==> eh[o, f] == h[o, f]) &&
- (forall o: ref :: { eh[o, held] } (0<eh[o, held]) == (0<h[o, held])) &&
- (forall o: ref :: { eh[o, rdheld] } eh[o, rdheld] == h[o, rdheld]) &&
- (forall o: ref :: { h[o, held] } (0<h[o, held]) ==> eh[o, mu] == h[o, mu]) &&
- (forall o: ref :: { h[o, rdheld] } h[o, rdheld] ==> eh[o, mu] == h[o, mu]) &&
- (forall o: ref :: { h[o, forkK] } { eh[o, forkK] } h[o, forkK] == eh[o, forkK]) &&
- (forall o: ref :: { h[o, held] } { eh[o, held] } h[o, held] == eh[o, held]) &&
- (forall o: ref, f: Field int :: { eh[o, f], PredicateField(f) } PredicateField(f) ==> h[o, f] <= eh[o, f]) &&
- (forall o: ref, f: Field int :: { h[o, predicateMaskField(f)], PredicateField(f) } { eh[o, predicateMaskField(f)], PredicateField(f) } { m[o, predicateMaskField(f)], PredicateField(f) } """
- val triggers = (TranslatorPrelude.predicates map (x => "{ #"+x.FullName+"#trigger(o), PredicateField(f) }")).mkString(" ")
- val rest = """ PredicateField(f) && CanRead(m, sm, o, f) ==>
- (forall<T> o2: ref, f2: Field T :: { h[o2, f2] } { eh[o2, f2] } { m[o2, f2] } h[o, predicateMaskField(f)][o2, f2] ==> eh[o2, f2] == h[o2, f2])) &&
- (forall o: ref, f: Field int :: { PredicateField(f), eh[o, predicateMaskField(f)] } PredicateField(f) && CanRead(m, sm, o, f) ==> eh[o, predicateMaskField(f)] == h[o, predicateMaskField(f)])
-}
- """
- base + triggers + rest
- }
-}
-object PermissionFunctionsAndAxiomsPL extends PreludeComponent {
- val text = """
-// ---------------------------------------------------------------
-// -- Permissions ------------------------------------------------
-// ---------------------------------------------------------------
-
-function {:expand false} CanRead<T>(m: MaskType, sm: MaskType, obj: ref, f: Field T) returns (bool)
-{
- 0.0 < m[obj,f][perm$R] || 0.0 < m[obj,f][perm$N]
-}
-function {:expand false} CanReadForSure<T>(m: MaskType, obj: ref, f: Field T) returns (bool)
-{
- 0.0 < m[obj,f][perm$R] || 0.0 < m[obj,f][perm$N]
-}
-function {:expand false} CanWrite<T>(m: MaskType, obj: ref, f: Field T) returns (bool)
-{
- m[obj,f][perm$R] == Permission$FullFraction && m[obj,f][perm$N] == 0.0
-}
-function {:expand true} IsGoodMask(m: MaskType) returns (bool)
-{
- (forall<T> o: ref, f: Field T ::
- 0.0 <= m[o,f][perm$R] &&
- (NonPredicateField(f) ==>
- (m[o,f][perm$R]<=Permission$FullFraction &&
- (0.0 < m[o,f][perm$N] ==> m[o,f][perm$R] < Permission$FullFraction))) &&
- (m[o,f][perm$N] < 0.0 ==> 0.0 < m[o,f][perm$R]))
-}
-
-axiom (forall h: HeapType, m, sm: MaskType, o: ref, q: ref :: {wf(h, m, sm), h[o, mu], h[q, mu]} wf(h, m, sm) && o!=q && (0 < h[o, held] || h[o, rdheld]) && (0 < h[q, held] || h[q, rdheld]) ==> h[o, mu] != h[q, mu]);
-
-function DecPerm<T>(m: MaskType, o: ref, f: Field T, howMuch: real) returns (MaskType);
-
-axiom (forall<T,U> m: MaskType, o: ref, f: Field T, howMuch: real, q: ref, g: Field U :: {DecPerm(m, o, f, howMuch)[q, g][perm$R]}
- DecPerm(m, o, f, howMuch)[q, g][perm$R] == ite(o==q && f ==g, m[q, g][perm$R] - howMuch, m[q, g][perm$R])
-);
-
-function DecEpsilons<T>(m: MaskType, o: ref, f: Field T, howMuch: real) returns (MaskType);
-
-axiom (forall<T,U> m: MaskType, o: ref, f: Field T, howMuch: real, q: ref, g: Field U :: {DecPerm(m, o, f, howMuch)[q, g][perm$N]}
- DecEpsilons(m, o, f, howMuch)[q, g][perm$N] == ite(o==q && f ==g, m[q, g][perm$N] - howMuch, m[q, g][perm$N])
-);
-
-function IncPerm<T>(m: MaskType, o: ref, f: Field T, howMuch: real) returns (MaskType);
-
-axiom (forall<T,U> m: MaskType, o: ref, f: Field T, howMuch: real, q: ref, g: Field U :: {IncPerm(m, o, f, howMuch)[q, g][perm$R]}
- IncPerm(m, o, f, howMuch)[q, g][perm$R] == ite(o==q && f ==g, m[q, g][perm$R] + howMuch, m[q, g][perm$R])
-);
-
-function IncEpsilons<T>(m: MaskType, o: ref, f: Field T, howMuch: real) returns (MaskType);
-
-axiom (forall<T,U> m: MaskType, o: ref, f: Field T, howMuch: real, q: ref, g: Field U :: {IncPerm(m, o, f, howMuch)[q, g][perm$N]}
- IncEpsilons(m, o, f, howMuch)[q, g][perm$N] == ite(o==q && f ==g, m[q, g][perm$N] + howMuch, m[q, g][perm$N])
-);
-
-function Havocing<T,U>(h: HeapType, o: ref, f: Field T, newValue: U) returns (HeapType);
-
-axiom (forall<T,U> h: HeapType, o: ref, f: Field T, newValue: U, q: ref, g: Field U :: {Havocing(h, o, f, newValue)[q, g]}
- Havocing(h, o, f, newValue)[q, g] == ite(o==q && f ==g, newValue, h[q, g])
-);
-
-function Call$Heap(int) returns (HeapType);
-function Call$Mask(int) returns (MaskType);
-function Call$SecMask(int) returns (MaskType);
-function Call$Credits(int) returns (CreditsType);
-function Call$Args(int) returns (ArgSeq);
-type ArgSeq = <T>[int]T;
-
-function EmptyMask(m: MaskType) returns (bool);
-axiom (forall m: MaskType :: {EmptyMask(m)} EmptyMask(m) <==> (forall<T> o: ref, f: Field T :: NonPredicateField(f) ==> m[o, f][perm$R]<=0.0 && m[o, f][perm$N]<=0.0));
-
-const ZeroCredits: CreditsType;
-axiom (forall o: ref :: ZeroCredits[o] == 0);
-function EmptyCredits(c: CreditsType) returns (bool);
-axiom (forall c: CreditsType :: {EmptyCredits(c)} EmptyCredits(c) <==> (forall o: ref :: o != null ==> c[o] == 0));
-
-function NonPredicateField<T>(f: Field T) returns (bool);
-function PredicateField<T>(f: Field T) returns (bool);
-axiom (forall<T> f: Field T :: NonPredicateField(f) ==> ! PredicateField(f));
-axiom (forall<T> f: Field T :: PredicateField(f) ==> ! NonPredicateField(f));
-
-// function for recording enclosure of one predicate instance in another
-function #predicateInside#(x:ref, p: Field (int), v:int, y:ref, q:Field (int), w : int) returns (bool);
-
-// transitivity for #predicateInside#
-axiom (forall x:ref, p: Field (int), v:int, y:ref, q:Field (int), w : int, z:ref, r:Field(int),u:int :: {#predicateInside#(x,p,v,y,q,w), #predicateInside#(y,q,w,z,r,u)} #predicateInside#(x,p,v,y,q,w) && #predicateInside#(y,q,w,z,r,u) ==> #predicateInside#(x,p,v,z,r,u));
-
-// knowledge that two identical instances of the same predicate cannot be inside each other
-axiom (forall x:ref, p: Field (int), v:int, y:ref, w:int :: {#predicateInside#(x,p,v,y,p,w)} #predicateInside#(x,p,v,y,p,w) ==> x!=y);
-
-
-function submask(m1: MaskType, m2: MaskType) returns (bool);
-
-axiom (forall m1: MaskType, m2: MaskType :: {submask(m1, m2)}
- submask(m1, m2) <==> (forall<T> o: ref, f: Field T :: (m1[o, f][perm$R] < m2[o, f][perm$R]) || (m1[o, f][perm$R] == m2[o, f][perm$R] && m1[o, f][perm$N] <= m2[o, f][perm$N]))
-);"""
-}
-object IfThenElsePL extends PreludeComponent {
- val text = """
-// ---------------------------------------------------------------
-// -- If then else -----------------------------------------------
-// ---------------------------------------------------------------
-
-function ite<T>(bool, T, T) returns (T);
-axiom (forall<T> con: bool, a: T, b: T :: {ite(con, a, b)} con ==> ite(con, a, b) == a);
-axiom (forall<T> con: bool, a: T, b: T :: {ite(con, a, b)} ! con ==> ite(con, a, b) == b);"""
-}
-object StringPL extends PreludeComponent {
- val text = """
-// ---------------------------------------------------------------
-// -- Strings ----------------------------------------------------
-// ---------------------------------------------------------------
-
-type string = int;"""
-}
-object AxiomatizationOfSequencesPL extends PreludeComponent {
- val text = """
-// ---------------------------------------------------------------
-// -- Axiomatization of sequences --------------------------------
-// ---------------------------------------------------------------
-
-type Seq T;
-
-function Seq#Length<T>(Seq T) returns (int);
-axiom (forall<T> s: Seq T :: { Seq#Length(s) } 0 <= Seq#Length(s));
-
-function Seq#Empty<T>() returns (Seq T);
-axiom (forall<T> :: Seq#Length(Seq#Empty(): Seq T) == 0);
-axiom (forall<T> s: Seq T :: { Seq#Length(s) } Seq#Length(s) == 0 ==> s == Seq#Empty());
-
-function Seq#Singleton<T>(T) returns (Seq T);
-axiom (forall<T> t: T :: { Seq#Length(Seq#Singleton(t)) } Seq#Length(Seq#Singleton(t)) == 1);
-
-function Seq#Build<T>(s: Seq T, index: int, val: T, newLength: int) returns (Seq T);
-axiom (forall<T> s: Seq T, i: int, v: T, len: int :: { Seq#Length(Seq#Build(s,i,v,len)) }
- 0 <= len ==> Seq#Length(Seq#Build(s,i,v,len)) == len);
-
-function Seq#Append<T>(Seq T, Seq T) returns (Seq T);
-axiom (forall<T> s0: Seq T, s1: Seq T :: { Seq#Length(Seq#Append(s0,s1)) }
- Seq#Length(Seq#Append(s0,s1)) == Seq#Length(s0) + Seq#Length(s1));
-
-function Seq#Index<T>(Seq T, int) returns (T);
-axiom (forall<T> t: T :: { Seq#Index(Seq#Singleton(t), 0) } Seq#Index(Seq#Singleton(t), 0) == t);
-axiom (forall<T> s0: Seq T, s1: Seq T, n: int :: { Seq#Index(Seq#Append(s0,s1), n) }
- (n < Seq#Length(s0) ==> Seq#Index(Seq#Append(s0,s1), n) == Seq#Index(s0, n)) &&
- (Seq#Length(s0) <= n ==> Seq#Index(Seq#Append(s0,s1), n) == Seq#Index(s1, n - Seq#Length(s0))));
-axiom (forall<T> s: Seq T, i: int, v: T, len: int, n: int :: { Seq#Index(Seq#Build(s,i,v,len),n) }
- 0 <= n && n < len ==>
- (i == n ==> Seq#Index(Seq#Build(s,i,v,len),n) == v) &&
- (i != n ==> Seq#Index(Seq#Build(s,i,v,len),n) == Seq#Index(s,n)));
-
-function Seq#Contains<T>(Seq T, T) returns (bool);
-axiom (forall<T> s: Seq T, x: T :: { Seq#Contains(s,x) }
- Seq#Contains(s,x) <==>
- (exists i: int :: { Seq#Index(s,i) } 0 <= i && i < Seq#Length(s) && Seq#Index(s,i) == x));
-axiom (forall x: ref ::
- { Seq#Contains(Seq#Empty(), x) }
- !Seq#Contains(Seq#Empty(), x));
-axiom (forall<T> s0: Seq T, s1: Seq T, x: T ::
- { Seq#Contains(Seq#Append(s0, s1), x) }
- Seq#Contains(Seq#Append(s0, s1), x) <==>
- Seq#Contains(s0, x) || Seq#Contains(s1, x));
-axiom (forall<T> s: Seq T, i: int, v: T, len: int, x: T ::
- { Seq#Contains(Seq#Build(s, i, v, len), x) }
- Seq#Contains(Seq#Build(s, i, v, len), x) <==>
- (0 <= i && i < len && x == v) ||
- (exists j: int :: { Seq#Index(s,j) } 0 <= j && j < Seq#Length(s) && j < len && j!=i && Seq#Index(s,j) == x));
-axiom (forall<T> s: Seq T, n: int, x: T ::
- { Seq#Contains(Seq#Take(s, n), x) }
- Seq#Contains(Seq#Take(s, n), x) <==>
- (exists i: int :: { Seq#Index(s, i) }
- 0 <= i && i < n && i < Seq#Length(s) && Seq#Index(s, i) == x));
-axiom (forall<T> s: Seq T, n: int, x: T ::
- { Seq#Contains(Seq#Drop(s, n), x) }
- Seq#Contains(Seq#Drop(s, n), x) <==>
- (exists i: int :: { Seq#Index(s, i) }
- 0 <= n && n <= i && i < Seq#Length(s) && Seq#Index(s, i) == x));
-
-function Seq#Equal<T>(Seq T, Seq T) returns (bool);
-axiom (forall<T> s0: Seq T, s1: Seq T :: { Seq#Equal(s0,s1) }
- Seq#Equal(s0,s1) <==>
- Seq#Length(s0) == Seq#Length(s1) &&
- (forall j: int :: { Seq#Index(s0,j) } { Seq#Index(s1,j) }
- 0 <= j && j < Seq#Length(s0) ==> Seq#Index(s0,j) == Seq#Index(s1,j)));
-axiom(forall<T> a: Seq T, b: Seq T :: { Seq#Equal(a,b) } // extensionality axiom for sequences
- Seq#Equal(a,b) ==> a == b);
-
-function Seq#SameUntil<T>(Seq T, Seq T, int) returns (bool);
-axiom (forall<T> s0: Seq T, s1: Seq T, n: int :: { Seq#SameUntil(s0,s1,n) }
- Seq#SameUntil(s0,s1,n) <==>
- (forall j: int :: { Seq#Index(s0,j) } { Seq#Index(s1,j) }
- 0 <= j && j < n ==> Seq#Index(s0,j) == Seq#Index(s1,j)));
-
-function Seq#Take<T>(s: Seq T, howMany: int) returns (Seq T);
-axiom (forall<T> s: Seq T, n: int :: { Seq#Length(Seq#Take(s,n)) }
- 0 <= n ==>
- (n <= Seq#Length(s) ==> Seq#Length(Seq#Take(s,n)) == n) &&
- (Seq#Length(s) < n ==> Seq#Length(Seq#Take(s,n)) == Seq#Length(s)));
-axiom (forall<T> s: Seq T, n: int, j: int :: { Seq#Index(Seq#Take(s,n), j) } {:weight 25}
- 0 <= j && j < n && j < Seq#Length(s) ==>
- Seq#Index(Seq#Take(s,n), j) == Seq#Index(s, j));
-
-function Seq#Drop<T>(s: Seq T, howMany: int) returns (Seq T);
-axiom (forall<T> s: Seq T, n: int :: { Seq#Length(Seq#Drop(s,n)) }
- 0 <= n ==>
- (n <= Seq#Length(s) ==> Seq#Length(Seq#Drop(s,n)) == Seq#Length(s) - n) &&
- (Seq#Length(s) < n ==> Seq#Length(Seq#Drop(s,n)) == 0));
-axiom (forall<T> s: Seq T, n: int, j: int :: { Seq#Index(Seq#Drop(s,n), j) } {:weight 25}
- 0 <= n && 0 <= j && j < Seq#Length(s)-n ==>
- Seq#Index(Seq#Drop(s,n), j) == Seq#Index(s, j+n));
-
-axiom (forall<T> s, t: Seq T ::
- { Seq#Append(s, t) }
- Seq#Take(Seq#Append(s, t), Seq#Length(s)) == s &&
- Seq#Drop(Seq#Append(s, t), Seq#Length(s)) == t);
-
-function Seq#Range(min: int, max: int) returns (Seq int);
-
-axiom (forall min: int, max: int :: { Seq#Length(Seq#Range(min, max)) } (min < max ==> Seq#Length(Seq#Range(min, max)) == max-min) && (max <= min ==> Seq#Length(Seq#Range(min, max)) == 0));
-axiom (forall min: int, max: int, j: int :: { Seq#Index(Seq#Range(min, max), j) } 0<=j && j<max-min ==> Seq#Index(Seq#Range(min, max), j) == min + j);
-
-axiom (forall<T> x, y: T ::
- { Seq#Contains(Seq#Singleton(x),y) }
- Seq#Contains(Seq#Singleton(x),y) <==> x==y);"""
-}
diff --git a/Chalice/src/main/scala/PrettyPrinter.scala b/Chalice/src/main/scala/PrettyPrinter.scala
deleted file mode 100644
index a54173df..00000000
--- a/Chalice/src/main/scala/PrettyPrinter.scala
+++ /dev/null
@@ -1,396 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-object PrintProgram {
- def P(prog: List[TopLevelDecl]) =
- for (decl <- prog) decl match {
- case cl: Class =>
- if (cl.IsExternal)
- print("external ")
- println("class " + cl.id + " module " + cl.module + (if (cl.IsRefinement) " refines " + cl.refinesId else "") + " {")
- cl.members foreach Member
- println("}")
- case ch: Channel =>
- println("channel " + ch.id + " where " + Expr(ch.where) + Semi)
- }
- def Semi = ";"
- def Member(m: Member) = m match {
- case MonitorInvariant(e) =>
- print(" invariant "); Expr(e); println(Semi)
- case f@ Field(id, t, ghost) =>
- println(" " + (if (ghost) "ghost " else "") + "var " + id + ": " + t.FullName + Semi)
- case m: Method =>
- print(" method " + m.id)
- print("("); VarList(m.ins); print(")")
- if (m.outs != Nil) {
- print(" returns ("); VarList(m.outs); print(")")
- }
- println
- PrintSpec(m.Spec)
- println(" {")
- for (s <- m.body) {
- Spaces(4); Stmt(s, 4)
- }
- println(" }")
- case Condition(id, optE) =>
- print(" condition " + id)
- optE match {
- case None =>
- case Some(e) => print(" where "); Expr(e)
- }
- println(Semi)
- case Predicate(id, definition) =>
- print(" predicate " + id + " { "); Expr(definition); println(" }")
- case Function(id, ins, out, specs, e) =>
- print(" function " + id + "("); VarList(ins); print("): " + out.FullName);
- println
- PrintSpec(specs)
- e match {
- case Some(e) => print(" { "); Expr(e); println(" }");
- case None =>
- }
- case m: MethodTransform =>
- print(" method " + m.id);
- print("("); VarList(m.ins); print(")")
- if (m.outs != Nil) {
- print(" returns ("); VarList(m.outs); print(")")
- }
- println;
- if (m.refines != null) PrintSpec(m.Spec);
- println(" {");
- if (m.body == null)
- println(" // body transform is not resolved")
- else
- for (s <- m.body) {
- Spaces(4); Stmt(s, 4)
- }
- println(" }")
- case CouplingInvariant(ids, e) =>
- print(" replaces "); Commas(ids); print(" by "); Expr(e); println(Semi);
-
- }
- def PrintSpec(specs: List[Specification]) {
- specs foreach {
- case Precondition(e) => print(" requires "); Expr(e); println(Semi)
- case Postcondition(e) => print(" ensures "); Expr(e); println(Semi)
- case LockChange(ee) => print(" lockchange "); ExprList(ee); println(Semi)
- }
- }
- def Stmt(s: Statement, indent: Int): Unit = s match {
- case a@Assert(e) =>
- print("assert "); Expr(e);
- if (!a.smokeErrorNr.isEmpty)
- println(Semi + " // smoke assertion: " + SmokeTest.smokeWarningMessage(a.smokeErrorNr.get))
- else
- println(Semi)
- case Assume(e) =>
- print("assume "); Expr(e); println(Semi)
- case BlockStmt(ss) =>
- PrintBlockStmt(ss, indent); println
- case RefinementBlock(ss, old) =>
- println("/* begin of refinement block")
- for (s <- old) {
- Spaces(indent + 2); Stmt(s, indent + 2)
- }
- Spaces(indent); println("end of abstract code */")
- for (s <- ss) {
- Spaces(indent); Stmt(s, indent)
- }
- Spaces(indent); println("// end of refinement block")
- case IfStmt(guard, BlockStmt(thn), els) =>
- print("if ("); Expr(guard); print(") ")
- PrintBlockStmt(thn, indent)
- els match {
- case None => println
- case Some(s) => print(" else "); Stmt(s, indent)
- }
- case w @ WhileStmt(guard, _, _, lkch, body) =>
- print("while ("); Expr(guard); println(")")
- for (inv <- w.oldInvs) {
- Spaces(indent+2)
- print("invariant "); Expr(inv); println(Semi)
- }
- for (inv <- w.newInvs) {
- Spaces(indent+2)
- print("invariant "); Expr(inv); print(Semi); println(" // refined");
- }
- for (l <- lkch) {
- Spaces(indent+2)
- print("lockchange "); Expr(l); println(Semi)
- }
- Spaces(indent); Stmt(body, indent)
- case Assign(lhs,rhs) =>
- Expr(lhs); print(" := "); Rhs(rhs); println(Semi)
- case FieldUpdate(lhs,rhs) =>
- Expr(lhs); print(" := "); Rhs(rhs); println(Semi)
- case LocalVar(v,rhs) =>
- print(v + ": " + v.t.FullName)
- rhs match { case None => case Some(rhs) => print(" := "); Rhs(rhs) }
- println(Semi)
- case SpecStmt(lhs, locals, pre, post) =>
- if (locals.size > 0) {
- if (locals(0).isGhost) print("ghost ");
- if (locals(0).isImmutable) print("const ") else print("var ")
- } else
- print("var ");
- VarList(locals);
- var first = (locals.size == 0);
- for (l <- lhs)
- if (! locals.exists(v => v.id == l.id)) {
- if (first) first = false else print(", ");
- print(l.id);
- }
- print(" ["); Expr(pre); print(", "); Expr(post); print("]"); println(Semi);
- case Call(_, outs, obj, id, args) =>
- print("call ")
- outs match {
- case Nil =>
- case x :: xs => Expr(x); xs foreach { x => print(", "); Expr(x) }; print(" := ")
- }
- MemberSelect(obj,id,0,false)
- print("(")
- ExprList(args)
- println(");")
- case Install(obj,lower,upper) =>
- print("reorder ")
- Expr(obj)
- PrintBounds(lower, upper)
- println(Semi)
- case Share(obj,lower,upper) =>
- print("share ")
- Expr(obj)
- PrintBounds(lower, upper)
- println(Semi)
- case Unshare(e) =>
- print("unshare "); Expr(e); println(Semi)
- case Acquire(e) =>
- print("acquire "); Expr(e); println(Semi)
- case Release(e) =>
- print("release "); Expr(e); println(Semi)
- case RdAcquire(e) =>
- print("rd acquire "); Expr(e); println(Semi)
- case RdRelease(e) =>
- print("rd release "); Expr(e); println(Semi)
- case Lock(e, b, rdLock) =>
- if (rdLock) print("rd lock (") else print("lock (")
- Expr(e); print(") ")
- Stmt(b, indent)
- case Downgrade(e) =>
- print("downgrade "); Expr(e); println(Semi)
- case Free(e) =>
- print("free "); Expr(e); println(Semi)
- case Fold(e) =>
- print("fold "); Expr(e); println(Semi)
- case Unfold(e) =>
- print("unfold "); Expr(e); println(Semi)
- case CallAsync(declaresLocal, token, obj, name, args) =>
- print("fork ");
- if (token != null) {
- Expr(token); print(" := ");
- }
- Expr(obj); print("."); print(name); print("("); ExprList(args); print(")");
- case JoinAsync(lhs, token) =>
- print("join ");
- if (lhs != null && !lhs.isEmpty) {
- ExprList(lhs);
- print(" := ");
- }
- Expr(token);
- println(Semi)
- case Wait(obj, id) =>
- print("wait ")
- MemberSelect(obj, id, 0, false)
- println(Semi)
- case Signal(obj, id, all) =>
- print("signal "); if (all) { print(" forall") }
- MemberSelect(obj, id, 0, false)
- println(Semi)
- case Send(ch, args) =>
- print("send "); Expr(ch); print("("); ExprList(args); print(")"); println(Semi)
- case Receive(_, ch, outs) =>
- print("receive ")
- outs match {
- case Nil =>
- case x :: xs => Expr(x); xs foreach { x => print(", "); Expr(x) }; print(" := ")
- }
- Expr(ch); println(Semi)
- }
- def PrintBounds(lower: List[Expression], upper: List[Expression]) = {
- if (lower == Nil && upper == Nil) {
- } else if (lower == Nil) {
- print(" below "); ExprList(upper)
- } else if (upper == Nil) {
- print(" above "); ExprList(lower)
- } else {
- print(" between "); ExprList(lower); print(" and "); ExprList(upper)
- }
- }
- def PrintBlockStmt(ss: List[Statement], indent: Int) = {
- println("{")
- for (s <- ss) {
- Spaces(indent+2); Stmt(s, indent+2)
- }
- Spaces(indent); print("}")
- }
- def VarList(vv: List[Variable]) = Commas(vv map {v => v.id + ": " + v.t.FullName})
- def Commas(ss: List[String]) = ss match {
- case Nil =>
- case s :: rest =>
- print(s); rest foreach {s => print(", " + s)}
- }
- def ExprList(ee: List[Expression]) = ee match {
- case Nil =>
- case e :: rest =>
- Expr(e)
- rest foreach { e => print(", "); Expr(e) }
- }
- def Rhs(e: RValue) = e match {
- case NewRhs(id, initialization, lower, upper) =>
- print("new " + id);
- if(0 < initialization.length) {
- print(" {"); print(initialization(0).id); print(":="); Expr(initialization(0).e); initialization.foreach({ init => print(", "); print(init.id); print(":="); Expr(init.e); }); print("}");
- }
- PrintBounds(lower, upper)
- case e: Expression => Expr(e)
- }
- def Expr(e: Expression): Unit = Expr(e, 0, false)
- def Expr(e: Expression, contextBindingPower: Int, fragileContext: Boolean): Unit = e match {
- case BoogieExpr(_) => throw new InternalErrorException("unexpected in pretty printer")
- case IntLiteral(n) => print(n)
- case BoolLiteral(b) => print(b)
- case NullLiteral() => print("null")
- case StringLiteral(s) => print("\"" + s + "\"")
- case MaxLockLiteral() => print("waitlevel")
- case LockBottomLiteral() => print("lockbottom")
- case _:ThisExpr => print("this")
- case _:Result => print("result")
- case VariableExpr(id) => print(id)
- case MemberAccess(e,f) => MemberSelect(e,f,contextBindingPower,fragileContext)
- case Full => print("100");
- case Epsilon => print("rd");
- case MethodEpsilon => print("rd");
- case Frac(e) => Expr(e);
- case Star => print("rd(*)")
- case ChannelEpsilon(None) | PredicateEpsilon(None) | MonitorEpsilon(None) => print("rd");
- case ChannelEpsilon(Some(e)) => print("rd("); Expr(e); print(")");
- case PredicateEpsilon(Some(e)) => print("rd("); Expr(e); print(")");
- case MonitorEpsilon(Some(e)) => print("rd("); Expr(e); print(")");
- case ForkEpsilon(tk) => print("rd("); Expr(tk); print(")");
- case PermPlus(e0, e1) => BinExpr(e0, e1, "+", 0x50, false, false, contextBindingPower, fragileContext)
- case PermMinus(e0, e1) => BinExpr(e0, e1, "-", 0x50, false, true, contextBindingPower, fragileContext)
- case PermTimes(e0, e1) => BinExpr(e0, e1, "*", 0x60, false, false, contextBindingPower, fragileContext)
- case IntPermTimes(n, p) => BinExpr(n, p, "*", 0x60, false, false, contextBindingPower, fragileContext)
- case Epsilons(e) => print("rd("); Expr(e); print(")");
- case Access(e, p) => print("acc("); Expr(e); print(", "); Expr(p); print(")")
- case AccessAll(obj, p) => print("acc("); Expr(obj); print(".*"); print(", "); Expr(p); print(")")
- case AccessSeq(s, f, p) => print("acc("); Expr(s); print(", "); print("[*].");
- f match { case None => print("*"); case Some(x) => print(x)}
- Expr(p); print(")")
- case Credit(e, n) =>
- print("credit("); Expr(e)
- n match { case None => case Some(n) => print(", "); Expr(n) }
- print(")")
- case Holds(e) =>
- print("holds("); Expr(e); print(")")
- case RdHolds(e) =>
- print("rd holds("); Expr(e); print(")")
- case Assigned(id) => print("assigned(" + id + ")")
- case Old(e) =>
- print("old("); Expr(e); print(")")
- case IfThenElse(con, then, els) =>
- print("("); Expr(con); print(" ? "); Expr(then); print(" : "); Expr(els); print(")");
- case Not(e) => print("!"); Expr(e, 0x80, false)
- case FunctionApplication(obj, id, ins) =>
- Expr(obj); print("."); print(id); print("("); ExprList(ins); print(")");
- case Unfolding(pred, e) =>
- print("unfolding "); Expr(pred); print(" in "); Expr(e);
- case e:Iff => BinExpr(e, e.OpName, 0x10, false, false, contextBindingPower, fragileContext)
- case e:Implies => BinExpr(e, e.OpName, 0x20, true, false, contextBindingPower, fragileContext)
- case e:And => BinExpr(e, e.OpName, 0x30, false, false, contextBindingPower, fragileContext)
- case e:Or => BinExpr(e, e.OpName, 0x31, false, false, contextBindingPower, fragileContext)
- case e:Eq => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case e:Neq => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case e:Less => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case e:AtMost => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case e:AtLeast => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case e:Greater => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case e:LockBelow => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case e:Plus => BinExpr(e, e.OpName, 0x50, false, false, contextBindingPower, fragileContext)
- case e:Minus => BinExpr(e, e.OpName, 0x50, false, true, contextBindingPower, fragileContext)
- case e:Times => BinExpr(e, e.OpName, 0x60, false, false, contextBindingPower, fragileContext)
- case e:Div => BinExpr(e, e.OpName, 0x60, false, true, contextBindingPower, fragileContext)
- case e:Mod => BinExpr(e, e.OpName, 0x60, false, true, contextBindingPower, fragileContext)
- case q:Quantification =>
- print("(" + (q.Q match {case Forall => "forall"; case Exists => "exists"}) + " ");
- q.Is match {
- case Nil =>
- case i :: rest => print(i); rest foreach { v => print(", " + v) }
- }
- q match {
- case q: SeqQuantification => print(" in "); Expr(q.seq);
- case q: TypeQuantification => print(": "); print(q.t.typ.FullName);
- }
- print(" :: "); Expr(q.E); print(")");
- case EmptySeq(t) =>
- print("nil<"); print(t.FullName); print(">");
- case ExplicitSeq(es) =>
- print("["); ExprList(es); print("]");
- case Range(min, max) =>
- print("["); Expr(min); print(":"); Expr(max); print("]");
- case Length(e)=>
- print("|"); Expr(e); print("|");
- case At(s, n) =>
- Expr(s); print("["); Expr(n); print("]");
- case e:Append =>
- BinExpr(e, e.OpName, 0x45, true, true, contextBindingPower, fragileContext)
- case Drop(s, n) =>
- Expr(s); print("["); Expr(n); print(" ..]");
- case Take(s, n) =>
- Expr(s); print("[.. "); Expr(n); print("]");
- case e:Contains => BinExpr(e, e.OpName, 0x40, true, true, contextBindingPower, fragileContext)
- case Eval(h, e) =>
- print("eval("); (h match
- {
- case AcquireState(obj) => Expr(obj); print(".acquire");
- case ReleaseState(obj) => Expr(obj); print(".release");
- case CallState(token, obj, id, args) => Expr(token); print(".fork"); print(" "); Expr(obj); print("." + id + "("); ExprList(args); print(")");
- }); print(", "); Expr(e); print(")");
- }
- def MemberSelect(e: Expression, f: String, contextBindingPower: Int, fragileContext: Boolean) = e match {
- case e:ImplicitThisExpr => print(f)
- case _ =>
- ParenExpr(0x90, contextBindingPower, fragileContext, { Expr(e,0x90,false); print("." + f) })
- }
- def BinExpr(bin: BinaryExpr, op: String, power: Int, fragileLeft: Boolean, fragileRight: Boolean,
- context: Int, fragileContext: Boolean) = {
- ParenExpr(power, context, fragileContext,
- { Expr(bin.E0, power, fragileLeft); print(" " + op + " "); Expr(bin.E1, power, fragileRight) })
- }
- def BinExpr(left: Expression, right: Expression, op: String, power: Int, fragileLeft: Boolean, fragileRight: Boolean,
- context: Int, fragileContext: Boolean) = {
- ParenExpr(power, context, fragileContext,
- { Expr(left, power, fragileLeft); print(" " + op + " "); Expr(right, power, fragileRight) })
- }
- def ParenExpr(power: Int, context: Int, fragileContext: Boolean, pe: =>Unit) {
- val ap = power & 0xF0;
- val cp = context & 0xF0;
- val parensNeeded = ap < cp || (ap == cp && (power != context || fragileContext));
- if (parensNeeded) { print("(") }
- pe
- if (parensNeeded) { print(")") }
- }
- def Spaces(N: Int) = {
- val abunchaSpaces = " "
- var n = N
- while (abunchaSpaces.length <= n) {
- print(abunchaSpaces)
- n = n - abunchaSpaces.length
- }
- if (0 < n) {
- print(abunchaSpaces.substring(0, n))
- }
- }
-}
diff --git a/Chalice/src/main/scala/Resolver.scala b/Chalice/src/main/scala/Resolver.scala
deleted file mode 100644
index 5dc24662..00000000
--- a/Chalice/src/main/scala/Resolver.scala
+++ /dev/null
@@ -1,1494 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-import scala.util.parsing.input.Position
-import scala.util.parsing.input.Positional
-import collection.mutable.ListBuffer
-
-object Resolver {
- sealed abstract class ResolverOutcome
- case class Success() extends ResolverOutcome
- case class Errors(ss: List[(Position,String)]) extends ResolverOutcome
-
- val runMethod = "run";
-
- sealed class ProgramContext(val decls: Map[String,TopLevelDecl], val currentClass: Class,
- val currentMember: Member, val errors: ListBuffer[(Position,String)]) {
- final def AddVariable(v: Variable): ProgramContext = new LProgramContext(v, this);
- final def Error(pos: Position, msg: String) {errors += ((pos, msg))}
- final def SetClass(cl: Class): ProgramContext = new MProgramContext(cl, null, false, this)
- final def SetMember(m: Member): ProgramContext = {
- val static = m match {
- case f: Function => f.isStatic
- case _ => false
- }
- var ctx:ProgramContext = new MProgramContext(currentClass, m, static, this)
- m match {
- case m: Method =>
- assert(currentClass == m.Parent)
- for (v <- m.Ins ++ m.Outs) ctx = ctx.AddVariable(v)
- case f: Function =>
- assert(currentClass == f.Parent)
- for (v <- f.ins) ctx = ctx.AddVariable(v)
- case mt: MethodTransform =>
- assert(currentClass == mt.Parent)
- for (v <- mt.Ins ++ mt.Outs) ctx = ctx.AddVariable(v)
- case _ =>
- }
- ctx
- }
- final def AsNonStatic(): ProgramContext = new NSProgramContext(this)
-
- def LookupVariable(id: String): Option[Variable] = None
- def IsVariablePresent(vr: Variable): Boolean = false
- def IsStatic: Boolean = false
-
- private class LProgramContext(v: Variable, parent: ProgramContext) extends ProgramContext(parent.decls, parent.currentClass, parent.currentMember, errors) {
- assert (v!=null)
- override def LookupVariable(id: String): Option[Variable] =
- if (id == v.id) Some(v) else parent.LookupVariable(id)
- override def IsVariablePresent(vr: Variable): Boolean =
- if (vr == v) true else parent.IsVariablePresent(vr)
- override def IsStatic = parent.IsStatic
- }
- private class MProgramContext(cl: Class, m: Member, static: Boolean, parent: ProgramContext) extends ProgramContext(parent.decls, cl, m, errors) {
- override def LookupVariable(id: String) = parent.LookupVariable(id)
- override def IsVariablePresent(vr: Variable) = parent.IsVariablePresent(vr)
- override def IsStatic: Boolean =
- if (static) true else parent.IsStatic
- }
- private class NSProgramContext(parent: ProgramContext) extends ProgramContext(parent.decls, parent.currentClass, parent.currentMember, errors) {
- override def LookupVariable(id: String) = parent.LookupVariable(id)
- override def IsVariablePresent(vr: Variable) = parent.IsVariablePresent(vr)
- override def IsStatic = false
- }
- }
-
- def Resolve(prog: List[TopLevelDecl]): ResolverOutcome = {
-
- // check for deprecates and/or unsupported constructs
- var refinements = false
- prog map (_ match {
- case c: Class => if (c.IsRefinement) refinements = true
- case _ => }
- )
- if (refinements) throw new NotSupportedException("stepwise refinements are currently not supported")
-
- // register the channels as well as the classes and their members
- var decls = Map[String,TopLevelDecl]()
- for (decl <- BoolClass :: IntClass :: RootClass :: NullClass :: StringClass :: MuClass :: prog) {
- if (decls contains decl.id) {
- return Errors(List((decl.pos, "duplicate class/channel name: " + decl.id)))
- } else {
- decl match {
- case cl: Class =>
- val ids = scala.collection.mutable.Set.empty[String]
- for (m <- cl.members) m match {
- case _:MonitorInvariant =>
- case _:CouplingInvariant =>
- case m: NamedMember =>
- m.Parent = cl
- if (ids contains m.Id) {
- return Errors(List((m.pos, "duplicate member name " + m.Id + " in class " + cl.id)))
- } else {
- ids += m.Id
- }
- }
- case ch: Channel =>
- }
- decls = decls + (decl.id -> decl)
- }
- }
-
- // resolve refinements
- val refinesRel = new DiGraph[Class];
- for (decl <- prog) decl match {
- case cl: Class if cl.IsRefinement =>
- if (! (decls contains cl.refinesId)) {
- return Errors(List((cl.pos, "refined class " + cl.refinesId + " does not exist")))
- } else if (cl.refinesId == cl.id) {
- return Errors(List((cl.pos, "class cannot refine itself")))
- } else decls(cl.refinesId) match {
- case abs: Class =>
- cl.refines = abs;
- refinesRel.addNode(cl);
- refinesRel.addNode(cl.refines);
- refinesRel.addEdge(cl, cl.refines);
- case _ =>
- return Errors(List((cl.pos, "refined declaration " + cl.refinesId + " is not a class")))
- }
- case _ =>
- }
- val (dag, refinesSCC) = refinesRel.computeSCC;
- refinesSCC.values foreach {l =>
- if (l.size > 1) {
- val msg = new StringBuilder("a refinement cycle detected ")
- return Errors(List((l(0).pos, l.map(cl => cl.id).addString(msg, "->").toString)))
- }
- }
-
- // resolve refinement members: set-up refinement between members and check for duplicates
- for (decl <- prog) decl match {
- case cl: Class =>
- if (! cl.IsRefinement) {
- // check has no refinement members
- if (cl.members.exists{
- case _: CouplingInvariant => true
- case _: MethodTransform => true
- case _ => false})
- return Errors(List((cl.pos, "non-refinement class cannot have refinement members")))
- } else for (member <- cl.members) member match {
- case r: MethodTransform =>
- r.refines = cl.refines.LookupMember(r.Id) match {
- case Some(m: Method) => m;
- case Some(mt: MethodTransform) => mt
- case None => return Errors(List((r.pos, "abstract class has no method with name " + r.Id)))
- case _ => return Errors(List((r.pos, "method transform can only refine a method or a method transform")))
- }
- case m: NamedMember =>
- cl.refines.LookupMember(m.Id) match {
- case Some(x) => return Errors(List((m.pos, "member needs to be a refinement since abstract class has a member with the same name: " + x.pos)))
- case None =>
- }
- case _ =>
- }
- case _ =>
- }
-
- // collect errors
- val baseContext = new ProgramContext(decls, null, null, new ListBuffer[(Position,String)])
-
- // resolve types of members
- for (decl <- prog) decl match {
- case ch: Channel =>
- for (v <- ch.parameters) {
- ResolveType(v.t, baseContext)
- }
- case cl: Class =>
- for (m <- cl.members) m match {
- case _: MonitorInvariant =>
- case _: CouplingInvariant =>
- case Field(_, t, _) =>
- ResolveType(t, baseContext)
- case Method(id, ins, outs, _, _) =>
- val ids = scala.collection.mutable.Set.empty[String]
- for (v <- ins ++ outs) {
- ResolveType(v.t, baseContext)
- if (ids contains v.Id) {
- return Errors(List((m.pos, "duplicate parameter " + v.Id + " of method " + id + " in class " + cl.id)))
- } else {
- ids += v.Id
- }
- }
- case _: Condition =>
- case _: Predicate =>
- case Function(id, ins, out, specs, _) =>
- val ids = scala.collection.mutable.Set.empty[String]
- for (v <- ins) {
- ResolveType(v.t, baseContext)
- if (ids contains v.Id) {
- return Errors(List((m.pos, "duplicate parameter " + v.Id + " of function " + id + " in class " + cl.id)))
- } else {
- ids += v.Id
- }
- }
- ResolveType(out, baseContext)
- case mt: MethodTransform =>
- val ids = scala.collection.mutable.Set.empty[String]
- for (v <- mt.ins ++ mt.outs) {
- ResolveType(v.t, baseContext)
- if (ids contains v.Id) {
- return Errors(List((m.pos, "duplicate parameter " + v.Id + " of method transform " + mt.Id + " in class " + cl.id)))
- } else {
- ids += v.Id
- }
- }
- }
- }
-
- // now, resolve and typecheck all
- // * Field types and Method formal-parameter types
- // * Assign, FieldUpdate, and Call statements
- // * VariableExpr and FieldSelect expressions
- // * Call graph for functions
- val calls = new DiGraph[Function];
- for (decl <- prog) decl match {
- case ch: Channel =>
- val context = baseContext.SetClass(ChannelClass(ch))
- var ctx = context
- for (v <- ch.parameters) {
- ctx = ctx.AddVariable(v)
- }
- ResolveExpr(ch.where, ctx, false, true)(false)
- case cl: Class =>
- for (m <- cl.members) {
- val context = baseContext.SetClass(cl).SetMember(m);
- m match {
- case MonitorInvariant(e) =>
- ResolveExpr(e, context, true, true)(true)
- if (!e.typ.IsBool) context.Error(m.pos, "monitor invariant requires a boolean expression (found " + e.typ.FullName + ")")
- case _:Field => // nothing more to do
- case m@Method(id, ins, outs, spec, body) =>
- spec foreach {
- case Precondition(e) => ResolveExpr(e, context, false, true)(false)
- case Postcondition(e) => ResolveExpr(e, context, true, true)(false)
- case lc@LockChange(ee) =>
- if (m.id == runMethod) context.Error(lc.pos, "lockchange not allowed on method run")
- ee foreach (e => ResolveExpr(e, context, true, false)(false))
- }
- ResolveStmt(BlockStmt(body), context)
- case Condition(id, None) =>
- case c@Condition(id, Some(e)) =>
- ResolveExpr(e, context, false, true)(false)
- if (!e.typ.IsBool) context.Error(c.pos, "where clause requires a boolean expression (found " + e.typ.FullName + ")")
- case p@Predicate(id, e) =>
- var ctx = context;
- if (ContainsWaitlevel(e)) context.Error(e.pos, "predicate body is not allowed to mention 'waitlevel'")
- ResolveExpr(e, ctx, false, true)(true);
- if(!e.typ.IsBool) context.Error(e.pos, "predicate requires a boolean expression (found " + e.typ.FullName + ")")
- case f@Function(id, ins, out, spec, definition) =>
- def hasCredit(e: Expression) = {
- var b = false
- e transform {
- case _:Credit => b = true; None
- case _ => None
- }
- b
- }
- def hasAccessibilityPredicate(e: Expression) = {
- var b = false
- e visitOpt {
- case _: PermissionExpr => b = true; false
- case ma: MemberAccess => if (ma.isPredicate) { b = true; false } else { true }
- case Unfolding(pred, e) => false
- case _ => true
- }
- b
- }
- def hasUnfoldingExpression(e: Expression) = {
- var b = false
- e visit {
- case Unfolding(pred, e) => b = true
- case _ =>
- }
- b
- }
- spec foreach {
- case p@Precondition(e) =>
- ResolveExpr(e, context, false, true)(false)
- if (hasCredit(e)) context.Error(p.pos, "the specification of functions cannot contain credit expressions")
- case p@Postcondition(e) =>
- ResolveExpr(e, context, false, true)(false)
- if (hasCredit(e)) context.Error(p.pos, "the specification of functions cannot contain credit expressions")
- if (hasAccessibilityPredicate(e)) context.Error(p.pos, "the postcondition of functions cannot contain accessibility predicates (permissions are returned automatically)")
- // The following check is necessary, because the postcondition axiom has the limited function as a trigger. If we were to allow unfolding expressions, then this might introduce a matching loop. Since we don't know of any cases where one would use an unfolding expression in the postcondition, we forbid it here.
- if (hasUnfoldingExpression(e)) context.Error(p.pos, "the postcondition of functions cannot contain unfolding expressions at the moment")
- case lc : LockChange => context.Error(lc.pos, "lockchange not allowed on function")
- }
-
- definition match {
- case Some(e) =>
- ResolveExpr(e, context, false, false)(false)
- if(! canAssign(out.typ, e.typ)) context.Error(e.pos, "function body does not match declared type (expected: " + out.FullName + ", found: " + e.typ.FullName + ")")
- // resolve function calls
- calls addNode f;
- e visit {
- case app : FunctionApplication if app.f != null /* may not be resolved */ =>
- calls addNode app.f;
- calls.addEdge(f, app.f);
- if (app.f == f) f.isRecursive = true; // self-recursion
- case _ =>
- }
- case None =>
- }
- case mt: MethodTransform => // need to resolve them in reverse refinement order
- case ci: CouplingInvariant => ResolveCouplingInvariant(ci, cl, baseContext)
- }
- }
- }
-
- // fill in SCC and height for recursive functions
- val (callGraphCondensation, h) = calls.computeSCC;
- val callGraphTopoSort = callGraphCondensation.computeTopologicalSort.reverse
- h.keys foreach {f:Function =>
- f.SCC = h(f);
- f.height = callGraphTopoSort.indexOf(h(f))
- assert(f.height >= 0)
- assert(f.SCC contains f);
- if (h(f).size > 1)
- f.isRecursive = true;
- }
-
- // resolve refinement members (starting from abstract programs): assign types to expressions
- for (List(cl) <- dag.computeTopologicalSort.reverse) {
- for (m <- cl.members) m match {
- case mt: MethodTransform => ResolveTransform(mt, baseContext)
- case _ =>
- }
- }
-
- val errors = baseContext.errors.toList
- if (errors.length == 0) {
- Success()
- } else {
- Errors(errors)
- }
- }
-
- def ResolveType(t: Type, context: ProgramContext): Unit = {
- for(p <- t.params){
- ResolveType(p, context);
- }
- if(t.isInstanceOf[TokenType]){
- val tt = t.asInstanceOf[TokenType];
- ResolveType(tt.C, context);
- if(! tt.C.typ.IsNormalClass) context.Error(t.pos, "Invalid token type. " + tt.C.FullName + " is not a user-defined class.");
- tt.C.typ.LookupMember(tt.m) match {
- case Some(m: Method) => val tc = TokenClass(tt.C, tt.m); tc.method = m; tt.typ = tc;
- case _ => context.Error(t.pos, "Invalid token type. " + tt.C.FullName + " does not declare a method " + tt.m + ".");
- }
- return;
- }
- if (context.decls contains t.FullName) {
- context.decls(t.FullName) match {
- case cl: Class => t.typ = cl
- case ch: Channel => t.typ = ChannelClass(ch)
- case _ =>
- context.Error(t.pos, "Invalid class: " + t.FullName + " does not denote a class")
- t.typ = IntClass
- }
- } else {
- if(t.id.equals("seq") && t.params.length == 1) {
- t.typ = new SeqClass(t.params(0).typ);
- } else {
- context.Error(t.pos, "undeclared type " + t.FullName)
- t.typ = IntClass
- }
- }
- }
-
- def ResolveStmt(s: Statement, context: ProgramContext):Unit = s match {
- case Assert(e) =>
- ResolveExpr(e, context, true, true)(false)
- if (!e.typ.IsBool) context.Error(e.pos, "assert statement requires a boolean expression (found " + e.typ.FullName + ")")
- case Assume(e) =>
- ResolveExpr(e, context, true, true)(false)
- if (!e.typ.IsBool) context.Error(e.pos, "assume statement requires a boolean expression (found " + e.typ.FullName + ")")
- case RefinementBlock(ss, _) => throw new InternalErrorException("unexpected statement")
- case BlockStmt(ss) =>
- var ctx = context
- for (s <- ss) s match {
- case l @ LocalVar(v, rhs) =>
- if (ctx.LookupVariable(v.id).isDefined) {
- context.Error(l.pos, "local variable name "+v.id+" collides with parameter or other local variable")
- }
- ResolveType(v.t, ctx)
- val oldCtx = ctx
- ctx = ctx.AddVariable(v)
- rhs match {
- case None =>
- case Some(rhs) =>
- val lhs = VariableExpr(v.id)
- lhs.pos = l.pos;
- ResolveExpr(lhs, ctx, false, false)(false)
- ResolveAssign(lhs, rhs, oldCtx)
- }
- case c: CallAsync =>
- ResolveStmt(c, ctx)
- if (c.local != null) {
- ctx = ctx.AddVariable(c.local)
- }
- case c: Call =>
- ResolveStmt(c, ctx)
- for (v <- c.locals) { ctx = ctx.AddVariable(v) }
- case r: Receive =>
- ResolveStmt(r, ctx)
- for (v <- r.locals) { ctx = ctx.AddVariable(v) }
- case s: SpecStmt =>
- for (v <- s.locals) { ResolveType(v.t, ctx); ctx = ctx.AddVariable(v) }
- for (v <- s.lhs) {
- ResolveExpr(v, ctx, true, true)(false)
- if (v.v != null && !s.locals.contains(v.v) && v.v.isImmutable)
- context.Error(s.pos, "Immutable variable cannot be updated by a spec statement: " + v.id);
- }
- ResolveExpr(s.pre, ctx, false, true)(false)
- ResolveExpr(s.post, ctx, true, true)(false)
- case s =>
- ResolveStmt(s, ctx)
- }
- case IfStmt(guard, thn, els) =>
- ResolveExpr(guard, context, false, false)(false)
- if (!guard.typ.IsBool) context.Error(guard.pos, "if statement requires a boolean guard (found " + guard.typ.FullName + ")")
- CheckNoGhost(guard, context)
- ResolveStmt(thn, context)
- els match { case None => case Some(s) => ResolveStmt(s, context) }
- case w@ WhileStmt(guard, invs, ref, lkch, body) =>
- if (ref.size > 0) throw new InternalErrorException("unexpected statement")
- ResolveExpr(guard, context, false, false)(false)
- if (!guard.typ.IsBool) context.Error(guard.pos, "while statement requires a boolean guard (found " + guard.typ.FullName + ")")
- CheckNoGhost(guard, context)
- for (inv <- invs) {
- ResolveExpr(inv, context, true, true)(false)
- if (!inv.typ.IsBool) context.Error(inv.pos, "loop invariant must be boolean (found " + inv.typ.FullName + ")")
- }
- for (l <- lkch) {
- ResolveExpr(l, context, true, false)(false)
- if (!l.typ.IsRef) context.Error(l.pos, "lockchange expression must be reference (found " + l.typ.FullName + ")")
- }
- ResolveStmt(body, context)
- w.LoopTargets = body.Targets.filter(context.IsVariablePresent).toList
- case Assign(lhs, rhs) =>
- ResolveExpr(lhs, context, false, false)(false)
- ResolveAssign(lhs, rhs, context)
- if (lhs.v != null && lhs.v.isImmutable) {
- if (lhs.v.isGhost)
- CheckNoGhost(rhs, context)
- else
- context.Error(lhs.pos, "cannot assign to immutable variable " + lhs.v.id)
- }
- case fu@FieldUpdate(lhs, rhs) =>
- ResolveExpr(lhs, context, false, false)(false)
- if (! lhs.isPredicate && lhs.f != null && !lhs.f.isGhost) CheckNoGhost(lhs.e, context)
- if (! lhs.isPredicate && lhs.f.isInstanceOf[SpecialField]) context.Error(lhs.pos, "cannot assign directly to special field: " + lhs.id)
- ResolveExpr(rhs, context, false, false)(false)
- if (! lhs.isPredicate && !canAssign(lhs.typ, rhs.typ)) context.Error(fu.pos, "type mismatch in assignment, lhs=" + lhs.typ.FullName + " rhs=" + rhs.typ.FullName)
- if (! lhs.isPredicate && lhs.f != null && !lhs.f.isGhost) CheckNoGhost(rhs, context)
- case _:LocalVar => throw new InternalErrorException("unexpected LocalVar; should have been handled in BlockStmt above")
- case _:SpecStmt => throw new InternalErrorException("should have been handled before")
- case c @ Call(declaresLocal, lhs, obj, id, args) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- args foreach { a => ResolveExpr(a, context, false, false)(false); CheckNoGhost(a, context) }
- // lookup method
- var typ: Class = IntClass
- c.m = obj.typ.LookupMember(id) match {
- case None =>
- context.Error(c.pos, "call of undeclared member " + id + " in class " + obj.typ.FullName)
- null
- case Some(m: Method) => m
- case Some(mt: MethodTransform) => mt
- case _ =>
- context.Error(c.pos, "call expression does not denote a method: " + obj.typ.FullName + "." + id)
- null
- }
- if (c.m != null) {
- if (args.size != c.m.Ins.size)
- context.Error(c.pos, "wrong number of actual in-parameters in call to " + obj.typ.FullName + "." + id +
- " (" + args.size + " instead of " + c.m.Ins.size + ")")
- else {
- for((actual, formal) <- args zip c.m.Ins){
- if(! canAssign(formal.t.typ, actual.typ))
- context.Error(actual.pos, "the type of the actual argument is not assignable to the formal parameter (expected: " + formal.t.FullName + ", found: " + actual.typ.FullName + ")")
- }
- }
- if (lhs.size != c.m.Outs.size)
- context.Error(c.pos, "wrong number of actual out-parameters in call to " + obj.typ.FullName + "." + id +
- " (" + lhs.size + " instead of " + c.m.Outs.size + ")")
- else
- c.locals = ResolveLHS(declaresLocal, lhs, c.m.Outs, context)
- }
- case Install(obj, lowerBounds, upperBounds) =>
- ResolveExpr(obj, context, false, false)(false)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in reorder statement must be of a reference type (found " + obj.typ.FullName + ")")
- if (obj.typ.IsChannel) context.Error(obj.pos, "object in reorder statement must not be a channel (found " + obj.typ.FullName + ")")
- ResolveBounds(lowerBounds, upperBounds, context, "install")
- case Share(obj, lowerBounds, upperBounds) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in share statement must be of a reference type (found " + obj.typ.FullName + ")")
- if (obj.typ.IsChannel) context.Error(obj.pos, "object in share statement must not be a channel (found " + obj.typ.FullName + ")")
- ResolveBounds(lowerBounds, upperBounds, context, "share")
- case Unshare(obj) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in unshare statement must be of a reference type (found " + obj.typ.FullName + ")")
- if (obj.typ.IsChannel) context.Error(obj.pos, "object in unshare statement must not be a channel (found " + obj.typ.FullName + ")")
- case Acquire(obj) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in acquire statement must be of a reference type (found " + obj.typ.FullName + ")")
- case Release(obj) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in release statement must be of a reference type (found " + obj.typ.FullName + ")")
- case RdAcquire(obj) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in rd acquire statement must be of a reference type (found " + obj.typ.FullName + ")")
- case RdRelease(obj) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in rd release statement must be of a reference type (found " + obj.typ.FullName + ")")
- case Lock(obj, b, rdLock) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) {
- val sname = if (rdLock) "rd lock" else "lock";
- context.Error(obj.pos, "object in " + sname + " statement must be of a reference type (found " + obj.typ.FullName + ")")
-
- }
- ResolveStmt(b, context)
- case Downgrade(obj) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in downgrade statement must be of a reference type (found " + obj.typ.FullName + ")")
- case Free(obj) =>
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- if (!obj.typ.IsRef) context.Error(obj.pos, "object in free statement must be of a reference type (found " + obj.typ.FullName + ")")
- case fld@Fold(e) =>
- ResolveExpr(e, context, false, true)(false);
- CheckNoGhost(e, context);
- if(!e.ma.isPredicate) context.Error(fld.pos, "Fold can only be applied to predicates.")
- case ufld@Unfold(e) =>
- ResolveExpr(e, context, false, true)(false);
- CheckNoGhost(e, context);
- if(!e.ma.isPredicate) context.Error(ufld.pos, "Unfold can only be applied to predicates.")
- case c@CallAsync(declaresLocal, token, obj, id, args) =>
- // resolve receiver
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- // resolve arguments
- args foreach { a => ResolveExpr(a, context, false, false)(false); CheckNoGhost(a, context) }
- // lookup method
- var typ: Class = IntClass
- obj.typ.LookupMember(id) match {
- case None =>
- context.Error(c.pos, "call of undeclared member " + id + " in class " + obj.typ.FullName)
- case Some(m: Method) =>
- c.m = m
- if (args.length != m.ins.length)
- context.Error(c.pos, "wrong number of actual in-parameters in call to " + obj.typ.FullName + "." + id +
- " (" + args.length + " instead of " + m.ins.length + ")")
- else {
- for((actual, formal) <- args zip m.ins){
- if(! canAssign(formal.t.typ, actual.typ))
- context.Error(actual.pos, "the type of the actual argument is not assignable to the formal parameter (expected: " + formal.t.FullName + ", found: " + actual.typ.FullName + ")")
- }
- }
- case _ => context.Error(c.pos, "call expression does not denote a method: " + obj.typ.FullName + "." + id)
- }
- // resolve the token
- if (declaresLocal) {
- c.local = new Variable(token.id, TokenType(new Type(obj.typ), id))
- ResolveType(c.local.t, context)
- token.Resolve(c.local)
- } else if (token != null) {
- ResolveExpr(token, context, false, false)(false)
- if(! canAssign(token.typ, TokenClass(new Type(obj.typ), id)))
- context.Error(token.pos, "wrong token type")
- }
- case jn@JoinAsync(lhs, token) =>
- // resolve the assignees
- var vars = Set[Variable]()
- for (v <- lhs) {
- ResolveExpr(v, context, false, false)(false)
- if (v.v != null) {
- if (v.v.isImmutable) context.Error(v.pos, "cannot use immutable variable " + v.id + " as actual out-parameter")
- if (vars contains v.v) {
- context.Error(v.pos, "duplicate actual out-parameter: " + v.id)
- } else {
- vars = vars + v.v
- }
- }
- }
- // resolve the token
- ResolveExpr(token, context, false, false)(false);
- if(token.typ == null || ! token.typ.IsToken || ! token.typ.isInstanceOf[TokenClass] || token.typ.asInstanceOf[TokenClass].method == null)
- context.Error(token.pos, "the first argument of a join async must be a token")
- else {
- val m = token.typ.asInstanceOf[TokenClass].method;
- jn.m = m
- if (lhs.length != m.outs.length)
- context.Error(jn.pos, "wrong number of actual out-parameters in join async of " + m.FullName +
- " (" + lhs.length + " instead of " + m.outs.length + ")")
- else {
- for((out, l) <- m.outs zip lhs){
- if(! canAssign(l.typ, out.t.typ))
- context.Error(l.pos, "the out parameter cannot be assigned to the lhs (expected: " + l.typ.FullName + ", found: " + out.t.FullName + ")")
- }
- }
-
- }
- case w@Wait(obj, id) =>
- // resolve receiver
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- // lookup condition
- obj.typ.LookupMember(id) match {
- case None =>
- context.Error(w.pos, "wait on undeclared member " + id + " in class " + obj.typ.FullName)
- case Some(c: Condition) => w.c = c
- case _ =>
- context.Error(w.pos, "wait expression does not denote a condition: " + obj.typ.FullName + "." + id)
- }
- case s@Signal(obj, id, all) =>
- // resolve receiver
- ResolveExpr(obj, context, false, false)(false)
- CheckNoGhost(obj, context)
- // lookup condition
- obj.typ.LookupMember(id) match {
- case None =>
- context.Error(s.pos, "signal on undeclared member " + id + " in class " + obj.typ.FullName)
- case Some(c: Condition) => s.c = c
- case _ =>
- context.Error(s.pos, "signal expression does not denote a condition: " + obj.typ.FullName + "." + id)
- }
- case s@Send(ch, args) =>
- ResolveExpr(ch, context, false, false)(false)
- CheckNoGhost(ch, context)
- args foreach { a => ResolveExpr(a, context, false, false)(false); CheckNoGhost(a, context) }
- // match types of arguments
- ch.typ match {
- case ChannelClass(channel) =>
- if (args.length != channel.parameters.length)
- context.Error(s.pos, "wrong number of actual in-parameters in send for channel type " + ch.typ.FullName +
- " (" + args.length + " instead of " + channel.parameters.length + ")")
- else {
- for ((actual, formal) <- args zip channel.parameters) {
- if (! canAssign(formal.t.typ, actual.typ))
- context.Error(actual.pos, "the type of the actual argument is not assignable to the formal parameter (expected: " + formal.t.FullName + ", found: " + actual.typ.FullName + ")")
- }
- }
- case _ => context.Error(s.pos, "send expression (which has type " + ch.typ.FullName + ") does not denote a channel")
- }
- case r@Receive(declaresLocal, ch, outs) =>
- ResolveExpr(ch, context, false, false)(false)
- CheckNoGhost(ch, context)
- // match types of arguments
- ch.typ match {
- case ChannelClass(channel) =>
- if (outs.length != channel.parameters.length)
- context.Error(r.pos, "wrong number of actual out-parameters in receive for channel type " + ch.typ.FullName +
- " (" + outs.length + " instead of " + channel.parameters.length + ")")
- else
- r.locals = ResolveLHS(declaresLocal, outs, channel.parameters, context)
- case _ => context.Error(r.pos, "receive expression (which has type " + ch.typ.FullName + ") does not denote a channel")
- }
- }
-
- def ResolveLHS(declaresLocal: List[Boolean], actuals: List[VariableExpr], formals: List[Variable], context: ProgramContext): List[Variable] = {
- var locals = List[Variable]()
- var vars = Set[Variable]()
- var ctx = context
- for (((declareLocal, actual), formal) <- declaresLocal zip actuals zip formals) {
- if (declareLocal) {
- val local = new Variable(actual.id, new Type(formal.t.typ))
- locals = locals ::: List(local)
- ResolveType(local.t, ctx)
- actual.Resolve(local)
- vars = vars + actual.v
- ctx = ctx.AddVariable(local)
- } else {
- ResolveExpr(actual, ctx, false, false)(false)
- CheckNoGhost(actual, ctx)
- if (actual.v != null) {
- if (! canAssign(actual.typ, formal.t.typ))
- ctx.Error(actual.pos, "the type of the formal argument is not assignable to the actual parameter (expected: " +
- formal.t.FullName + ", found: " + actual.typ.FullName + ")")
- if (vars contains actual.v)
- ctx.Error(actual.pos, "duplicate actual out-parameter: " + actual.id)
- else if (actual.v.isImmutable)
- ctx.Error(actual.pos, "cannot use immutable variable " + actual.id + " as actual out-parameter")
- vars = vars + actual.v
- }
- }
- }
- locals
- }
-
- def ResolveBounds(lowerBounds: List[Expression], upperBounds: List[Expression], context: ProgramContext, descript: String) =
- for (b <- lowerBounds ++ upperBounds) {
- ResolveExpr(b, context, true, false)(false)
- if (!b.typ.IsRef && !b.typ.IsMu)
- context.Error(b.pos, descript + " bound must be of a reference type or Mu type (found " + b.typ.FullName + ")")
- }
-
- def ResolveAssign(lhs: VariableExpr, rhs: RValue, context: ProgramContext) = {
- rhs match {
- case ExplicitSeq(Nil) => rhs.typ = lhs.typ; // if [] appears on the rhs of an assignment, we "infer" its type by looking at the type of the lhs
- case _ => ResolveExpr(rhs, context, false, false)(false)
- }
- if (! canAssign(lhs.typ, rhs.typ))
- context.Error(lhs.pos, "type mismatch in assignment, lhs=" + lhs.typ.FullName + " rhs=" + rhs.typ.FullName)
- if (lhs.v != null && !lhs.v.isGhost) CheckNoGhost(rhs, context)
- }
-
- // ResolvePermissionExpr resolves all parts of a permission expression, and replaces arithmetic operations
- // by the appropriate operation on permissions
- // Note that the parsing of permissions can be highly inaccurate. Besides historic reasons, we also need type information
- // to decide how rd(x) inside acc(o.f, ***) should be interpreted. If x is an integer expression, it stands for Epsilons(x),
- // but x could also be a channel, monitor or predicate.
- // For instance, acc(x,rd(n)) is parsed to
- // Access(MemberAccess(ImplicitThisExpr(),x),Frac(Access(MemberAccess(ImplicitThisExpr(),n),Epsilon)))
- // These error during parsing are corrected here during the resolve process. In particular, the following corrections are done:
- // - Plus and Minus are replaced by the corresponding operation on permission (i.e. PermPlus and PermMinus)
- // - Integer expressions x are replaced by Frac(x)
- def ResolvePermissionExpr(e: Expression, context: ProgramContext, twoStateContext: Boolean,
- specContext: Boolean, pos: Position)(implicit inPredicate: Boolean): Permission = e match {
- case ve @ VariableExpr(id) =>
- ResolvePermissionExpr(Frac(ve), context, twoStateContext, specContext, pos)(inPredicate);
- case f @ Frac(perm) =>
- ResolveExpr(perm, context, twoStateContext, false);
- if(perm.typ != IntClass)
- context.Error(pos, "fraction in permission must be of type integer")
- f
- case sel @ MemberAccess(e, id) =>
- ResolvePermissionExpr(Frac(sel), context, twoStateContext, specContext, pos)(inPredicate);
- case ep @ Epsilons(exp) =>
- ResolveExpr(exp, context, twoStateContext, false)
- var p: Permission = Epsilon
- exp.typ match {
- case BoolClass if exp.isInstanceOf[MemberAccess] && exp.asInstanceOf[MemberAccess].isPredicate =>
- p = PredicateEpsilon(Some(exp.asInstanceOf[MemberAccess]))
- p.pos = ep.pos
- case IntClass =>
- p = Epsilons(exp)
- p.pos = ep.pos
- case TokenClass(c, m) =>
- p = ForkEpsilon(exp)
- p.pos = ep.pos
- case c:Channel =>
- p = ChannelEpsilon(Some(exp))
- p.pos = ep.pos
- case c:Class if (c.IsNormalClass) =>
- p = MonitorEpsilon(Some(exp))
- p.pos = ep.pos
- case _ =>
- p = Star
- context.Error(ep.pos, "type " + exp.typ.FullName + " is not supported inside a rd expression.");
- }
- exp.pos = ep.pos
- p
- case f @ Full => f
- case f:PredicateEpsilon => f
- case f:ForkEpsilon => f
- case f:ChannelEpsilon => f
- case f:MonitorEpsilon => f
- case Epsilon => Epsilon
- case MethodEpsilon => MethodEpsilon
- case f @ Star => f
- case p @ Plus(ee0, ee1) =>
- if (ContainsStar(ee0) || ContainsStar(ee1))
- context.Error(p.pos, "rd* is not allowed inside permission expressions.")
- val e0 = ResolvePermissionExpr(ee0, context, twoStateContext, specContext, pos)(inPredicate);
- val e1 = ResolvePermissionExpr(ee1, context, twoStateContext, specContext, pos)(inPredicate);
- val pp = PermPlus(e0, e1)
- pp.pos = p.pos;
- pp
- case p @ Minus(ee0, ee1) =>
- if (ContainsStar(ee0) || ContainsStar(ee1))
- context.Error(p.pos, "rd* is not allowed inside permission expressions.")
- val e0 = ResolvePermissionExpr(ee0, context, twoStateContext, specContext, pos)(inPredicate);
- val e1 = ResolvePermissionExpr(ee1, context, twoStateContext, specContext, pos)(inPredicate);
- val pp = PermMinus(e0, e1)
- pp.pos = p.pos;
- pp
- case a @ Access(sel @ MemberAccess(e, id),Epsilon) =>
- var exp: Expression = sel
- var typ: Class = null
- if (e.getClass == classOf[ImplicitThisExpr]) { // id could be a local variable, if e == ImplicitThisExpr()
- val ve = VariableExpr(id)
- context.LookupVariable(id) match {
- case Some(v) => ve.Resolve(v); typ = ve.typ; exp = ve;
- case None =>
- }
- }
- if (typ == null) {
- ResolveExpr(e, context, twoStateContext, false)
- e.typ.LookupMember(id) match {
- case None =>
- context.Error(sel.pos, "undeclared member " + id + " in class " + e.typ.FullName)
- case Some(f: Field) => sel.f = f; typ = f.typ.typ
- case Some(pred@Predicate(id, body)) =>
- sel.predicate = pred;
- sel.isPredicate = true;
- typ = BoolClass
- case _ => context.Error(sel.pos, "field-select expression does not denote a field: " + e.typ.FullName + "." + id);
- }
- sel.typ = typ
- exp = sel
- }
- var p: Permission = Epsilon
- typ match {
- case BoolClass if sel.isPredicate =>
- p = PredicateEpsilon(Some(sel))
- p.pos = a.pos
- case IntClass =>
- p = Epsilons(exp)
- p.pos = a.pos
- case TokenClass(c, m) =>
- p = ForkEpsilon(exp)
- p.pos = a.pos
- case c:Channel =>
- p = ChannelEpsilon(Some(exp))
- p.pos = a.pos
- case c:Class if (c.IsNormalClass) =>
- p = MonitorEpsilon(Some(exp))
- p.pos = a.pos
- case null =>
- // ignore, found error earlier
- p = Star
- case _ =>
- context.Error(a.pos, "type " + typ.FullName + " of variable " + id + " is not supported inside a rd expression.")
- p = Star
- }
- exp.pos = a.pos
- p
- // multiplication is a bit tricky: we want to support integer multiplication i0*i1 (which will
- // correspond to a percentage i0*i1), but also the multiplication of an integer i0 with a permission
- // amount p1 (and vice versa): i0*p1 or p0*i1.
- // we first try to resolve both expressions as integer, and if not successful, try again as
- // permission amount
- case bin @ Times(e0, e1) =>
- var p0, p1: Permission = null
- var ee0 = e0
- var ee1 = e1
- var oldErrors = (new ListBuffer[(Position,String)]) ++= context.errors
- ResolveExpr(bin.E0, context, twoStateContext, false)
- if (context.errors.size > oldErrors.size) {
- context.errors.clear; context.errors ++= oldErrors // reset errors
- p0 = ResolvePermissionExpr(bin.E0, context, twoStateContext, specContext, pos)(inPredicate)
- ee0 = p0
- }
-
- oldErrors = (new ListBuffer[(Position,String)]) ++= context.errors
- ResolveExpr(bin.E1, context, twoStateContext, false)
- if (context.errors.size > oldErrors.size) {
- context.errors.clear; context.errors ++= oldErrors // reset errors
- p1 = ResolvePermissionExpr(bin.E1, context, twoStateContext, specContext, pos)(inPredicate)
- ee1 = p1
- }
-
- if (ee0.typ.IsInt && ee1.typ.IsInt) {
- bin.typ = IntClass
- val pp = Frac(bin)
- pp.pos = bin.pos
- pp
- } else if (ee0.typ.IsInt && ee1.typ.IsPermission) {
- val pp = IntPermTimes(ee0,p1)
- pp.pos = bin.pos
- pp
- } else if (ee0.typ.IsPermission && ee1.typ.IsInt) {
- val pp = IntPermTimes(ee1,p0)
- pp.pos = bin.pos
- pp
- } else {
- context.Error(pos, "multiplication of permission amounts not supported"); Star
- }
- case expr =>
- ResolveExpr(expr, context, twoStateContext, specContext)(inPredicate);
- if (expr.typ == IntClass) {
- val pp = Frac(expr)
- pp.pos = expr.pos;
- pp
- } else {
- context.Error(pos, "expression of type " + expr.typ.FullName + " invalid in permission"); Star
- }
- }
-
- // does e contain a Star (i.e., rd*)?
- def ContainsStar(expr: Expression): Boolean = {
- var x: Boolean = false
- AST.visit(expr,
- e => e match {
- case Star => x = true
- case _ =>
- }
- )
- x
- }
-
- // does e contain 'waitlevel'?
- def ContainsWaitlevel(expr: Expression): Boolean = {
- var x: Boolean = false
- AST.visit(expr,
- e => e match {
- case _:MaxLockLiteral => x = true
- case _ =>
- }
- )
- x
- }
-
- // ResolveExpr resolves all parts of an RValue, if possible, and (always) sets the RValue's typ field
- def ResolveExpr(e: RValue, context: ProgramContext,
- twoStateContext: Boolean, specContext: Boolean)(implicit inPredicate: Boolean): Unit = e match {
- case e @ NewRhs(id, initialization, lower, upper) =>
- if (context.decls contains id) {
- context.decls(id) match {
- case ch: Channel =>
- e.typ = ChannelClass(ch)
- case cl: Class =>
- e.typ = cl
- if (lower != Nil || upper != Nil)
- context.Error(e.pos, "A new object of a class type is not allowed to have a wait-order bounds clause (use the share statement instead)")
- }
- // initialize the fields
- var fieldNames = Set[String]()
- for(ini@Init(f, init) <- initialization) {
- if (fieldNames contains f) {
- context.Error(ini.pos, "The field " + f + " occurs more than once in initializer.")
- } else {
- fieldNames = fieldNames + f
- e.typ.LookupMember(f) match {
- case Some(field@Field(name, tp, _)) =>
- if(field.isInstanceOf[SpecialField]) context.Error(init.pos, "Initializer cannot assign to special field " + name + ".");
- ResolveExpr(init, context, false, false);
- if(! canAssign(tp.typ, init.typ)) context.Error(init.pos, "The field " + name + " cannot be initialized with an expression of type " + init.typ.id + ".");
- ini.f = field;
- case _ =>
- context.Error(e.pos, "The type " + id + " does not declare a field " + f + ".");
- }
- }
- }
- // resolve the bounds
- ResolveBounds(lower, upper, context, "new")
- } else {
- context.Error(e.pos, "undefined class or channel " + id + " used in new expression")
- e.typ = IntClass
- }
- case i:IntLiteral =>
- i.typ = IntClass
- case b:BoolLiteral =>
- b.typ = BoolClass
- case n:NullLiteral =>
- n.typ = NullClass
- case s:StringLiteral =>
- s.typ = StringClass
- case mx:MaxLockLiteral =>
- mx.typ = MuClass
- case mx:LockBottomLiteral =>
- mx.typ = MuClass
- case _:BoogieExpr =>
- throw new InternalErrorException("boogie expression unexpected here")
- case r:Result =>
- assert(context.currentMember!=null);
- r.typ = IntClass
- if(context.currentMember==null || ! context.currentMember.isInstanceOf[Function]){
- context.Error(r.pos, "The variable result can only be used in the postcondition of a function.");
- } else {
- r.typ = context.currentMember.asInstanceOf[Function].out.typ;
- }
- case ve @ VariableExpr(id) =>
- context.LookupVariable(id) match {
- case None => context.Error(ve.pos, "undefined local variable " + id); ve.typ = IntClass
- case Some(v) => ve.Resolve(v) }
- case v:ThisExpr =>
- v.typ = context.currentClass
- if (context.IsStatic) {
- context.Error(v.pos, "Accessing non-static member not allowed in static context.")
- }
- case sel @ MemberAccess(e, id) =>
- ResolveExpr(e, context, twoStateContext, false)
- var typ: Class = IntClass
- e.typ.LookupMember(id) match {
- case None =>
- context.Error(sel.pos, "undeclared member " + id + " in class " + e.typ.FullName)
- case Some(f: Field) => sel.f = f; typ = f.typ.typ
- case Some(pred@Predicate(id, body)) =>
- if(! specContext)
- context.Error(sel.pos, "predicate can only be used in positive predicate contexts")
- sel.predicate = pred;
- sel.isPredicate = true;
- typ = BoolClass
- case _ => context.Error(sel.pos, "field-select expression does not denote a field: " + e.typ.FullName + "." + id);
- }
- sel.typ = typ
- case p: Permission => context.Error(p.pos, "permission not expected here.")
- case expr @ Access(e, perm) =>
- if (!specContext) context.Error(expr.pos, permExpressionName(perm) + " expression is allowed only in positive predicate contexts")
- ResolveExpr(e, context, twoStateContext, true)
- val p = ResolvePermissionExpr(perm match { case Frac(f) => f; case o => o;}, context, twoStateContext, false, expr.pos);
- expr.perm = p;
- expr.typ = BoolClass
- case expr @ AccessAll(obj, perm) =>
- if (!specContext) context.Error(expr.pos, permExpressionName(perm) + " expression is allowed only in positive predicate contexts")
- ResolveExpr(obj, context, twoStateContext, false)
- if(!obj.typ.IsRef) context.Error(expr.pos, "Target of .* must be object reference.")
- val p = ResolvePermissionExpr(perm match { case Frac(f) => f; case o => o;}, context, twoStateContext, false, expr.pos);
- expr.perm = p;
- expr.typ = BoolClass
- case expr @ AccessSeq(s, f, perm) =>
- if (!specContext) context.Error(expr.pos, permExpressionName(perm) + " expression is allowed only in positive predicate contexts")
- ResolveExpr(s, context, twoStateContext, false)
- if(!s.typ.IsSeq) context.Error(expr.pos, "Target of [*] must be sequence.")
- val p = ResolvePermissionExpr(perm match { case Frac(f) => f; case o => o;}, context, twoStateContext, false, expr.pos);
- expr.perm = p;
- f match {
- case Some(x) =>
- ResolveExpr(x, context, twoStateContext, true);
- case _ => }
- expr.typ = BoolClass
- case expr@ Credit(e,n) =>
- if (!specContext) context.Error(expr.pos, "credit expression is allowed only in positive predicate contexts")
- ResolveExpr(e, context, twoStateContext, false)
- if(!e.typ.IsChannel) context.Error(expr.pos, "credit argument must denote a channel.")
- ResolveExpr(expr.N, context, twoStateContext, false)
- expr.typ = BoolClass
- case expr@ Holds(e) =>
- if(inPredicate) context.Error(expr.pos, "holds cannot be mentioned in monitor invariants or predicates")
- ResolveExpr(e, context, twoStateContext, false)
- expr.typ = BoolClass
- case expr@ RdHolds(e) =>
- if(inPredicate) context.Error(expr.pos, "rdholds cannot be mentioned in monitor invariants or predicates")
- ResolveExpr(e, context, twoStateContext, false)
- expr.typ = BoolClass
- case expr@ Assigned(id) =>
- context.LookupVariable(id) match {
- case None => context.Error(expr.pos, "undefined local variable " + id)
- case Some(v) =>
- expr.v = v
- if (!(v.isImmutable && v.isGhost))
- context.Error(expr.pos, "assigned can only be used with ghost consts")
- }
- expr.typ = BoolClass
- case expr@ Old(e) =>
- if (! twoStateContext) { context.Error(expr.pos, "old expression is not allowed here") }
- ResolveExpr(e, context, twoStateContext, false)
- expr.typ = e.typ
- case ite@IfThenElse(con, then, els) =>
- ResolveExpr(con, context, twoStateContext, false); ResolveExpr(then, context, twoStateContext, specContext); ResolveExpr(els, context, twoStateContext, specContext);
- if (!con.typ.IsBool) context.Error(con.pos, "condition of if-then-else expression must be a boolean");
- if (!canAssign(then.typ, els.typ) && !canAssign(els.typ, then.typ)) context.Error(ite.pos, "the then and else branch of an if-then-else expression must have compatible types");
- ite.typ = then.typ;
- case expr@ Not(e) =>
- ResolveExpr(e, context, twoStateContext, false)
- if (!e.typ.IsBool) context.Error(expr.pos, "not-expression requires boolean operand")
- expr.typ = BoolClass
- case appl@FunctionApplication(obj, id, args) =>
- // HACK: allow non-static access for receiver
- ResolveExpr(obj, context.AsNonStatic(), twoStateContext, false);
- args foreach { arg => ResolveExpr(arg, context, twoStateContext, false)};
- // lookup function
- appl.typ = IntClass
- obj.typ.LookupMember(id) match {
- case None =>
- context.Error(appl.pos, "function " + id + " not found in class " + obj.typ.FullName)
- case Some(func@Function(f, ins, out, specs, body)) =>
- appl.f = func
- appl.typ = func.out.typ;
- if (args.length != ins.length)
- context.Error(appl.pos, "wrong number of actual arguments in function application of " + obj.typ.FullName + "." + id +
- " (" + args.length + " instead of " + ins.length + ")")
- else {
- for((actual, formal) <- args zip func.ins){
- if(! canAssign(formal.t.typ, actual.typ))
- context.Error(actual.pos, "the type of the actual argument is not assignable to the formal parameter (expected: " + formal.t.FullName + ", found: " + actual.typ.FullName + ")")
- }
- }
- case _ => context.Error(appl.pos, obj.typ.id + "." + id + " is not a function")
- }
- case uf@Unfolding(pred, e) =>
- ResolveExpr(pred, context, twoStateContext, true);
- ResolveExpr(e, context, twoStateContext, false);
- if(! pred.ma.isPredicate) context.Error(uf.pos, "Only predicates can be unfolded.")
- uf.typ = e.typ;
- case bin: EqualityCompareExpr =>
- ResolveExpr(bin.E0, context, twoStateContext, false)
- ResolveExpr(bin.E1, context, twoStateContext, false)
- if (bin.E0.typ == bin.E1.typ) { /* all is well */ }
- else if (bin.E0.typ.IsRef && bin.E1.typ.IsNull) { /* all is well */ }
- else if (bin.E0.typ.IsNull && bin.E1.typ.IsRef) { /* all is well */ }
- else
- context.Error(bin.pos, bin.OpName + " requires operands of the same type, found " + bin.E0.typ.FullName + " and " + bin.E1.typ.FullName)
- bin.typ = BoolClass
- case bin: LockBelow =>
- ResolveExpr(bin.E0, context, twoStateContext, false)
- ResolveExpr(bin.E1, context, twoStateContext, false)
- if (!(bin.E0.typ.IsRef || bin.E0.typ.IsMu))
- context.Error(bin.pos, "type of " + bin.OpName + " LHS operand must be a reference or Mu type (found " + bin.E0.typ.FullName + ")")
- if (!(bin.E1.typ.IsRef || bin.E1.typ.IsMu))
- context.Error(bin.pos, "type of " + bin.OpName + " RHS operand must be a reference or Mu type (found " + bin.E1.typ.FullName + ")")
- bin.typ = BoolClass
- case app@Append(e0, e1) =>
- ResolveExpr(e0, context, twoStateContext, false);
- ResolveExpr(e1, context, twoStateContext, false);
- if(! e0.typ.IsSeq) context.Error(app.pos, "LHS operand of ++ must be sequence (found: " + e0.typ.FullName + ").");
- if(! e1.typ.IsSeq) context.Error(app.pos, "RHS operand of ++ must be sequence (found: " + e1.typ.FullName + ").");
- if(e0.typ != e1.typ) context.Error(app.pos, "++ can only be applied to sequences of the same type.");
- app.typ = e0.typ;
- case at@At(e0, e1) =>
- ResolveExpr(e0, context, twoStateContext, false);
- ResolveExpr(e1, context, twoStateContext, false);
- if(! e0.typ.IsSeq) context.Error(at.pos, "LHS operand of @ must be sequence. (found: " + e0.typ.FullName + ").");
- if(! e1.typ.IsInt) context.Error(at.pos, "RHS operand of @ must be an integer (found: " + e1.typ.FullName + ").");
- if(e0.typ.IsSeq) at.typ = e0.typ.parameters(0) else at.typ = IntClass;
- case drop@Drop(e0, e1) =>
- ResolveExpr(e0, context, twoStateContext, false);
- ResolveExpr(e1, context, twoStateContext, false);
- if(! e0.typ.IsSeq) context.Error(drop.pos, "LHS operand of drop must be sequence. (found: " + e0.typ.FullName + ").");
- if(! e1.typ.IsInt) context.Error(drop.pos, "RHS operand of drop must be an integer (found: " + e1.typ.FullName + ").");
- drop.typ = e0.typ;
- case take@Take(e0, e1) =>
- ResolveExpr(e0, context, twoStateContext, false);
- ResolveExpr(e1, context, twoStateContext, false);
- if(! e0.typ.IsSeq) context.Error(take.pos, "LHS operand of take must be sequence. (found: " + e0.typ.FullName + ").");
- if(! e1.typ.IsInt) context.Error(take.pos, "RHS operand of take must be an integer (found: " + e1.typ.FullName + ").");
- take.typ = e0.typ;
- case contains@Contains(e0, e1) =>
- ResolveExpr(e0, context, twoStateContext, false);
- ResolveExpr(e1, context, twoStateContext, false);
- if(! e1.typ.IsSeq)
- context.Error(contains.pos, "RHS operand of 'in' must be sequence. (found: " + e1.typ.FullName + ").");
- else if(! canAssign(e1.typ.parameters(0), e0.typ))
- context.Error(contains.pos, "LHS operand's type must be element type of sequence. (found: " + e0.typ.FullName + ", expected: " + e1.typ.parameters(0).FullName + ").");
- contains.typ = BoolClass;
- case bin: BinaryExpr =>
- ResolveExpr(bin.E0, context, twoStateContext, specContext && bin.isInstanceOf[And])
- ResolveExpr(bin.E1, context, twoStateContext, specContext && (bin.isInstanceOf[And] || bin.isInstanceOf[Implies]))
- if (bin.E0.typ != bin.ExpectedLhsType)
- context.Error(bin.E0.pos, "incorrect type of " + bin.OpName + " LHS" +
- " (expected " + bin.ExpectedLhsType.FullName +
- ", found " + bin.E0.typ.FullName + ")")
- if (bin.E1.typ != bin.ExpectedRhsType)
- context.Error(bin.E1.pos, "incorrect type of " + bin.OpName + " RHS" +
- " (expected " + bin.ExpectedRhsType.FullName + ", found " + bin.E1.typ.FullName + ")")
- bin.typ = bin.ResultType
- case q: Quantification =>
- q.Is foreach { i => if(context.LookupVariable(i).isDefined) context.Error(q.pos, "The variable " + i + " hides another local.") };
- val typ = q match {
- case q: SeqQuantification =>
- ResolveExpr(q.seq, context, twoStateContext, false);
- if(! q.seq.typ.IsSeq) {
- context.Error(q.seq.pos, "A quantification must range over a sequence. (found: " + q.seq.typ.FullName + ").");
- None;
- } else
- Some(q.seq.typ.parameters(0));
- case q: TypeQuantification =>
- ResolveType(q.t, context);
- if (q.t.typ == null) None else Some(q.t.typ);
- };
-
- if (typ.isDefined) {
- val vartype = typ.get;
- var bodyContext = context;
- var bvariables = Nil: List[Variable];
- q.Is foreach { i =>
- val variable = new Variable(i, new Type(vartype));
- bodyContext = bodyContext.AddVariable(variable);
- bvariables = bvariables ::: List(variable);
- }
- ResolveExpr(q.E, bodyContext, twoStateContext, true);
- if(! q.E.typ.IsBool) context.Error(q.E.pos, "Body of quantification must be a boolean. (found: " + q.E.typ.FullName + ").");
- q.variables = bvariables;
- }
- q.typ = BoolClass
- case seq@EmptySeq(t) =>
- ResolveType(t, context)
- seq.typ = SeqClass(t.typ);
- case seq@ExplicitSeq(es) =>
- es foreach { e => ResolveExpr(e, context, twoStateContext, false) }
- es match {
- case Nil => seq.typ = SeqClass(IntClass);
- case h :: t =>
- t foreach { e => if(! (e.typ == h.typ)) context.Error(e.pos, "The elements of the sequence expression have different types.")};
- seq.typ = SeqClass(h.typ);
- }
- case ran@Range(min, max) =>
- ResolveExpr(min, context, twoStateContext, false);
- if(! min.typ.IsInt) context.Error(min.pos, "The mininum of a range expression must be an integer (found: " + min.typ.FullName + ").");
- ResolveExpr(max, context, twoStateContext, false);
- if(! max.typ.IsInt) context.Error(max.pos, "The maximum of a range expression must be an integer (found: " + max.typ.FullName + ").");
- ran.typ = SeqClass(IntClass);
- case len@Length(e) =>
- ResolveExpr(e, context, twoStateContext, false);
- if(! e.typ.IsSeq) context.Error(len.pos, "The operand of a length expression must be sequence. (found: " + e.typ.FullName + ").");
- len.typ = IntClass;
- case ev@Eval(h, e) =>
- if(inPredicate) context.Error(ev.pos, "eval cannot be used in monitor invariants or predicates")
- h match {
- case AcquireState(obj) =>
- ResolveExpr(obj, context, twoStateContext, false)
- if(! obj.typ.IsRef) context.Error(ev.pos, "The target of acquire must be a reference.");
- case ReleaseState(obj) => ResolveExpr(obj, context, twoStateContext, false)
- if(! obj.typ.IsRef) context.Error(ev.pos, "The target of acquire must be a reference.");
- case c@CallState(token, obj, id, args) =>
- ResolveExpr(token, context, twoStateContext, false);
- if( ! token.typ.IsToken) context.Error(token.pos, "joinable is only applicable to tokens");
- ResolveExpr(obj, context, false, false)
- CheckNoGhost(obj, context)
- args foreach { a => a match {
- case VariableExpr("?") =>
- case _ => ResolveExpr(a, context, false, false); CheckNoGhost(a, context)
- }}
- // lookup method
- var typ: Class = IntClass
- obj.typ.LookupMember(id) match {
- case None =>
- context.Error(obj.pos, "call of undeclared member " + id + " in class " + obj.typ.FullName)
- case Some(m: Method) =>
- c.m = m
- if (args.length != m.ins.length)
- context.Error(obj.pos, "wrong number of actual in-parameters in call to " + obj.typ.FullName + "." + id +
- " (" + args.length + " instead of " + m.ins.length + ")")
- else {
- for((actual, formal) <- args zip m.ins){
- actual match {
- case VariableExpr("?") =>
- case _ => if (!canAssign(formal.t.typ, actual.typ))
- context.Error(actual.pos, "the type of the actual argument is not assignable to the formal parameter (expected: " + formal.t.FullName + ", found: " + actual.typ.FullName + ")")
- }
-
- }
- }
- case _ => context.Error(obj.pos, "call expression does not denote a method: " + obj.typ.FullName + "." + id)
- }
-
-
- }
- ResolveExpr(e, context, false, specContext)
- ev.typ = e.typ;
- }
-
- def LookupRunMethod(cl: Class, context: ProgramContext, op: String, pos: Position): Option[Method] = {
- cl.LookupMember(runMethod) match {
- case None =>
- context.Error(pos, "object given in " + op + " statement must be of a type with a parameter-less run method" +
- " (found type " + cl.id + ")")
- None
- case Some(m: Method) =>
- m.spec foreach {
- case Precondition(e) => CheckRunSpecification(e, context, true)
- case Postcondition(e) => CheckRunSpecification(e, context, false)
- case lc: LockChange => context.Error(lc.pos, "lockchange is not allowed in specification of run method")
- }
- if(0<m.ins.length || 0<m.outs.length) {
- context.Error(pos, "object given in " + op + " statement must be of a type with a parameter-less run method" +
- " (found " + m.ins.length + " in-parameters and " + m.outs.length + " out-parameters)"); None
- } else
- Some(m)
- case _ =>
- context.Error(pos, "object given in " + op + " statement must be of a type with a parameter-less run method" +
- " (found non-method member)")
- None
- }
- }
-
- // assumes that lhs and rhs are resolved
- def canAssign(lhs: Class, rhs: Class): Boolean = {
- (lhs, rhs) match {
- case (TokenClass(c1, m1), TokenClass(c2, m2)) => c1.id.equals(c2.id) && m1.equals(m2)
- case (TokenClass(c1, m1), _) => false
- case (_, TokenClass(c2, m2)) => false
- case (lhs, rhs) => lhs == rhs || (lhs.IsRef && rhs.IsNull)
- }
- }
-
- def CheckNoGhost(expr: RValue, context: ProgramContext): Unit = {
- AST.visit(expr, e => e match {
- case ve: VariableExpr =>
- if (ve.v != null && ve.v.isGhost) context.Error(ve.pos, "ghost variable not allowed here")
- case fs@ MemberAccess(e, id) =>
- if (!fs.isPredicate && fs.f != null && fs.f.isGhost) context.Error(fs.pos, "ghost fields not allowed here")
- case a: Assigned =>
- if (a.v != null && a.v.isGhost) context.Error(a.pos, "ghost variable not allowed here")
- case _ => // do nothing
- })
- }
-
- def CheckNoImmutableGhosts(expr: RValue, context: ProgramContext): Unit = {
- AST.visit(expr, e => e match {
- case ve: VariableExpr =>
- if (ve.v != null && ve.v.isGhost && ve.v.isImmutable) context.Error(ve.pos, "ghost const not allowed here")
- case a: Assigned =>
- if (a.v != null && a.v.isGhost && a.v.isImmutable) context.Error(a.pos, "ghost const not allowed here")
- case _ => // do nothing
- })
- }
-
- def CheckRunSpecification(e: Expression, context: ProgramContext, allowMaxLock: Boolean): Unit = e match {
- case _:MaxLockLiteral =>
- if (!allowMaxLock) context.Error(e.pos, "specification of run method is not allowed to mention waitlevel here")
- case _:Literal =>
- case _:VariableExpr =>
- case _:ThisExpr =>
- case _:Result =>
- case _:BoogieExpr =>
- case MemberAccess(e, id) =>
- CheckRunSpecification(e, context, false)
- case Frac(perm) => CheckRunSpecification(perm, context, false)
- case Epsilons(perm) => CheckRunSpecification(perm, context, false)
- case PermPlus(p0, p1) =>
- CheckRunSpecification(p0, context, false)
- CheckRunSpecification(p1, context, false)
- case PermMinus(p0, p1) =>
- CheckRunSpecification(p0, context, false)
- CheckRunSpecification(p1, context, false)
- case PermTimes(p0, p1) =>
- CheckRunSpecification(p0, context, false)
- CheckRunSpecification(p1, context, false)
- case IntPermTimes(p0, p1) =>
- CheckRunSpecification(p0, context, false)
- CheckRunSpecification(p1, context, false)
- case Full | Epsilon | Star | MethodEpsilon =>
- case ChannelEpsilon(None) | PredicateEpsilon(None) | MonitorEpsilon(None) =>;
- case ChannelEpsilon(Some(e)) => CheckRunSpecification(e, context, false);
- case PredicateEpsilon(Some(e)) => CheckRunSpecification(e, context, false);
- case MonitorEpsilon(Some(e)) => CheckRunSpecification(e, context, false);
- case ForkEpsilon(tk) => CheckRunSpecification(tk, context, false);
- case Access(e, perm) =>
- CheckRunSpecification(e, context, false);
- CheckRunSpecification(perm, context, false);
- case AccessAll(obj, perm) =>
- CheckRunSpecification(obj, context, false);
- CheckRunSpecification(perm, context, false);
- case AccessSeq(s, f, perm) =>
- CheckRunSpecification(s, context, false);
- CheckRunSpecification(perm, context, false);
- case expr@ Credit(e, n) =>
- CheckRunSpecification(e, context, false)
- CheckRunSpecification(expr.N, context, false)
- case Holds(e) =>
- context.Error(e.pos, "holds is not allowed in specification of run method")
- case RdHolds(e) =>
- context.Error(e.pos, "rd holds is not allowed in specification of run method")
- case _:Assigned =>
- case Old(e) =>
- CheckRunSpecification(e, context, false) // OLD occurs only in postconditions and monitor invariants, where waitlevel is not allowed anyhow
- case IfThenElse(con, then, els) =>
- CheckRunSpecification(con, context, false);
- CheckRunSpecification(con, context, allowMaxLock);
- CheckRunSpecification(con, context, allowMaxLock);
- case Not(e) =>
- CheckRunSpecification(e, context, false)
- case FunctionApplication(obj, id, args) =>
- obj :: args foreach { arg => CheckRunSpecification(arg, context, false)}
- case Unfolding(pred, e) =>
- CheckRunSpecification(pred, context, true);
- CheckRunSpecification(e, context, allowMaxLock);
- case LockBelow(e0,e1) =>
- CheckRunSpecification(e0, context, allowMaxLock)
- CheckRunSpecification(e1, context, false)
- case And(e0,e1) =>
- CheckRunSpecification(e0, context, allowMaxLock)
- CheckRunSpecification(e1, context, allowMaxLock)
- case Implies(e0,e1) =>
- CheckRunSpecification(e0, context, false)
- CheckRunSpecification(e1, context, allowMaxLock)
- case bin: BinaryExpr =>
- CheckRunSpecification(bin.E0, context, false)
- CheckRunSpecification(bin.E1, context, false)
- case q: SeqQuantification =>
- CheckRunSpecification(q.seq, context, false)
- CheckRunSpecification(q.e, context, true)
- case q: TypeQuantification =>
- CheckRunSpecification(q.e, context, true)
- case Length(e) =>
- CheckRunSpecification(e, context, false);
- case ExplicitSeq(es) =>
- es foreach { e => CheckRunSpecification(e, context, false) }
- case Range(min, max) =>
- CheckRunSpecification(min, context, false)
- CheckRunSpecification(max, context, false)
- case Eval(h, e) =>
- h match {
- case AcquireState(obj) => CheckRunSpecification(obj, context, false);
- case ReleaseState(obj) => CheckRunSpecification(obj, context, false);
- case CallState(token, obj, id, args) => CheckRunSpecification(token, context, false); CheckRunSpecification(obj, context, false); args foreach { a: Expression => CheckRunSpecification(a, context, false)};
- }
- CheckRunSpecification(e, context, allowMaxLock)
- }
-
- def ResolveTransform(mt: MethodTransform, baseContext: ProgramContext) {
- val context = baseContext.SetClass(mt.Parent).SetMember(mt);
-
- mt.spec foreach {
- case Precondition(e) =>
- context.Error(e.pos, "Method refinement cannot add a pre-condition")
- case Postcondition(e) =>
- ResolveExpr(e, context, true, true)(false)
- case _ : LockChange => throw new NotSupportedException("not implemented")
- }
- if (mt.ins != mt.refines.Ins) context.Error(mt.pos, "Refinement must have the same input arguments")
- if (! mt.outs.startsWith(mt.refines.Outs)) context.Error(mt.pos, "Refinement must declare all abstract output variables")
-
- mt.body = AST.refine(mt.refines.Body, mt.trans) match {
- case AST.Matched(ss) => ss
- case AST.Unmatched(t) => context.Error(mt.pos, "Cannot match transform around " + t.pos); Nil
- }
-
- /**
- * We thread two contexts for the concrete and abstract versions.
- */
- def resolveBody(ss: List[Statement],
- concreteContext: ProgramContext,
- abstractContext: List[Variable]) {
- var ctx = concreteContext;
- var locals = abstractContext;
- for (s <- ss) {
- s match {
- case r @ RefinementBlock(c, a) =>
- // abstract globals available at this point in the program
- r.before = locals;
-
- // resolve concrete version
- ResolveStmt(BlockStmt(c), ctx)
-
- // compare declared local variables
- val vs = c flatMap {s => s.Declares};
- for (s <- a;
- v <- s.Declares;
- if (! vs.contains(v)))
- ctx.Error(r.pos, "Refinement block must declare a local variable from the abstract program: " + v.id)
- case w @ WhileStmt(guard, oi, ni, lks, body) =>
- for (inv <- ni) {
- ResolveExpr(inv, ctx, true, true)(false)
- if (!inv.typ.IsBool) ctx.Error(inv.pos, "loop invariant must be boolean (found " + inv.typ.FullName + ")")
- }
- resolveBody(body.ss, ctx, locals)
- w.LoopTargets = body.Targets.filter(ctx.IsVariablePresent).toList
- case IfStmt(_, thn, None) =>
- resolveBody(thn.ss, ctx, locals)
- case IfStmt(_, thn, Some(els)) =>
- resolveBody(thn.ss, ctx, locals)
- resolveBody(List(els), ctx, locals)
- case BlockStmt(ss) =>
- resolveBody(ss, ctx, locals)
- case _ =>
- }
-
- // declare concrete and abstract locals
- for (v <- s.Declares) ctx = ctx.AddVariable(v);
- s match {
- case RefinementBlock(_, a) => locals = locals ++ (a flatMap {s => s.Declares})
- case _ => locals = locals ++ s.Declares
- }
- }
- }
-
- resolveBody(mt.body, context, mt.refines.Ins ++ mt.refines.Outs)
- }
-
- def ResolveCouplingInvariant(ci: CouplingInvariant, cl: Class, context: ProgramContext) {
- assert (cl.IsRefinement)
- for (id <- ci.ids) cl.refines.LookupMember(id) match {
- case Some(f: Field) => ci.fields = f :: ci.fields
- case Some(_) => context.Error(ci.pos, "coupling invariant can only be bound to a field of the abstract program")
- case None => context.Error(ci.pos, "coupling invariant does not refer to a member of the abstract program")
- }
- ResolveExpr(ci.e, context.SetClass(cl).SetMember(ci), false, true)(true)
- if (!ci.e.typ.IsBool) context.Error(ci.pos, "coupling invariant requires a boolean expression (found " + ci.e.typ.FullName + ")")
- // TODO: check coupling invariant may only give permissions to newly declared fields
- // TODO: check concrete body cannot refer to replaced fields
- }
-
- // TODO: this method might need to be replaced at some point. it is not possible
- // to decide what name is used on the source level just by the permission (e.g.,
- // Epsilons can be rd(x,1) or acc(x,rd(1))
- def permExpressionName(perm: Permission): String = {
- perm match {
- case _:Epsilons => "rd";
- case Epsilon => "rd";
- case MethodEpsilon => "rd"
- case Star => "rd";
- case Full => "acc";
- case _:Frac => "acc";
- case _:ArithmeticPermission => "acc";
- case _:ChannelEpsilon | _:ForkEpsilon | _:MonitorEpsilon | _:PredicateEpsilon => "acc";
- }
- }
-}
diff --git a/Chalice/src/main/scala/SmokeTest.scala b/Chalice/src/main/scala/SmokeTest.scala
deleted file mode 100644
index bd733ee6..00000000
--- a/Chalice/src/main/scala/SmokeTest.scala
+++ /dev/null
@@ -1,249 +0,0 @@
-
-package chalice;
-
-import scala.util.parsing.input.Position
-import scala.util.parsing.input.NoPosition
-
-/** SmokeTest allows to perform 'smoke testing' on any given Chalice program.
- * The prover is instructed to try proving 'false' at various places in the
- * program to find unreachable code, precondition that are equivalent to false
- * or assumptions that introduce a contradiction.
- *
- * @author Stefan Heule
- */
-object SmokeTest {
-
- /** SmokeAssert is used to keep track of the position and real error message
- * associated with a certain assert statement. Also, we build a DAG of
- * SmokeAssert that essentially corresponds to the control flow graph (the
- * member prev is used to record the in-edges of every SmokeAssert). This
- * graph is then used to omit certain warnings (e.g., if the precondition is
- * already false, we do not need to report that the method end cannot be
- * reached, too).
- */
- case class SmokeAssert(id: Int, pos: Position, msg: String, prev: Set[SmokeAssert], chaliceAssert: Assert) {
- var warning: Boolean = false // did this "assert false" generate a warning? (i.e. did it not generate a Boogie error?)
- }
- /** Serves as a sentinel for the first assert (which should always cause a
- * warning, thus SmokeAssertSentinel.warning = false)
- */
- object SmokeAssertSentinel extends SmokeAssert(-1, NoPosition, "", Set(), null)
-
- /** Map from error message ID's to their SmokeAssert object */
- private var smokeAssertions: Map[Int,SmokeAssert] = Map()
- private var count: Int = 0 // current error message id
-
- /** Get the warning message from an ID */
- def smokeWarningMessage(id: Int) = {
- smokeAssertions(id).msg
- }
-
- /** Process the output of Boogie and generate the correct warnings from smoke testing */
- def processBoogieOutput(out: List[String]): String = {
- var errorCount: Map[String, Int] = Map()
- val SmokePattern = ".*: SMOKE-TEST-([0-9]+).*".r
- val SummaryPattern = "Boogie program verifier finished with ([0-9]+) verified, ([0-9]+) errors".r
- var verificationResult = "";
- var smokeErrors: Set[Int] = Set()
- var outcome: Option[(Int,Int)] = None
- for (s <- out) s match {
- case SmokePattern(id) => smokeErrors += id.toInt
- case SummaryPattern(verified, errors) => outcome = Some((verified.toInt,errors.toInt))
- case _ => verificationResult += s + "\n"
- }
-
- // check which smoke assertions failed
- for ((errNr, s@SmokeAssert(_, pos, msg, prev, _)) <- smokeAssertions) yield {
- s.warning = !smokeErrors.contains(errNr)
- }
-
- var smokeTestWarnings = 0
- val smokeResult = {
- var t = "";
- for (s@SmokeAssert(_, pos, msg, prev, _) <- smokeAssertions.values.toList.sortWith((a,b) => a.pos < b.pos)) yield {
- if (s.warning) {
- if (s.prev.exists(a => !a.warning)) { // omit warning if all ancestors created a warning
- t += " " + pos + ": " + msg + "\n"
- smokeTestWarnings += 1
- }
- }
- }
- t
- }
-
- var realErrors = -1
- val status = (outcome match {
- case None => ""
- case Some((verified,errors)) =>
- realErrors = errors-smokeErrors.size
- "Boogie program verifier finished with " + realErrors + " errors and " + smokeTestWarnings + " smoke test warnings"
- })
-
- verificationResult +
- (if (realErrors > 0 && smokeTestWarnings > 0) "The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.\n" else "") +
- smokeResult + (if (smokeResult != "") "\n" else "") +
- status
- }
-
- /** Add smoke assertions for to a program. */
- def smokeProgram(prog: List[TopLevelDecl]): List[TopLevelDecl] = {
- for (decl <- prog) yield decl match {
- case cl: Class =>
- val newmembers = for (m <- cl.members) yield m match {
- case MonitorInvariant(e) => m
- case f@ Field(id, t, ghost) => m
- case method: Method =>
- copyPosition(method, smokeMethod(method))
- case Condition(id, optE) => m
- case Predicate(id, definition) => m
- case Function(id, ins, out, specs, e) => m
- case m: MethodTransform => m
- case CouplingInvariant(ids, e) => m
- }
- copyPosition(cl, Class(cl.classId, cl.parameters, cl.module, newmembers))
- case ch: Channel => ch
- }
- }
-
- /** Add smoke assertions for a method (if necessary). */
- private def smokeMethod(method: Method) = {
- val preassert = initSmokeAssert(method.pos, "Precondition of method " + method.Id + " is equivalent to false.")
- var (newbody, bodyout) = smokeStmt(method.body, Set(preassert))
- val postassert = initSmokeAssert(method.pos, "The end of method " + method.Id + " is unreachable.", bodyout)
- newbody = preassert.chaliceAssert :: newbody ::: postassert.chaliceAssert :: Nil
- Method(method.id, method.ins, method.outs, method.spec, newbody)
- }
-
- /** Add smoke assertions for multiple statements (if necessary). */
- private def smokeStmt(stmts: List[Statement], in: Set[SmokeAssert]): (List[Statement], Set[SmokeAssert]) = {
- var tmp = in
- val newstmts = (for (s <- stmts) yield {
- val (sstmts, sout) = smokeStmt(s, tmp)
- tmp = sout
- copyPosition(s, sstmts)
- }).flatten
- (newstmts, tmp)
- }
-
- /** Add smoke assertions for a statement (if necessary). */
- private def smokeStmt(stmt: Statement, in: Set[SmokeAssert]): (List[Statement], Set[SmokeAssert]) = {
- var out = in
-
- def helper(name: String): List[Statement] = {
- val (stmts, sout) = smokeSimpleStmt(stmt, in, name); out = sout; stmts
- }
-
- val result = stmt match {
- // composite statements
- case BlockStmt(ss) =>
- val (smokestmts, blocksmoke) = smokeStmt(ss, in)
- out = blocksmoke
- smokestmts
- case ifs@IfStmt(guard, BlockStmt(then), els) =>
- val thensmoke = initSmokeAssert(ifs.pos, "The begging of the if-branch is unreachable.", in)
- val (thensmokestmts, thenout) = smokeStmt(then, Set(thensmoke))
- out = thenout
- val newthen = thensmoke.chaliceAssert :: thensmokestmts
- val newelse = els match {
- case None =>
- out ++= in
- None
- case Some(s) =>
- val elsesmoke = initSmokeAssert(ifs.pos, "The begging of the else-branch is unreachable.", in)
- val (blocksmokestmts, blockout) = smokeStmt(s, Set(elsesmoke))
- out ++= blockout
- Some(BlockStmt(elsesmoke.chaliceAssert :: blocksmokestmts))
- }
- IfStmt(guard, BlockStmt(newthen), newelse) :: Nil
- case WhileStmt(guard, oldInvs, newInvs, lkch, BlockStmt(body)) =>
- val whilesmoke = initSmokeAssert(stmt.pos, "The begging of the while-body is unreachable.", in)
- val (whilesmokestmts, whileout) = smokeStmt(body, Set(whilesmoke))
- val whileaftersmoke = initSmokeAssert(stmt.pos, "The statements after the while-loop are unreachable.", in)
- val whileendsmoke = initSmokeAssert(stmt.pos, "The end of the while-loop is unreachable.", whileout)
- out = Set(whileaftersmoke)
- val newbody = whilesmoke.chaliceAssert :: whilesmokestmts ::: whileendsmoke.chaliceAssert :: Nil
- WhileStmt(guard, oldInvs, newInvs, lkch, BlockStmt(newbody)) :: whileaftersmoke.chaliceAssert :: Nil
- case Lock(obj, BlockStmt(body), rdLock) =>
- val locksmoke = initSmokeAssert(stmt.pos, "The begging of the lock-block is unreachable.", in)
- val (blocksmokestmts, blockout) = smokeStmt(body, Set(locksmoke))
- out = blockout
- Lock(obj, BlockStmt(locksmoke.chaliceAssert :: blocksmokestmts), rdLock) :: Nil
- case _: RefinementBlock =>
- // TODO
- stmt :: Nil
-
- // assumption
- case Assume(_) =>
- val assumeSmoke = initSmokeAssert(stmt.pos, "Assumption introduces a contradiction.", in)
- out = Set(assumeSmoke)
- stmt :: assumeSmoke.chaliceAssert :: Nil
-
- // simple statements that inhale something
- case Unfold(_) => helper("unfold")
- case JoinAsync(_, _) => helper("join")
- case _: Call => helper("method call")
- case _: SpecStmt => helper("specification")
- case Receive(_, _, _) => helper("receive")
- case Acquire(_) => helper("acquire")
- case RdAcquire(_) => helper("rd acquire")
-
- // any other simple statements
- case Assert(_) => if (Chalice.smokeAll) helper("assert") else stmt :: Nil
- case Assign(_, _) => if (Chalice.smokeAll) helper("assign") else stmt :: Nil
- case FieldUpdate(_, _) => if (Chalice.smokeAll) helper("field update") else stmt :: Nil
- case _: LocalVar => if (Chalice.smokeAll) helper("local variable") else stmt :: Nil
- case Install(_, _, _) => if (Chalice.smokeAll) helper("reorder") else stmt :: Nil
- case Share(_, _, _) => if (Chalice.smokeAll) helper("share") else stmt :: Nil
- case Unshare(_) => if (Chalice.smokeAll) helper("unshare") else stmt :: Nil
- case Release(_) => if (Chalice.smokeAll) helper("release") else stmt :: Nil
- case RdRelease(_) => if (Chalice.smokeAll) helper("rd release") else stmt :: Nil
- case Downgrade(_) => if (Chalice.smokeAll) helper("downgrade") else stmt :: Nil
- case Free(_) => if (Chalice.smokeAll) helper("free") else stmt :: Nil
- case Fold(_) => if (Chalice.smokeAll) helper("fold") else stmt :: Nil
- case CallAsync(_, _, _, _, _) => if (Chalice.smokeAll) helper("fork") else stmt :: Nil
- case Send(_, _) => if (Chalice.smokeAll) helper("send") else stmt :: Nil
- case _: Signal => if (Chalice.smokeAll) helper("signal") else stmt :: Nil
- case _: Wait => if (Chalice.smokeAll) helper("wait") else stmt :: Nil
- }
- (result, out)
- }
-
- /** Helper method to add a smoke assertion after a simple (non-compound)
- * statement.
- */
- def smokeSimpleStmt(stmt: Statement, in: Set[SmokeAssert], msg: String): (List[Statement], Set[SmokeAssert]) = {
- val smoke = initSmokeAssert(stmt.pos, "The statements after the " + msg + " statement are unreachable.", in)
- (stmt :: smoke.chaliceAssert :: Nil, Set(smoke))
- }
-
- /** Generate an "assert false" with a certain position and a certain error
- * message. Note: We generate "assert 1!=1" instead of "assert false", as
- * Boogie seems to perform some weird optimization for false, which does
- * not generate warnings for all failing assertions (even if the command
- * line switch /subsumption:0 is used).
- */
- def initSmokeAssert(pos: Position, error: String): SmokeAssert = initSmokeAssert(pos, error, Set(SmokeAssertSentinel))
- def initSmokeAssert(pos: Position, error: String, prev: Set[SmokeAssert]): SmokeAssert = {
- count += 1
- val i = IntLiteral(1); i.typ = IntClass
- val n = Neq(i, i); n.typ = BoolClass
- val assert = Assert(n)
- assert.smokeErrorNr = Some(count)
- assert.pos = pos
- val sm = SmokeAssert(count, pos, error, prev, assert)
- smokeAssertions += count -> sm
- sm
- }
-
- /** Copy the position of an old AST node to a new node (if not already
- * present).
- */
- private def copyPosition[A <: ASTNode](oldNode: A, newNode: A): A = {
- if (newNode.pos == NoPosition) newNode.pos = oldNode.pos
- newNode
- }
- /** Copy the position from one old AST node to multiple new nodes. */
- private def copyPosition[A <: ASTNode](oldNode: A, newNodes: List[A]): List[A] = {
- for (newNode <- newNodes) yield copyPosition(oldNode, newNode)
- }
-} \ No newline at end of file
diff --git a/Chalice/src/main/scala/Translator.scala b/Chalice/src/main/scala/Translator.scala
deleted file mode 100644
index 60163a1a..00000000
--- a/Chalice/src/main/scala/Translator.scala
+++ /dev/null
@@ -1,3616 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-package chalice;
-import scala.util.parsing.input.Position
-import scala.util.parsing.input.NoPosition
-
-import Boogie.Proc, Boogie.NamedType, Boogie.NewBVar, Boogie.Havoc, Boogie.Stmt, Boogie.Const,
- Boogie.Decl, Boogie.Expr, Boogie.FunctionApp, Boogie.Axiom, Boogie.BVar, Boogie.BType,
- Boogie.VarExpr, Boogie.IndexedType, Boogie.Comment, Boogie.MapUpdate, Boogie.MapSelect,
- Boogie.If, Boogie.Lambda, Boogie.Trigger;
-
-case class ErrorMessage(pos: Position, message: String)
-
-class Translator {
- import TranslationHelper._;
- var currentClass = null: Class;
- var modules = Nil: List[String]
- var etran = new ExpressionTranslator(null);
-
- def translateProgram(decls: List[TopLevelDecl]): List[Decl] = {
- decls flatMap {
- case cl: Class => translateClass(cl)
- case ch: Channel =>
- translateClass(ChannelClass(ch)) :::
- translateWhereClause(ch)
- /* TODO: waitlevel not allowed in postcondition of things forked (or, rather, joined) */
- }
- }
-
- def translateClass(cl: Class): List[Decl] = {
- currentClass = cl;
- etran = new ExpressionTranslator(cl);
- var declarations: List[Decl] = Nil;
- // add module (if no added yet)
- if(modules forall {mname => ! mname.equals(cl.module)}) {
- declarations = Const(ModuleName(cl), true, ModuleType) :: declarations;
- modules = cl.module :: modules;
- }
- // add class name
- declarations = Const(className(cl).id, true, TypeName) :: declarations;
- // translate monitor invariant
- declarations = declarations ::: translateMonitorInvariant(cl.MonitorInvariants, cl.pos);
- // translate each member
- for(member <- cl.members) {
- etran.fpi.reset
- declarations = declarations ::: translateMember(member);
- }
- declarations
- }
-
- /**********************************************************************
- ***************** MEMBERS *****************
- **********************************************************************/
-
- def translateMember(member: Member): List[Decl] = {
- member match {
- case f: Field =>
- translateField(f)
- case m: Method =>
- translateMethod(m)
- case f: Function =>
- translateFunction(f)
- case pred: Predicate =>
- translatePredicate(pred)
- case inv: MonitorInvariant =>
- Nil // already dealt with before
- case _: Condition =>
- throw new NotSupportedException("not yet implemented")
- case mt: MethodTransform =>
- translateMethodTransform(mt)
- case ci: CouplingInvariant =>
- Nil
- }
- }
-
- def translateWhereClause(ch: Channel): List[Decl] = {
-
- // pick new k
- val (whereKV, whereK) = Boogie.NewBVar("whereK", treal, true)
- val whereKStmts = BLocal(whereKV) :: bassume(0.0 < whereK && 1000.0*whereK < permissionOnePercent)
-
- // check definedness of where clause
- Proc(ch.channelId + "$whereClause$checkDefinedness",
- NewBVarWhere("this", new Type(currentClass)) :: (ch.parameters map {i => Variable2BVarWhere(i)}),
- Nil,
- GlobalNames,
- DefaultPrecondition(),
- whereKStmts :::
- DefinePreInitialState :::
- InhaleWithChecking(List(ch.where), "channel where clause", whereK) :::
- // smoke test: is the where clause equivalent to false?
- (if (Chalice.smoke) {
- val a = SmokeTest.initSmokeAssert(ch.pos, "Where clause of channel " + ch.channelId + " is equivalent to false.")
- translateStatement(a.chaliceAssert, whereK)
- } else Nil)
- )
- }
-
- def translateMonitorInvariant(invs: List[MonitorInvariant], pos: Position): List[Decl] = {
- val (h0V, h0) = NewBVar("h0", theap, true);
- val (m0V, m0) = NewBVar("m0", tmask, true);
- val (sm0V, sm0) = NewBVar("sm0", tmask, true);
- val (c0V, c0) = NewBVar("c0", tcredits, true);
- val (h1V, h1) = NewBVar("h1", theap, true);
- val (m1V, m1) = NewBVar("m1", tmask, true);
- val (sm1V, sm1) = NewBVar("sm1", tmask, true);
- val (c1V, c1) = NewBVar("c1", tcredits, true);
- val (lkV, lk) = NewBVar("lk", tref, true);
-
- // pick new k
- val (methodKV, methodK) = Boogie.NewBVar("methodK", treal, true)
- val methodKStmts = BLocal(methodKV) :: bassume(0.0 < methodK && 1000.0*methodK < permissionOnePercent)
-
- val oldTranslator = new ExpressionTranslator(Globals(h1, m1, sm1, c1), Globals(h0, m0, sm0, c0), currentClass);
- Proc(currentClass.id + "$monitorinvariant$checkDefinedness",
- List(NewBVarWhere("this", new Type(currentClass))),
- Nil,
- GlobalNames,
- DefaultPrecondition(),
- methodKStmts :::
- BLocal(h0V) :: BLocal(m0V) :: BLocal(sm0V) :: BLocal(c0V) :: BLocal(h1V) :: BLocal(m1V) :: BLocal(sm1V) :: BLocal(c1V) :: BLocal(lkV) ::
- bassume(wf(h0, m0, sm0)) :: bassume(wf(h1, m1, sm1)) ::
- resetState(oldTranslator) :::
- oldTranslator.Inhale(invs map { mi => mi.e}, "monitor invariant", false, methodK) :::
- resetState(etran) :::
- // check that invariant is well-defined
- etran.WhereOldIs(h1, m1, sm1, c1).Inhale(invs map { mi => mi.e}, "monitor invariant", true, methodK) :::
- // smoke test: is the monitor invariant equivalent to false?
- (if (Chalice.smoke) {
- val a = SmokeTest.initSmokeAssert(pos, "Monitor invariant is equivalent to false.")
- translateStatement(a.chaliceAssert, methodK)
- } else Nil) :::
- (if (! Chalice.checkLeaks || invs.length == 0) Nil else
- // check that there are no loops among .mu permissions in monitors
- // !CanWrite[this,mu]
- bassert(!etran.CanWrite(VarExpr("this"), "mu"), invs(0).pos, "Monitor invariant is not allowed to hold write permission to this.mu") ::
- // (forall lk :: lk != null && lk != this && CanRead[lk,mu] ==>
- // CanRead[this,mu] && Heap[this,mu] << Heap[lk,mu])
- bassert(
- (lk !=@ NullLiteral() && lk !=@ VarExpr("this") && etran.CanRead(lk, "mu")) ==>
- (etran.CanRead(VarExpr("this"), "mu") &&
- new FunctionApp("MuBelow", etran.Heap.select(VarExpr("this"), "mu"), etran.Heap.select(lk, "mu"))),
- invs(0).pos,
- "Monitor invariant can hold permission of other o.mu field only this.mu if this.mu<<o.mu")
- ) :::
- //check that invariant is reflexive
- etran.UseCurrentAsOld().Exhale(invs map {mi => (mi.e, ErrorMessage(mi.pos, "Monitor invariant might not be reflexive."))}, "invariant reflexive?", false, methodK, true) :::
- bassert(DebtCheck(), pos, "Monitor invariant is not allowed to contain debt.")
- )
- }
-
- def translateField(f: Field): List[Decl] = {
- Const(f.FullName, true, FieldType(f.typ.typ)) ::
- Axiom(NonPredicateField(f.FullName))
- }
-
- def translateFunction(f: Function): List[Decl] = {
- val myresult = BVar("result", f.out.typ);
- etran = etran.CheckTermination(! Chalice.skipTermination);
- val checkBody = f.definition match {case Some(e) => isDefined(e); case None => Nil};
- etran = etran.CheckTermination(false);
-
- // pick new k
- val (functionKV, functionK) = Boogie.NewBVar("functionK", treal, true)
- val functionKStmts = BLocal(functionKV) :: bassume(0.0 < functionK && 1000.0*functionK < permissionOnePercent)
-
- // Boogie function that represents the Chalice function
- {
- val bIns = if (f.isStatic) {
- BVar("heap", theap) :: (f.ins map Variable2BVar)
- } else {
- BVar("heap", theap) :: BVar("this", tref) :: (f.ins map Variable2BVar)
- }
- Boogie.Function(functionName(f), bIns, BVar("$myresult", f.out.typ))
- } ::
- // check definedness of the function's precondition and body
- Proc(f.FullName + "$checkDefinedness",
- {
- val insVar = f.ins map {i => Variable2BVarWhere(i)}
- if (!f.isStatic) {
- NewBVarWhere("this", new Type(currentClass)) :: insVar
- } else {
- insVar
- }
- },
- Nil,
- GlobalNames,
- DefaultPrecondition(f.isStatic),
- functionKStmts :::
- bassume(FunctionContextHeight ==@ f.height) ::
- DefinePreInitialState :::
- // check definedness of the precondition
- InhaleWithChecking(Preconditions(f.spec) map { p => (if(0 < Chalice.defaults) UnfoldPredicatesWithReceiverThis(p) else p)}, "precondition", functionK) :::
- bassume(CurrentModule ==@ VarExpr(ModuleName(currentClass))) :: // verify the body assuming that you are in the module
- // smoke test: is precondition equivalent to false?
- (if (Chalice.smoke) {
- val a = SmokeTest.initSmokeAssert(f.pos, "Precondition of function " + f.Id + " is equivalent to false.")
- translateStatement(a.chaliceAssert, functionK)
- } else Nil) :::
- // check definedness of function body
- checkBody :::
- (f.definition match {case Some(e) => BLocal(myresult) :: (Boogie.VarExpr("result") := etran.Tr(e)); case None => Nil}) :::
- // assume canCall for all recursive calls
- {
- var b: Expr = true
- f.definition match {
- case Some(e) => e transform {
- case app @ FunctionApplication(obj, id, args) if id == f.Id =>
- b = b && FunctionApp(functionName(f) + "#canCall", (obj :: args) map etran.Tr); None
- case _ => None
- }
- case _ =>
- }
- bassume(b) :: Nil
- } :::
- // check that postcondition holds
- ExhaleWithChecking(Postconditions(f.spec) map { post => ((if(0 < Chalice.defaults) UnfoldPredicatesWithReceiverThis(post) else post),
- ErrorMessage(f.pos, "Postcondition at " + post.pos + " might not hold."))}, "function postcondition", functionK, true)) ::
- // definition axiom
- (f.definition match {
- case Some(definition) => definitionAxiom(f, definition);
- case None => Nil
- }) :::
- // framing axiom (+ frame function)
- framingAxiom(f) :::
- // postcondition axiom(s)
- postconditionAxiom(f)
- }
-
- def definitionAxiom(f: Function, definition: Expression): List[Decl] = {
- val inArgs = (f.ins map {i => Boogie.VarExpr(i.UniqueName)})
- val thisArg = VarExpr("this")
- val args = if (f.isStatic) inArgs else thisArg :: inArgs;
-
- /////
-
- val formalsNoHeapNoMask = if (f.isStatic) {
- (f.ins map Variable2BVar)
- } else {
- BVar("this", tref) :: (f.ins map Variable2BVar)
- }
-
- val formalsNoMask = BVar(HeapName, theap) :: formalsNoHeapNoMask
- val formals = BVar(MaskName, tmask) :: BVar(SecMaskName, tmask) :: formalsNoMask
- val applyF = FunctionApp(functionName(f), List(etran.Heap) ::: args);
- val limitedApplyF = FunctionApp(functionName(f) + "#limited", List(etran.Heap) ::: args)
- /////
- val limitedFTrigger = FunctionApp(functionName(f) + "#limited#trigger", args)
-
- val pre = Preconditions(f.spec).foldLeft(BoolLiteral(true): Expression)({ (a, b) => And(a, b) });
- val wellformed = wf(VarExpr(HeapName), VarExpr(MaskName), VarExpr(SecMaskName))
- val triggers = f.dependentPredicates map (p => new Trigger(List(limitedApplyF, wellformed, FunctionApp("#" + p.FullName+"#trigger", thisArg :: Nil))))
- /////
- val newTriggers = new Trigger(List(limitedFTrigger, wellformed) ::: (f.dependentPredicates map (p => FunctionApp("#" + p.FullName+"#trigger", thisArg :: Nil))))
-
- /** Limit application of the function by introducing a second (limited) function */
- val body = etran.Tr(
- if (true) { // used to be: if (f.isRecursive && ! f.isUnlimited) ... but now we treat all functions uniformly
- val limited = Map() ++ (f.SCC zip (f.SCC map {f =>
- val result = Function(f.id + "#limited", f.ins, f.out, f.spec, None);
- result.isStatic = f.isStatic
- result.Parent = f.Parent;
- result;
- }));
- def limit: Expression => Option[Expression] = _ match {
- case app @ FunctionApplication(obj, id, args) if (f.SCC contains app.f) =>
- val result = FunctionApplication(obj transform limit, id, args map (e => e transform limit));
- result.f = limited(app.f);
- Some(result)
- case _ => None
- }
- definition transform limit;
- } else {
- definition
- }
- );
-
- Boogie.Function(functionName(f) + "#canCall", formalsNoHeapNoMask, BVar("$myresult", tbool)) ::
- /* axiom (forall h: HeapType, m, sm: MaskType, this: ref, x_1: t_1, ..., x_n: t_n ::
- wf(h, m, sm) && CurrentModule == module#C ==> #C.f(h, m, this, x_1, ..., x_n) == tr(body))
- */
- Axiom(new Boogie.Forall(Nil,
- formals, newTriggers :: List(new Trigger(List(applyF,wellformed))) ,
- (wellformed && (CurrentModule ==@ ModuleName(currentClass)) && etran.TrAll(pre))
- ==>
- (applyF ==@ body))) ::
- (if (true)
- // used to be: (if (f.isRecursive) ... but now we treat all functions uniformly
- // define the limited function (even for unlimited function since its SCC might have limited functions)
- Boogie.Function(functionName(f) + "#limited", formalsNoMask, BVar("$myresult", f.out.typ)) ::
- Axiom(new Boogie.Forall(Nil, formals,
- new Trigger(List(applyF,wellformed)) :: Nil,
- // new Trigger(List(applyF,wellformed)) :: triggers, // commented, as secondary patterns seem not to be working
- (wellformed ==> (applyF ==@ limitedApplyF)))) ::
- Boogie.Function(functionName(f) + "#limited#trigger", formalsNoHeapNoMask, BVar("$myresult", tbool)) ::
- Axiom(new Boogie.Forall(Nil, formals,
- List(new Trigger(List(limitedApplyF,wellformed))),
- (wellformed ==> limitedFTrigger))) ::
- Nil ///// above
- else
- Nil)
- }
-
- def framingAxiom(f: Function): List[Decl] = {
- val pre = Preconditions(f.spec).foldLeft(BoolLiteral(true): Expression)({ (a, b) => And(a, b) });
- var hasAccessSeq = false;
- pre visit {_ match {case _: AccessSeq => hasAccessSeq = true; case _ => }}
-
- if (!hasAccessSeq) {
- // Encoding with heapFragment and combine
- /* function ##C.f(state, ref, t_1, ..., t_n) returns (t);
- axiom (forall h: HeapType, m, sm: MaskType, this: ref, x_1: t_1, ..., x_n: t_n ::
- wf(h, m, sm) ==> #C.f(h, m, sm, this, x_1, ..., x_n) == ##C.f(partialHeap, this, x_1, ..., x_n))
- */
- val partialHeap = functionDependencies(pre, etran);
- val inArgs = (f.ins map {i => Boogie.VarExpr(i.UniqueName)});
- val frameFunctionName = "#" + functionName(f);
-
- val args = if (!f.isStatic) VarExpr("this") :: inArgs else inArgs;
- val applyF = FunctionApp(functionName(f) + (if (f.isRecursive) "#limited" else ""), List(etran.Heap) ::: args);
- val applyFrameFunction = FunctionApp(frameFunctionName, partialHeap :: args)
- val wellformed = wf(VarExpr(HeapName), VarExpr(MaskName), VarExpr(SecMaskName))
-
- if (!f.isStatic) (
- Boogie.Function(frameFunctionName, Boogie.BVar("state", tpartialheap) :: Boogie.BVar("this", tref) :: (f.ins map Variable2BVar), new BVar("$myresult", f.out.typ)) ::
- Axiom(new Boogie.Forall(
- BVar(HeapName, theap) :: BVar(MaskName, tmask) :: BVar(SecMaskName, tmask) :: BVar("this", tref) :: (f.ins map Variable2BVar),
- new Trigger(List(applyF, wellformed)),
- (wellformed)
- ==>
- (applyF ==@ applyFrameFunction))
- )
- ) else (
- Boogie.Function(frameFunctionName, Boogie.BVar("state", tpartialheap) :: (f.ins map Variable2BVar), new BVar("$myresult", f.out.typ)) ::
- Axiom(new Boogie.Forall(
- BVar(HeapName, theap) :: BVar(MaskName, tmask) :: BVar(SecMaskName, tmask) :: (f.ins map Variable2BVar),
- new Trigger(List(applyF, wellformed)),
- (wellformed)
- ==>
- (applyF ==@ applyFrameFunction))
- )
- )
- } else {
- // Encoding with universal quantification over two heaps
- /* axiom (forall h1, h2: HeapType, m1, m2, sm1, sm2: MaskType, this: ref, x_1: t_1, ..., x_n: t_n ::
- wf(h1,m1,sm1) && wf(h2,m2,sm1) && functionDependenciesEqual(h1, h2, #C.f) ==>
- #C.f(h1, m1, sm1, this, x_1, ..., x_n) == #C.f(h2, m2, sm2, this, x_1, ..., x_n)
- */
- var args = if (!f.isStatic) VarExpr("this") :: (f.ins map {i => Boogie.VarExpr(i.UniqueName)})
- else (f.ins map {i => Boogie.VarExpr(i.UniqueName)})
-
- // create two heaps
- val (globals1V, globals1) = etran.FreshGlobals("a"); val etran1 = new ExpressionTranslator(globals1, currentClass);
- val (globals2V, globals2) = etran.FreshGlobals("b"); val etran2 = new ExpressionTranslator(globals2, currentClass);
- val List(heap1, mask1, secmask1, _) = globals1V;
- val List(heap2, mask2, secmask2, _) = globals2V;
- val apply1 = FunctionApp(functionName(f), etran1.Heap :: args)
- val apply2 = FunctionApp(functionName(f), etran2.Heap :: args)
- val wellformed1 = wf(etran1.Heap, etran1.Mask, etran1.SecMask)
- val wellformed2 = wf(etran2.Heap, etran2.Mask, etran2.SecMask)
-
- if (!f.isStatic) (
- Axiom(new Boogie.Forall(
- heap1 :: heap2 :: mask1 :: mask2 :: secmask1 :: secmask2 :: BVar("this", tref) :: (f.ins map Variable2BVar),
- new Trigger(List(apply1, apply2, wellformed1, wellformed2)),
- (wellformed1 && wellformed2 && functionDependenciesEqual(pre, etran1, etran2))
- ==>
- (apply1 ==@ apply2)
- ))
- ) else (
- Axiom(new Boogie.Forall(
- heap1 :: heap2 :: mask1 :: mask2 :: secmask1 :: secmask2 :: (f.ins map Variable2BVar),
- new Trigger(List(apply1, apply2, wellformed1, wellformed2)),
- (wellformed1 && wellformed2 && functionDependenciesEqual(pre, etran1, etran2))
- ==>
- (apply1 ==@ apply2)
- ))
- )
- }
- }
-
- def postconditionAxiom(f: Function): List[Decl] = {
- /* axiom (forall h: HeapType, m, sm: MaskType, this: ref, x_1: t_1, ..., x_n: t_n ::
- wf(h, m, sm) && (CanAssumeFunctionDefs || f.height < FunctionContextHeight) ==> Q[#C.f(h, m, this, x_1, ..., x_n)/result]
- */
- val inArgs = (f.ins map {i => Boogie.VarExpr(i.UniqueName)});
- val myresult = Boogie.BVar("result", f.out.typ);
- val args = VarExpr("this") :: inArgs;
- val applyFLimited = FunctionApp(functionName(f)+"#limited", List(VarExpr(HeapName)) ::: args)
- val canCall = FunctionApp(functionName(f) + "#canCall", args)
- val wellformed = wf(VarExpr(HeapName), VarExpr(MaskName), VarExpr(SecMaskName))
-
- //postcondition axioms
- (Postconditions(f.spec) map { post : Expression =>
- Axiom(new Boogie.Forall(
- BVar(HeapName, theap) :: BVar(MaskName, tmask) :: BVar(SecMaskName, tmask) :: BVar("this", tref) :: (f.ins map Variable2BVar),
- new Trigger(List(applyFLimited, wellformed)),
- (wellformed && (CanAssumeFunctionDefs || f.height < FunctionContextHeight || canCall))
- ==>
- etran.Tr(SubstResult(post, f.apply(ExplicitThisExpr(), f.ins map { arg => new VariableExpr(arg) })))
- ))
- })
- }
-
- def translatePredicate(pred: Predicate): List[Decl] = {
-
- // pick new k
- val (predicateKV, predicateK) = Boogie.NewBVar("predicateK", treal, true)
- val predicateKStmts = BLocal(predicateKV) :: bassume(0.0 < predicateK && 1000.0*predicateK < permissionOnePercent)
-
- // const unique class.name: HeapType;
- Const(pred.FullName, true, FieldType(tint)) ::
- Const(pred.FullName+"#m", true, FieldType(tpmask)) ::
- Axiom(PredicateField(pred.FullName)) ::
- // axiom PredicateField(f);
- Axiom(FunctionApp("predicateMaskField", List(VarExpr(pred.FullName))) ==@ VarExpr(pred.FullName + "#m")) ::
- // trigger function to unfold function definitions
- Boogie.Function("#" + pred.FullName + "#trigger", BVar("this", tref) :: Nil, BVar("$myresult", tbool)) ::
- // check definedness of predicate body
- Proc(pred.FullName + "$checkDefinedness",
- List(NewBVarWhere("this", new Type(currentClass))),
- Nil,
- GlobalNames,
- DefaultPrecondition(),
- predicateKStmts :::
- DefinePreInitialState :::
- InhaleWithChecking(List(DefinitionOf(pred)), "predicate definition", predicateK) :::
- // smoke test: is the predicate equivalent to false?
- (if (Chalice.smoke) {
- val a = SmokeTest.initSmokeAssert(pred.pos, "Predicate " + pred.FullName + " is equivalent to false.")
- translateStatement(a.chaliceAssert, predicateK)
- } else Nil)
- )
- }
-
- def translateMethod(method: Method): List[Decl] = {
-
- // pick new k for this method, that represents the fraction for read permissions
- val (methodKV, methodK) = Boogie.NewBVar("methodK", treal, true)
- val methodKStmts = BLocal(methodKV) :: bassume(0.0 < methodK && 1000.0*methodK < permissionOnePercent)
-
- // check definedness of the method contract
- Proc(method.FullName + "$checkDefinedness",
- NewBVarWhere("this", new Type(currentClass)) :: (method.ins map {i => Variable2BVarWhere(i)}),
- method.outs map {i => Variable2BVarWhere(i)},
- GlobalNames,
- DefaultPrecondition(),
- methodKStmts :::
- DefinePreInitialState :::
- bassume(CanAssumeFunctionDefs) ::
- // check precondition
- InhaleWithChecking(Preconditions(method.spec), "precondition", methodK) :::
- DefineInitialState :::
- resetState(etran) :::
- // check postcondition
- InhaleWithChecking(Postconditions(method.spec), "postcondition", methodK) :::
- // check lockchange
- (LockChanges(method.spec) flatMap { lc => isDefined(lc)})) ::
- {
- etran.fpi.reset
- // check that method body satisfies the method contract
- Proc(method.FullName,
- NewBVarWhere("this", new Type(currentClass)) :: (method.ins map {i => Variable2BVarWhere(i)}),
- method.outs map {i => Variable2BVarWhere(i)},
- GlobalNames,
- DefaultPrecondition(),
- methodKStmts :::
- bassume(CurrentModule ==@ Boogie.VarExpr(ModuleName(currentClass))) ::
- bassume(CanAssumeFunctionDefs) ::
- DefinePreInitialState :::
- Inhale(Preconditions(method.spec) map { p => (if(0 < Chalice.defaults) UnfoldPredicatesWithReceiverThis(p) else p)}, "precondition", methodK) :::
- DefineInitialState :::
- translateStatements(method.body, methodK) :::
- Exhale(Postconditions(method.spec) map { p => ((if(0 < Chalice.defaults) UnfoldPredicatesWithReceiverThis(p) else p), ErrorMessage(method.pos, "The postcondition at " + p.pos + " might not hold."))}, "postcondition", methodK, true) :::
- (if(Chalice.checkLeaks) isLeaking(method.pos, "Method " + method.FullName + " might leak references.") else Nil) :::
- bassert(LockFrame(LockChanges(method.spec), etran), method.pos, "Method might lock/unlock more than allowed.") :::
- bassert(DebtCheck, method.pos, "Method body is not allowed to leave any debt."))
- }
- }
-
- def translateMethodTransform(mt: MethodTransform): List[Decl] = {
- // extract coupling invariants from the class pool of invariants
- val pool = mt.Parent.CouplingInvariants
-
- def extractInv(e: Expression): Expression = desugar(e) match {
- case And(a,b) => And(extractInv(a), extractInv(b))
- case Implies(a,b) => Implies(a, extractInv(b))
- case Access(ma, Full) if ! ma.isPredicate =>
- {for (ci <- pool;
- if (ci.fields.contains(ma.f)))
- yield scaleExpressionByPermission(ci.e, ci.fraction(ma.f), ma.pos)}.foldLeft(BoolLiteral(true):Expression)(And(_,_))
- case _: PermissionExpr => throw new NotSupportedException("not supported")
- case _ => BoolLiteral(true)
- }
-
- val preCI = Preconditions(mt.Spec).map(extractInv)
- val postCI = Postconditions(mt.refines.Spec).map(extractInv)
-
- // pick new k for this method, that represents the fraction for read permissions
- val (methodKV, methodK) = Boogie.NewBVar("methodK", treal, true)
- val methodKStmts = BLocal(methodKV) :: bassume(0.0 < methodK && 1000.0*methodK < permissionOnePercent)
-
- // check definedness of refinement specifications
- Proc(mt.FullName + "$checkDefinedness",
- NewBVarWhere("this", new Type(currentClass)) :: (mt.Ins map {i => Variable2BVarWhere(i)}),
- mt.Outs map {i => Variable2BVarWhere(i)},
- GlobalNames,
- DefaultPrecondition(),
- methodKStmts :::
- DefinePreInitialState :::
- bassume(CanAssumeFunctionDefs) ::
- // check precondition
- InhaleWithChecking(Preconditions(mt.Spec) ::: preCI, "precondition", methodK) :::
- DefineInitialState :::
- resetState(etran) :::
- // check postcondition
- InhaleWithChecking(Postconditions(mt.refines.Spec), "postcondition", methodK) :::
- tag(InhaleWithChecking(postCI ::: Postconditions(mt.spec), "postcondition", methodK), keepTag)
- ) ::
- // check correctness of refinement
- Proc(mt.FullName,
- NewBVarWhere("this", new Type(currentClass)) :: (mt.Ins map {i => Variable2BVarWhere(i)}),
- mt.Outs map {i => Variable2BVarWhere(i)},
- GlobalNames,
- DefaultPrecondition(),
- methodKStmts :::
- assert2assume {
- bassume(CurrentModule ==@ Boogie.VarExpr(ModuleName(currentClass))) ::
- bassume(CanAssumeFunctionDefs) ::
- DefinePreInitialState :::
- Inhale(Preconditions(mt.Spec) ::: preCI, "precondition", methodK) :::
- DefineInitialState :::
- translateStatements(mt.body, methodK) :::
- Exhale(Postconditions(mt.refines.Spec) map {p => (p, ErrorMessage(p.pos, "The postcondition at " + p.pos + " might not hold."))}, "postcondition", methodK, true) :::
- tag(Exhale(
- (postCI map {p => (p, ErrorMessage(mt.pos, "The coupling invariant might not be preserved."))}) :::
- (Postconditions(mt.spec) map {p => (p, ErrorMessage(p.pos, "The postcondition at " + p.pos + " might not hold."))}), "postcondition", methodK, true), keepTag)
- }
- )
-
- }
-
- def DebtCheck() = {
- // (forall ch :: ch == null || 0 <= Credits[ch])
- val (chV, ch) = NewBVar("ch", tref, false)
- new Boogie.Forall(chV, (ch ==@ bnull) || (0 <= new MapSelect(etran.Credits, ch)))
- }
-
- def DefaultPrecondition(isStatic: Boolean = false) = {
- if (!isStatic) {
- "requires this!=null;" ::
- "free requires wf(Heap, Mask, SecMask);" :: Nil
- } else {
- "free requires wf(Heap, Mask, SecMask);" :: Nil
- }
- }
-
- def DefinePreInitialState = {
- Comment("define pre-initial state") ::
- (etran.Mask := ZeroMask) :: (etran.SecMask := ZeroMask) :: (etran.Credits := ZeroCredits)
- }
- def DefineInitialState = {
- val (refV, ref) = Boogie.NewBVar("ref", tref, true)
- val (pmaskV, pmask) = Boogie.NewBVar("pmask", FieldType(tpmask), true)
- Comment("define initial state") ::
- bassume(etran.Heap ==@ Boogie.Old(etran.Heap)) ::
- bassume(etran.Mask ==@ Boogie.Old(etran.Mask)) ::
- bassume(etran.SecMask ==@ Boogie.Old(etran.SecMask)) ::
- bassume(etran.Credits ==@ Boogie.Old(etran.Credits)) ::
- bassume((etran.Heap.select(ref, pmask.id) ==@ ZeroPMask).forall(refV).forall(pmaskV))
- }
-
- /**********************************************************************
- ***************** STATEMENTS *****************
- **********************************************************************/
- def translateStatements(statements: List[Statement], methodK: Expr): List[Stmt] = statements flatMap (v => translateStatement(v, methodK))
-
- def translateStatement(s: Statement, methodK: Expr): List[Stmt] = {
- s match {
- case a@Assert(e) =>
- a.smokeErrorNr match {
- case None =>
- val (tmpGlobalsV, tmpGlobals) = etran.FreshGlobals("assert");
- val tmpTranslator = new ExpressionTranslator(tmpGlobals, etran.oldEtran.globals, currentClass);
- Comment("assert") ::
- // exhale e in a copy of the heap/mask/credits
- BLocals(tmpGlobalsV) :::
- copyState(tmpGlobals, etran) :::
- tmpTranslator.Exhale(List((e, ErrorMessage(s.pos, "Assertion might not hold."))), "assert", true, methodK, true)
- case Some(err) =>
- bassert(e, a.pos, "SMOKE-TEST-" + err + ". ("+SmokeTest.smokeWarningMessage(err)+")", 0) :: Nil
- }
- case Assume(e) =>
- Comment("assume") ::
- isDefined(e) :::
- bassume(e)
- case BlockStmt(ss) =>
- translateStatements(ss, methodK)
- case IfStmt(guard, then, els) =>
- val (condV, cond) = Boogie.NewBVar("cond", tbool, true)
- val oldConditions = etran.fpi.currentConditions
- etran.fpi.currentConditions += ((cond, true))
- val tt = translateStatement(then, methodK)
- val et = els match {
- case None => Nil
- case Some(els) =>
- etran.fpi.currentConditions = oldConditions
- etran.fpi.currentConditions += ((cond, false))
- translateStatement(els, methodK)
- }
- Comment("if") ::
- BLocal(condV) ::
- (cond := etran.Tr(guard)) ::
- isDefined(guard) :::
- Boogie.If(cond, tt, et)
- case w: WhileStmt =>
- translateWhile(w, methodK)
- case Assign(lhs, rhs) =>
- def assignOrAssumeEqual(r: Boogie.Expr): List[Boogie.Stmt] = {
- if (lhs.v.isImmutable) {
- // this must be a "ghost const"
- val name = lhs.v.UniqueName
- bassert(! VarExpr("assigned$" + name), lhs.pos, "Const variable can be assigned to only once.") ::
- bassume(lhs ==@ r) ::
- (VarExpr("assigned$" + name) := true)
- } else {
- lhs := r
- }
- }
- Comment("assigment to " + lhs.id) ::
- (rhs match {
- case rhs@NewRhs(c, initialization, lower, upper) => // x := new C;
- val (nw, ss) = translateAllocation(rhs.typ, initialization, lower, upper, rhs.pos);
- ss ::: assignOrAssumeEqual(new VarExpr(nw))
- case rhs: Expression => // x := E;
- isDefined(rhs) ::: assignOrAssumeEqual(rhs)
- })
- case FieldUpdate(lhs@MemberAccess(target, f), rhs) =>
- val (statements, toStore : Expr) =
- (rhs match {
- case rhs @ NewRhs(c, initialization, lower, upper) =>
- // e.f := new C;
- val (nw,ss) = translateAllocation(rhs.typ, initialization, lower, upper, rhs.pos)
- (ss, new VarExpr(nw))
- case rhs : Expression =>
- // e.f := E;
- (isDefined(rhs), TrExpr(rhs))
- });
- Comment("update field " + f) ::
- isDefined(target) :::
- bassert(CanWrite(target, lhs.f), s.pos, "Location might not be writable") ::
- statements ::: etran.Heap.store(target, lhs.f, toStore) :: bassume(wf(VarExpr(HeapName), VarExpr(MaskName), VarExpr(SecMaskName)))
- case lv : LocalVar =>
- translateLocalVarDecl(lv.v, false) :::
- { lv.rhs match {
- //update the local, provided a rhs was provided
- case None => Nil
- case Some(rhs) => translateStatement(Assign(new VariableExpr(lv.v), rhs), methodK) }}
- case s: SpecStmt => translateSpecStmt(s, methodK)
- case c: Call => translateCall(c, methodK)
- case Install(obj, lowerBounds, upperBounds) =>
- Comment("install") ::
- isDefined(obj) :::
- bassert(nonNull(obj), s.pos, "The target of the install statement might be null.") ::
- bassert(isHeld(obj), s.pos, "The lock of the target of the install statement might not be held.") ::
- // assert CanWrite(obj.mu); assume lowerbounds < obj.mu < upperBounds;
- UpdateMu(obj, false, false, lowerBounds, upperBounds, ErrorMessage(s.pos, "Install might fail."))
- case Share(obj, lowerBounds, upperBounds) =>
- val (preShareMaskV, preShareMask) = Boogie.NewBVar("preShareMask", tmask, true)
- Comment("share") ::
- // remember the mask immediately before the share
- BLocal(preShareMaskV) :: Boogie.Assign(preShareMask, etran.Mask) ::
- isDefined(obj) :::
- bassert(nonNull(obj), s.pos, "The target of the share statement might be null.") ::
- UpdateMu(obj, true, false, lowerBounds, upperBounds, ErrorMessage(s.pos, "Share might fail.")) :::
- bassume(!isHeld(obj) && ! isRdHeld(obj)) :: // follows from o.mu==lockbottom
- // assume a seen state is the one right before the share
- bassume(LastSeenHeap(etran.Heap.select(obj, "mu"), etran.Heap.select(obj, "held")) ==@ etran.Heap) ::
- bassume(LastSeenMask(etran.Heap.select(obj, "mu"), etran.Heap.select(obj, "held")) ==@ preShareMask) ::
- bassume(LastSeenCredits(etran.Heap.select(obj, "mu"), etran.Heap.select(obj, "held")) ==@ etran.Credits) ::
- // exhale the monitor invariant (using the current state as the old state)
- ExhaleInvariants(obj, false, ErrorMessage(s.pos, "Monitor invariant might not hold."), etran.UseCurrentAsOld(), methodK)
- case Unshare(obj) =>
- val (heldV, held) = Boogie.NewBVar("held", Boogie.NamedType("int"), true)
- val o = TrExpr(obj)
- Comment("unshare") ::
- isDefined(obj) :::
- bassert(nonNull(o), s.pos, "The target of the unshare statement might be null.") ::
- bassert(CanWrite(o, "mu"), s.pos, "The mu field of the target of the unshare statement might not be writable.") ::
- bassert(isShared(o), s.pos, "The target of the unshare statement might not be shared.") ::
- bassert(isHeld(o), s.pos, "The target of the unshare statement might not be locked by the current thread.") :: // locked or read-locked
- etran.Heap.store(o, "mu", bLockBottom) ::
- // havoc o.held where 0<=o.held
- BLocal(heldV) :: Boogie.Havoc(held) :: bassume(held <= 0) ::
- etran.Heap.store(o, "held", held) ::
- // set o.rdheld to false
- etran.Heap.store(o, "rdheld", false)
- case Acquire(obj) =>
- Comment("acquire") ::
- isDefined(obj) :::
- bassert(nonNull(TrExpr(obj)), s.pos, "The target of the acquire statement might be null.") ::
- TrAcquire(s, obj, methodK)
- case Release(obj) =>
- Comment("release") ::
- isDefined(obj) :::
- bassert(nonNull(TrExpr(obj)), s.pos, "The target of the release statement might be null.") ::
- TrRelease(s, obj, methodK)
- case Lock(e, body, readonly) =>
- val objV = new Variable("lock", new Type(e.typ))
- val obj = new VariableExpr(objV)
- val sname = if (readonly) "rd lock" else "lock"
- val o = TrExpr(obj)
- Comment(sname) ::
- isDefined(e) :::
- BLocal(Variable2BVar(objV)) :: (o := TrExpr(e)) ::
- bassert(nonNull(o), s.pos, "The target of the " + sname + " statement might be null.") ::
- { if (readonly) {
- TrRdAcquire(s, obj, methodK) :::
- translateStatement(body, methodK) :::
- TrRdRelease(s, obj, methodK)
- } else {
- TrAcquire(s, obj, methodK) :::
- translateStatement(body, methodK) :::
- TrRelease(s, obj, methodK)
- }
- }
- case RdAcquire(obj) =>
- Comment("rd acquire") ::
- isDefined(obj) :::
- bassert(nonNull(TrExpr(obj)), s.pos, "The target of the read-acquire statement might be null.") ::
- TrRdAcquire(s, obj, methodK)
- case rdrelease@RdRelease(obj) =>
- Comment("rd release") ::
- isDefined(obj) :::
- bassert(nonNull(TrExpr(obj)), obj.pos, "The target of the read-release statement might be null.") ::
- TrRdRelease(s, obj, methodK)
- case downgrade@Downgrade(obj) =>
- val o = TrExpr(obj);
- val prevHeapV = new Boogie.BVar("prevHeap", theap, true)
- Comment("downgrade") ::
- isDefined(obj) :::
- bassert(nonNull(o), s.pos, "The target of the downgrade statement might be null.") ::
- bassert(isHeld(o), s.pos, "The lock of the target of the downgrade statement might not be held by the current thread.") ::
- bassert(! isRdHeld(o), s.pos, "The current thread might hold the read lock.") ::
- ExhaleInvariants(obj, false, ErrorMessage(downgrade.pos, "Monitor invariant might not hold."), methodK) :::
- BLocal(prevHeapV) ::
- InhaleInvariants(obj, true, methodK) :::
- bassume(etran.Heap ==@ new Boogie.VarExpr(prevHeapV)) ::
- etran.Heap.store(o, "rdheld", true)
- case Free(obj) =>
- val o = TrExpr(obj);
- isDefined(obj) :::
- bassert(nonNull(o), s.pos, "The target of the free statement might be null.") ::
- (for (f <- obj.typ.Fields ++ RootClass.MentionableFields) yield
- bassert(CanWrite(o, f.FullName), s.pos, "The field " + f.id + " of the target of the free statement might not be writable.")) :::
- (for (f <- obj.typ.Fields ++ RootClass.MentionableFields) yield
- etran.SetNoPermission(o, f.FullName, etran.Mask))
- // probably need to havoc all the fields! Do we check enough?
- case fold@Fold(acc@Access(pred@MemberAccess(e, f), perm)) =>
- val o = TrExpr(e);
- var definition = scaleExpressionByPermission(SubstThis(DefinitionOf(pred.predicate), e), perm, fold.pos)
- val (receiverV, receiver) = Boogie.NewBVar("predRec", tref, true)
- val (versionV, version) = Boogie.NewBVar("predVer", tint, true)
- val (flagV, flag) = Boogie.NewBVar("predFlag", tbool, true)
-
- // pick new k
- val (foldKV, foldK) = Boogie.NewBVar("foldK", treal, true)
- val stmts = Comment("fold") ::
- functionTrigger(o, pred.predicate) ::
- BLocal(foldKV) :: bassume(0.0 < foldK && 1000.0*foldK < percentPermission(1) && 1000.0*foldK < methodK) ::
- isDefined(e) :::
- isDefined(perm) :::
- bassert(nonNull(o), s.pos, "The target of the fold statement might be null.") ::
- // remove the definition from the current state, and replace by predicate itself
- BLocal(receiverV) :: (receiver := o) ::
- BLocal(versionV) :: (version := etran.Heap.select(o, pred.predicate.FullName)) ::
- BLocal(flagV) :: (flag := true) ::
- etran.ExhaleAndTransferToSecMask(o, pred.predicate, List((definition, ErrorMessage(s.pos, "Fold might fail because the definition of " + pred.predicate.FullName + " does not hold."))), "fold", foldK, false, receiver, pred.predicate.FullName, version) :::
- Inhale(List(acc), "fold", foldK) :::
- etran.keepFoldedLocations(definition, o, pred.predicate, etran.Mask, etran.Heap, etran.fpi.getFoldedPredicates(pred.predicate)) :::
- bassume(wf(etran.Heap, etran.Mask, etran.SecMask))
-
- // record folded predicate
- etran.fpi.addFoldedPredicate(FoldedPredicate(pred.predicate, receiver, version, etran.fpi.currentConditions, flag))
-
- stmts
- case unfld@Unfold(acc@Access(pred@MemberAccess(e, f), perm:Permission)) =>
- val o = TrExpr(e);
- val definition = scaleExpressionByPermission(SubstThis(DefinitionOf(pred.predicate), e), perm, unfld.pos)
-
- // pick new k
- val (unfoldKV, unfoldK) = Boogie.NewBVar("unfoldK", treal, true)
- // record version of unfolded instance
- val (receiverV, receiver) = Boogie.NewBVar("predRec", tref, true)
- val (versionV, version) = Boogie.NewBVar("predVer", tint, true)
- Comment("unfold") ::
- functionTrigger(o, pred.predicate) ::
- BLocal(receiverV) :: (receiver := o) ::
- BLocal(versionV) :: (version := etran.Heap.select(o, pred.predicate.FullName)) ::
- BLocal(unfoldKV) :: bassume(0.0 < unfoldK && unfoldK < percentPermission(1) && 1000.0*unfoldK < methodK) ::
- isDefined(e) :::
- bassert(nonNull(o), s.pos, "The target of the fold statement might be null.") ::
- isDefined(perm) :::
- ExhaleDuringUnfold(List((acc, ErrorMessage(s.pos, "unfold might fail because the predicate " + pred.predicate.FullName + " does not hold."))), "unfold", unfoldK, false) :::
- etran.Inhale(List(definition), "unfold", false, unfoldK, receiver, pred.predicate.FullName, version)
- case c@CallAsync(declaresLocal, token, obj, id, args) =>
- val formalThisV = new Variable("this", new Type(c.m.Parent))
- val formalThis = new VariableExpr(formalThisV)
- val formalInsV = for (p <- c.m.ins) yield new Variable(p.id, p.t)
- val formalIns = for (v <- formalInsV) yield new VariableExpr(v)
-
- val (tokenV,tokenId) = NewBVar("token", tref, true)
- val (asyncStateV,asyncState) = NewBVar("asyncstate", tint, true)
- val (preCallHeapV, preCallHeap) = NewBVar("preCallHeap", theap, true)
- val (preCallMaskV, preCallMask) = NewBVar("preCallMask", tmask, true)
- val (preCallSecMaskV, preCallSecMask) = NewBVar("preCallSecMask", tmask, true)
- val (preCallCreditsV, preCallCredits) = NewBVar("preCallCredits", tcredits, true)
- val (argsSeqV, argsSeq) = NewBVar("argsSeq", tArgSeq, true)
- val argsSeqLength = 1 + args.length;
-
- // pick new k for this fork
- val (asyncMethodCallKV, asyncMethodCallK) = Boogie.NewBVar("asyncMethodCallK", treal, true)
- BLocal(asyncMethodCallKV) ::
- bassume(0.0 < asyncMethodCallK && 1000.0*asyncMethodCallK < percentPermission(1) && 1000.0*asyncMethodCallK < methodK) ::
- Comment("call " + id) ::
- // declare the local variable, if needed
- { if (c.local == null)
- List[Stmt]()
- else
- List(BLocal(Variable2BVarWhere(c.local))) } :::
- // remember the value of the heap/mask/credits
- BLocal(preCallHeapV) :: (preCallHeap := etran.Heap) ::
- BLocal(preCallMaskV) :: (preCallMask := etran.Mask) ::
- BLocal(preCallSecMaskV) :: (preCallSecMask := etran.SecMask) ::
- BLocal(preCallCreditsV) :: (preCallCredits := etran.Credits) ::
- BLocal(argsSeqV) ::
- // introduce formal parameters and pre-state globals
- (for (v <- formalThisV :: formalInsV) yield BLocal(Variable2BVarWhere(v))) :::
- // check definedness of arguments
- isDefined(obj) :::
- bassert(nonNull(obj), c.pos, "The target of the method call might be null.") ::
- (args flatMap { e: Expression => isDefined(e)}) :::
- // assign actual ins to formal ins
- (formalThis := obj) ::
- (for ((v,e) <- formalIns zip args) yield (v := e)) :::
- // insert all arguments in the argument sequence
- Boogie.AssignMap(argsSeq, 0, formalThis) ::
- { var i = 1
- for (v <- formalIns) yield { val r = Boogie.AssignMap(argsSeq, i, v); i += 1; r }
- } :::
- // exhale preconditions
- Exhale(Preconditions(c.m.spec) map
- (p => SubstVars(p, formalThis, c.m.ins, formalIns)) zip (Preconditions(c.m.spec) map { p => ErrorMessage(c.pos, "The precondition at " + p.pos + " might not hold.")}), "precondition", asyncMethodCallK, false) :::
- // create a new token
- BLocal(tokenV) :: Havoc(tokenId) :: bassume(nonNull(tokenId)) ::
- // the following assumes help in proving that the token is fresh
- bassume(etran.Heap.select(tokenId, "joinable") ==@ 0) ::
- bassume(new Boogie.MapSelect(etran.Mask, tokenId, "joinable", "perm$N")==@ 0.0) ::
- bassume(new Boogie.MapSelect(etran.Mask, tokenId, "joinable", "perm$R")==@ 0.0) ::
- etran.IncPermission(tokenId, "joinable", permissionFull) :::
- // create a fresh value for the joinable field
- BLocal(asyncStateV) :: Boogie.Havoc(asyncState) :: bassume(asyncState !=@ 0) ::
- etran.Heap.store(tokenId, "joinable", asyncState) ::
- // also store the k used for this fork, such that the same k can be used in the join
- etran.Heap.store(tokenId, forkK, asyncMethodCallK) ::
- // assume the pre call state for the token is the state before inhaling the precondition
- bassume(CallHeap(asyncState) ==@ preCallHeap) ::
- bassume(CallMask(asyncState) ==@ preCallMask) ::
- bassume(CallSecMask(asyncState) ==@ preCallSecMask) ::
- bassume(CallCredits(asyncState) ==@ preCallCredits) ::
- bassume(CallArgs(asyncState) ==@ argsSeq) :::
- // assign the returned token to the variable
- { if (token != null) List(token := tokenId) else List() } :::
- bassume(wf(VarExpr(HeapName), VarExpr(MaskName), VarExpr(SecMaskName))) :: Nil
- case jn@JoinAsync(lhs, token) =>
- val formalThisV = new Variable("this", new Type(jn.m.Parent))
- val formalThis = new VariableExpr(formalThisV)
- val formalInsV = for (p <- jn.m.ins) yield new Variable(p.id, p.t)
- val formalIns = for (v <- formalInsV) yield new VariableExpr(v)
- val formalOutsV = for (p <- jn.m.outs) yield new Variable(p.id, p.t)
- val formalOuts = for (v <- formalOutsV) yield new VariableExpr(v)
-
- val (argsSeqV, argsSeq) = NewBVar("argsSeq", tArgSeq, true)
- val (preCallHeapV, preCallHeap) = NewBVar("preCallHeap", theap, true);
- val (preCallMaskV, preCallMask) = NewBVar("preCallMask", tmask, true);
- val (preCallSecMaskV, preCallSecMask) = NewBVar("preCallSecMask", tmask, true);
- val (preCallCreditsV, preCallCredits) = NewBVar("preCallCredits", tcredits, true);
- val postEtran = new ExpressionTranslator(etran.globals, Globals(preCallHeap, preCallMask, preCallSecMask, preCallCredits), currentClass);
- val (asyncJoinKV, asyncJoinK) = Boogie.NewBVar("asyncJoinK", treal, true)
-
- Comment("join async") ::
- // pick new k for this join
- BLocal(asyncJoinKV) ::
- bassume(0.0 < asyncJoinK) ::
- // try to use the same k as for the fork
- bassume(asyncJoinK ==@ etran.Heap.select(token, forkK)) ::
- // check that token is well-defined
- isDefined(token) :::
- // check that we did not join yet
- bassert(CanWrite(token, "joinable"), jn.pos, "The joinable field might not be writable.") ::
- bassert(etran.Heap.select(token, "joinable") !=@ 0, jn.pos, "The joinable field might not be true.") ::
- // lookup token.joinable
- BLocal(argsSeqV) :: (argsSeq := CallArgs(etran.Heap.select(token, "joinable"))) ::
- // retrieve the call's pre-state from token.joinable
- BLocal(preCallHeapV) :: (preCallHeap := CallHeap(etran.Heap.select(token, "joinable"))) ::
- BLocal(preCallMaskV) :: (preCallMask := CallMask(etran.Heap.select(token, "joinable"))) ::
- BLocal(preCallSecMaskV) :: (preCallSecMask := CallSecMask(etran.Heap.select(token, "joinable"))) ::
- BLocal(preCallCreditsV) :: (preCallCredits := CallCredits(etran.Heap.select(token, "joinable"))) ::
- // introduce locals for the out parameters
- (for (v <- formalThisV :: formalInsV ::: formalOutsV) yield BLocal(Variable2BVarWhere(v))) :::
- // initialize the in parameters
- (formalThis := new MapSelect(argsSeq, 0)) ::
- { var i = 1
- (formalIns map { v => val r = (v := new MapSelect(argsSeq, i)); i += 1; r })
- } :::
- // havoc formal outs
- (for (v <- formalOuts) yield Havoc(v)) :::
- // set joinable to false
- etran.Heap.store(token, "joinable", 0) ::
- etran.SetNoPermission(token, "joinable", etran.Mask) ::
- // inhale postcondition of the call
- postEtran.Inhale(Postconditions(jn.m.spec) map
- { p => SubstVars(p, formalThis, jn.m.ins ++ jn.m.outs, formalIns ++ formalOuts)}, "postcondition", false, asyncJoinK) :::
- // assign formal outs to actual outs
- (for ((v,e) <- lhs zip formalOuts) yield (v := e))
- case s@Send(ch, args) =>
- val channel = ch.typ.asInstanceOf[ChannelClass].ch
- val formalThisV = new Variable("this", new Type(ch.typ))
- val formalThis = new VariableExpr(formalThisV)
- val formalParamsV = for (p <- channel.parameters) yield new Variable(p.id, p.t)
- val formalParams = for (v <- formalParamsV) yield new VariableExpr(v)
- Comment("send") ::
- // introduce formal parameters
- (for (v <- formalThisV :: formalParamsV) yield BLocal(Variable2BVarWhere(v))) :::
- // check definedness of arguments
- isDefined(ch) :::
- bassert(nonNull(ch), ch.pos, "The channel might be null.") ::
- (args flatMap { e: Expression => isDefined(e)}) :::
- // assign actual ins to formal parameters
- (formalThis := ch) ::
- (for ((v,e) <- formalParams zip args) yield (v := e)) :::
- // increase credits
- new Boogie.MapUpdate(etran.Credits, TrExpr(ch), new Boogie.MapSelect(etran.Credits, TrExpr(ch)) + 1) ::
- // exhale where clause
- Exhale(List(
- (SubstVars(channel.where, formalThis, channel.parameters, formalParams),
- ErrorMessage(s.pos, "The where clause at " + channel.where.pos + " might not hold."))),
- "channel where clause", methodK, false)
- case r@Receive(_, ch, outs) =>
- val channel = ch.typ.asInstanceOf[ChannelClass].ch
- val formalThisV = new Variable("this", new Type(ch.typ))
- val formalThis = new VariableExpr(formalThisV)
- val formalParamsV = for (p <- channel.parameters) yield new Variable(p.id, p.t)
- val formalParams = for (v <- formalParamsV) yield new VariableExpr(v)
- Comment("receive") ::
- // check definedness of arguments
- isDefined(ch) :::
- bassert(nonNull(ch), ch.pos, "The channel might be null.") ::
- // check that credits are positive
- bassert(0 < new Boogie.MapSelect(etran.Credits, TrExpr(ch)), r.pos, "receive operation requires a credit") ::
- // ...and check: waitlevel << ch.mu
- bassert(CanRead(ch, "mu"), r.pos, "The mu field of the channel in the receive statement might not be readable.") ::
- bassert(etran.MaxLockIsBelowX(etran.Heap.select(ch, "mu")), r.pos, "The channel must lie above waitlevel in the wait order") ::
- // introduce locals for the parameters
- (for (v <- formalThisV :: formalParamsV) yield BLocal(Variable2BVarWhere(v))) :::
- // initialize the parameters; that is, set "this" to the channel and havoc the other formal parameters
- (formalThis := ch) ::
- (for (v <- formalParams) yield Havoc(v)) :::
- // inhale where clause
- Inhale(List(SubstVars(channel.where, formalThis, channel.parameters, formalParams)), "channel where clause", methodK) :::
- // declare any new local variables among the actual outs
- (for (v <- r.locals) yield BLocal(Variable2BVarWhere(v))) :::
- // assign formal outs to actual outs
- (for ((v,e) <- outs zip formalParams) yield (v := e)) :::
- // decrease credits
- new Boogie.MapUpdate(etran.Credits, TrExpr(ch), new Boogie.MapSelect(etran.Credits, TrExpr(ch)) - 1)
- case r: RefinementBlock =>
- translateRefinement(r, methodK)
- case _: Signal => throw new NotSupportedException("not implemented")
- case _: Wait => throw new NotSupportedException("not implemented")
- }
- }
-
- def translateLocalVarDecl(v: Variable, assignConst: Boolean) = {
- val bv = Variable2BVarWhere(v)
- Comment("local " + v) ::
- BLocal(bv) ::
- { if (v.isImmutable) {
- val isAssignedVar = new Boogie.BVar("assigned$" + bv.id, BoolClass)
- // havoc x; var assigned$x: bool; assigned$x := false;
- Havoc(new Boogie.VarExpr(bv)) ::
- BLocal(isAssignedVar) ::
- (new Boogie.VarExpr(isAssignedVar) := assignConst)
- } else
- Nil }
- }
-
- def translateAllocation(cl: Class, initialization: List[Init], lowerBounds: List[Expression], upperBounds: List[Expression], pos: Position): (Boogie.BVar, List[Boogie.Stmt]) = {
- val (nw, nwe) = NewBVar("nw", cl, true)
- val (ttV,tt) = Boogie.NewTVar("T")
- val f = new Boogie.BVar("f", FieldType(tt))
- (nw,
- Comment("new") ::
- BLocal(nw) :: Havoc(nwe) ::
- bassume(nonNull(nwe) && (dtype(nwe) ==@ className(cl))) ::
- bassume(new Boogie.Forall(ttV, f, etran.HasNoPermission(nwe, f.id))) ::
- // initial values of fields:
- (if (cl.IsChannel)
- UpdateMu(nwe, false, true, lowerBounds, upperBounds, ErrorMessage(pos, "new might fail."))
- else
- List(bassume(etran.Heap.select(nwe, "mu") ==@ bLockBottom))) :::
- bassume(etran.Heap.select(nwe, "held") <= 0) ::
- bassume(etran.Heap.select(nwe, "rdheld") ==@ false) ::
- // give access to user-defined fields and special fields:
- (for (f <- cl.Fields ++ RootClass.MentionableFields) yield
- etran.IncPermission(nwe, f.FullName, permissionFull)).flatten :::
- // initialize fields according to the initialization
- (initialization flatMap { init => isDefined(init.e) ::: etran.Heap.store(nwe, init.f.FullName, init.e) })
- )
- }
-
- def TrAcquire(s: Statement, nonNullObj: Expression, currentK: Expr) = {
- val o = TrExpr(nonNullObj);
- val (lastAcquireVar, lastAcquire) = Boogie.NewBVar("lastAcquire", IntClass, true)
- val (lastSeenHeldV, lastSeenHeld) = Boogie.NewBVar("lastSeenHeld", tint, true)
- val (lastSeenMuV, lastSeenMu) = Boogie.NewBVar("lastSeenMu", tmu, true)
- (if (Chalice.skipDeadlockChecks)
- bassume(CanRead(o, "mu")) ::
- bassume(etran.MaxLockIsBelowX(etran.Heap.select(o,"mu")))
- else
- bassert(CanRead(o, "mu"), s.pos, "The mu field of the target of the acquire statement might not be readable.") ::
- bassert(etran.MaxLockIsBelowX(etran.Heap.select(o,"mu")), s.pos, "The mu field of the target of the acquire statement might not be above waitlevel.")) :::
- bassume(etran.Heap.select(o,"mu") !=@ bLockBottom) :: // this isn't strictly necessary, it seems; but we might as well include it
- // remember the state right before releasing
- BLocal(lastSeenMuV) :: (lastSeenMu := etran.Heap.select(o, "mu")) ::
- BLocal(lastSeenHeldV) :: Havoc(lastSeenHeld) :: (lastSeenHeld := etran.Heap.select(o, "held")) ::
- bassume(! isHeld(o) && ! isRdHeld(o)) :: // this assume follows from the previous assert
- // update the thread's locking state
- BLocal(lastAcquireVar) :: Havoc(lastAcquire) :: bassume(0 < lastAcquire) ::
- etran.Heap.store(o, "held", lastAcquire) ::
- InhaleInvariants(nonNullObj, false, etran.WhereOldIs(
- LastSeenHeap(lastSeenMu, lastSeenHeld),
- LastSeenMask(lastSeenMu, lastSeenHeld),
- LastSeenSecMask(lastSeenMu, lastSeenHeld),
- LastSeenCredits(lastSeenMu, lastSeenHeld)), currentK) :::
- // remember values of Heap/Mask/Credits globals (for proving history constraint at release)
- bassume(AcquireHeap(lastAcquire) ==@ etran.Heap) ::
- bassume(AcquireMask(lastAcquire) ==@ etran.Mask) ::
- bassume(AcquireSecMask(lastAcquire) ==@ etran.SecMask) ::
- bassume(AcquireCredits(lastAcquire) ==@ etran.Credits)
- }
- def TrRelease(s: Statement, nonNullObj: Expression, currentK: Expr) = {
- val (heldV, held) = Boogie.NewBVar("held", tint, true)
- val (prevLmV, prevLm) = Boogie.NewBVar("prevLM", tref, true)
- val (preReleaseHeapV, preReleaseHeap) = NewBVar("preReleaseHeap", theap, true)
- val (preReleaseMaskV, preReleaseMask) = NewBVar("preReleaseMask", tmask, true)
- val (preReleaseSecMaskV, preReleaseSecMask) = NewBVar("preReleaseSecMask", tmask, true)
- val (preReleaseCreditsV, preReleaseCredits) = NewBVar("preReleaseCredits", tcredits, true)
- val o = TrExpr(nonNullObj);
- BLocal(preReleaseHeapV) :: (preReleaseHeap := etran.Heap) ::
- BLocal(preReleaseMaskV) :: (preReleaseMask := etran.Mask) ::
- BLocal(preReleaseSecMaskV) :: (preReleaseSecMask := etran.SecMask) ::
- BLocal(preReleaseCreditsV) :: (preReleaseCredits := etran.Credits) ::
- bassert(isHeld(o), s.pos, "The target of the release statement might not be locked by the current thread.") ::
- bassert(!isRdHeld(o), s.pos, "Release might fail because the current thread might hold the read lock.") ::
- ExhaleInvariants(nonNullObj, false, ErrorMessage(s.pos, "Monitor invariant might hot hold."), etran.WhereOldIs(
- AcquireHeap(etran.Heap.select(o, "held")),
- AcquireMask(etran.Heap.select(o, "held")),
- AcquireSecMask(etran.Heap.select(o, "held")),
- AcquireCredits(etran.Heap.select(o, "held"))), currentK) :::
- // havoc o.held where 0<=o.held
- BLocal(heldV) :: Havoc(held) :: bassume(held <= 0) ::
- etran.Heap.store(o, "held", held) ::
- // assume a seen state is the one right before the share
- bassume(LastSeenHeap(etran.Heap.select(o, "mu"), held) ==@ preReleaseHeap) ::
- bassume(LastSeenMask(etran.Heap.select(o, "mu"), held) ==@ preReleaseMask) ::
- bassume(LastSeenSecMask(etran.Heap.select(o, "mu"), held) ==@ preReleaseSecMask) ::
- bassume(LastSeenCredits(etran.Heap.select(o, "mu"), held) ==@ preReleaseCredits)
- }
- def TrRdAcquire(s: Statement, nonNullObj: Expression, currentK: Expr) = {
- val (heldV, held) = Boogie.NewBVar("held", tint, true)
- val o = TrExpr(nonNullObj)
- bassert(CanRead(o, "mu"), s.pos, "The mu field of the target of the read-acquire statement might not be readable.") ::
- bassert(etran.MaxLockIsBelowX(etran.Heap.select(o, "mu")), s.pos, "The mu field of the target of the read-acquire statement might not be above waitlevel.") ::
- bassume(etran.Heap.select(o,"mu") !=@ bLockBottom) :: // this isn't strictly necessary, it seems; but we might as well include it
- bassume(! isHeld(o) && ! isRdHeld(o)) ::
- BLocal(heldV) :: Havoc(held) :: bassume(held <= 0) ::
- etran.Heap.store(o, "held", held) ::
- etran.Heap.store(o, "rdheld", true) ::
- InhaleInvariants(nonNullObj, true, currentK)
- }
- def TrRdRelease(s: Statement, nonNullObj: Expression, currentK: Expr) = {
- val (heldV, held) = Boogie.NewBVar("held", tint, true)
- val o = TrExpr(nonNullObj);
- bassert(isRdHeld(o), s.pos, "The current thread might not hold the read-lock of the object being released.") ::
- ExhaleInvariants(nonNullObj, true, ErrorMessage(s.pos, "Monitor invariant might not hold."), currentK) :::
- BLocal(heldV) :: Havoc(held) :: bassume(held <= 0) ::
- etran.Heap.store(o, "held", held) ::
- etran.Heap.store(o, "rdheld", false)
- }
-
- def translateSpecStmt(s: SpecStmt, methodK: Expr): List[Stmt] = {
- val (preGlobalsV, preGlobals) = etran.FreshGlobals("pre")
-
- // pick new k for the spec stmt
- val (specKV, specK) = Boogie.NewBVar("specStmtK", treal, true)
-
- BLocal(specKV) ::
- bassume(0.0 < specK && 1000.0*specK < percentPermission(1) && 1000.0*specK < methodK) ::
- // declare new local variables
- s.locals.flatMap(v => translateLocalVarDecl(v, true)) :::
- Comment("spec statement") ::
- BLocals(preGlobalsV) :::
- // remember values of globals
- copyState(preGlobals, etran) :::
- // exhale preconditions
- etran.Exhale(List((s.pre, ErrorMessage(s.pos, "The specification statement precondition at " + s.pos + " might not hold."))), "spec stmt precondition", true, specK, false) :::
- // havoc locals
- (s.lhs.map(l => Boogie.Havoc(l))) :::
- // inhale postconditions (using the state before the call as the "old" state)
- etran.FromPreGlobals(preGlobals).Inhale(List(s.post), "spec stmt postcondition", false, specK)
- }
-
- def translateCall(c: Call, methodK: Expr): List[Stmt] = {
- val obj = c.obj;
- val lhs = c.lhs;
- val id = c.id;
- val args = c.args;
- val formalThisV = new Variable("this", new Type(c.m.Parent))
- val formalThis = new VariableExpr(formalThisV)
- val formalInsV = for (p <- c.m.Ins) yield new Variable(p.id, p.t)
- val formalIns = for (v <- formalInsV) yield new VariableExpr(v)
- val formalOutsV = for (p <- c.m.Outs) yield new Variable(p.id, p.t)
- val formalOuts = for (v <- formalOutsV) yield new VariableExpr(v)
- val (preGlobalsV, preGlobals) = etran.FreshGlobals("call")
- val postEtran = etran.FromPreGlobals(preGlobals)
-
- // pick new k for this method call
- val (methodCallKV, methodCallK) = Boogie.NewBVar("methodCallK", treal, true)
- BLocal(methodCallKV) ::
- bassume(0.0 < methodCallK && 1000.0*methodCallK < percentPermission(1) && 1000.0*methodCallK < methodK) ::
- Comment("call " + id) ::
- // introduce formal parameters and pre-state globals
- (for (v <- formalThisV :: formalInsV ::: formalOutsV) yield BLocal(Variable2BVarWhere(v))) :::
- BLocals(preGlobalsV) :::
- // remember values of globals
- copyState(preGlobals, etran) :::
- // check definedness of arguments
- isDefined(obj) :::
- bassert(nonNull(obj), c.pos, "The target of the method call might be null.") ::
- (args flatMap { e: Expression => isDefined(e)}) :::
- // assign actual ins to formal ins
- (formalThis := obj) ::
- (for ((v,e) <- formalIns zip args) yield (v := e)) :::
- // exhale preconditions
- Exhale(Preconditions(c.m.Spec) map
- (p => SubstVars(p, formalThis, c.m.Ins, formalIns)) zip (Preconditions(c.m.Spec) map { p => ErrorMessage(c.pos, "The precondition at " + p.pos + " might not hold.")}), "precondition", methodCallK, false) :::
- // havoc formal outs
- (for (v <- formalOuts) yield Havoc(v)) :::
- // havoc lockchanges
- LockHavoc(for (e <- LockChanges(c.m.Spec) map (p => SubstVars(p, formalThis, c.m.Ins ++ c.m.Outs, formalIns ++ formalOuts))) yield etran.Tr(e), postEtran) :::
- // inhale postconditions (using the state before the call as the "old" state)
- postEtran.Inhale(Postconditions(c.m.Spec) map
- (p => SubstVars(p, formalThis, c.m.Ins ++ c.m.Outs, formalIns ++ formalOuts)) , "postcondition", false, methodCallK) :::
- // declare any new local variables among the actual outs
- (for (v <- c.locals) yield BLocal(Variable2BVarWhere(v))) :::
- // assign formal outs to actual outs
- (for ((v,e) <- lhs zip formalOuts) yield (v :=e))
- }
-
- def translateWhile(w: WhileStmt, methodK: Expr): List[Stmt] = {
- val guard = w.guard;
- val lkch = w.lkch;
- val body = w.body;
-
- val (preLoopGlobalsV, preLoopGlobals) = etran.FreshGlobals("while")
- val loopEtran = etran.FromPreGlobals(preLoopGlobals)
- val (iterStartGlobalsV, iterStartGlobals) = etran.FreshGlobals("iterStart")
- val iterStartEtran = etran.FromPreGlobals(iterStartGlobals)
- val saveLocalsV = for (v <- w.LoopTargets) yield new Variable(v.id, v.t)
- val iterStartLocalsV = for (v <- w.LoopTargets) yield new Variable(v.id, v.t)
- val lkchOld = lkch map (e => SubstVars(e, w.LoopTargets,
- for (v <- saveLocalsV) yield new VariableExpr(v)))
- val lkchIterStart = lkch map (e => SubstVars(e, w.LoopTargets,
- for (v <- iterStartLocalsV) yield new VariableExpr(v)))
- val oldLocks = lkchOld map (e => loopEtran.oldEtran.Tr(e))
- val iterStartLocks = lkchIterStart map (e => iterStartEtran.oldEtran.Tr(e))
- val newLocks = lkch map (e => loopEtran.Tr(e));
- val (whileKV, whileK) = Boogie.NewBVar("whileK", treal, true)
- val previousEtran = etran // save etran
-
- Comment("while") ::
- // pick new k for this method call
- BLocal(whileKV) ::
- bassume(0.0 < whileK && 1000.0*whileK < percentPermission(1) && 1000.0*whileK < methodK) ::
- // save globals
- BLocals(preLoopGlobalsV) :::
- copyState(preLoopGlobals, loopEtran) :::
- // check invariant on entry to the loop
- Exhale(w.oldInvs map { inv => (inv, ErrorMessage(inv.pos, "The loop invariant might not hold on entry to the loop."))}, "loop invariant, initially", whileK, false) :::
- tag(Exhale(w.newInvs map { inv => (inv, ErrorMessage(inv.pos, "The loop invariant might not hold on entry to the loop."))}, "loop invariant, initially", whileK, false), keepTag) :::
- List(bassert(DebtCheck, w.pos, "Loop invariant must consume all debt on entry to the loop.")) :::
- // check lockchange on entry to the loop
- Comment("check lockchange on entry to the loop") ::
- (bassert(LockFrame(lkch, etran), w.pos, "Method execution before loop might lock/unlock more than allowed by lockchange clause of loop.")) ::
- // save values of local-variable loop targets
- (for (sv <- saveLocalsV) yield BLocal(Variable2BVarWhere(sv))) :::
- (for ((v,sv) <- w.LoopTargets zip saveLocalsV) yield (new VariableExpr(sv) := new VariableExpr(v))) :::
- // havoc local-variable loop targets
- (w.LoopTargets :\ List[Boogie.Stmt]()) ( (v,vars) => (v match {
- case v: Variable if v.isImmutable => Boogie.Havoc(Boogie.VarExpr("assigned$" + v.id))
- case _ => Boogie.Havoc(Boogie.VarExpr(v.UniqueName)) }) :: vars) :::
- Boogie.If(null,
- // 1. CHECK DEFINEDNESS OF INVARIANT
- { etran = etran.resetFpi
- Comment("check loop invariant definedness") ::
- //(w.LoopTargets.toList map { v: Variable => Boogie.Havoc(Boogie.VarExpr(v.id)) }) :::
- resetState(etran) :::
- InhaleWithChecking(w.oldInvs, "loop invariant definedness", whileK) :::
- tag(InhaleWithChecking(w.newInvs, "loop invariant definedness", whileK), keepTag) :::
- bassume(false) }
- , Boogie.If(null,
- // 2. CHECK LOOP BODY
- // Renew state: set Mask to ZeroMask and Credits to ZeroCredits, and havoc Heap everywhere except
- // at {old(local),local}.{held,rdheld}
- { etran = etran.resetFpi
- resetState(etran) :::
- Inhale(w.Invs, "loop invariant, body", whileK) :::
- // assume lockchange at the beginning of the loop iteration
- Comment("assume lockchange at the beginning of the loop iteration") ::
- (bassume(LockFrame(lkch, etran))) ::
- // this is the state at the beginning of the loop iteration; save these values
- BLocals(iterStartGlobalsV) :::
- copyState(iterStartGlobals, iterStartEtran) :::
- (for (isv <- iterStartLocalsV) yield BLocal(Variable2BVarWhere(isv))) :::
- (for ((v,isv) <- w.LoopTargets zip iterStartLocalsV) yield
- (new VariableExpr(isv) := new VariableExpr(v))) :::
- // evaluate the guard
- isDefined(guard) ::: List(bassume(guard)) :::
- translateStatement(body, whileK) :::
- // check invariant
- Exhale(w.oldInvs map { inv => (inv, ErrorMessage(inv.pos, "The loop invariant at " + inv.pos + " might not be preserved by the loop."))}, "loop invariant, maintained", whileK, true) :::
- tag(Exhale(w.newInvs map { inv => (inv, ErrorMessage(inv.pos, "The loop invariant at " + inv.pos + " might not be preserved by the loop."))}, "loop invariant, maintained", whileK, true), keepTag) :::
- isLeaking(w.pos, "The loop might leak references.") :::
- // check lockchange after loop iteration
- Comment("check lockchange after loop iteration") ::
- (bassert(LockFrame(lkch, etran), w.pos, "The loop might lock/unlock more than the lockchange clause allows.")) ::
- // perform debt check
- bassert(DebtCheck, w.pos, "Loop body is not allowed to leave any debt.") :::
- bassume(false)},
- // 3. AFTER LOOP
- { etran = previousEtran
- LockHavoc(oldLocks ++ newLocks, loopEtran) :::
- // assume lockchange after the loop
- Comment("assume lockchange after the loop") ::
- (bassume(LockFrame(lkch, etran))) ::
- Inhale(w.Invs, "loop invariant, after loop", whileK) :::
- bassume(!guard)}))
- }
-
- def translateRefinement(r: RefinementBlock, methodK: Expr): List[Stmt] = {
- // abstract expression translator
- val absTran = etran;
- // concrete expression translate
- val (conGlobalsV, conGlobals) = etran.FreshGlobals("concrete")
- val conTran = new ExpressionTranslator(conGlobals, etran.oldEtran.globals, currentClass); // TODO: what about FoldedPredicateInfo?
- // shared locals existing before the block (excluding immutable)
- val before = for (v <- r.before; if (! v.isImmutable)) yield v;
- // shared locals declared in the block
- val (duringA, duringC) = r.during;
- // variables for locals before (to restore for the abstract version)
- val beforeV = for (v <- before) yield new Variable(v.id, v.t)
- // variables for locals after (to compare with the abstract version)
- val afterV = for (v <- before) yield new Variable(v.id, v.t)
-
- Comment("refinement block") ::
- // save heap
- BLocals(conGlobalsV) :::
- copyState(conGlobals, etran) :::
- // save shared local variables
- (for (v <- beforeV) yield BLocal(Variable2BVarWhere(v))) :::
- (for ((v, w) <- beforeV zip before) yield (new VariableExpr(v) := new VariableExpr(w))) :::
- // run concrete C on the fresh heap
- {
- etran = conTran;
- Comment("concrete program:") ::
- tag(translateStatements(r.con, methodK), keepTag)
- } :::
- // run angelically A on the old heap
- Comment("abstract program:") ::
- { etran = absTran;
- r.abs match {
- case List(s: SpecStmt) =>
- var (m, me) = NewBVar("specMask", tmask, true)
- var (sm, sme) = NewBVar("specSecMask", tmask, true)
- tag(
- Comment("give witnesses to the declared local variables") ::
- (for (v <- duringA) yield BLocal(Variable2BVarWhere(v))) :::
- (for ((v, w) <- duringA zip duringC) yield (new VariableExpr(v) := new VariableExpr(w))) :::
- BLocal(m) :: BLocal(sm) ::
- (me := absTran.Mask) :: (sme := absTran.SecMask) ::
- absTran.Exhale(me, sme, List((s.post,ErrorMessage(r.pos, "Refinement may fail to satisfy specification statement post-condition."))), "SpecStmt", false, methodK, false) :::
- (for ((v, w) <- beforeV zip before; if (! s.lhs.exists(ve => ve.v == w))) yield
- bassert(new VariableExpr(v) ==@ new VariableExpr(w), r.pos, "Refinement may change a variable outside of the frame of the specification statement: " + v.id)),
- keepTag)
- case _ =>
- // save locals after
- (for (v <- afterV) yield BLocal(Variable2BVarWhere(v))) :::
- (for ((v, w) <- afterV zip before) yield (new VariableExpr(v) := new VariableExpr(w))) :::
- // restore locals before
- (for ((v, w) <- before zip beforeV) yield (new VariableExpr(v) := new VariableExpr(w))) :::
- translateStatements(r.abs, methodK) :::
- // assert equality on shared locals
- tag(
- (for ((v, w) <- afterV zip before) yield
- bassert(new VariableExpr(v) ==@ new VariableExpr(w), r.pos, "Refinement may produce a different value for the pre-state local variable: " + v.id)) :::
- (for ((v, w) <- duringA zip duringC) yield
- bassert(new VariableExpr(v) ==@ new VariableExpr(w), r.pos, "Refinement may produce a different value for the declared variable: " + v.id)),
- keepTag)
- }} :::
- {
- val (v,ve) = NewBVar("this", tref, true)
- // TODO: check for mask coupling
- // TODO: we only inhale concrete values for "This"
-
- def copy(e: Expression):List[Stmt] = e match {
- case And(a,b) => copy(a) ::: copy(b)
- case Implies(a,b) => Boogie.If(absTran.Tr(a), copy(b), Nil)
- case Access(ma, _) if ! ma.isPredicate => absTran.Heap.store(absTran.Tr(ma.e), new VarExpr(ma.f.FullName), conTran.Heap.select(absTran.Tr(ma.e), ma.f.FullName))
- case _: PermissionExpr => throw new NotSupportedException("not implemented")
- case _ => Nil
- }
-
- // copy variables in the coupling invariants to the abstract heap (to preserve their values across refinement blocks and establish invariant)
- (for (ci <- currentClass.CouplingInvariants)
- yield Boogie.If((ci.fields.map(f => absTran.CanRead(new VarExpr("this"), f.FullName)).reduceLeft(_ || _)),
- copy(ci.e), Nil)) :::
- // assert equality on shared globals (except those that are replaced)
- tag(
- for (f <- currentClass.refines.Fields; if ! currentClass.CouplingInvariants.exists(_.fields.contains(f)))
- yield bassert((absTran.Heap.select(ve, f.FullName) ==@ conTran.Heap.select(ve, f.FullName)).forall(v), r.pos, "Refinement may change the value of the field " + f.FullName),
- keepTag)
- } :::
- Comment("end of the refinement block")
- }
-
- def UpdateMu(o: Expr, allowOnlyFromBottom: Boolean, justAssumeValue: Boolean,
- lowerBounds: List[Expression], upperBounds: List[Expression], error: ErrorMessage): List[Stmt] = {
- def BoundIsNullObject(b: Expression): Boogie.Expr = {
- if (b.typ.IsMu) false else b ==@ bnull
- }
- def MuValue(b: Expression): Expr = {
- if (b.typ.IsMu) b else etran.Heap.select(b, "mu")
- }
- def Below(a: Expr, b: Expr) = {
- new FunctionApp("MuBelow", a, b)
- }
- val (muV, mu) = Boogie.NewBVar("mu", Boogie.NamedType("Mu"), true)
- // check that bounds are well-defined
- ((lowerBounds ++ upperBounds) flatMap { bound => isDefined(bound)}) :::
- // check that we have full access to o.mu
- (if (!justAssumeValue)
- List(bassert(CanWrite(o, "mu"), error.pos, error.message + " The mu field of the target might not be writable."))
- else
- List()) :::
- // ...and that o.mu starts off as lockbottom, if desired
- (if (allowOnlyFromBottom)
- List(bassert(etran.Heap.select(o,"mu") ==@ bLockBottom,
- error.pos, error.message + " The object may already be shared (i.e., mu may not be LockBottom)"))
- else
- List()) :::
- // check for each bound that if it is a non-null object, then its mu field is readable
- (for (bound <- lowerBounds ++ upperBounds if !bound.typ.IsMu) yield
- bassert((bound ==@ bnull) || CanRead(bound, "mu"), bound.pos, "The mu field of bound at " + bound.pos + " might not be readable." )) :::
- // check that each lower bound is smaller than each upper bound
- (for (lb <- lowerBounds; ub <- upperBounds) yield
- bassert( (etran.ShaveOffOld(lb), etran.ShaveOffOld(ub)) match {
- case ((MaxLockLiteral(),o0), (MaxLockLiteral(),o1)) =>
- if (o0 == o1)
- false
- else
- etran.TemporalMaxLockComparison(etran.ChooseEtran(o0), etran.ChooseEtran(o1))
- case ((MaxLockLiteral(),o), _) => etran.ChooseEtran(o).MaxLockIsBelowX(MuValue(ub))
- case (_, (MaxLockLiteral(),o)) => etran.ChooseEtran(o).MaxLockIsAboveX(MuValue(lb))
- case _ => BoundIsNullObject(lb) ||
- BoundIsNullObject(ub) ||
- Below(MuValue(lb), MuValue(ub)) }, lb.pos, "The lower bound at " + lb.pos + " might not be smaller than the upper bound at " + ub.pos + ".")) :::
- // havoc mu
- BLocal(muV) :: Havoc(mu) :: bassume(mu !=@ bLockBottom) ::
- // assume that mu is between the given bounds (or above waitlevel if no bounds are given)
- (if (lowerBounds == Nil && upperBounds == Nil) {
- // assume waitlevel << mu
- List(bassume(etran.MaxLockIsBelowX(mu)))
- } else {
- (for (lb <- lowerBounds) yield
- // assume lb << mu
- bassume(
- if (etran.IsMaxLockLit(lb)) {
- val (f,o) = etran.ShaveOffOld(lb)
- etran.ChooseEtran(o).MaxLockIsBelowX(mu)
- } else
- (BoundIsNullObject(lb) || Below(MuValue(lb), mu)))) :::
- (for (ub <- upperBounds) yield
- // assume mu << ub
- bassume(
- if (etran.IsMaxLockLit(ub)) {
- val (f,o) = etran.ShaveOffOld(ub)
- etran.ChooseEtran(o).MaxLockIsAboveX(mu)
- } else
- (BoundIsNullObject(ub) || Below(mu, MuValue(ub)))))
- }) :::
- // store the mu field
- (if (justAssumeValue) bassume(etran.Heap.select(o, "mu") ==@ mu) else etran.Heap.store(o, "mu", mu))
- }
-
- def isLeaking(pos: Position, msg: String): List[Boogie.Stmt] = {
- if(Chalice.checkLeaks) {
- var o = Boogie.VarExpr("$o");
- var f = "$f";
- val (ttV,tt) = Boogie.NewTVar("T")
- List(
- bassert(new Boogie.Forall(
- List(ttV),
- List(Boogie.BVar("$o", tref), Boogie.BVar("$f", FieldType(tt))),
- Nil,
- (o ==@ bnull) || ((new MapSelect(etran.Mask, o, f, "perm$R") ==@ 0.0) && (new MapSelect(etran.Mask, o, f, "perm$N") ==@ 0.0))
- ), pos, msg)
- )
- } else {
- Nil
- }
- }
-
- def LockFrame(lkch: List[Expression], etran: ExpressionTranslator) =
- LocksUnchanged(for (l <- lkch) yield etran.Tr(l), etran)
- def LocksUnchanged(exceptions: List[Boogie.Expr], etran: ExpressionTranslator) = {
- val (lkV, lk) = Boogie.NewBVar("lk", tref, true)
- val b: Boogie.Expr = false
- Boogie.Forall(Nil, List(lkV),
- List(new Trigger(etran.Heap.select(lk, "held")), new Trigger(etran.Heap.select(lk, "rdheld"))),
- (((0 < etran.Heap.select(lk, "held")) ==@
- (0 < etran.oldEtran.Heap.select(lk, "held"))) &&
- (new Boogie.MapSelect(etran.Heap, lk, "rdheld") ==@
- new Boogie.MapSelect(etran.oldEtran.Heap, lk, "rdheld"))) ||
- // It seems we should exclude newly-allocated objects from lockchange. Since Chalice does not have an "alloc" field,
- // we could use the "mu" field as an approximation, but that breaks the HandOverHand example. So we leave it for now.
- // (new Boogie.MapSelect(etran.oldEtran.Heap, lk, "mu") ==@ bLockBottom) ||
- ((exceptions :\ b) ((e,ll) => ll || (lk ==@ e))))
- }
- def LockHavoc(locks: List[Boogie.Expr], etran: ExpressionTranslator) = {
- val (heldV, held) = NewBVar("isHeld", IntClass, true)
- val (rdheldV, rdheld) = NewBVar("isRdHeld", BoolClass, true)
- BLocal(heldV) :: BLocal(rdheldV) ::
- (for (o <- locks) yield { // todo: somewhere we should worry about Df(l)
- Havoc(held) :: Havoc(rdheld) ::
- bassume(rdheld ==> (0 < held)) ::
- new MapUpdate(etran.Heap, o, VarExpr("held"), held) ::
- new MapUpdate(etran.Heap, o, VarExpr("rdheld"), rdheld) }).flatten
- }
- def NumberOfLocksHeldIsInvariant(oldLocks: List[Boogie.Expr], newLocks: List[Boogie.Expr],
- etran: ExpressionTranslator) = {
- (for ((o,n) <- oldLocks zip newLocks) yield {
- // oo.held == nn.held && oo.rdheld == nn.rdheld
- (((0 < new Boogie.MapSelect(etran.oldEtran.Heap, o, "held")) ==@
- (0 < new Boogie.MapSelect(etran.Heap, n, "held"))) &&
- (new Boogie.MapSelect(etran.oldEtran.Heap, o, "rdheld") ==@
- new Boogie.MapSelect(etran.Heap, n, "rdheld"))) ::
- // no.held == on.held && no.rdheld == on.rdheld
- (((0 < new Boogie.MapSelect(etran.Heap, o, "held")) ==@
- (0 < new Boogie.MapSelect(etran.oldEtran.Heap, n, "held"))) &&
- (new Boogie.MapSelect(etran.Heap, o, "rdheld") ==@
- new Boogie.MapSelect(etran.oldEtran.Heap, n, "rdheld"))) ::
- // o == n || (oo.held != no.held && (!oo.rdheld || !no.rdheld))
- ((o ==@ n) ||
- (((0 < new Boogie.MapSelect(etran.oldEtran.Heap, o, "held")) !=@ (0 < new Boogie.MapSelect(etran.Heap, o, "held"))) &&
- ((! new Boogie.MapSelect(etran.oldEtran.Heap, o, "rdheld")) ||
- (! new Boogie.MapSelect(etran.Heap, o, "rdheld"))))) ::
- Nil
- }).flatten
- }
-
- implicit def lift(s: Stmt): List[Stmt] = List(s)
- def isDefined(e: Expression) = etran.isDefined(e)(true)
- def TrExpr(e: Expression) = etran.Tr(e)
-
- def InhaleInvariants(obj: Expression, readonly: Boolean, tran: ExpressionTranslator, currentK: Expr) = {
- val shV = new Variable("sh", new Type(obj.typ))
- val sh = new VariableExpr(shV)
- BLocal(Variable2BVar(shV)) :: Boogie.Assign(TrExpr(sh), TrExpr(obj)) ::
- tran.Inhale(obj.typ.MonitorInvariants map
- (inv => SubstThis(inv.e, sh)) map
- (inv => (if (readonly) SubstRd(inv) else inv)), "monitor invariant", false, currentK)
- }
- def ExhaleInvariants(obj: Expression, readonly: Boolean, msg: ErrorMessage, tran: ExpressionTranslator, currentK: Expr) = {
- val shV = new Variable("sh", new Type(obj.typ))
- val sh = new VariableExpr(shV)
- BLocal(Variable2BVar(shV)) :: Boogie.Assign(TrExpr(sh), TrExpr(obj)) ::
- tran.Exhale(obj.typ.MonitorInvariants map
- (inv => SubstThis(inv.e, sh)) map
- (inv => (if (readonly) SubstRd(inv) else inv, msg)), "monitor invariant", false, currentK, false)
- }
- def InhaleInvariants(obj: Expression, readonly: Boolean, currentK: Expr) = {
- val shV = new Variable("sh", new Type(obj.typ))
- val sh = new VariableExpr(shV)
- BLocal(Variable2BVar(shV)) :: Boogie.Assign(TrExpr(sh), TrExpr(obj)) ::
- Inhale(obj.typ.MonitorInvariants map
- (inv => SubstThis(inv.e, sh)) map
- (inv => (if (readonly) SubstRd(inv) else inv)), "monitor invariant", currentK)
- }
- def ExhaleInvariants(obj: Expression, readonly: Boolean, msg: ErrorMessage, currentK: Expr) = {
- val shV = new Variable("sh", new Type(obj.typ))
- val sh = new VariableExpr(shV)
- BLocal(Variable2BVar(shV)) :: Boogie.Assign(TrExpr(sh), TrExpr(obj)) ::
- Exhale(obj.typ.MonitorInvariants map
- (inv => SubstThis(inv.e, sh)) map
- (inv => (if (readonly) SubstRd(inv) else inv, msg)), "monitor invariant", currentK, false)
- }
-
- def Inhale(predicates: List[Expression], occasion: String, currentK: Expr): List[Boogie.Stmt] = etran.Inhale(predicates, occasion, false, currentK)
- def Exhale(predicates: List[(Expression, ErrorMessage)], occasion: String, currentK: Expr, exactchecking: Boolean): List[Boogie.Stmt] = etran.Exhale(predicates, occasion, false, currentK, exactchecking)
- def ExhaleDuringUnfold(predicates: List[(Expression, ErrorMessage)], occasion: String, currentK: Expr, exactchecking: Boolean): List[Boogie.Stmt] = etran.ExhaleDuringUnfold(predicates, occasion, false, currentK, exactchecking)
- def InhaleWithChecking(predicates: List[Expression], occasion: String, currentK: Expr): List[Boogie.Stmt] = etran.Inhale(predicates, occasion, true, currentK)
- def ExhaleWithChecking(predicates: List[(Expression, ErrorMessage)], occasion: String, currentK: Expr, exactchecking: Boolean): List[Boogie.Stmt] = etran.Exhale(predicates, occasion, true, currentK, exactchecking)
-
- def CanRead(obj: Boogie.Expr, field: Boogie.Expr): Boogie.Expr = etran.CanRead(obj, field)
- def CanWrite(obj: Boogie.Expr, field: Boogie.Expr): Boogie.Expr = etran.CanWrite(obj, field)
-
-
-/**********************************************************************
-***************** EXPRESSIONS *****************
-**********************************************************************/
-
-/** Represents a predicate that has been folded by ourselfs, or that we have peeked
- * at using unfolding.
- */
-case class FoldedPredicate(predicate: Predicate, receiver: Expr, version: Expr, conditions: Set[(VarExpr,Boolean)], flag: Expr)
-
-/** All information that we need to keep track of about folded predicates. */
-class FoldedPredicatesInfo {
-
- private var foldedPredicates: List[FoldedPredicate] = List()
- var currentConditions: Set[(VarExpr,Boolean)] = Set()
-
- /** Add a predicate that we have folded */
- def addFoldedPredicate(predicate: FoldedPredicate) {
- foldedPredicates ::= predicate
- }
-
- /** Start again with the empty information about folded predicates. */
- def reset {
- foldedPredicates = List()
- currentConditions = Set()
- }
-
- /** return a list of folded predicates that might match for predicate */
- def getFoldedPredicates(predicate: Predicate): List[FoldedPredicate] = {
- foldedPredicates filter (fp => fp.predicate.FullName == predicate.FullName)
- }
-
- /** return a list of all folded predicates */
- def getFoldedPredicates(): List[FoldedPredicate] = {
- foldedPredicates
- }
-
- /** get an upper bound on the recursion depth when updating the secondary mask */
- def getRecursionBound(predicate: Predicate): Int = {
- foldedPredicates length
- }
-
- /** get an upper bound on the recursion depth when updating the secondary mask */
- def getRecursionBound(): Int = {
- foldedPredicates length
- }
-
-}
-object FoldedPredicatesInfo {
- def apply() = new FoldedPredicatesInfo()
-}
-
-case class Globals(heap: Expr, mask: Expr, secmask: Expr, credits: Expr) {
- def list: List[Expr] = List(heap, mask, secmask, credits)
-}
-
-class ExpressionTranslator(val globals: Globals, preGlobals: Globals, val fpi: FoldedPredicatesInfo, currentClass: Class, checkTermination: Boolean) {
-
- import TranslationHelper._
-
- val Heap = globals.heap;
- val Mask = globals.mask;
- val SecMask = globals.secmask;
- val Credits = globals.credits;
- lazy val oldEtran = new ExpressionTranslator(preGlobals, preGlobals, fpi, currentClass, checkTermination)
-
- def this(globals: Globals, preGlobals: Globals, fpi: FoldedPredicatesInfo, currentClass: Class) = this(globals, preGlobals, fpi, currentClass, false)
- def this(globals: Globals, preGlobals: Globals, currentClass: Class) = this(globals, preGlobals, FoldedPredicatesInfo(), currentClass, false)
- def this(globals: Globals, cl: Class) = this(globals, Globals(Boogie.Old(globals.heap), Boogie.Old(globals.mask), Boogie.Old(globals.secmask), Boogie.Old(globals.credits)), cl)
- def this(cl: Class) = this(Globals(VarExpr(HeapName), VarExpr(MaskName), VarExpr(SecMaskName), VarExpr(CreditsName)), cl)
-
- def ChooseEtran(chooseOld: Boolean) = if (chooseOld) oldEtran else this
-
- def isOldEtran = {
- Heap match {
- case Boogie.Old(_) => true
- case _ => false
- }
- }
-
- /** return a new etran which is identical, expect for the fpi */
- def resetFpi = {
- new ExpressionTranslator(globals, preGlobals, new FoldedPredicatesInfo, currentClass, checkTermination)
- }
-
- /**
- * Create a list of fresh global variables
- */
- def FreshGlobals(prefix: String): (List[Boogie.BVar], Globals) = {
- val vs = new Boogie.BVar(prefix + HeapName, theap, true) ::
- new Boogie.BVar(prefix + MaskName, tmask, true) ::
- new Boogie.BVar(prefix + SecMaskName, tmask, true) ::
- new Boogie.BVar(prefix + CreditsName, tcredits, true) ::
- Nil
- val es = vs map {v => new Boogie.VarExpr(v)}
- (vs, Globals(es(0), es(1), es(2), es(3)))
- }
-
- def FromPreGlobals(pg: Globals) = {
- new ExpressionTranslator(globals, pg, fpi, currentClass, checkTermination)
- }
-
- def UseCurrentAsOld() = {
- new ExpressionTranslator(globals, globals, fpi, currentClass, checkTermination);
- }
-
- def WhereOldIs(h: Boogie.Expr, m: Boogie.Expr, sm: Boogie.Expr, c: Boogie.Expr) = {
- new ExpressionTranslator(globals, Globals(h, m, sm, c), fpi, currentClass, checkTermination);
- }
-
- def CheckTermination(check: Boolean) = {
- new ExpressionTranslator(globals, preGlobals, fpi, currentClass, check);
- }
-
- /**********************************************************************
- ***************** TR/DF *****************
- **********************************************************************/
-
- def isDefined(e: Expression)(implicit assumption: Expr): List[Boogie.Stmt] = {
- def prove(goal: Expr, pos: Position, msg: String)(implicit assumption: Expr) =
- bassert(assumption ==> goal, pos, msg)
-
- desugar(e) match {
- case IntLiteral(n) => Nil
- case BoolLiteral(b) => Nil
- case NullLiteral() => Nil
- case StringLiteral(s) => Nil
- case MaxLockLiteral() => Nil
- case LockBottomLiteral() => Nil
- case _:ThisExpr => Nil
- case _:Result => Nil
- case _:BoogieExpr => Nil
- case _:VariableExpr => Nil
- case fs @ MemberAccess(e, f) =>
- assert(!fs.isPredicate);
- isDefined(e) :::
- prove(nonNull(Tr(e)), e.pos, "Receiver might be null.") ::
- prove(CanRead(Tr(e), fs.f.FullName), fs.pos, "Location might not be readable.")
- case Full | Star | Epsilon | MethodEpsilon => Nil
- case ForkEpsilon(token) => isDefined(token)
- case MonitorEpsilon(Some(monitor)) => isDefined(monitor)
- case ChannelEpsilon(Some(channel)) => isDefined(channel)
- case PredicateEpsilon(_) => Nil
- case ChannelEpsilon(None) | MonitorEpsilon(None) => Nil
- case PermPlus(l,r) => isDefined(l) ::: isDefined(r)
- case PermMinus(l,r) => isDefined(l) ::: isDefined(r)
- case PermTimes(l,r) => isDefined(l) ::: isDefined(r)
- case IntPermTimes(l,r) => isDefined(l) ::: isDefined(r)
- case Frac(perm) => isDefined(perm)
- case Epsilons(p) => isDefined(p)
- case _:PermissionExpr => throw new InternalErrorException("permission expression unexpected here: " + e.pos + " (" + e + ")")
- case c@Credit(e, n) =>
- isDefined(e) :::
- isDefined(c.N)
- case Holds(e) =>
- isDefined(e)
- case RdHolds(e) =>
- isDefined(e)
- case _: Assigned => Nil
- case Old(e) =>
- oldEtran.isDefined(e)
- case IfThenElse(con, then, els) =>
- isDefined(con) ::: Boogie.If(Tr(con), isDefined(then), isDefined(els))
- case Not(e) =>
- isDefined(e)
- case func@FunctionApplication(obj, id, args) =>
- val (tmpGlobalsV, tmpGlobals) = this.FreshGlobals("fapp")
- val tmpTranslator = new ExpressionTranslator(tmpGlobals, this.oldEtran.globals, currentClass);
-
- // pick new k
- val (funcappKV, funcappK) = Boogie.NewBVar("funcappK", treal, true)
-
- // check definedness of receiver
- (if (!func.f.isStatic) {
- isDefined(obj)
- } else Nil) :::
- // check definedness of arguments
- (args flatMap { arg => isDefined(arg) }) :::
- // check that receiver is not null
- (if (!func.f.isStatic) {
- List(prove(nonNull(Tr(obj)), obj.pos, "Receiver might be null."))
- } else Nil) :::
- // check precondition of the function by exhaling the precondition in tmpHeap/tmpMask/tmpCredits
- Comment("check precondition of call") ::
- BLocal(funcappKV) :: bassume(0.0 < funcappK && 1000.0*funcappK < percentPermission(1)) ::
- bassume(assumption) ::
- BLocals(tmpGlobalsV) :::
- copyState(tmpGlobals, this) :::
- tmpTranslator.Exhale(Preconditions(func.f.spec) map { pre=> (if (func.f.isStatic) SubstVars(pre, func.f.ins, args) else SubstVars(pre, obj, func.f.ins, args), ErrorMessage(func.pos, "Precondition at " + pre.pos + " might not hold."))},
- "function call",
- false, funcappK, false) :::
- // size of the heap of callee must be strictly smaller than size of the heap of the caller
- (if(checkTermination) { List(prove(NonEmptyMask(tmpGlobals.mask), func.pos, "The heap of the callee might not be strictly smaller than the heap of the caller.")) } else Nil)
- case unfolding@Unfolding(acc@Access(pred@MemberAccess(obj, f), perm), e) =>
- val (tmpGlobalsV, tmpGlobals) = this.FreshGlobals("unfolding")
- val tmpTranslator = new ExpressionTranslator(tmpGlobals, this.oldEtran.globals, currentClass);
- val o = Tr(obj)
- val (flagV, flag) = Boogie.NewBVar("predFlag", tbool, true)
-
- val receiverOk = isDefined(obj) ::: prove(nonNull(o), obj.pos, "Receiver might be null.");
- val definition = scaleExpressionByPermission(SubstThis(DefinitionOf(pred.predicate), obj), perm, unfolding.pos)
-
- // pick new k
- val (unfoldingKV, unfoldingK) = Boogie.NewBVar("unfoldingK", treal, true)
- // record version of unfolded instance
- val (receiverV, receiver) = Boogie.NewBVar("predRec", tref, true)
- val (versionV, version) = Boogie.NewBVar("predVer", tint, true)
-
- val res = Comment("unfolding") ::
- BLocal(unfoldingKV) :: bassume(0.0 < unfoldingK && 1000.0*unfoldingK < percentPermission(1)) ::
- BLocal(flagV) :: (flag := true) ::
- BLocal(receiverV) :: (receiver := o) ::
- BLocal(versionV) :: (version := etran.Heap.select(o, pred.predicate.FullName)) :::
- // check definedness
- receiverOk ::: isDefined(perm) :::
- // copy state into temporary variables
- BLocals(tmpGlobalsV) :::
- copyState(tmpGlobals, this) :::
- // exhale the predicate
- tmpTranslator.ExhaleDuringUnfold(List((acc, ErrorMessage(unfolding.pos, "Unfolding might fail."))), "unfolding", false, unfoldingK, false) :::
- // inhale the definition of the predicate
- tmpTranslator.Inhale(List(definition), "unfolding", false, unfoldingK, receiver, pred.predicate.FullName, version) :::
- // update the predicate mask to indicate the predicates that are folded under 'pred'
- (if (isOldEtran) Nil
- else etran.keepFoldedLocations(definition, o, pred.predicate, etran.Mask, etran.Heap, etran.fpi.getFoldedPredicates(pred.predicate))) :::
- // check definedness of e in state where the predicate is unfolded
- tmpTranslator.isDefined(e) :::
- bassume(wf(etran.Heap, etran.Mask, etran.SecMask)) :: Nil
-
- // record folded predicate
- //val version = Heap.select(o, pred.predicate.FullName)
- if (!isOldEtran) fpi.addFoldedPredicate(FoldedPredicate(pred.predicate, o, version, fpi.currentConditions, flag))
-
- res
- case Iff(e0,e1) =>
- isDefined(e0) ::: isDefined(e1)
- case Implies(e0,e1) =>
- isDefined(e0) ::: isDefined(e1)(assumption && Tr(e0))
- case And(e0,e1) =>
- isDefined(e0) ::: isDefined(e1)(assumption && Tr(e0))
- case Or(e0,e1) =>
- isDefined(e0) ::: isDefined(e1)(assumption && Boogie.UnaryExpr("!", Tr(e0)))
- case LockBelow(e0,e1) =>
- var df = isDefined(e0) ::: isDefined(e1);
- if (e0.typ.IsRef) {
- df = df ::: List(prove(nonNull(Tr(e0)), e0.pos, "Receiver might be null."), prove(CanRead(Tr(e0),"mu"), e0.pos, "The mu field might not be readable."));
- }
- if (e1.typ.IsRef) {
- df = df ::: List(prove(nonNull(Tr(e1)), e1.pos, "Receiver might be null."), prove(CanRead(Tr(e1),"mu"), e1.pos, "The mu field might not be readable."));
- }
- df
- case e: CompareExpr =>
- isDefined(e.E0) ::: isDefined(e.E1)
- case Div(e0,e1) =>
- isDefined(e0) ::: isDefined(e1) :::
- List(prove(Tr(e1) !=@ 0, e1.pos, "Denominator might be zero."))
- case Mod(e0,e1) =>
- isDefined(e0) ::: isDefined(e1) ::: List(prove(Tr(e1) !=@ 0, e1.pos, "Denominator might be zero."))
- case e: ArithmeticExpr =>
- isDefined(e.E0) ::: isDefined(e.E1)
- case EmptySeq(t) => Nil
- case ExplicitSeq(es) =>
- es flatMap { e => isDefined(e) }
- case Range(min, max) =>
- isDefined(min) ::: isDefined(max) :::
- prove(Tr(min) <= Tr(max), e.pos, "Range minimum might not be smaller or equal to range maximum.")
- case Append(e0, e1) =>
- isDefined(e0) ::: isDefined(e1)
- case at@At(e0, e1) =>
- isDefined(e0) ::: isDefined(e1) :::
- prove(0 <= Tr(e1), at.pos, "Sequence index might be negative.") ::
- prove(Tr(e1) < SeqLength(Tr(e0)), at.pos, "Sequence index might be larger than or equal to the length of the sequence.")
- case Drop(e0, e1) =>
- isDefined(e0) ::: isDefined(e1) :::
- prove(0 <= Tr(e1), e.pos, "Cannot drop less than zero elements.") ::
- prove(Tr(e1) <= SeqLength(Tr(e0)), e.pos, "Cannot drop more than elements than the length of the sequence.")
- case Take(e0, e1) =>
- isDefined(e0) ::: isDefined(e1) :::
- prove(0 <= Tr(e1), e.pos, "Cannot take less than zero elements.") ::
- prove(Tr(e1) <= SeqLength(Tr(e0)), e.pos, "Cannot take more than elements than the length of the sequence.")
- case Length(e) =>
- isDefined(e)
- case Contains(e0, e1) =>
- isDefined(e0) ::: isDefined(e1)
- case Eval(h, e) =>
- val (evalHeap, evalMask, evalSecMask, evalCredits, checks, assumptions) = fromEvalState(h);
- val evalEtran = new ExpressionTranslator(Globals(evalHeap, evalMask, evalSecMask, evalCredits), this.oldEtran.globals, currentClass);
- evalEtran.isDefined(e)
- case _ : SeqQuantification => throw new InternalErrorException("should be desugared")
- case tq @ TypeQuantification(_, _, _, e, (min, max)) =>
- // replace variables since we need locals
- val vars = tq.variables map {v => val result = new Variable(v.id, v.t); result.pos = v.pos; result;}
- prove(Tr(min) <= Tr(max), e.pos, "Range minimum might not be smaller or equal to range maximum.") :::
- (vars map {v => BLocal(Variable2BVarWhere(v))}) :::
- isDefined(SubstVars(e, tq.variables, vars map {v => new VariableExpr(v);}))
- case tq @ TypeQuantification(_, _, _, e, _) =>
- // replace variables since we need locals
- val vars = tq.variables map {v => val result = new Variable(v.id, v.t); result.pos = v.pos; result;}
- (vars map {v => BLocal(Variable2BVarWhere(v))}) :::
- isDefined(SubstVars(e, tq.variables, vars map {v => new VariableExpr(v);}))
- }
- }
-
- /** Translate an expression, using 'trrec' in the recursive calls (which takes
- * the expression and an expression translator as argument). The default
- * behaviour is to translate only pure assertions (and throw and error otherwise).
- */
- def Tr(e: Expression): Boogie.Expr = (Tr(e,false))._1
- def Tr(e: Expression, listNeeded: Boolean) : (Boogie.Expr, List[Boogie.Stmt]) = (Tr(e, (ee,et) => et.Tr(ee,listNeeded), listNeeded))
- def Tr(e: Expression, trrec: (Expression, ExpressionTranslator) => (Boogie.Expr, List[Boogie.Stmt]), listNeeded: Boolean = false): (Boogie.Expr, List[Boogie.Stmt]) = {
- def trrecursive(e: Expression): (Boogie.Expr, List[Boogie.Stmt]) = trrec(e, this)
- desugar(e) match {
- case IntLiteral(n) => (n,Nil)
- case BoolLiteral(b) => (b,Nil)
- case NullLiteral() => (bnull,Nil)
- case StringLiteral(s) =>
- // since there currently are no operations defined on string, except == and !=, just translate
- // each string to a unique number
- (s.hashCode(),Nil)
- case BoogieExpr(b) => (b,Nil)
- case MaxLockLiteral() => throw new InternalErrorException("waitlevel case should be handled in << and == and !=")
- case LockBottomLiteral() => (bLockBottom,Nil)
- case _:ThisExpr => (VarExpr("this"),Nil)
- case _:Result => (VarExpr("result"),Nil)
- case ve : VariableExpr => (VarExpr(ve.v.UniqueName),Nil)
- case fs @ MemberAccess(e,_) =>
- assert(! fs.isPredicate);
- var (ee,ll) = trrecursive(e)
- var r = Heap.select(ee, fs.f.FullName);
- if (fs.f.isInstanceOf[SpecialField] && fs.f.id == "joinable")
- (r !=@ 0,ll) // joinable is encoded as an integer
- else
- (r,ll)
- case _:Permission => throw new InternalErrorException("permission unexpected here")
- case _:PermissionExpr => throw new InternalErrorException("permission expression unexpected here: " + e.pos)
- case _:Credit => throw new InternalErrorException("credit expression unexpected here")
- case Holds(e) =>
- var (ee,ll) = trrecursive(e)
- ((0 < Heap.select(ee, "held")) &&
- !Heap.select(ee, "rdheld"),ll)
- case RdHolds(e) =>
- var (ee,ll) = trrecursive(e)
- (Heap.select(ee, "rdheld"),ll)
- case a: Assigned =>
- (VarExpr("assigned$" + a.v.UniqueName),Nil)
- case Old(e) =>
- trrec(e, oldEtran)
- case IfThenElse(con, then, els) =>
- var (conE,conL) = trrecursive(con)
- var (thenE,thenL) = trrecursive(then)
- var (elsE,elsL) = trrecursive(els)
- (Boogie.Ite(conE, thenE, elsE), (if (listNeeded) (conL ::: thenL ::: elsL) else Nil)) // of type: VarExpr(TrClass(then.typ))
- case Not(e) =>
- var (ee,ll) = trrecursive(e)
- ((! ee),ll)
- case func@FunctionApplication(obj, id, args) => {
- var fullArgs = if (!func.f.isStatic) (obj :: args) else (args)
- var trArgs = fullArgs map {arg => trrecursive(arg)} // yields a list of (Expr, List[Boogie.Stmt]) pairs
- var trArgsE = trArgs.foldRight(List[Boogie.Expr]())((el, ll) => el._1 :: ll) // collect list of exprs
- var trArgsL = if (listNeeded) (trArgs.foldRight(List[Boogie.Stmt]())((x,y) => ((x._2) ::: y))) else Nil // concatenate lists of statements
- (FunctionApp(functionName(func.f), Heap :: trArgsE),trArgsL)
- }
- case uf@Unfolding(acc@Access(pred@MemberAccess(obj, f), perm), ufexpr) =>
- // record extra information resulting from "peeking inside" the predicate, generating appropriate statements (this is used in Exhale of an expression)
- val (ee,ll) = trrecursive(ufexpr)
- val (receiverV, receiver) = Boogie.NewBVar("predRec", tref, true)
- val (versionV, version) = Boogie.NewBVar("predVer", tint, true)
- val (flagV, flag) = Boogie.NewBVar("predFlag", tbool, true)
- val o = TrExpr(obj);
-
- val stmts = if (listNeeded) (BLocal(receiverV) :: (receiver := o) ::
- BLocal(flagV) :: (flag := true) ::
- functionTrigger(o, pred.predicate) ::
- BLocal(versionV) :: (version := Heap.select(o, pred.predicate.FullName)) :::
- // UpdateSecMaskDuringUnfold(pred.predicate, o, Heap.select(o, pred.predicate.FullName), perm, currentK) :::
- TransferPermissionToSecMask(pred.predicate, BoogieExpr(receiver), perm, uf.pos, receiver, pred.predicate.FullName, version)) else Nil
-
- (ee, ll ::: stmts)
- case Iff(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((ee0 <==> ee1), if (listNeeded) (l0 ::: l1) else Nil)
- case Implies(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((ee0 ==> ee1), if (listNeeded) (l0 ::: l1) else Nil)
- case And(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((ee0 && ee1), if (listNeeded) (l0 ::: l1) else Nil)
- case Or(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((ee0 || ee1), if (listNeeded) (l0 ::: l1) else Nil)
- case Eq(e0,e1) =>
- (ShaveOffOld(e0), ShaveOffOld(e1)) match {
- case ((MaxLockLiteral(),o0), (MaxLockLiteral(),o1)) =>
- if (o0 == o1)
- (true, Nil) // in this case, l0 and l1 would be Nil, (and Tr((MaxLockLiteral(),_)) is not defined)
- else
- (MaxLockPreserved, Nil) // in this case, l0 and l1 would be Nil, (and Tr((MaxLockLiteral(),_)) is not defined)
- case ((MaxLockLiteral(),o), _) =>
- var (ee1,l1) = trrecursive(e1)
- (ChooseEtran(o).IsHighestLock(ee1), l1) // in this case, l0 would be Nil, (and Tr((MaxLockLiteral(),_)) is not defined)
- case (_, (MaxLockLiteral(),o)) =>
- var (ee0,l0) = trrecursive(e0)
- (ChooseEtran(o).IsHighestLock(ee0), l0) // in this case, l1 would be Nil, (and Tr((MaxLockLiteral(),_)) is not defined)
- case _ =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((if(e0.typ.IsSeq) FunctionApp("Seq#Equal", List(ee0, ee1)) else (ee0 ==@ ee1)), if (listNeeded) (l0 ::: l1) else Nil)
- }
- case Neq(e0,e1) =>
- trrecursive(Not(Eq(e0,e1)))
- case Less(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 < ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case AtMost(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 <= ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case AtLeast(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 >= ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case Greater(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 > ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case LockBelow(e0,e1) => {
- def MuValue(b: Expression): (Boogie.Expr, List[Boogie.Stmt]) = (
- trrecursive(b) match {
- case (eb, lb) =>
- ((if (b.typ.IsRef) new Boogie.MapSelect(Heap, eb, "mu") else eb),lb)
- }
- )
- (ShaveOffOld(e0), ShaveOffOld(e1)) match {
- case ((MaxLockLiteral(),o0), (MaxLockLiteral(),o1)) =>
- if (o0 == o1)
- (false,Nil) // in this case, l0 and l1 are guaranteed to be Nil
- else
- (TemporalMaxLockComparison(ChooseEtran(o0), ChooseEtran(o1)),Nil) // in this case, l0 and l1 are guaranteed to be Nil
- case ((MaxLockLiteral(),o), _) =>
- var (ee1, l1) = MuValue(e1)
- (ChooseEtran(o).MaxLockIsBelowX(ee1),l1)
- case (_, (MaxLockLiteral(),o)) =>
- var (ee0, l0) = MuValue(e0)
- (ChooseEtran(o).MaxLockIsAboveX(ee0),l0)
- case _ =>
- var (ee0, l0) = MuValue(e0)
- var (ee1, l1) = MuValue(e1)
- ((new FunctionApp("MuBelow", ee0, ee1)), if (listNeeded) (l0 ::: l1) else Nil) }
- }
- case Plus(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 + ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case Minus(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 - ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case Times(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 * ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case Div(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 / ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case Mod(e0,e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (ee0 % ee1, if (listNeeded) (l0 ::: l1) else Nil)
- case EmptySeq(t) =>
- (createEmptySeq, Nil)
- case ExplicitSeq(es) =>
- es match {
- case Nil => (createEmptySeq, Nil)
- case h :: Nil =>
- var (eh,lh) = trrecursive(h)
- (createSingletonSeq(eh),lh)
- case h :: t =>
- var (eh,lh) = trrecursive(h)
- var (et,lt) = trrecursive(ExplicitSeq(t))
- ((createAppendSeq(createSingletonSeq(eh), et)), if (listNeeded) (lh ::: lt) else Nil)
- }
- case Range(min, max) =>
- var (emin,lmin) = trrecursive(min)
- var (emax,lmax) = trrecursive(max)
- ((createRange(emin, emax)), if (listNeeded) (lmin ::: lmax) else Nil)
- case Append(e0, e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((createAppendSeq(ee0, ee1)), if (listNeeded) (l0 ::: l1) else Nil)
- case at@At(e0, e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((SeqIndex(ee0, ee1)), if (listNeeded) (l0 ::: l1) else Nil)
- case Drop(e0, e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- e1 match {
- case IntLiteral(0) =>
- (ee0, if (listNeeded) (l0 ::: l1) else Nil)
- case _ =>
- ((Boogie.FunctionApp("Seq#Drop", List(ee0, ee1))), if (listNeeded) (l0 ::: l1) else Nil)
- }
- case Take(e0, e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- ((Boogie.FunctionApp("Seq#Take", List(ee0, ee1))), if (listNeeded) (l0 ::: l1) else Nil)
- case Length(e) =>
- var (ee,l) = trrecursive(e)
- (SeqLength(ee), l)
- case Contains(e0, e1) =>
- var (ee0,l0) = trrecursive(e0)
- var (ee1,l1) = trrecursive(e1)
- (SeqContains(ee1, ee0), if (listNeeded) (l0 ::: l1) else Nil) // Note: swapping of arguments
- case Eval(h, e) =>
- val (evalHeap, evalMask, evalSecMask, evalCredits, checks, assumptions) = fromEvalState(h);
- val evalEtran = new ExpressionTranslator(Globals(evalHeap, evalMask, evalSecMask, evalCredits), oldEtran.globals, currentClass);
- trrec(e, evalEtran)
- case _:SeqQuantification => throw new InternalErrorException("should be desugared")
- case tq @ TypeQuantification(Forall, _, _, e, _) =>
- val(ee,l) = trrecursive(e)
- val groupedTriggerSets = generateTriggers(tq.variables,e)
- val oneQuantifier : (((List[Trigger],List[Variable])) => Boogie.Expr) = ((trigsAndExtraVars) => (Boogie.Forall(Nil, (tq.variables ::: trigsAndExtraVars._2) map { v => Variable2BVar(v)}, trigsAndExtraVars._1, ee)))
- var firstTriggerSet : (List[Trigger],List[Variable]) = (Nil,Nil);
- var restTriggerSet : List[(List[Trigger],List[Variable])] = Nil;
-
- groupedTriggerSets match {
- case Nil =>
- firstTriggerSet = (Nil,Nil); // we will generate no triggers for this quantifier
- restTriggerSet = Nil
- case ts :: rest =>
- firstTriggerSet = ts;
- restTriggerSet = rest
- }
- (restTriggerSet.foldRight(oneQuantifier(firstTriggerSet))((trigset,expr) => (oneQuantifier(trigset) && expr)),l)
- case tq @ TypeQuantification(Exists, _, _, e, _) =>
- var (ee,l) = trrecursive(e)
- ((Boogie.Exists(Nil, tq.variables map { v => Variable2BVar(v)}, Nil, ee)),l)
- }
- }
-
- // This is used for searching for triggers for quantifiers around the expression "toSearch". The list "vs" gives the variables which need triggering
- // Returns a list of function applications (the framing function) paired with two sets of variables.
- // The first set of variables shows which of the "vs" occur (useful for deciding how to select applications for trigger sets later)
- // The second set of variables indicated the extra boolean variables which were introduced to "hide" problematic logical/comparison operators which may not occur in triggers.
- // e.g., if vs = [x] and toSearch = f(x, y ==> z) then a singleton list will be returned, containing (f(x,b),{x},{b}).
- def getFunctionAppsContaining(vs:List[Variable], toSearch : Expression): (List[(Boogie.FunctionApp,Set[Variable],Set[Variable])]) = {
- var functions: List[(Boogie.FunctionApp,Set[Variable],Set[Variable])] = List() // accumulate candidate functions to return
- var nestedBoundVars : List[Variable] = List(); // count all variables bound in nested quantifiers, to avoid considering function applications mentioning these
-
- // get all nested bound vars
- toSearch visit {
- _ match {
- case qe : Quantification =>
- nestedBoundVars :::= qe.variables
- case _ =>
- }
- }
-
- // get all function applications
- toSearch visit {
- _ match {
- case fapp@FunctionApplication(obj, id, args) =>
- var extraVars : Set[Variable] = Set() // collect extra variables generated for this term
- var containsNestedBoundVars = false // flag to rule out this term
- // closure to generate fresh boolean variable
- val freshBoolVar : (() => Option[Expression]) = {() =>
- val newV = new Variable("b", new Type(BoolClass))
- extraVars += newV;
- Some(new VariableExpr(newV))
- }
- // replaces problematic logical/comparison expressions with fresh boolean variables
- val boolExprEliminator : (Expression => Option[Expression]) = ((expr:Expression) =>
- expr match {
- case exp@Not(e) => freshBoolVar()
- case exp@Iff(e0,e1) => freshBoolVar()
- case exp@Implies(e0,e1) => freshBoolVar()
- case exp@And(e0,e1) => freshBoolVar()
- case exp@Or(e0,e1) => freshBoolVar()
- case Eq(e0,e1) => freshBoolVar()
- case Neq(e0,e1) => freshBoolVar()
- case Less(e0,e1) => freshBoolVar()
- case AtMost(e0,e1) => freshBoolVar()
- case AtLeast(e0,e1) => freshBoolVar()
- case Greater(e0,e1) => freshBoolVar()
- case _ => None
- });
- var containedVars : Set[Variable] = Set()
- val processedArgs = args map (_.transform(boolExprEliminator)) // eliminate all boolean expressions forbidden from triggers, and replace with "extraVars"
- // collect all the sought (vs) variables in the function application
- processedArgs map {e => e visit {_ match {
- case ve@VariableExpr(s) =>
- val v : Variable = ve.v
- if (nestedBoundVars.contains(v)) (containsNestedBoundVars = true);
- if (vs.contains(v)) (containedVars += v)
- case _ =>}
- }
- }
- if (!containsNestedBoundVars && !containedVars.isEmpty) {
- val fullArgs = if (!fapp.f.isStatic) (obj :: processedArgs) else (processedArgs)
- val noOldETran = this.UseCurrentAsOld();
- val trArgs = fullArgs map {arg => noOldETran.Tr(arg)} // translate args
- val triggerFunctionName = functionName(fapp.f) + "#limited#trigger";
- functions ::= (FunctionApp(triggerFunctionName, trArgs),containedVars,extraVars)
- }
- case _ =>}
- }
- functions
- }
-
-
-
-
- // Precondition : if vars is non-empty then every (f,vs) pair in functs satisfies the property that vars and vs are not disjoint.
- // Finds trigger sets by selecting entries from "functs" until all of "vars" occur, and accumulating the extra variables needed for each function term.
- // Returns a list of the trigger sets found, paired with the extra boolean variables they use
-def buildTriggersCovering(vars : Set[Variable], functs : List[(Boogie.FunctionApp,Set[Variable],Set[Variable])], currentTrigger : List[Expr], extraVars : Set[Variable]) : List[(Trigger,Set[Variable])] = {
- if (vars.isEmpty) (List((Boogie.Trigger(currentTrigger),extraVars))) // we have found a suitable trigger set
- else (functs match {
- case Nil => Nil // this branch didn't result in a solution
- case ((f,vs,extra) :: rest) => {
- val needed : Set[Variable] = vars.diff(vs) // variables still not triggered
- // try adding the next element of functs, or not..
- buildTriggersCovering(needed, (rest.filter(func => !func._2.intersect(needed).isEmpty)), f :: currentTrigger, extraVars|extra) ::: buildTriggersCovering(vars, rest, currentTrigger, extraVars)
- }
- }
- )
- }
-
-
- // Generates trigger sets to cover the variables "vs", by searching the expression "toSearch".
- // Returns a list of pairs of lists of trigger sets couple with the extra variables they require to be quantified over (each list of triggers must contain trigger sets which employ exactly the same extra variables).
- def generateTriggers(vs: List[Variable], toSearch : Expression) : List[(List[Trigger],List[Variable])] = {
- val functionApps : (List[(Boogie.FunctionApp,Set[Variable],Set[Variable])]) = getFunctionAppsContaining(vs, toSearch) // find suitable function applications
- if (functionApps.isEmpty) List() else {
- var triggerSetsToUse : List[(Trigger,Set[Variable])] = buildTriggersCovering(Set() ++ vs, functionApps, Nil, Set())
- var groupedTriggerSets : List[(List[Trigger],List[Variable])] = List() // group trigger sets by those which use the same sets of extra boolean variables
-
- while (!triggerSetsToUse.isEmpty) {
- triggerSetsToUse.partition((ts : (Trigger,Set[Variable])) => triggerSetsToUse.head._2.equals(ts._2)) match {
- case (sameVars,rest) =>
- triggerSetsToUse = rest;
- groupedTriggerSets ::= ((sameVars map (_._1)), sameVars.head._2.toList)
- }
- }
- groupedTriggerSets
- }
- }
-
-
- /** translate everything, including permissions and credit expressions */
- // Since this is only used in axiom generation (so far), the ability to generate "side-effects" from the evaluation of unfolding expressions (as in the list of boogie statements returned from Tr) is not implemented here (in axioms the side-effects are not wanted anyway)
- def TrAll(e: Expression): Expr = {
- def TrAllHelper(e: Expression, etran: ExpressionTranslator): Expr = e match {
- case pred@MemberAccess(e, p) if pred.isPredicate =>
- val tmp = Access(pred, Full); tmp.pos = pred.pos
- TrAll(tmp)
- case acc@Access(e,perm) =>
- val memberName = if(e.isPredicate) e.predicate.FullName else e.f.FullName;
- CanRead(Tr(e.e), memberName)
- case acc @ AccessSeq(s, Some(member), perm) =>
- if (member.isPredicate) throw new NotSupportedException("not yet implemented");
- val memberName = member.f.FullName;
- val (refV, ref) = Boogie.NewBVar("ref", tref, true);
- (SeqContains(Tr(s), ref) ==> CanRead(ref, memberName)).forall(refV)
- case _ => (etran.Tr(e, (ee : Expression, et : ExpressionTranslator) => (TrAllHelper(ee,et),Nil)))._1 //wrap TrAllHelper to give it the return type needed for Tr.
- }
- TrAllHelper(e, this)
- }
-
- def ShaveOffOld(e: Expression): (Expression, Boolean) = e match {
- case Old(e) =>
- val (f,o) = ShaveOffOld(e)
- (f,true)
- case _ => (e,false)
- }
- def IsMaxLockLit(e: Expression) = {
- val (f,o) = ShaveOffOld(e)
- f.isInstanceOf[MaxLockLiteral]
- }
-
- /**********************************************************************
- ***************** INHALE/EXHALE *****************
- **********************************************************************/
-
- def Inhale(predicates: List[Expression], occasion: String, check: Boolean, currentK: Expr, unfoldReceiver: VarExpr = null, unfoldPredicateName: String = null, unfoldVersion: VarExpr = null): List[Boogie.Stmt] = {
- if (predicates.size == 0) return Nil;
-
- //val (ihV, ih) = Boogie.NewBVar("inhaleHeap", theap, true)
- Comment("inhale (" + occasion + ")") ::
- //BLocal(ihV) :: Boogie.Havoc(ih) ::
- //bassume(IsGoodInhaleState(ih, Heap, Mask, SecMask)) ::
- (for (p <- predicates) yield Inhale(p, Heap, check, currentK, unfoldReceiver, unfoldPredicateName, unfoldVersion)).flatten :::
- bassume(AreGoodMasks(Mask, SecMask)) ::
- bassume(wf(Heap, Mask, SecMask)) ::
- Comment("end inhale")
- }
-
- def InhalePermission(perm: Permission, obj: Expr, memberName: String, currentK: Expr, m: Expr = Mask): List[Boogie.Stmt] = {
-
- val (f, stmts) = extractKFromPermission(perm, currentK)
- val n = extractEpsilonsFromPermission(perm);
-
- stmts :::
- (perm.permissionType match {
- case PermissionType.Mixed =>
- bassume(f > 0.0 || (f == 0.0 && n > 0.0)) ::
- IncPermission(obj, memberName, f, m) :::
- IncPermissionEpsilon(obj, memberName, n, m)
- case PermissionType.Epsilons =>
- bassume(n > 0.0) ::
- IncPermissionEpsilon(obj, memberName, n, m)
- case PermissionType.Fraction =>
- bassume(f > 0.0) ::
- IncPermission(obj, memberName, f, m)
- })
- }
-
- def Inhale(p: Expression, ih: Boogie.Expr, check: Boolean, currentK: Expr, unfoldReceiver: VarExpr, unfoldPredicateName : String, unfoldVersion: VarExpr): List[Boogie.Stmt] =
- InhaleImplementation(p, ih, check, currentK, false, unfoldReceiver, unfoldPredicateName, unfoldVersion)
-
- def InhaleToSecMask(p: Expression, unfoldingReceiver: VarExpr = null, unfoldingPredicateName: String = null, unfoldingVersion: VarExpr = null): List[Boogie.Stmt] =
- InhaleImplementation(p, Heap /* it should not matter what we pass here */, false /* check */, -1 /* it should not matter what we pass here */, true, unfoldingReceiver, unfoldingPredicateName, unfoldingVersion)
-
- def InhaleImplementation(p: Expression, ih: Boogie.Expr, check: Boolean, currentK: Expr, transferToSecMask: Boolean, unfoldReceiver: VarExpr = null, unfoldPredicateName: String = null, unfoldVersion: VarExpr = null): List[Boogie.Stmt] = desugar(p) match {
- case pred@MemberAccess(e, p) if pred.isPredicate =>
- val chk = (if (check) {
- isDefined(e)(true) :::
- bassert(nonNull(Tr(e)), e.pos, "Receiver might be null.") :: Nil
- } else Nil)
- val tmp = Access(pred, Full);
- tmp.pos = pred.pos;
- chk ::: InhaleImplementation(tmp, ih, check, currentK, transferToSecMask, unfoldReceiver, unfoldPredicateName, unfoldVersion)
- case AccessAll(obj, perm) => throw new InternalErrorException("should be desugared")
- case AccessSeq(s, None, perm) => throw new InternalErrorException("should be desugared")
- case acc@Access(e,perm) =>
- val trE = Tr(e.e)
- val module = currentClass.module;
- val memberName = if(e.isPredicate) e.predicate.FullName else e.f.FullName;
-
- // List(bassert(nonNull(trE), acc.pos, "The target of the acc predicate might be null."))
- (if(check) isDefined(e.e)(true) ::: isDefined(perm)(true)
- else Nil) :::
- bassume(nonNull(trE)) ::
- bassume(wf(Heap, Mask, SecMask)) ::
- (if(e.isPredicate) Nil else List(bassume(TypeInformation(new Boogie.MapSelect(Heap, trE, memberName), e.f.typ.typ)))) :::
- InhalePermission(perm, trE, memberName, currentK, (if (transferToSecMask) SecMask else Mask)) :::
- // record "inside" relationship for predicate instances
- (if(e.isPredicate && unfoldReceiver != null) bassume(FunctionApp("#predicateInside#", unfoldReceiver :: VarExpr(unfoldPredicateName) :: unfoldVersion :: trE :: VarExpr(memberName) :: Heap.select(trE, memberName) :: Nil)) :: Nil else Nil) :::
- bassume(AreGoodMasks(Mask, SecMask)) ::
- bassume(wf(Heap, Mask, SecMask)) ::
- bassume(wf(ih, Mask, SecMask))
- case acc @ AccessSeq(s, Some(member), perm) =>
- if (transferToSecMask) throw new NotSupportedException("not yet implemented")
- if (member.isPredicate) throw new NotSupportedException("not yet implemented");
- val e = Tr(s);
- val memberName = member.f.FullName;
- val (refV, ref) = Boogie.NewBVar("ref", tref, true);
-
- val (r, stmts) = extractKFromPermission(perm, currentK)
- val n = extractEpsilonsFromPermission(perm);
-
- stmts :::
- // assume that the permission is positive
- bassume((SeqContains(e, ref) ==>
- (perm.permissionType match {
- case PermissionType.Fraction => r > 0.0
- case PermissionType.Mixed => r > 0.0 || (r == 0.0 && n > 0.0)
- case PermissionType.Epsilons => n > 0.0
- })).forall(refV)) ::
- (if (check) isDefined(s)(true) ::: isDefined(perm)(true) else Nil) :::
- {
- val (aV,a) = Boogie.NewTVar("alpha");
- val (refV, ref) = Boogie.NewBVar("ref", tref, true);
- val (fV, f) = Boogie.NewBVar("f", FieldType(a), true);
- (Heap := Lambda(List(aV), List(refV, fV),
- (SeqContains(e, ref) && f ==@ memberName).thenElse
- (ih(ref, f), Heap(ref, f)))) ::
- bassume((SeqContains(e, ref) ==> TypeInformation(Heap(ref, memberName), member.f.typ.typ)).forall(refV))
- } :::
- bassume(wf(Heap, Mask, SecMask)) ::
- // update the map
- {
- val (aV,a) = Boogie.NewTVar("alpha");
- val (fV, f) = Boogie.NewBVar("f", FieldType(a), true);
- val (pcV,pc) = Boogie.NewBVar("p", tperm, true);
- Mask := Lambda(List(aV), List(refV, fV),
- (SeqContains(e, ref) && f ==@ memberName).thenElse
- (Lambda(List(), List(pcV),
- Boogie.Ite(pc ==@ "perm$R",
- Mask(ref, f)("perm$R") + r,
- Mask(ref, f)("perm$N") + n)),
- Mask(ref, f)))
- } :::
- bassume(AreGoodMasks(Mask, SecMask)) ::
- bassume(wf(Heap, Mask, SecMask)) ::
- bassume(wf(ih, Mask, SecMask))
- case cr@Credit(ch, n) =>
- val trCh = Tr(ch)
- (if (check)
- isDefined(ch)(true) :::
- bassert(nonNull(trCh), ch.pos, "The target of the credit predicate might be null.") :::
- isDefined(cr.N)(true)
- else
- Nil) :::
- new Boogie.MapUpdate(Credits, trCh, new Boogie.MapSelect(Credits, trCh) + Tr(cr.N))
- case Implies(e0,e1) =>
- (if(check) isDefined(e0)(true) else Nil) :::
- Boogie.If(Tr(e0), InhaleImplementation(e1, ih, check, currentK, transferToSecMask, unfoldReceiver, unfoldPredicateName, unfoldVersion), Nil)
- case IfThenElse(con, then, els) =>
- (if(check) isDefined(con)(true) else Nil) :::
- Boogie.If(Tr(con), InhaleImplementation(then, ih, check, currentK, transferToSecMask, unfoldReceiver, unfoldPredicateName, unfoldVersion), InhaleImplementation(els, ih, check, currentK, transferToSecMask, unfoldReceiver, unfoldPredicateName, unfoldVersion))
- case And(e0,e1) =>
- InhaleImplementation(e0, ih, check, currentK, transferToSecMask) ::: InhaleImplementation(e1, ih, check, currentK, transferToSecMask, unfoldReceiver, unfoldPredicateName, unfoldVersion)
- case holds@Holds(e) =>
- val trE = Tr(e);
- (if(check)
- isDefined(e)(true) :::
- bassert(nonNull(trE), holds.pos, "The target of the holds predicate might be null.")
- else Nil) :::
- bassume(AreGoodMasks(Mask, SecMask)) ::
- bassume(wf(Heap, Mask, SecMask)) ::
- bassume(wf(ih, Mask, SecMask)) ::
- new Boogie.MapUpdate(Heap, trE, VarExpr("held"),
- new Boogie.MapSelect(ih, trE, "held")) ::
- bassume(0 < new Boogie.MapSelect(ih, trE, "held")) ::
- bassume(! new Boogie.MapSelect(ih, trE, "rdheld")) ::
- bassume(new Boogie.MapSelect(ih, trE, "mu") !=@ bLockBottom) ::
- bassume(wf(Heap, Mask, SecMask)) ::
- bassume(AreGoodMasks(Mask, SecMask)) ::
- bassume(wf(Heap, Mask, SecMask)) ::
- bassume(wf(ih, Mask, SecMask))
- case Eval(h, e) =>
- if (transferToSecMask) throw new NotSupportedException("not yet implemented")
- val (evalHeap, evalMask, evalSecMask, evalCredits, checks, proofOrAssume) = fromEvalState(h);
- val (preGlobalsV, preGlobals) = etran.FreshGlobals("eval")
- val preEtran = new ExpressionTranslator(preGlobals, currentClass)
- BLocals(preGlobalsV) :::
- (preGlobals.mask := ZeroMask) ::
- (preGlobals.secmask := ZeroMask) ::
- // Should we start from ZeroMask instead of an arbitrary mask? In that case, assume submask(preEtran.Mask, evalMask); at the end!
- (if(check) checks else Nil) :::
- // havoc the held field when inhaling eval(o.release, ...)
- (if(h.isInstanceOf[ReleaseState]) {
- val (freshHeldV, freshHeld) = NewBVar("freshHeld", tint, true);
- val obj = Tr(h.target());
- List(BLocal(freshHeldV), bassume((0<Heap.select(obj, "held")) <==> (0<freshHeld)), (Heap.select(obj, "held") := freshHeld))
- } else Nil) :::
- bassume(AreGoodMasks(preEtran.Mask, preEtran.SecMask)) ::
- bassume(wf(preEtran.Heap, preEtran.Mask, preEtran.SecMask)) ::
- bassume(proofOrAssume) ::
- preEtran.InhaleImplementation(e, ih, check, currentK, transferToSecMask, unfoldReceiver, unfoldPredicateName, unfoldVersion) :::
- bassume(preEtran.Heap ==@ evalHeap) ::
- bassume(submask(preEtran.Mask, evalMask))
- case uf@Unfolding(acc@Access(pred@MemberAccess(obj, f), perm), ufexpr) =>
- if (transferToSecMask) return Nil
- // handle unfolding like the next case, but also record permissions of the predicate
- // in the secondary mask and track the predicate in the auxilary information
- val (receiverV, receiver) = Boogie.NewBVar("predRec", tref, true)
- val (versionV, version) = Boogie.NewBVar("predVer", tint, true)
- val (flagV, flag) = Boogie.NewBVar("predFlag", tbool, true)
- val o = TrExpr(obj);
-
- val stmts = BLocal(receiverV) :: (receiver := o) ::
- BLocal(flagV) :: (flag := true) ::
- functionTrigger(o, pred.predicate) ::
- BLocal(versionV) :: (version := Heap.select(o, pred.predicate.FullName)) ::
- (if(check) isDefined(uf)(true) else
- if (isOldEtran) Nil else
- // remove secondary permissions (if any), and add them again
- UpdateSecMaskDuringUnfold(pred.predicate, o, Heap.select(o, pred.predicate.FullName), perm, currentK) :::
- TransferPermissionToSecMask(pred.predicate, BoogieExpr(receiver), perm, uf.pos, receiver, pred.predicate.FullName, version)
- ) :::
- bassume(Tr(uf))
-
- // record folded predicate
- if (!isOldEtran) fpi.addFoldedPredicate(FoldedPredicate(pred.predicate, receiver, version, fpi.currentConditions, flag))
-
- stmts
- case e =>
- (if(check) isDefined(e)(true) else Nil) :::
- bassume(Tr(e))
- }
-
- /** Transfer the permissions mentioned in the body of the predicate to the
- * secondary mask.
- */
- def TransferPermissionToSecMask(pred: Predicate, obj: Expression, perm: Permission, pos: Position, unfoldingReceiver: VarExpr = null, unfoldingPredicateName: String = null, unfoldingVersion: VarExpr = null): List[Stmt] = {
- var definition = scaleExpressionByPermission(SubstThis(DefinitionOf(pred), obj), perm, pos)
- // go through definition and handle all permisions correctly
- InhaleToSecMask(definition, unfoldingReceiver, unfoldingPredicateName, unfoldingVersion)
- }
-
- // Exhale is done in two passes: In the first run, everything except permissions
- // which need exact checking are exhaled. Then, in the second run, those
- // permissions are exhaled. The behaviour is controlled with the parameter
- // onlyExactCheckingPermissions.
- // The reason for this behaviour is that we want to support preconditions like
- // "acc(o.f,100-rd) && acc(o.f,rd)", which should be equivalent to a full
- // permission to o.f. However, when we exhale in the given order, we cannot
- // use inexact checking for the abstract read permission ("acc(o.f,rd)"), as
- // this would introduce the (unsound) assumption that "methodcallk < mask[o.f]".
- // To avoid detecting this, we exhale all abstract read permissions first (or,
- // more precisely, we exhale all permissions with exact checking later).
-
- /** Regular exhale */
- def Exhale(predicates: List[(Expression, ErrorMessage)], occasion: String, check: Boolean, currentK: Expr, exactchecking: Boolean): List[Boogie.Stmt] =
- Exhale(Mask, SecMask, predicates, occasion, check, currentK, exactchecking)
- /** Exhale as part of a unfold statement (just like a regular exhale, but no heap havocing) */
- def ExhaleDuringUnfold(predicates: List[(Expression, ErrorMessage)], occasion: String, check: Boolean, currentK: Expr, exactchecking: Boolean): List[Boogie.Stmt] =
- Exhale(Mask, SecMask, predicates, occasion, check, currentK, exactchecking, false, -1, false, null, true)
- /** Regular exhale with specific mask/secmask */
- def Exhale(m: Expr, sm: Expr, predicates: List[(Expression, ErrorMessage)], occasion: String, check: Boolean, currentK: Expr, exactchecking: Boolean): List[Boogie.Stmt] = {
- Exhale(m, sm, predicates, occasion, check, currentK, exactchecking, false, -1, false, null, false)
- }
- /** Exhale that transfers permission to the secondary mask */
- def ExhaleAndTransferToSecMask(receiver: Expr, pred: Predicate, predicates: List[(Expression, ErrorMessage)], occasion: String, currentK: Expr, exactchecking: Boolean, foldReceiver: VarExpr = null, foldPredicateName: String = null, foldVersion: VarExpr = null): List[Boogie.Stmt] = {
- Exhale(receiver, pred, Mask, SecMask, predicates, occasion, false, currentK, exactchecking, true /* transfer to SecMask */, -1, false, null, false, foldReceiver, foldPredicateName, foldVersion)
- }
- /** Remove permission from the secondary mask, and assume all assertions that
- * would get generated. Recursion is bouded by the parameter depth.
- */
- def UpdateSecMask(predicate: Predicate, receiver: Expr, version: Expr, perm: Permission, currentK: Expr): List[Stmt] = {
- val depth = etran.fpi.getRecursionBound(predicate)
- UpdateSecMask(predicate, receiver, version, perm, currentK, depth, Map())
- }
- def UpdateSecMaskDuringUnfold(predicate: Predicate, receiver: Expr, version: Expr, perm: Permission, currentK: Expr): List[Stmt] = {
- UpdateSecMask(predicate, receiver, version, perm, currentK, 1, Map())
- }
- // no longer relevant (as of Sept 2012), since we don't take this approach with secondary mask any more
- def UpdateSecMask(predicate: Predicate, receiver: Expr, version: Expr, perm: Permission, currentK: Expr, depth: Int, previousReceivers: Map[String,List[Expr]]): List[Stmt] = {
- Nil
- }
- /** Most general form of exhale; implements all the specific versions above */
- // Note: If isUpdatingSecMask, then m is actually a secondary mask, and at the
- // moment we do not want an assumption IsGoodMask(SecMask). Therefore, we omit
- // those if isUpdatingSecMask.
- // Furthermore, we do not want to generate assumptions that we have enough
- // permission available (something like "assume 50% >= SecMask[obj,f]"; note
- // that these assumption come from the assertions that check that the necessary
- // permissions are available, and are then turned into assumptions by
- // assertion2assumption.
- //
- // Assumption 1: if isUpdatingSecMask==true, then the exhale heap is not used at
- // all, and the regular heap is not changed.
- // Assumption 2: If isUpdatingSecMask is false, then recurseOnPredicatesDepth
- // is meaningless (and should be -1 by convention). Only if isUpdatingSecMask
- // is true, then the depth is important. It is initially set in the method
- // UpdateSecMask (because only there we have precise knowledge of what upper
- // bound we want to use).
- // Assumption 3: Similarly, if isUpdatingSecMask is false, then the list
- // previousReceivers is not needed, and thus null.
- // Assumption 4+5: duringUnfold can only be true if transferPermissionToSecMask
- // and isUpdatingSecMask are not.
- // Assumption 6: foldReceiver, foldPredicateName, foldVersion are all either non-null (in which case this exhale is the body of the corresponding predicate instance being folded) or all non-null.
- def Exhale(m: Expr, sm: Expr, predicates: List[(Expression, ErrorMessage)], occasion: String, check: Boolean, currentK: Expr, exactchecking: Boolean, transferPermissionToSecMask: Boolean, recurseOnPredicatesDepth: Int, isUpdatingSecMask: Boolean, previousReceivers: Map[String,List[Expr]], duringUnfold: Boolean, foldReceiver: VarExpr = null, foldPredicateName: String = null, foldVersion: VarExpr = null): List[Boogie.Stmt] =
- Exhale(null, null, m, sm, predicates, occasion, check, currentK, exactchecking, transferPermissionToSecMask, recurseOnPredicatesDepth, isUpdatingSecMask, previousReceivers, duringUnfold, foldReceiver, foldPredicateName, foldVersion)
- def Exhale(receiver: Expr, pred: Predicate, m: Expr, sm: Expr, predicates: List[(Expression, ErrorMessage)], occasion: String, check: Boolean, currentK: Expr, exactchecking: Boolean, transferPermissionToSecMask: Boolean, recurseOnPredicatesDepth: Int, isUpdatingSecMask: Boolean, previousReceivers: Map[String,List[Expr]], duringUnfold: Boolean, foldReceiver: VarExpr, foldPredicateName: String, foldVersion: VarExpr): List[Boogie.Stmt] = {
- assert ((isUpdatingSecMask && recurseOnPredicatesDepth >= 0) || (!isUpdatingSecMask && recurseOnPredicatesDepth == -1)) // check assumption 2
- assert (isUpdatingSecMask || (previousReceivers == null))
- assert (!(isUpdatingSecMask && duringUnfold))
- assert (!(transferPermissionToSecMask && duringUnfold))
- assert ((foldReceiver == null) == (foldPredicateName == null))
- assert ((foldPredicateName == null) == (foldVersion == null))
- if (predicates.size == 0) return Nil;
- val (ehV, eh) = Boogie.NewBVar("exhaleHeap", theap, true)
- var (emV, em: Expr) = Boogie.NewBVar("exhaleMask", tmask, true)
- Comment("begin exhale (" + occasion + ")") ::
- (if (!isUpdatingSecMask && !duringUnfold && !transferPermissionToSecMask)
- BLocal(emV) :: (em := m) ::
- BLocal(ehV) :: Boogie.Havoc(eh) :: Nil
- else {
- em = m
- Nil
- }) :::
- (for (p <- predicates) yield ExhaleHelper(p._1, em, sm, eh, p._2, check, currentK, exactchecking, false, transferPermissionToSecMask, recurseOnPredicatesDepth, isUpdatingSecMask, previousReceivers, duringUnfold, foldReceiver, foldPredicateName, foldVersion )).flatten :::
- (for (p <- predicates) yield ExhaleHelper(p._1, em, sm, eh, p._2, check, currentK, exactchecking, true, transferPermissionToSecMask, recurseOnPredicatesDepth, isUpdatingSecMask, previousReceivers, duringUnfold, foldReceiver, foldPredicateName, foldVersion )).flatten :::
- (if (!isUpdatingSecMask && !duringUnfold && !transferPermissionToSecMask)
- (m := em) ::
- bassume(IsGoodExhaleState(eh, Heap, m, sm)) ::
- //restoreFoldedLocations(m, Heap, eh) :::
- (Heap := eh) :: Nil
- else Nil) :::
- (if (isUpdatingSecMask) Nil else bassume(AreGoodMasks(m, sm)) :: Nil) :::
- bassume(wf(Heap, m, sm)) ::
- Comment("end exhale")
- }
-
- /** copy all the values of locations that are folded under any predicate (that we care about) one or more levels down from 'heap' to 'exhaleHeap' */
- def restoreFoldedLocations(mask: Expr, heap: Boogie.Expr, exhaleHeap: Boogie.Expr): List[Boogie.Stmt] = {
- val foldedPredicates = etran.fpi.getFoldedPredicates()
- (for (fp <- foldedPredicates) yield {
- val stmts = bassume(IsGoodExhalePredicateState(exhaleHeap, heap, heap.select(fp.receiver, fp.predicate.FullName+"#m")))
- Boogie.If(CanRead(fp.receiver, fp.predicate.FullName, mask, ZeroMask) && heap.select(fp.receiver, fp.predicate.FullName) ==@ fp.version, stmts, Nil) :: Nil
- }) flatten
- }
-
- /** the actual recursive method for restoreFoldedLocationsHelperPred */
- def keepFoldedLocations(expr: Expression, foldReceiver: Expr, foldPred: Predicate, mask: Expr, heap: Boogie.Expr, otherPredicates: List[FoldedPredicate]): List[Boogie.Stmt] = {
- val f = (expr: Expression) => keepFoldedLocations(expr, foldReceiver, foldPred, mask, heap, otherPredicates)
- expr match {
- case pred@MemberAccess(e, p) if pred.isPredicate =>
- val tmp = Access(pred, Full);
- tmp.pos = pred.pos;
- f(tmp)
- case AccessAll(obj, perm) =>
- throw new InternalErrorException("not implemented yet")
- case AccessSeq(s, None, perm) =>
- throw new InternalErrorException("not implemented yet")
- case acc@Access(e,perm) =>
- val memberName = if (e.isPredicate) e.predicate.FullName else e.f.FullName;
- val trE = Tr(e.e)
- (if (e.isPredicate) {
- val (ttV,tt) = Boogie.NewTVar("T")
- val (refV, ref) = Boogie.NewBVar("ref", tref, true)
- val (fV, f) = Boogie.NewBVar("f", FieldType(tt), true)
- val (pmV, pm: Expr) = Boogie.NewBVar("newPredicateMask", tpmask, true)
- val assumption = (heap.select(foldReceiver, foldPred.FullName+"#m").select(ref, f.id) || heap.select(trE, memberName+"#m").select(ref, f.id)) ==> pm.select(ref, f.id)
- BLocal(pmV) :: Havoc(pm) ::
- bassume(new Boogie.Forall(ttV, fV, assumption).forall(refV)) ::
- (heap.select(foldReceiver, foldPred.FullName+"#m") := pm) :: Nil
- } else Nil) :::
- (heap.select(foldReceiver, foldPred.FullName+"#m").select(trE, memberName) := true) :: Nil
- case acc @ AccessSeq(s, Some(member), perm) =>
- throw new InternalErrorException("not implemented yet")
- case cr@Credit(ch, n) =>
- Nil
- case Implies(e0,e1) =>
- Boogie.If(Tr(e0), f(e1), Nil)
- case IfThenElse(con, then, els) =>
- Boogie.If(Tr(con), f(then), f(els))
- case And(e0,e1) =>
- f(e0) ::: f(e1)
- case holds@Holds(e) =>
- Nil
- case Eval(h, e) =>
- Nil
- case e =>
- Nil
- }
- }
-
- // see comment in front of method exhale about parameter isUpdatingSecMask
- def ExhalePermission(perm: Permission, obj: Expr, memberName: String, currentK: Expr, pos: Position, error: ErrorMessage, em: Boogie.Expr, exactchecking: Boolean, isUpdatingSecMask: Boolean): List[Boogie.Stmt] = {
- val (f, stmts) = extractKFromPermission(perm, currentK)
- val n = extractEpsilonsFromPermission(perm);
-
- val res = stmts :::
- (perm.permissionType match {
- case PermissionType.Mixed =>
- bassert(f > 0.0 || (f == 0.0 && n > 0.0), error.pos, error.message + " The permission at " + pos + " might not be positive.") ::
- (if (isUpdatingSecMask) DecPermissionBoth2(obj, memberName, f, n, em, error, pos, exactchecking)
- else DecPermissionBoth(obj, memberName, f, n, em, error, pos, exactchecking))
- case PermissionType.Epsilons =>
- bassert(n > 0.0, error.pos, error.message + " The permission at " + pos + " might not be positive.") ::
- (if (isUpdatingSecMask) DecPermissionEpsilon2(obj, memberName, n, em, error, pos)
- else DecPermissionEpsilon(obj, memberName, n, em, error, pos))
- case PermissionType.Fraction =>
- bassert(f > 0.0, error.pos, error.message + " The permission at " + pos + " might not be positive.") ::
- (if (isUpdatingSecMask) DecPermission2(obj, memberName, f, em, error, pos, exactchecking)
- else DecPermission(obj, memberName, f, em, error, pos, exactchecking))
- })
-
- if (isUpdatingSecMask)
- res filter (a => !a.isInstanceOf[Boogie.Assert]) // we do not want "insufficient permission checks" at the moment, as they will be turned into (possibly wrong) assumptions
- else res
- }
-
- // does this permission require exact checking, or is it enough to check that we have any permission > 0?
- def needExactChecking(perm: Permission, default: Boolean): Boolean = {
- perm match {
- case Full => true
- case Frac(_) => true
- case Epsilon => default
- case PredicateEpsilon(_) | MonitorEpsilon(_) | ChannelEpsilon(_) | ForkEpsilon(_) => true
- case MethodEpsilon => default
- case Epsilons(p) => true
- case Star => false
- case IntPermTimes(lhs, rhs) => needExactChecking(rhs, default)
- case PermTimes(lhs, rhs) => {
- val l = needExactChecking(lhs, default);
- val r = needExactChecking(rhs, default);
- (if (l == false || r == false) false else true) // if one side doesn't need exact checking, the whole multiplication doesn't
- }
- case PermPlus(lhs, rhs) => {
- val l = needExactChecking(lhs, default);
- val r = needExactChecking(rhs, default);
- (if (l == true || r == true) true else false) // if one side needs exact checking, use exact
- }
- case PermMinus(lhs, rhs) => {
- val l = needExactChecking(lhs, default);
- val r = needExactChecking(rhs, default);
- (if (l == true || r == true) true else false) // if one side needs exact checking, use exact
- }
- }
- }
-
- def ExhaleHelper(p: Expression, m: Boogie.Expr, sm: Boogie.Expr, eh: Boogie.Expr, error: ErrorMessage, check: Boolean, currentK: Expr, exactchecking: Boolean, onlyExactCheckingPermissions: Boolean, transferPermissionToSecMask: Boolean, recurseOnPredicatesDepth: Int, isUpdatingSecMask: Boolean, previousReceivers: Map[String,List[Expr]], duringUnfold: Boolean, foldReceiver: VarExpr = null, foldPredicateName: String = null, foldVersion: VarExpr = null): List[Boogie.Stmt] = {
- val LocalExhaleHelper = (expr: Expression) => ExhaleHelper(expr, m, sm, eh, error, check, currentK, exactchecking, onlyExactCheckingPermissions, transferPermissionToSecMask, recurseOnPredicatesDepth, isUpdatingSecMask, previousReceivers, duringUnfold, foldReceiver, foldPredicateName, foldVersion)
- desugar(p) match {
- case pred@MemberAccess(e, p) if pred.isPredicate =>
- val tmp = Access(pred, Full);
- tmp.pos = pred.pos;
- LocalExhaleHelper(tmp)
- case AccessAll(obj, perm) => throw new InternalErrorException("should be desugared")
- case AccessSeq(s, None, perm) => throw new InternalErrorException("should be desugared")
- case acc@Access(e,perm) =>
- val ec = needExactChecking(perm, exactchecking)
- if (ec != onlyExactCheckingPermissions) Nil else {
- val memberName = if(e.isPredicate) e.predicate.FullName else e.f.FullName;
- val (starKV, starK) = NewBVar("starK", treal, true);
- val trE = Tr(e.e)
-
- // check definedness
- (if(check) isDefined(e.e)(true) :::
- bassert(nonNull(Tr(e.e)), error.pos, error.message + " The target of the acc predicate at " + acc.pos + " might be null.") else Nil) :::
- (if(e.isPredicate && foldReceiver != null) bassume(FunctionApp("#predicateInside#", foldReceiver :: VarExpr(foldPredicateName) :: foldVersion :: trE :: VarExpr(memberName) :: Heap.select(trE, memberName) :: Nil)) :: Nil else Nil) :::
- // if the mask does not contain sufficient permissions, try folding acc(e, fraction)
- // TODO: include automagic again
- // check that the necessary permissions are there and remove them from the mask
- ExhalePermission(perm, trE, memberName, currentK, acc.pos, error, m, ec, isUpdatingSecMask) :::
- // update version number (if necessary)
- (if (e.isPredicate && !isUpdatingSecMask)
- Boogie.If(!CanRead(trE, memberName, m, sm), // if we cannot access the predicate anymore, then its version will be havoced
- (if (!duringUnfold) (if (!transferPermissionToSecMask) bassume(Heap.select(trE, memberName) < eh.select(trE, memberName)) :: Nil else Nil) // assume that the predicate's version grows monotonically
- else { // duringUnfold -> the heap is not havoced, thus we need to locally havoc the version
- val (oldVersV, oldVers) = Boogie.NewBVar("oldVers", tint, true)
- val (newVersV, newVers) = Boogie.NewBVar("newVers", tint, true)
- BLocal(oldVersV) :: (oldVers := Heap.select(trE, memberName)) ::
- BLocal(newVersV) :: Boogie.Havoc(newVers) :: (Heap.select(trE, memberName) := newVers) ::
- bassume(oldVers < Heap.select(trE, memberName)) :: Nil
- }),
- Nil) :: Nil
- else Nil) :::
- bassume(wf(Heap, m, sm)) :::
- (if (m != Mask || sm != SecMask) bassume(wf(Heap, Mask, SecMask)) :: Nil else Nil)
- }
- case acc @ AccessSeq(s, Some(member), perm) =>
- if (member.isPredicate) throw new NotSupportedException("not yet implemented");
- val ec = needExactChecking(perm, exactchecking);
-
- if (ec != onlyExactCheckingPermissions) Nil else {
- val e = Tr(s);
- val memberName = member.f.FullName;
- val (r, stmts) = extractKFromPermission(perm, currentK)
- val n = extractEpsilonsFromPermission(perm);
-
- stmts :::
- (if (check) isDefined(s)(true) ::: isDefined(perm)(true) else Nil) :::
- {
- val (aV,a) = Boogie.NewTVar("alpha");
- val (refV, ref) = Boogie.NewBVar("ref", tref, true);
- val (fV, f) = Boogie.NewBVar("f", FieldType(a), true);
- val (pcV,pc) = Boogie.NewBVar("p", tperm, true);
- val mr = m(ref, memberName)("perm$R");
- val mn = m(ref, memberName)("perm$N");
-
- // assert that the permission is positive
- bassert((SeqContains(e, ref) ==>
- (perm.permissionType match {
- case PermissionType.Fraction => r > 0.0
- case PermissionType.Mixed => r > 0.0 || (r == 0.0 && n > 0.0)
- case PermissionType.Epsilons => n > 0.0
- })).forall(refV), error.pos, error.message + " The permission at " + acc.pos + " might not be positive.") ::
- // make sure enough permission is available
- // (see comment in front of method exhale for explanation of isUpdatingSecMask)
- (if (!isUpdatingSecMask) bassert((SeqContains(e, ref) ==>
- ((perm,perm.permissionType) match {
- case _ if !ec => mr > 0.0
- case (Star,_) => mr > 0.0
- case (_,PermissionType.Fraction) => r <= mr && (r ==@ mr ==> 0.0 <= mn)
- case (_,PermissionType.Mixed) => r <= mr && (r ==@ mr ==> n <= mn)
- case (_,PermissionType.Epsilons) => mr ==@ 0.0 ==> n <= mn
- })).forall(refV), error.pos, error.message + " Insufficient permission at " + acc.pos + " for " + member.f.FullName) :: Nil else Nil) :::
- // additional assumption on k if we have a star permission or use inexact checking
- ( perm match {
- case _ if !ec => bassume((SeqContains(e, ref) ==> (r < mr)).forall(refV)) :: Nil
- case Star => bassume((SeqContains(e, ref) ==> (r < mr)).forall(refV)) :: Nil
- case _ => Nil
- }) :::
- // update the map
- (m := Lambda(List(aV), List(refV, fV),
- (SeqContains(e, ref) && f ==@ memberName).thenElse(
- Lambda(List(), List(pcV), (pc ==@ "perm$R").thenElse(mr - r, mn - n)),
- m(ref, f))))
- } :::
- bassume(wf(Heap, m, sm)) :::
- (if (m != Mask || sm != SecMask) bassume(wf(Heap, Mask, SecMask)) :: Nil else Nil)
- }
- case cr@Credit(ch, n) if !onlyExactCheckingPermissions =>
- val trCh = Tr(ch)
- (if (check)
- isDefined(ch)(true) :::
- bassert(nonNull(trCh), ch.pos, "The target of the credit predicate might be null.") :::
- isDefined(cr.N)(true)
- else
- Nil) :::
- // only update the heap if we are not updating the secondary mask
- (if (!isUpdatingSecMask)
- new Boogie.MapUpdate(Credits, trCh, new Boogie.MapSelect(Credits, trCh) - Tr(cr.N)) :: Nil
- else Nil)
- case Implies(e0,e1) =>
- (if(check && !onlyExactCheckingPermissions) isDefined(e0)(true) else Nil) :::
- Boogie.If(Tr(e0), LocalExhaleHelper(e1), Nil)
- case IfThenElse(con, then, els) =>
- (if(check) isDefined(con)(true) else Nil) :::
- Boogie.If(Tr(con), LocalExhaleHelper(then), LocalExhaleHelper(els))
- case And(e0,e1) =>
- LocalExhaleHelper(e0) ::: LocalExhaleHelper(e1)
- case holds@Holds(e) if !onlyExactCheckingPermissions =>
- (if(check) isDefined(e)(true) :::
- bassert(nonNull(Tr(e)), error.pos, error.message + " The target of the holds predicate at " + holds.pos + " might be null.") :: Nil else Nil) :::
- bassert(0 < new Boogie.MapSelect(Heap, Tr(e), "held"), error.pos, error.message + " The current thread might not hold lock at " + holds.pos + ".") ::
- bassert(! new Boogie.MapSelect(Heap, Tr(e), "rdheld"), error.pos, error.message + " The current thread might hold the read lock at " + holds.pos + ".") ::
- (if (isUpdatingSecMask) Nil else bassume(AreGoodMasks(m, sm)) :: Nil) :::
- bassume(wf(Heap, m, sm))
- case Eval(h, e) if !onlyExactCheckingPermissions =>
- val (evalHeap, evalMask, evalSecMask, evalCredits, checks, proofOrAssume) = fromEvalState(h);
- val (preGlobalsV, preGlobals) = etran.FreshGlobals("eval")
- val preEtran = new ExpressionTranslator(preGlobals, currentClass);
- BLocals(preGlobalsV) :::
- copyState(preGlobals, Globals(evalHeap, evalMask, evalSecMask, evalCredits)) :::
- (if(check) checks else Nil) :::
- (if (isUpdatingSecMask) Nil else bassume(AreGoodMasks(preEtran.Mask, preEtran.SecMask)) :: Nil) :::
- bassume(wf(preEtran.Heap, preEtran.Mask, preEtran.SecMask)) ::
- bassert(proofOrAssume, p.pos, "Arguments for joinable might not match up.") ::
- preEtran.Exhale(List((e, error)), "eval", check, currentK, exactchecking)
- case e if !onlyExactCheckingPermissions =>
- val (ee,ll) = Tr(e, true) // keep list ll of statements here, in case we are missing effects from unfolding expressions (if we do not call isDefined(e) below, we won't add secondary permissions/"inside" instances)
- (if(check) isDefined(e)(true) else ll) ::: List(bassert(ee, error.pos, error.message + " The expression at " + e.pos + " might not evaluate to true."))
- case _ => Nil
- }}
-
- def extractKFromPermission(expr: Permission, currentK: Expr): (Expr, List[Boogie.Stmt]) = expr match {
- case Full => (permissionFull, Nil)
- case Epsilon => (currentK, Nil)
- case Epsilons(_) => (0.0, Nil)
- case PredicateEpsilon(_) => (predicateK, Nil)
- case MonitorEpsilon(_) => (monitorK, Nil)
- case ChannelEpsilon(_) => (channelK, Nil)
- case MethodEpsilon => (currentK, Nil)
- case ForkEpsilon(token) =>
- val fk = etran.Heap.select(Tr(token), forkK)
- (fk, bassume(0.0 < fk && fk < percentPermission(1)) /* this is always true for forkK */)
- case Star =>
- val (starKV, starK) = NewBVar("starK", treal, true);
- (starK, BLocal(starKV) :: bassume(starK > 0.0 /* an upper bound is provided later by DecPermission */) :: Nil)
- case Frac(p) => (percentPermission(Tr(p)), Nil)
- case IntPermTimes(lhs, rhs) => {
- val (r, rs) = extractKFromPermission(rhs, currentK)
- (int2real(lhs) * r, rs)
- }
- case PermTimes(lhs, rhs) => {
- val (l, ls) = extractKFromPermission(lhs, currentK)
- val (r, rs) = extractKFromPermission(rhs, currentK)
- val (resV, res) = Boogie.NewBVar("productK", treal, true)
- (res, ls ::: rs ::: BLocal(resV) :: bassume(permissionFull * res ==@ l * r) :: Nil)
- }
- case PermPlus(lhs, rhs) => {
- val (l, ls) = extractKFromPermission(lhs, currentK)
- val (r, rs) = extractKFromPermission(rhs, currentK)
- (l + r, Nil)
- }
- case PermMinus(lhs, rhs) => {
- val (l, ls) = extractKFromPermission(lhs, currentK)
- val (r, rs) = extractKFromPermission(rhs, currentK)
- (l - r, Nil)
- }
- }
-
- def extractEpsilonsFromPermission(expr: Permission): Expr = expr match {
- case _:Write => 0.0
- case Epsilons(n) => int2real(Tr(n))
- case PermTimes(lhs, rhs) => 0.0 // multiplication cannot give epsilons
- case IntPermTimes(lhs, rhs) => int2real(lhs) * extractEpsilonsFromPermission(rhs)
- case PermPlus(lhs, rhs) => {
- val l = extractEpsilonsFromPermission(lhs)
- val r = extractEpsilonsFromPermission(rhs)
- l + r
- }
- case PermMinus(lhs, rhs) => {
- val l = extractEpsilonsFromPermission(lhs)
- val r = extractEpsilonsFromPermission(rhs)
- l - r
- }
- }
-
- def fromEvalState(h: EvalState): (Expr, Expr, Expr, Expr, List[Stmt], Expr) = {
- h match {
- case AcquireState(obj) =>
- (AcquireHeap(Heap.select(Tr(obj), "held")),
- AcquireMask(Heap.select(Tr(obj), "held")),
- AcquireSecMask(Heap.select(Tr(obj), "held")),
- AcquireCredits(Heap.select(Tr(obj), "held")),
- isDefined(obj)(true), true)
- case ReleaseState(obj) =>
- (LastSeenHeap(Heap.select(Tr(obj), "mu"), Heap.select(Tr(obj), "held")),
- LastSeenMask(Heap.select(Tr(obj), "mu"), Heap.select(Tr(obj), "held")),
- LastSeenSecMask(Heap.select(Tr(obj), "mu"), Heap.select(Tr(obj), "held")),
- LastSeenCredits(Heap.select(Tr(obj), "mu"), Heap.select(Tr(obj), "held")),
- isDefined(obj)(true), true)
- case CallState(token, obj, id, args) =>
- val argsSeq = CallArgs(Heap.select(Tr(token), "joinable"));
-
- var f: ((Expression, Int)) => Expr =
- (a: (Expression, Int)) => a match {
- case (VariableExpr("?"),_) => true: Expr
- case _ => new MapSelect(argsSeq, a._2) ==@ Tr(a._1)
- }
- var ll: List[(Expression, Int)] = null
- ll = (args zip (1 until args.length+1).toList);
-
- var i = 0;
- (CallHeap(Heap.select(Tr(token), "joinable")),
- CallMask(Heap.select(Tr(token), "joinable")),
- CallSecMask(Heap.select(Tr(token), "joinable")),
- CallCredits(Heap.select(Tr(token), "joinable")),
- isDefined(token)(true) :::
- isDefined(obj)(true) :::
- (args flatMap { a => isDefined(a)(true)}) :::
- bassert(CanRead(Tr(token), "joinable"), obj.pos, "Joinable field of the token might not be readable.") ::
- bassert(Heap.select(Tr(token), "joinable") !=@ 0, obj.pos, "Token might not be active."),
- (new MapSelect(argsSeq, 0) ==@ Tr(obj) ) &&
- ((ll map {
- f
- }).foldLeft(true: Expr){ (a: Expr, b: Expr) => a && b})
- )
- }
- }
-
- /**********************************************************************
- ***************** PERMISSIONS *****************
- **********************************************************************/
-
- def CanRead(obj: Boogie.Expr, field: Boogie.Expr, m: Boogie.Expr, sm: Boogie.Expr): Boogie.Expr = new Boogie.FunctionApp("CanRead", List(m, sm, obj, field))
- def CanRead(obj: Boogie.Expr, field: String, m: Boogie.Expr, sm: Boogie.Expr): Boogie.Expr = CanRead(obj, new Boogie.VarExpr(field), m, sm)
- def CanRead(obj: Boogie.Expr, field: Boogie.Expr): Boogie.Expr = new Boogie.FunctionApp("CanRead", List(Mask, SecMask, obj, field))
- def CanRead(obj: Boogie.Expr, field: String): Boogie.Expr = CanRead(obj, new Boogie.VarExpr(field))
- def CanReadForSure(obj: Boogie.Expr, field: Boogie.Expr): Boogie.Expr = new Boogie.FunctionApp("CanReadForSure", List(Mask, obj, field))
- def CanReadForSure(obj: Boogie.Expr, field: String): Boogie.Expr = CanReadForSure(obj, new Boogie.VarExpr(field))
- def CanReadForSure2(obj: Boogie.Expr, field: Boogie.Expr): Boogie.Expr = new Boogie.FunctionApp("CanReadForSure", List(SecMask, obj, field))
- def CanWrite(obj: Boogie.Expr, field: Boogie.Expr): Boogie.Expr = new Boogie.FunctionApp("CanWrite", Mask, obj, field)
- def CanWrite(obj: Boogie.Expr, field: String): Boogie.Expr = CanWrite(obj, new Boogie.VarExpr(field))
- def HasNoPermission(obj: Boogie.Expr, field: String) =
- (new Boogie.MapSelect(Mask, obj, field, "perm$R") ==@ 0.0) &&
- (new Boogie.MapSelect(Mask, obj, field, "perm$N") ==@ 0.0)
- def SetNoPermission(obj: Boogie.Expr, field: String, mask: Boogie.Expr) =
- Boogie.Assign(new Boogie.MapSelect(mask, obj, field), Boogie.VarExpr("Permission$Zero"))
- def HasFullPermission(obj: Boogie.Expr, field: String, mask: Boogie.Expr) =
- (new Boogie.MapSelect(mask, obj, field, "perm$R") ==@ permissionFull) &&
- (new Boogie.MapSelect(mask, obj, field, "perm$N") ==@ 0.0)
- def SetFullPermission(obj: Boogie.Expr, field: String) =
- Boogie.Assign(new Boogie.MapSelect(Mask, obj, field), Boogie.VarExpr("Permission$Full"))
-
- def IncPermission(obj: Boogie.Expr, field: String, howMuch: Boogie.Expr, m: Expr = Mask): List[Boogie.Stmt] = {
- MapUpdate3(m, obj, field, "perm$R", new Boogie.MapSelect(m, obj, field, "perm$R") + howMuch) :: Nil
- }
- def IncPermissionEpsilon(obj: Boogie.Expr, field: String, epsilons: Boogie.Expr, m: Expr = Mask): List[Boogie.Stmt] = {
- MapUpdate3(m, obj, field, "perm$N", new Boogie.MapSelect(m, obj, field, "perm$N") + epsilons) ::
- bassume(wf(Heap, m, SecMask)) :: Nil
- }
- def DecPermission(obj: Boogie.Expr, field: String, howMuch: Boogie.Expr, mask: Boogie.Expr, error: ErrorMessage, pos: Position, exactchecking: Boolean): List[Boogie.Stmt] = {
- val fP: Boogie.Expr = new Boogie.MapSelect(mask, obj, field, "perm$R")
- val fC: Boogie.Expr = new Boogie.MapSelect(mask, obj, field, "perm$N")
- (if (exactchecking) bassert(howMuch <= fP && (howMuch ==@ fP ==> 0.0 <= fC), error.pos, error.message + " Insufficient fraction at " + pos + " for " + field + ".") :: Nil
- else bassert(fP > 0.0, error.pos, error.message + " Insufficient fraction at " + pos + " for " + field + ".") :: bassume(howMuch < fP)) :::
- MapUpdate3(mask, obj, field, "perm$R", new Boogie.MapSelect(mask, obj, field, "perm$R") - howMuch)
- }
- def DecPermissionEpsilon(obj: Boogie.Expr, field: String, epsilons: Boogie.Expr, mask: Boogie.Expr, error: ErrorMessage, pos: Position): List[Boogie.Stmt] = {
- val xyz = new Boogie.MapSelect(mask, obj, field, "perm$N")
- bassert((new Boogie.MapSelect(mask, obj, field, "perm$R") ==@ 0.0) ==> (epsilons <= xyz), error.pos, error.message + " Insufficient epsilons at " + pos + " for " + field + ".") ::
- MapUpdate3(mask, obj, field, "perm$N", new Boogie.MapSelect(mask, obj, field, "perm$N") - epsilons) ::
- bassume(wf(Heap, Mask, SecMask)) :: Nil
- }
- def DecPermissionBoth(obj: Boogie.Expr, field: String, howMuch: Boogie.Expr, epsilons: Boogie.Expr, mask: Boogie.Expr, error: ErrorMessage, pos: Position, exactchecking: Boolean): List[Boogie.Stmt] = {
- val fP: Boogie.Expr = new Boogie.MapSelect(mask, obj, field, "perm$R")
- val fC: Boogie.Expr = new Boogie.MapSelect(mask, obj, field, "perm$N")
-
- (if (exactchecking) bassert(howMuch <= fP && (howMuch ==@ fP ==> epsilons <= fC), error.pos, error.message + " Insufficient permission at " + pos + " for " + field + ".") :: Nil
- else bassert(fP > 0.0, error.pos, error.message + " Insufficient permission at " + pos + " for " + field + ".") :: bassume(howMuch < fP)) :::
- MapUpdate3(mask, obj, field, "perm$N", fC - epsilons) ::
- MapUpdate3(mask, obj, field, "perm$R", fP - howMuch) ::
- bassume(wf(Heap, Mask, SecMask)) :: Nil
- }
- def DecPermission2(obj: Boogie.Expr, field: String, howMuch: Boogie.Expr, mask: Boogie.Expr, error: ErrorMessage, pos: Position, exactchecking: Boolean): List[Boogie.Stmt] = {
- DecPermission(obj, field, howMuch, mask, error, pos, exactchecking) :::
- Boogie.If(new Boogie.MapSelect(mask, obj, field, "perm$R") < 0.0,
- MapUpdate3(mask, obj, field, "perm$R", 0.0),
- Nil)
- }
- def DecPermissionEpsilon2(obj: Boogie.Expr, field: String, epsilons: Boogie.Expr, mask: Boogie.Expr, error: ErrorMessage, pos: Position): List[Boogie.Stmt] = {
- DecPermissionEpsilon(obj, field, epsilons, mask, error, pos) :::
- Boogie.If(new Boogie.MapSelect(mask, obj, field, "perm$N") < 0.0,
- MapUpdate3(mask, obj, field, "perm$N", 0.0),
- Nil)
- }
- def DecPermissionBoth2(obj: Boogie.Expr, field: String, howMuch: Boogie.Expr, epsilons: Boogie.Expr, mask: Boogie.Expr, error: ErrorMessage, pos: Position, exactchecking: Boolean): List[Boogie.Stmt] = {
- DecPermissionBoth(obj, field, howMuch, epsilons, mask, error, pos, exactchecking) :::
- Boogie.If(new Boogie.MapSelect(mask, obj, field, "perm$R") < 0.0,
- MapUpdate3(mask, obj, field, "perm$R", 0.0),
- Nil) ::
- Boogie.If(new Boogie.MapSelect(mask, obj, field, "perm$N") < 0.0,
- MapUpdate3(mask, obj, field, "perm$N", 0.0),
- Nil) :: Nil
- }
-
-
- def MapUpdate3(m: Boogie.Expr, arg0: Boogie.Expr, arg1: String, arg2: String, rhs: Boogie.Expr) = {
- // m[a,b,c] := rhs
- // m[a,b][c] := rhs
- // m[a,b] := map[a,b][c := rhs]
- val m01 = new Boogie.MapSelect(m, arg0, arg1)
- Boogie.Assign(m01, Boogie.MapStore(m01, arg2, rhs))
- }
-
- def DecPerm(m: Expr, e: Expr, f: Expr, i: Expr) = FunctionApp("DecPerm", List(m, e, f, i))
- def DecEpsilons(m: Expr, e: Expr, f: Expr, i: Expr) = FunctionApp("DecEpsilons", List(m, e, f, i))
- def IncPerm(m: Expr, e: Expr, f: Expr, i: Expr) = FunctionApp("IncPerm", List(m, e, f, i))
- def IncEpsilons(m: Expr, e: Expr, f: Expr, i: Expr) = FunctionApp("IncEpsilons", List(m, e, f, i))
-
-
- def MaxLockIsBelowX(x: Boogie.Expr) = { // waitlevel << x
- val (oV, o) = Boogie.NewBVar("o", tref, true)
- new Boogie.Forall(oV,
- (contributesToWaitLevel(o, Heap, Credits)) ==>
- new Boogie.FunctionApp("MuBelow", new Boogie.MapSelect(Heap, o, "mu"), x))
- }
- def MaxLockIsAboveX(x: Boogie.Expr) = { // x << waitlevel
- val (oV, o) = Boogie.NewBVar("o", tref, true)
- new Boogie.Exists(oV,
- (contributesToWaitLevel(o, Heap, Credits)) &&
- new Boogie.FunctionApp("MuBelow", x, new Boogie.MapSelect(Heap, o, "mu")))
- }
- def IsHighestLock(x: Boogie.Expr) = {
- // (forall r :: r.held ==> r.mu << x || r.mu == x)
- val (rV, r) = Boogie.NewBVar("r", tref, true)
- new Boogie.Forall(rV,
- contributesToWaitLevel(r, Heap, Credits) ==>
- (new Boogie.FunctionApp("MuBelow", new MapSelect(Heap, r, "mu"), x) ||
- (new Boogie.MapSelect(Heap, r, "mu") ==@ x)))
- }
- def MaxLockPreserved = { // old(waitlevel) == waitlevel
- // I don't know what the best encoding of this conding is, so I'll try a disjunction.
- // Disjunct b0 is easier to prove, but it is stronger than b1.
-
- // (forall r: ref ::
- // old(Heap)[r,held] == Heap[r,held] &&
- // (Heap[r,held] ==> old(Heap)[r,mu] == Heap[r,mu]))
- val (rV, r) = Boogie.NewBVar("r", tref, true)
- val b0 = new Boogie.Forall(rV,
- ((0 < new Boogie.MapSelect(oldEtran.Heap, r, "held")) ==@
- (0 < new Boogie.MapSelect(Heap, r, "held"))) &&
- ((0 < new Boogie.MapSelect(Heap, r, "held")) ==>
- (new Boogie.MapSelect(oldEtran.Heap, r, "mu") ==@
- new Boogie.MapSelect(Heap, r, "mu"))))
-
- // (forall o, p ::
- // old(o.held) && (forall r :: old(r.held) ==> old(r.mu) << old(o.mu) || old(r.mu)==old(o.mu)) &&
- // p.held && (forall r :: r.held ==> r.mu << p.mu || r.mu == p.mu )
- // ==>
- // old(o.mu) == p.mu)
- val (oV, o) = Boogie.NewBVar("o", tref, true)
- val (pV, p) = Boogie.NewBVar("p", tref, true)
- val b1 = Boogie.Forall(Nil, List(oV,pV), Nil,
- ((0 < new Boogie.MapSelect(oldEtran.Heap, o, "held")) &&
- oldEtran.IsHighestLock(new Boogie.MapSelect(oldEtran.Heap, o, "mu")) &&
- (0 < new Boogie.MapSelect(Heap, p, "held")) &&
- IsHighestLock(new Boogie.MapSelect(Heap, p, "mu")))
- ==>
- (new Boogie.MapSelect(oldEtran.Heap, o, "mu") ==@ new Boogie.MapSelect(Heap, p, "mu")))
- b0 || b1
- }
- def TemporalMaxLockComparison(e0: ExpressionTranslator, e1: ExpressionTranslator) = { // e0(waitlevel) << e1(waitlevel)
- // (exists o ::
- // e1(o.held) &&
- // (forall r :: e0(r.held) ==> e0(r.mu) << e1(o.mu)))
- val (oV, o) = Boogie.NewBVar("o", tref, true)
- new Boogie.Exists(oV,
- (0 < new Boogie.MapSelect(e1.Heap, o, "held")) &&
- e0.MaxLockIsBelowX(new Boogie.MapSelect(e1.Heap, o, "mu")))
- }
-}
-
- // implicit (uses etran)
-
- implicit def expression2Expr(e: Expression) = etran.Tr(e);
-
- // prelude (uses etran)
- def isHeld(e: Expr): Expr = (0 < etran.Heap.select(e, "held"))
- def isRdHeld(e: Expr): Expr = etran.Heap.select(e, "rdheld")
- def isShared(e: Expr): Expr = etran.Heap.select(e, "mu") !=@ bLockBottom
-
-object TranslationHelper {
- // implicit conversions
-
- implicit def string2VarExpr(s: String) = VarExpr(s);
- implicit def field2Expr(f: Field) = VarExpr(f.FullName);
- implicit def bool2Bool(b: Boolean): Boogie.BoolLiteral = Boogie.BoolLiteral(b)
- implicit def int2Int(n: Int): Boogie.IntLiteral = Boogie.IntLiteral(n)
- implicit def real2Real(d: Double): Boogie.RealLiteral = Boogie.RealLiteral(d)
- implicit def lift(s: Boogie.Stmt): List[Boogie.Stmt] = List(s)
- implicit def type2BType(cl: Class): BType = {
- if(cl.IsRef) {
- tref
- } else if(cl.IsBool) {
- tbool
- } else if(cl.IsMu) {
- tmu
- } else if(cl.IsInt) {
- tint
- } else if(cl.IsString) {
- tstring
- } else if(cl.IsSeq) {
- tseq(type2BType(cl.asInstanceOf[SeqClass].parameter))
- } else {
- assert(false, "unexpected type: " + cl.FullName); null
- }
- }
- implicit def decl2DeclList(decl: Decl): List[Decl] = List(decl)
- implicit def function2RichFunction(f: Function) = RichFunction(f);
-
- case class RichFunction(f: Function) {
- def apply(args: List[Expr]) = {
- FunctionApp(functionName(f), args)
- }
- }
-
- // prelude definitions
-
- def ModuleType = NamedType("ModuleName");
- def ModuleName(cl: Class) = "module#" + cl.module.id;
- def TypeName = NamedType("TypeName");
- def FieldType(tp: BType) = IndexedType("Field", tp);
- def bassert(e: Expr, pos: Position, msg: String) = new Boogie.Assert(e, pos, msg)
- def bassert(e: Expr, pos: Position, msg: String, subsumption: Int) = new Boogie.Assert(e, pos, msg, subsumption)
- def bassume(e: Expr) = Boogie.Assume(e)
- def BLocal(id: String, tp: BType) = new Boogie.LocalVar(id, tp)
- def BLocal(x: Boogie.BVar) = Boogie.LocalVar(x)
- def BLocals(xs: List[Boogie.BVar]) = xs map BLocal
- def tArgSeq = NamedType("ArgSeq");
- def tref = NamedType("ref");
- def tbool = NamedType("bool");
- def treal = NamedType("real");
- def tmu = NamedType("Mu");
- def tint = NamedType("int");
- def tstring = NamedType("string");
- def tseq(arg: BType) = IndexedType("Seq", arg)
- def theap = NamedType("HeapType");
- def tmask = NamedType("MaskType");
- def tpmask = NamedType("PMaskType");
- def tcredits = NamedType("CreditsType");
- def tperm = NamedType("PermissionComponent");
- def ZeroMask = VarExpr("ZeroMask");
- def ZeroPMask = VarExpr("ZeroPMask");
- def ZeroCredits = VarExpr("ZeroCredits");
- def HeapName = "Heap";
- def MaskName = "Mask";
- def SecMaskName = "SecMask";
- def CreditsName = "Credits";
- def GlobalNames = List(HeapName, MaskName, SecMaskName, CreditsName);
- def CanAssumeFunctionDefs = VarExpr("CanAssumeFunctionDefs");
- def FunctionContextHeight = VarExpr("FunctionContextHeight");
- def permissionFull = percentPermission(100);
- def permissionOnePercent = percentPermission(1);
- def percentPermission(e: Expr) = {
- Chalice.percentageSupport match {
- case 0 => int2real(e)*0.01
- case 1 => FunctionApp("Fractions", List(e))
- }
- }
- def int2real(e: Expr): Expr = FunctionApp("real", List(e))
- def forkK = "forkK";
- def channelK = "channelK";
- def monitorK = "monitorK";
- def predicateK = "predicateK";
- def CurrentModule = VarExpr("CurrentModule");
- def dtype(e: Expr) = FunctionApp("dtype", List(e))
- def functionName(f: Function) = "#" + f.FullName;
- def className(cl: Class) = Boogie.VarExpr(cl.id + "#t")
- def bnull = Boogie.Null();
- def bLockBottom = VarExpr("$LockBottom")
- def nonNull(e: Expr): Expr = e !=@ bnull
- def LastSeenHeap(sharedBit: Expr, heldBit: Expr) = FunctionApp("LastSeen$Heap", List(sharedBit, heldBit))
- def LastSeenMask(sharedBit: Expr, heldBit: Expr) = FunctionApp("LastSeen$Mask", List(sharedBit, heldBit))
- def LastSeenSecMask(sharedBit: Expr, heldBit: Expr) = FunctionApp("LastSeen$SecMask", List(sharedBit, heldBit))
- def LastSeenCredits(sharedBit: Expr, heldBit: Expr) = FunctionApp("LastSeen$Credits", List(sharedBit, heldBit))
- def AcquireHeap(heldBit: Expr) = FunctionApp("Acquire$Heap", List(heldBit))
- def AcquireMask(heldBit: Expr) = FunctionApp("Acquire$Mask", List(heldBit))
- def AcquireSecMask(heldBit: Expr) = FunctionApp("Acquire$SecMask", List(heldBit))
- def AcquireCredits(heldBit: Expr) = FunctionApp("Acquire$Credits", List(heldBit))
- def CallHeap(joinableBit: Expr) = FunctionApp("Call$Heap", List(joinableBit))
- def CallMask(joinableBit: Expr) = FunctionApp("Call$Mask", List(joinableBit))
- def CallSecMask(joinableBit: Expr) = FunctionApp("Call$SecMask", List(joinableBit))
- def CallCredits(joinableBit: Expr) = FunctionApp("Call$Credits", List(joinableBit))
- def CallArgs(joinableBit: Expr) = FunctionApp("Call$Args", List(joinableBit))
- def submask(m0: Expr, m1: Expr) = FunctionApp("submask", List(m0, m1))
-
- def wf(g: Globals) = FunctionApp("wf", List(g.heap, g.mask, g.secmask));
- def wf(h: Expr, m: Expr, sm: Expr) = FunctionApp("wf", List(h, m, sm));
- def IsGoodMask(m: Expr) = FunctionApp("IsGoodMask", List(m))
- def AreGoodMasks(m: Expr, sm: Expr) = IsGoodMask(m) // && IsGoodMask(sm) /** The second mask does currently not necessarily contain positive permissions, which means that we cannot assume IsGoodMask(sm). This might change in the future if we see a need for it */
- def IsGoodInhaleState(ih: Expr, h: Expr, m: Expr, sm: Expr) = FunctionApp("IsGoodInhaleState", List(ih,h,m,sm))
- def IsGoodExhaleState(eh: Expr, h: Expr, m: Expr, sm: Expr) = FunctionApp("IsGoodExhaleState", List(eh,h,m,sm))
- def IsGoodExhalePredicateState(eh: Expr, h: Expr, pm: Expr) = FunctionApp("IsGoodExhalePredicateState", List(eh,h,pm))
- def contributesToWaitLevel(e: Expr, h: Expr, c: Expr) =
- (0 < h.select(e, "held")) || h.select(e, "rdheld") || (new Boogie.MapSelect(c, e) < 0)
- def NonEmptyMask(m: Expr) = ! FunctionApp("EmptyMask", List(m))
- def NonPredicateField(f: String) = FunctionApp("NonPredicateField", List(VarExpr(f)))
- def PredicateField(f: String) = FunctionApp("PredicateField", List(VarExpr(f)))
- def cast(a: Expr, b: Expr) = FunctionApp("cast", List(a, b))
-
- // output a dummy function assumption that serves as trigger for the function
- // definition axiom.
- def functionTrigger(receiver: Expr, predicate: Predicate): Stmt = {
- bassume(FunctionApp("#" + predicate.FullName+"#trigger", receiver :: Nil))
- }
-
- def emptyPartialHeap: Expr = Boogie.VarExpr("emptyPartialHeap")
- def heapFragment(dep: Expr): Expr = Boogie.FunctionApp("heapFragment", List(dep))
- def combine(l: Expr, r: Expr): Expr = {
- (l,r) match {
- case (VarExpr("emptyPartialHeap"), a) => a
- case (a, VarExpr("emptyPartialHeap")) => a
- case _ => Boogie.FunctionApp("combine", List(l, r))
- }
- }
- def tpartialheap = NamedType("PartialHeapType");
-
- def copyState(globals: Globals, et: ExpressionTranslator): List[Stmt] =
- copyState(globals, et.globals)
- def copyState(globals: Globals, globalsToCopyFrom: Globals): List[Stmt] = {
- (for ((a, b) <- globals.list zip globalsToCopyFrom.list) yield (a := b)) :::
- bassume(wf(globals)) :: Nil
- }
- def resetState(et: ExpressionTranslator): List[Stmt] = resetState(et.globals)
- def resetState(globals: Globals): List[Stmt] = {
- (globals.mask := ZeroMask) ::
- (globals.secmask := ZeroMask) ::
- (globals.credits := ZeroCredits) ::
- Havoc(globals.heap) ::
- Nil
- }
-
- // sequences
-
- def createEmptySeq = FunctionApp("Seq#Empty", List())
- def createSingletonSeq(e: Expr) = FunctionApp("Seq#Singleton", List(e))
- def createAppendSeq(a: Expr, b: Expr) = FunctionApp("Seq#Append", List(a, b))
- def createRange(min: Expr, max: Expr) = FunctionApp("Seq#Range", List(min, max))
- def SeqLength(s: Expr) = FunctionApp("Seq#Length", List(s))
- def SeqContains(s: Expr, elt: Expr) = FunctionApp("Seq#Contains", List(s, elt))
- def SeqIndex(s: Expr, idx: Expr) = FunctionApp("Seq#Index", List(s, idx))
-
- def Variable2BVar(v: Variable) = new Boogie.BVar(v.UniqueName, v.t.typ)
- def Variable2BVarWhere(v: Variable) = NewBVarWhere(v.UniqueName, v.t)
- def NewBVarWhere(id: String, tp: Type) = {
- new Boogie.BVar(id, tp.typ){
- override val where = TypeInformation(new Boogie.VarExpr(id), tp.typ) }
- }
-
- // scale an expression (such as the definition of a predicate) by a permission
- def scaleExpressionByPermission(expr: Expression, perm1: Permission, pos: Position): Expression = {
- val result = expr match {
- case pred@MemberAccess(o, p) if pred.isPredicate => Access(pred, perm1)
- case Access(e, perm2) => Access(e, multiplyPermission(perm1, perm2, pos))
- case AccessSeq(e, f, perm2) => AccessSeq(e, f, multiplyPermission(perm1, perm2, pos))
- case And(lhs, rhs) => And(scaleExpressionByPermission(lhs, perm1, pos), scaleExpressionByPermission(rhs, perm1, pos))
- case Implies(lhs, rhs) => Implies(lhs, scaleExpressionByPermission(rhs, perm1, pos))
- case _ if ! expr.isInstanceOf[PermissionExpr] => expr
- case _ => throw new InternalErrorException("Unexpected expression, unable to scale.");
- }
- result.pos = expr.pos;
- result
- }
-
- // multiply two permissions
- def multiplyPermission(perm1: Permission, perm2: Permission, pos: Position): Permission = {
- val result = (perm1,perm2) match {
- case (Full,p2) => p2
- case (p1,Full) => p1
- case (Epsilons(_),_) => throw new NotSupportedException(pos + ": Scaling epsilon permissions with non-full permissions is not possible.")
- case (_,Epsilons(_)) => throw new NotSupportedException(pos + ": Scaling epsilon permissions with non-full permissions is not possible.")
- case (p1,p2) => PermTimes(p1,p2)
- }
- result
- }
-
- def TypeInformation(e: Boogie.Expr, cl: Class): Boogie.Expr = {
- if (cl.IsRef) {
- (e ==@ Boogie.Null()) || (dtype(e) ==@ className(cl))
- } else if (cl.IsSeq && cl.parameters(0).IsRef) {
- val (v,ve) = Boogie.NewBVar("$i", tint, true);
- (0 <= ve && ve < SeqLength(e)
- ==> TypeInformation(SeqIndex(e,ve), cl.parameters(0))).forall(v);
- } else {
- true
- }
- }
-
- /** Generate an expression that represents the state a function can depend on
- * (as determined by examining the functions preconditions).
- */
- def functionDependencies(pre: Expression, etran: ExpressionTranslator): Boogie.Expr = {
- desugar(pre) match {
- case pred@MemberAccess(e, p) if pred.isPredicate =>
- functionDependencies(Access(pred, Full), etran)
- case acc@Access(e, _) =>
- val memberName = if(e.isPredicate) e.predicate.FullName else e.f.FullName;
- heapFragment(new Boogie.MapSelect(etran.Heap, etran.Tr(e.e), memberName))
- case Implies(e0,e1) =>
- heapFragment(Boogie.Ite(etran.Tr(e0), functionDependencies(e1, etran), emptyPartialHeap))
- case And(e0,e1) =>
- combine(functionDependencies(e0, etran), functionDependencies(e1, etran))
- case IfThenElse(con, then, els) =>
- heapFragment(Boogie.Ite(etran.Tr(con), functionDependencies(then, etran), functionDependencies(els, etran)))
- case Unfolding(_, _) =>
- emptyPartialHeap // the predicate of the unfolding expression needs to have been mentioned already (framing check), so we can safely ignore it now
- case p: PermissionExpr => throw new InternalErrorException("unexpected permission expression")
- case e =>
- e visitOpt {_ match {
- case Unfolding(_, _) => false
- case _ : PermissionExpr => throw new InternalErrorException("unexpected permission expression")
- case _ => true }
- }
- emptyPartialHeap
- }
- }
-
- /** Generate the boolean condition that needs to be true in order to assume
- * that a function with precondition pre has the same value in two different
- * states. Essentially, everything that the function can depend on must be
- * equal.
- *
- * - conservative for Implies and IfThenElse
- * - returns an expression of Boogie type bool
- */
- def functionDependenciesEqual(pre: Expression, etran1: ExpressionTranslator, etran2: ExpressionTranslator): Boogie.Expr = {
- desugar(pre) match {
- case pred@MemberAccess(e, p) if pred.isPredicate =>
- functionDependenciesEqual(Access(pred, Full), etran1, etran2)
- case Access(e, _) =>
- val memberName = if(e.isPredicate) e.predicate.FullName else e.f.FullName;
- etran1.Heap.select(etran1.Tr(e.e), memberName) ==@ etran2.Heap.select(etran2.Tr(e.e), memberName)
- case AccessSeq(s, Some(e), _) =>
- val name = if(e.isPredicate) e.predicate.FullName else e.f.FullName;
- val (iV, i) = Boogie.NewBVar("i", tint, true)
- (SeqLength(etran1.Tr(s)) ==@ SeqLength(etran2.Tr(s))) &&
- ((((0 <= i) && (i < SeqLength(etran1.Tr(s)))) ==>
- (etran1.Heap.select(SeqIndex(etran1.Tr(s), i), name) ==@ etran2.Heap.select(SeqIndex(etran2.Tr(s), i), name))).forall(iV))
- case Implies(e0,e1) =>
- Boogie.Ite(etran1.Tr(e0) || etran2.Tr(e0), functionDependenciesEqual(e1, etran1, etran2), true)
- case And(e0,e1) =>
- functionDependenciesEqual(e0, etran1, etran2) && functionDependenciesEqual(e1, etran1, etran2)
- case IfThenElse(con, then, els) =>
- functionDependenciesEqual(then, etran1, etran2) && functionDependenciesEqual(els, etran1, etran2)
- case Unfolding(_, _) =>
- Boogie.BoolLiteral(true) // the predicate of the unfolding expression needs to have been mentioned already (framing check), so we can safely ignore it now
- case _: PermissionExpr => throw new InternalErrorException("unexpected permission expression")
- case e =>
- e visitOpt {_ match {
- case Unfolding(_, _) => false
- case _ : PermissionExpr => throw new InternalErrorException("unexpected permission expression")
- case _ => true }
- }
- Boogie.BoolLiteral(true)
- }
- }
-
- def Preconditions(spec: List[Specification]): List[Expression] = {
- val result = spec flatMap ( s => s match {
- case Precondition(e) => List(e)
- case _ => Nil });
- if(Chalice.autoMagic) {
- automagic(result.foldLeft(BoolLiteral(true): Expression)({ (a, b) => And(a, b)}), Nil)._1 ::: result
- } else {
- result
- }
- }
- def Postconditions(spec: List[Specification]): List[Expression] = {
- val result = spec flatMap ( s => s match {
- case Postcondition(e) => List(e)
- case _ => Nil })
- if(Chalice.autoMagic) {
- automagic(result.foldLeft(BoolLiteral(true): Expression)({ (a, b) => And(a, b)}), Nil)._1 ::: result
- } else {
- result
- }
- }
-
- def automagic(expr: Expression, handled: List[Expression]): (/*assumptions*/ List[Expression], /*newHandled*/List[Expression]) = {
- def isHandled(e: Expression) = handled exists { ex => ex.equals(e) }
- expr match {
- case ma@MemberAccess(obj, f) =>
- val (assumptions, handled1) = automagic(obj, handled);
- if(isHandled(ma)) {
- (assumptions, handled1)
- } else {
- if(ma.isPredicate){
- // assumption: obj!=null
- (assumptions ::: Neq(obj, NullLiteral()) :: Nil, handled1 ::: List(ma))
- } else {
- // assumption: obj!=null && acc(obj, f)
- (assumptions ::: Neq(obj, NullLiteral()) :: Access(ma, Full) :: Nil, handled1 ::: List(ma))
- }
- }
- case Access(ma@MemberAccess(obj, f), perm) =>
- val (assumptions, handled1) = automagic(obj, handled ::: List(ma));
- perm match {
- case Full | Epsilon | Star | MethodEpsilon => (assumptions, handled1);
- case Frac(fraction) => val result = automagic(fraction, handled1); (assumptions ::: result._1, result._2)
- case Epsilons(epsilon) => val result = automagic(epsilon, handled1); (assumptions ::: result._1, result._2)
- case ChannelEpsilon(None) | PredicateEpsilon(None) | MonitorEpsilon(None) => (assumptions, handled1)
- case ChannelEpsilon(Some(e)) => val result = automagic(e, handled1); (assumptions ::: result._1, result._2)
- case PredicateEpsilon(Some(e)) => val result = automagic(e, handled1); (assumptions ::: result._1, result._2)
- case MonitorEpsilon(Some(e)) => val result = automagic(e, handled1); (assumptions ::: result._1, result._2)
- case ForkEpsilon(e) => val result = automagic(e, handled1); (assumptions ::: result._1, result._2)
- case IntPermTimes(e0, e1) =>
- val (assumptions1, handled2) = automagic(e0, handled1);
- val result = automagic(e1, handled2);
- (assumptions ::: assumptions1 ::: result._1, result._2)
- case PermTimes(e0, e1) =>
- val (assumptions1, handled2) = automagic(e0, handled1);
- val result = automagic(e1, handled2);
- (assumptions ::: assumptions1 ::: result._1, result._2)
- case PermPlus(e0, e1) =>
- val (assumptions1, handled2) = automagic(e0, handled1);
- val result = automagic(e1, handled2);
- (assumptions ::: assumptions1 ::: result._1, result._2)
- case PermMinus(e0, e1) =>
- val (assumptions1, handled2) = automagic(e0, handled1);
- val result = automagic(e1, handled2);
- (assumptions ::: assumptions1 ::: result._1, result._2)
- }
- case AccessAll(obj, perm) =>
- automagic(obj, handled)
- case Holds(e) =>
- automagic(e, handled)
- case RdHolds(e) =>
- automagic(e, handled)
- case a: Assigned =>
- (Nil, handled)
- case Old(e) =>
- (Nil, handled) // ??
- case IfThenElse(con, then, els) =>
- val (assumptions, handled1) = automagic(con, handled);
- val (assumptions2, handled2) = automagic(then, handled1);
- val result = automagic(els, handled2);
- (assumptions ::: assumptions2 ::: result._1, result._2)
- case Not(e) =>
- automagic(e, handled)
- case func@FunctionApplication(obj, id, args) =>
- var assumption = Nil: List[Expression];
- var newHandled = handled;
- for(a <- obj :: args) {
- val (ass, hd) = automagic(a, handled);
- assumption = assumption ::: ass;
- newHandled = hd;
- }
- (assumption, newHandled)
- case uf@Unfolding(_, e) =>
- (Nil, handled)
- case bin: BinaryExpr =>
- val (assumptions, handled1) = automagic(bin.E0, handled);
- val result = automagic(bin.E1, handled1);
- (assumptions ::: result._1, result._2)
- case EmptySeq(t) =>
- (Nil, handled)
- case ExplicitSeq(es) =>
- var assumption = Nil: List[Expression];
- var newHandled = handled;
- for(a <- es) {
- val (ass, hd) = automagic(a, handled);
- assumption = assumption ::: ass;
- newHandled = hd;
- }
- (assumption, newHandled)
- case Range(min, max) =>
- val (assumptions, handled1) = automagic(min, handled);
- val result = automagic(max, handled1);
- (assumptions ::: result._1, result._2)
- case Length(e) =>
- automagic(e, handled)
- case Eval(h, e) =>
- (Nil, handled)
- case _ => (Nil, handled)
- }
- }
-
- def DefinitionOf(predicate: Predicate): Expression = {
- if(Chalice.autoMagic) {
- And(automagic(predicate.definition, Nil)._1.foldLeft(BoolLiteral(true): Expression)({ (a, b) => And(a, b)}), predicate.definition)
- } else {
- predicate.definition
- }
- }
-
- def LockChanges(spec: List[Specification]): List[Expression] = {
- spec flatMap ( s => s match {
- case LockChange(ee) => ee
- case _ => Nil })
- }
-
- def SubstRd(e: Expression): Expression = e match {
- case Access(e, p: Permission) if p != Star =>
- //val r = Access(e,MonitorEpsilon(None)); r.pos = e.pos; r.typ = BoolClass; r
- val r = Access(e,Epsilons(IntLiteral(1))); r.pos = e.pos; r.typ = BoolClass; r
- case Implies(e0,e1) =>
- val r = Implies(e0, SubstRd(e1)); r.pos = e.pos; r.typ = BoolClass; r
- case And(e0,e1) =>
- val r = And(SubstRd(e0), SubstRd(e1)); r.pos = e.pos; r.typ = BoolClass; r
- case _ => e
- }
-
- def UnfoldPredicatesWithReceiverThis(expr: Expression): Expression = {
- val func = (e:Expression) =>
- e match {
- case pred@MemberAccess(o, f) if pred.isPredicate && o.isInstanceOf[ThisExpr] =>
- Some(SubstThis(DefinitionOf(pred.predicate), o))
- case Access(pred@MemberAccess(o, f), p) if pred.isPredicate && o.isInstanceOf[ThisExpr] =>
- val definition = scaleExpressionByPermission(SubstThis(DefinitionOf(pred.predicate), o), p, e.pos)
- Some(definition)
- case func@FunctionApplication(obj: ThisExpr, name, args) if 2<=Chalice.defaults && func.f.definition.isDefined =>
- Some(SubstVars(func.f.definition.get, obj, func.f.ins, args))
- case _ => None
- }
- AST.transform(expr, func)
- }
-
- // needed to do a _simultaneous_ substitution!
- def SubstVars(expr: Expression, x:Expression, vs:List[Variable], es:List[Expression]): Expression =
- SubstVars(expr, Some(x), Map() ++ (vs zip es));
- def SubstVars(expr: Expression, vs:List[Variable], es:List[Expression]): Expression =
- SubstVars(expr, None, Map() ++ (vs zip es));
- def SubstVars(expr: Expression, t: Option[Expression], vs: Map[Variable, Expression]): Expression = expr.transform {
- case _: ThisExpr if t.isDefined => t
- case e: VariableExpr =>
- if (vs.contains(e.v)) Some(vs(e.v)) else None;
- case q: Quantification =>
- q.variables foreach { (v) => if (vs.contains(v)) throw new InternalErrorException("cannot substitute a variable bound in the quantifier")}
- None;
- case _ => None;
- }
-
- def SubstThis(expr: Expression, x: Expression): Expression = expr.transform {
- case _: ThisExpr => Some(x)
- case _ => None
- }
-
- def SubstResult(expr: Expression, x: Expression): Expression = expr.transform {
- case _: Result => Some(x)
- case _ => None
- }
-
- // De-sugar expression (idempotent)
- // * unroll wildcard pattern (for objects) in permission expression
- // * convert sequence quantification into type quantification
- // * perform simple permission expression optimizations (e.g. Frac(1)+Frac(1) = Frac(1+1) or Frac(100) = Full)
- // * simplify quantification over empty sequences
- def desugar(expr: Expression): Expression = expr transform {
- _ match {
- case Frac(IntLiteral(100)) => Some(Full)
- case PermTimes(Full, r) => Some(r)
- case PermTimes(l, Full) => Some(l)
- case PermPlus(lhs, rhs) =>
- val ll = desugar(lhs)
- val rr = desugar(rhs)
- (ll, rr) match {
- case (Frac(l), Frac(r)) => Some(Frac(Plus(l,r)))
- case _ => Some(PermPlus(ll.asInstanceOf[Permission], rr.asInstanceOf[Permission]))
- }
- case PermMinus(lhs, rhs) =>
- val ll = desugar(lhs)
- val rr = desugar(rhs)
- (ll, rr) match {
- case (Frac(l), Frac(r)) => Some(Frac(Minus(l,r)))
- case _ => Some(PermMinus(ll.asInstanceOf[Permission], rr.asInstanceOf[Permission]))
- }
- case PermTimes(lhs, rhs) =>
- val ll = desugar(lhs)
- val rr = desugar(rhs)
- (ll, rr) match {
- case (Frac(l), Frac(r)) => Some(Frac(Times(l,r)))
- case _ => Some(PermTimes(ll.asInstanceOf[Permission], rr.asInstanceOf[Permission]))
- }
- case AccessAll(obj, perm) =>
- Some(obj.typ.Fields.map({f =>
- val ma = MemberAccess(desugar(obj), f.id);
- ma.f = f; ma.pos = expr.pos; ma.typ = f.typ.typ;
- val acc = Access(ma, perm);
- acc.pos = expr.pos; acc.typ = acc.typ; acc
- }).foldLeft(BoolLiteral(true): Expression){(e1, e2) =>
- val and = And(e1, e2);
- and.pos = expr.pos; and.typ = BoolClass; and
- })
- case AccessSeq(s, None, perm) =>
- Some(s.typ.parameters(0).Fields.map({(f) =>
- val ma = MemberAccess(At(desugar(s), IntLiteral(0)), f.id);
- ma.f = f; ma.pos = expr.pos; ma.typ = f.typ.typ;
- val acc = AccessSeq(s, Some(ma), perm);
- acc.pos = expr.pos; acc.typ = acc.typ; acc
- }).foldLeft(BoolLiteral(true): Expression){(e1, e2) =>
- val and = And(e1, e2);
- and.pos = expr.pos; and.typ = BoolClass; and
- })
- case qe @ SeqQuantification(q, is, Range(min, max), e) =>
- val dmin = desugar(min);
- val dmax = desugar(max);
- val dis = qe.variables;
- val disx = dis map {v => new VariableExpr(v)};
- val de = desugar(e);
-
- val assumption = disx map {x =>
- And(AtMost(dmin, x), Less(x, dmax))
- } reduceLeft {(e0, e1) =>
- And(e0, e1)
- };
- assumption transform {e => e.pos = expr.pos; None};
- val body = q match {
- case Forall => Implies(assumption, de);
- case Exists => And(assumption, de);
- }
- body.pos = expr.pos;
- val result = TypeQuantification(q, is, new Type(IntClass), body, (dmin,dmax));
- result.variables = dis;
- Some(result);
- case qe @ SeqQuantification(Forall, is, ExplicitSeq(List()), e) => Some(BoolLiteral(true))
- case qe @ SeqQuantification(Exists, is, ExplicitSeq(List()), e) => Some(BoolLiteral(false))
- case qe @ SeqQuantification(Forall, is, EmptySeq(_), e) => Some(BoolLiteral(true))
- case qe @ SeqQuantification(Exists, is, EmptySeq(_), e) => Some(BoolLiteral(false))
- case qe @ SeqQuantification(q, is, seq, e) =>
- val dseq = desugar(seq);
- val min = IntLiteral(0);
- val max = Length(dseq);
- val dis = qe.variables map {v => new Variable(v.UniqueName, new Type(IntClass))};
- val disx = dis map {v => new VariableExpr(v)};
- val de = SubstVars(desugar(e), qe.variables, disx map {x => At(dseq, x)});
-
- val assumption = disx map {x =>
- And(AtMost(min, x), Less(x, max))
- } reduceLeft {(e0, e1) =>
- And(e0, e1)
- };
- assumption transform {e => e.pos = expr.pos; None};
- val body = q match {
- case Forall => Implies(assumption, de);
- case Exists => And(assumption, de);
- }
- body.pos = expr.pos;
- val result = new TypeQuantification(q, is, new Type(IntClass), body);
- result.variables = dis;
- Some(result);
- case _ => None;
- }
- }
-
- // tags statements to be preserved
- val keepTag = Boogie.Tag("keep")
-
- // Assume the only composite statement in Boogie is If
- def tag(l: List[Stmt], t: Boogie.Tag):List[Stmt] =
- for (s <- l) yield {
- s.tags = t :: s.tags;
- s match {
- case Boogie.If(_, thn, els) => tag(thn, t); tag(els, t);
- case _ =>
- }
- s
- }
- // Assume the only composite statement in Boogie is If
- def assert2assume(l: List[Stmt], b: Boolean):List[Stmt] =
- if (Chalice.noFreeAssume && b) l else
- l flatMap {
- case Boogie.If(guard, thn, els) => Boogie.If(guard, assert2assume(thn), assert2assume(els))
- case ba @ Boogie.Assert(e) =>
- if (ba.tags contains keepTag) ba else Comment(" assert " + ba.pos + ": " + ba.message) :: Boogie.Assume(e)
- case s => s
- }
- def assert2assume(l: List[Stmt]):List[Stmt] = assert2assume(l, false)
-}
-
-}
diff --git a/Chalice/tests/examples/AVLTree.iterative.chalice b/Chalice/tests/examples/AVLTree.iterative.chalice
deleted file mode 100644
index 4156a73f..00000000
--- a/Chalice/tests/examples/AVLTree.iterative.chalice
+++ /dev/null
@@ -1,227 +0,0 @@
-class AVLTree{
- var root : AVLTreeNode;
-
- predicate valid{
- acc(root,100)
- && (root!=null ==> root.valid)
- && (root!=null ==> acc(root.parent,100))
- && (root!=null ==> root.parent==null)
- && (root!=null ==> acc(root.root,50))
- && (root!=null ==> root.root==root)
- }
-
- method init()
- requires acc(root,100);
- ensures valid;
- {
- root := null;
- fold valid;
- }
-
- method has(k : int) returns (b : bool)
- requires valid;
- ensures valid;
- {
- unfold valid;
- if (root==null){
- b := false;
- fold valid;
- }else{
- var n : AVLTreeNode := root;
- b := false;
- var end : bool := false;
- fold n.udParentValid;
- while (!end)
- invariant acc(root,100);
- invariant root != null && acc(root.parent,50);
- invariant n!=null;
- invariant n.valid;
- invariant acc(n.root,40);
- invariant n.udParentValid;
- invariant unfolding n.valid in n.root==root;
- invariant root!=null;
- {
- unfold n.valid;
- unfold n.validRest;
- if (n.key==k){
- b := true;
- fold n.validRest;
- fold n.valid;
- end := true;
- }else{
- if (n.key<k){
- if (n.left==null){
- end := true;
- fold n.validRest;
- fold n.valid;
- }else{
- var p : AVLTreeNode := n;
- unfold p.leftValid;
- n := p.left;
- p.leftDown := true;
- fold p.leftOpen;
- fold p.udValid;
- assert p.right!=p.left;
- assert n.parent.left==n;
- fold n.udParentValid;
- }
- }else{
- if (n.right==null){
- end := true;
- fold n.validRest;
- fold n.valid;
- }else{
- var p : AVLTreeNode := n;
- unfold p.rightValid;
- n := p.right;
- p.leftDown := false;
- fold p.rightOpen;
- fold p.udValid;
- fold n.udParentValid;
- }
- }
- }
- }
-
- end := false;
- while (!end)
- invariant acc(root,100);
- invariant root != null && acc(root.parent,50);
- invariant n!=null;
- invariant n.valid;
- invariant n.udParentValid;
- invariant acc(n.root,40);
- invariant unfolding n.valid in n.root==root;
- invariant root!=null;
- invariant end==>unfolding n.udParentValid in n.parent==null;
- {
- unfold n.udParentValid;
- var p : AVLTreeNode := n.parent;
- if (p==null){
- end := true;
- fold n.udParentValid;
- }else{
- unfold p.udValid;
- if (p.left==n){
- unfold p.leftOpen;
- fold p.leftValid;
- }else{
- unfold p.rightOpen;
- fold p.rightValid;
- }
- fold p.validRest;
- fold p.valid;
- n:=p;
- }
- }
- assert unfolding n.udParentValid in n==root;
- assert acc(n.root,40);
- unfold n.udParentValid;
- assert acc(n.root,50);
- fold valid;
- }
- }
-}
-
-class AVLTreeNode{
- var key : int;
- var left : AVLTreeNode;
- var right : AVLTreeNode;
- var parent : AVLTreeNode;
-
- ghost var leftDown : bool;
- ghost var root : AVLTreeNode;
-
- predicate valid{
- validRest
- && leftValid
- && rightValid
- }
-
- predicate validRest{
- acc(key ,100)
- && acc(root, 30)
- && acc(left ,75)
- && acc(right ,75)
- && acc(leftDown,100)
- && (right!=left || right==null)
- }
-
- predicate rightValid{
- acc(right ,25)
- && acc(root,10)
- && (right!=null ==> right.valid)
- && (right!=null ==> acc(right.parent,100))
- && (right!=null ==> right.parent==this)
- && (right!=null ==> acc(right.root,50))
- && (right!=null ==> right.root==root)
- }
- predicate leftValid{
- acc(left ,25)
- && acc(root,10)
- && (left!=null ==> left.valid)
- && (left!=null ==> acc(left.parent,100))
- && (left!=null ==> left.parent == this)
- && (left!=null ==> acc(left.root,50))
- && (left!=null ==> left.root == root)
- }
-
- predicate leftOpen{
- acc(left ,25)
- && acc(root,10)
- && (left!=null ==> acc(left.parent,50))
- && (left!=null ==> left.parent==this)
- }
-
- predicate rightOpen{
- acc(right ,25)
- && acc(root,10)
- && (right!=null ==> acc(right.parent,50))
- && (right!=null ==> right.parent==this)
- }
-
- predicate udParentValid {
- acc(parent,50)
- && acc(root,10)
- && (parent!=null ==> parent.udValid)
- && (parent!=null ==> acc(parent.leftDown,50))
- && (parent!=null ==> acc(parent.left,50))
- && (parent!=null ==> ( parent.leftDown<==>parent.left==this))
- && (parent!=null ==> acc(parent.right,50))
- && (parent!=null ==> (!parent.leftDown<==>parent.right==this))
- && (parent!=null ==> acc(parent.root,50))
- && (parent!=null ==> root==parent.root)
- && (parent==null ==> root==this)
- }
-
- predicate udValid{
- acc(key ,100)
- && acc(leftDown,50)
- && acc(left ,25)
- && acc(right ,25)
- && acc(root ,20)
- && ( leftDown ==> rightValid)
- && ( leftDown ==> leftOpen )
- && (!leftDown ==> leftValid )
- && (!leftDown ==> rightOpen )
- && udParentValid
- }
-
- method init(k : int)
- requires acc(key ,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(leftDown ,100);
- requires acc(root, 100);
- ensures valid;
- {
- left := null;
- right := null;
- key := k;
-
- fold leftValid;
- fold rightValid;
- fold validRest;
- fold valid;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/AVLTree.iterative.output.txt b/Chalice/tests/examples/AVLTree.iterative.output.txt
deleted file mode 100644
index 9b8797ef..00000000
--- a/Chalice/tests/examples/AVLTree.iterative.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of AVLTree.iterative.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/AVLTree.nokeys.chalice b/Chalice/tests/examples/AVLTree.nokeys.chalice
deleted file mode 100644
index 721541f2..00000000
--- a/Chalice/tests/examples/AVLTree.nokeys.chalice
+++ /dev/null
@@ -1,609 +0,0 @@
-class AVLTree{
- var root : AVLTreeNode;
-
- predicate valid{
- acc(root,100)
- && (root!=null ==> root.valid)
- && (root!=null ==> acc(root.height ,50))
- && (root!=null ==> acc(root.balanceFactor,50))
- }
-
- method init()
- requires acc(root,100);
- ensures valid;
- {
- root := null;
- fold valid;
- }
-
- method insert(k : int)
- requires valid;
- ensures valid;
- {
- unfold valid;
- if (root==null){
- var n : AVLTreeNode := new AVLTreeNode;
- call n.init(k);
- root := n;
- }else{
- call r := root.insert(k);
- root := r;
- }
- fold valid;
- }
-
- method remove(k : int)
- requires valid;
- ensures valid;
- {
- unfold valid;
- if (root==null){
- }else{
- call r := root.remove(k);
- root := r;
- }
- fold valid;
- }
-
- method has(k : int) returns (b : bool)
- requires valid;
- ensures valid;
- {
- unfold valid;
- if (root==null){
- b := false;
- }else{
- var bb : bool;
- call bb:= root.has(k);
- b := bb;
- }
- fold valid;
- }
-}
-
-class AVLTreeNode{
- var key : int;
- var height : int;
- var left : AVLTreeNode;
- var right : AVLTreeNode;
- ghost var balanceFactor : int;
-
- predicate valid{
- acc(key ,100)
- && acc(height,50)
- && acc(left ,100)
- && acc(right ,100)
- && acc(balanceFactor,50)
- && (left!=null ==> left.valid)
- && (left!=null ==> acc(left.height ,50))
- && (left!=null ==> acc(left.balanceFactor,50))
- && (left!=null ==> left.height > 0)
- && (right!=null ==> right.valid)
- && (right!=null ==> acc(right.height ,50))
- && (right!=null ==> acc(right.balanceFactor,50))
- && (right!=null ==> right.height > 0)
- && height == ( (left==null?0:left.height)>(right==null?0:right.height) ? (left==null?0:left.height)+1 : (right==null?0:right.height)+1 )
- && balanceFactor == (left==null?0:left.height) - (right==null?0:right.height)
- && balanceFactor<= 1
- && balanceFactor>=-1
- && height > 0
- }
-
- method init(k : int)
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100)
- ensures valid;
- ensures acc(height,50);
- ensures acc(balanceFactor,50);
- ensures height == 1;
- ensures balanceFactor == 0;
- {
- left := null;
- right := null;
- key := k;
- call close();
- }
-
- method insert(k : int) returns ( r : AVLTreeNode )
- requires valid;
- requires acc(height,50);
- requires acc(balanceFactor,50);
- ensures r != null;
- ensures r.valid;
- ensures acc(r.height,50);
- ensures acc(r.balanceFactor,50);
- ensures ( r.height == old(height) ) || ( r.height == old(height) + 1 );
- {
- unfold valid;
- if (key==k){
- r := this;
- call r.close();
- }else{ //key!=k
- if (k<key){ // insert left
- var nl : AVLTreeNode;
- if (left==null){
- nl := new AVLTreeNode;
- call nl.init(k);
- }else{
- call nl := left.insert(k);
- }
- left := nl;
- var bf : int;
- call bf := getBalanceFactorI();
-
- if (bf==2){ //rebalance
- call r:= rebalanceLeft();
- }else{ //no rebalance
- r := this;
- call r.close();
- }
- }else{ // k>key -- insert right
- var nr : AVLTreeNode;
- if (right==null){
- nr := new AVLTreeNode;
- call nr.init(k);
- }else{
- call nr := right.insert(k);
- }
- right := nr;
-
- var bf : int;
- call bf := getBalanceFactorI();
- if (bf==-2){ //rebalance
- call r := rebalanceRight();
- }else{//no rebalance
- r := this;
- call r.close();
- }
- }
- }
- }
-
- method remove(k : int) returns ( r : AVLTreeNode )
- requires valid;
- requires acc(height,50);
- requires acc(balanceFactor,50);
- ensures r != null ==> r.valid;
- ensures r != null ==> acc(r.height,50);
- ensures r != null ==> acc(r.balanceFactor,50);
- ensures old(height)>1 ==> r!=null;
- ensures r != null ==> r.height==old(height) || r.height+1==old(height);
- {
- unfold valid;
- if (key==k){
- if (left==null || right==null){
- if (left==null){ // replace with right
- r := right;
- }else{ // right==null
- r := left;
- }
- }else{ // prune max/min of left/right
- var bf : int;
- var nl : AVLTreeNode := left;
- var nr : AVLTreeNode := right;
-
- call bf := getBalanceFactorI();
- if (bf > 0 ){ // left larger - prune leftmax
- call nl,r := left.pruneMax();
- }else{ // right larger equal - prune rightmin
- call nr,r := right.pruneMin();
- }
- unfold r.valid;
- r.left := nl;
- r.right := nr;
- call r.close();
- }
- }else{ //key!=k
- if (k<key){ // remove left
- if (left!=null){
- var nl : AVLTreeNode;
- call nl := left.remove(k);
- left := nl;
-
- var bf : int;
- call bf := getBalanceFactorI();
-
- if (bf==-2){ // rebalance
- call r:=rebalanceRight();
- }else{ // no rebalance
- call close();
- r := this;
- }
- }else{
- r := this;
- call r.close();
- }
- }else{ // k>key -- remove right
- if (right != null){
- var nr : AVLTreeNode;
- call nr := right.remove(k);
- right := nr;
-
- var bf : int;
- call bf := getBalanceFactorI();
- if (bf==2){ // rebalance
- call r := rebalanceLeft();
- }else{ // no rebalance
- r := this;
- call r.close();
- }
- }else{
- r := this;
- call r.close();
- }
- }
- }
- }
-
- method pruneMax() returns ( r : AVLTreeNode, m : AVLTreeNode )
- requires valid;
- requires acc(height,50);
- requires acc(balanceFactor,50);
- ensures r != null ==> r.valid;
- ensures r != null ==> acc(r.height,50);
- ensures r != null ==> acc(r.balanceFactor,50);
- ensures r != null ==> (r.height == old(height) || r.height+1 == old(height));
- ensures old(height) >1 ==> r != null;
- ensures old(height)==1 ==> r == null;
- ensures old(height)==(r==null?0:r.height) || old(height)==(r==null?0:r.height)+1;
- ensures m != null;
- ensures m.valid;
- ensures acc(m.height,50);
- ensures acc(m.balanceFactor,50);
- ensures m.height == 1;
- {
- unfold valid;
- if (right==null){
- r := left;
- left := null;
- call close();
- m := this;
- }else{
- var nr : AVLTreeNode;
- call nr,m := right.pruneMax();
- right := nr;
- var bf : int;
- call bf := getBalanceFactorI();
- if (bf == 2){
- call r:=rebalanceLeft();
- }else{
- call close();
- r := this;
- }
- }
- }
-
- method pruneMin() returns ( r : AVLTreeNode, m : AVLTreeNode )
- requires valid;
- requires acc(height,50);
- requires acc(balanceFactor,50);
- ensures r != null ==> r.valid;
- ensures r != null ==> acc(r.height,50);
- ensures r != null ==> acc(r.balanceFactor,50);
- ensures r != null ==> (r.height == old(height) || r.height == old(height)-1);
- ensures old(height) >1 ==> r != null;
- ensures old(height)==1 ==> r == null;
- ensures old(height)==(r==null?0:r.height) || old(height)==(r==null?0:r.height)+1;
- ensures m != null;
- ensures m.valid;
- ensures acc(m.height,50);
- ensures acc(m.balanceFactor,50);
- ensures m.height == 1;
- {
- unfold valid;
- if (left==null){
- r := right;
- right := null;
- call close();
- m := this;
- assert r!=null ==> (r.height == old(height) || r.height == old(height)-1);
- }else{
- var nl : AVLTreeNode;
- call nl,m := left.pruneMin();
- left := nl;
- var bf : int;
- call bf := getBalanceFactorI();
- if (bf == -2){
- call r:=rebalanceRight();
- assert r != null ==> (r.height == old(height) || r.height == old(height)-1);
- }else{
- call close();
- r := this;
- assert r != null ==> (r.height == old(height) || r.height == old(height)-1);
- }
- }
- }
-
- method has(k : int) returns (b : bool)
- requires valid;
- ensures valid;
- {
- unfold valid;
- if (k==key){
- b := true;
- }else{ //k!=key
- if (k < key){
- if (left!=null){
- call b := left.has(k);
- }else{
- b := false;
- }
- }else{ //k > key;
- if (right!=null){
- call b := right.has(k);
- }else{
- b := false;
- }
- }
- }
- fold valid;
- }
-
- method getBalanceFactor() returns ( bf : int )
- requires valid;
- requires rd(balanceFactor);
-
- ensures valid;
- ensures rd(balanceFactor);
- ensures bf == balanceFactor;
-
- ensures unfolding valid in bf>0 ==> left !=null;
- ensures unfolding valid in bf<0 ==> right!=null;
- {
- unfold valid;
- var lh : int := (left ==null ? 0 : left .height );
- var rh : int := (right==null ? 0 : right.height );
- bf := lh-rh;
-
- fold valid;
- }
-
- //////////////////////////////////////////////////////////
- method getBalanceFactorI() returns ( bf : int )
- requires rd(left);
- requires left!=null ==> left.valid;
- requires left!=null ==> rd(left.height);
- requires rd(right);
- requires right!=null ==> right.valid;
- requires right!=null ==> rd(right.height);
- ensures rd(left);
- ensures left!=null ==> left.valid;
- ensures left!=null ==> rd(left.height);
- ensures rd(right);
- ensures right!=null ==> right.valid;
- ensures right!=null ==> rd(right.height);
- ensures bf == (left==null?0:left.height)-(right==null?0:right.height);
- ensures bf>0 ==> left !=null;
- ensures bf<0 ==> right!=null;
- {
- var lh : int := (left ==null ? 0 : left .height );
- var rh : int := (right==null ? 0 : right.height );
- bf := lh-rh;
- assert right!=null ==> unfolding right.valid in right.height>0;
- assert left !=null ==> unfolding left .valid in left .height>0;
- assert lh>=0;
- assert rh>=0;
- }
-
- method close()
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100);
- requires left!=null ==> left.valid;
- requires left!=null ==> acc(left.height ,50);
- requires left!=null ==> acc(left.balanceFactor,50);
- requires right!=null ==> right.valid;
- requires right!=null ==> acc(right.height ,50);
- requires right!=null ==> acc(right.balanceFactor,50);
- requires ( left==null ? 0 : left.height )-( right==null ? 0 : right.height ) <= 1;
- requires ( left==null ? 0 : left.height )-( right==null ? 0 : right.height ) >=-1;
- ensures valid;
- ensures acc(height ,50);
- ensures acc(balanceFactor,50);
- ensures height ==
- ( ( old(left)==null ? 0 : old(left.height) )>( old(right)==null ? 0 : old(right.height) )
- ?
- ( old(left)==null ? 0 : old(left.height) )+1
- :
- ( old(right)==null ? 0 : old(right.height))+1
- );
- ensures balanceFactor ==
- ( old(left)==null ? 0 : old(left.height) )-( old(right)==null ? 0 : old(right.height) );
- {
- var lh : int := (left ==null ? 0 : left .height );
- var rh : int := (right==null ? 0 : right.height );
-
- assert left !=null ==> unfolding left .valid in left .height>0;
- assert right!=null ==> unfolding right.valid in right.height>0;
- height := ( (( left==null ? 0 : left.height )>( right==null ? 0 : right.height )) ? ( left==null ? 0 : left.height )+1 : ( right==null ? 0 : right.height )+1);
-
- balanceFactor := ( left==null ? 0 : left.height )-( right==null ? 0 : right.height );
-
- fold valid;
- }
-
- method rebalanceLeft() returns ( r : AVLTreeNode )
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100);
- requires left!=null;
- requires left.valid;
- requires acc(left.height ,50);
- requires acc(left.balanceFactor,50);
- requires right!=null ==> right.valid;
- requires right!=null ==> acc(right.height ,50)
- requires right!=null ==> acc(right.balanceFactor,50)
- requires left.height-(right==null?0:right.height)==2;
- ensures r != null && r.valid;
- ensures acc(r.height ,50);
- ensures acc(r.balanceFactor,50);
- ensures r.height == old(left.height) || r.height == old(left.height)+1;
- {
- var lbf : int;
- call lbf := left.getBalanceFactor();
- if (lbf<0){
- assert unfolding left.valid in lbf==-1;
- call r := rebalanceRL();
- }else{//lbf>=0
- call r := rebalanceRR();
- }
- }
-
- method rebalanceRL() returns ( r : AVLTreeNode )
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100);
- requires left!=null;
- requires left.valid;
- requires acc(left.height ,50);
- requires acc(left.balanceFactor,50);
- requires right!=null ==> right.valid;
- requires right!=null ==> acc(right.height ,50)
- requires right!=null ==> acc(right.balanceFactor,50)
- requires left.height-(right==null?0:right.height)==2;
- requires left.balanceFactor==-1;
- ensures r != null && r.valid;
- ensures acc(r.height ,50);
- ensures acc(r.balanceFactor,50);
- ensures r.height == old(left.height);
- {
- unfold left.valid;
- r := left.right;
- unfold r.valid;
-
- left.right := r.left;
- call left.close();
- r.left := left;
- left := r.right;
-
- call close();
- r.right := this;
- call r.close();
- }
-
- method rebalanceRR() returns ( r : AVLTreeNode )
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100);
- requires left!=null;
- requires left.valid;
- requires acc(left.height ,50);
- requires acc(left.balanceFactor,50);
- requires right!=null ==> right.valid;
- requires right!=null ==> acc(right.height ,50)
- requires right!=null ==> acc(right.balanceFactor,50)
- requires left.height - (right==null?0:right.height)==2;
- requires left.balanceFactor>=0;
- ensures r != null && r.valid;
- ensures acc(r.height ,50);
- ensures acc(r.balanceFactor,50);
- ensures r.height == old(left.height) || r.height == old(left.height)+1;
- {
- unfold left.valid;
- r := left;
- left := r.right;
- call close();
- r.right := this;
- call r.close();
- }
-
- method rebalanceRight() returns ( r : AVLTreeNode )
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100);
- requires left!=null==>left.valid;
- requires left!=null==>acc(left.height ,50);
- requires left!=null==>acc(left.balanceFactor,50);
- requires right!=null;
- requires right.valid;
- requires acc(right.height ,50)
- requires acc(right.balanceFactor,50)
- requires (left==null?0:left.height)-right.height==-2;
- ensures r != null && r.valid;
- ensures acc(r.height ,50);
- ensures acc(r.balanceFactor,50);
- ensures r.height == old(right.height) || r.height == old(right.height)+1;
- {
- var rbf : int;
- call rbf := right.getBalanceFactor();
- if (rbf>0){
- assert unfolding right.valid in rbf==1;
- call r := rebalanceLR();
- }else{//rbf<=0
- call r := rebalanceLL();
- }
- }
-
- method rebalanceLR() returns ( r : AVLTreeNode )
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100);
- requires left!=null==>left.valid;
- requires left!=null==>acc(left.height ,50);
- requires left!=null==>acc(left.balanceFactor,50);
- requires right!=null;
- requires right.valid;
- requires acc(right.height ,50);
- requires acc(right.balanceFactor,50);
- requires (left==null?0:left.height)-right.height==-2;
- requires right.balanceFactor==1;
- ensures r != null && r.valid;
- ensures acc(r.height ,50);
- ensures acc(r.balanceFactor,50);
- ensures r.height == old(right.height);
- {
- unfold right.valid;
- r := right.left;
- unfold r.valid;
- right.left := r.right;
- call right.close();
- r.right := right;
- right := r.left;
- call close();
- r.left := this;
- call r.close();
- }
-
- method rebalanceLL() returns ( r : AVLTreeNode )
- requires acc(key ,100);
- requires acc(height,100);
- requires acc(left ,100);
- requires acc(right ,100);
- requires acc(balanceFactor,100);
- requires left!=null==>left.valid;
- requires left!=null==>acc(left.height ,50);
- requires left!=null==>acc(left.balanceFactor,50);
- requires right!=null;
- requires right.valid;
- requires acc(right.height ,50);
- requires acc(right.balanceFactor,50);
- requires (left==null?0:left.height)-right.height==-2;
- requires right.balanceFactor<=0;
- ensures r != null && r.valid;
- ensures acc(r.height ,50);
- ensures acc(r.balanceFactor,50);
- ensures r.height == old(right.height) || r.height == old(right.height)+1;
- {
- unfold right.valid;
- r := right;
- right := r.left;
- call close();
- r.left := this;
- call r.close();
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/AVLTree.nokeys.output.txt b/Chalice/tests/examples/AVLTree.nokeys.output.txt
deleted file mode 100644
index 49850add..00000000
--- a/Chalice/tests/examples/AVLTree.nokeys.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of AVLTree.nokeys.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/AssociationList.chalice b/Chalice/tests/examples/AssociationList.chalice
deleted file mode 100644
index 418bcd12..00000000
--- a/Chalice/tests/examples/AssociationList.chalice
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- Note: This example seems to be completely broken. The failing assertion
- about locking/unlocking too much causes an inconsistency and all following
- assertions pass by default.
- It seems that the specification, in particular the loop invariant in method
- Add, is wrong. (see also http://boogie.codeplex.com/workitem/10207)
- -- August 2011, Stefan Heule
-*/
-
-class Client {
- method Main(d: Data)
- requires d != null
- {
- var a := new AssociationList
- call a.Init()
- call a.Add(5, d)
- call a.Add(10, d)
- var t: Data
- call t := a.Get(10)
- }
-}
-
-class AssociationList {
- var head: Node // sentinel
- invariant rd(head) && head != null
- invariant rd(mu) && rd(head.mu) && this << head
-
- method Init()
- requires acc(head) && acc(mu) && mu == lockbottom
- ensures acc(mu) && waitlevel << this
- {
- head := new Node
- head.next := null
- share head
- share this between waitlevel and head
- }
-
- method Add(key: int, value: Data)
- requires value != null
- requires rd(mu) && waitlevel << this
- ensures rd(mu)
- {
- acquire this
- var p: Node := head
- acquire p
- release this
-
- var n := new Node
- n.key := key
- n.value := value
- n.next := p.next
- p.next := n
- share n between p and n.next
- release p
- }
-
- method Get(key: int) returns (d: Data)
- requires rd(mu) && waitlevel << this
- ensures rd(mu)
- {
- d := null
- acquire this
- var p: Node := head
- acquire p
- release this
-
- if (p.next != null) {
- acquire p.next
- if (p.next.key == key) {
- d := p.next.value
- } else {
- var done := false
- while (!done)
- // invariant: holds p and p.next
- invariant p != null && rd(p.key) && rd(p.value) && acc(p.next) && acc(p.mu,50) && p.next != null
- invariant acc(p.next.mu) && p << p.next
- invariant rd(p.next.key) && rd(p.next.value) && acc(p.next.next)
- invariant p.next.next != null ==>
- acc(p.next.next.mu,50) && p.next << p.next.next
- invariant holds(p) && holds(p.next) && waitlevel == p.next.mu
- invariant p.next.next != null ==> waitlevel << p.next.next
- lockchange p, p.next.next
- {
- if (p.next.next == null) {
- done := true // key not present
- } else {
- acquire p.next.next
- if (p.next.next.key == key) {
- done := true // key is present
- d := p.next.next.value
- // move p.next.next closer to the head by one step
-
- var t: Node := p.next
- p.next := t.next
- t.next := p.next.next
- p.next.next := t
- reorder t between p.next and t.next
- release t
- } else {
- var t: Node := p
- p := p.next
- release t
- }
- }
- }
- }
- release p.next
- }
- release p
- }
-}
-
-class Data { }
-
-class Node
-{
- var key: int
- var value: Data
- var next: Node
- invariant rd(key) && rd(value) && acc(next) && acc(mu,50)
- invariant next != null ==> acc(next.mu,50) && this << next
-}
diff --git a/Chalice/tests/examples/AssociationList.output.txt b/Chalice/tests/examples/AssociationList.output.txt
deleted file mode 100644
index e7ae56f6..00000000
--- a/Chalice/tests/examples/AssociationList.output.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Verification of AssociationList.chalice using parameters=""
-
- 28.3: The postcondition at 30.13 might not hold. Insufficient fraction at 30.13 for mu.
- 73.9: Method execution before loop might lock/unlock more than allowed by lockchange clause of loop.
- 98.15: Monitor invariant might hot hold. Insufficient fraction at 120.13 for Node.key.
- 102.15: Monitor invariant might hot hold. Insufficient fraction at 120.13 for Node.key.
- 73.9: The loop might lock/unlock more than the lockchange clause allows.
- 107.7: Monitor invariant might hot hold. Insufficient fraction at 120.13 for Node.key.
-
-Boogie program verifier finished with 6 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/BackgroundComputation.chalice b/Chalice/tests/examples/BackgroundComputation.chalice
deleted file mode 100644
index e8168183..00000000
--- a/Chalice/tests/examples/BackgroundComputation.chalice
+++ /dev/null
@@ -1,38 +0,0 @@
-class C {
- var x: int;
-
- method main()
- requires acc(x);
- ensures acc(x);
- {
- // start long-running processing
- fork tk := processing();
-
- /* do some computation itself */
-
- // finish
- call finish(tk);
- }
-
- method finish(tk: token<C.processing>)
- requires acc(x,100-rd(tk));
- requires acc(tk.joinable) && tk.joinable && tk != null;
- requires eval(tk.fork this.processing(), true);
- ensures acc(x);
- {
- var res: int;
- join res := tk;
-
- // final write to x (requires full permission)
- this.x := res - 1;
- }
-
- method processing() returns (res: int)
- requires rd(x);
- ensures rd(x);
- {
- res := 1;
- /* do some computation */
- }
-
-}
diff --git a/Chalice/tests/examples/BackgroundComputation.output.txt b/Chalice/tests/examples/BackgroundComputation.output.txt
deleted file mode 100644
index ad3f590e..00000000
--- a/Chalice/tests/examples/BackgroundComputation.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of BackgroundComputation.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/CopyLessMessagePassing-with-ack.chalice b/Chalice/tests/examples/CopyLessMessagePassing-with-ack.chalice
deleted file mode 100644
index 9ed9f0a9..00000000
--- a/Chalice/tests/examples/CopyLessMessagePassing-with-ack.chalice
+++ /dev/null
@@ -1,87 +0,0 @@
-// program inspired by "Proving Copyless Message Passing" (Villard, Lozes and Calcagno, APLAS 2009)
-
-// msg tag indicates what the type of the message
-// channel is freed by Getter when it completes
-// ack works, but an assume is needed and negative credits are sent over channels!
-
-// Conjecture: it is ok to send debit for yourself over yourself.
-// Why: Suppose a channel that allows self-debt is involved in a deadlock. The either that channel is empty, which means there's no difference between the situation with or with self-debt. Or the channel is non-empty. This means that we can make progress by receiving the message stored in the channel! Does this make any sense?
-
-channel C(msg: int, n: Node) where
- (msg == 0 || msg == 1 || msg == 2) &&
- (msg == 0 ==> credit(this, -1)) && // ack
- (msg == 1 ==> n != null && acc(n.next) && acc(n.mu) && credit(this, -1)) && // cell
- (msg == 2 ==> acc(this.mu, 50)); // done
-
-
-class Node {
- var next: Node;
-
- function length(): int
- requires this.list;
- {
- unfolding this.list in 1 + (next == null ? 0 : next.length())
- }
-
- predicate list {
- acc(next) && acc(mu) && (next != null ==> next.list)
- }
-}
-
-class Program {
- method Putter(e: C, x0: Node)
- requires e!= null && acc(e.mu, 50) && e.mu == waitlevel && (x0 != null ==> x0.list) && (x0 != null ==> credit(e, - 1));
- {
- var x: Node := x0;
- var t: Node;
-
- while(x != null)
- invariant (x != null ==> x.list) && acc(e.mu, 50) && credit(e, - 1);
- {
- unfold x.list;
- t := x.next;
- send e(1, x);
- x := t;
- var ack;
- assume waitlevel << e.mu; // Chalice should be able to figure this out itself
- receive ack, t := e;
- if(ack != 2) { assume false; /* abort */ }
- }
- send e(2, null);
- }
-
- method Getter(f: C)
- requires f!= null && credit(f, 1) && acc(f.mu, 50) && waitlevel << f.mu;
- {
- var x: Node := null;
- var msg := 1;
- while(msg != 0)
- invariant msg == 0 || msg == 1;
- invariant acc(f.mu, 50) && waitlevel << f.mu && (credit(f, 1));
- {
- assert msg == 1
- receive msg, x := f;
-
- if(msg == 1) {
- free x;
- }
- send f(0, null);
- if(msg == 2) { assume false; /* abort */ }
- }
- receive msg, x := f;
- if (msg != 2) { assume false; /* abort */ }
- free f; // close the channel
- }
-
- method Main(x: Node)
- requires x != null;
- requires x.list;
- {
- var e := new C;
- fork Putter(e, x);
- fork Getter(e);
- }
-}
-
-
-
diff --git a/Chalice/tests/examples/CopyLessMessagePassing-with-ack.output.txt b/Chalice/tests/examples/CopyLessMessagePassing-with-ack.output.txt
deleted file mode 100644
index 91c56769..00000000
--- a/Chalice/tests/examples/CopyLessMessagePassing-with-ack.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of CopyLessMessagePassing-with-ack.chalice using parameters=""
-
-
- 48.22: Assumption introduces a contradiction.
- 69.22: Assumption introduces a contradiction.
- 72.21: Assumption introduces a contradiction.
-
-Boogie program verifier finished with 0 errors and 3 smoke test warnings
diff --git a/Chalice/tests/examples/CopyLessMessagePassing-with-ack2.chalice b/Chalice/tests/examples/CopyLessMessagePassing-with-ack2.chalice
deleted file mode 100644
index 3b03853d..00000000
--- a/Chalice/tests/examples/CopyLessMessagePassing-with-ack2.chalice
+++ /dev/null
@@ -1,86 +0,0 @@
-// program inspired by "Proving Copyless Message Passing" (Villard, Lozes and Calcagno, APLAS 2009)
-
-// msg tag indicates what the type of the message
-// channel is freed by Getter when it completes
-// ack-channel instead of single channel with ack message channel
-// using Owicki-Gries ghostfields can be used to remove the "assume false;" statements
-
-// Conjecture: it is ok to send debit credit(d, -x) over a channel c as long as
-// a) d.mu << c.mu
-// b) leaking positive or negative debit is not allowed
-
-channel AckChannel(ch: C) where ch != null && credit(ch, -1); // ack
-
-channel C(msg: bool, n: Node, ackC: AckChannel) where
- (!msg ==> acc(this.mu, 50) && acc(ackC.mu, 50)) &&
- (msg ==> n != null && acc(n.next) && acc(n.mu) && ackC != null && credit(ackC, -1)); // cell
-
-class Node {
- var next: Node;
-
- function length(): int
- requires this.list;
- {
- unfolding this.list in 1 + (next == null ? 0 : next.length())
- }
-
- predicate list {
- acc(next) && acc(mu) && (next != null ==> next.list)
- }
-}
-
-class Program {
- method Putter(e: C, x0: Node, ackC: AckChannel)
- requires e!= null && acc(e.mu, 50) && e.mu == waitlevel && acc(ackC.mu, 50) && e.mu << ackC.mu && (x0 != null ==> x0.list) && (x0 != null ==> credit(e, - 1));
- {
- var x: Node := x0;
- var t: Node;
-
- while(x != null)
- invariant (x != null ==> x.list) && acc(e.mu, 50) && acc(ackC.mu, 50) && e.mu << ackC.mu && credit(e, - 1);
- {
- unfold x.list;
- t := x.next;
- send e(true, x, ackC);
- x := t;
- var ack;
- assume waitlevel << ackC.mu; // Chalice should be able to figure this out itself?
- var ctmp: C;
- receive ctmp := ackC;
- if(ctmp != e) { assume false; /* abort */ }
- }
- send e(false, null, ackC);
- }
-
- method Getter(f: C, ackC: AckChannel)
- requires f!= null && credit(f, 1) && acc(f.mu, 50) && waitlevel << f.mu && ackC != null && acc(ackC.mu, 50) && f.mu << ackC.mu;
- {
- var x: Node := null;
- var msg: bool := true;
- while(msg)
- invariant acc(f.mu, 50) && waitlevel << f.mu && (msg ==> credit(f, 1)) && (!msg ==> acc(f.mu, 50) && acc(ackC.mu, 50));
- {
- var ackC2: AckChannel;
- receive msg, x, ackC2 := f;
- if(ackC2 != ackC) { assume false; /* abort */ }
- if(msg) {
- free x;
- send ackC(f);
- }
- }
- free f; // close the channel
- }
-
- method Main(x: Node)
- requires x != null;
- requires x.list;
- {
- var e := new C;
- var ackC := new AckChannel above e;
- fork Putter(e, x, ackC);
- fork Getter(e, ackC);
- }
-}
-
-
-
diff --git a/Chalice/tests/examples/CopyLessMessagePassing-with-ack2.output.txt b/Chalice/tests/examples/CopyLessMessagePassing-with-ack2.output.txt
deleted file mode 100644
index 2d6d752d..00000000
--- a/Chalice/tests/examples/CopyLessMessagePassing-with-ack2.output.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Verification of CopyLessMessagePassing-with-ack2.chalice using parameters=""
-
-
- 50.23: Assumption introduces a contradiction.
- 65.27: Assumption introduces a contradiction.
-
-Boogie program verifier finished with 0 errors and 2 smoke test warnings
diff --git a/Chalice/tests/examples/CopyLessMessagePassing.chalice b/Chalice/tests/examples/CopyLessMessagePassing.chalice
deleted file mode 100644
index 3a9b80e0..00000000
--- a/Chalice/tests/examples/CopyLessMessagePassing.chalice
+++ /dev/null
@@ -1,72 +0,0 @@
-// program inspired by "Proving Copyless Message Passing" (Villard, Lozes and Calcagno, APLAS 2009)
-
-// msg tag indicates what the type of the message
-// channel is freed by Getter when it completes
-
-// todo: accept ack message before sending the next one (requires sending negative credit!)
-
-channel C(msg: bool, n: Node) where n!= null && acc(n.next) && acc(n.mu) && (msg ==> credit(this, 1)) && (!msg ==> acc(this.mu, 50));
-
-class Node {
- var next: Node;
-
- function length(): int
- requires this.list;
- {
- unfolding this.list in 1 + (next == null ? 0 : next.length())
- }
-
- predicate list {
- acc(next) && acc(mu) && (next != null ==> next.list)
- }
-}
-
-class Program {
- method Putter(e: C, x0: Node)
- requires e!= null && acc(e.mu, 50) && (x0 != null ==> x0.list) && (x0 != null ==> credit(e, - 1));
- {
- var x: Node := x0;
- var t: Node;
-
- while(x != null)
- invariant (x != null ==> x.list) && (x!=null ==> acc(e.mu, 50)) && (x != null ==> credit(e, - 1));
- {
- unfold x.list;
- t := x.next;
- if(t != null) {
- send e(true, x);
- } else {
- send e(false, x);
- }
- x := t;
- }
- }
-
- method Getter(f: C)
- requires f!= null && credit(f, 1) && acc(f.mu, 50) && waitlevel << f.mu;
- {
- var x: Node := null;
- var msg: bool := true;
- while(msg)
- invariant acc(f.mu, 50) && waitlevel << f.mu && (msg ==> credit(f, 1)) && (!msg ==> acc(f.mu, 50));
- {
- receive msg, x := f;
- if(msg) {
- free x;
- }
- }
- free f; // close the channel
- }
-
- method Main(x: Node)
- requires x != null;
- requires x.list;
- {
- var e := new C;
- fork Putter(e, x);
- fork Getter(e);
- }
-}
-
-
-
diff --git a/Chalice/tests/examples/CopyLessMessagePassing.output.txt b/Chalice/tests/examples/CopyLessMessagePassing.output.txt
deleted file mode 100644
index 2caf540b..00000000
--- a/Chalice/tests/examples/CopyLessMessagePassing.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of CopyLessMessagePassing.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/FictionallyDisjointCells.chalice b/Chalice/tests/examples/FictionallyDisjointCells.chalice
deleted file mode 100644
index d26dedbb..00000000
--- a/Chalice/tests/examples/FictionallyDisjointCells.chalice
+++ /dev/null
@@ -1,75 +0,0 @@
-class Cell
-{
- var inner: InnerCell;
-
- predicate inv
- {
- acc(inner) && inner!=null && rd(inner.value,1) && rd*(inner.mu) && rd*(this.mu)
- }
-
- method CellConstructor()
- requires acc(inner) && acc(this.mu)
- ensures inv && get()==0;
- {
- inner := new InnerCell;
- call inner.InnerCellConstructor(0)
- share inner;
- fold inv;
- }
-
- method CellConstructor2(other: Cell)
- requires acc(inner) && acc(this.mu)
- requires other != null && other.inv;
- requires unfolding other.inv in waitlevel << other.inner.mu
- ensures inv && other.inv && get()==other.get();
- {
- unfold other.inv;
- inner := other.inner;
- acquire inner;
- inner.refCount := inner.refCount+1;
- release inner;
- fold other.inv;
- fold inv;
- }
-
- function get():int
- requires inv;
- { unfolding inv in inner.value }
-
- method set(x:int)
- requires inv;
- requires unfolding inv in waitlevel << inner.mu
- ensures inv && get()==x;
- {
- var old_in: InnerCell;
- unfold inv;
- old_in := inner;
- acquire old_in;
- if (inner.refCount==1) { inner.value:=x; }
- else
- {
- inner.refCount := inner.refCount-1;
- inner := new InnerCell;
- call inner.InnerCellConstructor(x)
- share inner;
- }
- release old_in;
- fold inv;
- }
-}
-
-class InnerCell
-{
- var value: int;
- var refCount: int;
-
- invariant acc(refCount) && refCount > 0 && acc(value,100-rd(refCount));
-
- method InnerCellConstructor(val: int)
- requires acc(refCount) && acc(value)
- ensures acc(refCount) && acc(value) && refCount==1 && value == val;
- {
- refCount := 1;
- value := val
- }
-}
diff --git a/Chalice/tests/examples/FictionallyDisjointCells.output.txt b/Chalice/tests/examples/FictionallyDisjointCells.output.txt
deleted file mode 100644
index 0b8b0c4f..00000000
--- a/Chalice/tests/examples/FictionallyDisjointCells.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of FictionallyDisjointCells.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/ForkJoin.chalice b/Chalice/tests/examples/ForkJoin.chalice
deleted file mode 100644
index e79cded9..00000000
--- a/Chalice/tests/examples/ForkJoin.chalice
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Example taken from ESOP submission */
-
-class T {
- var k: int;
- var l: int;
-
- method run()
- requires acc(k);
- ensures acc(k) && k == old(k) + 1;
- {
- k := k + 1;
- }
-}
-
-class Program {
- method main() {
- var x := new T;
- x.k := 17;
- x.l := 20;
- fork tok := x.run();
- x.l := 10;
- join tok;
- assert x.k == 18 && x.l == 10;
- }
-
- method justJoin(tok: token<T.run>, x: T) returns (rt: int)
- requires x!=null && tok!=null && acc(tok.joinable) && tok.joinable && eval(tok.fork x.run(), acc(x.k));
- ensures rt == old(eval(tok.fork x.run(), x.k)) + 1;
- {
- join tok;
- rt := x.k;
- }
-}
-
-/* example using asynchronous method calls */
-
-class C {
- var x: int;
-
- method m(v: int) returns (rt: int)
- ensures rt == v + 1;
- {
- rt := v + 1;
- }
-}
-
-class Program2 {
- method main1(){
- var c := new C;
- var tok: token<C.m>;
- fork tok := c.m(5);
-
- // do some computation
-
- var x : int;
- join x := tok;
- assert x == 6;
- }
-
- method main2(){
- var c := new C;
- var tok: token<C.m>;
- fork tok := c.m(5);
-
- // do some computation
-
- call foo(tok, c);
- }
-
- method foo(tok: token<C.m>, o: C)
- requires tok!=null && acc(tok.joinable) && tok.joinable && eval(tok.fork o.m(5), true);
- {
- var x: int;
- join x := tok;
- assert x == 6;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/ForkJoin.output.txt b/Chalice/tests/examples/ForkJoin.output.txt
deleted file mode 100644
index 5ddd0f65..00000000
--- a/Chalice/tests/examples/ForkJoin.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of ForkJoin.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/HandOverHand.chalice b/Chalice/tests/examples/HandOverHand.chalice
deleted file mode 100644
index 31818ca6..00000000
--- a/Chalice/tests/examples/HandOverHand.chalice
+++ /dev/null
@@ -1,132 +0,0 @@
-class List {
- ghost var sum: int
- var head: Node
- invariant acc(head) && head != null
- invariant rd(head.val) && head.val == -1
- invariant rd(mu) && acc(head.mu,50) && this << head
- invariant acc(sum,20) && acc(head.sum, 50) && sum == head.sum
-
- method Main()
- {
- var list := new List
- call list.Init()
- call list.Insert(8)
- call list.Insert(12)
- call list.Insert(4)
- assert list.sum == 24
- }
-
- method Init()
- requires acc(mu) && mu == lockbottom && acc(head) && acc(sum)
- ensures rd*(mu) && waitlevel << this
- ensures acc(sum,80) && sum == 0
- {
- var t := new Node
- t.val := -1
- t.next := null
- t.sum := 0
- share t
- head := t
- sum := 0
- share this between waitlevel and t
- }
-
- method Insert(x: int)
- requires rd(mu) && waitlevel << this
- requires acc(sum,80) && 0 <= x
- ensures rd(mu)
- ensures acc(sum,80) && sum == old(sum) + x
- {
- acquire this
- assert waitlevel == this.mu;
- sum := sum + x
- var p: Node := head
- acquire p
- p.sum := p.sum + x
- release this
-
- while (p.next != null && p.next.val < x)
- invariant p != null && acc(p.next) && acc(p.val,rd(p)) && acc(p.mu,50)
- invariant holds(p) && waitlevel == p.mu
- invariant !old(holds(p)) && !old(rd holds(p))
- invariant p.next != null ==> acc(p.next.mu,50) && p << p.next
- invariant p.next != null ==> acc(p.next.val,rd(p.next)) && p.val <= p.next.val
- invariant acc(p.sum, 50)
- invariant p.next == null ==> p.sum == x
- invariant p.next != null ==> acc(p.next.sum, 50) && p.sum == p.next.val + p.next.sum + x
- invariant p.val <= x
- lockchange p
- {
- var nx: Node := p.next
- acquire nx
- nx.sum := nx.sum + x
- release p
- p := nx
- }
- var t := new Node
- t.val := x
- t.next := p.next
- if (t.next == null) { t.sum := 0 } else { t.sum := p.next.val + p.next.sum }
- share t between p and p.next
- p.next := t
- release p
- }
-
- method Delete(x: int) returns (wasPresent: bool)
- requires rd(mu) && waitlevel << this
- requires acc(sum,80) && 0 <= x
- ensures acc(sum,80) && (wasPresent ==> sum == old(sum) - x) && (!wasPresent ==> sum == old(sum))
- {
- ghost const c
-
- acquire this
- sum := sum - c
- var p: Node := head
- acquire p
- p.sum := p.sum - c
- release this
-
- while (p.next != null && p.next.val < x)
- invariant p != null && acc(p.next) && acc(p.val,rd(p)) && acc(p.mu,50)
- invariant holds(p) && waitlevel == p.mu && !assigned(c)
- invariant !old(holds(p)) && !old(rd holds(p))
- invariant p.next != null ==> acc(p.next.mu,50) && p << p.next
- invariant p.next != null ==> acc(p.next.val,rd(p.next)) && p.val <= p.next.val
- invariant acc(p.sum, 50)
- invariant p.next == null ==> p.sum == 0 - c
- invariant p.next != null ==> acc(p.next.sum, 50) && p.sum == p.next.val + p.next.sum - c
- invariant p.val <= x
- lockchange p
- {
- var nx: Node := p.next
- acquire nx
- nx.sum := nx.sum - c
- release p
- p := nx
- }
- if (p.next != null && p.next.val == x) {
- wasPresent := true
- c := x
- var nx: Node := p.next
- acquire nx
- p.next := nx.next
- unshare nx
- } else {
- wasPresent := false
- c := 0
- }
- release p
- }
-}
-
-class Node {
- ghost var sum: int
- var val: int
- var next: Node
- invariant acc(next) && rd(val)
- invariant next != null ==> rd(next.val) && val <= next.val
- invariant acc(sum, 50)
- invariant next == null ==> sum == 0
- invariant next != null ==> acc(next.sum, 50) && sum == next.val + next.sum
- invariant acc(mu,50) && (next != null ==> acc(next.mu,50) && this << next)
-}
diff --git a/Chalice/tests/examples/HandOverHand.output.txt b/Chalice/tests/examples/HandOverHand.output.txt
deleted file mode 100644
index 13ff996a..00000000
--- a/Chalice/tests/examples/HandOverHand.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of HandOverHand.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/OwickiGries.chalice b/Chalice/tests/examples/OwickiGries.chalice
deleted file mode 100644
index f466b58a..00000000
--- a/Chalice/tests/examples/OwickiGries.chalice
+++ /dev/null
@@ -1,35 +0,0 @@
-class OwickiGries {
- var counter: int
- ghost var c0: int
- ghost var c1: int
- invariant acc(counter) && acc(c0,50) && acc(c1,50) && counter == c0 + c1
-
- method Main() {
- var og := new OwickiGries{ counter := 0, c0 := 0, c1 := 0 }
- share og
-
- fork tk0 := og.Worker(false)
- fork tk1 := og.Worker(true)
- join tk0; join tk1
-
- acquire og; unshare og
- assert og.counter == 2
- }
-
- method Worker(b: bool)
- requires rd(mu) && waitlevel << mu
- requires (!b ==> acc(c0,50)) && (b ==> acc(c1,50))
- ensures rd(mu)
- ensures !b ==> acc(c0,50) && c0 == old(c0) + 1
- ensures b ==> acc(c1,50) && c1 == old(c1) + 1
- {
- lock (this) {
- counter := counter + 1
- if (!b) {
- c0 := c0 + 1
- } else {
- c1 := c1 + 1
- }
- }
- }
-}
diff --git a/Chalice/tests/examples/OwickiGries.output.txt b/Chalice/tests/examples/OwickiGries.output.txt
deleted file mode 100644
index 8235b0f4..00000000
--- a/Chalice/tests/examples/OwickiGries.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of OwickiGries.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/PetersonsAlgorithm.chalice b/Chalice/tests/examples/PetersonsAlgorithm.chalice
deleted file mode 100644
index 8760b04b..00000000
--- a/Chalice/tests/examples/PetersonsAlgorithm.chalice
+++ /dev/null
@@ -1,79 +0,0 @@
-class Peterson {
- var x0: bool;
- var x1: bool;
- var turn: bool;
- ghost var cs0: bool;
- ghost var cs1: bool;
- ghost var b0: bool;
- ghost var b1: bool;
-
- invariant acc(x0,50) && acc(x1,50) && acc(turn);
- invariant acc(cs0,50) && acc(cs1,50) && acc(b0,50) && acc(b1,50);
- invariant cs0 ==> x0 && !b0 && (!x1 || !turn || b1);
- invariant cs1 ==> x1 && !b1 && (!x0 || turn || b0);
-
- method Main() {
- var p := new Peterson{ x0 := false, x1 := false,
- cs0 := false, cs1 := false, b0 := false, b1 := false };
- share p;
- fork p.Process0();
- fork p.Process1();
- // The purpose of the following loop is simply to prove mutual exclusion, that is,
- // to prove that !(cs0 && cs1) follows from the monitor invariant.
- while (true)
- invariant rd(p.mu) && waitlevel << p.mu;
- {
- lock (p) { assert !(p.cs0 && p.cs1); }
- }
- }
-
- method Process0()
- requires rd(mu) && waitlevel << mu;
- requires acc(x0,50) && acc(cs0,50) && acc(b0,50) && !x0 && !cs0 && !b0;
- {
- while (true)
- invariant rd(mu) && waitlevel << mu;
- invariant acc(x0,50) && acc(cs0,50) && acc(b0,50) && !x0 && !cs0 && !b0;
- {
- [[ x0 := true; b0 := true; ]]
- [[ turn := true; b0 := false; ]]
- // await (!x1 || !turn)
- var waiting := true;
- while (waiting)
- invariant rd(mu) && waitlevel << mu && acc(cs0,50);
- invariant acc(x0,50) && acc(b0,50) && x0 && !b0;
- invariant !waiting ==> cs0;
- {
- [[ if (!x1) { waiting := false; cs0 := true; } ]]
- [[ if (!turn) { waiting := false; cs0 := true; } ]]
- }
- // critical section...
- [[ cs0 := false; x0 := false; ]]
- }
- }
-
- method Process1()
- requires rd(mu) && waitlevel << mu;
- requires acc(x1,50) && acc(cs1,50) && acc(b1,50) && !x1 && !cs1 && !b1;
- {
- while (true)
- invariant rd(mu) && waitlevel << mu;
- invariant acc(x1,50) && acc(cs1,50) && acc(b1,50) && !x1 && !cs1 && !b1;
- {
- [[ x1 := true; b1 := true; ]]
- [[ turn := false; b1 := false; ]]
- // await (!x0 || turn)
- var waiting := true;
- while (waiting)
- invariant rd(mu) && waitlevel << mu && acc(cs1,50);
- invariant acc(x1,50) && acc(b1,50) && x1 && !b1;
- invariant !waiting ==> cs1;
- {
- [[ if (!x0) { waiting := false; cs1 := true; } ]]
- [[ if (turn) { waiting := false; cs1 := true; } ]]
- }
- // critical section...
- [[ cs1 := false; x1 := false; ]]
- }
- }
-}
diff --git a/Chalice/tests/examples/PetersonsAlgorithm.output.txt b/Chalice/tests/examples/PetersonsAlgorithm.output.txt
deleted file mode 100644
index 1be5bf8c..00000000
--- a/Chalice/tests/examples/PetersonsAlgorithm.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of PetersonsAlgorithm.chalice using parameters=""
-
-
- 23.5: The statements after the while-loop are unreachable.
- 34.5: The statements after the while-loop are unreachable.
- 59.5: The statements after the while-loop are unreachable.
-
-Boogie program verifier finished with 0 errors and 3 smoke test warnings
diff --git a/Chalice/tests/examples/ProdConsChannel.chalice b/Chalice/tests/examples/ProdConsChannel.chalice
deleted file mode 100644
index abac4f5c..00000000
--- a/Chalice/tests/examples/ProdConsChannel.chalice
+++ /dev/null
@@ -1,45 +0,0 @@
-class Cell {
- var val: int
-}
-
-channel Ch(c: Cell) where
- c != null ==> acc(c.val) && 0 <= c.val && credit(this)
-
-class Program {
- method Main() {
- var ch := new Ch
- fork tk0 := Producer(ch)
- fork tk1 := Consumer(ch)
- join tk0
- join tk1
- }
- method Producer(ch: Ch)
- requires ch != null
- ensures credit(ch)
- {
- var i := 0
- while (i < 25)
- {
- var x := i*i
- var c := new Cell { val := x }
- send ch(c)
- i := i + 1
- }
- send ch(null)
- }
- method Consumer(ch: Ch)
- requires rd(ch.mu) && waitlevel << ch.mu
- requires credit(ch)
- ensures rd(ch.mu)
- {
- var c: Cell
- receive c := ch
- while (c != null)
- invariant rd(ch.mu) && waitlevel << ch.mu
- invariant c != null ==> acc(c.val) && 0 <= c.val && credit(ch)
- {
- var i := c.val
- receive c := ch
- }
- }
-}
diff --git a/Chalice/tests/examples/ProdConsChannel.output.txt b/Chalice/tests/examples/ProdConsChannel.output.txt
deleted file mode 100644
index 20a587da..00000000
--- a/Chalice/tests/examples/ProdConsChannel.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of ProdConsChannel.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/RockBand.chalice b/Chalice/tests/examples/RockBand.chalice
deleted file mode 100644
index 379b4113..00000000
--- a/Chalice/tests/examples/RockBand.chalice
+++ /dev/null
@@ -1,112 +0,0 @@
-// chalice-parameter=-checkLeaks -defaults -autoFold
-// verify this program with -checkLeaks -defaults -autoFold
-
-class Client {
- method Main() {
- var b := new RockBand
- call b.Init()
- call b.Play()
- call b.Play()
- call b.Dispose()
- }
-}
-
-class RockBand module M {
- var gigs: int
- var gt: Guitar
- var doowops: seq<Vocalist>
- var b3: Organ
- predicate Valid {
- acc(gigs) && 0 <= gigs &&
- acc(gt) && gt != null && gt.Valid &&
- acc(gt.mu) && // to enable an eventual free
- acc(doowops) && //forall d: Vocalist in doowops :: d != null && d.Valid} &&
- acc(b3) && b3 != null && b3.Valid &&
- acc(b3.mu) // to enable an eventual free
- }
-
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- gigs := 0
- gt := new Guitar
- call gt.Init()
- b3 := new Organ
- call b3.Init()
- }
-
- method Dispose()
- requires Valid && acc(mu)
- {
- call gt.Dispose()
- call b3.Dispose()
- free this
- }
-
- method Play()
- requires Valid
- ensures Valid
- {
- gigs := gigs + 1
- call gt.Strum()
- call b3.Grind()
- }
-}
-
-class Guitar module Musicians {
- predicate Valid { true }
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- }
- method Dispose()
- requires Valid && acc(mu)
- {
- free this
- }
- method Strum()
- requires Valid
- ensures Valid
- {
- }
-}
-
-class Vocalist module Musicians {
- predicate Valid { true }
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- }
- method Dispose()
- requires Valid && acc(mu)
- {
- free this
- }
- method Strum()
- requires Valid
- ensures Valid
- {
- }
-}
-
-class Organ module Musicians {
- predicate Valid { true }
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- }
- method Dispose()
- requires Valid && acc(mu)
- {
- free this
- }
- method Grind()
- requires Valid
- ensures Valid
- {
- }
-}
diff --git a/Chalice/tests/examples/RockBand.output.txt b/Chalice/tests/examples/RockBand.output.txt
deleted file mode 100644
index f505fdb3..00000000
--- a/Chalice/tests/examples/RockBand.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of RockBand.chalice using parameters="-checkLeaks -defaults -autoFold"
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/Sieve.chalice b/Chalice/tests/examples/Sieve.chalice
deleted file mode 100644
index d7223d04..00000000
--- a/Chalice/tests/examples/Sieve.chalice
+++ /dev/null
@@ -1,63 +0,0 @@
-channel NumberStream(x: int) where 2 <= x ==> credit(this);
-
-class Sieve {
- method Counter(n: NumberStream, to: int) // sends the plurals along n
- requires rd(n.mu) && credit(n,-1) && 0 <= to;
- {
- var i := 2;
- while (i < to)
- invariant rd(n.mu);
- invariant 2 <= i;
- invariant credit(n, -1)
- {
- send n(i);
- i := i + 1;
- }
- send n(-1);
- }
-
- method Filter(prime: int, r: NumberStream, s: NumberStream)
- requires 2 <= prime;
- requires rd(r.mu) && waitlevel << r.mu;
- requires rd(s.mu) && s.mu << r.mu && credit(r) && credit(s, -1);
- {
- receive x := r;
- while (2 <= x)
- invariant rd(r.mu) && rd(s.mu) && s << r && waitlevel << r.mu;
- invariant 2<= x ==> credit(r);
- invariant credit(s, -1);
- {
- if (x % prime != 0) { // suppress multiples of prime
- send s(x);
- }
- receive x := r;
-
- }
- send s(-1);
- }
-
- method Start()
- {
- var ch := new NumberStream;
- fork Counter(ch, 101);
- var p: int;
- receive p := ch;
- while (2 <= p)
- invariant ch != null;
- invariant 2 <= p ==> credit(ch, 1);
- invariant rd*(ch.mu) && waitlevel << ch.mu;
- {
- // print p--it's a prime!
- var cp := new ChalicePrint; call cp.Int(p);
-
- var n := new NumberStream between waitlevel and ch;
- fork Filter(p, ch, n);
- ch := n;
- receive p := ch;
- }
- }
-}
-
-external class ChalicePrint {
- method Int(x: int) { }
-}
diff --git a/Chalice/tests/examples/Sieve.output.txt b/Chalice/tests/examples/Sieve.output.txt
deleted file mode 100644
index 0e37cd00..00000000
--- a/Chalice/tests/examples/Sieve.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of Sieve.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/Solver.chalice b/Chalice/tests/examples/Solver.chalice
deleted file mode 100644
index 0de8a987..00000000
--- a/Chalice/tests/examples/Solver.chalice
+++ /dev/null
@@ -1,44 +0,0 @@
-class Client {
-
- method main(p: Problem, s: Solver) returns (r: int)
- requires acc(p.f) && s != null
- ensures acc(p.f)
- {
- // start randomized computations
- var tk1: token<Solver.solve>
- var tk2: token<Solver.solve>
- call tk1 := s.start(p)
- call tk2 := s.start(p)
-
- // get the results
- var r1: int
- join r1 := tk1
- var r2: int
- join r2:= tk2
- r := r1 > r2 ? r1 : r2
- }
-
-}
-class Solver {
-
- method solve(p: Problem, d: Data) returns (r: int)
- requires rd(p.f)
- requires acc(d.*)
- ensures rd(p.f)
- { /* ... */ }
-
- method start(p: Problem)
- returns (tk: token<Solver.solve>)
- requires rd(p.f)
- ensures acc(p.f, rd-rd(tk))
- ensures acc(tk.joinable) && tk.joinable;
- ensures eval(tk.fork this.solve(p,_), true)
- {
- var d: Data := new Data
- /* .. perform some set-up/initialization and prepare the data d for the solve method */
- fork tk := solve(p, d)
- }
-
-}
-class Problem { var f: int }
-class Data { var f: int; var g: int }
diff --git a/Chalice/tests/examples/Solver.output.txt b/Chalice/tests/examples/Solver.output.txt
deleted file mode 100644
index 7b6882c5..00000000
--- a/Chalice/tests/examples/Solver.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of Solver.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/TreeOfWorker.chalice b/Chalice/tests/examples/TreeOfWorker.chalice
deleted file mode 100644
index 6483f884..00000000
--- a/Chalice/tests/examples/TreeOfWorker.chalice
+++ /dev/null
@@ -1,29 +0,0 @@
-class Node {
- var l: Node
- var r: Node
-
- method work(data: Data)
- requires rd(data.f)
- requires valid
- ensures rd(data.f)
- ensures valid
- {
- var tkl: token<Node.work>
- var tkr: token<Node.work>
-
- unfold valid
- if (l != null) { fork tkl := l.work(data) }
- if (r != null) { fork tkr := r.work(data) }
- /* .. perform work on this node (using the global data: data.f) */
- if (l != null) { join tkl }
- if (r != null) { join tkr }
- fold valid
- }
-
- predicate valid {
- acc(l) && acc(r) &&
- (l != null ==> l.valid) &&
- (r != null ==> r.valid)
- }
-}
-class Data { var f: int; }
diff --git a/Chalice/tests/examples/TreeOfWorker.output.txt b/Chalice/tests/examples/TreeOfWorker.output.txt
deleted file mode 100644
index fe0c3376..00000000
--- a/Chalice/tests/examples/TreeOfWorker.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of TreeOfWorker.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/UnboundedThreads.chalice b/Chalice/tests/examples/UnboundedThreads.chalice
deleted file mode 100644
index c52bb10a..00000000
--- a/Chalice/tests/examples/UnboundedThreads.chalice
+++ /dev/null
@@ -1,59 +0,0 @@
-class C {
-
- var f: int;
-
- method main(n: int)
- requires n > 0 && acc(this.f)
- ensures acc(this.f)
- {
- // fork all threads, and join them afterwards
- call work(n);
-
- this.f := 100; // we want a full permission in the end
- }
-
- method work(n: int)
- requires rd(this.f,n)
- ensures rd(this.f,n)
- {
- var tks:seq<token<C.m>> := nil<token<C.m>>;
-
- // first loop; fork all threads
- var i := 0;
- while (i < n)
- invariant i <= n && |tks| == i;
- invariant i < n ==> rd(this.f,n-i);
- invariant acc(tks[*].joinable);
- invariant forall k in [0..|tks|] :: tks[k] != null && tks[k].joinable;
- invariant forall k in [0..|tks|] :: eval(tks[k].fork this.m(), true);
- invariant forall k,j in [0..|tks|] :: k < j ==> tks[k] != tks[j];
- {
- fork tk := m();
- tks := tks ++ [tk];
- i := i+1;
- }
-
- // second loop; join all threads
- i := n;
- while (i > 0)
- invariant i >= 0 && |tks| == i;
- invariant i < n ==> rd(this.f,n-i); // BUG: the eval construct inside the quantification does not give us the information needed to proof this invariant, see http://boogie.codeplex.com/workitem/10187
- invariant acc(tks[*].joinable);
- invariant forall k in [0..|tks|] :: tks[k] != null && tks[k].joinable;
- invariant forall k in [0..|tks|] :: eval(tks[k].fork this.m(), true);
- invariant forall k,j in [0..|tks|] :: k < j ==> tks[k] != tks[j];
- {
- var tk: token<C.m>;
- tk := tks[i-1];
- join tk;
- i := i-1;
- tks := tks[0..i];
- }
- }
-
- method m()
- requires rd(this.f,1);
- ensures rd(this.f,1);
- { /* do some computation */ }
-
-}
diff --git a/Chalice/tests/examples/UnboundedThreads.output.txt b/Chalice/tests/examples/UnboundedThreads.output.txt
deleted file mode 100644
index f8a05ed9..00000000
--- a/Chalice/tests/examples/UnboundedThreads.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of UnboundedThreads.chalice using parameters=""
-
- 40.17: The loop invariant at 40.17 might not be preserved by the loop. Insufficient epsilons at 40.27 for C.f.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/cell.chalice b/Chalice/tests/examples/cell.chalice
deleted file mode 100644
index 1cf82950..00000000
--- a/Chalice/tests/examples/cell.chalice
+++ /dev/null
@@ -1,163 +0,0 @@
-class Cell module Library {
- var x: int;
-
- method init(v: int)
- requires acc(this.x) && 0<=v;
- ensures valid && this.get() == v;
- {
- x := v;
- fold valid;
- }
-
- method set(v: int)
- requires valid && 0<=v;
- ensures valid && get()==v;
- {
- unfold valid;
- x := v;
- fold valid;
- }
-
- method increment()
- requires valid;
- ensures valid && get() == old(get()) + 1;
- {
- unfold valid;
- x := x + 1;
- fold valid;
- }
-
- method dispose()
- requires valid && acc(mu);
- ensures true;
- {
- unfold valid;
- free this;
- }
-
- function get(): int
- requires valid;
- ensures 0<=result;
- {
- unfolding valid in x
- }
-
- predicate valid {
- acc(this.x) && 0<=x
- }
-
- invariant valid;
-}
-
-class Interval module Library2 {
- var left: Cell;
- var right: Cell;
-
- method init(l: int, r: int)
- requires 0<=l && l <= r;
- requires acc(left) && acc(right);
- ensures valid;
- ensures getLeft()==l;
- ensures getRight()==r;
- {
- left := new Cell;
- call left.init(l);
- right := new Cell;
- call right.init(r);
- fold valid;
- }
-
- method setLeft(l: int)
- requires valid;
- requires 0<=l && l<=getRight();
- ensures valid;
- ensures getLeft()==l && getRight()==old(getRight());
- {
- unfold valid;
- call left.set(l);
- fold valid;
- }
-
- method setRight(r: int)
- requires valid;
- requires 0<=r && getLeft()<=r;
- ensures valid;
- ensures getLeft()==old(getLeft()) && getRight()==r;
- {
- unfold valid;
- call right.set(r);
- fold valid;
- }
-
- method shift(v: int)
- requires valid;
- requires 0<=v;
- ensures valid;
- ensures getLeft()==old(getLeft())+v && getRight()==old(getRight())+v;
- {
- unfold valid;
- call left.set(left.get()+v);
- call right.set(right.get()+v);
- fold valid;
- }
-
- function getLeft() : int
- requires valid;
- {
- unfolding valid in left.get()
- }
-
- function getRight() : int
- requires valid;
- {
- unfolding valid in right.get()
- }
-
- predicate valid
- {
- acc(left) && acc(right) && left!=null && right!=null && left.valid && right.valid && left.get() <= right.get()
- }
-}
-
-class Program module Main {
- method main(){
- var c1 := new Cell;
- call c1.init(5);
- call c1.set(6);
-
- var c2 := new Cell;
- call c2.init(10);
- call c2.set(11);
-
- assert c1.get() == 6;
- }
-
- method main2(){
- var c: Cell;
-
- c := new Cell;
- call c.init(0);
- call c.dispose();
-
- assert c.valid; // should fail
- }
-
- method main3() returns (rt: Cell)
- ensures rt!=null && rt.valid && rt.get() == 0;
- {
- rt := new Cell;
- call rt.init(0);
- }
-
- method main4() {
- var c: Cell;
-
- c := new Cell;
- call c.init(0);
- share c;
-
- acquire c;
- call c.set(1);
- release c;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/cell.output.txt b/Chalice/tests/examples/cell.output.txt
deleted file mode 100644
index b1567d01..00000000
--- a/Chalice/tests/examples/cell.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of cell.chalice using parameters=""
-
- 142.5: Assertion might not hold. Insufficient fraction at 142.12 for Cell.valid.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 135.3: The end of method main2 is unreachable.
-
-Boogie program verifier finished with 1 errors and 1 smoke test warnings
diff --git a/Chalice/tests/examples/dining-philosophers.chalice b/Chalice/tests/examples/dining-philosophers.chalice
deleted file mode 100644
index f4a7d1a6..00000000
--- a/Chalice/tests/examples/dining-philosophers.chalice
+++ /dev/null
@@ -1,93 +0,0 @@
-class Philosopher module Philosophers {
- var left: Fork;
- var right: Fork;
-
- method init(f1: Fork, f2: Fork)
- requires f1!=null && f2!=null;
- requires acc(this.*);
- ensures valid;
- ensures getLeft()==f1 && getRight()==f2;
- {
- left := f1;
- right := f2;
- fold valid;
- }
-
- method run()
- requires valid;
- requires acc(getLeft().mu, 10);
- requires acc(getRight().mu, 10);
- requires waitlevel << getLeft().mu;
- requires waitlevel << getRight().mu;
- requires getLeft().mu << getRight().mu;
- {
- while(true)
- invariant valid && acc(getLeft().mu, 10) && acc(getRight().mu, 10) && waitlevel << getLeft().mu && waitlevel << getRight().mu && getLeft().mu << getRight().mu;
- {
- unfold valid;
- acquire left;
- acquire right;
- //eat
- release left;
- release right;
- fold valid;
- }
- }
-
- function getLeft(): Fork
- requires valid;
- ensures result!=null;
- {
- unfolding valid in left
- }
-
- function getRight(): Fork
- requires valid;
- ensures result!=null;
- {
- unfolding valid in right
- }
-
- predicate valid {
- acc(left) && acc(right) && left!=null && right!=null
- }
-}
-
-class Fork module Dining {
- invariant true;
-}
-
-class Program module Main {
- method main(){
- // create forks
- var f1 := new Fork;
- var f2 := new Fork;
- var f3 := new Fork;
-
- share f1;
- share f2 above f1;
- share f3 above f1, f2;
-
- // create philosophers
- var aristotle := new Philosopher;
- call aristotle.init(f1, f2);
-
- var plato := new Philosopher;
- call plato.init(f2, f3);
-
- var kant := new Philosopher;
- call kant.init(f1, f3);
-
- assert f2.mu << f3.mu;
-
- // start eating
- fork tk0 := aristotle.run();
- fork tk1 := plato.run();
- fork tk2 := kant.run();
-
- // everyone's done
- join tk0;
- join tk1;
- join tk2;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/dining-philosophers.output.txt b/Chalice/tests/examples/dining-philosophers.output.txt
deleted file mode 100644
index ffba722f..00000000
--- a/Chalice/tests/examples/dining-philosophers.output.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Verification of dining-philosophers.chalice using parameters=""
-
-
- 24.5: The statements after the while-loop are unreachable.
-
-Boogie program verifier finished with 0 errors and 1 smoke test warnings
diff --git a/Chalice/tests/examples/generate_reference.bat b/Chalice/tests/examples/generate_reference.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/examples/generate_reference.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/examples/generate_reference_all.bat b/Chalice/tests/examples/generate_reference_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/examples/generate_reference_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/examples/iterator.chalice b/Chalice/tests/examples/iterator.chalice
deleted file mode 100644
index fd5d0352..00000000
--- a/Chalice/tests/examples/iterator.chalice
+++ /dev/null
@@ -1,150 +0,0 @@
-class List module Collections {
- var contents: seq<int>;
-
- method init()
- requires acc(contents);
- ensures valid && size(100)==0;
- {
- contents := nil<int>;
- fold valid;
- }
-
- method add(x: int)
- requires valid;
- ensures valid && size(100) == old(size(100)+1) && get(size(100)-1, 100) == x;
- ensures forall i in [0..size(100)-1] :: get(i, 100) == old(get(i, 100));
- {
- unfold valid;
- contents := contents ++ [x];
- fold valid;
- }
-
- function get(index: int, f: int): int
- requires 0<f && f<=100 && acc(valid, f) && (0<=index && index<size(f));
- ensures forall i in [1..f] :: get(index, f) == get(index, i);
- {
- unfolding acc(valid, f) in contents[index]
- }
-
- function size(f: int): int
- requires 0<f && f<=100 && acc(valid, f);
- ensures 0<=result;
- ensures forall i in [1..f] :: size(f) == size(i);
- {
- unfolding acc(valid, f) in |contents|
- }
-
- predicate valid {
- acc(contents)
- }
-}
-
-class Iterator module Collections {
- var list: List;
- var index: int;
- var frac: int;
-
- method init(l: List, f: int)
- requires 0<f && f<=100;
- requires acc(list) && acc(index) && acc(frac);
- requires l!=null;
- requires acc(l.valid, f);
- ensures valid;
- ensures getList()==l;
- ensures getFraction()==f;
- {
- list := l;
- this.index := 0;
- frac := f;
- fold valid;
- }
-
- method next() returns (rt: int)
- requires valid && hasNext();
- ensures valid;
- ensures getList()==old(getList());
- ensures getFraction()==old(getFraction());
- {
- unfold valid;
- rt := list.get(index, frac);
- index := index + 1;
- fold valid;
- }
-
- method dispose()
- requires valid;
- ensures acc(old(getList()).valid, old(getFraction()));
- {
- unfold valid;
- }
-
- function hasNext(): bool
- requires valid;
- {
- unfolding valid in index<list.size(frac)
- }
-
- function getFraction(): int
- requires valid;
- ensures 0<result && result<=100;
- {
- unfolding valid in frac
- }
-
- function getList(): List
- requires valid;
- ensures getList()!=null;
- {
- unfolding valid in list
- }
-
- predicate valid
- {
- acc(list) && acc(index) && acc(frac) && 0<frac && frac<=100 && list!=null && acc(list.valid, frac) && 0<=index && index<=list.size(frac)
- }
-}
-
-class Program module Main {
- method main(){
- var tmp: int;
- //create a new list
- var list := new List;
- call list.init();
- call list.add(5);
- call list.add(6);
-
- // create a new iterator
- var iter1 := new Iterator;
- assert list!=null; // needed here: triggering problem?
- assert list.size(100)==2;
- assert list.size(50)==2;
- call iter1.init(list, 10);
-
- // create a second iterator
- var iter2 := new Iterator;
- assert list!=null; // needed here: triggering problem?
- call iter2.init(list, 10);
-
- // iterate over the list
- while(iter1.hasNext())
- invariant iter1.valid && iter1.getList()==list && iter1.getFraction()==10;
- {
- call tmp := iter1.next();
- }
-
- // iterate over the list
- while(iter2.hasNext())
- invariant iter2.valid && iter2.getList()==list && iter2.getFraction()==10;
- {
- call tmp := iter2.next();
- }
-
- // dispose the iterators
- call iter1.dispose();
- call iter2.dispose();
-
- // full access to the list
- assert list.valid;
- assert list.size(50)==2;
- }
-}
diff --git a/Chalice/tests/examples/iterator.output.txt b/Chalice/tests/examples/iterator.output.txt
deleted file mode 100644
index 36a72bac..00000000
--- a/Chalice/tests/examples/iterator.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of iterator.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/iterator2.chalice b/Chalice/tests/examples/iterator2.chalice
deleted file mode 100644
index 4020ece3..00000000
--- a/Chalice/tests/examples/iterator2.chalice
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Iterator pattern in Chalice. */
-
-class List module Collections {
- var contents: seq<int>;
-
- method init()
- requires acc(contents);
- ensures valid && size()==0;
- {
- contents := nil<int>;
- fold valid;
- }
-
- method add(x: int)
- requires valid;
- ensures valid && size() == old(size()+1) && get(size()-1) == x; // I don't know why this happens.
- ensures forall i in [0..size()-1] :: get(i) == old(get(i));
- {
- unfold valid;
- contents := contents ++ [x];
- fold valid;
- }
-
- function get(index: int): int
- requires rd(valid) && 0<=index && index<size();
- {
- unfolding rd(valid) in contents[index]
- }
-
- function size(): int
- requires rd(valid);
- ensures 0<=result;
- {
- unfolding rd(valid) in |contents|
- }
-
- predicate valid {
- acc(contents)
- }
-}
-
-class Iterator module Collections {
- var list: List;
- var index: int;
-
- method init(l: List)
- requires acc(list) && acc(index);
- requires l!=null;
- requires acc(l.valid,rd(l.valid));
- ensures valid;
- ensures getList()==l;
- {
- list := l;
- this.index := 0;
- fold valid;
- }
-
- method next() returns (rt: int)
- requires valid && hasNext();
- ensures valid;
- ensures getList()==old(getList());
- {
- unfold valid;
- rt := list.get(index);
- index := index + 1;
- fold valid;
- }
-
- method dispose()
- requires valid;
- ensures acc(old(getList()).valid,rd(old(getList()).valid));
- {
- unfold valid;
- }
-
- function hasNext(): bool
- requires valid;
- {
- unfolding valid in index<list.size()
- }
-
- function getList(): List
- requires valid;
- ensures result!=null;
- {
- unfolding valid in list
- }
-
- predicate valid
- {
- acc(list) && acc(index) && list!=null && rd(list.valid) && 0<=index && index<=list.size()
- }
-}
-
-class Program module Main {
- method main(){
- var tmp: int;
- //create a new list
- var list := new List;
- call list.init();
- call list.add(5);
- call list.add(6);
-
- // create a new iterator
- var iter1 := new Iterator;
- call iter1.init(list);
-
- // create a second iterator
- var iter2 := new Iterator;
- call iter2.init(list);
-
- // iterate over the list
- while(iter1.hasNext())
- invariant iter1.valid && iter1.getList()==list;
- {
- call tmp := iter1.next();
- }
-
- // iterate over the list
- while(iter2.hasNext())
- invariant iter2.valid && iter2.getList()==list;
- {
- call tmp := iter2.next();
- }
-
- // dispose the iterators
- call iter1.dispose();
- call iter2.dispose();
-
- // full access to the list
- assert list.valid;
- assert list.size()==2;
- }
-}
diff --git a/Chalice/tests/examples/iterator2.output.txt b/Chalice/tests/examples/iterator2.output.txt
deleted file mode 100644
index a28c5785..00000000
--- a/Chalice/tests/examples/iterator2.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of iterator2.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/linkedlist.chalice b/Chalice/tests/examples/linkedlist.chalice
deleted file mode 100644
index a9859aaa..00000000
--- a/Chalice/tests/examples/linkedlist.chalice
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Recursive implementation and specification of a linked list. */
-
-class Node {
- var next: Node;
- var value: int;
-
- method init(v: int)
- requires acc(next) && acc(value);
- ensures valid && size() == 1 && (forall y:int :: contains(y) <==> y==v);
- {
- next := null;
- value := v;
- fold this.valid;
- }
-
- method add(x: int)
- requires valid;
- ensures valid;
- ensures size() == old(size())+1;
- ensures (forall y:int :: contains(y)==(old(contains(y)) || x==y));
- {
- unfold this.valid;
- if(next==null) {
- var n : Node;
- n := new Node;
- call n.init(x);
- next := n;
- // unfold next.valid; fold next.valid; // makes it work
- } else {
-
- call next.add(x);
- }
- fold this.valid;
- }
-
- method addother(i:int)
- requires valid
- ensures valid && (forall x:int :: contains(x)==(old(contains(x)) || x==i))
- {
- unfold valid
- if(next!=null)
- {
- call next.addother(i)
- }
- else
- {
- next:=new Node
- next.value:=i
- next.next:=null
- fold next.valid
- }
- fold valid
- }
-
- method addFirst(x: int) returns (rt: Node)
- requires valid;
- ensures rt!=null && rt.valid;
- ensures rt.size() == old(size()) + 1;
- {
- var n: Node;
- n := new Node;
- n.value := x;
- n.next := this;
- fold n.valid;
- rt := n;
- }
-
- function at(i: int): int
- requires valid && 0<=i && i<size();
- {
- unfolding valid in i==0 ? value : next.at(i-1)
- }
-
- function size(): int
- requires valid;
- ensures result > 0
- {
- unfolding this.valid in (next!=null ? 1+ next.size() : 1)
- }
-
- function contains(i:int):bool
- requires valid
- {
- unfolding valid in i==value || (next!=null && next.contains(i))
- }
-
-
- predicate valid {
- acc(next) && acc(value) && (next!=null ==> next.valid)
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/linkedlist.output.txt b/Chalice/tests/examples/linkedlist.output.txt
deleted file mode 100644
index ffb5327d..00000000
--- a/Chalice/tests/examples/linkedlist.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of linkedlist.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/list-reverse.chalice b/Chalice/tests/examples/list-reverse.chalice
deleted file mode 100644
index c694b4c9..00000000
--- a/Chalice/tests/examples/list-reverse.chalice
+++ /dev/null
@@ -1,44 +0,0 @@
-class Node {
- var next : Node;
- var val : int;
-
- predicate list {
- acc(next) && acc(val) && (next!=null ==> next.list)
- }
-
- function vals() : seq<int>
- requires list
- {
- unfolding list in (next == null ? [val] : [val] ++ next.vals())
- }
-
- function reverse_vals() : seq<int>
- requires list
- {
- unfolding list in (next == null ? [val] : next.reverse_vals() ++ [val])
- }
-
- method reverse_in_place() returns (r:Node)
- requires list;
- ensures r != null && r.list;
- ensures r.vals() == old(this.reverse_vals());
- {
- var l : Node := this;
- r := null;
-
- while (l != null)
- invariant l!=null ==> l.list;
- invariant r!=null ==> r.list;
- invariant old(this.reverse_vals()) == (l==null ? nil<int> : l.reverse_vals()) ++ (r==null ? nil<int> : r.vals());
- {
- var y: Node;
- unfold l.list;
-
- y := l.next;
- l.next := r;
- r := l;
- fold r.list;
- l := y;
- }
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/list-reverse.output.txt b/Chalice/tests/examples/list-reverse.output.txt
deleted file mode 100644
index 6179841d..00000000
--- a/Chalice/tests/examples/list-reverse.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of list-reverse.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/lseg.chalice b/Chalice/tests/examples/lseg.chalice
deleted file mode 100644
index c7b6421a..00000000
--- a/Chalice/tests/examples/lseg.chalice
+++ /dev/null
@@ -1,86 +0,0 @@
-class Node {
- var next : Node;
- var val : int;
- /* ghost */ var length : int;
-
- predicate lseg {
- acc(length) && length > 0 && acc(next) && acc(val) && (length > 1 ==> next != null && next.lseg && next.lseg_length() + 1 == this.length)
- }
-
- function lseg_length() : int
- requires lseg
- {
- unfolding lseg in length
- }
-
- function elems() : seq<int>
- requires lseg
- {
- unfolding lseg in (length == 1 ? [val] : [val] ++ next.elems())
- }
-
- function end() : Node
- requires lseg
- {
- unfolding lseg in (length == 1 ? next : next.end())
- }
-
- /* ghost */ method addAtEndRec(n:Node)
- requires lseg && acc(n.*)
- ensures lseg
- ensures elems() == old(elems()) ++ [old(n.val)]
- ensures end() == old(n.next)
- ensures lseg_length() == old(lseg_length()) + 1
- {
- unfold this.lseg;
- if (length == 1) {
- this.next := n
- n.length := 1
- fold n.lseg
- } else {
- call this.next.addAtEndRec(n)
- }
- this.length := this.length + 1
- fold this.lseg
- }
-
- method addAtEnd(v: int)
- requires lseg
- requires this.end() == null
- ensures lseg
- ensures elems() == old(elems()) ++ [v]
- {
- var cur: Node := this
- unfold lseg
- while (cur.next != null)
- invariant acc(cur.*)
- invariant this != cur ==> this.lseg && this.end() == cur
- invariant cur.length > 0 && (cur.length > 1 ==> cur.next != null && cur.next.lseg) && (cur.length == 1 ? cur.next : cur.next.end()) == null
- invariant ((this == cur ? [] : this.elems())
- ++ [cur.val]
- ++ (cur.next == null ? [] : cur.next.elems())) == old(this.elems())
- {
- /* ghost */ var temp: Node := cur
- cur := cur.next
- if (this == temp) {
- this.length := 1
- fold lseg
- } else {
- call addAtEndRec(temp)
- }
- unfold cur.lseg
- }
-
- var n: Node := new Node
- n.val := v
- n.next := null
- cur.next := n
- if(cur == this) {
- this.length := 1
- fold lseg
- } else {
- call addAtEndRec(cur)
- }
- call addAtEndRec(n)
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/examples/lseg.output.txt b/Chalice/tests/examples/lseg.output.txt
deleted file mode 100644
index ed31a673..00000000
--- a/Chalice/tests/examples/lseg.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of lseg.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/producer-consumer.chalice b/Chalice/tests/examples/producer-consumer.chalice
deleted file mode 100644
index 25253bfb..00000000
--- a/Chalice/tests/examples/producer-consumer.chalice
+++ /dev/null
@@ -1,202 +0,0 @@
-class Program {
- method main(){
- var buffer := new Queue;
- call buffer.init();
- share buffer;
-
- var producer := new Producer;
- call producer.init(buffer);
- fork tkP := producer.run();
-
- var consumer := new Consumer;
- call consumer.init(buffer);
- fork tkC := consumer.run();
-
- join tkP;
- join tkC;
-
- acquire buffer;
- unshare buffer;
-
- var tmp := buffer.size();
- }
-}
-
-class Producer module Producer {
- var buffer: Queue;
-
- method init(buff: Queue)
- requires acc(buffer) && buff!=null;
- ensures valid && getBuffer()==buff;
- {
- buffer := buff;
- fold valid;
- }
-
- method run()
- requires valid && rd(getBuffer().mu) && waitlevel << getBuffer().mu;
- ensures rd(old(getBuffer()).mu);
- {
- var tmp: int;
-
- while(true)
- invariant valid && rd(getBuffer().mu) && waitlevel << getBuffer().mu;
- {
- unfold valid;
- acquire buffer;
- call buffer.enqueue(5);
- release buffer;
- fold valid;
- }
- unfold valid;
- }
-
- function getBuffer(): Queue
- requires valid;
- ensures result!=null;
- {
- unfolding valid in buffer
- }
-
- predicate valid {
- acc(buffer) && buffer!=null
- }
-}
-
-class Consumer module Consumer {
- var buffer: Queue;
-
- method init(buff: Queue)
- requires acc(buffer) && buff!=null;
- ensures valid && getBuffer()==buff;
- {
- buffer := buff;
- fold valid;
- }
-
- method run()
- requires valid && rd(getBuffer().mu) && waitlevel << getBuffer().mu;
- ensures rd(old(getBuffer()).mu);
- {
- while(true)
- invariant valid && rd(getBuffer().mu) && waitlevel << getBuffer().mu;
- {
- unfold valid;
- acquire buffer;
- if(0<=buffer.size()){
- call buffer.enqueue(5);
- }
- release buffer;
- fold valid;
- }
- unfold valid;
- }
-
- function getBuffer(): Queue
- requires valid;
- ensures result!=null;
- {
- unfolding valid in buffer
- }
-
- predicate valid {
- acc(buffer) && buffer!=null
- }
-}
-
-class Queue module Queue {
- var contents: List;
-
- invariant valid;
-
- method init()
- requires acc(contents);
- ensures valid;
- ensures size()==0;
- {
- contents := new List;
- call contents.init();
- fold valid;
- }
-
- method enqueue(x: int)
- requires valid;
- ensures valid;
- ensures size() == old(size())+1;
- {
- unfold valid;
- call contents.add(x);
- fold valid;
- }
-
- method dequeue() returns (rt: int)
- requires valid && 0<size();
- ensures valid;
- ensures size() == old(size())-1;
- {
- unfold valid;
- call rt := contents.removeFirst();
- fold valid;
- }
-
- function size(): int
- requires valid;
- {
- unfolding valid in contents.size()
- }
-
- predicate valid {
- acc(contents) && contents!=null && contents.valid
- }
-}
-
-class List module Collections {
- var contents: seq<int>;
-
- method init()
- requires acc(contents);
- ensures valid && size()==0;
- {
- contents := nil<int>;
- fold valid;
- }
-
- method add(x: int)
- requires valid;
- ensures valid && size() == old(size()+1) && get(size()-1) == x;
- ensures forall i in [0..size()-1] :: get(i) == old(get(i));
- {
- unfold valid;
- contents := contents ++ [x];
- fold valid;
- }
-
- method removeFirst() returns (rt: int)
- requires valid && 0<size();
- ensures valid && size() == old(size()-1);
- ensures forall i in [0..size()] :: get(i) == old(get(i+1));
- {
- unfold valid;
- rt := contents[0];
- contents := contents[1..];
- fold valid;
- }
-
-
- function get(index: int): int
- requires rd(valid) && 0<=index && index<size();
- {
- unfolding rd(valid) in contents[index]
- }
-
- function size(): int
- requires rd(valid);
- ensures 0<=result;
- {
- unfolding rd(valid) in |contents|
- }
-
- predicate valid {
- acc(contents)
- }
-}
diff --git a/Chalice/tests/examples/producer-consumer.output.txt b/Chalice/tests/examples/producer-consumer.output.txt
deleted file mode 100644
index f3c3a28a..00000000
--- a/Chalice/tests/examples/producer-consumer.output.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Verification of producer-consumer.chalice using parameters=""
-
-
- 42.5: The statements after the while-loop are unreachable.
- 81.5: The statements after the while-loop are unreachable.
-
-Boogie program verifier finished with 0 errors and 2 smoke test warnings
diff --git a/Chalice/tests/examples/reg_test.bat b/Chalice/tests/examples/reg_test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/examples/reg_test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/examples/reg_test_all.bat b/Chalice/tests/examples/reg_test_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/examples/reg_test_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/examples/swap.chalice b/Chalice/tests/examples/swap.chalice
deleted file mode 100644
index 46a6a71a..00000000
--- a/Chalice/tests/examples/swap.chalice
+++ /dev/null
@@ -1,20 +0,0 @@
-class C {
- method m(a, b) returns (x, y)
- ensures x == a && y == b;
- {
- x := a;
- y := b;
- }
-
- var F;
- var G;
- method n()
- requires acc(F) && acc(this.G);
- ensures acc(F) && acc(G);
- ensures F == old(G) && G == old(F);
- {
- var tmp := F;
- F := G;
- G := tmp;
- }
-}
diff --git a/Chalice/tests/examples/swap.output.txt b/Chalice/tests/examples/swap.output.txt
deleted file mode 100644
index c0e86b2a..00000000
--- a/Chalice/tests/examples/swap.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of swap.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/examples/test.bat b/Chalice/tests/examples/test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/examples/test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/general-tests/FunctionPostcondition.chalice b/Chalice/tests/general-tests/FunctionPostcondition.chalice
deleted file mode 100644
index 7fd95b05..00000000
--- a/Chalice/tests/general-tests/FunctionPostcondition.chalice
+++ /dev/null
@@ -1,10 +0,0 @@
-// this test is for function postconditions
-
-class FunctionPostconditions
-{
- predicate valid { true }
-
- function t1(): int
- ensures unfolding valid in true;
- { 1 }
-}
diff --git a/Chalice/tests/general-tests/FunctionPostcondition.output.txt b/Chalice/tests/general-tests/FunctionPostcondition.output.txt
deleted file mode 100644
index 3244dc57..00000000
--- a/Chalice/tests/general-tests/FunctionPostcondition.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of FunctionPostcondition.chalice using parameters=""
-
-The program did not typecheck.
-8.5: the postcondition of functions cannot contain unfolding expressions at the moment
diff --git a/Chalice/tests/general-tests/ImplicitLocals.chalice b/Chalice/tests/general-tests/ImplicitLocals.chalice
deleted file mode 100644
index 15ebe8e0..00000000
--- a/Chalice/tests/general-tests/ImplicitLocals.chalice
+++ /dev/null
@@ -1,27 +0,0 @@
-class C {
- var k: int;
-
- method MyMethod() returns (x: int, y: C)
- requires acc(k)
- ensures acc(y.k) && x < y.k
- {
- x := k - 15;
- y := this;
- }
-
- method B() {
- var c := new C;
- call a, b := c.MyMethod();
- assert a < b.k;
- }
-
- method D() {
- var ch := new Ch;
- var c := new C;
- send ch(c.k - 15, c); // give ourselves some credit
- receive a, b := ch;
- assert a < b.k;
- }
-}
-
-channel Ch(x: int, y: C) where acc(y.k) && x < y.k;
diff --git a/Chalice/tests/general-tests/ImplicitLocals.output.txt b/Chalice/tests/general-tests/ImplicitLocals.output.txt
deleted file mode 100644
index 8e59a2b0..00000000
--- a/Chalice/tests/general-tests/ImplicitLocals.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of ImplicitLocals.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/general-tests/LoopLockChange.chalice b/Chalice/tests/general-tests/LoopLockChange.chalice
deleted file mode 100644
index 5ccce089..00000000
--- a/Chalice/tests/general-tests/LoopLockChange.chalice
+++ /dev/null
@@ -1,142 +0,0 @@
-class LoopLockChange {
-
- method Test0()
- requires rd(mu) && waitlevel << mu
- lockchange this;
- {
- acquire this;
-
- var b := true;
- while(b) // error: lockchange clause of loop must include all lock changes that happened before the loop
- {
- b := false;
- }
- }
-
- method Test1()
- requires rd(mu) && waitlevel << mu
- lockchange this;
- {
- acquire this;
-
- var b := true;
- while(b)
- lockchange this;
- {
- b := false;
- }
- }
-
- method Test2()
- requires rd(mu) && waitlevel << mu
- lockchange this;
- {
- var b := true;
- while(b) // error: insufficient lockchange clause
- invariant rd(mu);
- invariant b ==> waitlevel << mu
- {
- acquire this;
- b := false;
- }
- }
-
- method Test3()
- requires rd(mu) && waitlevel << mu
- lockchange this;
- {
- var b := true;
- while(b)
- invariant rd(mu);
- invariant b ==> waitlevel << mu
- lockchange this;
- {
- acquire this;
- b := false;
- }
- }
-
- method Test4(p: LoopLockChange)
- requires rd(p.mu) && waitlevel << p.mu
- requires rd(mu) && waitlevel << mu
- {
- var current: LoopLockChange := this;
- var b := true;
- while(b)
- invariant rd(current.mu)
- invariant b ==> rd(p.mu);
- invariant b ==> waitlevel << current.mu
- lockchange current; // error: after the loop body, current does no longer point to the object whose lock was acquired
- {
- acquire current;
- current := p;
- b := false;
- }
- assume false; // to prevent complaint about method's lockchange clause
- }
-
-
- method Test5(p: LoopLockChange)
- requires rd(p.mu) && waitlevel << p.mu
- requires rd(mu) && waitlevel << mu
- lockchange this;
- {
- var current: LoopLockChange := this;
- var b := true;
- while(b)
- invariant rd(current.mu)
- invariant b ==> rd(p.mu);
- invariant b ==> current == this;
- invariant b ==> waitlevel << current.mu
- lockchange this;
- {
- acquire current;
- current := p;
- b := false;
- }
- }
-
-
- method Test6()
- requires rd(mu) && waitlevel << mu
- {
- var b := true;
- while(b)
- invariant rd(mu);
- invariant b ==> waitlevel << mu
- invariant b ==> !(rd holds(this))
- invariant !b ==> holds(this)
- lockchange this;
- {
- acquire this;
- b := false;
- }
- release this;
- }
-
-
- method Test7()
- requires rd(mu) && waitlevel << mu
- {
- acquire this;
- release this;
- }
-
-
-// The following test requires a better treatment of allocation, which we don't have yet
-/* method Test8()
- {
- var tmp : LoopLockChange := this;
- var b := false;
- while(b)
- {
- tmp := new LoopLockChange;
- share tmp;
- acquire tmp;
- b := false;
- }
- assert !holds(tmp);
- }
-*/
-}
-
diff --git a/Chalice/tests/general-tests/LoopLockChange.output.txt b/Chalice/tests/general-tests/LoopLockChange.output.txt
deleted file mode 100644
index ccd9a36a..00000000
--- a/Chalice/tests/general-tests/LoopLockChange.output.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Verification of LoopLockChange.chalice using parameters=""
-
- 10.5: Method execution before loop might lock/unlock more than allowed by lockchange clause of loop.
- 35.5: The loop might lock/unlock more than the lockchange clause allows.
- 65.5: The loop might lock/unlock more than the lockchange clause allows.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 10.5: The begging of the while-body is unreachable.
- 10.5: The statements after the while-loop are unreachable.
- 75.5: Assumption introduces a contradiction.
-
-Boogie program verifier finished with 3 errors and 3 smoke test warnings
diff --git a/Chalice/tests/general-tests/RockBand-automagic.chalice b/Chalice/tests/general-tests/RockBand-automagic.chalice
deleted file mode 100644
index 8a64b691..00000000
--- a/Chalice/tests/general-tests/RockBand-automagic.chalice
+++ /dev/null
@@ -1,112 +0,0 @@
-// chalice-parameter=-checkLeaks -defaults -autoFold -autoMagic
-// verify this program with -checkLeaks -defaults -autoFold -autoMagic
-
-class Client {
- method Main() {
- var b := new RockBand
- call b.Init()
- call b.Play()
- call b.Play()
- call b.Dispose()
- }
-}
-
-class RockBand module M {
- var gigs: int
- var gt: Guitar
- var doowops: seq<Vocalist>
- var b3: Organ
- predicate Valid {
- /*acc(gigs) &&*/ 0 <= gigs &&
- /*acc(gt) && gt != null &&*/ gt.Valid &&
- acc(gt.mu) &&
- acc(doowops) &&
- /*acc(b3) && b3 != null &&*/ b3.Valid &&
- acc(b3.mu)
- }
-
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- gigs := 0
- gt := new Guitar
- call gt.Init()
- b3 := new Organ
- call b3.Init()
- }
-
- method Dispose()
- requires Valid && acc(mu)
- {
- call gt.Dispose()
- call b3.Dispose()
- free this
- }
-
- method Play()
- requires Valid
- ensures Valid
- {
- gigs := gigs + 1
- call gt.Strum()
- call b3.Grind()
- }
-}
-
-class Guitar module Musicians {
- predicate Valid { true }
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- }
- method Dispose()
- requires Valid && acc(mu)
- {
- free this
- }
- method Strum()
- requires Valid
- ensures Valid
- {
- }
-}
-
-class Vocalist module Musicians {
- predicate Valid { true }
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- }
- method Dispose()
- requires Valid && acc(mu)
- {
- free this
- }
- method Strum()
- requires Valid
- ensures Valid
- {
- }
-}
-
-class Organ module Musicians {
- predicate Valid { true }
- method Init()
- requires acc(this.*)
- ensures Valid
- {
- }
- method Dispose()
- requires Valid && acc(mu)
- {
- free this
- }
- method Grind()
- requires Valid
- ensures Valid
- {
- }
-}
diff --git a/Chalice/tests/general-tests/RockBand-automagic.output.txt b/Chalice/tests/general-tests/RockBand-automagic.output.txt
deleted file mode 100644
index 652213d9..00000000
--- a/Chalice/tests/general-tests/RockBand-automagic.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of RockBand-automagic.chalice using parameters="-checkLeaks -defaults -autoFold -autoMagic"
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/general-tests/SmokeTestTest.chalice b/Chalice/tests/general-tests/SmokeTestTest.chalice
deleted file mode 100644
index 6ff283ec..00000000
--- a/Chalice/tests/general-tests/SmokeTestTest.chalice
+++ /dev/null
@@ -1,121 +0,0 @@
-// This file is meant as a test for Chalice's smoke testing feature (command line switch -smoke)
-class Cell {
- var f: int;
-
- invariant acc(this.f) && f == 1
- invariant f == 2 // SMOKE: contradiction
-
- method a1()
- requires false // SMOKE: precondition is false
- {}
-
- method a2()
- requires acc(this.f,-2) // SMOKE: precondition is equivalent to false
- {}
-
- method a3()
- requires acc(this.f)
- {
- if (this.f > 0) {
- this.f := 0;
- }
- }
-
- method a4()
- requires acc(this.f)
- {
- if (false) {
- this.f := 0; // SMOKE: unreachable
- }
- }
-
- method a5()
- requires acc(this.f)
- {
- if (true) {
- this.f := 0;
- }
- }
-
- method a6()
- requires acc(this.f)
- {
- if (false) {
- this.f := 0; // SMOKE: unreachable
- } else {
- this.f := 1;
- }
- }
-
- method a7(i: int, j: int)
- requires i != j;
- {
- assume i == j; // SMOKE: introduces contradiction
- }
-
- method a8()
- requires acc(this.f)
- {
- while (true)
- invariant acc(this.f)
- {
- this.f := this.f + 1
- }
- // SMOKE: unreachable, loop does not terminate
- }
-
- method a9()
- requires acc(this.f)
- {
- call a8()
- }
-
- method a10()
- requires acc(this.f)
- {
- if (true) {
- this.f := 0;
- } else {
- this.f := 1; // SMOKE: unreachable
- }
- }
-
- function f1(): int
- requires false // SMOKE: precondition is false
- { 1 }
-
- method a11()
- {
- var i: int := 0
- if (false) {
- // SMOKE: unreachable
- } else {
- if (true) { assume false } // SMOKE: introduces contradiction
- else { assume i == 1 } // SMOKE: introduces contradiction
- }
- }
-
- method a12()
- {
- assume false // SMOKE: introduces contradiction
- while (false) {
-
- }
- }
-
- method a13()
- ensures false // ERROR: cannot prove false
- {
- }
-
- method a14()
- {
- call a13(); // SMOKE: statements afterwards not reachable anymore
- }
-
- predicate valid {
- 1 == 2 // SMOKE: contradiction
- }
-}
-
-channel C(msg: bool) where msg && !msg // SMOKE: contradiction \ No newline at end of file
diff --git a/Chalice/tests/general-tests/SmokeTestTest.output.txt b/Chalice/tests/general-tests/SmokeTestTest.output.txt
deleted file mode 100644
index 1ad5f926..00000000
--- a/Chalice/tests/general-tests/SmokeTestTest.output.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Verification of SmokeTestTest.chalice using parameters=""
-
- 106.3: The postcondition at 107.13 might not hold. The expression at 107.13 might not evaluate to true.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 2.1: Monitor invariant is equivalent to false.
- 8.3: Precondition of method a1 is equivalent to false.
- 12.3: Precondition of method a2 is equivalent to false.
- 27.5: The begging of the if-branch is unreachable.
- 43.5: The begging of the if-branch is unreachable.
- 53.5: Assumption introduces a contradiction.
- 59.5: The statements after the while-loop are unreachable.
- 76.5: The begging of the else-branch is unreachable.
- 83.3: Precondition of function f1 is equivalent to false.
- 90.5: The begging of the if-branch is unreachable.
- 93.7: The begging of the else-branch is unreachable.
- 93.19: Assumption introduces a contradiction.
- 100.5: Assumption introduces a contradiction.
- 113.5: The statements after the method call statement are unreachable.
- 116.3: Predicate Cell.valid is equivalent to false.
- 121.1: Where clause of channel C is equivalent to false.
-
-Boogie program verifier finished with 1 errors and 16 smoke test warnings
diff --git a/Chalice/tests/general-tests/VariationsOfProdConsChannel.chalice b/Chalice/tests/general-tests/VariationsOfProdConsChannel.chalice
deleted file mode 100644
index 2d2f9b91..00000000
--- a/Chalice/tests/general-tests/VariationsOfProdConsChannel.chalice
+++ /dev/null
@@ -1,88 +0,0 @@
-class Cell {
- var val: int
-}
-
-channel Ch(c: Cell) where
- c != null ==> acc(c.val) && 0 <= c.val && credit(this)
-
-class Program {
- method Main0() { // error: debt remains after body
- var ch := new Ch
- fork tk0 := Producer(ch)
- fork tk1 := Consumer(ch)
- // join tk0
- join tk1
- }
- method Main1() {
- var ch := new Ch
- fork tk0 := Producer(ch)
- fork tk1 := Consumer(ch)
- join tk0
- // join tk1
- } // no problem
- method Producer0(ch: Ch) // error: debt remains after body
- requires ch != null
- ensures credit(ch)
- {
- var i := 0
- while (i < 25)
- {
- var x := i*i
- var c := new Cell { val := x }
- send ch(c)
- i := i + 1
- }
- // send ch(null)
- }
- method Producer1(ch: Ch)
- requires ch != null
- ensures credit(ch)
- {
- var i := 0
- while (i < 25)
- {
- var x := i*i
- var c := new Cell { val := x }
- send ch(c)
- i := i + 1 + c.val // error: can no longer read c.val
- }
- send ch(null)
- }
- method Consumer0(ch: Ch)
- requires rd(ch.mu) && waitlevel << ch.mu
- requires credit(ch)
- ensures rd(ch.mu)
- {
- var c: Cell
- receive c := ch
- while (c != null && c.val == 7) // this consumer may end early, but that's allowed
- invariant rd(ch.mu) && waitlevel << ch.mu
- invariant c != null ==> acc(c.val) && 0 <= c.val && credit(ch)
- {
- var i := c.val
- receive c := ch
- }
- }
- method Consumer1(ch: Ch)
- requires rd(ch.mu) && waitlevel << ch.mu
- requires credit(ch)
- ensures rd(ch.mu)
- {
- var c: Cell
- receive c := ch
- if (c != null) {
- assert 0 <= c.val // follows from where clause
- }
- }
- method Consumer2(ch: Ch)
- requires rd(ch.mu) && waitlevel << ch.mu
- requires credit(ch)
- ensures rd(ch.mu)
- {
- var c: Cell
- receive c := ch
- if (c != null) {
- assert c.val < 2 // error: does not follow from where clause
- }
- }
-}
diff --git a/Chalice/tests/general-tests/VariationsOfProdConsChannel.output.txt b/Chalice/tests/general-tests/VariationsOfProdConsChannel.output.txt
deleted file mode 100644
index d5b9c9ee..00000000
--- a/Chalice/tests/general-tests/VariationsOfProdConsChannel.output.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Verification of VariationsOfProdConsChannel.chalice using parameters=""
-
-The program did not typecheck.
-11.5: call of undeclared member Producer in class Program
-<undefined position>: Invalid token type. Program does not declare a method Producer.
-12.5: call of undeclared member Consumer in class Program
-<undefined position>: Invalid token type. Program does not declare a method Consumer.
-14.10: the first argument of a join async must be a token
-18.5: call of undeclared member Producer in class Program
-<undefined position>: Invalid token type. Program does not declare a method Producer.
-19.5: call of undeclared member Consumer in class Program
-<undefined position>: Invalid token type. Program does not declare a method Consumer.
-20.10: the first argument of a join async must be a token
diff --git a/Chalice/tests/general-tests/cell-defaults.chalice b/Chalice/tests/general-tests/cell-defaults.chalice
deleted file mode 100644
index eb826f89..00000000
--- a/Chalice/tests/general-tests/cell-defaults.chalice
+++ /dev/null
@@ -1,153 +0,0 @@
-// chalice-parameter=-defaults -autoFold -autoMagic
-// verify this program with -defaults -autoFold -autoMagic
-
-class Cell module Library {
- var x: int;
-
- method init(v: int)
- requires acc(this.x) && 0<=v;
- ensures valid && this.get() == v;
- {
- x := v;
- }
-
- method set(v: int)
- requires valid && 0<=v;
- ensures valid && get()==v;
- {
- x := v;
- }
-
- method increment()
- requires valid;
- ensures valid && get() == old(get()) + 1;
- {
- x := x + 1;
- }
-
- method dispose()
- requires valid && acc(mu);
- ensures true;
- {
- free this;
- }
-
- function get(): int
- requires valid;
- ensures 0<=result;
- {
- x
- }
-
- predicate valid {
- acc(this.x) && 0<=x
- }
-
- invariant valid;
-}
-
-class Interval module Library2 {
- var left: Cell;
- var right: Cell;
-
- method init(l: int, r: int)
- requires 0<=l && l <= r;
- requires acc(left) && acc(right);
- ensures valid;
- ensures getLeft()==l
- ensures getRight()==r;
- {
- left := new Cell;
- call left.init(l);
- right := new Cell;
- call right.init(r);
- }
-
- method setLeft(l: int)
- requires valid;
- requires 0<=l && l<=getRight();
- ensures valid;
- ensures getLeft()==l && getRight()==old(getRight());
- {
- call left.set(l);
- }
-
- method setRight(r: int)
- requires valid;
- requires 0<=r && getLeft()<=r;
- ensures valid;
- ensures getLeft()==old(getLeft()) && getRight()==r;
- {
- call right.set(r);
- }
-
- method shift(v: int)
- requires valid;
- requires 0<=v;
- ensures valid;
- ensures getLeft()==old(getLeft())+v && getRight()==old(getRight())+v;
- {
- call left.set(left.get()+v);
- call right.set(right.get()+v);
- }
-
- function getLeft() : int
- requires valid;
- {
- left.get() // for some reason, Boogie can't figure out the callee's heap is smaller when using defaults
- }
-
- function getRight() : int
- requires valid;
- {
- right.get() // for some reason, Boogie can't figure out the callee's heap is smaller when using defaults
- }
-
- predicate valid
- {
- left.valid && right.valid && left.get() <= right.get()
- }
-}
-
-class Program module Main {
- method main(){
- var c1 := new Cell;
- call c1.init(5);
- call c1.set(6);
-
- var c2 := new Cell;
- call c2.init(10);
- call c2.set(11);
-
- assert c1.get() == 6;
- }
-
- method main2(){
- var c: Cell;
-
- c := new Cell;
- call c.init(0);
- call c.dispose();
-
- assert c.valid; // should fail
- }
-
- method main3() returns (rt: Cell)
- ensures rt!=null && rt.valid && rt.get() == 0
- {
- rt := new Cell;
- call rt.init(0)
- }
-
- method main4() {
- var c: Cell;
-
- c := new Cell;
- call c.init(0);
- share c;
-
- acquire c;
- call c.set(1);
- release c;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/general-tests/cell-defaults.output.txt b/Chalice/tests/general-tests/cell-defaults.output.txt
deleted file mode 100644
index fd748230..00000000
--- a/Chalice/tests/general-tests/cell-defaults.output.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Verification of cell-defaults.chalice using parameters="-defaults -autoFold -autoMagic"
-
- 97.5: The heap of the callee might not be strictly smaller than the heap of the caller.
- 103.5: The heap of the callee might not be strictly smaller than the heap of the caller.
- 132.5: Assertion might not hold. Insufficient fraction at 132.12 for Cell.valid.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 125.3: The end of method main2 is unreachable.
-
-Boogie program verifier finished with 3 errors and 1 smoke test warnings
diff --git a/Chalice/tests/general-tests/counter.chalice b/Chalice/tests/general-tests/counter.chalice
deleted file mode 100644
index c15ed36b..00000000
--- a/Chalice/tests/general-tests/counter.chalice
+++ /dev/null
@@ -1,153 +0,0 @@
-class Counter {
- var value: int;
-
- invariant acc(value) && old(value)<=value;
-}
-
-class Program {
-
- method main1(){
- var counter := new Counter;
- counter.value := 0;
- share counter;
-
- acquire counter;
- var tmp1 := counter.value;
- release counter;
-
- acquire counter;
- var tmp2 := counter.value;
- release counter;
-
- assert tmp1 <= tmp2;
- }
-
- method main2(){
- var counter := new Counter;
- counter.value := 0;
- share counter;
-
- acquire counter;
- release counter;
-
- call bar(counter);
- }
-
- method bar(c: Counter)
- requires c!=null && acc(c.mu) && waitlevel << c.mu;
- requires eval(c.release, acc(c.value) && 0<=c.value);
- {
- lock (c) {
- assert 0 <= c.value; // ok, because of the lastSeen conjunct in the precondition
- }
- }
-
- method main3() returns (counter: Counter)
- lockchange counter;
- {
- counter := new Counter;
- counter.value := 0;
- share counter;
- acquire counter;
- call doRelease(counter, counter.value);
- }
-
- method doRelease(c: Counter, i: int)
- requires c!=null && holds(c) && acc(c.value) && eval(c.acquire, acc(c.value) && c.value <= i);
- lockchange c;
- {
- c.value := i+1
- release c; // ok, because of atAcquire conjunct in the precondition
- }
-
- method main4(){
- var counter := new Counter;
- counter.value := 0;
- share counter;
-
- acquire counter;
- counter.value := counter.value - 1;
- release counter; // error: should fail
- }
-
- method main5(){
- var counter := new Counter;
- counter.value := 10;
- share counter;
-
- call foo(counter);
-
- unshare counter;
- assert 10<=counter.value; // error: should fail
- }
-
- method foo(c: Counter)
- requires c!=null && acc(c.mu) && waitlevel << c.mu && eval(c.release, acc(c.value) && 10<=c.value);
- ensures c!=null && holds(c) && acc(c.mu) && acc(c.value);
- lockchange c;
- {
- acquire c;
- unshare c;
- c.value := 5;
- share c;
- acquire c;
- }
-
- method nestedGood0(c: Counter)
- requires c != null && acc(c.mu) && waitlevel << c.mu;
- {
- lock (c) {
- release c
- acquire c
- }
- }
-
- method nestedGood1(c: Counter)
- requires c != null && acc(c.mu) && waitlevel << c.mu;
- {
- var t: Counter := c
- lock (t) {
- t := new Counter
- share t
- acquire t
- } // this line releases the original value for t
- release t
- }
-
- method nestedBad0(c: Counter)
- requires c != null && acc(c.mu) && waitlevel << c.mu;
- {
- lock (c) {
- release c
- } // error: no longer holds c
- }
-
- method nestedBad1(c: Counter)
- requires c != null && acc(c.mu) && waitlevel << c.mu;
- {
- lock (c) {
- acquire c // error: already holds c
- }
- }
-
- method nestedBad2(c: Counter)
- requires c != null && acc(c.mu) && waitlevel << c.mu;
- {
- lock (c) {
- lock (c) { // error: already holds c
- }
- }
- }
-
- method nestedBad3(c: Counter)
- requires c != null && acc(c.mu) && waitlevel << c.mu;
- {
- var t: Counter := c
- lock (t) {
- release t
- t := new Counter
- share t
- acquire t
- } // error: this line attempts to release the original t
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/general-tests/counter.output.txt b/Chalice/tests/general-tests/counter.output.txt
deleted file mode 100644
index 53bcd98d..00000000
--- a/Chalice/tests/general-tests/counter.output.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Verification of counter.chalice using parameters=""
-
- 70.5: Monitor invariant might hot hold. The expression at 4.27 might not evaluate to true.
- 81.5: Assertion might not hold. The expression at 81.12 might not evaluate to true.
- 120.5: The target of the release statement might not be locked by the current thread.
- 129.7: The mu field of the target of the acquire statement might not be above waitlevel.
- 137.7: The mu field of the target of the acquire statement might not be above waitlevel.
- 146.5: The target of the release statement might not be locked by the current thread.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 63.3: The end of method main4 is unreachable.
- 117.3: The end of method nestedBad0 is unreachable.
- 129.7: The statements after the acquire statement are unreachable.
- 137.7: The begging of the lock-block is unreachable.
- 142.3: The end of method nestedBad3 is unreachable.
-
-Boogie program verifier finished with 6 errors and 5 smoke test warnings
diff --git a/Chalice/tests/general-tests/generate_reference.bat b/Chalice/tests/general-tests/generate_reference.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/general-tests/generate_reference.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/general-tests/generate_reference_all.bat b/Chalice/tests/general-tests/generate_reference_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/general-tests/generate_reference_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/general-tests/ll-lastnode.chalice b/Chalice/tests/general-tests/ll-lastnode.chalice
deleted file mode 100644
index f7a44cfe..00000000
--- a/Chalice/tests/general-tests/ll-lastnode.chalice
+++ /dev/null
@@ -1,82 +0,0 @@
-// This test case showed a triggering problem (and potentially a matching loop).
-// The quantified assertion and postcondition that did not verify are highlighted below.
-class Node
-{
- var val:int
- var next:Node
- var break_here:bool
-
- predicate lseg
- {
- acc(break_here) && (!break_here ==> acc(val) && acc(next) && (next!=null ==> next.lseg))
- }
-
- predicate xlseg
- {
- acc(val) && acc(next) && (next!=null ==> next.lseg)
- }
-
- function length():int
- requires lseg
- ensures 0 <= result
- {
- unfolding lseg in (break_here ? 0 : (next==null ? 1 : 1+next.length()))
- }
-
- function xlength():int
- requires xlseg
- ensures 0 < result
- {
- unfolding xlseg in (next==null ? 1 : 1+next.length())
- }
-
- function get(i:int):int
- requires lseg && i>=0 && i<length()
- {
- unfolding lseg in i==0 ? val : next.get(i-1)
- }
-
- function xget(i:int):int
- requires xlseg && i>=0 && i<xlength()
- {
- unfolding xlseg in i==0 ? val : next.get(i-1)
- }
-
- function get_next_seg():Node
- requires lseg
- {
- unfolding lseg in break_here ? this : (next==null ? next : next.get_next_seg())
- }
-
- method lastNode() returns(res:Node)
- requires lseg && length()>0
- ensures res != null && lseg && res.xlseg
- ensures res.xlength()==1 && res.xget(0)==old(get(length()-1))
- ensures length() == old(length()-1)
- // Did not verify.
- ensures (forall i:int :: 0<=i && i<length() ==> get(i) == old(get(i)))
- {
- var I:int
- var h:Node
-
- res:=this
- unfold lseg
- break_here:=true
- fold lseg
- fold xlseg
-
- while(res.xlength()>1)
- invariant res!=null && lseg && res.xlseg &&
- res==get_next_seg() && // new invariant
- length() + res.xlength() == old(length()) &&
- 0 <= length() && length() < old(length()) &&
- (forall i:int :: 0<=i && i<length() ==> get(i)==old(get(i))) &&
- (forall i:int :: length()<=i && i<old(length()) ==> res.xget(i-length())==old(get(i)))
- {
- // We are not interested (at the moment) in verifying the loop.
- assume false
- }
- // Did not verify.
- assert (forall i:int :: length()<=i && i<old(length()) ==> res.xget(i-length())==old(get(i)))
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/general-tests/ll-lastnode.output.txt b/Chalice/tests/general-tests/ll-lastnode.output.txt
deleted file mode 100644
index a02dd2d8..00000000
--- a/Chalice/tests/general-tests/ll-lastnode.output.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Verification of ll-lastnode.chalice using parameters=""
-
-
- 77.9: Assumption introduces a contradiction.
-
-Boogie program verifier finished with 0 errors and 1 smoke test warnings
diff --git a/Chalice/tests/general-tests/nestedPredicates.chalice b/Chalice/tests/general-tests/nestedPredicates.chalice
deleted file mode 100644
index 8afbff5c..00000000
--- a/Chalice/tests/general-tests/nestedPredicates.chalice
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Recursive implementation and specification of a linked list. */
-
-class Node {
- var next: Node;
- var value: int;
-
- predicate valid {
- rd*(next) && rd*(value) && (next!=null ==> next.valid)
- }
-
- method testNestingUnfold()
- requires acc(this.valid)
- {
- unfold this.valid;
- assert this != this.next;
- if(this.next != null) {
- unfold this.next.valid;
- assert this.next != this.next.next;
- assert this != this.next.next;
- }
- }
-
- method testNestingFold() // this test shows that we build in the assumption that predicate instances with infinite expansions cannot be exist (in reachable code)
- requires rd*(this.next) && rd*(this.value) && rd*(this.next.next) && rd*(this.next.value) && this.next != null && this.next.next != null && this.next.next.valid
-
- {
- fold this.next.valid;
- assert this.next != this.next.next; // definition of valid "proves" that this.next and this.next.next cannot be aliases
- fold this.valid;
- assert this != this.next;
- assert this != this.next.next;
- }
-
- method testNestingUnfolding()
- requires acc(this.valid)
- {
- assert this != (unfolding this.valid in this.next);
- if((unfolding this.valid in this.next) != null) {
- assert (unfolding this.valid in this.next) != (unfolding this.valid in (unfolding this.next.valid in this.next.next));
- assert this != (unfolding this.valid in (unfolding this.next.valid in this.next.next));
- }
- }
-
- predicate p {
- rd*(next) && rd*(value) && (next!=null ==> next.q)
- }
-
- predicate q {
- rd*(next) && rd*(value) && (next!=null ==> next.p)
- }
-
- method testNestingUnfoldTwo()
- requires acc(this.p)
- {
- unfold this.p;
- assert this != this.next; // should fail
- if(this.next != null) {
- unfold this.next.q;
- assert this.next != this.next.next; // should fail
- assert this != this.next.next; // should succeed
- }
- }
-
- method testNestingFoldTwo() // this test shows that we build in the assumption that predicate instances with infinite expansions cannot be exist (in reachable code)
- requires rd*(this.next) && rd*(this.value) && rd*(this.next.next) && rd*(this.next.value) && this.next != null && this.next.next != null && this.next.next.p
-
- {
- fold this.next.q;
- assert this != this.next; // should fail
- assert this.next != this.next.next; // should fail
- assert this != this.next.next; // should fail
- }
-
- method testNestingFoldThree() // this test shows that we build in the assumption that predicate instances with infinite expansions cannot be exist (in reachable code)
- requires rd*(this.next) && rd*(this.value) && rd*(this.next.next) && rd*(this.next.value) && this.next != null && this.next.next != null && this.next.next.p
-
- {
- fold this.next.q;
- fold this.p;
- assert this != this.next; // should succeed, since this == this.next ==> this == this.next.next
- assert this.next != this.next.next; // should fail - we haven't seen a cycle which would follow from this fact
- assert this != this.next.next; // should succeed
- }
-
- method testNestingUnfoldingTwo()
- requires acc(this.p)
- {
- assert this != (unfolding this.p in this.next); // should fail
- if((unfolding this.p in this.next) != null) {
- assert (unfolding this.p in this.next) != (unfolding this.p in (unfolding this.next.q in this.next.next)); // should fail
- assert this != (unfolding this.p in (unfolding this.next.q in this.next.next)); // should succeed
- }
- }
-
- method testNestingUnfoldingPrecondition(x: Node)
- requires acc(this.valid) && (unfolding this.valid in this.next == x);
- {
- assert this != x;
- }
-
- function getNext() : Node
- requires this.valid;
- {
- unfolding this.valid in this.next
- }
-
- method testNestingUnfoldingPostcondition(x: Node)
- requires acc(this.valid);
- ensures acc(this.valid) && (unfolding this.valid in true) && this != this.getNext()
- {
- // nothing
- }
-
-} \ No newline at end of file
diff --git a/Chalice/tests/general-tests/nestedPredicates.output.txt b/Chalice/tests/general-tests/nestedPredicates.output.txt
deleted file mode 100644
index 635ae780..00000000
--- a/Chalice/tests/general-tests/nestedPredicates.output.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Verification of nestedPredicates.chalice using parameters=""
-
- 56.7: Assertion might not hold. The expression at 56.14 might not evaluate to true.
- 59.9: Assertion might not hold. The expression at 59.16 might not evaluate to true.
- 69.7: Assertion might not hold. The expression at 69.14 might not evaluate to true.
- 70.7: Assertion might not hold. The expression at 70.14 might not evaluate to true.
- 71.7: Assertion might not hold. The expression at 71.14 might not evaluate to true.
- 81.7: Assertion might not hold. The expression at 81.14 might not evaluate to true.
- 88.7: Assertion might not hold. The expression at 88.14 might not evaluate to true.
- 90.9: Assertion might not hold. The expression at 90.16 might not evaluate to true.
-
-Boogie program verifier finished with 8 errors and 0 smoke test warnings
diff --git a/Chalice/tests/general-tests/prog0.chalice b/Chalice/tests/general-tests/prog0.chalice
deleted file mode 100644
index fb835a24..00000000
--- a/Chalice/tests/general-tests/prog0.chalice
+++ /dev/null
@@ -1,109 +0,0 @@
-class C {
- method m() {
- assert 4 + (a * 5) + (2 + 3) * (a + a);
- a := a + 3;
- b := a - b - c + 4 * d + 20 + --25;
- b := ((((a - b) - c) + 4 * d) + 20) + --25;
- c := a - (b - (c + (4 * d + (20 + 25))));
- assert (X ==> Y) ==> Z <==> A ==> B ==> C;
- assume A && B && (C || D || E) && F;
- var x;
- var y := 12 + !(x.f.g).h - (!x).f + (!x.f);
- var z := new C;
- y := new D;
- o.f := 5;
- (a + b).y := new T;
- reorder (2 ==(O != 3)) != O between a,b,c and x,y,z;
- reorder X ==> Y below x+5;
- reorder o.f above this, null;
- share o;
- unshare o;
- acquire o;
- release o;
- rd acquire o;
- rd release o;
- downgrade o;
- var tok: token<C.m>;
- fork tok := o.m();
- join tok;
- assert rd(x) + acc(y) + acc(z, 1/4) + old(old(k)) + null.f;
- x := this.f;
- call m(2,3,4);
- call this.m(2,3,4);
- call a,b,c := o.m();
- call x := m(200);
- reorder o above waitlevel;
- }
- method p(a,b,c) returns (x,y,z)
- requires 8 + 2 == 10;
- ensures 8 + 5 > 10;
- requires x == y+1;
- ensures old(x) < x;
- {
- if (x == 7) {
- y := y + 1; z := z + 2;
- } else if (x == 8) {
- y := 2;
- } else {
- z := 10;
- }
- { // empty block
- }
- if (x == 9) { }
- if (x == 10) { x := 10; } else { }
- var n := 0;
- while (n < 100) { n := n - 1; }
- while (n != 0)
- invariant n % 2 == 0;
- invariant sqrt2 * sqrt2 == 2;
- {
- n := n - 2;
- }
- call v,x := s.M(65);
- }
-}
-class D { }
-
-// ----- tests specifically of implicit locals in CALL and RECEIVE statements
-
-class ImplicitC {
- var k: int;
-
- method MyMethod() returns (x: int, y: ImplicitC)
- requires acc(k)
- ensures acc(y.k) && x < y.k
- {
- x := k - 15;
- y := this;
- }
-
- method B0() {
- var c := new ImplicitC;
- call a, b := c.MyMethodX(); // error: method not found (so what is done with a,b?)
- assert a < b.k;
- }
-
- method B1() {
- var c := new ImplicitC;
- call a, a := c.MyMethod(); // error: a occurs twice
- assert a < b.k;
- }
-
- method D0() {
- var ch := new Ch;
- var c := new ImplicitC;
- send ch(c.k - 15, c); // give ourselves some credit
- receive a, b := chX; // error: channel not found (so what is done with a,b?)
- assert a < b.k;
- }
-
- method D1() {
- var ch := new Ch;
- var c := new ImplicitC;
- send ch(c.k - 15, c); // give ourselves some credit
- receive a, a := ch; // error: a occurs twice
- assert a < b.k;
- }
-}
-
-channel Ch(x: int, y: ImplicitC) where acc(y.k) && x < y.k;
diff --git a/Chalice/tests/general-tests/prog0.output.txt b/Chalice/tests/general-tests/prog0.output.txt
deleted file mode 100644
index 5b329874..00000000
--- a/Chalice/tests/general-tests/prog0.output.txt
+++ /dev/null
@@ -1,146 +0,0 @@
-Verification of prog0.chalice using parameters=""
-
-The program did not typecheck.
-3.17: undeclared member a in class C
-3.37: undeclared member a in class C
-3.41: undeclared member a in class C
-3.12: assert statement requires a boolean expression (found int)
-4.5: undeclared member a in class C
-4.10: undeclared member a in class C
-5.5: undeclared member b in class C
-5.10: undeclared member a in class C
-5.14: undeclared member b in class C
-5.18: undeclared member c in class C
-5.26: undeclared member d in class C
-6.5: undeclared member b in class C
-6.14: undeclared member a in class C
-6.18: undeclared member b in class C
-6.23: undeclared member c in class C
-6.32: undeclared member d in class C
-7.5: undeclared member c in class C
-7.10: undeclared member a in class C
-7.15: undeclared member b in class C
-7.20: undeclared member c in class C
-7.29: undeclared member d in class C
-8.13: undeclared member X in class C
-8.19: undeclared member Y in class C
-8.13: incorrect type of ==> LHS (expected bool, found int)
-8.19: incorrect type of ==> RHS (expected bool, found int)
-8.26: undeclared member Z in class C
-8.26: incorrect type of ==> RHS (expected bool, found int)
-8.33: undeclared member A in class C
-8.39: undeclared member B in class C
-8.45: undeclared member C in class C
-8.39: incorrect type of ==> LHS (expected bool, found int)
-8.45: incorrect type of ==> RHS (expected bool, found int)
-8.33: incorrect type of ==> LHS (expected bool, found int)
-9.12: undeclared member A in class C
-9.17: undeclared member B in class C
-9.12: incorrect type of && LHS (expected bool, found int)
-9.17: incorrect type of && RHS (expected bool, found int)
-9.23: undeclared member C in class C
-9.28: undeclared member D in class C
-9.23: incorrect type of || LHS (expected bool, found int)
-9.28: incorrect type of || RHS (expected bool, found int)
-9.33: undeclared member E in class C
-9.33: incorrect type of || RHS (expected bool, found int)
-9.39: undeclared member F in class C
-9.39: incorrect type of && RHS (expected bool, found int)
-11.21: undeclared member f in class int
-11.21: undeclared member g in class int
-11.21: undeclared member h in class int
-<undefined position>: not-expression requires boolean operand
-<undefined position>: incorrect type of + RHS (expected int, found bool)
-11.33: not-expression requires boolean operand
-11.33: undeclared member f in class bool
-11.43: undeclared member f in class int
-11.42: not-expression requires boolean operand
-11.42: incorrect type of + RHS (expected int, found bool)
-13.5: type mismatch in assignment, lhs=int rhs=D
-14.5: undeclared member o in class C
-14.5: undeclared member f in class int
-15.6: undeclared member a in class C
-15.10: undeclared member b in class C
-15.5: undeclared member y in class int
-15.18: undefined class or channel T used in new expression
-16.19: undeclared member O in class C
-16.14: == requires operands of the same type, found int and bool
-16.31: undeclared member O in class C
-16.13: != requires operands of the same type, found bool and int
-16.13: object in reorder statement must be of a reference type (found bool)
-16.41: undeclared member a in class C
-16.41: install bound must be of a reference type or Mu type (found int)
-16.43: undeclared member b in class C
-16.43: install bound must be of a reference type or Mu type (found int)
-16.45: undeclared member c in class C
-16.45: install bound must be of a reference type or Mu type (found int)
-16.51: install bound must be of a reference type or Mu type (found int)
-16.53: install bound must be of a reference type or Mu type (found int)
-17.13: undeclared member X in class C
-17.19: undeclared member Y in class C
-17.13: incorrect type of ==> LHS (expected bool, found int)
-17.19: incorrect type of ==> RHS (expected bool, found int)
-17.13: object in reorder statement must be of a reference type (found bool)
-17.27: install bound must be of a reference type or Mu type (found int)
-18.13: undeclared member o in class C
-18.13: undeclared member f in class int
-18.13: object in reorder statement must be of a reference type (found int)
-19.11: undeclared member o in class C
-19.11: object in share statement must be of a reference type (found int)
-20.13: undeclared member o in class C
-20.13: object in unshare statement must be of a reference type (found int)
-21.13: undeclared member o in class C
-21.13: object in acquire statement must be of a reference type (found int)
-22.13: undeclared member o in class C
-22.13: object in release statement must be of a reference type (found int)
-23.16: undeclared member o in class C
-23.16: object in rd acquire statement must be of a reference type (found int)
-24.16: undeclared member o in class C
-24.16: object in rd release statement must be of a reference type (found int)
-25.15: undeclared member o in class C
-25.15: object in downgrade statement must be of a reference type (found int)
-27.17: undeclared member o in class C
-27.5: call of undeclared member m in class int
-27.10: wrong token type
-29.12: rd expression is allowed only in positive predicate contexts
-29.15: undeclared member x in class C
-29.20: acc expression is allowed only in positive predicate contexts
-29.24: undeclared member y in class C
-29.12: incorrect type of + LHS (expected int, found bool)
-29.20: incorrect type of + RHS (expected int, found bool)
-29.29: acc expression is allowed only in positive predicate contexts
-29.33: undeclared member z in class C
-29.29: incorrect type of + RHS (expected int, found bool)
-29.51: undeclared member k in class C
-29.57: undeclared member f in class null
-29.12: assert statement requires a boolean expression (found int)
-30.10: undeclared member f in class C
-31.5: wrong number of actual in-parameters in call to C.m (3 instead of 0)
-32.5: wrong number of actual in-parameters in call to C.m (3 instead of 0)
-33.19: undeclared member o in class C
-33.5: call of undeclared member m in class int
-34.5: wrong number of actual in-parameters in call to C.m (1 instead of 0)
-34.5: wrong number of actual out-parameters in call to C.m (1 instead of 0)
-35.13: undeclared member o in class C
-35.13: object in reorder statement must be of a reference type (found int)
-58.17: undeclared member sqrt2 in class C
-58.25: undeclared member sqrt2 in class C
-62.17: undeclared member s in class C
-62.5: call of undeclared member M in class int
-82.5: call of undeclared member MyMethodX in class ImplicitC
-83.12: undefined local variable a
-83.16: undefined local variable b
-83.16: undeclared member k in class int
-88.13: the type of the formal argument is not assignable to the actual parameter (expected: ImplicitC, found: int)
-88.13: duplicate actual out-parameter: a
-89.16: undeclared member b in class ImplicitC
-89.16: undeclared member k in class int
-96.21: undeclared member chX in class ImplicitC
-96.5: receive expression (which has type int) does not denote a channel
-97.12: undefined local variable a
-97.16: undefined local variable b
-97.16: undeclared member k in class int
-104.16: the type of the formal argument is not assignable to the actual parameter (expected: ImplicitC, found: int)
-104.16: duplicate actual out-parameter: a
-105.16: undeclared member b in class ImplicitC
-105.16: undeclared member k in class int
diff --git a/Chalice/tests/general-tests/prog1.chalice b/Chalice/tests/general-tests/prog1.chalice
deleted file mode 100644
index 133de36d..00000000
--- a/Chalice/tests/general-tests/prog1.chalice
+++ /dev/null
@@ -1,86 +0,0 @@
-// 7 errors expected
-
-class C {
- var x: int;
- invariant acc(x) && 0 <= x;
-
- method seq0() returns (r: int)
- {
- r := x; // error: cannot access this.x here (90)
- }
- method seq1() returns (r: int)
- requires acc(x);
- {
- r := x;
- }
- method seq2() returns (r: int)
- requires rd(x);
- {
- r := x;
- }
- method seq3() returns (r: int)
- requires rd(x);
- {
- r := x;
- x := x + 1; // error: cannot write to this.x here (184)
- }
-
- method main0()
- {
- var c := new C;
- c.x := 0;
- share c;
- var t := c.x; // error: cannot access c.x now (254)
- }
- method main1()
- {
- var c := new C;
- c.x := 2;
- share c;
- acquire c;
- c.x := c.x - 1;
- release c; // error: monitor invariant might not hold (362)
- }
- method main2()
- {
- var c := new C;
- c.x := 2;
- share c;
- acquire c;
- c.x := c.x + 1;
- release c; // good!
- }
- method main3()
- {
- var c := new C;
- c.x := 2;
- share c;
- rd acquire c;
- var tmp := c.x + 1; // fine
- c.x := tmp; // error: cannot write to c.x here (582)
- rd release c;
- }
- method main4()
- {
- var c := new C;
- c.x := 2;
- share c;
- acquire c;
- c.x := c.x + 1;
- unshare c;
- c.x := c.x + 1;
- }
- method main5()
- {
- var c := new C;
- unshare c; // error: cannot unshare an object that isn't shared (754)
- }
- method main6()
- {
- var c := new C;
- c.x := 0;
- share c; acquire c;
- unshare c;
- unshare c; // error: cannot unshare an object that isn't shared (862)
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/general-tests/prog1.output.txt b/Chalice/tests/general-tests/prog1.output.txt
deleted file mode 100644
index c6c5fe0e..00000000
--- a/Chalice/tests/general-tests/prog1.output.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Verification of prog1.chalice using parameters=""
-
- 9.10: Location might not be readable.
- 25.5: Location might not be writable
- 33.14: Location might not be readable.
- 42.5: Monitor invariant might hot hold. The expression at 5.23 might not evaluate to true.
- 60.5: Location might not be writable
- 76.5: The target of the unshare statement might not be shared.
- 84.5: The target of the unshare statement might not be shared.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 7.3: The end of method seq0 is unreachable.
- 21.3: The end of method seq3 is unreachable.
- 28.3: The end of method main0 is unreachable.
- 53.3: The end of method main3 is unreachable.
- 73.3: The end of method main5 is unreachable.
- 78.3: The end of method main6 is unreachable.
-
-Boogie program verifier finished with 7 errors and 6 smoke test warnings
diff --git a/Chalice/tests/general-tests/prog2.chalice b/Chalice/tests/general-tests/prog2.chalice
deleted file mode 100644
index 3b6f2783..00000000
--- a/Chalice/tests/general-tests/prog2.chalice
+++ /dev/null
@@ -1,92 +0,0 @@
-// 4 errors expected
-
-class C {
- method M(x: int) returns (y: bool)
- requires 0 <= x;
- ensures y <==> x == 10;
- {
- y := true;
- if (x != 10) { y := !y; }
- }
-
- method Caller0()
- {
- var b: bool;
- call b := M(12);
- assert !b;
- call b := M(10);
- assert b;
- }
- method Caller1()
- {
- var b: bool;
- call b := M(11);
- assert b; // error (258)
- }
-
- var F: int;
-
- method P(n: int)
- requires acc(F);
- ensures F == old(F) + n; // error
- {
- F := F + n;
- }
- method Caller2()
- requires acc(F);
- {
- var prev := F;
- call P(2);
- }
-
- method Q(n: int)
- requires acc(F);
- ensures acc(F) && F == old(F) + n;
- {
- F := F + n;
- }
- method Caller3()
- requires acc(F);
- ensures acc(F);
- {
- var prev := F;
- call Q(2);
- assert F == prev + 2;
- }
-}
-
-class Consts {
- method M0() returns (z: int)
- ensures z == 5
- {
- const a := 5
- z := a
- }
- method M1() {
- ghost const a
- a := 5
- }
- method M2() {
- ghost const a
- a := 5
- a := 5 // error (569)
- }
- method M3(b: bool) {
- ghost const a
- if (b) { a := 5 }
- assert a < 10 // error (611)
- }
- method M4(b: bool) {
- ghost const a
- if (b) { a := 5 }
- ghost var x := a
- if (!b) { a := 7 }
- assert a < 10
- assert b ==> x == 5 // cool, huh?
- }
- method M5(b: bool) {
- ghost const a
- if (b) { a := 5 }
- assert assigned(a) ==> a == 5
- }
-}
diff --git a/Chalice/tests/general-tests/prog2.output.txt b/Chalice/tests/general-tests/prog2.output.txt
deleted file mode 100644
index da8dcf22..00000000
--- a/Chalice/tests/general-tests/prog2.output.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Verification of prog2.chalice using parameters=""
-
- 24.5: Assertion might not hold. The expression at 24.12 might not evaluate to true.
- 31.13: Location might not be readable.
- 72.5: Const variable can be assigned to only once.
- 77.5: Assertion might not hold. The expression at 77.12 might not evaluate to true.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 20.3: The end of method Caller1 is unreachable.
- 69.3: The end of method M2 is unreachable.
-
-Boogie program verifier finished with 4 errors and 2 smoke test warnings
diff --git a/Chalice/tests/general-tests/prog3.chalice b/Chalice/tests/general-tests/prog3.chalice
deleted file mode 100644
index de5dfad7..00000000
--- a/Chalice/tests/general-tests/prog3.chalice
+++ /dev/null
@@ -1,246 +0,0 @@
-// 4 errors expected
-
-class Main {
- method A() {
- var d := new Data;
- call d.Init();
- share d;
-
- var t0: T := new T; t0.d := d;
- share t0 between waitlevel and d
- var t1: T := new T; t1.d := d;
- share t1 between waitlevel and d
-
- var t0Token: token<T.run>;
- fork t0Token := t0.run();
- var t1Token: token<T.run>;
- fork t1Token := t1.run();
-
- join t0Token; acquire t0; unshare t0;
- join t1Token; acquire t1; unshare t1;
-
- acquire d; unshare d;
- assert 0 <= d.x && d.x < 100;
- }
-
- method B() returns (r: U)
- lockchange r;
- {
- var u := new U;
- share u;
-
- var uToken: token<U.run>;
- fork uToken := u.run();
-
- acquire u; // a little unusual to acquire after a fork, but allowed
- assert waitlevel == u.mu;
-
- var v := new U;
- share v; acquire v; // this line has the effect of increasing waitlevel
-
- assert waitlevel == v.mu;
- assert waitlevel != u.mu;
- assert u << v;
- assert u << waitlevel;
-
- join uToken; // material for the smoke check
- release u;
- r := v;
- }
-
- method C()
- ensures waitlevel == old(waitlevel);
- {
- var u := new U;
- share u;
- acquire u;
- release u;
- }
-
- method Mx0()
- {
- }
- method Mx1()
- lockchange this
- {
- }
- method MxCaller0()
- ensures waitlevel == old(waitlevel);
- {
- }
- method MxCaller1()
- ensures waitlevel == old(waitlevel);
- {
- call Mx0();
- }
- method MxCaller2()
- ensures waitlevel == old(waitlevel); // error
- {
- call Mx1();
- } // error: missing lockchange
-
- method D(u: U)
- requires u != null && rd(u.mu) && waitlevel << u;
- ensures waitlevel == old(waitlevel);
- {
- acquire u;
- release u;
- }
-}
-
-class Data {
- var x: int;
- invariant acc(x) && 0 <= x && x < 100;
- method Init()
- requires acc(x);
- ensures acc(x) && x == 0;
- {
- x := 0;
- }
-}
-
-class T {
- var d: Data;
- invariant rd(d) && d != null && rd(d.mu) && rd(this.mu) && this << d;
- method run()
- requires rd(mu) && waitlevel << this;
- ensures rd(mu);
- {
- acquire this;
- acquire d;
- d.x := d.x + 1;
- if (d.x == 100) { d.x := 0; }
- release d;
- release this;
- }
-}
-
-class U {
- method run()
- requires rd(mu) && waitlevel << this;
- ensures rd(mu);
- {
- }
-}
-
-// Tests that use OLD in postcondition of run:
-
-class X {
- var k: int
- var l: int
-
- method inc()
- requires acc(k)
- ensures acc(k) && k == old(k) + 1
- {
- k := k + 1
- }
- method Client0() returns (y: int)
- ensures y == 8
- {
- var x := new X
- x.k := 17 x.l := 10
- call x.inc()
- assert x.k == 18 && x.l == 10
- y := x.k - x.l
- }
-
- method run()
- requires acc(k) && 0 <= k
- ensures acc(k) && k == old(k) + 1
- {
- k := k + 1
- }
-
- method Client1() returns (y: int)
- ensures y == 8
- {
- var x := new X
- x.k := 17
- x.l := 20
- var xToken: token<X.run>;
- fork xToken := x.run();
- x.l := 10
- join xToken
- assert x.k == 18 && x.l == 10
- y := x.k - x.l
- }
- method Client2(tk: token<X.run>, x: X) returns (z: int)
- requires x!=null && tk!=null && acc(tk.joinable) && tk.joinable && eval(tk.fork x.run(), acc(x.k) && 0<=x.k);
- ensures 1 <= z
- {
- join tk
- z := x.k
- assert 1<=x.k;
- }
-}
-
-class ReadSharing {
- var x: int
-
- method Consume()
- requires rd(x,1)
- {
- // skip
- }
-
- method Divulge() // bad
- requires rd(x,1)
- {
- call Consume()
- call Consume() // error: cannot share twice (1773)
- }
-
- method Communicates() // good
- requires rd(x,3)
- ensures rd(x,1)
- {
- call Consume()
- call Consume()
- }
-
- method Gossips() // bad
- requires rd(x,3)
- ensures rd(x,1)
- {
- call Consume()
- call Consume()
- call Consume()
- } // error: does not live up to postcondition (2015)
-
- method Shares() // good
- requires rd*(x)
- ensures rd*(x)
- {
- call Consume()
- call Consume()
- call Consume()
- }
-
- method TeamPlayer(N: int) // good
- requires 0<N && rd(x,N)
- {
- var n := N
- while (1 < n)
- invariant 0<n && rd(x,n)
- {
- n := n - 1
- }
- }
-
- method Unselfish(N: int) // good
- requires rd*(x)
- ensures rd*(x)
- {
- var n := N
- if (N == 173) {
- call Unselfish(200)
- }
- while (0 < n)
- invariant rd*(x)
- {
- call Consume()
- n := n - 1
- }
- }
-}
diff --git a/Chalice/tests/general-tests/prog3.output.txt b/Chalice/tests/general-tests/prog3.output.txt
deleted file mode 100644
index 286b9248..00000000
--- a/Chalice/tests/general-tests/prog3.output.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Verification of prog3.chalice using parameters=""
-
- 76.3: The postcondition at 77.13 might not hold. The expression at 77.13 might not evaluate to true.
- 76.3: Method might lock/unlock more than allowed.
- 191.5: The precondition at 182.14 might not hold. Insufficient epsilons at 182.14 for ReadSharing.x.
- 202.3: The postcondition at 204.13 might not hold. Insufficient epsilons at 204.13 for ReadSharing.x.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 191.5: The statements after the method call statement are unreachable.
-
-Boogie program verifier finished with 4 errors and 1 smoke test warnings
diff --git a/Chalice/tests/general-tests/prog4.chalice b/Chalice/tests/general-tests/prog4.chalice
deleted file mode 100644
index 3c655c71..00000000
--- a/Chalice/tests/general-tests/prog4.chalice
+++ /dev/null
@@ -1,53 +0,0 @@
-class LoopTargets {
- method M() returns (y) {
- y := 0
- while (y < 100) { y := y + 1 }
- assert y == 0 // error (139)
- }
- method N() returns (t: LoopTargets)
- lockchange t
- {
- t := new LoopTargets
- share t
- acquire t
- var s := true
- while (s)
- lockchange t
- {
- release t // error: loop invariant does not say holds(t) (252)
- s := false
- }
- }
- method P() {
- var t := new LoopTargets
- share t
- acquire t
- var s := true
- while (s)
- invariant acc(t.mu) && waitlevel == t.mu
- lockchange t
- {
- release t // error: loop invariant does not say holds(t) (414)
- acquire t
- s := false
- }
- release t
- }
- method Q() {
- var t := new LoopTargets
- share t
- acquire t
- var s := true
- while (s)
- invariant rd(t.mu)
- invariant holds(t) && waitlevel == t.mu
- lockchange t
- {
- release t
- acquire t
- s := false
- }
- assert holds(t) // there we are
- release t
- }
-}
diff --git a/Chalice/tests/general-tests/prog4.output.txt b/Chalice/tests/general-tests/prog4.output.txt
deleted file mode 100644
index 4ab057dd..00000000
--- a/Chalice/tests/general-tests/prog4.output.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Verification of prog4.chalice using parameters=""
-
- 5.5: Assertion might not hold. The expression at 5.12 might not evaluate to true.
- 17.7: The target of the release statement might not be locked by the current thread.
- 17.7: Release might fail because the current thread might hold the read lock.
- 30.7: The target of the release statement might not be locked by the current thread.
- 30.7: Release might fail because the current thread might hold the read lock.
- 34.5: The target of the release statement might not be locked by the current thread.
- 34.5: Release might fail because the current thread might hold the read lock.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 2.3: The end of method M is unreachable.
-
-Boogie program verifier finished with 7 errors and 1 smoke test warnings
diff --git a/Chalice/tests/general-tests/quantifiers.chalice b/Chalice/tests/general-tests/quantifiers.chalice
deleted file mode 100644
index 7377ca3f..00000000
--- a/Chalice/tests/general-tests/quantifiers.chalice
+++ /dev/null
@@ -1,59 +0,0 @@
-class A {
- var f: int;
-}
-
-class Quantifiers {
- var bamboo: seq<A>;
-
- method test1(a: seq<int>, b: int)
- requires b in a;
- requires b > 0;
- {
- assert exists j in a :: true && j > 0;
- assert exists j:int :: 0 <= j && j < |a| && a[j] > 0;
- assert forall j in a :: exists k in a :: k > 0;
- }
-
- method test2(a: seq<A>)
- requires rd(a[*].*);
- requires |a| > 0;
- requires forall i in a :: i != null && i.f > 0;
- {
- assert a[0].f > 0;
- assert forall j: A :: j in a && j != null ==> j.f > 0;
- assert exists j: A :: j in a && j != null && j.f > 0;
- }
-
- method test3(a: seq<A>)
- requires |a| > 0;
- requires acc(a[*].f);
- {
- var c := new A;
- assert c != a[0];
- }
-}
-
-class Functions {
- var x: int;
- var y: int;
-
- function test1(): int
- requires acc(this.*);
- {
- x + y
- }
-
- function test2(): int
- requires acc(x) && acc(y);
- {
- x + y
- }
-
- function test3(a: seq<A>): int
- requires acc(a[*].f);
- requires forall x in a :: x != null;
- requires forall i,j in [0..|a|] :: i != j ==> a[i] != a[j];
- {
- |a| == 0 ? 0 : a[0].f + test3(a[1..])
- }
-}
diff --git a/Chalice/tests/general-tests/quantifiers.output.txt b/Chalice/tests/general-tests/quantifiers.output.txt
deleted file mode 100644
index f05847b6..00000000
--- a/Chalice/tests/general-tests/quantifiers.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of quantifiers.chalice using parameters=""
-
- 57.29: The heap of the callee might not be strictly smaller than the heap of the caller.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/general-tests/reg_test.bat b/Chalice/tests/general-tests/reg_test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/general-tests/reg_test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/general-tests/reg_test_all.bat b/Chalice/tests/general-tests/reg_test_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/general-tests/reg_test_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/general-tests/test.bat b/Chalice/tests/general-tests/test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/general-tests/test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/general-tests/triggers.chalice b/Chalice/tests/general-tests/triggers.chalice
deleted file mode 100644
index 08a6a7dd..00000000
--- a/Chalice/tests/general-tests/triggers.chalice
+++ /dev/null
@@ -1,81 +0,0 @@
-// this test is for the automatic trigger generation
-
-class Triggers
-{
- var next : Triggers // to allow recursive definitions
-
- predicate valid { acc(next) && next != null && next.valid } // intentionally doesn't terminate - allows function definitions to be unknown
-
- function f(x,y,z : int):bool
- requires valid
- {
- unfolding valid in next.f(x,y,z) // unknown definition
- }
-
- function h(x,y,z : int):bool
- requires valid
- {
- unfolding valid in next.h(x,y,z) // unknown definition
- }
-
- function g(x : int) : bool
- requires valid
- {
- unfolding valid in next.g(x) // unknown definition
- }
-
- function i(x:int, y:bool) : bool
- requires valid
- {
- unfolding valid in next.i(x,y) // unknown definition
- }
-
-
- method triggers_one()
- requires valid
- requires (forall a : int :: !(g(a) ==> false))
- ensures valid
- ensures (forall b : int :: g(b))
- { }
-
- method triggers_two()
- requires valid
- requires (forall a,b,c : int :: ( g(a) && f(a,b,c)))
- ensures valid
- ensures (forall x,y,z : int :: f(x,y,z))
- ensures (forall w : int :: (g(w))) // fails because there isn't a good enough trigger for finding g(w)
- { }
-
- method triggers_three()
- requires valid
- requires (forall a : int :: ( g(a) && (forall b,c : int :: f(a,b,c))))
- ensures valid
- ensures (forall x,y,z : int :: f(x,y,z)) // fails because of the trigger chosen for a (g(a)).
- ensures (forall w : int :: (g(w)))
- { }
-
- method triggers_four()
- requires valid
- requires (forall a,b,c,d,e:int :: f(a,b,c) && h(b,c,d) && f(c,d,e))
- ensures valid
- ensures (forall x,y,z : int :: f(x,y,z)) // fails - not enough triggers
- ensures (forall x,y,z : int :: f(x,y,z) && f(z,y,x)) // succeeds - {f(a,b,c),f(c,d,e)} is one of the trigger sets which should be found
- { }
-
- method triggers_five(c : bool, d : bool)
- requires c ==> d
- requires valid
- requires (forall x : int :: i(x, (c ==> d))) // check that logical operators are suitably avoided in triggers
- ensures valid
- ensures i(4,true)
- { }
-
- method triggers_six(c : int, d : int)
- requires c > d
- requires valid
- requires (forall x : int :: i(x, (c > d))) // check that logical operators are suitably avoided in triggers
- ensures valid
- ensures i(4,true)
- { }
-
-} \ No newline at end of file
diff --git a/Chalice/tests/general-tests/triggers.output.txt b/Chalice/tests/general-tests/triggers.output.txt
deleted file mode 100644
index 3fae3c21..00000000
--- a/Chalice/tests/general-tests/triggers.output.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Verification of triggers.chalice using parameters=""
-
- 41.3: The postcondition at 46.14 might not hold. The expression at 46.14 might not evaluate to true.
- 49.3: The postcondition at 53.14 might not hold. The expression at 53.14 might not evaluate to true.
- 57.3: The postcondition at 61.14 might not hold. The expression at 61.14 might not evaluate to true.
-
-Boogie program verifier finished with 3 errors and 0 smoke test warnings
diff --git a/Chalice/tests/permission-model/basic.chalice b/Chalice/tests/permission-model/basic.chalice
deleted file mode 100644
index 53443a49..00000000
--- a/Chalice/tests/permission-model/basic.chalice
+++ /dev/null
@@ -1,232 +0,0 @@
-class Cell {
- var x: int;
-
- // dispose a read permission to x
- method dispose_rd()
- requires rd(x);
- ensures true;
- {
- }
-
- // return read permission
- method void()
- requires rd(x);
- ensures rd(x);
- {
- }
-
- // multiple calls to method that destroys rd(x)
- method a1()
- requires rd(x);
- ensures true;
- {
- call dispose_rd();
- call dispose_rd();
- }
-
- // call to method that destroys rd(x) really removes permission
- method a2()
- requires rd(x);
- ensures rd(x);
- {
- call dispose_rd();
- // ERROR: should fail to verify postcondition
- }
-
- // forking and method calls of dispose_rd
- method a3()
- requires rd(x);
- ensures true;
- {
- fork dispose_rd();
- call dispose_rd();
- fork dispose_rd();
- call dispose_rd();
- }
-
- // forking and method calls of dispose_rd
- method a4()
- requires rd(x);
- ensures rd(x);
- {
- fork dispose_rd();
- // ERROR: should fail to verify postcondition
- }
-
- // forking and method calls of dispose_rd
- method a5()
- requires rd(x);
- ensures rd(x,1);
- {
- fork dispose_rd();
- // OK: giving away an epsilon permission however should work
- }
-
- // forking and method calls of dispose_rd
- method a6()
- requires rd(x);
- ensures rd*(x);
- {
- fork dispose_rd();
- // OK: giving away a 'undefined' read permission however should work
- }
-
- // multiple forks of dispose_rd
- method a7()
- requires rd(x);
- ensures true;
- {
- fork dispose_rd();
- fork dispose_rd();
- fork dispose_rd();
- fork dispose_rd();
- fork dispose_rd();
- fork dispose_rd();
- }
-
- // joining to regain permission
- method a8(a: int)
- requires rd(x);
- ensures rd(x)
- {
- fork tk := void();
- join tk;
- }
-
- // joining to regain permission
- method a9(a: int)
- requires rd(x);
- ensures rd(x)
- {
- fork tk := dispose_rd();
- join tk;
- // ERROR: should fail to verify postcondition
- }
-
- // joining to regain permission
- method a10(a: int)
- requires rd(x);
- ensures a == 3 ==> rd(x)
- {
- fork tk := void();
- if (3 == a) {
- join tk;
- }
- }
-
- // finite loop of method calls, preserving rd(x)
- method a11()
- requires rd(x);
- ensures rd(x);
- {
- var i: int;
- i := 0;
- while (i < 1000)
- invariant rd(x);
- {
- call void();
- i := i+1;
- }
- }
-
- // forking dispose_rd in a loop (using rd(x,*) to denote unknown read permission)
- method a12(a: int)
- requires rd(x);
- ensures rd*(x);
- {
- var i: int;
- i := 0;
- while (i < a)
- invariant rd*(x);
- {
- fork dispose_rd();
- i := i+1;
- }
- }
-
- // forking dispose_rd in a loop (using rd(x,*) to denote unknown read permission)
- method a13(a: int)
- requires rd(x);
- ensures rd(x);
- {
- var i: int;
- i := 0;
- while (i < a)
- invariant rd*(x);
- {
- fork dispose_rd();
- i := i+1;
- }
- // ERROR: should fail to verify postcondition
- }
-
- // calling dispose_rd in a loop (using rd(x,*) to denote unknown read permission)
- method a14()
- requires rd(x);
- ensures true;
- {
- call dispose_rd();
-
- var i: int;
- i := 0;
- while (i < 1000)
- invariant rd*(x);
- {
- call dispose_rd();
- i := i+1;
- }
- }
-
- // return unknown permission
- method a15()
- requires rd(x);
- ensures rd*(x);
- {
- call dispose_rd();
- }
-
- // rd in loop invariant
- method a16()
- requires rd(x);
- ensures rd*(x);
- {
- call dispose_rd();
-
- var i: int;
- i := 0;
- while (i < 1000)
- invariant acc(x,rd);
- {
- call void();
- i := i+1;
- }
- }
-
- // rd in method contracts
- method a17()
- requires acc(x,rd);
- {
- call dispose_rd();
- call a17();
- }
-
- // multiple rd in method contracts
- method a18()
- requires rd(x);
- ensures rd(x)
- {
- call a18a()
- call a18b()
- }
- method a18a()
- requires acc(x,2*rd);
- ensures acc(x,rd+rd);
- {
- }
- method a18b()
- requires acc(x,rd+rd);
- ensures acc(x,rd*2);
- {
- }
-
-}
diff --git a/Chalice/tests/permission-model/basic.output.txt b/Chalice/tests/permission-model/basic.output.txt
deleted file mode 100644
index b2bf49bd..00000000
--- a/Chalice/tests/permission-model/basic.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of basic.chalice using parameters=""
-
- 28.3: The postcondition at 30.13 might not hold. Insufficient fraction at 30.13 for Cell.x.
- 48.3: The postcondition at 50.13 might not hold. Insufficient fraction at 50.13 for Cell.x.
- 97.3: The postcondition at 99.13 might not hold. Insufficient fraction at 99.13 for Cell.x.
- 148.3: The postcondition at 150.13 might not hold. Insufficient fraction at 150.13 for Cell.x.
-
-Boogie program verifier finished with 4 errors and 0 smoke test warnings
diff --git a/Chalice/tests/permission-model/channels.chalice b/Chalice/tests/permission-model/channels.chalice
deleted file mode 100644
index 6a4961cd..00000000
--- a/Chalice/tests/permission-model/channels.chalice
+++ /dev/null
@@ -1,45 +0,0 @@
-class C {
- var f: int;
-
- method t1(ch: C1)
- requires ch != null && rd(f);
- ensures true;
- {
- send ch(this) // ERROR
- }
-
- method t2(ch: C1)
- requires ch != null && acc(f);
- ensures true;
- {
- send ch(this)
- }
-
- method t3(ch: C2)
- requires ch != null && rd(f);
- ensures rd(f);
- {
- send ch(this)
- // ERROR: should fail to verify postcondition
- }
-
- method t4(ch: C1, a: C) returns (b: C)
- requires ch != null && credit(ch, 1) && rd(ch.mu) && waitlevel << ch;
- ensures rd*(b.f);
- {
- receive b := ch
- }
-
- method t5(ch: C1)
- requires ch != null && acc(f,1);
- ensures true;
- {
- send ch(this)
- send ch(this)
- send ch(this)
- }
-
-}
-
-channel C1(x: C) where rd(x.f);
-channel C2(x: C) where rd*(x.f);
diff --git a/Chalice/tests/permission-model/channels.output.txt b/Chalice/tests/permission-model/channels.output.txt
deleted file mode 100644
index b2f76ab6..00000000
--- a/Chalice/tests/permission-model/channels.output.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Verification of channels.chalice using parameters=""
-
- 8.5: The where clause at 44.24 might not hold. Insufficient fraction at 44.24 for C.f.
- 18.3: The postcondition at 20.13 might not hold. Insufficient fraction at 20.13 for C.f.
-
-Boogie program verifier finished with 2 errors and 0 smoke test warnings
diff --git a/Chalice/tests/permission-model/generate_reference.bat b/Chalice/tests/permission-model/generate_reference.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/permission-model/generate_reference.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/permission-model/generate_reference_all.bat b/Chalice/tests/permission-model/generate_reference_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/permission-model/generate_reference_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/permission-model/locks.chalice b/Chalice/tests/permission-model/locks.chalice
deleted file mode 100644
index 5107fd38..00000000
--- a/Chalice/tests/permission-model/locks.chalice
+++ /dev/null
@@ -1,146 +0,0 @@
-class Cell {
- var x: int;
-
- // use starred read permission
- invariant rd*(x);
-
- method a1(c: Cell)
- requires c != null && rd(c.mu) && waitlevel << c;
- {
- acquire c;
- assert(rd*(c.x));
-
- release c;
- assert(rd*(c.x));
- }
-
- method a2(c: Cell)
- requires c != null && rd(c.mu) && waitlevel << c;
- {
- acquire c;
- assert(rd(c.x)); // ERROR: should fail
-
- release c;
- assert(rd(c.x)); // ERROR: should fail
- }
-
- method a3()
- {
- var c: Cell := new Cell;
-
- share c;
- assert(rd*(c.x));
-
- acquire c;
- unshare c;
- assert(rd*(c.x));
- }
-
- method a4()
- {
- var c: Cell := new Cell;
-
- share c;
- assert(rd(c.x)); // ERROR: should fail
- }
-
- method a5()
- {
- var c: Cell := new Cell;
-
- share c;
- acquire c;
- unshare c;
- assert(rd(c.x)); // ERROR: should fail
- }
-
-}
-
-
-class Cell2 {
- var x: int;
-
- // use normal fractional permission
- invariant rd(x);
-
- method a1(c: Cell2)
- requires c != null && rd(c.mu) && waitlevel << c;
- {
- acquire c;
- assert(rd*(c.x));
-
- release c;
- assert(rd*(c.x)); // ERROR: we gave away all permission
- }
-
- method a2(c: Cell2)
- requires c != null && rd(c.mu) && waitlevel << c;
- {
- acquire c;
- assert(rd(c.x)); // ERROR: should fail
-
- release c;
- assert(rd(c.x)); // ERROR: should fail
- }
-
- method a3()
- {
- var c: Cell2 := new Cell2;
-
- share c;
- assert(rd*(c.x));
-
- call void(c);
- assert(rd*(c.x));
-
- call dispose(c);
- assert(rd*(c.x));
-
- acquire c;
- unshare c;
- assert(rd*(c.x));
-
- assert(acc(c.x)); // ERROR: should fail
- }
-
- method a4(c: Cell2)
- requires c != null && acc(c.mu) && holds(c);
- requires rd(c.x);
- lockchange c
- {
- release c; // ERROR: should fail, we don't have enough permission
- }
-
- method a5()
- {
- var c: Cell2 := new Cell2;
-
- share c;
- acquire c;
- assert(acc(c.x));
-
- unshare c;
- assert(acc(c.x));
- }
-
- method a6(c: Cell2)
- requires acc(c.x,rd(c)) && acc(c.mu) && c.mu == lockbottom
- {
- var n: int;
-
- share c;
- rd acquire c;
- n := c.x
- rd release c;
-
- n := c.x // ERROR: no read access possible
-
- acquire c;
- unshare c;
- }
-
- method void(c: Cell2) requires rd(c.x); ensures rd(c.x); {}
-
- method dispose(c: Cell2) requires rd(c.x); {}
-
-}
diff --git a/Chalice/tests/permission-model/locks.output.txt b/Chalice/tests/permission-model/locks.output.txt
deleted file mode 100644
index 6b3a7abe..00000000
--- a/Chalice/tests/permission-model/locks.output.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Verification of locks.chalice using parameters=""
-
- 21.5: Assertion might not hold. Insufficient fraction at 21.12 for Cell.x.
- 24.5: Assertion might not hold. Insufficient fraction at 24.12 for Cell.x.
- 44.5: Assertion might not hold. Insufficient fraction at 44.12 for Cell.x.
- 54.5: Assertion might not hold. Insufficient fraction at 54.12 for Cell.x.
- 73.5: Assertion might not hold. Insufficient fraction at 73.12 for Cell2.x.
- 80.5: Assertion might not hold. Insufficient fraction at 80.12 for Cell2.x.
- 83.5: Assertion might not hold. Insufficient fraction at 83.12 for Cell2.x.
- 103.5: Assertion might not hold. Insufficient fraction at 103.12 for Cell2.x.
- 111.5: Monitor invariant might hot hold. Insufficient fraction at 64.13 for Cell2.x.
- 136.10: Location might not be readable.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 66.3: The end of method a1 is unreachable.
- 76.3: The end of method a2 is unreachable.
- 86.3: The end of method a3 is unreachable.
- 138.5: The statements after the acquire statement are unreachable.
-
-Boogie program verifier finished with 10 errors and 4 smoke test warnings
diff --git a/Chalice/tests/permission-model/peculiar.chalice b/Chalice/tests/permission-model/peculiar.chalice
deleted file mode 100644
index 31c4d259..00000000
--- a/Chalice/tests/permission-model/peculiar.chalice
+++ /dev/null
@@ -1,55 +0,0 @@
-class Cell {
- var x: int;
-
- invariant rd(x);
-
- method t1()
- requires acc(x);
- ensures rd(x) && rd(x);
- {
- }
-
- method t2()
- requires acc(x,1);
- ensures rd(x);
- {
- call void();
- }
-
- method t3()
- requires rd(x);
- {
- call t3helper();
- }
-
- method t3helper()
- requires rd(x) && rd(x);
- ensures rd(x) && rd(x);
- {}
-
- method t4()
- requires rd(x);
- {
- call dispose();
- call void(); // call succeeds, even though the precondition is also rd(x), and the next assertion fails
- assert(rd(x)); // ERROR: fails, as this check is done exactly (as it would in a postcondition)
- }
-
- method t5(n: int)
- requires acc(x);
- {
- var i: int := 0;
- call req99();
- while (i < n)
- invariant rd*(x);
- {
- call dispose();
- i := i+1
- }
- }
-
- method dispose() requires rd(x); {}
- method void() requires rd(x); ensures rd(x); {}
- method req99() requires acc(x,99); {}
-
-}
diff --git a/Chalice/tests/permission-model/peculiar.output.txt b/Chalice/tests/permission-model/peculiar.output.txt
deleted file mode 100644
index 07104e77..00000000
--- a/Chalice/tests/permission-model/peculiar.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of peculiar.chalice using parameters=""
-
- 35.5: Assertion might not hold. Insufficient fraction at 35.12 for Cell.x.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 30.3: The end of method t4 is unreachable.
-
-Boogie program verifier finished with 1 errors and 1 smoke test warnings
diff --git a/Chalice/tests/permission-model/permarith_parser.chalice b/Chalice/tests/permission-model/permarith_parser.chalice
deleted file mode 100644
index 5b011d79..00000000
--- a/Chalice/tests/permission-model/permarith_parser.chalice
+++ /dev/null
@@ -1,37 +0,0 @@
-class Cell {
- var x: int;
- var y: Cell;
-
- method a1()
- requires acc(x,y); // ERROR: amount is not integer
- {
- }
-
- method a2()
- requires acc(x,n); // ERROR: unknown variable
- {
- }
-
- method a3()
- requires acc(x,rd(rd(1))); // ERROR: invalid permission expression
- {
- }
-
- method a4()
- requires acc(x,rd*(y)); // ERROR: invalid permission expression
- {
- }
-
- method a5()
- requires acc(x,rd(this.mu)); // ERROR: invalid type inside rd
- requires acc(x,rd(null)); // ERROR: invalid type inside rd
- requires acc(x,rd(true)); // ERROR: invalid type inside rd
- {
- }
-
- method a6()
- requires acc(x,rd(x)*rd(x)); // ERROR: permission multiplication not allowed
- {
- }
-
-}
diff --git a/Chalice/tests/permission-model/permarith_parser.output.txt b/Chalice/tests/permission-model/permarith_parser.output.txt
deleted file mode 100644
index bc6598a1..00000000
--- a/Chalice/tests/permission-model/permarith_parser.output.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Verification of permarith_parser.chalice using parameters=""
-
-The program did not typecheck.
-6.14: fraction in permission must be of type integer
-11.20: undeclared member n in class Cell
-16.26: permission not expected here.
-16.26: type $Permission is not supported inside a rd expression.
-21.20: rd expression is allowed only in positive predicate contexts
-21.14: expression of type bool invalid in permission
-26.20: type $Mu of variable mu is not supported inside a rd expression.
-27.23: type null is not supported inside a rd expression.
-28.23: type bool is not supported inside a rd expression.
-33.14: multiplication of permission amounts not supported
diff --git a/Chalice/tests/permission-model/permission_arithmetic.chalice b/Chalice/tests/permission-model/permission_arithmetic.chalice
deleted file mode 100644
index 0cdf8aae..00000000
--- a/Chalice/tests/permission-model/permission_arithmetic.chalice
+++ /dev/null
@@ -1,246 +0,0 @@
-class Cell {
- var x: int;
- var i: int;
- var y: Cell;
- var f: int;
- var g: int;
-
- invariant rd(x);
-
- predicate valid { rd(x) }
-
- method a1(n: int) // test various arithmetic operations on permissions
- requires acc(x,1+1) && acc(x,1) && acc(x,3) && acc(x,1-rd(5-7)+rd(3)) && rd(x) && rd(this.y);
- ensures acc(x,100-97);
- {
- }
-
- method a2(n: int)
- requires acc(x,1-rd(1)-2);
- {
- assert false; // this should verify, as the precondition contains an invalid permission
- }
-
- method a3(n: int)
- {
- assert acc(x,1-rd(1)-2); // ERROR: invalid (negative) permission
- }
-
- method a4(n: int)
- requires acc(x,rd(n));
- {
- }
-
- method a5(n: int)
- requires acc(x,rd(n)-rd(2));
- {
- }
-
- method a6()
- requires acc(x);
- {
- call a5(1); // ERROR: n=1 makes the permission in the precondition negative
- }
-
- method a7(c: Cell)
- requires acc(c.x,100-rd(c));
- requires c != null && acc(c.mu) && waitlevel << c;
- ensures acc(c.x);
- {
- acquire(c);
- unshare(c);
- }
-
- method a8()
- requires acc(x,100-rd(valid)) && valid;
- ensures acc(x);
- {
- unfold valid;
- }
-
- method a9()
- requires acc(x,rd(valid));
- ensures valid;
- {
- fold valid;
- }
-
- method a10()
- requires valid;
- ensures acc(x,rd(valid));
- {
- unfold valid;
- }
-
- method a11() // ERROR: postcondition does not hold (not enough permission)
- requires valid;
- ensures acc(x);
- {
- unfold valid;
- }
-
- method a12()
- requires rd(this.i) && this.i > 0 && acc(x,rd(this.i));
- ensures rd(this.i) && this.i > 0 && acc(x,rd(i));
- {
- }
-
- method a13(i: int) // ERROR: postcondition does not hold
- requires rd(this.i) && this.i > 0 && i > 0 && acc(x,rd(this.i));
- ensures i > 0 && acc(x,rd(i));
- {
- }
-
- method a14()
- requires acc(y) && this.y == this; // test aliasing
- requires acc(x,100-rd(y));
- requires y != null && acc(this.mu) && waitlevel << this;
- ensures acc(x);
- lockchange this;
- {
- acquire this;
- }
-
- method a15()
- requires acc(x,rd(this.i)); // ERROR: this.i is not readable
- ensures acc(x,rd(this.i));
- {
- }
-
- method a16()
- requires acc(x,rd(this.y)); // ERROR: this.y is not readable
- ensures acc(x,rd(this.y));
- {
- }
-
- method a17(tk: token<Cell.void>)
- requires acc(x,100-rd(tk)) && acc(tk.joinable) && tk.joinable;
- requires eval(tk.fork this.void(),true);
- ensures acc(x);
- {
- join tk;
- }
-
- method a18()
- requires acc(x,rd+rd-rd+10*rd-rd*(5+5))
- ensures rd(x)
- {
- call void();
- }
-
- method a19()
- requires acc(x)
- requires acc(this.mu) && lockbottom == this.mu
- ensures acc(x)
- lockchange this;
- {
- share this;
- acquire this;
- unshare this;
- }
-
- method a20()
- requires rd(x)
- requires acc(this.mu) && lockbottom == this.mu
- lockchange this;
- {
- share this; // ERROR: not enough permission
- }
-
- method a21()
- requires acc(x,rd*2)
- ensures rd(x) && rd(x)
- {
- assert acc(x,rd+rd)
- assert acc(x,(1+1)*rd)
- }
-
- method a22()
- requires acc(x,1*2*5)
- ensures acc(x,10)
- {
- }
-
- method a23(c: Cell) // ERROR: permission in postcondition not positive
- requires acc(x,rd-rd(c))
- ensures acc(x,rd(c)-rd)
- {
- }
-
- method a24()
- requires rd*(x)
- requires rd*(x)
- {
- }
-
- method a25() // ERROR: postcondition does not hold, possibly not enough permission
- requires rd*(x)
- ensures acc(x,rd)
- {
- }
-
- // interaction of monitors and predicates
- method a26()
- requires acc(x,rd(this))
- requires acc(mu) && lockbottom == this.mu
- ensures valid
- lockchange this
- {
- share this
- acquire this
- fold valid
- }
-
- method a27()
- requires acc(f,100-rd) && acc(f,rd)
- {
- assert acc(f) // ok, we have full access
- }
-
- method a28()
- requires acc(f)
- {
- call a27();
- var x: int
- x := f // ERROR: no permission left
- }
-
- method a27b()
- requires acc(f,100-rd)
- requires acc(f,rd)
- {
- assert acc(f) // ok, we have full access
- }
-
- method a28b()
- requires acc(f)
- {
- call a27b();
- var x: int
- x := f // ERROR: no permission left
- }
-
- method a29()
- requires acc(f, 100-rd) && acc(g, rd)
- { }
-
- method a30()
- requires acc(f, 100) && acc(g, rd)
- {
- call a29();
- var tmp: int := this.g;
- }
-
- method a31(c: Cell)
- requires acc(f, 100-rd) && acc(c.f, rd)
- { }
-
- method a32(c: Cell)
- requires acc(f, 100) && acc(c.f, rd)
- {
- call a31(c);
- var tmp: int := this.f;
- }
-
- method void() requires rd(x); ensures rd(x); {}
-}
diff --git a/Chalice/tests/permission-model/permission_arithmetic.output.txt b/Chalice/tests/permission-model/permission_arithmetic.output.txt
deleted file mode 100644
index b9d20e08..00000000
--- a/Chalice/tests/permission-model/permission_arithmetic.output.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Verification of permission_arithmetic.chalice using parameters=""
-
- 26.5: Assertion might not hold. The permission at 26.12 might not be positive.
- 42.5: The precondition at 35.14 might not hold. The permission at 35.14 might not be positive.
- 75.3: The postcondition at 77.13 might not hold. Insufficient fraction at 77.13 for Cell.x.
- 88.3: The postcondition at 90.13 might not hold. Insufficient epsilons at 90.22 for Cell.x.
- 105.20: Location might not be readable.
- 111.20: Location might not be readable.
- 147.5: Monitor invariant might not hold. Insufficient fraction at 8.13 for Cell.x.
- 164.3: The postcondition at 166.13 might not hold. The permission at 166.13 might not be positive.
- 176.3: The postcondition at 178.13 might not hold. Insufficient fraction at 178.13 for Cell.x.
- 205.10: Location might not be readable.
- 220.10: Location might not be readable.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 18.3: Precondition of method a2 is equivalent to false.
- 24.3: The end of method a3 is unreachable.
- 42.5: The statements after the method call statement are unreachable.
- 200.3: The end of method a28 is unreachable.
- 215.3: The end of method a28b is unreachable.
-
-Boogie program verifier finished with 11 errors and 5 smoke test warnings
diff --git a/Chalice/tests/permission-model/predicate_error1.chalice b/Chalice/tests/permission-model/predicate_error1.chalice
deleted file mode 100644
index 0726e349..00000000
--- a/Chalice/tests/permission-model/predicate_error1.chalice
+++ /dev/null
@@ -1,20 +0,0 @@
-class Cell {
- var x: int;
-
- // --- some predicates ---
-
- predicate write1 { acc(x) } // full permission in a predicate
- predicate write2 { acc(x,10) } // 10%
- predicate read1 { rd(x) } // fractional read permission
- predicate read2 { rd*(x) } // starred fractional read permission
- predicate read3 { rd(x,1) } // counting permission (1 epsilon)
-
- // --- invalid permission scaling ---
-
- method error()
- requires rd(read3);
- {
- unfold rd(read3); // ERROR: scaling epsilons is not possible
- }
-
-}
diff --git a/Chalice/tests/permission-model/predicate_error1.output.txt b/Chalice/tests/permission-model/predicate_error1.output.txt
deleted file mode 100644
index a5e27bac..00000000
--- a/Chalice/tests/permission-model/predicate_error1.output.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Verification of predicate_error1.chalice using parameters=""
-
-Error: Not supported: 17.5: Scaling epsilon permissions with non-full permissions is not possible.
diff --git a/Chalice/tests/permission-model/predicate_error2.chalice b/Chalice/tests/permission-model/predicate_error2.chalice
deleted file mode 100644
index cc8d7d28..00000000
--- a/Chalice/tests/permission-model/predicate_error2.chalice
+++ /dev/null
@@ -1,20 +0,0 @@
-class Cell {
- var x: int;
-
- // --- some predicates ---
-
- predicate write1 { acc(x) } // full permission in a predicate
- predicate write2 { acc(x,10) } // 10%
- predicate read1 { rd(x) } // fractional read permission
- predicate read2 { rd*(x) } // starred fractional read permission
- predicate read3 { rd(x,1) } // counting permission (1 epsilon)
-
- // --- invalid permission scaling ---
-
- method error()
- requires rd(read1,1);
- {
- unfold rd(read1,1); // ERROR: scaling epsilons is not possible
- }
-
-}
diff --git a/Chalice/tests/permission-model/predicate_error2.output.txt b/Chalice/tests/permission-model/predicate_error2.output.txt
deleted file mode 100644
index fb660013..00000000
--- a/Chalice/tests/permission-model/predicate_error2.output.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Verification of predicate_error2.chalice using parameters=""
-
-Error: Not supported: 17.5: Scaling epsilon permissions with non-full permissions is not possible.
diff --git a/Chalice/tests/permission-model/predicate_error3.chalice b/Chalice/tests/permission-model/predicate_error3.chalice
deleted file mode 100644
index eb1d8777..00000000
--- a/Chalice/tests/permission-model/predicate_error3.chalice
+++ /dev/null
@@ -1,20 +0,0 @@
-class Cell {
- var x: int;
-
- // --- some predicates ---
-
- predicate write1 { acc(x) } // full permission in a predicate
- predicate write2 { acc(x,10) } // 10%
- predicate read1 { rd(x) } // fractional read permission
- predicate read2 { rd*(x) } // starred fractional read permission
- predicate read3 { rd(x,1) } // counting permission (1 epsilon)
-
- // --- invalid permission scaling ---
-
- method error()
- requires rd(read3,1);
- {
- unfold rd(read3,1); // ERROR: scaling epsilons is not possible
- }
-
-}
diff --git a/Chalice/tests/permission-model/predicate_error3.output.txt b/Chalice/tests/permission-model/predicate_error3.output.txt
deleted file mode 100644
index 9f5b503c..00000000
--- a/Chalice/tests/permission-model/predicate_error3.output.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Verification of predicate_error3.chalice using parameters=""
-
-Error: Not supported: 17.5: Scaling epsilon permissions with non-full permissions is not possible.
diff --git a/Chalice/tests/permission-model/predicate_error4.chalice b/Chalice/tests/permission-model/predicate_error4.chalice
deleted file mode 100644
index 0726e349..00000000
--- a/Chalice/tests/permission-model/predicate_error4.chalice
+++ /dev/null
@@ -1,20 +0,0 @@
-class Cell {
- var x: int;
-
- // --- some predicates ---
-
- predicate write1 { acc(x) } // full permission in a predicate
- predicate write2 { acc(x,10) } // 10%
- predicate read1 { rd(x) } // fractional read permission
- predicate read2 { rd*(x) } // starred fractional read permission
- predicate read3 { rd(x,1) } // counting permission (1 epsilon)
-
- // --- invalid permission scaling ---
-
- method error()
- requires rd(read3);
- {
- unfold rd(read3); // ERROR: scaling epsilons is not possible
- }
-
-}
diff --git a/Chalice/tests/permission-model/predicate_error4.output.txt b/Chalice/tests/permission-model/predicate_error4.output.txt
deleted file mode 100644
index 16da656f..00000000
--- a/Chalice/tests/permission-model/predicate_error4.output.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Verification of predicate_error4.chalice using parameters=""
-
-Error: Not supported: 17.5: Scaling epsilon permissions with non-full permissions is not possible.
diff --git a/Chalice/tests/permission-model/predicates.chalice b/Chalice/tests/permission-model/predicates.chalice
deleted file mode 100644
index 1f752fda..00000000
--- a/Chalice/tests/permission-model/predicates.chalice
+++ /dev/null
@@ -1,103 +0,0 @@
-class Cell {
- var x: int;
-
- // --- some predicates ---
-
- predicate write1 { acc(x) } // full permission in a predicate
- predicate write2 { acc(x,10) } // 10%
- predicate read1 { rd(x) } // fractional read permission
- predicate read2 { rd*(x) } // starred fractional read permission
- predicate read3 { rd(x,1) } // counting permission (1 epsilon)
-
- // --- basic tests ---
-
- method b1()
- requires write1 && write2 && read1 && read2 && read3;
- ensures write1 && write2 && read1 && read2 && read3;
- {
- }
-
- method b2()
- requires write1;
- ensures read1;
- {
- unfold write1;
- fold read1;
- }
-
- method b3()
- requires read1;
- ensures read3;
- {
- unfold read1;
- fold read3;
- fold read2;
- fold read3;
- fold read2;
- fold write1; // ERROR: should fail
- }
-
- method b4()
- requires read2;
- ensures read2;
- {
- unfold read2;
- call dispose();
- fold read2;
- }
-
- method b5()
- requires read1;
- ensures read1;
- {
- unfold read1;
- call dispose();
- fold read1; // ERROR: should fail
- }
-
- method b6()
- requires acc(x);
- ensures acc(x);
- {
- fold read1;
- unfold read1;
- }
-
- method b7() // ERROR: precondition does not hold
- requires acc(x);
- ensures acc(x);
- {
- fold read2;
- unfold read2;
- }
-
- method b8()
- requires acc(x);
- ensures acc(x);
- {
- fold read3;
- unfold read3;
- }
-
- method b9()
- requires acc(x);
- ensures acc(x);
- {
- fold write1;
- unfold write1;
- }
-
- method b10()
- requires acc(x);
- ensures acc(x);
- {
- fold write2;
- unfold write2;
- }
-
- // --- helper functions ---
-
- method void() requires rd(x); ensures rd(x); {}
- method dispose() requires rd(x); {}
-
-}
diff --git a/Chalice/tests/permission-model/predicates.output.txt b/Chalice/tests/permission-model/predicates.output.txt
deleted file mode 100644
index 2f4acf7b..00000000
--- a/Chalice/tests/permission-model/predicates.output.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Verification of predicates.chalice using parameters=""
-
- 37.5: Fold might fail because the definition of Cell.write1 does not hold. Insufficient fraction at 6.22 for Cell.x.
- 55.5: Fold might fail because the definition of Cell.read1 does not hold. Insufficient fraction at 8.21 for Cell.x.
- 66.3: The postcondition at 68.13 might not hold. Insufficient fraction at 68.13 for Cell.x.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 28.3: The end of method b3 is unreachable.
- 49.3: The end of method b5 is unreachable.
-
-Boogie program verifier finished with 3 errors and 2 smoke test warnings
diff --git a/Chalice/tests/permission-model/reg_test.bat b/Chalice/tests/permission-model/reg_test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/permission-model/reg_test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/permission-model/reg_test_all.bat b/Chalice/tests/permission-model/reg_test_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/permission-model/reg_test_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/permission-model/scaling.chalice b/Chalice/tests/permission-model/scaling.chalice
deleted file mode 100644
index ffe9aac1..00000000
--- a/Chalice/tests/permission-model/scaling.chalice
+++ /dev/null
@@ -1,76 +0,0 @@
-
-class Cell {
- var x: int;
-
- // --- some predicates ---
-
- predicate write1 { acc(x) } // full permission in a predicate
- predicate write2 { acc(x,10) } // 10%
- predicate read1 { rd(x) } // abstract read permission
- predicate read2 { rd*(x) } // starred read permission
- predicate read3 { rd(x,1) } // counting permission (1 epsilon)
-
- // --- permission scaling ---
-
- method s1()
- requires rd(read1);
- {
- unfold rd(read1);
- assert(rd*(x));
- assert(rd(x)); // ERROR: should fail
- }
-
- method s2() // INCOMPLETNESS: postcondition should hold, but fails at the moment
- requires rd(read1);
- ensures rd(read1);
- {
- unfold rd(read1);
- fold rd(read1);
- }
-
- method s3()
- requires acc(x);
- ensures rd(read1);
- {
- fold rd(read1);
- assert(rd*(x));
- assert(acc(x)); // ERROR: should fail
- }
-
- method s4() // ERROR: postcondition does not hold
- requires acc(x);
- ensures read1;
- {
- fold rd(read1);
- }
-
- method s5()
- requires rd(read2);
- {
- unfold rd(read2);
- assert(rd*(x));
- assert(rd(x)); // ERROR: should fail
- }
-
- method s6()
- requires acc(x);
- ensures rd(read2);
- {
- fold rd(read2);
- assert(rd*(x));
- assert(acc(x)); // ERROR: should fail
- }
-
- method s7() // ERROR: postcondition does not hold
- requires acc(x);
- ensures read2;
- {
- fold rd(read2);
- }
-
- // --- helper functions ---
-
- method void() requires rd(x); ensures rd(x); {}
- method dispose() requires rd(x); {}
-
-}
diff --git a/Chalice/tests/permission-model/scaling.output.txt b/Chalice/tests/permission-model/scaling.output.txt
deleted file mode 100644
index 2ba1640a..00000000
--- a/Chalice/tests/permission-model/scaling.output.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Verification of scaling.chalice using parameters=""
-
- 20.5: Assertion might not hold. Insufficient fraction at 20.12 for Cell.x.
- 23.3: The postcondition at 25.13 might not hold. Insufficient fraction at 25.13 for Cell.read1.
- 37.5: Assertion might not hold. Insufficient fraction at 37.12 for Cell.x.
- 40.3: The postcondition at 42.13 might not hold. Insufficient fraction at 42.13 for Cell.read1.
- 52.5: Assertion might not hold. Insufficient fraction at 52.12 for Cell.x.
- 61.5: Assertion might not hold. Insufficient fraction at 61.12 for Cell.x.
- 64.3: The postcondition at 66.13 might not hold. Insufficient fraction at 66.13 for Cell.read2.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 15.3: The end of method s1 is unreachable.
- 31.3: The end of method s3 is unreachable.
- 55.3: The end of method s6 is unreachable.
-
-Boogie program verifier finished with 7 errors and 3 smoke test warnings
diff --git a/Chalice/tests/permission-model/sequences.chalice b/Chalice/tests/permission-model/sequences.chalice
deleted file mode 100644
index 0560945d..00000000
--- a/Chalice/tests/permission-model/sequences.chalice
+++ /dev/null
@@ -1,85 +0,0 @@
-class Program {
- var x: int;
-
- method a(a: seq<A>)
- requires |a| > 2;
- requires rd(a[*].f);
- requires forall i in [0..|a|-1] :: a[i] != null;
- requires a[0].f == 1;
- ensures rd(a[*].f);
- {
- assert rd(a[*].f);
- call b(a);
- }
-
- method b(a: seq<A>)
- requires |a| > 2;
- requires rd(a[*].f);
- requires forall i in [0..|a|-1] :: a[i] != null;
- requires a[0].f == 1;
- ensures rd(a[*].f);
- {
- assert rd(a[*].f);
- }
-
- method c(a: seq<A>)
- requires |a| > 2;
- requires rd(a[*].f);
- requires forall i in [0..|a|-1] :: a[i] != null;
- requires a[0].f == 1;
- ensures rd(a[*].f);
- {
- call void(a[1]);
- call void(a[0]);
- }
-
- method c1(a: seq<A>) // ERROR: should fail to verify postcondition
- requires |a| > 2;
- requires rd(a[*].f);
- requires forall i in [0..|a|-1] :: a[i] != null;
- requires a[0].f == 1;
- ensures rd(a[*].f);
- {
- call dispose(a[1]);
- }
-
- method d(a: seq<A>)
- requires |a| > 2;
- requires rd(a[*].f);
- requires forall i in [0..|a|-1] :: a[i] != null;
- requires a[0].f == 1;
- ensures rd*(a[*].f);
- {
- call dispose(a[1]); // we don't give away all the permission, thus verification succeeds
-
- var x: int;
- call x := some_number();
- call dispose(a[x]); // slighly more interesting, but still clearly ok
- }
-
- method e(a: seq<A>) // ERROR: should fail to verify postcondition
- requires |a| > 2;
- requires acc(a[*].f,10);
- requires forall i in [0..|a|-1] :: a[i] != null;
- requires a[0].f == 1;
- ensures rd*(a[*].f);
- {
- var x: int;
- call x := some_number();
- call dispose2(a[x]);
- }
-
- method some_number() returns (a: int)
- ensures 0 <= a && a < 3;
- {
- a := 1;
- }
-
- method dispose(a: A) requires rd(a.f); {}
- method dispose2(a: A) requires acc(a.f,10); {}
- method void(a: A) requires rd(a.f); ensures rd(a.f); {}
-}
-
-class A {
- var f: int;
-}
diff --git a/Chalice/tests/permission-model/sequences.output.txt b/Chalice/tests/permission-model/sequences.output.txt
deleted file mode 100644
index 7c295c9d..00000000
--- a/Chalice/tests/permission-model/sequences.output.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Verification of sequences.chalice using parameters=""
-
- 36.3: The postcondition at 41.13 might not hold. Insufficient permission at 41.13 for A.f
- 60.3: The postcondition at 65.13 might not hold. Insufficient permission at 65.13 for A.f
-
-Boogie program verifier finished with 2 errors and 0 smoke test warnings
diff --git a/Chalice/tests/permission-model/test.bat b/Chalice/tests/permission-model/test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/permission-model/test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/predicates/FoldUnfoldExperiments.chalice b/Chalice/tests/predicates/FoldUnfoldExperiments.chalice
deleted file mode 100644
index 4bead442..00000000
--- a/Chalice/tests/predicates/FoldUnfoldExperiments.chalice
+++ /dev/null
@@ -1,32 +0,0 @@
-class FoldUnfoldExperiments
-{
- var x:int;
- var y:int;
- predicate X { acc(x) }
- predicate Y { acc(y) }
-
- function getX():int
- requires X;
- { unfolding X in x }
-
- function getY():int
- requires Y;
- { unfolding Y in y }
-
- method setX(v:int)
- requires X;
- ensures X && getX()==v;
- {
- unfold X; x:=v; fold X;
- }
-
- method check()
- requires acc(x) && acc(y);
- ensures acc(y) && y==2 && X && getX()==3;
- {
- x:=1; y:=2;
- fold X; fold Y;
- call setX(3);
- unfold Y;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/FoldUnfoldExperiments.output.txt b/Chalice/tests/predicates/FoldUnfoldExperiments.output.txt
deleted file mode 100644
index ba48d6f4..00000000
--- a/Chalice/tests/predicates/FoldUnfoldExperiments.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of FoldUnfoldExperiments.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/LinkedList-various.chalice b/Chalice/tests/predicates/LinkedList-various.chalice
deleted file mode 100644
index a888b647..00000000
--- a/Chalice/tests/predicates/LinkedList-various.chalice
+++ /dev/null
@@ -1,176 +0,0 @@
-class Node
-{
- var v:int;
- var n:Node;
-
- predicate inv
- { acc(v) && acc(n) && (n!=null ==> n.inv) }
-
- function len():int
- requires inv;
- ensures result>0;
- {
- unfolding inv in (n==null) ? 1 : 1+n.len()
- }
-
- function get(i:int):int
- requires inv && 0<=i && i<len();
- {
- unfolding inv in (i==0) ? v : n.get(i-1)
- }
-
- method addLast(x:int)
- requires inv;
- ensures inv;
- ensures len()==old(len())+1 && get(old(len()))==x;
- ensures (forall i:int :: 0<=i && i<old(len()) ==> get(i)==old(get(i)));
- {
- unfold inv;
- if(n==null)
- {
- n:=new Node;
- n.v:=x; n.n:=null;
- fold n.inv;
- }
- else
- {
- call n.addLast(x);
- }
- fold inv;
- }
-
- method append(p:List)
- requires inv && p!=null && p.inv;
- ensures inv;
- ensures len()==old(len()+p.len());
- ensures (forall i in [0..old(len())] :: get(i)==old(get(i)));
- ensures (forall i in [old(len())..len()] :: get(i)==old(p.get(i-len())));
- {
- unfold inv;
- if(n==null)
- {
- unfold p.inv;
- n:=p.c;
- }
- else
- {
- call n.append(p);
- }
- fold inv;
- }
-
- method remove(i:int)
- requires inv && i>=0 && i<len()-1;
- ensures inv;
- ensures len()==old(len())-1;
- ensures (forall j in [0..i+1] :: get(j)==old(get(j)));
- ensures (forall j in [i+1..len()] :: get(j)==old(get(j+1)));
- {
- unfold inv;
- if(i==0)
- {
- unfold n.inv;
- n:=n.n;
- }
- else
- {
- call n.remove(i-1);
- }
- fold inv;
- }
-}
-
-class List
-{
- var c:Node;
-
- predicate inv { acc(c) && (c!=null ==> c.inv) }
-
- function len():int
- requires inv;
- ensures result>=0;
- {
- unfolding inv in (c==null) ? 0 : c.len()
- }
-
- function get(i:int):int
- requires inv && 0<=i && i<len();
- {
- unfolding inv in c.get(i)
- }
-
- method addFirst(x:int)
- requires inv;
- ensures inv;
- ensures len()==old(len())+1 && get(0)==x;
- ensures (forall i:int :: 1<=i && i<len() ==> get(i)==old(get(i-1)));
- {
- var p:Node;
-
- unfold inv;
- p:=new Node; p.v:=x; p.n:=c; c:=p;
- fold c.inv;
- assert c.len()==old(len())+1
- fold inv;
- }
-
- method addLast(x:int)
- requires inv;
- ensures inv;
- ensures len()==old(len())+1 && get(old(len()))==x;
- ensures (forall i:int :: 0<=i && i<old(len()) ==> get(i)==old(get(i)));
- {
- unfold inv;
- if(c==null)
- {
- c:=new Node;
- c.v:=x; c.n:=null;
- fold c.inv;
- }
- else
- {
- call c.addLast(x);
- }
- fold inv;
- }
-
- method append(p:List)
- requires inv && p!=null && p.inv;
- ensures inv;
- ensures len()==old(len()+p.len());
- ensures (forall i in [0..old(len())] :: get(i)==old(get(i)));
- ensures (forall i in [old(len())..len()] :: get(i)==old(p.get(i-len())));
- {
- unfold inv;
- if(c==null)
- {
- unfold p.inv;
- c:=p.c;
- }
- else
- {
- call c.append(p);
- }
- fold inv;
- }
-
- method remove(i:int)
- requires inv && i>=0 && i<len();
- ensures inv;
- ensures len()==old(len())-1;
- ensures (forall j in [0..i] :: get(j)==old(get(j)));
- ensures (forall j in [i..len()] :: get(j)==old(get(j+1)));
- {
- unfold inv;
- if(i==0)
- {
- unfold c.inv;
- c:=c.n;
- }
- else
- {
- call c.remove(i-1);
- }
- fold inv;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/LinkedList-various.output.txt b/Chalice/tests/predicates/LinkedList-various.output.txt
deleted file mode 100644
index a8a90bb8..00000000
--- a/Chalice/tests/predicates/LinkedList-various.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of LinkedList-various.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/aux-info.chalice b/Chalice/tests/predicates/aux-info.chalice
deleted file mode 100644
index f457c481..00000000
--- a/Chalice/tests/predicates/aux-info.chalice
+++ /dev/null
@@ -1,33 +0,0 @@
-class Cell {
- var value: int;
-
- predicate p { acc(value,1) }
-
- method test()
- requires p && acc(value,2)
- {
- // previously, the following sequence let to negative secondary permission
- // to the field value.
- fold p
- fold p
- call void()
- call void()
- call void2()
-
- unfold p
- var tmp: int := value
- fold p
- // make sure that at this point we can retain information about the field value
- assert tmp == unfolding p in value
- }
-
- method void()
- requires p
- {}
-
- method void2()
- requires p
- ensures p
- {}
-
-}
diff --git a/Chalice/tests/predicates/aux-info.output.txt b/Chalice/tests/predicates/aux-info.output.txt
deleted file mode 100644
index 3d873f60..00000000
--- a/Chalice/tests/predicates/aux-info.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of aux-info.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/framing-fields.chalice b/Chalice/tests/predicates/framing-fields.chalice
deleted file mode 100644
index 6cfd4607..00000000
--- a/Chalice/tests/predicates/framing-fields.chalice
+++ /dev/null
@@ -1,21 +0,0 @@
-class List
-{
- var value:int;
- var next:List;
- predicate valid { acc(value) && acc(next) && (next!=null ==> next.valid) }
-
- method set(x:int, y:int) requires valid; ensures valid; {}
-}
-
-class C
-{
- method M (x:List, y:List)
- requires x!=null && y!=null && x!=y && x.valid && y.valid;
- {
- var i: int := unfolding x.valid in x.value;
- var j: int := unfolding y.valid in y.value;
- call y.set(0,10);
- assert unfolding x.valid in (i == x.value); // succeeds
- assert unfolding y.valid in (j == y.value); // correctly fails to verify
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/framing-fields.output.txt b/Chalice/tests/predicates/framing-fields.output.txt
deleted file mode 100644
index f1b426c6..00000000
--- a/Chalice/tests/predicates/framing-fields.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of framing-fields.chalice using parameters=""
-
- 19.5: Assertion might not hold. The expression at 19.12 might not evaluate to true.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/framing-functions.chalice b/Chalice/tests/predicates/framing-functions.chalice
deleted file mode 100644
index 8b66a473..00000000
--- a/Chalice/tests/predicates/framing-functions.chalice
+++ /dev/null
@@ -1,25 +0,0 @@
-class List
-{
- var value:int;
- var next:List;
- predicate valid { acc(value) && acc(next) && (next!=null ==> next.valid) }
-
- method set(x:int, y:int) requires valid; ensures valid; {}
-
- function itemAt(i: int): int
- requires valid && 0 <= i;
- { unfolding valid in i == 0 || next == null ? value : next.itemAt(i-1) }
-}
-
-class C
-{
- method M (x:List, y:List)
- requires x!=null && y!=null && x!=y && x.valid && y.valid;
- {
- var i: int := x.itemAt(0);
- var j: int := y.itemAt(0);
- call y.set(0,10);
- assert i==x.itemAt(0); // succeeds
- assert j==y.itemAt(0); // correctly fails to verify
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/framing-functions.output.txt b/Chalice/tests/predicates/framing-functions.output.txt
deleted file mode 100644
index 2a3426c9..00000000
--- a/Chalice/tests/predicates/framing-functions.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of framing-functions.chalice using parameters=""
-
- 23.5: Assertion might not hold. The expression at 23.12 might not evaluate to true.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/generate_reference.bat b/Chalice/tests/predicates/generate_reference.bat
deleted file mode 100644
index 6864843c..00000000
--- a/Chalice/tests/predicates/generate_reference.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%0" %*
diff --git a/Chalice/tests/predicates/generate_reference_all.bat b/Chalice/tests/predicates/generate_reference_all.bat
deleted file mode 100644
index 6864843c..00000000
--- a/Chalice/tests/predicates/generate_reference_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%0" %*
diff --git a/Chalice/tests/predicates/list-reverse-extra-unfold-fold.chalice b/Chalice/tests/predicates/list-reverse-extra-unfold-fold.chalice
deleted file mode 100644
index 8467ce4c..00000000
--- a/Chalice/tests/predicates/list-reverse-extra-unfold-fold.chalice
+++ /dev/null
@@ -1,51 +0,0 @@
-class Node {
- var next : Node;
- var val : int;
-
- predicate list {
- acc(next) && acc(val) && (next!=null ==> next.list)
- }
-
- function vals() : seq<int>
- requires list
- {
- unfolding list in (next == null ? [val] : [val] ++ next.vals())
- }
-
- function reverse_vals() : seq<int>
- requires list
- {
- unfolding list in (next == null ? [val] : next.reverse_vals() ++ [val])
- }
-
- method reverse_in_place() returns (r:Node)
- requires list;
- ensures r != null && r.list;
- ensures r.vals() == old(this.reverse_vals());
- {
- var l : Node := this;
- r := null;
-
- while (l != null)
- invariant l!=null ==> l.list;
- invariant r!=null ==> r.list;
- invariant old(this.reverse_vals()) == (l==null ? nil<int> : l.reverse_vals()) ++ (r==null ? nil<int> : r.vals());
- {
- var y: Node;
- if (r != null) {
- unfold r.list; fold r.list;
- }
- unfold l.list;
- if (l.next != null) {
- unfold l.next.list; fold l.next.list;
- }
-
-
- y := l.next;
- l.next := r;
- r := l;
- fold r.list;
- l := y;
- }
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/list-reverse-extra-unfold-fold.output.txt b/Chalice/tests/predicates/list-reverse-extra-unfold-fold.output.txt
deleted file mode 100644
index 6d2967f5..00000000
--- a/Chalice/tests/predicates/list-reverse-extra-unfold-fold.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of list-reverse-extra-unfold-fold.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/mutual-dependence.chalice b/Chalice/tests/predicates/mutual-dependence.chalice
deleted file mode 100644
index a0939607..00000000
--- a/Chalice/tests/predicates/mutual-dependence.chalice
+++ /dev/null
@@ -1,24 +0,0 @@
-class Cell {
- var value: int;
- var next: Cell;
-
- predicate p { q }
- predicate q { acc(value) && acc(next) && (next != null ==> next.p) }
-
- method test()
- requires acc(this.*)
- {
- value := 1
- next := null
- fold q
- fold p
- call void()
- assert unfolding p in unfolding q in value == 1 // ERROR: should not verify
- }
-
- method void()
- requires p
- ensures p
- {}
-
-}
diff --git a/Chalice/tests/predicates/mutual-dependence.output.txt b/Chalice/tests/predicates/mutual-dependence.output.txt
deleted file mode 100644
index 263084ac..00000000
--- a/Chalice/tests/predicates/mutual-dependence.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of mutual-dependence.chalice using parameters=""
-
- 16.5: Assertion might not hold. The expression at 16.12 might not evaluate to true.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/reg_test.bat b/Chalice/tests/predicates/reg_test.bat
deleted file mode 100644
index 6864843c..00000000
--- a/Chalice/tests/predicates/reg_test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%0" %*
diff --git a/Chalice/tests/predicates/reg_test_all.bat b/Chalice/tests/predicates/reg_test_all.bat
deleted file mode 100644
index 6864843c..00000000
--- a/Chalice/tests/predicates/reg_test_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%0" %*
diff --git a/Chalice/tests/predicates/setset.chalice b/Chalice/tests/predicates/setset.chalice
deleted file mode 100644
index 512c65c1..00000000
--- a/Chalice/tests/predicates/setset.chalice
+++ /dev/null
@@ -1,57 +0,0 @@
-class Node {
- var value: int;
-
- method init(v: int)
- requires acc(value)
- ensures valid
- {
- value := v
- fold this.valid
- }
-
- function get():int requires valid { unfolding valid in value }
-
- method set(v: int)
- requires valid
- ensures valid && get() == v
- {
- unfold valid
- value := v
- fold valid
- }
-
- predicate valid {
- acc(value)
- }
-
- method main(x: Node, y: Node)
- requires x != null && y != null
- requires x.valid && y.valid
- {
- call x.set(3)
- call y.set(3)
- call x.set(3)
- call y.set(3)
- call x.set(3)
- call y.set(3)
- call x.set(3)
- unfold x.valid
- x.value := 3
- fold x.valid
- call y.set(3)
- call x.set(3)
- call y.set(3)
- unfold x.valid
- x.value := 3
- fold x.valid
- unfold x.valid
- x.value := 3
- fold x.valid
- call x.set(3)
- call y.set(3)
- call x.set(4)
-
- assert y.get() == 3
- assert x.get() == 3 // error: should fail
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/setset.output.txt b/Chalice/tests/predicates/setset.output.txt
deleted file mode 100644
index b2e963ee..00000000
--- a/Chalice/tests/predicates/setset.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of setset.chalice using parameters=""
-
- 55.5: Assertion might not hold. The expression at 55.12 might not evaluate to true.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 27.3: The end of method main is unreachable.
-
-Boogie program verifier finished with 1 errors and 1 smoke test warnings
diff --git a/Chalice/tests/predicates/test.bat b/Chalice/tests/predicates/test.bat
deleted file mode 100644
index 6864843c..00000000
--- a/Chalice/tests/predicates/test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%0" %*
diff --git a/Chalice/tests/predicates/test.chalice b/Chalice/tests/predicates/test.chalice
deleted file mode 100644
index 9477caa6..00000000
--- a/Chalice/tests/predicates/test.chalice
+++ /dev/null
@@ -1,35 +0,0 @@
-class List
-{
- var value:int;
- var next:List;
-
- predicate inv { acc(value) && acc(next) && (next!=null ==> next.inv) }
-
- function len():int
- requires inv;
- {
- unfolding inv in (next==null) ? 1 : (1+next.len())
- }
-
- predicate P { acc(value,50) }
-
- method skip()
- requires P; ensures P
- {}
-
- method goo()
- requires acc(value);
- {
- // mask: value=100, secmask: -
- fold P;
- // mask: value=50,p=100, secmask: value=50
- call skip();
- // mask: value=50,p=100, secmask: -
- fold P;
- // mask: value=0,p=200, secmask: value=50
- fork t:=skip();
- // mask: value=0,p=100, secmask: -
- assert unfolding P in value==old(value);
- }
-
-}
diff --git a/Chalice/tests/predicates/test.output.txt b/Chalice/tests/predicates/test.output.txt
deleted file mode 100644
index 8b97e503..00000000
--- a/Chalice/tests/predicates/test.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of test.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/test1.chalice b/Chalice/tests/predicates/test1.chalice
deleted file mode 100644
index 7dbde565..00000000
--- a/Chalice/tests/predicates/test1.chalice
+++ /dev/null
@@ -1,50 +0,0 @@
-class List
-{
- var value:int;
- var next:List;
-
- predicate inv { acc(value) && acc(next) && (next!=null ==> next.inv) }
-
- function get():int
- requires inv;
- { unfolding inv in value }
-
- // the purpose of this method is to test whether the methodology can roll back correctly the secondary mask:
- // s0 unf s1 unf s2 fold, should roll back to state s1 and not s0
- // note also the unfolding expression in the precondition: the fact that next!=null must be known in the body of the method
- // this means that the secondary mask must start off containing this.next, according to the proposal
- method foo()
- requires inv && unfolding inv in next!=null;
- ensures inv && unfolding inv in next!=null;
- {
- unfold inv;
- value:=0;
- unfold next.inv;
- next.value:=1;
- fold next.inv;
- assert next.get()==1;
- assert value==0;
- fold inv;
- assert get()==0;
- assert unfolding inv in next!=null && next.get()==1;
- assert unfolding inv in next.get()==1;
- }
-
- // this method tests whether the methodology works correctly when (un)folds happen on statically unknown objects
- method goo(a:List, b:List, c:bool)
- requires a!=null && b!=null && a.inv && b.inv;
- {
- var z:List;
- unfold a.inv;
- unfold b.inv;
- a.value:=0;
- b.value:=1;
- if(c) { z:=a } else { z:=b }
- fold z.inv;
- assert c ==> a.inv && a.get()==0;
- assert !c ==> b.inv && b.get()==1;
- unfold z.inv;
- assert a.value==0;
- assert b.value==1;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/test1.output.txt b/Chalice/tests/predicates/test1.output.txt
deleted file mode 100644
index 56888ecb..00000000
--- a/Chalice/tests/predicates/test1.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of test1.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/test10.chalice b/Chalice/tests/predicates/test10.chalice
deleted file mode 100644
index 7d45914c..00000000
--- a/Chalice/tests/predicates/test10.chalice
+++ /dev/null
@@ -1,18 +0,0 @@
-class List
-{
- var value:int;
- var next:List;
-
- predicate inv { acc(value) && acc(next) && (next!=null ==> next.inv) }
-
- function get():int
- requires inv;
- { unfolding inv in value }
-
- method foo()
- requires inv && unfolding inv in next!=null;
- ensures inv && unfolding inv in next!=null;
- {
- assert unfolding inv in unfolding next.inv in true;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/test10.output.txt b/Chalice/tests/predicates/test10.output.txt
deleted file mode 100644
index c043cbed..00000000
--- a/Chalice/tests/predicates/test10.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of test10.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/test2.chalice b/Chalice/tests/predicates/test2.chalice
deleted file mode 100644
index f93a1eeb..00000000
--- a/Chalice/tests/predicates/test2.chalice
+++ /dev/null
@@ -1,55 +0,0 @@
-class FoldUnfoldExperiments
-{
- var x:int;
- var y:int;
- var z:int;
- var w:int;
- predicate X { acc(x) }
- predicate Y { acc(y) }
- predicate Z { acc(z) }
-
- function getX():int
- requires X;
- { unfolding X in x }
-
- function getY():int
- requires Y;
- { unfolding Y in y }
-
- function getZ():int
- requires Z;
- { unfolding Z in z }
-
- method setX(v:int)
- requires X;
- ensures X && getX()==v;
- {
- unfold X; x:=v; fold X;
- }
-
- // this method checks if the methodology frames correctly around a method call: what happens with folded data and unfolded data
- // also: what happens if we have folded data during the call, that we unfold after the call
- method check()
- requires acc(x) && acc(y) && acc(z) && acc(w);
- ensures acc(y) && y==2 && X && getX()==3 && Z && getZ()==4 && acc(w) && w==10;
- {
- x:=1; y:=2; z:=4; w:=10;
- fold X; fold Y; fold Z;
- call setX(3);
- unfold Y;
- }
-
- // this method checks that method calls do not interfere with the correct handling of folds and unfolds
- method check1()
- requires X && acc(y) && y==1;
- ensures acc(y) && y==1 && X && getX()==200;
- {
- call setX(10);
- fold Y;
- call setX(100);
- unfold Y;
- fold Y;
- unfold Y;
- call setX(200);
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/test2.output.txt b/Chalice/tests/predicates/test2.output.txt
deleted file mode 100644
index 780c15ef..00000000
--- a/Chalice/tests/predicates/test2.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of test2.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/test3.chalice b/Chalice/tests/predicates/test3.chalice
deleted file mode 100644
index 2a364fee..00000000
--- a/Chalice/tests/predicates/test3.chalice
+++ /dev/null
@@ -1,29 +0,0 @@
-class Unsound
-{
- var value:int;
-
- predicate inv { acc(value) }
-
- function get():int
- requires inv;
- {
- unfolding inv in value
- }
-
- method set(newval:int)
- requires inv;
- ensures inv && get()==newval;
- {
- unfold inv;
- value:=newval;
- fold inv;
- }
-
- method test()
- requires inv;
- {
- call set(3);
- call set(4);
- // at this point, Chalice used to be able to prove false
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/test3.output.txt b/Chalice/tests/predicates/test3.output.txt
deleted file mode 100644
index 2753e3f5..00000000
--- a/Chalice/tests/predicates/test3.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of test3.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/test4.chalice b/Chalice/tests/predicates/test4.chalice
deleted file mode 100644
index 201b643d..00000000
--- a/Chalice/tests/predicates/test4.chalice
+++ /dev/null
@@ -1,56 +0,0 @@
-class Cell
-{
- var value:int;
-
- predicate P { acc(value,50) }
-
- function get():int
- requires P;
- {
- unfolding P in value
- }
-
- method boom(x:Cell, y:Cell)
- requires x!=null && y!=null && x.P && y.P;
- ensures x.P && y.P && (x==y ==> x.get()==100) && (x!=y ==> x.get()==old(x.get()));
- {
- if(x==y)
- {
- unfold x.P; unfold x.P;
- y.value:=100;
- fold y.P; fold y.P;
- }
- }
-
- method skip()
- requires P;
- ensures P;
- {}
-
- // is the bookkeeping correct when calculating the secondary mask?
- // fold happens once on a statically unknown object
- // intermediate calls to skip happen in all examples to create artificial "changes" to the heap,
- // thereby testing framing in the bookkeeping of folds/unfolds
- method foo(z:Cell)
- requires acc(value,50) && value==2 && z!=null && acc(z.value,50);
- {
- fold z.P;
- call z.skip();
- fold P;
- call boom(this, z);
- assert this!=z ==> unfolding P in value==2;
- assert this==z ==> unfolding P in value==100;
- }
-
- // must fail: give away all permission, even in pieces, and you lose all information about value
- method hoo()
- requires acc(value);
- {
- fold P;
- call skip();
- fold P;
- fork t:=skip();
- call skip ();
- assert unfolding P in value==old(value); // ERROR: should fail
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/test4.output.txt b/Chalice/tests/predicates/test4.output.txt
deleted file mode 100644
index 08a565c8..00000000
--- a/Chalice/tests/predicates/test4.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of test4.chalice using parameters=""
-
- 54.2: Assertion might not hold. The expression at 54.9 might not evaluate to true.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/test7.chalice b/Chalice/tests/predicates/test7.chalice
deleted file mode 100644
index 6ad8e592..00000000
--- a/Chalice/tests/predicates/test7.chalice
+++ /dev/null
@@ -1,109 +0,0 @@
-class C
-{
- var value:int;
-
- predicate inv { acc(value) }
-
- function get():int
- requires inv;
- {
- unfolding inv in value
- }
-
- method set(newval:int)
- requires inv;
- ensures inv && get()==newval;
- {
- unfold inv;
- value:=newval;
- fold inv;
- }
-
- method callmethod0()
- requires inv;
- ensures inv && get()==3;
- {
- call set(3);
- }
-
- method callmethod1()
- {
- call set(3); // ERROR: should fail
- }
-
- method ifc()
- requires inv;
- ensures inv && get()>old(get())
- {
- if(get()>0) { call set(get()+get()); }
- else { call set(2); }
- }
-
- method loop0() returns (r:int)
- requires inv && get()>0;
- ensures inv && r==get();
- {
- r:=0;
- while (r<unfolding inv in value)
- invariant inv && r<=get();
- { r:=r+1; }
- }
-
- method loop1() returns (r:int)
- requires inv && get()>0;
- ensures inv && r==get();
- {
- r:=0;
- while (r<get())
- invariant inv && r<=unfolding inv in value;
- { r:=r+1; }
- }
-
- method uf0()
- requires acc(value);
- {
- assert acc(value);
- fold inv;
- assert acc(value); // ERROR: should fail
- }
-
- method uf1()
- requires acc(value);
- {
- assert acc(value);
- fold inv;
- assert acc(inv);
- }
-
- method uf2()
- requires inv;
- {
- assert inv;
- unfold inv;
- assert acc(value);
- }
-
- method uf3()
- requires inv;
- {
- assert inv;
- unfold inv;
- assert acc(inv); // ERROR: should fail
- }
-
- method badframing0()
- requires get()==2; // ERROR: should fail
- {}
-
- method badframing1()
- requires value==2; // ERROR: should fail
- {}
-
- method badframing2()
- requires acc(value) && get()==2; // ERROR: should fail
- {}
-
- method badframing3()
- requires inv && value==2; // ERROR: should fail
- {}
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/test7.output.txt b/Chalice/tests/predicates/test7.output.txt
deleted file mode 100644
index e66a1d75..00000000
--- a/Chalice/tests/predicates/test7.output.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Verification of test7.chalice using parameters=""
-
- 31.5: The precondition at 14.14 might not hold. Insufficient fraction at 14.14 for C.inv.
- 67.5: Assertion might not hold. Insufficient fraction at 67.12 for C.value.
- 91.5: Assertion might not hold. Insufficient fraction at 91.12 for C.inv.
- 95.14: Precondition at 8.14 might not hold. Insufficient fraction at 8.14 for C.inv.
- 99.14: Location might not be readable.
- 103.28: Precondition at 8.14 might not hold. Insufficient fraction at 8.14 for C.inv.
- 107.21: Location might not be readable.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 31.5: The statements after the method call statement are unreachable.
- 62.3: The end of method uf0 is unreachable.
- 86.3: The end of method uf3 is unreachable.
-
-Boogie program verifier finished with 7 errors and 3 smoke test warnings
diff --git a/Chalice/tests/predicates/test8.chalice b/Chalice/tests/predicates/test8.chalice
deleted file mode 100644
index e824f161..00000000
--- a/Chalice/tests/predicates/test8.chalice
+++ /dev/null
@@ -1,55 +0,0 @@
-// fold/unfold in various combinations
-class FUFU
-{
- var value:int;
- var next:FUFU;
-
- predicate inv { acc(value) }
-
- predicate tinv { acc(value) && acc(next) && (next!=null ==> next.tinv) }
-
- function get():int
- requires tinv;
- { unfolding tinv in value }
-
- method fufu()
- requires acc(value);
- {
- fold inv;
- unfold inv;
- fold inv;
- unfold inv;
- }
-
- method fuf()
- requires acc(value);
- {
- fold inv;
- unfold inv;
- fold inv;
- }
-
- method uf()
- requires inv;
- {
- unfold inv;
- fold inv;
- }
-
- method fu()
- requires acc(value);
- {
- fold inv;
- unfold inv;
- }
-
- method t()
- requires tinv && unfolding tinv in next!=null;
- ensures tinv && unfolding tinv in next!=null;
- {
- unfold tinv;
- unfold next.tinv;
- fold next.tinv;
- fold tinv;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/predicates/test8.output.txt b/Chalice/tests/predicates/test8.output.txt
deleted file mode 100644
index 567d2894..00000000
--- a/Chalice/tests/predicates/test8.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of test8.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/predicates/unfolding.chalice b/Chalice/tests/predicates/unfolding.chalice
deleted file mode 100644
index 6b276a04..00000000
--- a/Chalice/tests/predicates/unfolding.chalice
+++ /dev/null
@@ -1,32 +0,0 @@
-class Cell {
- var value: int;
-
- predicate p { acc(value) }
-
- method test()
- requires p
- {
- var tmp: int := unfolding p in value;
- var tmp2: int := unfolding p in value;
- call void()
- assert tmp == unfolding p in value // ERROR: should fail
- }
-
- method test2()
- requires p
- ensures p
- {
- var tmp: int := unfolding p in value;
- var tmp2: int := unfolding p in value;
- call v()
- assert tmp == unfolding p in value
- }
-
- method v() requires true {}
-
- method void()
- requires p
- ensures p
- {}
-
-}
diff --git a/Chalice/tests/predicates/unfolding.output.txt b/Chalice/tests/predicates/unfolding.output.txt
deleted file mode 100644
index 7ff49106..00000000
--- a/Chalice/tests/predicates/unfolding.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of unfolding.chalice using parameters=""
-
- 12.5: Assertion might not hold. The expression at 12.12 might not evaluate to true.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/readme.txt b/Chalice/tests/readme.txt
deleted file mode 100644
index d6875825..00000000
--- a/Chalice/tests/readme.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-
-Chalice Test Suite
-==================
-
-Contents
---------
-- examples: Various examples how Chalice can be used to verify concurrent
- programs. These tests represent (the core of) real problems and are therefore
- well suited for performance and comparison tests (e.g. with other tools).
-- general-tests: Regression tests for various aspects of Chalice.
-- regressions: Regression tests for fixed bugs to ensure they do not occur
- again.
-- permission-model: Regression tests specifically for the permission model of
- Chalice.
-- refinements: Regression tests for the refinement extension.
-- test-scripts: Some batch scripts that can be used to execute the tests in an
- easy and automated way. More information below.
-
-
-Test Scripts
-------------
-In the directory test-scripts are various scripts to allow the execution of the
-tests in different ways. There are launchers in the test directories (e.g. in
-examples or permission-model) to access them.
-
-Commands (sorted by relevance):
-- runalltests.bat: Executes all tests in all test folders.
-- test.bat <file> [-params]: Execute a test and output the result of the
- verification. Note: <file> must not include the file extension.
-- reg_test.bat <file> [-params]: Execute a tests as a regression test, i.e., run
- the test and compare the verification result with the reference output stored
- in <file.output.txt>. Also shows the differences if any.
-- reg_test_all.bat: Execute all tests as regression tests in the current
- directory.
-- generete_reference.bat <file> [-params]: Generate the reference output.
-- generate_reference_all.bat: Generate reference files for all tests in the
- current directory.
-- getboogieoutput.bat: File used internally by generete_reference.bat.
-
-To provide additional parameters to Chalice when verifying the tests (e.g., to
-test the autoMagic feature, see tests/examples/RockBand-automagic.chalice), one
-can start the Chalice source file with the line
- "// chalice-parameter=<list of space-separated parameters>"
-
-Note: For the refinement tests, there is a bash script test.sh.
diff --git a/Chalice/tests/refinements/AngelicExec.chalice b/Chalice/tests/refinements/AngelicExec.chalice
deleted file mode 100644
index 582c3944..00000000
--- a/Chalice/tests/refinements/AngelicExec.chalice
+++ /dev/null
@@ -1,34 +0,0 @@
-class A0 {
- method m(b: bool) {
- var x;
- if (b) {
- spec x [0 <= x && x < 3];
- } else {
- x := 1;
- }
- }
-}
-
-class B0 refines A0 {
- refines m(b: bool) {
- var x := 1;
- }
-}
-
-class A1 refines A0 {
- transforms m(b: bool) {
- _
- if {
- replaces * by {x := 1;}
- } else {
- *
- }
- _
- }
-}
-
-class A2 refines A1 {
- refines m(b: bool) {
- var x := 1;
- }
-}
diff --git a/Chalice/tests/refinements/Answer b/Chalice/tests/refinements/Answer
deleted file mode 100644
index aa387295..00000000
--- a/Chalice/tests/refinements/Answer
+++ /dev/null
@@ -1,50 +0,0 @@
-Processing LoopSqRoot.chalice
-
-Boogie program verifier finished with 9 verified, 0 errors
-Processing RecSqRoot.chalice
-
-Boogie program verifier finished with 11 verified, 0 errors
-Processing SpecStmt.chalice
- 12.5: Assertion might not hold. The expression at 12.12 might not evaluate to true.
- 25.5: Assertion might not hold. The expression at 25.12 might not evaluate to true.
- 33.5: Assertion might not hold. The expression at 33.12 might not evaluate to true.
-
-Boogie program verifier finished with 4 verified, 3 errors
-Processing SumCubes.chalice
-
-Boogie program verifier finished with 6 verified, 0 errors
-Processing TestTransform.chalice
-
-Boogie program verifier finished with 10 verified, 0 errors
-Processing TestRefines.chalice
- 40.5: Refinement may produce a different value for the pre-state local variable: c
- 46.21: Refinement may change a variable outside of the frame of the specification statement: k
- 52.9: Refinement may produce a different value for the pre-state local variable: k
-
-Boogie program verifier finished with 16 verified, 3 errors
-Processing RecFiniteDiff.chalice
-
-Boogie program verifier finished with 9 verified, 0 errors
-Processing LoopFiniteDiff.chalice
-
-Boogie program verifier finished with 12 verified, 0 errors
-Processing Pick.chalice
- 26.25: Sequence index might be larger than or equal to the length of the sequence.
-
-Boogie program verifier finished with 11 verified, 1 error
-Processing TestCoupling.chalice
- 35.13: The postcondition at 35.13 might not hold. Insufficient fraction at 35.13 for A1.y.
- 62.38: Location might not be readable.
- 66.5: Location might not be writable
-
-Boogie program verifier finished with 17 verified, 3 errors
-Processing Calculator.chalice
-
-Boogie program verifier finished with 15 verified, 0 errors
-Processing AngelicExec.chalice
- 14.5: Refinement may produce a different value for the declared variable: x
-
-Boogie program verifier finished with 11 verified, 1 error
-Processing RefinesLoop.chalice
-The program did not typecheck.
-2.1: a refinement cycle detected B->C->A
diff --git a/Chalice/tests/refinements/Calculator.chalice b/Chalice/tests/refinements/Calculator.chalice
deleted file mode 100644
index 57c4c87d..00000000
--- a/Chalice/tests/refinements/Calculator.chalice
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- Carrol Morgan's calculator
- 7/2/2010 Kuat Dafny version
- 8/22/2010 translated into Chalice
-*/
-
-class Calc0 {
- var vals: seq<int>;
-
- method reset()
- requires acc(vals);
- ensures acc(vals);
- {
- vals := [];
- }
-
- method add(x: int)
- requires acc(vals);
- ensures acc(vals);
- {
- vals := [x] ++ vals;
- }
-
- method mean() returns (m: int)
- requires acc(vals) && |vals| > 0;
- ensures acc(vals);
- {
- m := total(vals)/|vals|;
- }
-
- unlimited function total(s: seq<int>): int
- {
- |s| == 0 ? 0 : s[0] + total(s[1..])
- }
-}
-
-
-
-class Calc1 refines Calc0 {
- var sum: int;
- var num: int;
- replaces vals by acc(sum) && acc(num) && sum == total(vals) && num == |vals|;
-
- refines reset()
- {
- sum := 0;
- num := 0;
- }
-
- refines add(x: int)
- {
- sum := sum + x;
- num := num + 1;
- }
-
- refines mean() returns (m: int)
- {
- m := sum/num;
- }
-}
-
-
-
-
-
-
-
-
-
diff --git a/Chalice/tests/refinements/Celebrity.chalice b/Chalice/tests/refinements/Celebrity.chalice
deleted file mode 100644
index b0d398e0..00000000
--- a/Chalice/tests/refinements/Celebrity.chalice
+++ /dev/null
@@ -1,48 +0,0 @@
-// Celebrity example, inspired by the Rodin tutorial
-class Person {
- function knows(other: Person): bool
- requires this != other;
-}
-
-class Celebrity0 {
- function IsCelebrity(c: Person, people: seq<Person>): bool
- requires null !in people;
- {
- c in people && forall p in people :: p != c ==> (p.knows(c)) && (! c.knows(p))
- }
-
- method Find(people: seq<Person>, /*ghost*/ c: Person) returns (r: Person)
- requires null !in people && IsCelebrity(c, people);
- {
- var r [r == c];
- }
-}
-
-/** Without theory of sets, hard to describe: "remove an element from a sequence" */
-class Celebrity1 refines Celebrity0 {
- refines Find(people: seq<Person>, c: Person) returns (r: Person)
- {
- var q:seq<Person> := people;
-
- // pick and remove a
- var a:Person := q[0]; q := q[1..]; assert people == [a] ++ q;
-
- while (|q| > 0)
- invariant forall p in q :: p in people;
- invariant a in people;
- invariant IsCelebrity(c,[a] ++ q);
- {
- // pick and remove b
- var oldq:seq<Person> := q;
- var b:Person := q[0]; q := q[1..];
- assert oldq == [b] ++ q;
-
- if (a != b && a.knows(b)) {
- a := b;
- }
- }
-
- r := a;
- }
-}
-
diff --git a/Chalice/tests/refinements/Counter.chalice b/Chalice/tests/refinements/Counter.chalice
deleted file mode 100644
index d1efae76..00000000
--- a/Chalice/tests/refinements/Counter.chalice
+++ /dev/null
@@ -1,112 +0,0 @@
-class Counter0 {
- var x: int;
-
- method init()
- requires acc(x);
- ensures acc(x) && x == 0;
- {
- x := 0;
- }
-
- method inc()
- requires acc(x);
- ensures acc(x) && x == old(x) + 1;
- {
- x := x + 1;
- }
-
- method dec()
- requires acc(x);
- ensures acc(x) && x == old(x) - 1;
- {
- x := x - 1;
- }
-
- method magic() returns (c: Cell)
- requires acc(x);
- ensures acc(x) && acc(c.n) && x == old(x);
- {
- var c [acc(c.n)]
- }
-}
-
-class Counter1 refines Counter0 {
- var y: int;
- var z: int;
- replaces x by acc(y) && acc(z) && x == y - z && y >= 0 && z >= 0;
-
- refines init()
- {
- this.y := 0;
- this.z := 0;
- }
-
- refines inc()
- {
- this.y := this.y + 1;
- }
-
- refines dec()
- {
- this.z := this.z + 1;
- }
-
- refines magic() returns (c: Cell)
- {
- c := new Cell;
- }
-}
-
-class Cell {var n: int}
-
-/** TODO:
-Two-step data refinement doesn't work for the following reason:
-the spec of Counter1 uses the abstract field x which disappears at the concrete method body level.
-I'm not sure what a good solution to this problem...
-*/
-
-class Counter2 refines Counter0 {
- var a: Cell;
- var b: Cell;
- replaces x by acc(a) && acc(b) && acc(a.n) && acc(b.n) && x == a.n - b.n;
-
- refines init()
- {
- this.a := new Cell;
- this.b := new Cell;
- this.a.n := 0;
- this.b.n := 0;
- }
-
- refines inc()
- {
- this.a.n := this.a.n + 1;
- }
-
- refines dec()
- {
- var i := this.b.n + 1;
- this.b := new Cell;
- this.b.n := i;
- }
-
- refines magic() returns (c: Cell)
- {
- c := a;
- }
-}
-
-class Client {
- method main()
- {
- var c := new Counter0;
- call c.init();
- call c.inc();
- call c.inc();
- call c.dec();
- call d := c.magic();
- d.n := 100;
- assert c.x == 1;
- }
-}
-
diff --git a/Chalice/tests/refinements/CounterReverse.chalice b/Chalice/tests/refinements/CounterReverse.chalice
deleted file mode 100644
index 57d87803..00000000
--- a/Chalice/tests/refinements/CounterReverse.chalice
+++ /dev/null
@@ -1,21 +0,0 @@
-class Counter1 {
- var y: int;
- var z: int;
- method inc()
- requires acc(y) && acc(z);
- requires y >= 0 && z >= 0;
- ensures acc(y) && acc(z);
- ensures y >= 0 && z >= 0;
- {
- y := y + 1;
- }
-}
-
-class Counter0 refines Counter1 {
- var x: int;
- replaces y,z by acc(x) && x == y - z;
- refines inc()
- {
- this.x := this.x + 1;
- }
-}
diff --git a/Chalice/tests/refinements/DSW.chalice b/Chalice/tests/refinements/DSW.chalice
deleted file mode 100644
index 1737df85..00000000
--- a/Chalice/tests/refinements/DSW.chalice
+++ /dev/null
@@ -1,119 +0,0 @@
-// Schorr-Waite algorithm in Chalice
-// (see Test/dafny1/SchorrWaite.dfy)
-
-class Node {
- var children: seq<Node>;
- var marked: bool;
- ghost var path: seq<Node>;
-
- var parent: Node;
-}
-
-class DSW0 {
- var stack: seq<Node>;
- var S: seq<Node>;
- var root: Node;
-
- function Reachable(to: Node, p:seq<Node>, from: Node): bool
- requires acc(p[*].children);
- {
- |p| == 0 ? to == from :
- (p[0] != null && to in p[0].children && Reachable(p[0], p[1..], from))
- }
-
- method IterativeMark()
- requires acc(this.*) && acc(S[*].children) && acc(S[*].marked) && acc(S[*].path);
- requires root in S;
- requires forall n in S :: n != null && (forall ch in n.children :: ch != null && ch in S);
- requires forall n in S :: ! n.marked;
- ensures acc(this.*) && acc(S[*].children) && acc(S[*].marked) && acc(S[*].path);
- // graph structure is the same
- ensures S == old(S) && root == old(root);
- ensures forall n in S :: n.children == old(n.children);
- // all nodes reachable from root are marked
- ensures root.marked;
- ensures forall n in S :: n.marked ==> (forall ch in n.children :: ch.marked);
- // all marked nodes are reachable from root
- ensures forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- {
- var t:Node := root;
- t.marked := true;
- stack := nil<Node>;
- t.path := stack;
-
- // no termination check
- var stop := false;
- while(!stop)
- invariant acc(this.*) && acc(S[*].children) && acc(S[*].marked) && acc(S[*].path);
- invariant root == old(root);
- invariant S == old(S);
- invariant root.marked;
- invariant t in S && t.marked && t !in stack;
- // stack well-formed
- invariant forall i in [0..|stack|] :: forall j in [i+1..|stack|] :: stack[i] != stack[j];
- invariant forall n in stack :: n in S && n.marked;
- invariant forall i in [1..|stack|] :: stack[i-1] in stack[i].children;
- invariant 0 < |stack| ==> t in stack[0].children;
- // goal
- invariant forall n in S :: n.marked && n !in stack && n != t ==>
- (forall ch in n.children :: ch in S && ch.marked);
- invariant forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- // preservation
- invariant forall n in S :: n.children == old(n.children);
- // termination
- invariant stop ==> |stack| == 0 && (forall ch in t.children :: ch.marked);
- {
- call n := PickUnmarked(t.children);
- if (n != null) {
- // push
- stack := [t] ++ stack;
- n.path := [t] ++ t.path;
- t := n;
- t.marked := true;
- assert Reachable(t.path[0], t.path[1..], root); // needed for limited function
- } else {
- // pop
- if (|stack| == 0) {
- stop := true;
- } else {
- t := stack[0];
- stack := stack[1..];
- }
- }
- }
- }
-
- method PickUnmarked(p: seq<Node>) returns (x: Node)
- requires rd(p[*].marked);
- requires forall n in p :: n != null;
- ensures rd(p[*].marked);
- ensures x != null ==> x in p && ! x.marked;
- ensures x == null ==> (forall n in p :: n.marked);
- {
- var x [(exists n in p :: !n.marked) ? (x in p && !x.marked) : (x == null)]
- }
-}
-
-class DSW1 refines DSW0 {
- replaces stack by acc(S[*].parent);
-
- transforms IterativeMark()
- {
- *
- }
-
- transforms PickUnmarked(p: seq<Node>) returns (x: Node)
- {
- replaces x by {
- if (|p| == 0) {
- x := null;
- } else if (! p[0].marked) {
- x := p[0];
- } else {
- call x := PickUnmarked(p[1..]);
- }
- }
- }
-}
diff --git a/Chalice/tests/refinements/Duplicates.chalice b/Chalice/tests/refinements/Duplicates.chalice
deleted file mode 100644
index 52cdc3c3..00000000
--- a/Chalice/tests/refinements/Duplicates.chalice
+++ /dev/null
@@ -1,115 +0,0 @@
-class Duplicates0 {
- // 3. we can do fast set checks if we know the bounds on the elements
- method find(s: seq<int>) returns (b:bool)
- requires forall i in s :: 0 <= i && i < 100;
- {
- var b [b == (exists i in [0..|s|] :: s[i] in s[..i]) ];
- }
-}
-
-class Duplicates1 refines Duplicates0 {
- refines find(s: seq<int>) returns (b: bool)
- {
- b := false;
- // 0. need a loop
- // 1. need a set data structure
- var i := 0;
- var d := new Set0;
- call d.init();
-
- // 6. use a witness from the loop
- ghost var w;
-
- while (i < |s|)
- invariant 0 <= i && i <= |s|;
- // 5. add loop invariants using value of Set.add: equivalence as a set
- invariant acc(d.rep);
- // 6. assert equivalent as sets of d.rep and s[..i]
- invariant forall n in d.rep :: n in s[..i];
- invariant forall n in [0..i] :: s[n] in d.rep;
- // 7. devise termination conditions to satisfy the spec
- invariant b ==> 0 <= w && w < |s| && s[w] in s[..w];
- invariant !b ==> (forall j,k in [0..i] :: j != k ==> s[j] != s[k]);
- {
- call r := d.add(s[i]);
- assert r ==> d.rep[0] == s[i]; // help out sequence axioms
-
- if (! r) {
- b := true;
- w := i;
- }
-
- i := i + 1;
- }
- }
-}
-
-class Set0 {
- var rep: seq<int>;
-
- method init()
- requires acc(rep);
- ensures acc(rep) && |rep| == 0;
- {
- rep := nil<int>;
- }
-
- method add(i) returns (b:bool)
- requires acc(rep);
- requires 0 <= i && i < 100;
- ensures acc(rep);
- ensures (i in old(rep)) ==> !b && rep == old(rep);
- ensures (i !in old(rep)) ==> b && rep == [i] ++ old(rep);
- {
- // 2. need a way to compute whether element is in the set
- var c:bool [c <==> i in old(rep)];
- if (c) {
- b := false;
- } else {
- b := true;
- rep := [i] ++ rep;
- assert rep[0] == i;
- }
- }
-}
-
-class Set1 refines Set0 {
- var bitset: seq<bool>;
-
- // 4. represent a set as a bitset (provided representation invariant of the uppermost class)
- replaces rep by acc(bitset) &&
- /** representation invariant */ (forall i in rep :: 0 <= i && i < 100) && |bitset| == 100 &&
- /** coupling invariant */ (forall j in [0..100] :: bitset[j] <==> (j in rep))
-
-
- refines init()
- {
- var i := 0;
- bitset := nil<bool>;
- while (i < 100)
- invariant i <= 100 && acc(bitset);
- invariant |bitset| == i;
- invariant forall b in bitset :: ! b;
- {
- bitset := [false] ++ bitset;
- i := i + 1;
- }
- }
-
- transforms add(i) returns (b: bool)
- {
- replaces c by {var c:bool := this.bitset[i]}
- if {
- *
- } else {
- replaces * by {
- b := true;
- var s:seq<bool> := [true] ++ this.bitset[i+1..];
- assert s[0] == true; // help out sequence axioms
- s := this.bitset[..i] ++ s;
-
- this.bitset := s;
- }
- }
- }
-}
diff --git a/Chalice/tests/refinements/DuplicatesLight.chalice b/Chalice/tests/refinements/DuplicatesLight.chalice
deleted file mode 100644
index 5fbe0735..00000000
--- a/Chalice/tests/refinements/DuplicatesLight.chalice
+++ /dev/null
@@ -1,42 +0,0 @@
-class Duplicates0 {
- method find(s: seq<int>) returns (b: bool)
- requires forall i in s :: i in [0..100];
- {
- spec b [ b <==> (exists i in [0..|s|] :: s[i] in s[..i]) ];
- }
-}
-
-class Duplicates1 refines Duplicates0 {
- refines find(s: seq<int>) returns (b: bool)
- {
- var n := 0;
- b := false;
- while (n < |s|)
- invariant 0 <= n && n <= |s|;
- invariant b <==> (exists i in [0..n] :: s[i] in s[..i]);
- {
- spec c: bool [ c <==> s[n] in s[..n] ];
- b := b || c;
- n := n + 1;
- }
- }
-}
-
-class Duplicates2 refines Duplicates1 {
- transforms find(s: seq<int>) returns (b: bool)
- {
- _
- var bitset:seq<bool> [ |bitset| == 100 && true !in bitset ];
- while
- invariant |bitset| == 100;
- invariant forall i in [0..100] :: bitset[i] <==> i in s[..n];
- {
- replaces c by {
- var c: bool := bitset[ s[n] ];
- }
- bitset := bitset[ .. s[n] ] ++ [true] ++ bitset[ s[n] + 1 ..];
- _
- }
- _
- }
-}
diff --git a/Chalice/tests/refinements/DuplicatesVideo.chalice b/Chalice/tests/refinements/DuplicatesVideo.chalice
deleted file mode 100644
index 3886cb78..00000000
--- a/Chalice/tests/refinements/DuplicatesVideo.chalice
+++ /dev/null
@@ -1,43 +0,0 @@
-class Duplicates0 {
- method Find(s: seq<int>) returns (b: bool)
- requires forall i in s :: i in [0..100];
- {
- b := exists i in [0..|s|] :: s[i] in s[..i];
- }
-}
-
-class Duplicates1 refines Duplicates0 {
- refines Find(s: seq<int>) returns (b: bool)
- {
- var n := 0;
- b := false;
- while (n < |s|)
- invariant 0 <= n && n <= |s|;
- invariant b <==> exists i in [0..n] :: s[i] in s[..i];
- {
- var c := s[n] in s[..n];
- b := b || c;
- n := n + 1;
- }
- }
-}
-
-class Duplicates2 refines Duplicates1 {
- transforms Find(s: seq<int>) returns (b: bool)
- {
- _;
- // bitset has length 100, initially all false
- var bitset:seq<bool> [|bitset| == 100 && true !in bitset ];
- while
- invariant |bitset| == 100;
- invariant forall i in [0..n] :: bitset[ s[i] ];
- invariant forall j in [0..100] :: bitset[j] ==> j in s[..n];
- {
- replaces c by {
- var c: bool := bitset[ s[n] ];
- }
- bitset := bitset[..s[n] ] ++ [true] ++ bitset[ s[n] + 1 ..];
- _;
- }
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/refinements/List.chalice b/Chalice/tests/refinements/List.chalice
deleted file mode 100644
index b13f6ee3..00000000
--- a/Chalice/tests/refinements/List.chalice
+++ /dev/null
@@ -1,47 +0,0 @@
-class List0 {
- var rep: seq<int>;
-
- method init()
- requires acc(rep);
- ensures acc(rep);
- {
- rep := [0];
- }
-
- method get(i) returns (v)
- requires acc(rep);
- requires 0 <= i && i < |rep|;
- ensures acc(rep);
- {
- v := rep[i];
- }
-}
-
-class List1 refines List0 {
- var sub: seq<List1>;
- var data: int;
-
- replaces rep by acc(sub) && acc(data) && acc(sub[*].sub) && acc(sub[*].data) &&
- /** valid */ |sub| >= 0 &&
- (forall i in [0..|sub|] :: sub[i] != null && sub[i].sub == sub[i+1..]) &&
- /** coupling */ |sub| + 1 == |rep| &&
- (forall i in [0..|sub|] :: sub[i].data == rep[i+1]) &&
- data == rep[0]
-
- refines init()
- {
- data := 0;
- sub := nil<List1>;
- }
-
- refines get(i) returns (v)
- {
- if (i == 0) {
- v := data;
- } else {
- var next:List1 := sub[0];
- call v := next.get(i-1);
- //v := sub[i-1].data;
- }
- }
-}
diff --git a/Chalice/tests/refinements/LoopFiniteDiff.chalice b/Chalice/tests/refinements/LoopFiniteDiff.chalice
deleted file mode 100644
index bd744c89..00000000
--- a/Chalice/tests/refinements/LoopFiniteDiff.chalice
+++ /dev/null
@@ -1,61 +0,0 @@
-class Cube0 {
- method compute(n)
- requires n >= 0;
- {
- var v [v == n*n*n];
- }
-}
-
-class Cube1 refines Cube0 {
- transforms compute(n)
- {
- replaces v by {
- var i := 0;
- var v := 0;
- while (i < n)
- invariant i <= n
- invariant v == i * i * i
- {
- i := i + 1;
- var v [v == i * i * i];
- }
- }
- }
-}
-
-class Cube2 refines Cube1 {
- transforms compute(n)
- {
- _
- var w := 1;
- while
- invariant w == (i+1)*(i+1)*(i+1) - i*i*i
- {
- _
- replaces v by {
- v := v + w;
- var w [w == (i+1)*(i+1)*(i+1) - i*i*i];
- }
- }
- _
- }
-}
-
-class Cube3 refines Cube2 {
- transforms compute(n)
- {
- _
- var x := 0;
- while
- invariant x == i*i
- {
- _
- replaces w by {
- x := x + 2*i - 1;
- w := 3*x + 3*i + 1;
- }
- }
- _
- }
-}
-
diff --git a/Chalice/tests/refinements/LoopSqRoot.chalice b/Chalice/tests/refinements/LoopSqRoot.chalice
deleted file mode 100644
index 4ea9434d..00000000
--- a/Chalice/tests/refinements/LoopSqRoot.chalice
+++ /dev/null
@@ -1,43 +0,0 @@
-class A0 {
- method sqroot(n) returns (x)
- requires n >= 0;
- {
- var x [x*x <= n && n < (x+1)*(x+1) && x >=0];
- }
-}
-
-class A1 refines A0 {
- transforms sqroot(n) returns (x)
- {
- replaces x by {
- var l := 0;
- var r := n + 1;
- while (l + 1 != r)
- invariant l >= 0 && r > l;
- invariant l*l <= n && n < r*r;
- {
- var k [l < k && k < r];
- if (k*k <= n) {
- l := k;
- } else {
- r := k;
- }
- }
- x := l;
- }
- }
-}
-
-class A2 refines A1 {
- transforms sqroot(n) returns (x)
- {
- _
- while {
- replaces k by {
- var k [2*k <= l+r && l+r < 2*(k+1)]
- }
- *
- }
- _
- }
-}
diff --git a/Chalice/tests/refinements/Pick.chalice b/Chalice/tests/refinements/Pick.chalice
deleted file mode 100644
index 7df2f90d..00000000
--- a/Chalice/tests/refinements/Pick.chalice
+++ /dev/null
@@ -1,28 +0,0 @@
-class Pick0 {
- method pick(s: seq<int>) returns (x)
- requires |s| > 0;
- {
- var x [x in s]
- }
-}
-
-class Pick1 refines Pick0 {
- transforms pick(s: seq<int>) returns (x)
- {
- replaces x by {x := s[0]}
- }
-}
-
-class Pick2 refines Pick0 {
- transforms pick(s: seq<int>) returns (x)
- {
- replaces * by {x := s[|s|-1]}
- }
-}
-
-class Pick3 refines Pick0 {
- transforms pick(s: seq<int>) returns (x)
- {
- replaces x by {x := s[1]}
- }
-}
diff --git a/Chalice/tests/refinements/RecFiniteDiff.chalice b/Chalice/tests/refinements/RecFiniteDiff.chalice
deleted file mode 100644
index 1a971aed..00000000
--- a/Chalice/tests/refinements/RecFiniteDiff.chalice
+++ /dev/null
@@ -1,51 +0,0 @@
-// Example of a program computing cube using only addition.
-// Step-wise refinement using specification statement.
-// Chalice does not have termination metric for recursive methods.
-
-class Cube0 {
- method compute(n) returns (v)
- requires n >= 0;
- ensures v == n*n*n;
- {
- var v [v == n*n*n]
- }
-}
-
-class Cube1 refines Cube0 {
- transforms compute(n) returns (v, w)
- // strengthen post-condition based on new output variables
- ensures w == (n+1)*(n+1)*(n+1)-n*n*n;
- {
- replaces v by {
- if (n == 0) {
- v := 0;
- w := 1;
- } else {
- call v1,w1 := compute(n-1); // rely on stronger post-condition
- v := v1 + w1;
- // simplified form: aha! we need n*n to compute with addition
- var w [w == 3*n*n + 3*n + 1];
- }
- }
- }
-}
-
-class Cube2 refines Cube1 {
- transforms compute(n) returns (v, w, x)
- ensures x == (n+1)*(n+1);
- {
- if {
- _
- x := 1;
- } else {
- replaces v1, w1 by {
- call v1,w1,x1 := compute(n-1);
- }
- _
- replaces w by {
- w := 3*x1 + 3*n + 1;
- x := x1 + 2*n + 1;
- }
- }
- }
-}
diff --git a/Chalice/tests/refinements/RecSqRoot.chalice b/Chalice/tests/refinements/RecSqRoot.chalice
deleted file mode 100644
index a10c1b55..00000000
--- a/Chalice/tests/refinements/RecSqRoot.chalice
+++ /dev/null
@@ -1,46 +0,0 @@
-class A0 {
- method sqroot(n) returns (x)
- requires n >= 0;
- {
- var x [x*x <= n && n < (x+1)*(x+1)];
- }
-}
-
-class A1 refines A0 {
- transforms sqroot(n) returns (x)
- {
- replaces x by {call x := rec(n,0,n+1)}
- }
-
- method rec(n, l, r) returns (x)
- requires l*l <= n && n < r*r;
- requires l >= 0 && r >= 0;
- ensures x*x <= n && n < (x+1)*(x+1);
- {
- if (l+1 == r) {
- x := l;
- } else {
- var k [l < k && k < r];
- if (n < k*k) {
- call x := rec(n,l,k);
- } else {
- call x := rec(n,k,r);
- }
- }
- }
-}
-
-class A2 refines A1 {
- transforms rec(n, l, r) returns (x)
- {
- if {
- *
- } else {
- replaces k by {
- assert l < r;
- var k := l+1;
- }
- *
- }
- }
-}
diff --git a/Chalice/tests/refinements/RefinesLoop.chalice b/Chalice/tests/refinements/RefinesLoop.chalice
deleted file mode 100644
index 305fc164..00000000
--- a/Chalice/tests/refinements/RefinesLoop.chalice
+++ /dev/null
@@ -1,3 +0,0 @@
-class A refines B {}
-class B refines C {}
-class C refines A {}
diff --git a/Chalice/tests/refinements/SpecStmt.chalice b/Chalice/tests/refinements/SpecStmt.chalice
deleted file mode 100644
index 55eacdb0..00000000
--- a/Chalice/tests/refinements/SpecStmt.chalice
+++ /dev/null
@@ -1,35 +0,0 @@
-class Test {
- var x: int;
- method m(a:int) returns (b:int)
- {
- var c := 0;
- ghost const d,c [d == c];
- var b [b == 0];
- var e [e == a];
- assert d == c;
- assert e == a;
- assert b == 0;
- assert c == 0; // error
- }
-
- method n()
- requires acc(x);
- {
- x := 0;
- const y [acc(x), acc(x) && x == old(x) + 1 && y == x];
- assert y == 1;
- const v [acc(x), acc(x) && v == old(x) + 1];
- assert v == 2;
- const z [z == 1];
- ghost var t [z == 1, true];
- assert false; // reachable
- }
-
- method o()
- {
- var z [acc(x) && z == 0]; // unimplementable
- x := z;
- assert x == 0;
- assert false; // reachable
- }
-}
diff --git a/Chalice/tests/refinements/SumCubes.chalice b/Chalice/tests/refinements/SumCubes.chalice
deleted file mode 100644
index a24a0f37..00000000
--- a/Chalice/tests/refinements/SumCubes.chalice
+++ /dev/null
@@ -1,29 +0,0 @@
-class SumCubes0 {
- method compute(n)
- requires n >= 0;
- {
- var i := 0;
- var s := 0;
- while (i < n)
- invariant i <= n;
- {
- i := i + 1;
- s := s + i*i*i;
- }
- }
-}
-
-class SumCubes1 refines SumCubes0 {
- transforms compute(n)
- {
- _
- var t := 0;
- while
- invariant s == t*t;
- invariant 2*t == i*(i+1);
- {
- _
- t := t + i;
- }
- }
-}
diff --git a/Chalice/tests/refinements/TestCoupling.chalice b/Chalice/tests/refinements/TestCoupling.chalice
deleted file mode 100644
index a178c9b4..00000000
--- a/Chalice/tests/refinements/TestCoupling.chalice
+++ /dev/null
@@ -1,74 +0,0 @@
-class A0 {
- var x: int;
- var n: int;
- var k: int;
-
- method inc()
- requires acc(x) && acc(n);
- ensures acc(x) && x == old(x) + 1;
- {
- x := x + 1;
- n := n + 1;
- }
-
- method error()
- requires acc(x)
- ensures acc(x)
- {
- x := x + 1;
- }
-}
-
-class A1 refines A0 {
- var y: int;
- var z: int;
- replaces x by acc(y) && acc(z) && x == y - z && y >= 0 && z >= 0;
-
- refines inc()
- ensures y == old(y) + 1
- {
- this.y := 1 + this.y;
- this.n := this.n + 1;
- }
-
- refines error()
- ensures acc(y)
- {
- this.y := 1 + this.y;
- }
-}
-
-class B0 {
- var x: int;
- var y: int;
-
- method error()
- requires acc(x);
- ensures acc(x);
- {
- x := x + 1;
- }
-
- method inc()
- requires acc(x) && acc(y);
- ensures acc(x) && acc(y);
- {
- x := x + 1;
- }
-}
-
-class B1 refines B0 {
- var z: int;
- replaces x,y by acc(z) && z == x + y;
-
- refines error()
- {
- this.z := this.z + 1;
- }
-
- refines inc()
- {
- this.z := this.z + 1;
- }
-}
-
diff --git a/Chalice/tests/refinements/TestRefines.chalice b/Chalice/tests/refinements/TestRefines.chalice
deleted file mode 100644
index 40f21cea..00000000
--- a/Chalice/tests/refinements/TestRefines.chalice
+++ /dev/null
@@ -1,56 +0,0 @@
-// Simple refinements
-class A {
- var x:int;
- function f():int {1}
- method m(i:int) returns (j:int) {
- var j [j > 0];
- }
-
- method n() returns (c: bool)
- {
- c := true;
- }
-
- method o() returns ()
- {
- var k := 1;
- var j := 0;
- spec j [j > 0];
- }
-
- method p(b: bool) returns ()
- {
- var k := 1;
- if (b) {
- } else {
- }
- }
-}
-
-class B refines A {
- // correct
- transforms m(i:int) returns (j:int, k:int)
- {
- *
- }
-
- // broken: c
- refines n() returns (c: bool)
- {
- c := false;
- }
-
- // broken: spec stmt frame, k
- transforms o() returns () {
- _
- replaces j by { j := 1; k := 0 }
- }
-
- // broken: k
- transforms p(b: bool) returns () {
- _
- if {k := 2} else {*}
- }
-}
-
-
diff --git a/Chalice/tests/refinements/TestTransform.chalice b/Chalice/tests/refinements/TestTransform.chalice
deleted file mode 100644
index 2c18907f..00000000
--- a/Chalice/tests/refinements/TestTransform.chalice
+++ /dev/null
@@ -1,38 +0,0 @@
-class A {
- method m(i: int) returns (x: int)
- ensures x == i;
- {
- var j := 0;
- var v [v == i + j];
- x := v;
- }
-
- method n() {
- var x := 0;
- var y := 1;
- var z := 2;
- }
-}
-
-class B refines A {
- transforms m(i: int) returns (x: int, y: int)
- ensures y == 0;
- {
- var t := 0;
- _
- replaces v by {
- var v := i + j;
- call t, j := m(0);
- y := j;
- }
- _
- }
-
- transforms n() {
- replaces * by {
- var x := 0;
- var y := x + 1;
- var z := 2*y;
- }
- }
-}
diff --git a/Chalice/tests/refinements/experiments/CounterPredicate.chalice b/Chalice/tests/refinements/experiments/CounterPredicate.chalice
deleted file mode 100644
index fd35c18c..00000000
--- a/Chalice/tests/refinements/experiments/CounterPredicate.chalice
+++ /dev/null
@@ -1,136 +0,0 @@
-class Cell {
- var n : int;
-}
-
-class A {
- var x : int;
-
- predicate valid {
- acc(x) && x >= 0
- }
-
- function getX(): int requires valid
- {
- unfolding valid in x
- }
-
- method init()
- requires acc(this.*);
- ensures valid;
- {
- x := 0;
- fold valid;
- }
-
- method inc()
- requires valid;
- ensures valid && getX() == old(getX()) + 1;
- {
- unfold valid;
- x := x + 1;
- fold valid;
- }
-
- method dec()
- requires valid && getX() > 0;
- ensures valid;
- {
- unfold valid;
- x := x - 1;
- fold valid;
- }
-
- method magic() returns (c: Cell)
- requires valid;
- ensures valid;
- {
- }
-}
-
-class C {
- ghost var x : int;
- var y : Cell;
- var z : Cell;
-
- function getX() : int
- requires valid;
- {
- unfolding valid in y.n - z.n
- }
-
- predicate valid {
- acc(x) && acc(y) && acc(z) && acc(y.n) && acc(z.n) &&
- y != null && z != null &&
- y.n >= 0 && z.n >= 0 &&
- y.n - z.n == x &&
- x >= 0
- }
-
- method init()
- requires acc(this.*);
- ensures valid;
- {
- x := 0;
- //
- y := new Cell;
- z := new Cell;
- y.n := 0;
- z.n := 0;
- fold valid;
- }
-
- method inc()
- requires valid;
- ensures valid && getX() == old(getX()) + 1;
- {
- unfold valid;
- x := x + 1;
- //
- y.n := y.n + 1;
- fold valid;
- }
-
- method dec()
- requires valid && getX() > 0;
- ensures valid;
- {
- unfold valid;
- x := x - 1;
- //
- z.n := z.n + 1;
- fold valid;
- }
-
- method magic() returns (c: Cell)
- requires valid;
- ensures valid;
- {
- unfold valid;
- c := y;
- fold valid;
- }
-}
-
-class Client {
- method main()
- {
- // Abstract program
- var a := new A;
- call a.init();
- call a.inc(); // problem is here
- call a.inc();
- call a.dec();
- call ac := a.magic();
- ac.n := 0;
-
- // Concrete program
- var c := new C;
- call c.init();
- call c.inc();
- call c.inc();
- call c.dec();
- call cc := c.magic();
- cc.n := 0;
- }
-}
-
diff --git a/Chalice/tests/refinements/experiments/DSW0.chalice b/Chalice/tests/refinements/experiments/DSW0.chalice
deleted file mode 100644
index d83c5438..00000000
--- a/Chalice/tests/refinements/experiments/DSW0.chalice
+++ /dev/null
@@ -1,145 +0,0 @@
-// Schorr-Waite algorithm in Chalice
-// (see Test/dafny1/SchorrWaite.dfy)
-
-// (incomplete version) Two children instead of a sequence of an array
-class Node {
- var left: Node;
- var right: Node;
- var marked: bool;
- var l: bool;
- var r: bool;
-}
-
-class Main {
- method RecursiveMark(root: Node, S: seq<Node>)
- requires acc(S[*].marked, 50) && acc(S[*].*, 50);
- requires root != null && root in S;
- // S is closed under 'left' and 'right':
- requires forall n in S :: n != null &&
- ((n.left != null ==> n.left in S) &&
- (n.right != null ==> n.right in S));
- requires forall n in S :: ! n.marked;
- ensures acc(S[*].marked, 50) && acc(S[*].*, 50);
- ensures root.marked;
- // nodes reachable from 'root' are marked:
- ensures forall n in S :: n.marked ==>
- ((n.left != null ==> n.left in S && n.left.marked) &&
- (n.right != null ==> n.right in S && n.right.marked));
- {
- var stack: seq<Node> := [];
- call RecursiveMarkWorker(root, S, stack);
- }
-
- method RecursiveMarkWorker(root: Node, S: seq<Node>, stack: seq<Node>)
- requires acc(S[*].marked, 50) && acc(S[*].*, 50);
- requires root != null && root in S;
- requires forall n in S :: n != null &&
- ((n.left != null ==> n.left in S) &&
- (n.right != null ==> n.right in S))
- requires forall n in S :: n.marked ==>
- (n in stack ||
- ((n.left != null ==> n.left.marked) &&
- (n.right != null ==> n.right.marked)));
- requires forall n in stack :: n != null && n in S && n.marked;
- ensures acc(S[*].marked, 50) && acc(S[*].*, 50);
- ensures forall n in S :: n.left == old(n.left) && n.right == old(n.right);
- ensures forall n in S :: n.marked ==>
- (n in stack ||
- ((n.left != null ==> n.left.marked) &&
- (n.right != null ==> n.right.marked)));
- ensures forall n in S :: old(n.marked) ==> n.marked;
- ensures root.marked;
- {
- if (! root.marked) {
- root.marked := true;
- var next:seq<Node> := [root] ++ stack;
- assert next[0] == root;
- if (root.left != null) {
- call RecursiveMarkWorker(root.left, S, next);
- }
-
- if (root.right != null) {
- call RecursiveMarkWorker(root.right, S, next);
- }
- }
- }
-
- method IterativeMark(root: Node, S: seq<Node>)
- requires acc(S[*].*);
- requires root in S;
- requires forall n in S :: n != null &&
- (n.left != null ==> n.left in S) &&
- (n.right != null ==> n.right in S);
- requires forall n in S :: ! n.marked;
- requires forall n in S :: ! n.l && ! n.r;
- ensures acc(S[*].*);
- ensures forall n in S :: n.left == old(n.left) && n.right == old(n.right);
- ensures root.marked;
- ensures forall n in S :: n.marked ==>
- (n.left != null ==> n.left.marked) &&
- (n.right != null ==> n.right.marked);
- ensures forall n in S :: ! n.l && ! n.r;
- {
- var t:Node := root;
- t.marked := true;
- var stack: seq<Node> := [];
-
- var stop := false;
- while(!stop)
- invariant acc(S[*].*);
- invariant root.marked && t in S && t !in stack;
- invariant forall n in stack :: n in S;
- invariant forall i in [0..|stack|] :: forall j in [i+1..|stack|] :: stack[i] != stack[j];
- invariant forall n in S :: (n in stack || n == t) ==>
- n.marked &&
- (n.r ==> n.l) &&
- (n.l && n.left != null ==> n.left in S && n.left.marked) &&
- (n.r && n.right != null ==> n.right in S && n.right.marked)
- // stack is linked
- invariant forall i in [1..|stack|] :: stack[i-1] == (stack[i].l ? stack[i].right : stack[i].left);
- invariant 0 < |stack| ==> t == (stack[0].l ? stack[0].right : stack[0].left);
- // goal
- invariant forall n in S :: n.marked && n !in stack && n != t ==>
- (n.left != null ==> n.left in S && n.left.marked) &&
- (n.right != null ==> n.right in S && n.right.marked);
- // preservation
- invariant forall n in S :: n !in stack && n != t ==> ! n.l && ! n.r;
- invariant forall n in S :: n.left == old(n.left) && n.right == old(n.right);
- invariant stop ==> |stack| == 0 && ! t.l && ! t.r &&
- (t.left != null ==> t.left.marked) &&
- (t.right != null ==> t.right.marked);
- {
- if (! t.l && (t.left == null || t.left.marked)) {
- // advance
- t.l := true;
- } else if (t.l && ! t.r && (t.right == null || t.right.marked)) {
- // advance
- t.r := true;
- } else if (t.r) {
- // pop
- t.l := false;
- t.r := false;
- if (|stack| == 0) {
- stop := true;
- } else {
- t := stack[0];
- stack := stack[1..];
- if (t.l) {t.r := true} else {t.l := true}
- }
- } else if (!t.l) {
- // push
- stack := [t] ++ stack;
- assert stack[0] == t;
- t := t.left;
- t.marked := true;
- } else if (!t.r) {
- // push
- assert t.l;
- stack := [t] ++ stack;
- assert stack[0] == t;
- t := t.right;
- t.marked := true;
- }
- }
- }
-}
diff --git a/Chalice/tests/refinements/experiments/DSW1.chalice b/Chalice/tests/refinements/experiments/DSW1.chalice
deleted file mode 100644
index 612f21ac..00000000
--- a/Chalice/tests/refinements/experiments/DSW1.chalice
+++ /dev/null
@@ -1,91 +0,0 @@
-// Schorr-Waite algorithm in Chalice
-// (see Test/dafny1/SchorrWaite.dfy)
-
-// Arbitrary number of children
-// No counter for visited nodes; next node is selected non-deterministically
-class Node {
- var children: seq<Node>;
- var marked: bool;
- ghost var path: seq<Node>;
-}
-
-class Main {
- function Reachable(to: Node, p:seq<Node>, from: Node): bool
- requires acc(p[*].children);
- {
- |p| == 0 ? to == from :
- (p[0] != null && to in p[0].children && Reachable(p[0], p[1..], from))
- }
-
- method IterativeMark(root: Node, S: seq<Node>)
- requires acc(S[*].*);
- requires root in S;
- requires forall n in S :: n != null && (forall ch in n.children :: ch != null && ch in S);
- requires forall n in S :: ! n.marked;
- ensures acc(S[*].*);
- // graph structure is the same
- ensures forall n in S :: n.children == old(n.children);
- // all nodes reachable from root are marked
- ensures root.marked;
- ensures forall n in S :: n.marked ==> (forall ch in n.children :: ch.marked);
- // all marked nodes are reachable from root
- ensures forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- {
- var t:Node := root;
- t.marked := true;
- var stack: seq<Node> := [];
- t.path := stack;
-
- // no termination check
- var stop := false;
- while(!stop)
- invariant acc(S[*].*);
- invariant root.marked;
- invariant t in S && t.marked && t !in stack;
- // stack well-formed
- invariant forall i in [0..|stack|] :: forall j in [i+1..|stack|] :: stack[i] != stack[j];
- invariant forall n in stack :: n in S && n.marked;
- invariant forall i in [1..|stack|] :: stack[i-1] in stack[i].children;
- invariant 0 < |stack| ==> t in stack[0].children;
- // goal
- invariant forall n in S :: n.marked && n !in stack && n != t ==>
- (forall ch in n.children :: ch in S && ch.marked);
- invariant forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- // preservation
- invariant forall n in S :: n.children == old(n.children);
- // termination
- invariant stop ==> |stack| == 0 && (forall ch in t.children :: ch.marked);
- {
- call n := PickUnmarked(t.children);
-
- if (n != null) {
- // push
- stack := [t] ++ stack;
- n.path := [t] ++ t.path;
- t := n;
- t.marked := true;
- assert Reachable(t.path[0], t.path[1..], root); // needed for limited function
- } else {
- // pop
- if (|stack| == 0) {
- stop := true;
- } else {
- t := stack[0];
- stack := stack[1..];
- }
- }
- }
- }
-
- method PickUnmarked(p: seq<Node>) returns (x: Node)
- requires rd(p[*].marked);
- requires forall n in p :: n != null;
- ensures rd(p[*].marked);
- ensures x != null ==> x in p && ! x.marked;
- ensures x == null ==> (forall n in p :: n.marked);
- {
- assume false; // magic!
- }
-}
diff --git a/Chalice/tests/refinements/experiments/DSW10.chalice b/Chalice/tests/refinements/experiments/DSW10.chalice
deleted file mode 100644
index 3bf70eeb..00000000
--- a/Chalice/tests/refinements/experiments/DSW10.chalice
+++ /dev/null
@@ -1,120 +0,0 @@
-// Schorr-Waite algorithm in Chalice
-// (see Test/dafny1/SchorrWaite.dfy)
-
-// Arbitrary number of children
-// Added visited field to refine non-det choice with a conditional
-// Added a client
-class Node {
- var children: seq<Node>;
- var marked: bool;
- var visited: int;
- ghost var path: seq<Node>;
-}
-
-class Main {
- method Test()
- {
- var a := new Node {marked := false, visited := 0};
- var b := new Node {marked := false, visited := 0};
- var c := new Node {marked := false, visited := 0};
- var d := new Node {marked := false, visited := 0};
- a.children := [b];
- b.children := [c,a];
- c.children := [b];
- d.children := [a,b,c];
- // a <-> b <-> c
- // ^ \ ^ / ^
- // d
- assert [a,b,c,d][0] == a; // root is in sequence
- call IterativeMark(a, [a,b,c,d]);
- assert a.marked;
- assert a.children[0] == b; // b should be marked
- assert b.marked;
- assert b.children[0] == c; // c should be marked
- assert c.marked;
- assert !d.marked;
- }
-
- function Reachable(to: Node, p:seq<Node>, from: Node): bool
- requires acc(p[*].children);
- {
- |p| == 0 ? to == from :
- (p[0] != null && to in p[0].children && Reachable(p[0], p[1..], from))
- }
-
- method IterativeMark(root: Node, S: seq<Node>)
- requires acc(S[*].*);
- requires root in S;
- requires forall n in S :: n != null && (forall ch in n.children :: ch != null && ch in S);
- requires forall n in S :: ! n.marked;
- requires forall n in S :: n.visited == 0;
- ensures acc(S[*].*);
- // graph structure is the same
- ensures forall n in S :: n.children == old(n.children);
- ensures forall n in S :: n.visited == 0;
- // all nodes reachable from root are marked
- ensures root.marked;
- ensures forall n in S :: n.marked ==> (forall ch in n.children :: ch.marked);
- // all marked nodes are reachable from root
- ensures forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) &&
- Reachable(n, n.path, root);
- {
- var t:Node := root;
- t.marked := true;
- var stack: seq<Node> := [];
- t.path := stack;
-
- var stop := false;
- while(!stop)
- invariant acc(S[*].*);
- invariant root.marked && t in S && t.marked && t !in stack;
- // no duplicates in the stack
- invariant forall i in [0..|stack|] :: forall j in [i+1..|stack|] :: stack[i] != stack[j];
- // stack well-formed
- invariant forall n in stack :: n in S;
- invariant forall n in S :: n in stack || n == t ==>
- n.marked &&
- 0 <= n.visited && n.visited <= |n.children| &&
- (forall i in [0..n.visited] :: n.children[i] in S && n.children[i].marked);
- invariant forall n in stack :: n.visited < |n.children|;
- // stack is linked
- invariant forall i in [1..|stack|] :: stack[i-1] == stack[i].children[stack[i].visited];
- invariant 0 < |stack| ==> t == stack[0].children[stack[0].visited];
- // goal
- invariant forall n in S :: n.marked && n !in stack && n != t ==>
- (forall ch in n.children :: ch in S && ch.marked);
- invariant forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) &&
- Reachable(n, n.path, root);
- // preservation
- invariant forall n in S :: n !in stack && n != t ==> n.visited == old(n.visited);
- invariant forall n in S :: n.children == old(n.children);
- // termination
- invariant stop ==> |stack| == 0 && (forall ch in t.children :: ch.marked) && t.visited == 0;
- {
- if (t.visited == |t.children|) {
- // pop
- t.visited := 0;
- if (|stack| == 0) {
- stop := true;
- } else {
- t := stack[0];
- stack := stack[1..];
- t.visited := t.visited + 1;
- }
- } else if (t.children[t.visited].marked) {
- // skip
- t.visited := t.visited + 1;
- } else {
- // push
- ghost var oldt:Node := t;
- stack := [t] ++ stack;
- t := t.children[t.visited];
- t.path := [oldt] ++ oldt.path; // TODO: in fact, this is stack
- t.marked := true;
- assert Reachable(oldt, oldt.path, root); // needed for limited function
- }
- }
- }
-}
diff --git a/Chalice/tests/refinements/experiments/DSW2.chalice b/Chalice/tests/refinements/experiments/DSW2.chalice
deleted file mode 100644
index 7438c688..00000000
--- a/Chalice/tests/refinements/experiments/DSW2.chalice
+++ /dev/null
@@ -1,95 +0,0 @@
-// Schorr-Waite algorithm in Chalice
-// (see Test/dafny1/SchorrWaite.dfy)
-
-// Add arbitrary number of children, not just two.
-// Remove visited field for visited nodes; next node is selected non-deterministically (verification time 30s)
-// Added parent pointer p (stack remains) (verification time 8s, limited functions)
-class Node {
- var children: seq<Node>;
- var marked: bool;
- ghost var path: seq<Node>;
-}
-
-class Main {
- function Reachable(to: Node, p:seq<Node>, from: Node): bool
- requires acc(p[*].children);
- {
- |p| == 0 ? to == from :
- (p[0] != null && to in p[0].children && Reachable(p[0], p[1..], from))
- }
-
- method SchorrWaite(root: Node, S: seq<Node>)
- requires acc(S[*].*);
- requires root in S;
- requires forall n in S :: n != null && (forall ch in n.children :: ch != null && ch in S);
- requires forall n in S :: ! n.marked;
- ensures acc(S[*].*);
- // graph structure is the same
- ensures forall n in S :: n.children == old(n.children);
- // all nodes reachable from root are marked
- ensures root.marked;
- ensures forall n in S :: n.marked ==> (forall ch in n.children :: ch.marked);
- // all marked nodes are reachable from root
- ensures forall n in S :: n.marked ==> (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- {
- var p:Node := null;
- var t:Node := root;
- t.marked := true;
- var stack: seq<Node> := [];
- t.path := stack;
-
- // no termination check
- var stop := false;
- while(!stop)
- invariant acc(S[*].*);
- invariant root.marked;
- invariant t in S && t.marked && t !in stack;
- // stack well-formed
- invariant forall i in [0..|stack|] :: forall j in [i+1..|stack|] :: stack[i] != stack[j];
- invariant forall n in stack :: n in S && n.marked;
- invariant forall i in [1..|stack|] :: stack[i-1] in stack[i].children;
- invariant 0 < |stack| ==> p == stack[0] && t in p.children;
- invariant 0 == |stack| ==> p == null;
- // goal
- invariant forall n in S :: n.marked && n !in stack && n != t ==>
- (forall ch in n.children :: ch in S && ch.marked);
- invariant forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- // preservation
- invariant forall n in S :: n.children == old(n.children);
- // termination
- invariant stop ==> |stack| == 0 && (forall ch in t.children :: ch.marked);
- {
- call n := PickUnmarked(t.children);
-
- if (n != null) {
- // push
- p := t;
- stack := [t] ++ stack;
- n.path := [t] ++ t.path;
- t := n;
- t.marked := true;
- assert Reachable(t.path[0], t.path[1..], root); // limited function
- } else {
- // pop
- if (p == null) {
- stop := true;
- } else {
- t := p;
- stack := stack[1..];
- p := |stack| > 0 ? stack[0] : null;
- }
- }
- }
- }
-
- method PickUnmarked(p: seq<Node>) returns (x: Node)
- requires rd(p[*].marked);
- requires forall n in p :: n != null;
- ensures rd(p[*].marked);
- ensures x != null ==> x in p && ! x.marked;
- ensures x == null ==> (forall n in p :: n.marked);
- {
- assume false; // magic!
- }
-}
diff --git a/Chalice/tests/refinements/experiments/DSW3.chalice b/Chalice/tests/refinements/experiments/DSW3.chalice
deleted file mode 100644
index dbf161cd..00000000
--- a/Chalice/tests/refinements/experiments/DSW3.chalice
+++ /dev/null
@@ -1,106 +0,0 @@
-// Schorr-Waite algorithm in Chalice
-// (see Test/dafny1/SchorrWaite.dfy)
-
-// Add arbitrary number of children, not just two.
-// Remove visited field for visited nodes; next node is selected non-deterministically
-// Added parent pointer p (stack remains)
-// Note: the challenge is to update children field of nodes on stack so that we can recover
-// parent pointer in pop operation
-// Add parent field to Node and made stack ghost (verification time 80s, limited functions)
-class Node {
- var children: seq<Node>;
- var marked: bool;
- var parent: Node;
- ghost var path: seq<Node>;
-}
-
-class Main {
- function Reachable(to: Node, p:seq<Node>, from: Node): bool
- requires acc(p[*].children);
- {
- |p| == 0 ? to == from :
- (p[0] != null && to in p[0].children && Reachable(p[0], p[1..], from))
- }
-
- method SchorrWaite(root: Node, S: seq<Node>)
- requires acc(S[*].*);
- requires root in S;
- requires forall n in S :: n != null && (forall ch in n.children :: ch != null && ch in S);
- requires forall n in S :: ! n.marked && n.parent == null;
- ensures acc(S[*].*);
- // graph structure is the same
- ensures forall n in S :: n.children == old(n.children);
- ensures forall n in S :: n.parent == null;
- // all nodes reachable from root are marked
- ensures root.marked;
- ensures forall n in S :: n.marked ==> (forall ch in n.children :: ch.marked);
- // all marked nodes are reachable from root
- ensures forall n in S :: n.marked ==> (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- {
- var p:Node := null;
- var t:Node := root;
- t.marked := true;
- ghost var stack: seq<Node> := [];
- t.path := stack;
-
- // no termination check
- var stop := false;
- while(!stop)
- invariant acc(S[*].*);
- invariant root.marked;
- invariant t in S && t.marked && t !in stack;
- // stack well-formed
- invariant forall i in [0..|stack|] :: forall j in [i+1..|stack|] :: stack[i] != stack[j];
- invariant forall n in stack :: n in S && n.marked;
- invariant forall i in [1..|stack|] :: stack[i-1] in stack[i].children;
- invariant forall i in [1..|stack|] :: stack[i-1].parent == stack[i];
- invariant 0 < |stack| ==> p == stack[0] && t in p.children && stack[|stack|-1].parent == null;
- invariant 0 == |stack| <==> p == null;
- // goal
- invariant forall n in S :: n.marked && n !in stack && n != t ==>
- (forall ch in n.children :: ch in S && ch.marked);
- invariant forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) && Reachable(n, n.path, root);
- invariant forall n in S :: n !in stack ==> n.parent == null;
- // preservation
- invariant forall n in S :: n.children == old(n.children);
- // termination
- invariant stop ==> |stack| == 0 && (forall ch in t.children :: ch.marked);
- {
- call n := PickUnmarked(t.children);
-
- if (n != null) {
- // push
- t.parent := p;
- p := t;
- stack := [t] ++ stack;
- n.path := [t] ++ t.path;
- t := n;
- t.marked := true;
- assert Reachable(t.path[0], t.path[1..], root); // limited function
- assert forall x in S :: x.marked ==> Reachable(x, x.path, root);
- assume forall x in S :: x.marked ==> Reachable(x, x.path, root);
- } else {
- // pop
- if (p == null) {
- stop := true;
- } else {
- t := p;
- p := t.parent;
- t.parent := null;
- stack := stack[1..];
- }
- }
- }
- }
-
- method PickUnmarked(p: seq<Node>) returns (x: Node)
- requires rd(p[*].marked);
- requires forall n in p :: n != null;
- ensures rd(p[*].marked);
- ensures x != null ==> x in p && ! x.marked;
- ensures x == null ==> (forall n in p :: n.marked);
- {
- assume false;
- }
-}
diff --git a/Chalice/tests/refinements/experiments/DSW4.chalice b/Chalice/tests/refinements/experiments/DSW4.chalice
deleted file mode 100644
index f594595a..00000000
--- a/Chalice/tests/refinements/experiments/DSW4.chalice
+++ /dev/null
@@ -1,117 +0,0 @@
-// Schorr-Waite algorithm in Chalice
-// (see Test/dafny1/SchorrWaite.dfy)
-
-// Add arbitrary number of children, not just two.
-// Remove visited field for visited nodes; next node is selected non-deterministically
-// Added parent pointer p (stack remains)
-// Note: the challenge is to update children field of nodes on stack so that we can recover
-// parent pointer in pop operation
-// Add parent field to Node and made stack ghost (verification time 80s, limited functions)
-// Add Reachable that existentially quantifies over paths (verification time 23s, limited functions)
-class Node {
- var children: seq<Node>;
- var marked: bool;
- var parent: Node;
- var visited: int;
- ghost var path: seq<Node>;
-}
-
-class Main {
- function Reachable(to: Node, from: Node, S: seq<Node>): bool
- requires acc(S[*].children);
- {
- exists p:seq<Node> :: (forall n in p :: n in S) && Via(to, p, from)
- }
-
- function Via(to: Node, p:seq<Node>, from: Node): bool
- requires acc(p[*].children);
- {
- |p| == 0 ? to == from :
- (p[0] != null && to in p[0].children && Via(p[0], p[1..], from))
- }
-
- method SchorrWaite(root: Node, S: seq<Node>)
- requires acc(S[*].*);
- requires root in S;
- requires forall n in S :: n != null && (forall ch in n.children :: ch != null && ch in S);
- requires forall n in S :: ! n.marked && n.parent == null && n.visited == 0;
- ensures acc(S[*].*);
- // graph structure is the same
- ensures forall n in S :: n.children == old(n.children);
- ensures forall n in S :: n.parent == null && n.visited == 0;
- // all nodes reachable from root are marked
- ensures root.marked;
- ensures forall n in S :: n.marked ==> (forall ch in n.children :: ch.marked);
- // all marked nodes are reachable from root
- ensures forall n in S :: n.marked ==> (forall m in n.path :: m in S) && Reachable(n, root, S);
- {
- var p:Node := null;
- var t:Node := root;
- t.marked := true;
- ghost var stack: seq<Node> := [];
- t.path := stack;
-
- // no termination check
- var stop := false;
- while(!stop)
- invariant acc(S[*].*);
- invariant root.marked;
- invariant t in S && t.marked && t !in stack;
- // stack well-formed
- invariant forall i in [0..|stack|] :: forall j in [i+1..|stack|] :: stack[i] != stack[j];
- invariant forall n in stack :: n in S && n.marked;
- invariant forall i in [1..|stack|] :: stack[i-1] in stack[i].children;
- invariant forall i in [1..|stack|] :: stack[i-1].parent == stack[i];
- invariant 0 < |stack| ==> p == stack[0] && t in p.children && stack[|stack|-1].parent == null;
- invariant 0 == |stack| <==> p == null;
- // goal
- invariant forall n in S :: n.marked && n !in stack && n != t ==>
- (forall ch in n.children :: ch in S && ch.marked);
- invariant forall n in S :: n.marked ==>
- (forall m in n.path :: m in S) && Via(n, n.path, root);
- invariant forall n in S :: n !in stack ==> n.parent == null;
- // preservation
- invariant forall n in S :: n.children == old(n.children) && n.visited == 0;
- // termination
- invariant stop ==> |stack| == 0 && (forall ch in t.children :: ch.marked);
- {
- call n := PickUnmarked(t, t.children);
-
- if (n != null) {
- // push
- t.parent := p;
- p := t;
- stack := [t] ++ stack;
- n.path := [t] ++ t.path;
- t := n;
- t.marked := true;
- assert Via(t.path[0], t.path[1..], root); // limited function
- assert forall x in S :: x.marked ==> Via(x, x.path, root);
- assume forall x in S :: x.marked ==> Via(x, x.path, root);
- } else {
- // pop
- if (p == null) {
- stop := true;
- } else {
- t := p;
- p := t.parent;
- t.parent := null;
- stack := stack[1..];
- }
- }
- }
- }
-
- method PickUnmarked(n: Node, p: seq<Node>) returns (x: Node)
- requires rd(p[*].marked, 50);
- requires rd(n.*, 50);
- requires forall q in p :: q != null;
- requires p == n.children;
- ensures rd(p[*].marked, 50);
- ensures rd(n.*, 50);
- ensures x != null ==> x in p && ! x.marked;
- ensures x == null ==> (forall q in p :: q.marked);
- {
- assume false;
- }
-}
diff --git a/Chalice/tests/refinements/experiments/List.chalice b/Chalice/tests/refinements/experiments/List.chalice
deleted file mode 100644
index efcec2c8..00000000
--- a/Chalice/tests/refinements/experiments/List.chalice
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
-Interesting issues:
- * using functions in refinement to write getters
- * using functions to write coupling invariant
- * refining to a recursive implementation
- * restricting refinement (List1 must have at least one item)
- * refining a method with an output variable
-
-Do we shadows the abstract variables in the later concrete programs?
-
-How do we handle generic sequence in List2
-*/
-
-class List0 {
- var rep: seq<int>;
-
- method init()
- requires acc(this.*);
- ensures acc(rep);
- {
- rep := [0];
- }
-
- function length(): int
- requires acc(rep);
- {
- |rep|
- }
-
- method get(i: int) returns (v: int)
- requires acc(rep);
- requires 0 <= i && i < length();
- ensures acc(rep);
- {
- v := rep[i];
- }
-
- method pick() returns (v: int)
- requires acc(rep);
- ensures acc(rep);
- {
- var i: int;
- assume 0 <= i && i < length();
- v := rep[i];
- }
-}
-
-class List1 {
- ghost var rep: seq<int>;
-
- var data: int;
- var l: seq<List1>;
-
- function inv(): bool
- requires acc(rep) && acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l);
- {
- /** valid */ |l| >= 0 &&
- (forall i in [0..|l|] :: l[i] != null && l[i].l == l[i+1..]) &&
- /** coupling */ |l| + 1 == |rep| &&
- (forall i in [0..|l|] :: l[i].data == rep[i+1]) &&
- data == rep[0]
- }
-
- method init()
- requires acc(this.*);
- ensures acc(rep) && acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && inv();
- {
- rep := [0];
- data := 0;
- l := nil<List1>;
- }
-
- function length(): int
- requires acc(rep) && acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && inv();
- {
- |l| + 1
- }
-
- method checkLength()
- requires acc(rep) && acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && inv();
- {
- assert |l| + 1 == |rep|;
- }
-
- method get(i: int) returns (v: int)
- requires acc(rep) && acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && inv();
- requires 0 <= i && i < length();
- ensures acc(rep) && acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && inv();
- {
- if (i == 0) {
- v := data;
- } else {
- v := l[i-1].data;
- }
- assert v == rep[i];
- }
-}
-
-class List2 {
- // ghost var rep: seq<int>;
- ghost var l: seq<List2>;
-
- var data: int;
- var next: List2;
- var size: int;
-
- function inv(): bool
- requires acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && acc(size) && acc(next) && acc(l[*].size) && acc(l[*].next);
- {
- /** valid */ |l| >= 0 &&
- (forall i in [0..|l|] :: l[i] != null && l[i].l == l[i+1..]) &&
- /** new coupling */ size == |l| + 1 &&
- (next == null ==> |l| == 0) &&
- (next != null ==> |l| > 0 && next == l[0] && l[|l|-1].next == null) &&
- (forall i in [0..|l|] :: l[i].size == size - i - 1) &&
- (forall i in [0..|l|-1] :: l[i].next == l[i+1])
- }
-
- method init()
- requires acc(this.*);
- ensures acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && acc(size) && acc(next) && acc(l[*].size) && acc(l[*].next) && inv();
- {
- data := 0;
- l := nil<List2>;
- next := null;
- size := 1;
- }
-
- function length(): int
- requires acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && acc(size) && acc(next) && acc(l[*].size) && acc(l[*].next) && inv();
- {
- size
- }
-
- method checkLength()
- requires acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && acc(size) && acc(next) && acc(l[*].size) && acc(l[*].next) && inv();
- {
- assert size == |l| + 1;
- }
-
- method get(i: int) returns (v: int)
- requires acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && acc(size) && acc(next) && acc(l[*].size) && acc(l[*].next) && inv();
- requires 0 <= i && i < length();
- ensures acc(l) && acc(data) && acc(l[*].data) && acc(l[*].l) && acc(size) && acc(next) && acc(l[*].size) && acc(l[*].next) && inv();
- /** loop invariant: assertion on coupling of abstract and concrete outputs */
- ensures i == 0 ==> v == data;
- ensures i > 0 ==> i-1 < |l| && l[i-1] != null && v == l[i-1].data;
- {
- if (i == 0) {
- v := data;
- } else {
- assert next != null;
- assert l == [next] ++ next.l;
- call w := next.get(i-1);
- v := w;
- }
- }
-}
-
diff --git a/Chalice/tests/refinements/experiments/ListNode.chalice b/Chalice/tests/refinements/experiments/ListNode.chalice
deleted file mode 100644
index ae72fe67..00000000
--- a/Chalice/tests/refinements/experiments/ListNode.chalice
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
-Interesting issues:
- * recursive functions should either use read accesses or provide frame conditions of operating on the same state
- * carrying super-abstract state might be beneficial for the proof in the concrete program
- * proofs of function refinement might be needed as lemmas in places where they are used
-*/
-
-class List0 {
- var rep: seq<int>;
-
- method init()
- requires acc(this.*);
- ensures acc(rep);
- {
- rep := [0];
- }
-
- function length(): int
- requires acc(rep);
- {
- |rep|
- }
-
- method get(i: int) returns (v: int)
- requires acc(rep);
- requires 0 <= i && i < length();
- ensures acc(rep);
- {
- v := rep[i];
- }
-
- method pick() returns (v: int)
- requires acc(rep);
- ensures acc(rep);
- {
- var i: int;
- assume 0 <= i && i < length();
- v := rep[i];
- }
-}
-
-class Node1 {
- var data;
-}
-
-class List1 {
- ghost var rep: seq<int>;
- var l: seq<Node1>;
-
- function inv(): bool
- requires acc(rep) && acc(l) && acc(l[*].data);
- {
- /** valid */ (forall i in [0..|l|] :: l[i] != null) &&
- /** coupling */ |l| == |rep| && (forall i in [0..|l|] :: l[i].data == rep[i])
- }
-
- method init()
- requires acc(this.*);
- ensures acc(rep) && acc(l) && acc(l[*].data) && inv();
- {
- rep := nil<int>;
- l := nil<Node1>;
- }
-
- function length(): int
- requires acc(rep) && acc(l) && acc(l[*].data) && inv();
- {
- |l|
- }
-
- method checkLength()
- requires acc(rep) && acc(l) && acc(l[*].data) && inv();
- {
- assert length() == |rep|;
- }
-
- method get(i: int) returns (v: int)
- requires acc(rep) && acc(l) && acc(l[*].data) && inv();
- requires 0 <= i && i < length();
- ensures acc(rep) && acc(l) && acc(l[*].data) && inv();
- {
- v := l[i].data;
- assert v == rep[i];
- }
-}
-
-class Node2 {
- var data;
- var next: Node2;
-}
-
-class List2 {
- ghost var rep: seq<int>;
- ghost var l: seq<Node2>;
-
- var head: Node2;
- var size: int;
-
- function inv(): bool
- requires acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size)
- {
- /** valid */ (forall i in [0..|l|] :: l[i] != null) &&
- /** coupling */ |l| == |rep| && (forall i in [0..|l|] :: l[i].data == rep[i]) &&
- /** new coupling */ size == |l| &&
- (head == null ==> |l| == 0) &&
- (head != null ==> |l| > 0 && head == l[0] && l[|l|-1].next == null) &&
- (forall i in [0..|l|-1] :: l[i].next == l[i+1])
- }
-
- method init()
- requires acc(this.*);
- ensures acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size) && inv();
- {
- rep := nil<int>;
- l := nil<Node2>;
- head := null;
- size := 0;
- }
-
- function length(): int
- requires acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size) && inv();
- {
- size
- }
-
- method checkLength()
- requires acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size) && inv();
- {
- assert length() == |l|;
- }
-
- method get(i: int) returns (v: int)
- requires acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size) && inv();
- requires 0 <= i && i < length();
- ensures acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size) && inv();
- {
- call v := getrec(i, head, 0);
- assert v == l[i].data;
- }
-
- method getrec(i: int, n: Node2, /* ghost */ j: int) returns (v: int)
- requires acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size) && inv();
- requires length() == |l|;
- requires 0 <= i && i < length();
- requires 0 <= j && j <= i;
- requires l[j] == n;
- ensures acc(rep) && acc(l) && acc(l[*].data) && acc(l[*].next) && acc(head) && acc(size) && inv();
- // frame
- ensures l == old(l);
- ensures forall x in l :: x != null && x.data == old(x.data) && x.next == old(x.next);
- ensures size == old(size);
- ensures head == old(head);
- ensures rep == old(rep);
- ensures v == l[i].data;
- ensures l == old(l);
- {
- if (i == j) {
- v := n.data;
- } else {
- call v := getrec(i, n.next, j+1);
- }
- }
-}
diff --git a/Chalice/tests/refinements/experiments/ListPredicate.chalice b/Chalice/tests/refinements/experiments/ListPredicate.chalice
deleted file mode 100644
index af334093..00000000
--- a/Chalice/tests/refinements/experiments/ListPredicate.chalice
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Recursive implementation and specification of a linked list. */
-
-class Node {
- var next: Node;
- var value: int;
-
- method init(v: int)
- requires acc(next) && acc(value);
- ensures valid && size() == 1;
- {
- next := null;
- value := v;
- fold this.valid;
- }
-
- method append(x: int)
- requires valid;
- ensures valid;
- ensures size() == old(size())+1;
- {
- unfold this.valid;
- if(next==null) {
- var n : Node;
- n := new Node;
- call n.init(x);
- next := n;
- } else {
- call next.append(x);
- }
- fold this.valid;
- }
-
- method prepend(x: int) returns (rt: Node)
- requires valid;
- ensures rt!=null && rt.valid;
- ensures rt.size() == old(size()) + 1;
- {
- var n: Node;
- n := new Node;
- n.value := x;
- n.next := this;
- fold n.valid;
- rt := n;
- }
-
- function at(i: int): int
- requires valid && 0<=i && i<size();
- {
- unfolding valid in i==0 ? value : next.at(i-1)
- }
-
- function size(): int
- requires valid;
- {
- unfolding this.valid in (next!=null ? 1 + next.size() : 1)
- }
-
- predicate valid {
- acc(next) && acc(value) &&
- (next!=null ==> next.valid)
- }
-}
-
-// abstract sequence of integers
-class LinkedList {
- ghost var rep: seq<int>;
-
- var first: Node;
-
- method init()
- requires acc(this.*);
- ensures valid;
- {
- first := null;
- assert coupling(rep, first);
- fold valid;
- }
-
- method append(x: int)
- requires valid;
- ensures valid;
- {
- unfold valid;
- rep := rep ++ [x];
- fold valid;
- }
-
- method prepend(x: int)
- requires valid;
- ensures valid;
- {
- unfold valid;
- rep := [x] ++ rep;
- fold valid;
- }
-
- predicate valid {
- acc(rep) && acc(first) && (first != null ==> first.valid)
- }
-
- function coupling(a: seq<int>, c: Node) : bool
- requires c != null ==> c.valid;
- {
- c == null ? a == nil<int> :
- (|a| > 0 && a[0] == c.value && coupling(a[1..], c.next))
- }
-
-
-}
diff --git a/Chalice/tests/refinements/experiments/StringBuilder.chalice b/Chalice/tests/refinements/experiments/StringBuilder.chalice
deleted file mode 100644
index d73f8373..00000000
--- a/Chalice/tests/refinements/experiments/StringBuilder.chalice
+++ /dev/null
@@ -1,67 +0,0 @@
-class Char {}
-class StringBuilder0 {
- var rep: seq<Char>;
- method Init()
- requires acc(rep);
- ensures acc(rep);
- { rep := nil<Char>; }
- function ToString(): seq<Char>
- requires rd(rep);
- { rep }
- method Append(chars: seq<Char>)
- requires acc(rep);
- ensures acc(rep);
- ensures ToString() == old(ToString()) ++ chars;
- { rep := rep ++ chars; }
-}
-
-class Chunk0 {
- var rep: seq<Char>;
- ghost var start;
-}
-
-
-class StringBuilder1 refines StringBuilder0 {
- var chunks: seq<Chunk0>;
-
- replaces rep by acc(chunks) && acc(chunks[*].rep) && acc(chunks[*].start) &&
- /** representation invariant */ null !in chunks && |chunks| > 0 &&
- chunks[0].start == 0 &&
- (forall i in [0..|chunks|-1] :: chunks[i+1].start == chunks[i].start + |chunks[i].rep|) &&
- /** coupling invariant */ (forall c in chunks :: c.rep == rep[c.start..c.start + |c.rep|])
-
- refines Init()
- {
- var c := new Chunk0;
- c.rep := nil<Char>;
- c.start := 0;
- chunks := [c];
- rep := nil<Char>;
- }
-
-
- refines Append(chars: seq<Char>)
- {
- rep := rep ++ chars;
- var i; assume 0 <= i && i < |chars|;
- if (i > 0) {
- call AppendChunk(chunks[|chunks|-1], chars[..i]);
- }
- if (i < |chars| - 1) {
- call ExpandByABlock();
- call AppendChunk(chunks[|chunks|-1], chars[i..]);
- }
- }
-
- method AppendChunk(ch: Chunk0, chars: seq<Char>)
- {
- ch.rep := ch.rep ++ chars;
- }
-
- method ExpandByABlock()
- {
- var c := new Chunk0;
- c.rep := nil<Char>;
- chunks := chunks ++ [c];
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/refinements/test.bat b/Chalice/tests/refinements/test.bat
deleted file mode 100644
index 986647d6..00000000
--- a/Chalice/tests/refinements/test.bat
+++ /dev/null
@@ -1,47 +0,0 @@
-@echo off
-
-REM Regression tests for the refinement extension to Chalice
-REM Author: Kuat Yessenov
-
-setlocal EnableDelayedExpansion
-
-set chalice="%~dp0\..\..\chalice.bat"
-set output=Output
-set answer=Answer
-set parameters="-noTermination"
-set tests=LoopSqRoot,RecSqRoot,SpecStmt,SumCubes,TestTransform,TestRefines,RecFiniteDiff,LoopFiniteDiff,Pick,TestCoupling,Calculator,AngelicExec,RefinesLoop
-
-REM Remove stale output file
-if exist %output% del %output%
-
-echo -------------------------------------
-echo Refinement extension regression tests
-echo -------------------------------------
-
-REM Process each test
-for %%f in (%tests%) do (
- echo Processing %%f.chalice >> %output%
- echo Processing %%f
-
- if exist out.bpl del out.bpl
- call %chalice% "%%f.chalice" "%parameters%" >> %output% 2>&1
-)
-
-echo -------------------------------------
-
-REM Compare with the reference
-
-fc %answer% %output% > nul
-if not errorlevel 1 goto passTest
-goto failTest
-
-:passTest
-echo Passed
-if exist %output% del %output%
-if exist out.bpl del out.bpl
-exit /b 0
-
-:failTest
-echo Failed (see Output)
-exit /b 1
-
diff --git a/Chalice/tests/regressions/generate_reference.bat b/Chalice/tests/regressions/generate_reference.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/regressions/generate_reference.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/regressions/generate_reference_all.bat b/Chalice/tests/regressions/generate_reference_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/regressions/generate_reference_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/regressions/internal-bug-1.chalice b/Chalice/tests/regressions/internal-bug-1.chalice
deleted file mode 100644
index 10caeebb..00000000
--- a/Chalice/tests/regressions/internal-bug-1.chalice
+++ /dev/null
@@ -1,16 +0,0 @@
-class Test {
- var next: Test;
- var elem: int;
-
- predicate valid {
- acc(elem) && acc(next) &&
- (next != null ==> next.valid)
- }
-
- function get(index:int):int
- requires valid
- // on 2012-02-21, a bug was reported that caused Chalice to crash with an
- // InternalError for the following precondition.
- requires unfolding valid in true
- {0}
-}
diff --git a/Chalice/tests/regressions/internal-bug-1.output.txt b/Chalice/tests/regressions/internal-bug-1.output.txt
deleted file mode 100644
index 7685b77a..00000000
--- a/Chalice/tests/regressions/internal-bug-1.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of internal-bug-1.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/internal-bug-2.chalice b/Chalice/tests/regressions/internal-bug-2.chalice
deleted file mode 100644
index ac6b5a09..00000000
--- a/Chalice/tests/regressions/internal-bug-2.chalice
+++ /dev/null
@@ -1,13 +0,0 @@
-class Lala {
- var x;
-
- predicate inv { acc(x) }
-
- method koko()
- requires inv
- {
- x := x + 1;
- assert (unfolding inv in x) == old(unfolding inv in x)
- }
-}
-
diff --git a/Chalice/tests/regressions/internal-bug-2.output.txt b/Chalice/tests/regressions/internal-bug-2.output.txt
deleted file mode 100644
index 8724af64..00000000
--- a/Chalice/tests/regressions/internal-bug-2.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of internal-bug-2.chalice using parameters=""
-
- 9.9: Location might not be writable
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 6.5: The end of method koko is unreachable.
-
-Boogie program verifier finished with 1 errors and 1 smoke test warnings
diff --git a/Chalice/tests/regressions/internal-bug-3.chalice b/Chalice/tests/regressions/internal-bug-3.chalice
deleted file mode 100644
index 17b6dd25..00000000
--- a/Chalice/tests/regressions/internal-bug-3.chalice
+++ /dev/null
@@ -1,8 +0,0 @@
-class C
-{
- var f: int
- method M ()
- requires acc(f, 100-rd(non_existing_field))
- {
- }
-}
diff --git a/Chalice/tests/regressions/internal-bug-3.output.txt b/Chalice/tests/regressions/internal-bug-3.output.txt
deleted file mode 100644
index 5f5ebd08..00000000
--- a/Chalice/tests/regressions/internal-bug-3.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of internal-bug-3.chalice using parameters=""
-
-The program did not typecheck.
-5.28: undeclared member non_existing_field in class C
diff --git a/Chalice/tests/regressions/internal-bug-4.chalice b/Chalice/tests/regressions/internal-bug-4.chalice
deleted file mode 100644
index af850d49..00000000
--- a/Chalice/tests/regressions/internal-bug-4.chalice
+++ /dev/null
@@ -1,17 +0,0 @@
-class C
-{
- var f: int;
- predicate valid { acc(f) }
-
- function foo1(): int
- ensures valid;
- { 1 }
-
- function foo2(): int
- ensures acc(f);
- { 1 }
-
- function foo3(): int
- ensures rd(f);
- { 1 }
-}
diff --git a/Chalice/tests/regressions/internal-bug-4.output.txt b/Chalice/tests/regressions/internal-bug-4.output.txt
deleted file mode 100644
index a985df28..00000000
--- a/Chalice/tests/regressions/internal-bug-4.output.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Verification of internal-bug-4.chalice using parameters=""
-
-The program did not typecheck.
-7.3: the postcondition of functions cannot contain accessibility predicates (permissions are returned automatically)
-11.3: the postcondition of functions cannot contain accessibility predicates (permissions are returned automatically)
-15.3: the postcondition of functions cannot contain accessibility predicates (permissions are returned automatically)
diff --git a/Chalice/tests/regressions/internal-bug-5.chalice b/Chalice/tests/regressions/internal-bug-5.chalice
deleted file mode 100644
index 35dfcb88..00000000
--- a/Chalice/tests/regressions/internal-bug-5.chalice
+++ /dev/null
@@ -1,38 +0,0 @@
-class Cell {
- var x: int;
- var b: bool;
-
- predicate valid {
- acc(this.b) && (this.b ==> acc(this.x,50))
- }
-
- method m()
- requires this.valid && (unfolding valid in this.b) && acc(this.mu) && waitlevel << mu
- {
- acquire this;
-
- var c := (unfolding valid in this.x);
- release this;
- acquire this;
- assert c == this.x;
- call n();
- c := (unfolding valid in this.x);
- release this;
- acquire this;
- // ERROR: this is not supposed to verify (it did in previous versions of Chalice)
- assert c == this.x;
- release this;
- }
-
- method n()
- requires this.valid
- ensures this.valid
- {
- unfold this.valid;
- this.b := false;
- fold this.valid;
- }
-
- invariant acc(this.x,50)
-}
-
diff --git a/Chalice/tests/regressions/internal-bug-5.output.txt b/Chalice/tests/regressions/internal-bug-5.output.txt
deleted file mode 100644
index 3b6cc316..00000000
--- a/Chalice/tests/regressions/internal-bug-5.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of internal-bug-5.chalice using parameters=""
-
- 23.5: Assertion might not hold. The expression at 23.12 might not evaluate to true.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/internal-bug-6.chalice b/Chalice/tests/regressions/internal-bug-6.chalice
deleted file mode 100644
index b02c1a65..00000000
--- a/Chalice/tests/regressions/internal-bug-6.chalice
+++ /dev/null
@@ -1,10 +0,0 @@
-class Cell {
-
- function foo(): Cell
- { this }
-
- method m(b: bool)
- {
- var c: Cell := b ? null : foo()
- }
-}
diff --git a/Chalice/tests/regressions/internal-bug-6.output.txt b/Chalice/tests/regressions/internal-bug-6.output.txt
deleted file mode 100644
index 5b7560cd..00000000
--- a/Chalice/tests/regressions/internal-bug-6.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of internal-bug-6.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/internal-bug-7.chalice b/Chalice/tests/regressions/internal-bug-7.chalice
deleted file mode 100644
index 9f7d474d..00000000
--- a/Chalice/tests/regressions/internal-bug-7.chalice
+++ /dev/null
@@ -1,26 +0,0 @@
-class Node {
- var n: Node
-
- predicate P { acc(n) && (n != null ==> acc(n.P)) }
-
- function length(): int
- requires rd(P)
- ensures result >= 1
- { unfolding rd(P) in 1 + (n == null ? 0 : n.length()) }
-
-}
-
-class Test {
- method test(node: Node)
- requires node != null
- requires acc(node.P)
- {
- assert node.length() >= 1
- assert (unfolding rd(node.P) in node.n == null) ==> (node.length() == 1) /* Holds in Chalice and Syxc */
- //assert (unfolding rd(node.P) in node.n != null) ==> (unfolding rd(node.P) in node.n.length() >= 1) /* Holds in Chalice and Syxc */
- assert (unfolding rd(node.P) in node.n != null) ==> (node.length() > 1) /* Holds in Chalice and Syxc */
- assert (node.length() == 1) ==> (unfolding rd(node.P) in node.n == null) /* Fails in Chalice and Syxc */
- assert (node.length() == 1) <==> (unfolding rd(node.P) in node.n == null)
- // assert n.length() > 1 <==> unfolding rd(n.P) in n.n != null /* Fails in Chalice and Syxc */
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/internal-bug-7.output.txt b/Chalice/tests/regressions/internal-bug-7.output.txt
deleted file mode 100644
index 78ae95fd..00000000
--- a/Chalice/tests/regressions/internal-bug-7.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of internal-bug-7.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/reg_test.bat b/Chalice/tests/regressions/reg_test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/regressions/reg_test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/regressions/reg_test_all.bat b/Chalice/tests/regressions/reg_test_all.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/regressions/reg_test_all.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/regressions/test.bat b/Chalice/tests/regressions/test.bat
deleted file mode 100644
index c9b04fcd..00000000
--- a/Chalice/tests/regressions/test.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-call "..\test-scripts\%~nx0" %*
diff --git a/Chalice/tests/regressions/workitem-10147.chalice b/Chalice/tests/regressions/workitem-10147.chalice
deleted file mode 100644
index eb6f31c7..00000000
--- a/Chalice/tests/regressions/workitem-10147.chalice
+++ /dev/null
@@ -1,22 +0,0 @@
-class Cell {
-
- var x: int;
-
- // the declaration of a method with the same name for a parameter
- // as well as a result alone does not yet cause a problem, but ...
- method problematic_method(c: Cell) returns (c: Cell)
- requires acc(c.x);
- {
- }
-
- // ... calling it leads to various 'undeclared identifier' errors
- // in boogie. (previously. now fixed by not allowing c as both in and out parameter)
- method error()
- {
- var a: Cell := new Cell;
- var b: Cell;
-
- call b := problematic_method(a);
- }
-
-}
diff --git a/Chalice/tests/regressions/workitem-10147.output.txt b/Chalice/tests/regressions/workitem-10147.output.txt
deleted file mode 100644
index 63bb3c9c..00000000
--- a/Chalice/tests/regressions/workitem-10147.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10147.chalice using parameters=""
-
-The program did not typecheck.
-7.3: duplicate parameter c of method problematic_method in class Cell
diff --git a/Chalice/tests/regressions/workitem-10189.chalice b/Chalice/tests/regressions/workitem-10189.chalice
deleted file mode 100644
index b37b83f2..00000000
--- a/Chalice/tests/regressions/workitem-10189.chalice
+++ /dev/null
@@ -1,23 +0,0 @@
-class Node {
- var v: int
- var next: Node
-
- predicate V {
- acc(v)
- && acc(next)
- && (next != null ==> next.V)
- }
-
- unlimited function length(): int
- requires rd(V)
- { 1 + unfolding rd(V) in next == null ? 0 : next.length() }
-
- unlimited function at(i: int): int
- requires rd(V)
- requires i >= 0
- requires i < length() // XXXX
- {
- unfolding rd(V) in i == 0 ? v : next.at(i - 1)
- // Precondition at XXX might not hold
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10189.output.txt b/Chalice/tests/regressions/workitem-10189.output.txt
deleted file mode 100644
index 96f05468..00000000
--- a/Chalice/tests/regressions/workitem-10189.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10189.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10190.chalice b/Chalice/tests/regressions/workitem-10190.chalice
deleted file mode 100644
index ad84553a..00000000
--- a/Chalice/tests/regressions/workitem-10190.chalice
+++ /dev/null
@@ -1,6 +0,0 @@
-// previously resulted in a StackOverFlowError of the Chalice parser
-class Node {
-/*
-Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
-*/
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10190.output.txt b/Chalice/tests/regressions/workitem-10190.output.txt
deleted file mode 100644
index e314cbd3..00000000
--- a/Chalice/tests/regressions/workitem-10190.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of workitem-10190.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 verified, 1 error
-
diff --git a/Chalice/tests/regressions/workitem-10192.chalice b/Chalice/tests/regressions/workitem-10192.chalice
deleted file mode 100644
index 06ff5881..00000000
--- a/Chalice/tests/regressions/workitem-10192.chalice
+++ /dev/null
@@ -1,19 +0,0 @@
-class Sequences {
- var xs: seq<int>
-
- method append(a: int)
- requires acc(xs)
- ensures acc(xs)
- ensures size() == old(size()) + 1 /* verifies */
- ensures |xs| == old(|xs|) + 1 /* previously failed */
- { xs := xs ++ [a] }
-
- /* this heap-independent version also verifies. */
- method append0(ins: seq<int>, a: int) returns (outs: seq<int>)
- ensures |outs| == |ins| + 1
- { outs := ins ++ [a] }
-
- function size(): int
- requires rd(xs)
- { |xs| }
-}
diff --git a/Chalice/tests/regressions/workitem-10192.output.txt b/Chalice/tests/regressions/workitem-10192.output.txt
deleted file mode 100644
index f2a5b539..00000000
--- a/Chalice/tests/regressions/workitem-10192.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10192.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10194.chalice b/Chalice/tests/regressions/workitem-10194.chalice
deleted file mode 100644
index 5828b0bf..00000000
--- a/Chalice/tests/regressions/workitem-10194.chalice
+++ /dev/null
@@ -1,37 +0,0 @@
-class Test {
- var x: int
- var tk: token<Test.incX>
-
- predicate V { acc(x) }
-
- method incX()
- requires V
- ensures V
- {
- unfold V
- x := x + 1
- fold V
- }
-
- method joinTk()
- requires acc(tk) && tk != null && acc(tk.joinable) && tk.joinable
- requires eval(tk.fork this.incX(), true)
- ensures V
- ensures unfolding V in x == old(x) // ERROR: old(x) is not readable (no error here, previously)
- {
- join tk
- assert V
- }
-
- method test()
- requires acc(x) && x == 0
- requires acc(tk)
- {
- fold V
- fork tklocal := incX()
- tk := tklocal
- call joinTk()
- unfold V
- assert x == old(x) // this verified previously (without any errors anywhere in the file)
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10194.output.txt b/Chalice/tests/regressions/workitem-10194.output.txt
deleted file mode 100644
index 23114b0a..00000000
--- a/Chalice/tests/regressions/workitem-10194.output.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Verification of workitem-10194.chalice using parameters=""
-
- 20.35: Location might not be readable.
- 35.3: Assertion might not hold. The expression at 35.10 might not evaluate to true.
-
-Boogie program verifier finished with 2 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10195.chalice b/Chalice/tests/regressions/workitem-10195.chalice
deleted file mode 100644
index 99ea69f8..00000000
--- a/Chalice/tests/regressions/workitem-10195.chalice
+++ /dev/null
@@ -1,38 +0,0 @@
-class Test {
- method fails()
- {
- assert forall j in [10..5] :: true // ERROR: min > max
- assert false // failed previously, now we get a smoke warning
- }
-
- method succeeds1()
- {
- assert forall j in [10..5] :: f(j) == 0 // ERROR: min > max
- assert false // failed previously, now we get a smoke warning
- }
-
- method fails1()
- {
- assert forall j in [5..10] :: f(j) == 0
- }
-
- method succeeds2(a: int, b: int)
- requires 0 <= a && 0 <= b
- requires f(a) < f(b)
- {
- assert forall j in [f(b)..f(a)] :: f(j) == 0 // ERROR: min > max
- assert false // holds
- }
-
- method fails2(a: int, b: int)
- requires 0 <= a && 0 <= b
- requires 0 < f(a)
- requires f(a) < f(b)
- {
- assert forall j in [f(a)..f(b)] :: f(j) == 0
- }
-
- function f(i: int): int
- requires 0 <= i
- { 0 }
- } \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10195.output.txt b/Chalice/tests/regressions/workitem-10195.output.txt
deleted file mode 100644
index 6e8b3556..00000000
--- a/Chalice/tests/regressions/workitem-10195.output.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Verification of workitem-10195.chalice using parameters=""
-
- 4.14: Range minimum might not be smaller or equal to range maximum.
- 10.14: Range minimum might not be smaller or equal to range maximum.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 2.5: The end of method fails is unreachable.
- 8.5: The end of method succeeds1 is unreachable.
- 19.9: Precondition of method succeeds2 is equivalent to false.
- 27.9: Precondition of method fails2 is equivalent to false.
-
-Boogie program verifier finished with 2 errors and 4 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10196.chalice b/Chalice/tests/regressions/workitem-10196.chalice
deleted file mode 100644
index 9257e5c2..00000000
--- a/Chalice/tests/regressions/workitem-10196.chalice
+++ /dev/null
@@ -1,11 +0,0 @@
-class C {
- method singleWarning()
- { assert forall i in [] :: true } // previously, quantification over the empty list resulted in Boogie errors
-
- method multipleWarnings()
- { assert forall i in [] :: reqIGt0(i) == i } // previously, quantification over the empty list resulted in Boogie errors
-
- function reqIGt0(i: int): int
- requires i >= 0
- { i }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10196.output.txt b/Chalice/tests/regressions/workitem-10196.output.txt
deleted file mode 100644
index 26199999..00000000
--- a/Chalice/tests/regressions/workitem-10196.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10196.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10197.chalice b/Chalice/tests/regressions/workitem-10197.chalice
deleted file mode 100644
index 7212581c..00000000
--- a/Chalice/tests/regressions/workitem-10197.chalice
+++ /dev/null
@@ -1,7 +0,0 @@
-class Cell { var x: int }
-
-class Test {
- method noop()
- ensures old(waitlevel) == waitlevel // previously resulted in Boogie errors
- {}
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10197.output.txt b/Chalice/tests/regressions/workitem-10197.output.txt
deleted file mode 100644
index c83bbfe0..00000000
--- a/Chalice/tests/regressions/workitem-10197.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10197.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10198.chalice b/Chalice/tests/regressions/workitem-10198.chalice
deleted file mode 100644
index fd51977d..00000000
--- a/Chalice/tests/regressions/workitem-10198.chalice
+++ /dev/null
@@ -1,17 +0,0 @@
-class Cell { var x: int }
-
-class Test {
- method get() returns (c: Cell)
- ensures c != null
- lockchange c /* previosly, this introduced errors */
- {
- c := new Cell
- }
-
- /* method was needed to get Boogie errors */
- method testRd() // expected ERROR: method might lock/unlock more than allowed
- {
- var x: Cell
- call x := get()
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10198.output.txt b/Chalice/tests/regressions/workitem-10198.output.txt
deleted file mode 100644
index c3b59307..00000000
--- a/Chalice/tests/regressions/workitem-10198.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of workitem-10198.chalice using parameters=""
-
- 12.2: Method might lock/unlock more than allowed.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10199.chalice b/Chalice/tests/regressions/workitem-10199.chalice
deleted file mode 100644
index 678ed078..00000000
--- a/Chalice/tests/regressions/workitem-10199.chalice
+++ /dev/null
@@ -1,21 +0,0 @@
-class Test {
- var z: int
-
- predicate Z { acc(z) }
- predicate ZZ { Z } // XXX
-
- method useZZ()
- requires ZZ
- {
- // (ZZ,100)
- unfold acc(ZZ, 40)
- // (ZZ, 60), (Z, 40)
- unfold acc(Z, 20)
- // (ZZ, 60), (Z, 20), (z, 20)
- fold acc(Z, 10)
- // (ZZ, 60), (Z, 30), (z, 10)
- fold acc(ZZ, 30)
- // previoulsy: Fold might fail because the definition of Test.ZZ does not hold. Insufficient fraction at XXX for Test.Z.
- // Should be (ZZ, 90), (z, 10)
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10199.output.txt b/Chalice/tests/regressions/workitem-10199.output.txt
deleted file mode 100644
index 660fd6ae..00000000
--- a/Chalice/tests/regressions/workitem-10199.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10199.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10200.chalice b/Chalice/tests/regressions/workitem-10200.chalice
deleted file mode 100644
index a7394793..00000000
--- a/Chalice/tests/regressions/workitem-10200.chalice
+++ /dev/null
@@ -1,25 +0,0 @@
-class Test {
- var f: int;
-
- function fib(n: int): int
- requires n >= 0
- {
- n < 2 ? n : fib(n - 1) + fib(n - 2) // incompletness: termination not atomatically proven
- }
-
- method fibSeq(n: int) returns (r: int)
- requires n >= 0
- requires acc(this.f)
- ensures acc(this.f)
- ensures r == fib(n) // previous error: the postcondition might not hold
- {
- if (n < 2) {
- r := n
- } else {
- var f1: int; var f2: int
- call f1 := fibSeq(n - 1)
- call f2 := fibSeq(n - 2)
- r := f1 + f2
- }
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10200.output.txt b/Chalice/tests/regressions/workitem-10200.output.txt
deleted file mode 100644
index 90d5b467..00000000
--- a/Chalice/tests/regressions/workitem-10200.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of workitem-10200.chalice using parameters=""
-
- 7.15: The heap of the callee might not be strictly smaller than the heap of the caller.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10208.chalice b/Chalice/tests/regressions/workitem-10208.chalice
deleted file mode 100644
index ae1a7d89..00000000
--- a/Chalice/tests/regressions/workitem-10208.chalice
+++ /dev/null
@@ -1,41 +0,0 @@
-class Test {
- var f1: int;
- var f2: int;
-
- predicate valid {
- acc(f1) && acc(f2) && f1 == f2
- }
-
- method test()
- requires valid
- {
- unfold valid
- f1 := 2
- f2 := 2
- fold valid
-
- /* --- not strictly necessary */
- unfold valid
- assert f1 == 2
- fold valid
- /* --- */
-
- call test2()
-
- unfold valid
- assert f1 == 2 // BUG: this should not verify (1)
- assert false // BUG: this should not verify (2)
- }
-
- method test2()
- requires valid
- ensures valid
- ensures unfolding valid in f1 == 1 // line (1) above verifies also without this postcondition
- {
- unfold valid
- f1 := 1
- f2 := 1
- fold valid
- }
-
-}
diff --git a/Chalice/tests/regressions/workitem-10208.output.txt b/Chalice/tests/regressions/workitem-10208.output.txt
deleted file mode 100644
index 0666393a..00000000
--- a/Chalice/tests/regressions/workitem-10208.output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Verification of workitem-10208.chalice using parameters=""
-
- 26.5: Assertion might not hold. The expression at 26.12 might not evaluate to true.
-
-The program did not fully verify; the smoke warnings might be misleading if contradictions are introduced by failing proof attempts of the verification.
- 9.3: The end of method test is unreachable.
-
-Boogie program verifier finished with 1 errors and 1 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10221.chalice b/Chalice/tests/regressions/workitem-10221.chalice
deleted file mode 100644
index 2a8ae723..00000000
--- a/Chalice/tests/regressions/workitem-10221.chalice
+++ /dev/null
@@ -1,158 +0,0 @@
-// In this example, additional unfold/fold pairs make the verification of the last three methods fail.
-
-class Node {
- var next : Node;
- var val : int;
-
- predicate list {
- acc(next) && acc(val) && (next!=null ==> next.list)
- }
-
- function vals() : seq<int>
- requires list
- {
- unfolding list in (next == null ? [val] : [val] ++ next.vals())
- }
-
- function reverse_vals() : seq<int>
- requires list
- {
- unfolding list in (next == null ? [val] : next.reverse_vals() ++ [val])
- }
-
- method reverse_in_place() returns (r:Node)
- requires list;
- ensures true;
- {
- var l : Node := this;
- r := null;
-
- var rev : seq<int> := this.reverse_vals();
-
- while (l != null)
- invariant l!=null ==> l.list;
- invariant r!=null ==> r.list;
- invariant rev == (l==null ? nil<int> : l.reverse_vals()) ++ (r==null ? nil<int> : r.vals());
- {
- var y: Node;
-// if (r != null) {
-// unfold r.list; fold r.list;
-// }
- unfold l.list;
-// if (l.next != null) {
-// unfold l.next.list; fold l.next.list;
-// }
-
- y := l.next;
- l.next := r;
- r := l;
- fold r.list;
- l := y;
- }
- assert r.vals() == rev; // should be the post-condition
- }
-
-
- method reverse_in_place_01() returns (r:Node)
- requires list;
- ensures true;
- {
- var l : Node := this;
- r := null;
-
- var rev : seq<int> := this.reverse_vals();
-
- while (l != null)
- invariant l!=null ==> l.list;
- invariant r!=null ==> r.list;
- invariant rev == (l==null ? nil<int> : l.reverse_vals()) ++ (r==null ? nil<int> : r.vals());
- {
- var y: Node;
-// if (r != null) {
-// unfold r.list; fold r.list;
-// }
- unfold l.list;
- if (l.next != null) {
- unfold l.next.list; fold l.next.list;
- }
-
- y := l.next;
- l.next := r;
- r := l;
- fold r.list;
- l := y;
- }
- assert r.vals() == rev; // should be the post-condition
- }
-
-
-
- method reverse_in_place_10() returns (r:Node)
- requires list;
- ensures true;
- {
- var l : Node := this;
- r := null;
-
- var rev : seq<int> := this.reverse_vals();
-
- while (l != null)
- invariant l!=null ==> l.list;
- invariant r!=null ==> r.list;
- invariant rev == (l==null ? nil<int> : l.reverse_vals()) ++ (r==null ? nil<int> : r.vals());
- {
- var y: Node;
- if (r != null) {
- unfold r.list; fold r.list;
- }
- unfold l.list;
-// if (l.next != null) {
-// unfold l.next.list; fold l.next.list;
-// }
-
- y := l.next;
- l.next := r;
- r := l;
- fold r.list;
- l := y;
- }
- assert r.vals() == rev; // should be the post-condition
- }
-
-
-
-
- method reverse_in_place_11() returns (r:Node)
- requires list;
- ensures true;
- {
- var l : Node := this;
- r := null;
-
- var rev : seq<int> := this.reverse_vals();
-
- while (l != null)
- invariant l!=null ==> l.list;
- invariant r!=null ==> r.list;
- invariant rev == (l==null ? nil<int> : l.reverse_vals()) ++ (r==null ? nil<int> : r.vals());
- {
- var y: Node;
- if (r != null) {
- unfold r.list; fold r.list;
- }
- unfold l.list;
- if (l.next != null) {
- unfold l.next.list; fold l.next.list;
- }
-
- y := l.next;
- l.next := r;
- r := l;
- fold r.list;
- l := y;
- }
- assert r.vals() == rev; // should be the post-condition
- }
-
-
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-10221.output.txt b/Chalice/tests/regressions/workitem-10221.output.txt
deleted file mode 100644
index e209c3c1..00000000
--- a/Chalice/tests/regressions/workitem-10221.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10221.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-10222.chalice b/Chalice/tests/regressions/workitem-10222.chalice
deleted file mode 100644
index a01253c9..00000000
--- a/Chalice/tests/regressions/workitem-10222.chalice
+++ /dev/null
@@ -1,8 +0,0 @@
-class Test {
- var t: Test;
-
- // previously, mentioning "waitlevel" in a predicate did not cause an error
- predicate inv {
- acc(t) && acc(t.mu) && t.mu << waitlevel
- }
-}
diff --git a/Chalice/tests/regressions/workitem-10222.output.txt b/Chalice/tests/regressions/workitem-10222.output.txt
deleted file mode 100644
index eac18363..00000000
--- a/Chalice/tests/regressions/workitem-10222.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10222.chalice using parameters=""
-
-The program did not typecheck.
-6.9: predicate body is not allowed to mention 'waitlevel'
diff --git a/Chalice/tests/regressions/workitem-10223.chalice b/Chalice/tests/regressions/workitem-10223.chalice
deleted file mode 100644
index eb4bd00b..00000000
--- a/Chalice/tests/regressions/workitem-10223.chalice
+++ /dev/null
@@ -1,8 +0,0 @@
-class Lala {
- var next: Lala;
- var x: int;
- predicate inv {
- acc(next) && acc(x) &&
- (next != null ==> (next.inv && unfolding next.inv in this.x > next.x))
- }
-}
diff --git a/Chalice/tests/regressions/workitem-10223.output.txt b/Chalice/tests/regressions/workitem-10223.output.txt
deleted file mode 100644
index b65fbc0c..00000000
--- a/Chalice/tests/regressions/workitem-10223.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-10223.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-8234.chalice b/Chalice/tests/regressions/workitem-8234.chalice
deleted file mode 100644
index 5fbcea02..00000000
--- a/Chalice/tests/regressions/workitem-8234.chalice
+++ /dev/null
@@ -1,26 +0,0 @@
-class Test{
- var tests : seq<Test>;
- var total : int;
-
- invariant acc(tests, 100);
- invariant acc(total, 50);
-
- function at(loc : int) : Test
- requires acc(tests);
- requires loc >= 0 && loc < size();
- {
- tests[loc]
- }
-
-
- function size() : int
- requires acc(tests);
- ensures result >= 0;
- ensures result == |tests|; // previously, there was a nullpointer exception here
- {
- |tests|
- }
-
- predicate pre
- { acc(total, 50) }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-8234.output.txt b/Chalice/tests/regressions/workitem-8234.output.txt
deleted file mode 100644
index 14175fd2..00000000
--- a/Chalice/tests/regressions/workitem-8234.output.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Verification of workitem-8234.chalice using parameters=""
-
-
-Boogie program verifier finished with 0 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-8236.chalice b/Chalice/tests/regressions/workitem-8236.chalice
deleted file mode 100644
index 819bdb74..00000000
--- a/Chalice/tests/regressions/workitem-8236.chalice
+++ /dev/null
@@ -1,16 +0,0 @@
-class Bug{
-
- method Main() // expected ERROR: method might lock/unlock more than allowed
- {
- var a : Bug;
- call a:= m();
- }
-
- method m() returns (a : Bug)
- lockchange a // resulted previously in Boogie errors
- {
- a := new Bug;
- share a;
- acquire a;
- }
-} \ No newline at end of file
diff --git a/Chalice/tests/regressions/workitem-8236.output.txt b/Chalice/tests/regressions/workitem-8236.output.txt
deleted file mode 100644
index 6f1994d3..00000000
--- a/Chalice/tests/regressions/workitem-8236.output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Verification of workitem-8236.chalice using parameters=""
-
- 3.2: Method might lock/unlock more than allowed.
-
-Boogie program verifier finished with 1 errors and 0 smoke test warnings
diff --git a/Chalice/tests/regressions/workitem-9978.chalice b/Chalice/tests/regressions/workitem-9978.chalice
deleted file mode 100644
index 02cd2e66..00000000
--- a/Chalice/tests/regressions/workitem-9978.chalice
+++ /dev/null
@@ -1,9 +0,0 @@
-class C {
- method nullPointerException()
- {
- while (true)
- {
- fork nullPointerException(); // previously, fork without token inside a while loop introduced a nullpointer exception.
- }
- }
-}
diff --git a/Chalice/tests/regressions/workitem-9978.output.txt b/Chalice/tests/regressions/workitem-9978.output.txt
deleted file mode 100644
index e6086625..00000000
--- a/Chalice/tests/regressions/workitem-9978.output.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Verification of workitem-9978.chalice using parameters=""
-
-
- 4.5: The statements after the while-loop are unreachable.
-
-Boogie program verifier finished with 0 errors and 1 smoke test warnings
diff --git a/Chalice/tests/runalltests.bat b/Chalice/tests/runalltests.bat
deleted file mode 100644
index eb26d4ec..00000000
--- a/Chalice/tests/runalltests.bat
+++ /dev/null
@@ -1,37 +0,0 @@
-@echo off
-
-setlocal EnableDelayedExpansion
-
-:: no-summary command line parameter
-set nosummary=0
-if "%1"=="-no-summary" (
- set nosummary=1
- SHIFT
-)
-
-set t=0
-set c=0
-for %%f in (examples permission-model general-tests regressions predicates) do (
- echo Running tests in %%f ...
- echo ------------------------------------------------------
- cd %%f
- set tt=0
- for %%f in (*.chalice) do set /A tt+=1
- call reg_test_all.bat -no-summary %1 %2 %3 %4 %5
- set /A c=!c!+!errorlevel!
- set /A t=!t!+!tt!
- cd ..
- echo ------------------------------------------------------
-)
-
-REM Run refinement regression tests
-cd refinements
-REM call test.bat
-cd ..
-
-if !nosummary!==0 (
- echo.
- if !c!==0 (echo SUMMARY: completed !t! tests successfully.) else (echo SUMMARY: !c! of !t! tests failed.)
-)
-
-exit /b !c!
diff --git a/Chalice/tests/test-scripts/diff.bat b/Chalice/tests/test-scripts/diff.bat
deleted file mode 100644
index 87fa935f..00000000
--- a/Chalice/tests/test-scripts/diff.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@echo off
-
-set differ="C:\Program Files\TortoiseSVN\bin\TortoiseMerge.exe"
-if exist %differ% goto :diff
-if not exist %differ% goto :txtdiff
-
-:txtdiff
-echo ====================================
-echo Reference output: %1
-echo ------------------------------------
-type "%1"
-echo ====================================
-echo Currenct output: %2
-echo ------------------------------------
-type "%2"
-echo ====================================
-goto :eof
-
-:diff
-%differ% "%1" "%2"
-goto :eof
diff --git a/Chalice/tests/test-scripts/generate_reference.bat b/Chalice/tests/test-scripts/generate_reference.bat
deleted file mode 100644
index 0c480e5c..00000000
--- a/Chalice/tests/test-scripts/generate_reference.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-@echo off
-set getboogieoutput="%~dp0\getboogieoutput.bat"
-
-echo Generating reference for %1.chalice ...
-call %getboogieoutput% %1 %2 %3 %4 %5 %6 %7
-
-exit /b 0
diff --git a/Chalice/tests/test-scripts/generate_reference_all.bat b/Chalice/tests/test-scripts/generate_reference_all.bat
deleted file mode 100644
index 1e9e7cfb..00000000
--- a/Chalice/tests/test-scripts/generate_reference_all.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@echo off
-
-set generatereference="%~dp0\generate_reference.bat"
-
-for /F %%f in ('dir *.chalice /b') do (
- call %generatereference% %%~nf %1 %2 %3 %4 %5 %6 %7
-)
-
-exit /b 0
diff --git a/Chalice/tests/test-scripts/getboogieoutput.bat b/Chalice/tests/test-scripts/getboogieoutput.bat
deleted file mode 100644
index 76af1fcf..00000000
--- a/Chalice/tests/test-scripts/getboogieoutput.bat
+++ /dev/null
@@ -1,33 +0,0 @@
-@echo off
-set chalice="%~dp0\..\..\chalice.bat"
-set getparams="%~dp0\getparams.bat"
-
-set output="%1.output.txt"
-
-:: get parameters
-set chaliceparameters=
-setlocal EnableDelayedExpansion
-set done=0
-set key=a
-FOR /F "usebackq tokens=1,2 delims==" %%i in (%1.chalice) do (
-
- if !done!==0 (
- set key=%%i
- set param=%%j
- )
-
- set done=1
-)
-set str=// chalice-parameter
-if "!key!"=="!str!" (
- set chaliceparameters=!param!
-)
-
-echo Verification of %1.chalice using parameters="%chaliceparameters%" > %output%
-echo.>> %output%
-call %chalice% "%1.chalice" -smoke -time:0 %chaliceparameters% %2 %3 %4 %5 %6 %7 >> %output% 2>&1
-
-set o=%~dp1%out.bpl
-if exist "%o%" copy "%o%" "%1.bpl">nul
-if exist "%o%" del "%~dp1%out.bpl"
-goto :eof
diff --git a/Chalice/tests/test-scripts/readme.txt b/Chalice/tests/test-scripts/readme.txt
deleted file mode 100644
index d4f408e8..00000000
--- a/Chalice/tests/test-scripts/readme.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-The scripts in this directory are NOT meant for direct execution, but rather
-provide the implementation of the same-named scripts in the actual test folders.
diff --git a/Chalice/tests/test-scripts/reg_test.bat b/Chalice/tests/test-scripts/reg_test.bat
deleted file mode 100644
index 54549afc..00000000
--- a/Chalice/tests/test-scripts/reg_test.bat
+++ /dev/null
@@ -1,75 +0,0 @@
-@echo off
-setlocal
-set chalice="%~dp0\..\..\chalice.bat"
-set diff="%~dp0\diff.bat"
-
-:: no-diff command line parameter
-set nodiff=0
-if "%1"=="-no-diff" (
- set nodiff=1
- SHIFT
-)
-
-if not exist "%1.chalice" goto errorNotFound
-if not exist "%1.output.txt" goto errorNoRef
-
-:: get parameters
-set chaliceparameters=
-setlocal EnableDelayedExpansion
-set done=0
-set key=a
-FOR /F "usebackq tokens=1,2 delims==" %%i in (%1.chalice) do (
-
- if !done!==0 (
- set key=%%i
- set param=%%j
- )
-
- set done=1
-)
-set str=// chalice-parameter
-if "!key!"=="!str!" (
- set chaliceparameters=!param!
-)
-
-set output=output.txt
-echo Verification of %1.chalice using parameters="%chaliceparameters%" > %output%
-echo.>> %output%
-call %chalice% "%1.chalice" -smoke -time:3 %chaliceparameters% %2 %3 %4 %5 %6 %7 1>> %output% 2> time.log
-set /p extime= < time.log
-del time.log
-
-fc "%1.output.txt" output.txt > nul
-if not errorlevel 1 goto passTest
-goto failTest
-
-:passTest
-echo OK: %1.chalice (%extime% seconds)
-goto end
-
-:failTest
-echo FAIL: %1.chalice (%extime% seconds)
-if %nodiff%==0 (
- call %diff% "%1.output.txt" output.txt
-)
-goto errorEnd
-
-:errorEnd
-if exist out.bpl del out.bpl
-if exist output.txt del output.txt
-endlocal
-exit /b 1
-
-:end
-if exist out.bpl del out.bpl
-if exist output.txt del output.txt
-endlocal
-exit /b 0
-
-:errorNotFound
-echo ERROR: %1.chalice not found.
-goto errorEnd
-
-:errorNoRef
-echo ERROR: %1.output.txt (reference output) not found.
-goto errorEnd
diff --git a/Chalice/tests/test-scripts/reg_test_all.bat b/Chalice/tests/test-scripts/reg_test_all.bat
deleted file mode 100644
index 23aca316..00000000
--- a/Chalice/tests/test-scripts/reg_test_all.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-@echo off
-
-setlocal EnableDelayedExpansion
-
-:: no-summary command line parameter
-set nosummary=0
-if "%1"=="-no-summary" (
- set nosummary=1
- SHIFT /1
-)
-
-set regtest="%~dp0\reg_test.bat"
-set t=0
-set c=0
-for /F %%f in ('dir *.chalice /b') do (
- call %regtest% -no-diff %%~nf %1 %2 %3 %4 %5 %6 %7 %8
- set /A c=!c!+!errorlevel!
- set /A t=!t!+1
-)
-if !nosummary!==0 (
- echo.
- if !c!==0 (echo SUMMARY: completed !t! tests successfully.) else (echo SUMMARY: failed !c! of !t! tests.)
-)
-exit /b !c!
diff --git a/Chalice/tests/test-scripts/test.bat b/Chalice/tests/test-scripts/test.bat
deleted file mode 100644
index 8572dc6b..00000000
--- a/Chalice/tests/test-scripts/test.bat
+++ /dev/null
@@ -1,37 +0,0 @@
-@echo off
-
-set chalice="%~dp0\..\..\chalice.bat"
-set getparams="%~dp0\getparams.bat"
-
-if not exist "%1.chalice" goto errorNotFound
-
-:: get parameters
-set chaliceparameters=
-setlocal EnableDelayedExpansion
-set done=0
-set key=a
-FOR /F "usebackq tokens=1,2 delims==" %%i in (%1.chalice) do (
-
- if !done!==0 (
- set key=%%i
- set param=%%j
- )
-
- set done=1
-)
-set str=// chalice-parameter
-if "!key!"=="!str!" (
- set chaliceparameters=!param!
-)
-
-set output=output.txt
-echo Verification of %1.chalice using parameters="%chaliceparameters%" > %output%
-echo.>> %output%
-call %chalice% "%1.chalice" -smoke -time:0 %chaliceparameters% %2 %3 %4 %5 %6 %7 >> %output% 2>&1
-type %output%
-
-exit /B 0
-
-:errorNotFound
-echo ERROR: %1.chalice not found.
-exit /B 1
diff --git a/Jennisys/Jennisys.sln b/Jennisys/Jennisys.sln
deleted file mode 100644
index 3f213e27..00000000
--- a/Jennisys/Jennisys.sln
+++ /dev/null
@@ -1,58 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Jennisys", "Jennisys\Jennisys.fsproj", "{F2FF4B3A-2FE8-474A-88DF-6950F7D78908}"
- ProjectSection(ProjectDependencies) = postProject
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83} = {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "..\Source\Model\Model.csproj", "{ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Checked|Any CPU = Checked|Any CPU
- Checked|Mixed Platforms = Checked|Mixed Platforms
- Checked|x86 = Checked|x86
- Debug|Any CPU = Debug|Any CPU
- Debug|Mixed Platforms = Debug|Mixed Platforms
- Debug|x86 = Debug|x86
- Release|Any CPU = Release|Any CPU
- Release|Mixed Platforms = Release|Mixed Platforms
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Checked|Any CPU.ActiveCfg = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Checked|Mixed Platforms.ActiveCfg = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Checked|Mixed Platforms.Build.0 = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Checked|x86.ActiveCfg = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Checked|x86.Build.0 = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Debug|Any CPU.ActiveCfg = Debug|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Debug|Mixed Platforms.Build.0 = Debug|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Debug|x86.ActiveCfg = Debug|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Debug|x86.Build.0 = Debug|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Release|Any CPU.ActiveCfg = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Release|Mixed Platforms.Build.0 = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Release|x86.ActiveCfg = Release|x86
- {F2FF4B3A-2FE8-474A-88DF-6950F7D78908}.Release|x86.Build.0 = Release|x86
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Checked|Any CPU.Build.0 = Checked|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Checked|Mixed Platforms.ActiveCfg = Checked|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Checked|Mixed Platforms.Build.0 = Checked|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Checked|x86.ActiveCfg = Checked|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Debug|x86.ActiveCfg = Debug|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Release|Any CPU.Build.0 = Release|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.Release|x86.ActiveCfg = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Jennisys/Jennisys/Analyzer.fs b/Jennisys/Jennisys/Analyzer.fs
deleted file mode 100644
index db4887ed..00000000
--- a/Jennisys/Jennisys/Analyzer.fs
+++ /dev/null
@@ -1,953 +0,0 @@
-module Analyzer
-
-open Ast
-open Getters
-open AstUtils
-open CodeGen
-open DafnyModelUtils
-open DafnyPrinter
-open FixpointSolver
-open MethodUnifier
-open Modularizer
-open Options
-open PipelineUtils
-open PrintUtils
-open Resolver
-open TypeChecker
-open Utils
-
-open Microsoft.Boogie
-
-let Rename suffix vars =
- vars |> List.map (function Var(nm,tp,old) -> nm, Var(nm + suffix, tp, old))
-
-let ReplaceName substMap nm =
- match Map.tryFind nm substMap with
- | Some(Var(name,_,_)) -> name
- | None -> nm
-
-let rec Substitute substMap = function
- | IdLiteral(s) -> IdLiteral(ReplaceName substMap s)
- | Dot(e,f) -> Dot(Substitute substMap e, ReplaceName substMap f)
- | UnaryExpr(op,e) -> UnaryExpr(op, Substitute substMap e)
- | BinaryExpr(n,op,e0,e1) -> BinaryExpr(n, op, Substitute substMap e0, Substitute substMap e1)
- | SelectExpr(e0,e1) -> SelectExpr(Substitute substMap e0, Substitute substMap e1)
- | UpdateExpr(e0,e1,e2) -> UpdateExpr(Substitute substMap e0, Substitute substMap e1, Substitute substMap e2)
- | SequenceExpr(ee) -> SequenceExpr(List.map (Substitute substMap) ee)
- | SeqLength(e) -> SeqLength(Substitute substMap e)
- | ForallExpr(vv,e) -> ForallExpr(vv, Substitute substMap e)
- | expr -> expr
-
-let GenMethodAnalysisCode comp m assertion genOld =
- let methodName = GetMethodName m
- let signature = GetMethodSig m
- let ppre,ppost = GetMethodPrePost m
- let pre = Desugar ppre
- let post = Desugar ppost |> RewriteOldExpr
- let ghostPre = GetMethodGhostPrecondition m |> Desugar
- //let sigStr = PrintSig signature
- let sigVarsDecl =
- match signature with
- | Sig(ins,outs) -> ins @ outs |> List.fold (fun acc vd -> acc + (sprintf " var %s;" (PrintVarDecl vd)) + newline) ""
-
- " method " + methodName + "()" + newline +
- " modifies this;" + newline +
- " {" + newline +
- // print signature as local variables
- sigVarsDecl +
- " // assume precondition" + newline +
- " assume " + (PrintExpr 0 pre) + ";" + newline +
- " // assume ghost precondition" + newline +
- " assume " + (PrintExpr 0 ghostPre) + ";" + newline +
- " // assume invariant and postcondition" + newline +
- " assume Valid();" + newline +
- (if genOld then " assume Valid_old();" + newline else "") +
- " assume " + (PrintExpr 0 post) + ";" + newline +
- " // assume user defined invariant again because assuming Valid() doesn't always work" + newline +
- (GetInvariantsAsList comp |> PrintSep newline (fun e -> " assume " + (PrintExpr 0 e) + ";")) + newline +
- // if the following assert fails, the model hints at what code to generate; if the verification succeeds, an implementation would be infeasible
- " // assert false to search for a model satisfying the assumed constraints" + newline +
- " assert " + (PrintExpr 0 assertion) + ";" + newline +
- " }" + newline
-
-let rec MethodAnalysisPrinter onlyForThese assertion genOld comp =
- let cname = GetComponentName comp
- match onlyForThese with
- | (c,m) :: rest when GetComponentName c = cname ->
- match m with
- | Method(_) ->
- (GenMethodAnalysisCode c m assertion genOld) + newline +
- (MethodAnalysisPrinter rest assertion genOld comp)
- | _ -> ""
- | _ :: rest -> MethodAnalysisPrinter rest assertion genOld comp
- | [] -> ""
-
-// =========================================================================
-/// For a given constant "objRefName" (which is an object, something like
-/// "gensym32"), finds a path of field references from "this" (e.g. something
-/// like "this.next.next").
-///
-/// Implements a backtracking search over the heap entries to find that
-/// path. It starts from the given object, and follows the backpointers
-/// until it reaches the root ("this")
-// =========================================================================
-// let objRef2ExprCache = new System.Collections.Generic.Dictionary<string, Expr>()
-let GetObjRefExpr objRefName (heapInst: HeapInstance) =
- let rec __GetObjRefExpr objRefName visited =
- if Set.contains objRefName visited then
- None
- else
- let newVisited = Set.add objRefName visited
- match objRefName with
- | "this" -> Some(ObjLiteral("this"))
- | _ ->
- let rec __fff lst =
- match lst with
- | ((o,var),_) :: rest ->
- match __GetObjRefExpr o.name newVisited with
- | Some(expr) -> Some(Dot(expr, GetExtVarName var))
- | None -> __fff rest
- | [] -> None
- let backPointers = heapInst.concreteValues |> List.choose (function
- FieldAssignment (x,l) ->
- if l = ObjLiteral(objRefName) then Some(x,l) else None
- |_ -> None)
- __fff backPointers
- (* --- function body starts here --- *)
- __GetObjRefExpr objRefName (Set.empty)
-// THIS DOESN'T WORK BECAUSE THE CACHE HAS TO BE PURGED AFTER EVERY METHOD
-// if objRef2ExprCache.ContainsKey(objRefName) then
-// Some(objRef2ExprCache.[objRefName])
-// else
-// let res = __GetObjRefExpr objRefName (Set.empty)
-// match res with
-// | Some(e) -> objRef2ExprCache.Add(objRefName, e)
-// | None -> ()
-// res
-
-// =============================================================================
-/// Returns an expression that combines the post-condition of a given method with
-/// invariants for all objects present on the heap
-// =============================================================================
-let GetHeapExpr prog mthd heapInst includePreState =
- // get expressions to evaluate:
- // - add post (and pre?) conditions
- // - go through all objects on the heap and assert their invariants
- let pre,post = GetMethodPrePost mthd
- let prepostExpr = post //TODO: do we need the "pre" here as well?
- let heapObjs = heapInst.assignments |> List.fold (fun acc asgn ->
- match asgn with
- | FieldAssignment((o,_),_) -> acc |> Set.add o
- | _ -> acc) Set.empty
- heapObjs |> Set.fold (fun acc o ->
- let receiverOpt = GetObjRefExpr o.name heapInst
- let receiver = Utils.ExtractOption receiverOpt
- let objComp = FindComponent prog (GetTypeShortName o.objType) |> Utils.ExtractOption
- let objInvs = GetInvariantsAsList objComp
- let objInvsUpdated = objInvs |> List.map (ChangeThisReceiver receiver)
- let objInvFinal = objInvsUpdated |> List.fold BinaryAnd TrueLiteral
- let objAllInvs =
- if includePreState then
- let objInvPre = MakeOld objInvFinal
- BinaryAnd objInvFinal objInvPre
- else
- objInvFinal
- BinaryAnd prepostExpr objAllInvs
- ) prepostExpr
-
-let IsUnmodConcrOnly prog (comp,meth) expr =
- let isConstr = IsModifiableObj (ThisObj comp) (comp,meth)
- let rec __IsUnmodOnly args expr =
- let __IsUnmodOnlyLst elist =
- elist |> List.fold (fun acc e -> acc && (__IsUnmodOnly args e)) true
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarDeclExpr(_)
- | ObjLiteral(_) -> true
- | VarLiteral(id) -> args |> List.exists (fun var -> GetExtVarName var = id)
- | IdLiteral("null") | IdLiteral("this") -> true
- | IdLiteral(id) ->
- not (isConstr || IsAbstractField comp id)
- | Dot(e, fldName) -> //if isConstr then false else __IsUnmodOnlyLst [e]
- if isConstr then
- false
- else
- // assume it is unmodifiable, because it is a method, so just check if it's concrete
- let lhsType = InferType prog comp (MethodArgChecker prog meth) e |> Utils.ExtractOptionMsg (sprintf "Inference failed for %s" (PrintExpr 0 e))
- IsConcreteField lhsType fldName
- | AssertExpr(e)
- | AssumeExpr(e)
- | SeqLength(e)
- | LCIntervalExpr(e)
- | MethodOutSelect(e,_)
- | OldExpr(e)
- | UnaryExpr(_,e) -> __IsUnmodOnlyLst [e]
- | SelectExpr(e1, e2)
- | BinaryExpr(_,_,e1,e2) -> __IsUnmodOnlyLst [e1; e2]
- | IteExpr(e3, e1, e2)
- | UpdateExpr(e1, e2, e3) -> __IsUnmodOnlyLst [e1; e2; e3]
- | SequenceExpr(exprs) | SetExpr(exprs) -> __IsUnmodOnlyLst exprs
- | MethodCall(rcv,_,_,aparams) -> __IsUnmodOnlyLst (rcv :: aparams)
- | ForallExpr(vars,e) -> __IsUnmodOnly (args @ vars) e
- (* --- function body starts here --- *)
- __IsUnmodOnly (GetMethodInArgs meth) expr
-
-let AddUnif indent e v unifMap =
- let idt = Indent indent
- let builder = new CascadingBuilder<_>(unifMap)
- builder {
- let! notAlreadyAdded = Map.tryFind e unifMap |> Utils.IsNoneOption |> Utils.BoolToOption
- Logger.DebugLine (idt + " - adding unification " + (PrintExpr 0 e) + " <--> " + (PrintConst v))
- return Map.add e v unifMap
- }
-
-//TODO: unifications should probably by "Expr <--> Expr" instead of "Expr <--> Const"
-let rec GetUnifications prog indent (comp,meth) heapInst unifs expr =
- let idt = Indent indent
- // - first looks if the give expression talks only about method arguments (args)
- // - then it tries to evaluate it to a constant
- // - if all of these succeed, it adds a unification rule e <--> val(e) to the given unifMap map
- let __AddUnif e unifsAcc =
- if IsConstExpr e then
- unifsAcc
- else
- let builder = new CascadingBuilder<_>(unifsAcc)
- builder {
- let! argsOnly = IsUnmodConcrOnly prog (comp,meth) e |> Utils.BoolToOption
- let! v = try Some(EvalFull heapInst e |> Expr2Const) with ex -> None
- return AddUnif indent e v unifsAcc
- }
- (* --- function body starts here --- *)
- AstUtils.DescendExpr2 __AddUnif expr unifs
-
-// =======================================================
-/// Returns a map (Expr |--> Const) containing unifications
-/// found for the given method wrt to heapInst.
-///
-/// The list of potential unifications include:
-/// (1) arg-value pairs for all method arguments,
-/// (2) field-value pairs for all unmodifiable fields,
-/// (3) expr-value pairs where expr are unmodifiable
-/// expressions found in the spec.
-// =======================================================
-let GetUnificationsForMethod indent prog comp m heapInst =
- let idt = Indent indent
- let rec GetArgValueUnifications args =
- match args with
- | var :: rest ->
- let name = GetExtVarName var
- match Map.tryFind name heapInst.methodArgs with
- | Some(c) ->
- GetArgValueUnifications rest |> AddUnif indent (VarLiteral(name)) c
- | None -> failwith ("couldn't find value for argument " + name)
- | [] -> Map.empty
- let rec GetFldValueUnifications unifs =
- heapInst.assignments |> List.fold (fun acc asgn ->
- match asgn with
- | FieldAssignment((obj,var), fldVal) ->
- try
- let vname = GetExtVarName var
- let comp = obj.objType |> FindComponentForType prog |> Utils.ExtractOption
- if IsConcreteField comp vname then
- let path = GetObjRefExpr obj.name heapInst |> Utils.ExtractOption
- let c = Expr2Const fldVal
- AddUnif indent (Dot(path, vname)) c acc
- else
- acc
- with
- | ex ->
- Logger.WarnLine ("[WARN]: error during getting field value unifications: " + ex.Message)
- acc
- | _ -> acc
- ) unifs
-
- (* --- function body starts here --- *)
- let unifs = GetArgValueUnifications (GetMethodInArgs m)
- let unifs =
- //TODO: it should really read the "modifies" clause and figure out modifiable fields from there
- if not (IsConstructor m) then
- GetFldValueUnifications unifs
- else
- unifs
- GetUnifications prog indent (comp,m) heapInst unifs (GetMethodPrePost m |> fun x -> BinaryAnd (fst x) (snd x))
-
-// =======================================================
-/// Applies given unifications onto a given heapInstance
-///
-/// If "conservative" is true, applies only those that
-/// can be verified to hold, otherwise applies all of them
-// =======================================================
-let rec ApplyUnifications indent prog comp mthd unifs heapInst conservative =
- let idt = Indent indent
- ///
- let __CheckUnif o f e idx =
- if not conservative || not Options.CONFIG.checkUnifications then
- true
- else
- let lhs = if o = NoObj then
- VarLiteral(GetVarName f)
- else
- let objRefExpr = GetObjRefExpr o.name heapInst |> Utils.ExtractOptionMsg ("Couldn't find a path from 'this' to " + o.name)
- let fldName = GetVarName f
- Dot(objRefExpr, fldName)
- let assertionExpr = match GetVarType f with
- | Some(SeqType(_)) when not (idx = -1) -> BinaryEq (SelectExpr(lhs, IntLiteral(idx))) e
- | Some(SetType(_)) when not (idx = -1) -> BinaryIn e lhs
- | _ -> BinaryEq lhs e
- // check if the assertion follows and if so update the env
- let genOld = false
- let code = PrintDafnyCodeSkeleton prog (MethodAnalysisPrinter [comp,mthd] assertionExpr genOld) true genOld
- Logger.Debug (idt + " - checking assertion: " + (PrintExpr 0 assertionExpr) + " ... ")
- let ok = CheckDafnyProgram code ("unif_" + (GetMethodFullName comp mthd))
- if ok then
- Logger.DebugLine " HOLDS"
- else
- Logger.DebugLine " DOESN'T HOLD"
- ok
- ///
- let __Apply (o,f) c e value=
- if value = Const2Expr c then
- if __CheckUnif o f e -1 then
- // change the value to expression
- //Logger.TraceLine (sprintf "%s - applied: %s.%s --> %s" idt (PrintConst o) (GetVarName f) (PrintExpr 0 e) )
- e
- else
- value
- else
- let rec __UnifyOverLst lst cnt =
- match lst with
- | lstElem :: rest when lstElem = Const2Expr c ->
- if __CheckUnif o f e cnt then
- //Logger.TraceLine (sprintf "%s - applied: %s.%s[%d] --> %s" idt (PrintConst o) (GetVarName f) cnt (PrintExpr 0 e) )
- e :: __UnifyOverLst rest (cnt+1)
- else
- lstElem :: __UnifyOverLst rest (cnt+1)
- | lstElem :: rest ->
- lstElem :: __UnifyOverLst rest (cnt+1)
- | [] -> []
- // see if it's a list, then try to match its elements, otherwise leave it as is
- match value with
- | SequenceExpr(elist) ->
- let newExprList = __UnifyOverLst elist 0
- SequenceExpr(newExprList)
- | SetExpr(elist) ->
- let newExprList = __UnifyOverLst elist 0
- SetExpr(newExprList)
- | _ ->
- value
-
- (* --- function body starts here --- *)
- match unifs with
- | (e,c) :: rest ->
- let heapInst = ApplyUnifications indent prog comp mthd rest heapInst conservative
- let newHeap = heapInst.assignments|> List.fold (fun acc asgn ->
- match asgn with
- | FieldAssignment((o,f),value) when heapInst.modifiableObjs |> Set.contains o ->
- let e2 = __Apply (o,f) c e value
- acc @ [FieldAssignment((o,f),e2)]
- | _ -> acc @ [asgn]
- ) []
- let newRetVals = heapInst.methodRetVals |> Map.fold (fun acc key value ->
- let e2 = __Apply (NoObj,Var(key, None, false)) c e value
- acc |> Map.add key e2
- ) Map.empty
- {heapInst with assignments = newHeap; methodRetVals = newRetVals}
- | [] -> heapInst
-
-// ====================================================================================
-/// Returns whether the code synthesized for the given method can be verified with Dafny
-// ====================================================================================
-let VerifySolution prog solutions genRepr =
- // print the solution to file and try to verify it with Dafny
- //let prog = Program(solutions |> Utils.MapKeys |> Map.ofList |> Utils.MapKeys)
- let code = PrintImplCode prog solutions genRepr false
- CheckDafnyProgram code dafnyVerifySuffix
-
-let rec DiscoverAliasing exprList heapInst =
- match exprList with
- | e1 :: rest ->
- let eqExpr = rest |> List.fold (fun acc e ->
- if EvalFull heapInst (BinaryEq e1 e) = TrueLiteral then
- BinaryAnd acc (BinaryEq e1 e)
- else
- acc
- ) TrueLiteral
- BinaryAnd eqExpr (DiscoverAliasing rest heapInst)
- | [] -> TrueLiteral
-
-//
-let DontResolveUnmodifiableStuff prog comp meth expr =
- let methodArgs = GetMethodInArgs meth
- let __IsMethodArg argName = methodArgs |> List.exists (fun var -> GetExtVarName var = argName)
- let isMod = IsModifiableObj (ThisObj comp) (comp,meth)
- match expr with
- | VarLiteral(id) when __IsMethodArg id -> false
- | IdLiteral(id) when id = "this" || id = "null" -> true
- | IdLiteral(id) | Dot(_, id) ->
- // this must be a field, so resolve it only if modifiable
- isMod
- | _ -> true
-
-/// Descends down a given expression and returns bunch of sub-expressions that all evaluate to true
-let FindClauses trueOnly resolverFunc heapInst expr =
- let MyFun expr acc =
- try
- match expr with
- // skip binary logical operators because we want to find smallest sub-expressions
- | BinaryExpr(_,op,_,_) when IsLogicalOp op -> acc
- | _ ->
- let exprEval = Eval heapInst resolverFunc expr
- match exprEval with
- | _ when exprEval = TrueLiteral -> acc
- | _ ->
- let exprAllResolved = EvalFull heapInst expr
- match exprAllResolved with
- | BoolLiteral(true) -> acc @ (exprEval |> SplitIntoConjunts)
- | BoolLiteral(false) -> acc //if trueOnly then acc else acc @ (UnaryNot exprEval |> SplitIntoConjunts)
- | _ -> acc
- with
- | _ -> acc
- (* --- function body starts here --- *)
- DescendExpr2 MyFun expr []
-
-/// Descends down a given expression and returns all sub-expressions that evaluate to TrueLiteral
-let FindTrueClauses resolverFunc heapInst expr =
- FindClauses true resolverFunc heapInst expr
-
-/// Returns a list of boolean expressions obtained by combining (in some way)
-/// the two given list of conditions conditions
-let GetAllPossibleConditions specConds argConds aliasingConds =
- let __Conjoin lst = lst |> List.fold (fun acc e -> BinaryAnd acc e) TrueLiteral
- let __Preproc lst = lst |> List.map SplitIntoConjunts |> List.concat |> Utils.ListDeduplicate
-
- // 0. aliasing conditions
- // 1. conjunction of spec conditions
- // 2. individual arg conditions
- // 3. conjunction of arg conditions
- // 4. individual spec conditions
- let aliasing = aliasingConds |> __Preproc
- let specIndi = specConds |> __Preproc
- let specConj = [__Conjoin specIndi]
- let argsIndi = argConds |> __Preproc
- let argsConj = [__Conjoin argsIndi]
-
- let allConds = aliasing @ specConj @ argsIndi @ specIndi @ argsConj
- allConds |> List.filter (fun e -> not (e = TrueLiteral))
- |> Utils.ListDeduplicate
-
-// check whther a given solution (in the form of heapInst) verifies assuming a given guard
-let rec CheckGuard prog comp m candCond indent idt heapInst callGraph =
- let rec __MinGuard guard idx m2 sol =
- let conjs = SplitIntoConjunts guard
- let len = List.length conjs
- if idx >= 0 && idx < len && len > 1 then
- let guard' = conjs |> Utils.ListRemoveIdx (len - idx - 1) |> List.fold BinaryAnd TrueLiteral
- match CheckGuard prog comp m guard' indent idt heapInst callGraph with
- | Some(x) -> x
- | None -> __MinGuard guard (idx+1) m2 sol
- else
- guard, m2, sol
-
- let m2 = AddPrecondition m candCond
- let sol = MakeModular (indent+2) prog comp m2 candCond heapInst callGraph
- Logger.Info (idt + " - verifying partial solution ... ")
- let verified =
- if Options.CONFIG.verifyPartialSolutions then
- VerifySolution prog sol Options.CONFIG.genRepr
- else
- true
- if verified then
- if Options.CONFIG.verifyPartialSolutions then Logger.InfoLine "VERIFIED" else Logger.InfoLine "SKIPPED"
- if Options.CONFIG.minimizeGuards then
- Logger.InfoLine(idt + " - minimizing guard ... " + (PrintExpr 0 candCond))
- Some(__MinGuard candCond 0 m2 sol)
- else
- Some(candCond,m2,sol)
- else
- Logger.InfoLine ("NOT VERIFIED")
- None
-
-// iteratively tries to remove conjunts and check whether the solutions still verifies
-//let MinimizeGuard guard prog comp m heapInst callGraph indent =
-
-
-// ============================================================================
-/// Attempts to synthesize the initialization code for the given constructor "m"
-///
-/// Returns a (heap,env,ctx) tuple
-// ============================================================================
-let rec AnalyzeConstructor indent prog comp m callGraph =
- let idt = Indent indent
- let TryFindAndVerify m =
- match TryFindExistingAndConvertToSolution indent comp m TrueLiteral callGraph with
- | Some(sol) ->
- if VerifySolution prog sol Options.CONFIG.genRepr then
- Logger.InfoLine (idt + " ~~~ VERIFIED ~~~")
- Some(sol)
- else
- Logger.InfoLine (idt + " !!! NOT VERIFIED !!!")
- None
- | None -> None
-
- (* --- function body starts here --- *)
- Logger.InfoLine (idt + "[*] Analyzing constructor")
- Logger.InfoLine (idt + "------------------------------------------")
- Logger.InfoLine (Printer.PrintMethodSignFull (indent + 4) comp m)
- Logger.InfoLine (idt + "------------------------------------------")
- match TryFindAndVerify m with
- | Some(sol) -> sol
- | None ->
- let methodName = GetMethodName m
- let pre,post = GetMethodPrePost m
- // generate Dafny code for analysis first
- let genOld = true
- let code = PrintDafnyCodeSkeleton prog (MethodAnalysisPrinter [comp,m] FalseLiteral genOld) true genOld
- Logger.Info (idt + " - searching for an instance ...")
- let models = RunDafnyProgram code (dafnyScratchSuffix + "_" + (GetMethodFullName comp m))
- if models.Count = 0 then
- // no models means that the "assert false" was verified, which means that the spec is inconsistent
- Logger.WarnLine (idt + " !!! SPEC IS INCONSISTENT !!!")
- Map.empty
- else
- if models.Count > 1 then
- Logger.WarnLine " FAILED "
- failwith "internal error (more than one model for a single constructor analysis)"
- Logger.InfoLine " OK "
- let model = models.[0]
- let hModel = ReadFieldValuesFromModel model prog comp m
- let heapInst = ResolveModel hModel (comp,m)
- let unifs = GetUnificationsForMethod indent prog comp m heapInst |> Map.toList
- let heapInst = ApplyUnifications indent prog comp m unifs heapInst true
-
- // split into method calls
- let sol = MakeModular indent prog comp m TrueLiteral heapInst callGraph |> FixSolution comp m
-
- if Options.CONFIG.verifySolutions then
- Logger.InfoLine (idt + " - verifying synthesized solution ... ")
- let verified = VerifySolution prog sol Options.CONFIG.genRepr
- Logger.Info (idt + " ")
- if verified then
- Logger.InfoLine "~~~ VERIFIED ~~~"
- sol
- else
- Logger.InfoLine "!!! NOT VERIFIED !!!"
- if Options.CONFIG.inferConditionals then
- TryRecursion (indent + 4) prog comp m unifs heapInst callGraph
- else
- sol
- else
- sol
-and TryRecursion indent prog comp m unifs heapInst callGraph =
- let idt = Indent indent
-
- /// checks whether an expression is ok, meaning
- /// - only immediate concrete fields of the "this" object are used,
- /// - no recursion on the same object with the same parameters
- let __IsOk hInst expr =
- let compName = GetComponentName comp
- let methName = GetMethodName m
- let myVisitor =
- fun expr acc ->
- if not acc then
- false
- else
- match expr with
- | Dot(discr, fldName) ->
- let obj = EvalFull heapInst discr
- match obj with
- | ObjLiteral(id) when id = "this" ->
- try
- let fname = RenameFromOld fldName
- IsConcreteField (InferType prog comp (MethodArgChecker prog m) discr |> Utils.ExtractOption) fname
- with
- | _ -> false
- | ObjLiteral(id) -> false
- | _ -> failwithf "Didn't expect the discriminator of a Dot to not be ObjLiteral"
- | MethodCall(receiver, cn, mn, elst) when receiver = ThisLiteral && cn = compName && mn = methName ->
- elst |> List.exists (function VarLiteral(_) -> false | _ -> true)
- | _ -> true
- DescendExpr2 myVisitor expr true
-
- /// Finds all modifiable fields in a given hInst, and checks if an "ok"
- /// expression exists for each one of them.
- ///
- /// Returns all possible combinations of "ok" solutions (these are not verified yet).
- let __GetAllAssignments hInst premises =
- let rec __IterVars vars =
- match vars with
- | lhs :: [] ->
- let lhsOptions = premises |> Set.toList
- |> List.choose (function
- | BinaryExpr(_,"=",l,r) -> if l = lhs then Some(r) elif r = lhs then Some(l) else None
- | _ -> None)
- |> List.filter (__IsOk hInst)
- |> List.map (fun e -> [lhs,e])
- lhsOptions
- | lhs :: rest ->
- let lhsOptions = __IterVars [lhs]
- if List.isEmpty lhsOptions then
- List.empty
- else
- let restOptions = __IterVars rest
- Utils.ListCombine (fun t1 t2 -> t1 @ t2) lhsOptions restOptions
- | [] -> List.empty
-
- let stmts = ConvertToStatements hInst true
- let modVars = stmts |> List.choose (function
- | Assign(lhs,_) -> Some(lhs)
- | _ -> None)
- __IterVars modVars
-
- /// Print a given list of assignments
- let rec __PrintSol indent s =
- let idt = Indent indent
- match s with
- | (l,r) :: [] ->
- sprintf "%s%s := %s" idt (PrintExpr 0 l) (PrintExpr 0 r)
- | (l,r) :: rest ->
- let str = __PrintSol indent [l,r]
- str + newline + (__PrintSol indent rest)
- | [] -> ""
-
- /// Returns a given method's postcondition where
- /// - all input variables are renamed so that their names start with "$" and
- /// (so that the unifier know that it's ok to try to unify those variables)
- /// - all output variables are rewritten as $this.<method_name>(<args>)["<out_var_name>"]
- /// (so that it is clear that they are results of a method call)
- let __GetMethodPostTemplate comp m =
- let compName = GetComponentName comp
- let methName = GetMethodName m
- let ins = GetMethodInArgs m
- let outs = GetMethodOutArgs m
- let post = GetMethodPrePost m |> snd
- post |> RewriteWithCtx (fun ctx e ->
- match e with
- | VarLiteral(id) when not (IsInVarList ctx id) ->
- if IsInVarList outs id then
- let mcall = MethodCall(ThisLiteral, compName, methName, ins |> List.map (function var -> VarLiteral("$" + (GetExtVarName var))))
- let outSel = MethodOutSelect(mcall, id)
- Some(outSel)
- else
- Some(VarLiteral("$" + id))
- | _ -> None) []
- |> ChangeThisReceiver (VarLiteral("$this"))
-
- /// Merges ...
- let __MergeSolutions hInst s =
- let __FindRhs lhs = s |> List.choose (fun (l,r) -> if l = lhs then Some(r) else None) |> Utils.ListToOption
- let rec __FixAssignments asgs =
- match asgs with
- | asg :: rest ->
- let newAsg =
- match asg with
- | FieldAssignment((obj,var) as discr,valExpr) ->
- let objPath = GetObjRefExpr obj.name hInst |> Utils.ExtractOption
- let lhs = Dot(objPath, GetExtVarName var)
- match __FindRhs lhs with
- | Some(rhs) -> FieldAssignment(discr,rhs)
- | None -> asg
- | _ -> asg
- newAsg :: (__FixAssignments rest)
- | [] -> []
- let rec __FixRetValues retVals =
- match retVals with
- | (varName,varExpr) :: rest ->
- let lhs = VarLiteral(varName)
- let newVarExpr =
- match __FindRhs lhs with
- | Some(rhs) -> rhs
- | None -> varExpr
- __FixRetValues rest |> Map.add varName newVarExpr
- | [] -> Map.empty
- if s = [] then
- hInst
- else
- // fix assignments
- let newAsgs = __FixAssignments hInst.assignments
- // fix return values
- let newRetVals = __FixRetValues (hInst.methodRetVals |> Map.toList)
- {hInst with assignments = newAsgs;
- methodRetVals = newRetVals}
-
-
- /// For a given heap instance and a list of possible solutions, it iterates
- /// trough all of them and returns whichever verifies first.
- let rec __IterSolutions hInst premises wrongSol sList =
- match sList with
- | s :: rest ->
- Logger.InfoLine (idt + "Candidate solution:")
- Logger.InfoLine (__PrintSol (indent + 4) s)
- let hInst' = __MergeSolutions hInst s
- let sol = Utils.MapSingleton (comp,m) [TrueLiteral, hInst']
- if not (hInst' = hInst) && VerifySolution prog sol Options.CONFIG.genRepr then
- Logger.InfoLine (idt + " ~~~ VERIFIED ~~~")
- sol
- else
- Logger.InfoLine (idt + " !!! NOT VERIFIED !!!")
- match TryInferConditionals indent prog comp m unifs hInst' callGraph premises with
- | Some(candCond,solThis) ->
- let m' = AddPrecondition m (UnaryNot(candCond))
- let solRest = AnalyzeConstructor (indent + 2) prog comp m' callGraph
- MergeSolutions solThis solRest |> FixSolution comp m
- | None ->
- __IterSolutions hInst premises wrongSol rest
- | [] -> wrongSol
-
- (* --- function body starts here --- *)
- let loggerFunc = fun e -> Logger.TraceLine (sprintf "%s --> %s" idt (PrintExpr 0 e))
-
- //TODO
- let expandOnlyModVarsFunc = fun e ->
- true
-// let __CheckExpr l =
-// //TODO: FIX THIS!!!!!
-// match l with
-// | VarLiteral(vname) -> GetMethodOutArgs m |> List.exists (fun var -> GetVarName var = vname)
-// | IdLiteral(_) -> true
-// | Dot(_,_) -> true
-// | _ -> false
-// match e with
-// | BinaryExpr(_,"=",l,_) ->
-// //TODO: it should really check both lhs and rhs
-// __CheckExpr l
-// | BinaryExpr(_,op,l,_) when IsRelationalOp op ->
-// __CheckExpr l
-// | _ -> __CheckExpr e
-
- let wrongSol = Utils.MapSingleton (comp,m) [TrueLiteral, heapInst]
- let heapInst = ApplyUnifications indent prog comp m unifs heapInst false
- let methodArgs = GetMethodInArgs m
- let heapExpr = GetHeapExpr prog m heapInst true
-
- //Logger.TraceLine (PrintExpr 0 heapExpr)
-
- // find set of premises (don't resolve anything)
- let premises = heapExpr |> FindClauses false (fun e -> false) heapInst
-
- Logger.TraceLine (sprintf "%s Premises:" idt)
- premises |> List.iter loggerFunc
-
- // add only recursive call for now
- let post = __GetMethodPostTemplate comp m
-
- let premiseSet = premises |> Set.ofList |> Set.add post
- let closedPremises = ComputeClosure heapInst expandOnlyModVarsFunc premiseSet
-
- Logger.TraceLine (idt + "Closed premises with methods")
- closedPremises |> Set.iter loggerFunc
-
- let s = __GetAllAssignments heapInst closedPremises
- if s = [] then
- // have at least one empty sol so that the original heapInst is not missed
- __IterSolutions heapInst closedPremises wrongSol [[]]
- else
- __IterSolutions heapInst closedPremises wrongSol s
-
-and TryInferConditionals indent prog comp m unifs heapInst callGraph premises =
- let idt = Indent indent
- let loggerFunc = fun e -> Logger.TraceLine (sprintf "%s --> %s" idt (PrintExpr 0 e))
- let methodArgs = GetMethodInArgs m
-
- /// Iterates through a given list of boolean conditions and checks
- /// which one suffices. If it finds such a condition, it returns
- /// the following three things:
- /// - the condition itself
- /// - the method with this condition added to its preconditions
- /// - a solution
- /// Otherwise returns None.
- let rec __TryOutConditions heapInst candidateConditions =
- let idt = Indent indent
- match candidateConditions with
- | [] ->
- Logger.InfoLine (sprintf "%s - no more interesting pre-conditions" idt)
- None
- | candCond :: rest ->
- Logger.InfoLine (sprintf "%s ________________________" idt)
- Logger.InfoLine (sprintf "%s candidate pre-condition: %s" idt (PrintExpr 0 candCond))
- Logger.InfoLine (sprintf "%s ------------------------" idt)
- let idt = idt + " "
- match CheckGuard prog comp m candCond indent idt heapInst callGraph with
- | Some(guard, m2, sol) -> Some(guard, m2, sol)
- | None -> __TryOutConditions heapInst rest
-
- if IsSolution1stLevelOnly heapInst then
- // try to find a non-recursive solution
- Logger.InfoLine (idt + "Strengthening the pre-condition")
- let expr = GetHeapExpr prog m heapInst false
- let specConds1 = expr |> FindTrueClauses (DontResolveUnmodifiableStuff prog comp m) heapInst
- let specConds2 = premises |> Set.toList
-
- let isConstFunc = fun e -> try
- EvalNone heapInst e |> Expr2Const |> ignore
- true
- with
- | _ -> false
- let unmodConcrFunc = IsUnmodConcrOnly prog (comp,m)
- let is1stLevelFunc = __Is1stLevelExpr false heapInst
-
- let specConds = (specConds1 @ specConds2)
- |> List.map SimplifyExpr
- |> List.filter (fun e -> is1stLevelFunc e && unmodConcrFunc e && not (isConstFunc e))
-
- let aliasingCond = lazy(DiscoverAliasing (methodArgs |> List.map (function var -> VarLiteral(GetExtVarName var))) heapInst)
- let argConds = heapInst.methodArgs |> Map.fold (fun acc name value -> acc @ [BinaryEq (VarLiteral(name)) (Const2Expr value)]) []
- let allConds = GetAllPossibleConditions specConds argConds [aliasingCond.Force()]
- allConds |> List.iter loggerFunc
-
- match __TryOutConditions heapInst allConds with
- | Some(candCond,m2,sol) ->
- Logger.InfoLine (idt + " - guard found: " + (PrintExpr 0 candCond))
- let solThis = match TryFindExistingAndConvertToSolution indent comp m2 candCond callGraph with
- | Some(sol2) -> sol2
- | None -> sol
- let solThis = solThis |> FixSolution comp m
- Some(candCond,solThis)
- | None ->
- Logger.InfoLine (idt + "!!! Giving up !!!")
- None
- else
- // the solution is not immediate
- None
-
-
-
-// ===========================================================
-/// Reads CONFIG.methodToSynth to return a list of methods
-/// that Jennisys should attempt to synthesize.
-// ===========================================================
-let GetMethodsToAnalyze prog =
- let __ReadMethodsParam =
- let mOpt = Options.CONFIG.methodToSynth;
- if mOpt = "*" then
- (* all *)
- FilterMembers prog FilterMethodMembers
- else
- let allMethods,neg =
- if mOpt.StartsWith("~") then
- mOpt.Substring(1), true
- else
- mOpt, false
- (* exact list *)
- let methods = allMethods.Split([|','|])
- let lst = methods |> Array.fold (fun acc m ->
- let idx = m.LastIndexOf(".")
- if idx = -1 || idx = m.Length - 1 then
- raise (InvalidCmdLineArg("Invalid method full name: " + m))
- let compName = m.Substring(0, idx)
- let methName = m.Substring(idx + 1)
- let c = FindComponent prog compName |> Utils.ExtractOptionMsg ("Cannot find component " + compName)
- let mthd = FindMethod c methName |> Utils.ExtractOptionMsg ("Cannot find method " + methName + " in component " + compName)
- (c,mthd) :: acc
- ) []
- if neg then
- FilterMembers prog FilterMethodMembers |> List.filter (fun e -> not (Utils.ListContains e lst))
- else
- lst
- (* --- function body starts here --- *)
- let meths = __ReadMethodsParam
- if Options.CONFIG.constructorsOnly then
- meths |> List.filter (fun (c,m) -> IsConstructor m)
- else
- meths
-
-// ============================================================================
-/// Goes through a given list of methods of the given program and attempts to
-/// synthesize code for each one of them.
-///
-/// Returns a map from (component * method) |--> Expr * HeapInstance
-// ============================================================================
-let rec AnalyzeMethods prog members solutionsSoFar =
- let __IsAlreadySolved c m solutionMap =
- let existingKey = solutionMap |> Map.tryFindKey (fun (cc,mm) v -> CheckSameMethods (c,m) (cc,mm) && not (v = []))
- match existingKey with
- | Some(_) -> true
- | None -> false
-
- let rec __AnalyzeConstructorDeep prog mList solutionsSoFar =
- let callGraph = GetCallGraph (solutionsSoFar |> Map.toList) Map.empty
- match mList with
- | (comp,mthd) :: rest ->
- if not (__IsAlreadySolved comp mthd solutionsSoFar) then
- let sol = AnalyzeConstructor 2 prog comp mthd callGraph
- let unsolved = sol |> Map.filter (fun (c,m) lst -> lst = [] && not(__IsAlreadySolved c m solutionsSoFar)) |> Utils.MapKeys
- let newSols = solutionsSoFar |> MergeSolutions sol
- __AnalyzeConstructorDeep prog (rest@unsolved) newSols
- else
- __AnalyzeConstructorDeep prog rest solutionsSoFar
- | [] -> solutionsSoFar
-
- (* --- function body starts here --- *)
- match members with
- | (comp,m) :: rest ->
- match m with
- | Method(_,_,_,_,_) ->
- let sol = __AnalyzeConstructorDeep prog [comp,m] solutionsSoFar
- Logger.InfoLine ""
- AnalyzeMethods prog rest sol
- | _ -> AnalyzeMethods prog rest solutionsSoFar
- | [] -> solutionsSoFar
-
-let Analyze prog filename =
- let rec __AddMethodsFromProg methods solutions =
- match methods with
- | (c,m) :: rest ->
- let exists = solutions |> Map.tryFindKey (fun (c1,m1) _ -> CheckSameMethods (c,m) (c1,m1))
- match exists with
- | Some(_) -> __AddMethodsFromProg rest solutions
- | None -> __AddMethodsFromProg rest (solutions |> Map.add (c,m) [])
- | [] -> solutions
-
- /// Prints given solutions to a file
- let __PrintSolution prog outFileName solutions =
- use file = System.IO.File.CreateText(outFileName)
- file.AutoFlush <- true
- //let prog = Program(solutions |> Utils.MapKeys |> Map.ofList |> Utils.MapKeys)
- // add all other methods (those for which we don't have synthesized solution) as well
- let allMethods = FilterMembers prog FilterConstructorMembers
- let extSolutions = solutions //__AddMethodsFromProg allMethods solutions
- let synthCode = PrintImplCode prog extSolutions Options.CONFIG.genRepr false
- fprintfn file "%s" synthCode
-
- (* --- function body starts here --- *)
- let solutions = AnalyzeMethods prog (GetMethodsToAnalyze prog) Map.empty
- let progName = System.IO.Path.GetFileNameWithoutExtension(filename)
- let outFlatSolFileName = dafnySynthFileNameTemplate.Replace("###", progName)
- Logger.InfoLine "Printing synthesized code"
- __PrintSolution prog outFlatSolFileName solutions
- ()
-
-//let AnalyzeComponent_rustan c =
-// match c with
-// | Component(Class(name,typeParams,members), Model(_,_,cVars,frame,inv), code) ->
-// let aVars = Fields members
-// let aVars0 = Rename "0" aVars
-// let aVars1 = Rename "1" aVars
-// let allVars = List.concat [aVars; List.map (fun (a,b) -> b) aVars0; List.map (fun (a,b) -> b) aVars1; cVars]
-// let inv0 = Substitute (Map.ofList aVars0) inv
-// let inv1 = Substitute (Map.ofList aVars1) inv
-// // Now print it as a Dafny program
-// printf "class %s" name
-// match typeParams with
-// | [] -> ()
-// | _ -> printf "<%s>" (typeParams |> PrintSep ", " (fun tp -> tp))
-// printfn " {"
-// // the fields: original abstract fields plus two more copies thereof, plus and concrete fields
-// allVars |> List.iter (function Var(nm,None) -> printfn " var %s;" nm | Var(nm,Some(tp)) -> printfn " var %s: %s;" nm (PrintType tp))
-// // the method
-// printfn " method %s_checkInjective() {" name
-// printf " assume " ; (VarsAreDifferent aVars0 aVars1) ; printfn ";"
-// printfn " assume %s;" (PrintExpr 0 inv0)
-// printfn " assume %s;" (PrintExpr 0 inv1)
-// printfn " assert false;" // {:msg "Two abstract states map to the same concrete state"}
-// printfn " }"
-// // generate code
-// members |> List.iter (function
-// | Constructor(methodName,signature,pre,stmts) -> printf "%s" (GenerateCode methodName signature pre stmts inv false)
-// | Method(methodName,signature,pre,stmts) -> printf "%s" (GenerateCode methodName signature pre stmts inv true)
-// | _ -> ())
-// // the end of the class
-// printfn "}"
-// | _ -> assert false // unexpected case \ No newline at end of file
diff --git a/Jennisys/Jennisys/Ast.fs b/Jennisys/Jennisys/Ast.fs
deleted file mode 100644
index d355023a..00000000
--- a/Jennisys/Jennisys/Ast.fs
+++ /dev/null
@@ -1,95 +0,0 @@
-// ####################################################################
-/// The AST of a Jennisy program
-///
-/// author: Rustan Leino (leino@microsoft.com)
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// ####################################################################
-
-namespace Ast
-
-open System
-open System.Numerics
-
-type Type =
- | IntType
- | BoolType
- | SetType of Type (* type parameter *)
- | SeqType of Type (* type parameter *)
- | NamedType of string * string list (* type parameters *)
- | InstantiatedType of string * Type list (* type parameters *)
-
-type VarDecl =
- | Var of string * Type option * (* isOld *) bool
-
-(*
- the difference between IdLiteral and VarLiteral is that the VarLiteral is more specific,
- it always referes to a local variable (either method parameter or quantification variable)
-
- ObjLiteral is a concrete object, so if two ObjLiterals have different names,
- they are different objects (as opposed to IdLiterals and VarLiterals, which can alias).
- *)
-type Expr =
- | IntLiteral of int
- | BoolLiteral of bool
- | BoxLiteral of string
- | VarLiteral of string
- | IdLiteral of string
- | ObjLiteral of string
- | Star
- | Dot of Expr * string
- | UnaryExpr of string * Expr
- | OldExpr of Expr
- | LCIntervalExpr of Expr
- | BinaryExpr of int * string * Expr * Expr
- | IteExpr of (* cond *) Expr * (* thenExpr *) Expr * (* elseExpr *) Expr
- | SelectExpr of Expr * Expr
- | UpdateExpr of Expr * Expr * Expr
- | SequenceExpr of Expr list
- | SeqLength of Expr
- | SetExpr of Expr list //TODO: maybe this should really be a set instead of a list
- | ForallExpr of VarDecl list * Expr
- | MethodCall of (* receiver *) Expr * (* component name *) string * (* method name *) string * (* actual parameters *) Expr list
- | MethodOutSelect of (* method *) Expr * (* out param name *) string
- | VarDeclExpr of (* var list *) VarDecl list * (* declareAlso *) bool
- | AssertExpr of Expr
- | AssumeExpr of Expr
-
-type Const =
- | IntConst of int
- | BoolConst of bool
- | BoxConst of string
- | SetConst of Set<Const>
- | SeqConst of Const list
- | NullConst
- | NoneConst
- | ThisConst of (* loc id *) string * Type option
- | VarConst of string
- | NewObj of (* loc id *) string * Type option
- | Unresolved of (* loc id *) string
-
-type Stmt =
- | Block of Stmt list
- | ExprStmt of Expr
- | Assign of Expr * Expr
-
-type Signature =
- | Sig of (* ins *) VarDecl list * (* outs *) VarDecl list
-
-type Member =
- | Field of VarDecl
- | Method of (* name *) string * Signature * (* pre *) Expr * (* post *) Expr * (* isConstructor *) bool
- | Invariant of Expr list
-
-type TopLevelDecl =
- | Interface of string * string list * Member list
- | DataModel of string * string list * VarDecl list * (* frame *) Expr list * (* invariant *) Expr
- | Code of string * string list
-
-type SyntacticProgram =
- | SProgram of TopLevelDecl list
-
-type Component =
- | Component of (*interface*)TopLevelDecl * (*datamodel*)TopLevelDecl * (*code*)TopLevelDecl
-
-type Program =
- | Program of Component list
diff --git a/Jennisys/Jennisys/AstUtils.fs b/Jennisys/Jennisys/AstUtils.fs
deleted file mode 100644
index 6aac59e2..00000000
--- a/Jennisys/Jennisys/AstUtils.fs
+++ /dev/null
@@ -1,1033 +0,0 @@
-// ####################################################################
-/// Utility functions for manipulating AST elements
-///
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// ####################################################################
-
-module AstUtils
-
-open Ast
-open Getters
-open Logger
-open Utils
-
-let ThisLiteral = ObjLiteral("this")
-let NullLiteral = ObjLiteral("null")
-
-let IsLogicalOp op = [ "&&"; "||"; "==>"; "<==>" ] |> Utils.ListContains op
-let IsRelationalOp op = [ "="; "!="; "<"; "<="; ">"; ">="; "in"; "!in" ] |> Utils.ListContains op
-
-let AreInverseOps op1 op2 = match op1, op2 with "<" , ">" | ">" , "<" | "<=", ">=" | ">=", "<=" -> true | _ -> false
-
-let DoesImplyOp op1 op2 =
- match op1, op2 with
- | "<" , "!=" | ">" , "!=" -> true
- | "=" , ">=" | "=" , "<=" -> true
- | ">" , ">=" | "<" , "<=" -> true
- | _ -> false
-let IsCommutativeOp op = match op with "=" | "!=" -> true | _ -> false
-
-exception ExprConvFailed of string
-
-let Expr2Int e =
- match e with
- | IntLiteral(n) -> n
- | _ -> raise (ExprConvFailed(sprintf "not an int but: %O" e))
-
-let Expr2Bool e =
- match e with
- | BoolLiteral(b) -> b
- | _ -> raise (ExprConvFailed(sprintf "not a bool but: %O" e))
-
-let Expr2List e =
- match e with
- | SequenceExpr(elist) -> elist
- | _ -> raise (ExprConvFailed(sprintf "not a Seq but: %O" e))
-
-let rec MyRewrite rewriterFunc rewriteRecurseFunc expr =
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarLiteral(_)
- | ObjLiteral(_)
- | VarDeclExpr(_)
- | IdLiteral(_) -> match rewriterFunc expr with
- | Some(e) -> e
- | None -> expr
- | Dot(e, id) -> Dot(rewriteRecurseFunc e, id)
- | ForallExpr(vars,e) -> ForallExpr(vars, rewriteRecurseFunc e)
- | UnaryExpr(op,e) -> UnaryExpr(op, rewriteRecurseFunc e)
- | OldExpr(e) -> OldExpr(rewriteRecurseFunc e)
- | LCIntervalExpr(e) -> LCIntervalExpr(rewriteRecurseFunc e)
- | SeqLength(e) -> SeqLength(rewriteRecurseFunc e)
- | SelectExpr(e1, e2) -> SelectExpr(rewriteRecurseFunc e1, rewriteRecurseFunc e2)
- | BinaryExpr(p,op,e1,e2) -> BinaryExpr(p, op, rewriteRecurseFunc e1, rewriteRecurseFunc e2)
- | IteExpr(e1,e2,e3) -> IteExpr(rewriteRecurseFunc e1, rewriteRecurseFunc e2, rewriteRecurseFunc e3)
- | UpdateExpr(e1,e2,e3) -> UpdateExpr(rewriteRecurseFunc e1, rewriteRecurseFunc e2, rewriteRecurseFunc e3)
- | SequenceExpr(exs) -> SequenceExpr(exs |> List.map rewriteRecurseFunc)
- | SetExpr(exs) -> SetExpr(exs |> List.map rewriteRecurseFunc)
- | MethodCall(rcv,cname,mname,ins) -> MethodCall(rewriteRecurseFunc rcv, cname, mname, ins |> List.map rewriteRecurseFunc)
- | MethodOutSelect(mth,name) -> MethodOutSelect(rewriteRecurseFunc mth, name)
- | AssertExpr(e) -> AssertExpr(rewriteRecurseFunc e)
- | AssumeExpr(e) -> AssumeExpr(rewriteRecurseFunc e)
-
-let rec Rewrite rewriterFunc expr =
- let __RewriteOrRecurse e =
- match rewriterFunc e with
- | Some(ee) -> ee
- | None -> Rewrite rewriterFunc e
- MyRewrite rewriterFunc __RewriteOrRecurse expr
-
-// TODO: double check this!
-let rec RewriteBU rewriterFunc expr =
- let rewriteRecurseFunc e =
- RewriteBU rewriterFunc e
-// let e' = Rewrite rewriterFunc e
-// match rewriterFunc e' with
-// | Some(ee) -> ee
-// | None -> e'
- let rewriteFunc e =
- match rewriterFunc e with
- | Some(ee) -> ee
- | None -> e
- let expr' =
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarLiteral(_)
- | ObjLiteral(_)
- | VarDeclExpr(_)
- | IdLiteral(_) -> expr
- | Dot(e, id) -> Dot(rewriteRecurseFunc e, id)
- | ForallExpr(vars,e) -> ForallExpr(vars, rewriteRecurseFunc e)
- | UnaryExpr(op,e) -> UnaryExpr(op, rewriteRecurseFunc e)
- | OldExpr(e) -> OldExpr(rewriteRecurseFunc e)
- | LCIntervalExpr(e) -> LCIntervalExpr(rewriteRecurseFunc e)
- | SeqLength(e) -> SeqLength(rewriteRecurseFunc e)
- | SelectExpr(e1, e2) -> SelectExpr(rewriteRecurseFunc e1, rewriteRecurseFunc e2)
- | BinaryExpr(p,op,e1,e2) -> BinaryExpr(p, op, rewriteRecurseFunc e1, rewriteRecurseFunc e2)
- | IteExpr(e1,e2,e3) -> IteExpr(rewriteRecurseFunc e1, rewriteRecurseFunc e2, rewriteRecurseFunc e3)
- | UpdateExpr(e1,e2,e3) -> UpdateExpr(rewriteRecurseFunc e1, rewriteRecurseFunc e2, rewriteRecurseFunc e3)
- | SequenceExpr(exs) -> SequenceExpr(exs |> List.map rewriteRecurseFunc)
- | SetExpr(exs) -> SetExpr(exs |> List.map rewriteRecurseFunc)
- | MethodCall(rcv,cname,mname,ins) -> MethodCall(rewriteRecurseFunc rcv, cname, mname, ins |> List.map rewriteRecurseFunc)
- | MethodOutSelect(mth,name) -> MethodOutSelect(rewriteRecurseFunc mth, name)
- | AssertExpr(e) -> AssertExpr(rewriteRecurseFunc e)
- | AssumeExpr(e) -> AssumeExpr(rewriteRecurseFunc e)
- expr' |> rewriteFunc
-
-let rec RewriteWithCtx rewriterFunc ctx expr =
- let __RewriteOrRecurse ctx e =
- match rewriterFunc ctx e with
- | Some(ee) -> ee
- | None -> RewriteWithCtx rewriterFunc ctx e
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarLiteral(_)
- | ObjLiteral(_)
- | VarDeclExpr(_)
- | IdLiteral(_) -> match rewriterFunc ctx expr with
- | Some(e) -> e
- | None -> expr
- | Dot(e, id) -> Dot(__RewriteOrRecurse ctx e, id)
- | ForallExpr(vars,e) -> ForallExpr(vars, __RewriteOrRecurse (ctx @ vars) e)
- | UnaryExpr(op,e) -> UnaryExpr(op, __RewriteOrRecurse ctx e)
- | OldExpr(e) -> OldExpr(__RewriteOrRecurse ctx e)
- | LCIntervalExpr(e) -> LCIntervalExpr(__RewriteOrRecurse ctx e)
- | SeqLength(e) -> SeqLength(__RewriteOrRecurse ctx e)
- | SelectExpr(e1, e2) -> SelectExpr(__RewriteOrRecurse ctx e1, __RewriteOrRecurse ctx e2)
- | BinaryExpr(p,op,e1,e2) -> BinaryExpr(p, op, __RewriteOrRecurse ctx e1, __RewriteOrRecurse ctx e2)
- | IteExpr(e1,e2,e3) -> IteExpr(__RewriteOrRecurse ctx e1, __RewriteOrRecurse ctx e2, __RewriteOrRecurse ctx e3)
- | UpdateExpr(e1,e2,e3) -> UpdateExpr(__RewriteOrRecurse ctx e1, __RewriteOrRecurse ctx e2, __RewriteOrRecurse ctx e3)
- | SequenceExpr(exs) -> SequenceExpr(exs |> List.map (__RewriteOrRecurse ctx))
- | SetExpr(exs) -> SetExpr(exs |> List.map (__RewriteOrRecurse ctx))
- | MethodCall(rcv,cname,mname,ins) -> MethodCall(__RewriteOrRecurse ctx rcv, cname, mname, ins |> List.map (__RewriteOrRecurse ctx))
- | MethodOutSelect(mth,name) -> MethodOutSelect(__RewriteOrRecurse ctx mth, name)
- | AssertExpr(e) -> AssertExpr(__RewriteOrRecurse ctx e)
- | AssumeExpr(e) -> AssumeExpr(__RewriteOrRecurse ctx e)
-
-// ====================================================
-/// Substitutes all occurences of all IdLiterals having
-/// the same name as one of the variables in "vars" with
-/// VarLiterals, in "expr".
-// ====================================================
-let RewriteVars vars expr =
- let __IdIsArg id = vars |> List.exists (fun var -> GetVarName var = id)
- Rewrite (fun e ->
- match e with
- | IdLiteral(id) when __IdIsArg id -> Some(VarLiteral(id))
- | _ -> None) expr
-
-// ================================================
-/// Substitutes all occurences of e1 with e2 in expr
-// ================================================
-let Substitute e1 e2 expr =
- Rewrite (fun e ->
- if e = e1 then
- Some(e2)
- else
- None) expr
-
-// ================================================
-/// Distributes the negation operator over
-/// arithmetic relations
-// ================================================
-let rec DistributeNegation expr =
- let __Neg op =
- match op with
- | "=" -> Some("!=")
- | "!=" -> Some("=")
- | "<" -> Some(">=")
- | ">" -> Some("<=")
- | ">=" -> Some("<")
- | "<=" -> Some(">")
- | _ -> None
- Rewrite (fun e ->
- match e with
- | UnaryExpr("!", sub) ->
- match sub with
- | BinaryExpr(p,op,lhs,rhs) ->
- match __Neg op with
- | Some(op') -> Some(BinaryExpr(p, op', DistributeNegation lhs, DistributeNegation rhs))
- | None -> None
- | _ -> None
- | _ -> None) expr
-
-let rec DescendExpr visitorFunc composeFunc leafVal expr =
- let __Compose elist =
- match elist with
- | [] -> leafVal
- | fs :: rest -> rest |> List.fold (fun acc e -> composeFunc (composeFunc acc (visitorFunc e)) (DescendExpr visitorFunc composeFunc leafVal e)) (visitorFunc fs)
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarLiteral(_)
- | ObjLiteral(_)
- | VarDeclExpr(_)
- | IdLiteral(_) -> leafVal
- | AssertExpr(e)
- | AssumeExpr(e)
- | Dot(e, _)
- | ForallExpr(_,e)
- | LCIntervalExpr(e)
- | OldExpr(e)
- | UnaryExpr(_,e)
- | MethodOutSelect(e,_)
- | SeqLength(e) -> __Compose (e :: [])
- | SelectExpr(e1, e2)
- | BinaryExpr(_,_,e1,e2) -> __Compose (e1 :: e2 :: [])
- | IteExpr(e1,e2,e3)
- | UpdateExpr(e1,e2,e3) -> __Compose (e1 :: e2 :: e3 :: [])
- | MethodCall(rcv,_,_,aparams) -> __Compose (rcv :: aparams)
- | SequenceExpr(exs)
- | SetExpr(exs) -> __Compose exs
-
-let rec DescendExpr2 visitorFunc expr acc =
- let newAcc = acc |> visitorFunc expr
- let __Pipe elist = elist |> List.fold (fun a e -> a |> DescendExpr2 visitorFunc e) newAcc
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarLiteral(_)
- | ObjLiteral(_)
- | VarDeclExpr(_)
- | IdLiteral(_) -> newAcc
- | AssertExpr(e)
- | AssumeExpr(e)
- | Dot(e, _)
- | ForallExpr(_,e)
- | LCIntervalExpr(e)
- | OldExpr(e)
- | UnaryExpr(_,e)
- | MethodOutSelect(e,_)
- | SeqLength(e) -> __Pipe (e :: [])
- | SelectExpr(e1, e2)
- | BinaryExpr(_,_,e1,e2) -> __Pipe (e1 :: e2 :: [])
- | IteExpr(e1,e2,e3)
- | UpdateExpr(e1,e2,e3) -> __Pipe (e1 :: e2 :: e3 :: [])
- | MethodCall(rcv,_,_,aparams) -> __Pipe (rcv :: aparams)
- | SequenceExpr(exs)
- | SetExpr(exs) -> __Pipe exs
-
-let rec DescendExpr2BU visitorFunc expr acc =
- let __Pipe elist =
- let newAcc = elist |> List.fold (fun a e -> a |> DescendExpr2 visitorFunc e) acc
- newAcc |> visitorFunc expr
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarLiteral(_)
- | ObjLiteral(_)
- | VarDeclExpr(_)
- | IdLiteral(_) -> __Pipe []
- | AssertExpr(e)
- | AssumeExpr(e)
- | Dot(e, _)
- | ForallExpr(_,e)
- | LCIntervalExpr(e)
- | OldExpr(e)
- | UnaryExpr(_,e)
- | MethodOutSelect(e,_)
- | SeqLength(e) -> __Pipe (e :: [])
- | SelectExpr(e1, e2)
- | BinaryExpr(_,_,e1,e2) -> __Pipe (e1 :: e2 :: [])
- | IteExpr(e1,e2,e3)
- | UpdateExpr(e1,e2,e3) -> __Pipe (e1 :: e2 :: e3 :: [])
- | MethodCall(rcv,_,_,aparams) -> __Pipe (rcv :: aparams)
- | SequenceExpr(exs)
- | SetExpr(exs) -> __Pipe exs
-
-//TODO: if names in dafny models contain funky characters,
-// these gensym variables might not be valid identifiers
-let PrintGenSym (name: string) =
- if name.StartsWith("gensym") then
- name
- else
- let idx = name.LastIndexOf("!")
- if idx <> -1 then
- sprintf "gensym%s" (name.Substring(idx+1))
- else
- sprintf "gensym%s" name
-
-// =====================
-/// Returns TRUE literal
-// =====================
-let TrueLiteral = BoolLiteral(true)
-
-// =====================
-/// Returns FALSE literal
-// =====================
-let FalseLiteral = BoolLiteral(false)
-
-let UnaryNeg sub =
- match sub with
- | UnaryExpr("-", s) -> s
- | _ -> UnaryExpr("-", sub)
-
-let UnaryNot sub =
- match sub with
- | UnaryExpr("!", s) -> s
- | BoolLiteral(b) -> BoolLiteral(not b)
- | BinaryExpr(p,"=",l,r) -> BinaryExpr(p,"!=",l,r)
- | BinaryExpr(p,"!=",l,r) -> BinaryExpr(p,"=",l,r)
- | BinaryExpr(p,"in",l,r) -> BinaryExpr(p,"!in",l,r)
- | BinaryExpr(p,"!in=",l,r) -> BinaryExpr(p,"in",l,r)
- | BinaryExpr(p,"<",l,r) -> BinaryExpr(p,">=",l,r)
- | BinaryExpr(p,"<=",l,r) -> BinaryExpr(p,">",l,r)
- | BinaryExpr(p,">",l,r) -> BinaryExpr(p,"<=",l,r)
- | BinaryExpr(p,">=",l,r) -> BinaryExpr(p,"<",l,r)
- | _ -> UnaryExpr("!", sub)
-
-// =======================================================================
-/// Returns a binary AND of the two given expressions with short-circuiting
-// =======================================================================
-let BinaryAnd (lhs: Expr) (rhs: Expr) =
- match lhs, rhs with
- | BoolLiteral(true), _ -> rhs
- | BoolLiteral(false), _ -> FalseLiteral
- | _, BoolLiteral(true) -> lhs
- | _, BoolLiteral(false) -> FalseLiteral
- | _, _ -> BinaryExpr(30, "&&", lhs, rhs)
-
-// =======================================================================
-/// Returns a binary OR of the two given expressions with short-circuiting
-// =======================================================================
-let BinaryOr (lhs: Expr) (rhs: Expr) =
- match lhs, rhs with
- | BoolLiteral(true), _ -> TrueLiteral
- | BoolLiteral(false), _ -> rhs
- | _, BoolLiteral(true) -> TrueLiteral
- | _, BoolLiteral(false) -> lhs
- | _, _ -> BinaryExpr(30, "||", lhs, rhs)
-
-// ===================================================================================
-/// Returns a binary IMPLIES of the two given expressions
-// ===================================================================================
-let BinaryImplies lhs rhs =
- match lhs, rhs with
- | BoolLiteral(false), _ -> TrueLiteral
- | BoolLiteral(true), _ -> rhs
- | _, BoolLiteral(true) -> lhs
- | _, BoolLiteral(false) -> UnaryNot(lhs)
- | _ -> BinaryExpr(20, "==>", lhs, rhs)
-
-// =======================================================
-/// Constructors for binary EQ/NEQ of two given expressions
-// =======================================================
-let BinaryNeq lhs rhs =
- match lhs, rhs with
- | BoolLiteral(true), x | x, BoolLiteral(true) -> UnaryNot x
- | BoolLiteral(false), x | x, BoolLiteral(false) -> x
- | _ -> BinaryExpr(40, "!=", lhs, rhs)
-
-let BinaryEq lhs rhs =
- match lhs, rhs with
- | BoolLiteral(true), x | x, BoolLiteral(true) -> x
- | BoolLiteral(false), x | x, BoolLiteral(false) -> UnaryNot x
- | _ when lhs = rhs -> TrueLiteral
- | _ -> BinaryExpr(40, "=", lhs, rhs)
-
-// =======================================================
-/// Constructor for binary GETS
-// =======================================================
-let BinaryGets lhs rhs = Assign(lhs, rhs)
-
-let BinaryAdd lhs rhs = BinaryExpr(55, "+", lhs, rhs)
-let BinarySub lhs rhs = BinaryExpr(55, "-", lhs, rhs)
-
-// =======================================================
-/// Constructors for binary IN/!IN of two given expressions
-// =======================================================
-let BinaryIn lhs rhs =
- match lhs, rhs with
- | _, SequenceExpr(elist) | _, SetExpr(elist) when elist |> List.length = 0 -> FalseLiteral
- | _, SequenceExpr(elist) | _, SetExpr(elist) when elist |> List.length = 1 -> BinaryEq lhs (elist.[0])
- | _ -> BinaryExpr(40, "in", lhs, rhs)
-
-let BinaryNotIn lhs rhs =
- match lhs, rhs with
- | _, SequenceExpr(elist) | _, SetExpr(elist) when elist |> List.length = 0 -> TrueLiteral
- | _, SequenceExpr(elist) | _, SetExpr(elist) when elist |> List.length = 1 -> BinaryNeq lhs (elist.[0])
- | _ -> BinaryExpr(40, "!in", lhs, rhs)
-
-// ==========================================
-/// Splits "expr" into a list of its conjuncts
-// ==========================================
-let rec SplitIntoConjunts expr =
- match expr with
- | BoolLiteral(true) -> []
- | BinaryExpr(_,"&&",e0,e1) -> List.concat [SplitIntoConjunts e0 ; SplitIntoConjunts e1]
- | _ -> [expr]
-
-// ======================================
-/// Applies "f" to each conjunct of "expr"
-// ======================================
-let rec ForeachConjunct f expr =
- SplitIntoConjunts expr |> List.fold (fun acc e -> acc + (f e)) ""
-
-// =======================================
-/// Converts a given constant to expression
-// =======================================
-let rec Const2Expr c =
- match c with
- | IntConst(n) -> IntLiteral(n)
- | BoolConst(b) -> BoolLiteral(b)
- | BoxConst(id) -> BoxLiteral(id)
- | SeqConst(clist) ->
- let expList = clist |> List.fold (fun acc c -> Const2Expr c :: acc) [] |> List.rev
- SequenceExpr(expList)
- | SetConst(cset) ->
- let expSet = cset |> Set.fold (fun acc c -> Set.add (Const2Expr c) acc) Set.empty
- SetExpr(Set.toList expSet)
- | VarConst(id) -> VarLiteral(id)
- | ThisConst(_,_) -> ObjLiteral("this")
- | NewObj(name,_) -> ObjLiteral(PrintGenSym name)
- | NullConst -> ObjLiteral("null")
- | Unresolved(id) -> BoxLiteral(id) // failwithf "don't want to convert Unresolved(%s) to expr" name //
- | _ -> failwithf "not implemented or not supported: %O" c
-
-let rec Expr2Const e =
- match e with
- | IntLiteral(n) -> IntConst(n)
- | BoolLiteral(b) -> BoolConst(b)
- | BoxLiteral(id) -> BoxConst(id)
- | ObjLiteral("this") -> ThisConst("this",None)
- | ObjLiteral("null") -> NullConst
- | ObjLiteral(name) -> NewObj(name, None)
- | IdLiteral(id) -> Unresolved(id)
- | VarLiteral(id) -> VarConst(id)
- | SequenceExpr(elist) -> SeqConst(elist |> List.map Expr2Const)
- | SetExpr(elist) -> SetConst(elist |> List.map Expr2Const |> Set.ofList)
- | _ -> failwithf "Not a constant: %O" e
-
-let rec Expr2ConstStrict e =
- match e with
- | IntLiteral(n) -> IntConst(n)
- | BoolLiteral(b) -> BoolConst(b)
- | BoxLiteral(id) -> BoxConst(id)
- | ObjLiteral("this") -> ThisConst("this",None)
- | ObjLiteral("null") -> NullConst
- | ObjLiteral(name) -> NewObj(name, None)
- | SequenceExpr(elist) -> SeqConst(elist |> List.map Expr2ConstStrict)
- | SetExpr(elist) -> SetConst(elist |> List.map Expr2ConstStrict |> Set.ofList)
- | _ -> failwithf "Not a constant: %O" e
-
-let TryExpr2Const e =
- try
- Some(Expr2Const e)
- with
- | ex -> None
-
-let IsConstExpr e =
- try
- Expr2Const e |> ignore
- true
- with
- | _ -> false
-
-///////
-
-let GetMethodPre mthd =
- match mthd with
- | Method(_,_,pre,_,_) -> pre
- | _ -> failwith ("not a method" + mthd.ToString())
-
-let GetMethodPrePost mthd =
- let __FilterOutAssumes e = e |> SplitIntoConjunts |> List.filter (function AssumeExpr(_) -> false | _ -> true) |> List.fold BinaryAnd TrueLiteral
- match mthd with
- | Method(_,_,pre,post,_) -> __FilterOutAssumes pre,post
- | _ -> failwith ("not a method: " + mthd.ToString())
-
-let GetMethodGhostPrecondition mthd =
- match mthd with
- | Method(_,_,pre,_,_) ->
- pre |> SplitIntoConjunts |> List.choose (function AssumeExpr(e) -> Some(e) | _ -> None) |> List.fold BinaryAnd TrueLiteral
- | _ -> failwith ("not a method: " + mthd.ToString())
-
-// ==============================================================
-/// Returns all invariants of a component as a list of expressions
-// ==============================================================
-let GetInvariantsAsList comp =
- match comp with
- | Component(Interface(_,_,members), DataModel(_,_,_,_,inv), _) ->
- let clsInvs = members |> List.choose (function Invariant(exprList) -> Some(exprList) | _ -> None) |> List.concat
- List.append (SplitIntoConjunts inv) clsInvs
- | _ -> failwithf "unexpected kind of component: %O" comp
-
-/// Replaces all Old nodes with IdLiteral with name = "old_" + <name>
-let RewriteOldExpr expr =
- expr |> RewriteBU (fun e -> match e with
- | OldExpr(IdLiteral(name)) -> Some(IdLiteral(RenameToOld name))
- | _ -> None)
-
-let MakeOldVar var =
- match var with
- | Var(name, ty, _) -> Var(name, ty, true)
-
-let MakeOldVars varLst =
- varLst |> List.map MakeOldVar
-
-/// renames ALL variables to "old_"+<varname>
-let MakeOld expr =
- expr |> RewriteBU (fun e -> match e with
- | IdLiteral(name) when not (name="this") -> Some(IdLiteral(RenameToOld name))
- | Dot(e, name) -> Some(Dot(e, RenameToOld name))
- | _ -> None)
-
-let BringToPost expr =
- expr |> RewriteBU (fun e -> match e with
- | IdLiteral(name) -> Some(IdLiteral(RenameFromOld name))
- | Dot(e, name) -> Some(Dot(e, RenameFromOld name))
- | _ -> None)
-
-////////////////////////
-
-let AddReplaceMethod prog comp newMthd oldMethod =
- match prog, comp with
- | Program(clist), Component(Interface(cname, ctypeParams, members), model, code) ->
- let newMembers =
- match oldMethod with
- | None -> members @ [newMthd]
- | Some(m) -> Utils.ListReplace m newMthd members
- let newCls = Interface(cname, ctypeParams, newMembers)
- let newComp = Component(newCls, model, code)
- let newProg = Program(Utils.ListReplace comp newComp clist)
- newProg, newComp
- | _ -> failwithf "Invalid component: %O" comp
-
-let UnwrapAssumes e = e |> SplitIntoConjunts |> List.map (function AssumeExpr(e) -> e | x -> x) |> List.fold BinaryAnd TrueLiteral
-
-let AddPrecondition m e =
- match m with
- | Method(mn, sgn, pre, post, cstr) -> Method(mn, sgn, BinaryAnd pre (AssumeExpr(e |> UnwrapAssumes)), post, cstr)
- | _ -> failwithf "Not a method: %O" m
-
-let SetPrecondition m e =
- match m with
- | Method(mn, sgn, pre, post, cstr) -> Method(mn, sgn, AssumeExpr(e |> UnwrapAssumes), post, cstr)
- | _ -> failwithf "Not a method: %O" m
-
-////////////////////
-
-exception EvalFailed of string
-exception DomainNotInferred
-
-let DefaultResolver e fldOpt =
- match fldOpt with
- | None -> e
- | Some(fldName) -> Dot(e, fldName)
-
-let DefaultFallbackResolver resolverFunc e =
- match resolverFunc e with
- | Some(e') -> e'
- | None -> e
-
-let __CheckEqual e1 e2 =
- match e1, e2 with
- | BoolLiteral(b1), BoolLiteral(b2) -> Some(b1 = b2)
- | IntLiteral(n1), IntLiteral(n2) -> Some(n1 = n2)
- | ObjLiteral(o1), ObjLiteral(o2) -> Some(o1 = o2)
- | SetExpr(elist1), SetExpr(elist2) -> Some(Set.ofList elist1 = Set.ofList elist2)
- | SequenceExpr(elist1), SequenceExpr(elist2) -> Some(elist1 = elist2)
- | UnaryExpr("-", sub1), sub2
- | sub1, UnaryExpr("-", sub2) when sub1 = sub2 -> Some(false)
- | UnaryExpr("-", sub1), UnaryExpr("-", sub2) when sub1 = sub2 -> Some(true)
- | UnaryExpr("!", sub1), sub2
- | sub1, UnaryExpr("!", sub2) when sub1 = sub2 -> Some(false)
- | UnaryExpr("!", sub1), UnaryExpr("-", sub2) when sub1 = sub2 -> Some(true)
- | _ when e1 = e2 -> Some(true)
- | _ -> None
-
-let EvalSym2 fullResolverFunc otherResolverFunc returnFunc ctx expr =
- let rec __EvalSym resolverFunc returnFunc ctx expr =
- let expr' =
- match expr with
- | IntLiteral(_) -> expr
- | BoolLiteral(_) -> expr
- | BoxLiteral(_) -> expr
- | ObjLiteral(_) -> expr
- | Star -> expr //TODO: can we do better?
- | VarDeclExpr(_) -> expr
- | AssertExpr(e) -> AssertExpr(__EvalSym resolverFunc returnFunc ctx e)
- | AssumeExpr(e) -> AssumeExpr(__EvalSym resolverFunc returnFunc ctx e)
- | VarLiteral(id) ->
- try
- let _,e = ctx |> List.find (fun (v,e) -> GetVarName v = id)
- e
- with
- | ex -> resolverFunc expr None
- | IdLiteral(_) -> resolverFunc expr None
- | Dot(e, str) ->
- let discr = __EvalSym resolverFunc returnFunc ctx e
- resolverFunc discr (Some(str))
- | SeqLength(e) ->
- let e' = __EvalSym resolverFunc returnFunc ctx e
- match e' with
- | SequenceExpr(elist) -> IntLiteral(List.length elist)
- | _ -> SeqLength(e')
- | SequenceExpr(elist) ->
- let elist' = elist |> List.map (__EvalSym resolverFunc returnFunc ctx) // List.fold (fun acc e -> (__EvalSym resolverFunc returnFunc ctx e) :: acc) [] |> List.rev
- SequenceExpr(elist')
- | SetExpr(elist) ->
- let elist' = elist |> List.map (__EvalSym resolverFunc returnFunc ctx) //List.fold (fun acc e -> Set.add (__EvalSym resolverFunc returnFunc ctx e) acc) Set.empty
- SetExpr(elist' |> Set.ofList |> Set.toList)
- | MethodOutSelect(e,name) ->
- MethodOutSelect(__EvalSym resolverFunc returnFunc ctx e, name)
- | MethodCall(rcv,cname, mname,aparams) ->
- let rcv' = __EvalSym resolverFunc returnFunc ctx rcv
- let aparams' = aparams |> List.fold (fun acc e -> __EvalSym resolverFunc returnFunc ctx e :: acc) [] |> List.rev
- MethodCall(rcv', cname, mname, aparams')
- | LCIntervalExpr(_) -> expr
- | SelectExpr(lst, idx) ->
- let lst' = __EvalSym resolverFunc returnFunc ctx lst
- let idx' = __EvalSym resolverFunc returnFunc ctx idx
- match lst', idx' with
- | SequenceExpr(elist), IntLiteral(n) -> elist.[n]
- | SequenceExpr(elist), LCIntervalExpr(startIdx) ->
- let startIdx' = __EvalSym resolverFunc returnFunc ctx startIdx
- match startIdx' with
- | IntLiteral(startIdxInt) ->
- let rec __Skip n l = if n = 0 then l else __Skip (n-1) (List.tail l)
- SequenceExpr(__Skip startIdxInt elist)
- | _ -> SelectExpr(lst', idx')
- | _ -> SelectExpr(lst', idx')
- | UpdateExpr(lst,idx,v) ->
- let lst', idx', v' = __EvalSym resolverFunc returnFunc ctx lst, __EvalSym resolverFunc returnFunc ctx idx, __EvalSym resolverFunc returnFunc ctx v
- match lst', idx', v' with
- | SequenceExpr(elist), IntLiteral(n), _ -> SequenceExpr(Utils.ListSet n v' elist)
- | _ -> UpdateExpr(lst', idx', v')
- | IteExpr(c, e1, e2) ->
- let c' = __EvalSym fullResolverFunc returnFunc ctx c
- match c' with
- | BoolLiteral(b) -> if b then __EvalSym resolverFunc returnFunc ctx e1 else __EvalSym resolverFunc returnFunc ctx e2
- | _ -> IteExpr(c', __EvalSym resolverFunc returnFunc ctx e1, __EvalSym resolverFunc returnFunc ctx e2)
- | BinaryExpr(p,op,e1,e2) ->
- let e1' = lazy (__EvalSym resolverFunc returnFunc ctx e1)
- let e2' = lazy (__EvalSym resolverFunc returnFunc ctx e2)
- let recomposed = lazy (BinaryExpr(p, op, e1'.Force(), e2'.Force()))
- match op with
- | "=" ->
- let e1'' = e1'.Force()
- let e2'' = e2'.Force()
- let eq = __CheckEqual e1'' e2''
- match eq with
- | Some(b) -> BoolLiteral(b)
- | None -> recomposed.Force()
- | "!=" ->
- let e1'' = e1'.Force()
- let e2'' = e2'.Force()
- let eq = __CheckEqual e1'' e2''
- match eq with
- | Some(b) -> BoolLiteral(not b)
- | None -> recomposed.Force()
- | "<" ->
- match e1'.Force(), e2'.Force() with
- | IntLiteral(n1), IntLiteral(n2) -> BoolLiteral(n1 < n2)
- | _ -> recomposed.Force()
- | "<=" ->
- let e1'' = e1'.Force()
- let e2'' = e2'.Force()
- let eq = __CheckEqual e1'' e2''
- match eq with
- | Some(true) -> TrueLiteral
- | _ -> match e1'', e2'' with
- | IntLiteral(n1), IntLiteral(n2) -> BoolLiteral(n1 <= n2)
- | _ -> recomposed.Force()
- | ">" ->
- match e1'.Force(), e2'.Force() with
- | IntLiteral(n1), IntLiteral(n2) -> BoolLiteral(n1 > n2)
- | _ -> recomposed.Force()
- | ">=" ->
- let e1'' = e1'.Force()
- let e2'' = e2'.Force()
- let eq = __CheckEqual e1'' e2''
- match eq with
- | Some(true) -> TrueLiteral
- | _ -> match e1'', e2'' with
- | IntLiteral(n1), IntLiteral(n2) -> BoolLiteral(n1 >= n2)
- | _ -> recomposed.Force()
- | ".." ->
- let e1'' = e1'.Force()
- let e2'' = e2'.Force()
- match e1'', e2'' with
- | IntLiteral(lo), IntLiteral(hi) -> SequenceExpr([lo .. hi] |> List.map (fun n -> IntLiteral(n)))
- | _ -> recomposed.Force();
- | "in" ->
- match e1'.Force(), e2'.Force() with
- | _, SetExpr(s)
- | _, SequenceExpr(s) -> //BoolLiteral(Utils.ListContains (e1'.Force()) s)
- if Utils.ListContains (e1'.Force()) s then
- TrueLiteral
- else
- try
- let contains = s |> List.map Expr2ConstStrict |> Utils.ListContains (e1'.Force() |> Expr2ConstStrict)
- BoolLiteral(contains)
- with
- | _ -> recomposed.Force()
- | _ -> recomposed.Force()
- | "!in" ->
- match e1'.Force(), e2'.Force() with
- | _, SetExpr(s)
- | _, SequenceExpr(s) -> //BoolLiteral(not (Utils.ListContains (e1'.Force()) s))
- if Utils.ListContains (e1'.Force()) s then
- FalseLiteral
- else
- try
- let contains = s |> List.map Expr2ConstStrict |> Utils.ListContains (e1'.Force() |> Expr2ConstStrict)
- BoolLiteral(not contains)
- with
- | _ -> recomposed.Force()
- | _ -> recomposed.Force()
- | "+" ->
- let e1'' = e1'.Force();
- let e2'' = e2'.Force();
- match e1'', e2'' with
- | IntLiteral(n1), IntLiteral(n2) -> IntLiteral(n1 + n2)
- | SequenceExpr(l1), SequenceExpr(l2) -> SequenceExpr(List.append l1 l2)
- | SetExpr(s1), SetExpr(s2) -> SetExpr(Set.union (Set.ofList s1) (Set.ofList s2) |> Set.toList)
- | _ -> recomposed.Force()
- | "-" ->
- match e1'.Force(), e2'.Force() with
- | IntLiteral(n1), IntLiteral(n2) -> IntLiteral(n1 - n2)
- | SetExpr(s1), SetExpr(s2) -> SetExpr(Set.difference (Set.ofList s1) (Set.ofList s2) |> Set.toList)
- | _ -> recomposed.Force()
- | "*" ->
- match e1'.Force(), e2'.Force() with
- | IntLiteral(n1), IntLiteral(n2) -> IntLiteral(n1 * n2)
- | _ -> recomposed.Force()
- | "div" ->
- match e1'.Force(), e2'.Force() with
- | IntLiteral(n1), IntLiteral(n2) -> IntLiteral(n1 / n2)
- | _ -> recomposed.Force()
- | "mod" ->
- match e1'.Force(), e2'.Force() with
- | IntLiteral(n1), IntLiteral(n2) -> IntLiteral(n1 % n2)
- | _ -> recomposed.Force()
- | "&&" ->
- // shortcircuit
- match e1'.Force() with
- | BoolLiteral(false) -> BoolLiteral(false)
- | _ ->
- match e1'.Force(), e2'.Force() with
- | _, BoolLiteral(false) -> BoolLiteral(false)
- | BoolLiteral(b1), BoolLiteral(b2) -> BoolLiteral(b1 && b2)
- | _ -> BinaryAnd (e1'.Force()) (e2'.Force())
- | "||" ->
- // shortcircuit
- match e1'.Force() with
- | BoolLiteral(true) -> BoolLiteral(true)
- | _ ->
- match e1'.Force(), e2'.Force() with
- | _, BoolLiteral(true) -> BoolLiteral(true)
- | BoolLiteral(b1), BoolLiteral(b2) -> BoolLiteral(b1 || b2)
- | _ -> BinaryOr (e1'.Force()) (e2'.Force())
- | "==>" ->
- // shortcircuit
- match e1'.Force() with
- | BoolLiteral(false) -> BoolLiteral(true)
- | _ ->
- let e1'' = e1'.Force()
- let e2'' = e2'.Force()
- BinaryImplies e1'' e2''
- | "<==>" ->
- match e1'.Force(), e2'.Force() with
- | BoolLiteral(b1), BoolLiteral(b2) -> BoolLiteral(b1 = b2)
- | x, BoolLiteral(b)
- | BoolLiteral(b), x -> if b then x else UnaryNot(x)
- | _ -> recomposed.Force()
- | _ -> recomposed.Force()
- | OldExpr(e) ->
- let e' = __EvalSym resolverFunc returnFunc ctx e
- let recomposed = OldExpr(e')
- match e with
- | IdLiteral(name) -> resolverFunc (IdLiteral(RenameToOld name)) None
- | _ -> recomposed
- | UnaryExpr(op, e) ->
- let e' = __EvalSym resolverFunc returnFunc ctx e
- let recomposed = UnaryExpr(op, e')
- match op with
- | "!" ->
- match e' with
- | BoolLiteral(b) -> BoolLiteral(not b)
- | _ -> recomposed
- | "-" ->
- match e' with
- | IntLiteral(n) -> IntLiteral(-n)
- | _ -> recomposed
- | _ -> recomposed
- | ForallExpr(vars, e) ->
- let rec __ExhaustVar v restV vDomain =
- match vDomain with
- | vv :: restD ->
- let ctx' = (v,vv) :: ctx
- let e' = __EvalSym resolverFunc returnFunc ctx' (ForallExpr(restV, e))
- let erest = __ExhaustVar v restV restD
- BinaryAnd e' erest
- | [] -> BoolLiteral(true)
- let rec __TraverseVars vars =
- match vars with
- | v :: restV ->
- try
- let vDom = GetVarDomain resolverFunc returnFunc ctx v e
- __ExhaustVar v restV vDom
- with
- | ex -> ForallExpr([v], __TraverseVars restV)
- | [] -> __EvalSym resolverFunc returnFunc ctx e
- (* --- function body starts here --- *)
- __TraverseVars vars
- if expr' = FalseLiteral then
- Logger.Debug ""
- expr' |> returnFunc
- and GetVarDomain resolverFunc returnFunc ctx var expr =
- match expr with
- | BinaryExpr(_, "==>", lhs, rhs) ->
- let conjs = SplitIntoConjunts lhs
- conjs |> List.fold (fun acc e ->
- match e with
- | BinaryExpr(_, "in", VarLiteral(vn), rhs) when GetVarName var = vn ->
- match __EvalSym resolverFunc returnFunc ctx rhs with
- | SetExpr(elist)
- | SequenceExpr(elist) -> elist |> List.append acc
- | x -> raise DomainNotInferred
- | BinaryExpr(_, op, VarLiteral(vn),oth)
- | BinaryExpr(_, op, oth, VarLiteral(vn)) when GetVarName var = vn && Set.ofList ["<"; "<="; ">"; ">="] |> Set.contains op ->
- failwith "Not implemented yet"
- | _ -> raise DomainNotInferred) []
- | _ ->
- Logger.WarnLine ("unknown pattern for a quantified expression; cannot infer domain of quantified variable \"" + (GetVarName var) + "\"")
- raise DomainNotInferred
- (* --- function body starts here --- *)
- __EvalSym otherResolverFunc returnFunc ctx expr
-
-let EvalSym resolverFunc expr =
- EvalSym2 resolverFunc resolverFunc (fun e -> e) [] expr
-
-let EvalSymRet fullResolverFunc resolverFunc returnFunc expr =
- EvalSym2 fullResolverFunc resolverFunc returnFunc [] expr
-
-// ==========================================================
-/// Desugars a given expression so that all list constructors
-/// are expanded into explicit assignments to indexed elements
-// ==========================================================
-let MyDesugar expr removeOriginal =
- let rec __Desugar expr =
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | VarDeclExpr(_)
- | IdLiteral(_)
- | VarLiteral(_)
- | ObjLiteral(_)
- | Star
- | Dot(_)
- | SelectExpr(_)
- | SeqLength(_)
- | UpdateExpr(_)
- | SetExpr(_)
- | MethodCall(_)
- | MethodOutSelect(_)
- | SequenceExpr(_) -> expr
- // forall v :: v in {a1 a2 ... an} ==> e ~~~> e[v/a1] && e[v/a2] && ... && e[v/an]
- // forall v :: v in [a1 a2 ... an] ==> e ~~~> e[v/a1] && e[v/a2] && ... && e[v/an]
- | ForallExpr([Var(vn1,ty1,old1)] as v, (BinaryExpr(_, "==>", BinaryExpr(_, "in", VarLiteral(vn2), rhsCol), sub) as ee)) when vn1 = vn2 ->
- match rhsCol with
- | SetExpr(elist)
- | SequenceExpr(elist) -> elist |> List.fold (fun acc e -> BinaryAnd acc (__Desugar (Substitute (VarLiteral(vn2)) e sub))) TrueLiteral
- | _ -> ForallExpr(v, __Desugar ee)
- | ForallExpr(v,e) -> ForallExpr(v, __Desugar e)
- | LCIntervalExpr(e) -> LCIntervalExpr(__Desugar e)
- | OldExpr(e) -> OldExpr(__Desugar e)
- | UnaryExpr(op,e) -> UnaryExpr(op, __Desugar e)
- | AssertExpr(e) -> AssertExpr(__Desugar e)
- | AssumeExpr(e) -> AssumeExpr(__Desugar e)
- | IteExpr(c,e1,e2) -> IteExpr(c, __Desugar e1, __Desugar e2)
- // lst = [a1 a2 ... an] ~~~> lst = [a1 a2 ... an] && lst[0] = a1 && lst[1] = a2 && ... && lst[n-1] = an && |lst| = n
- | BinaryExpr(p,op,e1,e2) ->
- let be = BinaryExpr(p, op, __Desugar e1, __Desugar e2)
- let fs = if removeOriginal then TrueLiteral else be
- try
- match op with
- | "=" ->
- match EvalSym DefaultResolver e1, EvalSym DefaultResolver e2 with
- | SequenceExpr(l1), SequenceExpr(l2) ->
- let rec __fff lst1 lst2 cnt =
- match lst1, lst2 with
- | fs1 :: rest1, fs2 :: rest2 -> BinaryEq l1.[cnt] l2.[cnt] :: __fff rest1 rest2 (cnt+1)
- | [], [] -> []
- | _ -> failwith "Lists are of different sizes"
- __fff l1 l2 0 |> List.fold (fun acc e -> BinaryAnd acc e) fs
- | e, SequenceExpr(elist)
- | SequenceExpr(elist), e ->
- let rec __fff lst cnt =
- match lst with
- | fs :: rest -> BinaryEq (SelectExpr(e, IntLiteral(cnt))) elist.[cnt] :: __fff rest (cnt+1)
- | [] -> [BinaryEq (SeqLength(e)) (IntLiteral(cnt))]
- __fff elist 0 |> List.fold (fun acc e -> BinaryAnd acc e) fs
- | _ -> be
- | _ -> be
- with
- | EvalFailed(_) as ex -> (* printfn "%O" (ex.StackTrace); *) be
- __Desugar expr
-
-let Desugar expr = MyDesugar expr false
-let DesugarAndRemove expr = MyDesugar expr true
-
-let rec DesugarLst exprLst =
- match exprLst with
- | expr :: rest -> Desugar expr :: DesugarLst rest
- | [] -> []
-
-let ChangeThisReceiver receiver expr =
- let rec __ChangeThis locals expr =
- match expr with
- | IntLiteral(_)
- | BoolLiteral(_)
- | BoxLiteral(_)
- | Star
- | VarDeclExpr(_)
- | VarLiteral(_) -> expr
- | ObjLiteral("this") -> receiver
- | ObjLiteral(_) -> expr
- | IdLiteral("null") -> failwith "should never happen anymore" //TODO
- | IdLiteral("this") -> failwith "should never happen anymore"
- | IdLiteral(id) -> if Set.contains id locals then VarLiteral(id) else __ChangeThis locals (Dot(ObjLiteral("this"), id))
- | Dot(e, id) -> Dot(__ChangeThis locals e, id)
- | AssertExpr(e) -> AssertExpr(__ChangeThis locals e)
- | AssumeExpr(e) -> AssumeExpr(__ChangeThis locals e)
- | ForallExpr(vars,e) -> let newLocals = vars |> List.map GetVarName |> Set.ofList |> Set.union locals
- ForallExpr(vars, __ChangeThis newLocals e)
- | LCIntervalExpr(e) -> LCIntervalExpr(__ChangeThis locals e)
- | OldExpr(e) -> OldExpr(__ChangeThis locals e)
- | UnaryExpr(op,e) -> UnaryExpr(op, __ChangeThis locals e)
- | SeqLength(e) -> SeqLength(__ChangeThis locals e)
- | SelectExpr(e1, e2) -> SelectExpr(__ChangeThis locals e1, __ChangeThis locals e2)
- | BinaryExpr(p,op,e1,e2) -> BinaryExpr(p, op, __ChangeThis locals e1, __ChangeThis locals e2)
- | IteExpr(e1,e2,e3) -> IteExpr(__ChangeThis locals e1, __ChangeThis locals e2, __ChangeThis locals e3)
- | UpdateExpr(e1,e2,e3) -> UpdateExpr(__ChangeThis locals e1, __ChangeThis locals e2, __ChangeThis locals e3)
- | SequenceExpr(exs) -> SequenceExpr(exs |> List.map (__ChangeThis locals))
- | SetExpr(exs) -> SetExpr(exs |> List.map (__ChangeThis locals))
- | MethodOutSelect(e, name) -> MethodOutSelect(__ChangeThis locals e, name)
- | MethodCall(rcv,cname, mname,aparams) -> MethodCall(__ChangeThis locals rcv, cname, mname, aparams |> List.map (__ChangeThis locals))
- (* --- function body starts here --- *)
- __ChangeThis Set.empty expr
-
-let rec SimplifyExpr expr =
- let __Simplify expr =
- match expr with
- | UnaryExpr("!", sub) -> Some(UnaryNot sub)
- | BinaryExpr(_, "&&", l, r) -> Some(BinaryAnd l r)
- | BinaryExpr(_, "||", l, r) -> Some(BinaryOr l r)
- | BinaryExpr(_, "in", l, r) -> Some(BinaryIn l r)
- | BinaryExpr(_, "!in", l, r) -> Some(BinaryNotIn l r)
- | BinaryExpr(_, "==>", l, r) -> Some(BinaryImplies l r)
- | BinaryExpr(_, "=", l, r) -> Some(BinaryEq l r)
- | BinaryExpr(_, "!=", l, r) -> Some(BinaryNeq l r)
- | _ -> None
- RewriteBU __Simplify expr
-
-let rec ExtractTopLevelExpressions stmt =
- match stmt with
- | ExprStmt(e) -> [e]
- | Assign(e1, e2) -> [e1; e2]
- | Block(slist) -> slist |> List.fold (fun acc s -> acc @ ExtractTopLevelExpressions s) []
-
-let rec PullUpMethodCalls stmt =
- let stmtList = new System.Collections.Generic.LinkedList<_>()
- let rec __PullUpMethodCalls expr =
- let newExpr = RewriteBU (fun expr ->
- match expr with
- | MethodOutSelect(_) ->
- let vname = SymGen.NewSymFake expr
- let e' = VarLiteral(vname)
- let var = VarDeclExpr([Var(vname,None,false)], true)
- let asgn = BinaryGets var expr
- stmtList.AddLast asgn |> ignore
- Some(e')
- | _ -> None
- ) expr
- newExpr, (stmtList |> List.ofSeq)
- stmtList.Clear()
- match stmt with
- | ExprStmt(e) ->
- let e', slist = __PullUpMethodCalls e
- slist @ [ExprStmt(e')]
- | Assign(e1, e2) ->
- let e2', slist = __PullUpMethodCalls e2
- slist @ [Assign(e1, e2')]
- | Block(slist) -> slist |> List.fold (fun acc s -> acc @ PullUpMethodCalls s) []
-
-// ==========================================================
-/// Very simple for now:
-/// - if "m" is a constructor, everything is modifiable
-/// - if the method's post condition contains assignments to fields, everything is modifiable
-/// - otherwise, all objects are immutable
-///
-/// (TODO: instead it should read the "modifies" clause of a method and figure out what's modifiable from there)
-// ==========================================================
-let IsModifiableObj obj (c,m) =
- let __IsFld name = FindVar c name |> Utils.OptionToBool
- match m with
- | Method(name,_,_,_,_) when name.EndsWith("__mod__") -> true
- | Method(_,_,_,_,true) -> true
- | Method(_,_,_,post,false) ->
- DescendExpr2 (fun e acc ->
- match e with
- | BinaryExpr(_,"=",IdLiteral(name),r) when __IsFld name -> true
- | Dot(_,name) when __IsFld name -> true
- | _ -> acc
- ) post false
- | _ -> failwithf "expected a Method but got %O" m \ No newline at end of file
diff --git a/Jennisys/Jennisys/CodeGen.fs b/Jennisys/Jennisys/CodeGen.fs
deleted file mode 100644
index 8df4ca60..00000000
--- a/Jennisys/Jennisys/CodeGen.fs
+++ /dev/null
@@ -1,429 +0,0 @@
-module CodeGen
-
-open Ast
-open Getters
-open AstUtils
-open Utils
-open Resolver
-open TypeChecker
-open PrintUtils
-open DafnyPrinter
-open DafnyModelUtils
-open Options
-
-let validFuncName = "Valid()"
-let validSelfFuncName = "Valid_self()"
-let validReprFuncName = "Valid_repr()"
-
-/// requires: numUnrols >= 0
-/// requires: |fldExprs| = |fldNames|
-let rec GetUnrolledFieldValidExpr fldExprs fldNames validFuncToUse numUnrolls =
- let rec __Combine exprLst strLst =
- match exprLst with
- | e :: rest ->
- let resLst1 = strLst |> List.map (fun s -> Dot(e, s))
- List.concat [resLst1; __Combine rest strLst]
- | [] -> []
- let rec __NotNull e =
- match e with
- | IdLiteral(_)
- | ObjLiteral(_) -> BinaryNeq e (ObjLiteral("null"))
- | Dot(sub, str) -> BinaryAnd (__NotNull sub) (BinaryNeq e (ObjLiteral("null")))
- | _ -> failwith "not supposed to happen"
- (* --- function body starts here --- *)
- assert (numUnrolls >= 0)
- if numUnrolls = 0 then
- [TrueLiteral]
- else
- let exprList = fldExprs |> List.map (fun e -> BinaryImplies (__NotNull e) (Dot(e, validFuncToUse)))
- if numUnrolls = 1 then
- exprList
- else
- let fldExprs = __Combine fldExprs fldNames
- List.append exprList (GetUnrolledFieldValidExpr fldExprs fldNames validFuncToUse (numUnrolls - 1))
-
-let GetFieldValidExpr flds validFunName numUnrolls =
- let fldExprs = flds |> List.map (fun var -> IdLiteral(GetExtVarName var))
- let fldNames = flds |> List.map GetExtVarName
- let unrolledExprs = GetUnrolledFieldValidExpr fldExprs fldNames validFunName numUnrolls
- // add the recursive definition as well
- let recExprs =
- if not (validFunName = validFuncName) && Options.CONFIG.recursiveValid then
- flds //|> List.filter (fun var -> not ((GetExtVarName var).StartsWith("_back_"))) //don't use back pointers
- |> List.map (fun var ->
- let name = GetExtVarName var
- BinaryImplies (BinaryNeq (IdLiteral(name)) NullLiteral) (Dot(IdLiteral(name), validFuncName)))
- else
- []
- recExprs @ unrolledExprs
-
-let GetFieldsForValidExpr allFields prog comp : VarDecl list =
- let frameVars = GetFrameFields comp
- allFields |> List.filter (fun var -> IsUserType prog (GetVarType var))
- |> List.filter (fun var -> Utils.ListContains var frameVars)
-
-let GetFieldsValidExprList clsName allFields prog : Expr list =
- let fields = GetFieldsForValidExpr allFields prog (FindComponent prog clsName |> ExtractOption)
- let fieldsByType = GroupFieldsByType fields
- fieldsByType |> Map.fold (fun acc t varSet ->
- let validFunName, numUnrolls =
- match t with
- | Some(ty) when clsName = (GetTypeShortName ty) -> validSelfFuncName, Options.CONFIG.numLoopUnrolls
- | _ -> validFuncName, 1
- acc |> List.append (GetFieldValidExpr (Set.toList varSet) validFunName numUnrolls)
- ) []
-
-let PrintValidFunctionCode comp prog vars allInvs genRepr nameSuffix: string =
- let validFuncName = "Valid" + nameSuffix + "()"
- let validReprFuncName = "Valid_repr" + nameSuffix + "()"
- let validSelfFuncName = "Valid_self" + nameSuffix + "()"
- let idt = " "
- let __PrintInvs invs =
- invs |> List.fold (fun acc e -> List.concat [acc ; SplitIntoConjunts e]) []
- |> PrintSep (" &&" + newline) (fun e -> sprintf "%s(%s)" idt (PrintExpr 0 e))
- |> fun s -> if s = "" then (idt + "true") else s
- let clsName = GetClassName comp
- let compTypeName = GetClassType comp |> PrintType
- let hasLoop = vars |> List.exists (fun var -> match GetVarType var with Some(ty) when compTypeName = PrintType ty -> true | _ -> false)
- let fieldsValid = GetFieldsValidExprList clsName vars prog
-
- let frameFldNames = GetFrameFields comp |> List.map GetExtVarName
- let validReprBody =
- " this in Repr &&" + newline +
- " null !in Repr" +
- (PrintSep "" (fun x -> " &&" + newline + " ($x != null ==> $x in Repr && $x.Repr <= Repr && this !in $x.Repr)".Replace("$x", x)) frameFldNames)
-
- let vr =
- if genRepr then
- " function " + validReprFuncName + ": bool" + newline +
- " reads *;" + newline +
- " {" + newline +
- validReprBody + newline +
- " }" + newline + newline
- else
- ""
-
- let decreasesStr =
- if Options.CONFIG.recursiveValid then
- if hasLoop then
- if genRepr then
- " decreases Repr;" + newline
- else
- // TODO: Dafny currently doesn't accept "decreases *" on methods
- " decreases *;" + newline
- else
- ""
- else ""
- vr +
- " function " + validSelfFuncName + ": bool" + newline +
- " reads *;" + newline +
- " {" + newline +
- (if genRepr then " " + validReprFuncName + " &&" + newline else "") +
- (__PrintInvs allInvs) + newline +
- " }" + newline +
- newline +
- " function " + validFuncName + ": bool" + newline +
- " reads *;" + newline +
- decreasesStr +
- " {" + newline +
- " this." + validSelfFuncName + " &&" + newline +
- (__PrintInvs fieldsValid) + newline +
- " }" + newline
-
-let PrintDafnyCodeSkeleton prog methodPrinterFunc genRepr genOld =
- match prog with
- | Program(components) -> components |> List.fold (fun acc comp ->
- match comp with
- | Component(Interface(name,typeParams,members), DataModel(_,_,cVars,frame,inv), code) as comp ->
- let aVars = FilterFieldMembers members
- let aOldVars = MakeOldVars aVars
- let cOldVars = MakeOldVars cVars
- let allInvs = GetInvariantsAsList comp |> DesugarLst
- let allOldInvs = MakeOld (allInvs |> List.fold BinaryAnd TrueLiteral) |> SplitIntoConjunts
- let aVarsAndRepr = aVars |> List.append (Utils.Ite genRepr [Var("Repr", Some(SetType(NamedType("object", []))), false)] [])
- let compMethods = FilterConstructorMembers members
- // Now print it as a Dafny program
- acc +
- (sprintf "class %s%s {" name (PrintTypeParams typeParams)) + newline +
- // the fields: original abstract fields plus concrete fields
- (sprintf "%s" (PrintFields aVarsAndRepr 2 true)) + newline +
- (sprintf "%s" (PrintFields cVars 2 false)) + newline +
- (if genOld then
- (sprintf "%s" (PrintFields aOldVars 2 true)) + newline +
- (sprintf "%s" (PrintFields cOldVars 2 false)) + newline
- else
- "") +
- // generate the Valid function
- (sprintf "%s" (PrintValidFunctionCode comp prog (aVars @ cVars) allInvs genRepr "")) + newline +
- (if genOld then
- (sprintf "%s" (PrintValidFunctionCode comp prog (aOldVars @ cOldVars) allOldInvs genRepr "_old")) + newline
- else
- "") +
- // call the method printer function on all methods of this component
- (methodPrinterFunc comp) +
- // the end of the class
- "}" + newline + newline
- | _ -> assert false; "") ""
-
-let PrintPrePost pfix expr =
- SplitIntoConjunts expr |> PrintSep "" (fun e -> pfix + (PrintExpr 0 e) + ";")
-
-let GetPreconditionForMethod m =
- let validExpr = IdLiteral(validFuncName);
- if IsConstructor m then
- GetMethodPrePost m |> fst
- else
- BinaryAnd validExpr (GetMethodPrePost m |> fst)
-
-let GetPostconditionForMethod prog m genRepr =
- let validExpr = IdLiteral(validFuncName);
- match m with
- | Method(_,_,_,post,isConstr) ->
- // this.Valid() and user-defined post-condition
- let postExpr = BinaryAnd validExpr post
- // method out args are valid
- let postExpr = (GetMethodOutArgs m) |> List.fold (fun acc var ->
- if IsUserType prog (GetVarType var) then
- let varExpr = VarLiteral(GetExtVarName var)
- let argValidExpr = BinaryImplies (BinaryNeq varExpr NullLiteral) (Dot(varExpr, validFuncName))
- BinaryAnd acc argValidExpr
- else
- acc
- ) postExpr
- // fresh Repr
- if genRepr then
- let freshExpr = if isConstr then "fresh(Repr - {this})" else "fresh(Repr - old(Repr))";
- BinaryAnd (IdLiteral(freshExpr)) postExpr
- else
- postExpr
- | _ -> failwithf "expected a method, got %O" m
-
-let PrintAssumePostcondition prog m genRepr prefix =
- PrintPrePost prefix (GetPostconditionForMethod prog m genRepr |> Desugar) + newline
-
-let GetAllocObjects heapInst =
- heapInst.assignments |> List.fold (fun acc a ->
- match a with
- | FieldAssignment((obj,fld),_) when not (obj.name = "this") ->
- acc |> Set.add obj
- | FieldAssignment(_, ObjLiteral(name)) when not (name = "this" || name = "null") ->
- acc |> Set.add (heapInst.objs |> Map.find name)
- | _ -> acc
- ) Set.empty
-
-let PrintAllocNewObjects heapInst indent =
- let idt = Indent indent
- GetAllocObjects heapInst |> Set.fold (fun acc obj -> acc + (sprintf "%svar %s := new %s;%s" idt obj.name (PrintType obj.objType) newline)) ""
-
-let PrintVarAssignments heapInst indent =
- let idt = Indent indent
- let stmts = ConvertToStatements heapInst true
- let str = stmts |> PrintSep (newline) (fun s -> (PrintStmt s indent false))
- str + newline
-
-///
-let PrintReprAssignments prog heapInst indent =
- let __FollowsFunc o1 o2 =
- heapInst.assignments |> List.fold (fun acc assgn ->
- match assgn with
- | FieldAssignment ((srcObj,fld),value) -> acc || (srcObj = o1 && value = ObjLiteral(o2.name))
- | _ -> false
- ) false
- let idt = Indent indent
- let objs = heapInst.assignments |> List.fold (fun acc assgn ->
- match assgn with
- | FieldAssignment((obj,var),_) -> if GetVarName var = "" then acc else acc |> Set.add obj
- | _ -> acc
- ) Set.empty
- |> Set.toList
- |> Utils.TopSort __FollowsFunc
- |> List.rev
- let rec __GetReprConcrete obj =
- let expr = SetExpr([ObjLiteral(obj.name)])
- let builder = CascadingBuilder<_>(expr)
- builder {
- let typeName = GetTypeShortName obj.objType
- let! comp = FindComponent prog typeName
- let vars = GetFrameFields comp
- let nonNullVars = vars |> List.choose (fun v ->
- let lst = heapInst.assignments |> List.choose (function FieldAssignment(x,y) -> Some(x,y) | _ -> None)
- match Utils.ListMapTryFind (obj,v) lst with
- | Some(ObjLiteral(n)) when not (n = "null" || n = obj.name) -> Some(v,n)
- | _ -> None)
- return nonNullVars |> List.map (fun (var,objName) -> var,(Map.find objName heapInst.objs))
- |> List.fold (fun acc (var,varValObj) ->
- if Options.CONFIG.genMod then
- BinaryAdd acc (Dot(Dot(ObjLiteral(obj.name), (GetVarName var)), "Repr"))
- else
- BinaryAdd acc (__GetReprConcrete varValObj)
- ) expr
- }
-
- let reprGetsList = objs |> List.fold (fun acc obj ->
- let objStmt = BinaryGets (Dot(ObjLiteral(obj.name), "Repr")) (__GetReprConcrete obj)
- objStmt :: acc
-// let expr = SetExpr([ObjLiteral(obj.name)])
-// let builder = CascadingBuilder<_>(expr)
-// let fullRhs = builder {
-// let typeName = GetTypeShortName obj.objType
-// let! comp = FindComponent prog typeName
-// let vars = GetFrameFields comp
-// let nonNullVars = vars |> List.filter (fun v ->
-// let lst = heapInst.assignments |> List.choose (function FieldAssignment(x,y) -> Some(x,y) | _ -> None)
-// match Utils.ListMapTryFind (obj,v) lst with
-// | Some(ObjLiteral(n)) when not (n = "null") -> true
-// | _ -> false)
-// return nonNullVars |> List.fold (fun a v ->
-// BinaryAdd a (Dot(Dot(ObjLiteral(obj.name), (GetVarName v)), "Repr"))
-// ) expr
-// }
-// let fullReprExpr = BinaryGets (Dot(ObjLiteral(obj.name), "Repr")) fullRhs
-// fullReprExpr :: acc
- ) []
-
- let reprStr = if not (reprGetsList = []) then
- idt + "// repr stuff" + newline +
- (PrintStmtList reprGetsList indent true)
- else
- ""
-
- let reprValidExpr = GetAllocObjects heapInst |> Set.fold (fun acc obj -> BinaryAnd acc (Dot(ObjLiteral(obj.name), validFuncName))) TrueLiteral
-
- let assertValidStr = if not (reprValidExpr = TrueLiteral) then
- idt + "// assert repr objects are valid (helps verification)" + newline +
- (PrintStmt (ExprStmt(AssertExpr(reprValidExpr))) indent true)
- else
- ""
- let outStr = reprStr + assertValidStr
- if outStr = "" then
- outStr
- else
- newline + outStr
-
-let rec PrintHeapCreationCodeOld prog (comp,meth) sol indent genRepr =
- let rec __RewriteOldStmt stmt =
- match stmt with
- | Assign(l, r) -> Assign(l, BringToPost r)
- | ExprStmt(e) -> ExprStmt(BringToPost e)
- | Block(slist) -> Block(slist |> List.map __RewriteOldStmt)
-
- let __RewriteOldAsgn a =
- match a with
- | FieldAssignment((o,f),e) -> FieldAssignment((o,f), BringToPost e)
- | ArbitraryStatement(stmt) -> ArbitraryStatement(__RewriteOldStmt stmt)
-
- /// inserts an assignments into a list of assignments such that the list remains
- /// topologically sorted wrt field dependencies between different assignments
- let rec __InsertSorted asgsLst asg =
- let ___DependsOn dependentAsg asg =
- match asg, dependentAsg with
- | FieldAssignment((o,f),_), FieldAssignment(_,e) ->
- let mf = fun e acc ->
- match e with
- | IdLiteral(name) when name = GetVarName f && o.name = "this" -> true
- | Dot(discr, name) ->
- let t1 = InferType prog comp (fun s -> None) discr
- let t2 = FindComponentForType prog o.objType
- acc || (name = GetVarName f && t1 = t2)
- | _ -> acc
- DescendExpr2 (mf
- ) e false
- | _ -> false
- match asgsLst with
- | [] -> [asg]
- | a :: rest -> if ___DependsOn a asg then asg :: a :: rest else a :: __InsertSorted rest asg
-
- /// - removes all FieldAssignments to unmodifiable objects and old variables
- /// - rewrites expressions not to use old fields
- let __RemoveUnmodifiableStuff heapInst =
- let newAsgs = heapInst.assignments |> List.fold (fun acc a ->
- match a with
- | FieldAssignment((obj,_),_) when not (Set.contains obj heapInst.modifiableObjs) -> acc
- | FieldAssignment((_,var),_) when IsOldVar var -> acc
- | _ -> __InsertSorted acc (__RewriteOldAsgn a)
- ) []
- { heapInst with assignments = newAsgs }
-
- let idt = Indent indent
- match sol with
- | (c, hi) :: rest ->
- let heapInstMod = __RemoveUnmodifiableStuff hi
- let __ReprAssignments ind =
- if genRepr then
- (PrintReprAssignments prog heapInstMod ind)
- else
- ""
- if c = TrueLiteral then
- (PrintAllocNewObjects heapInstMod indent) +
- (PrintVarAssignments heapInstMod indent) +
- (__ReprAssignments indent) +
- (PrintHeapCreationCodeOld prog (comp,meth) rest indent genRepr)
- else
- if List.length rest > 0 then
- idt + "if (" + (PrintExpr 0 c) + ") {" + newline +
- (PrintAllocNewObjects heapInstMod (indent+2)) +
- (PrintVarAssignments heapInstMod (indent+2)) +
- (__ReprAssignments (indent+2)) +
- idt + "} else {" + newline +
- (PrintHeapCreationCodeOld prog (comp,meth) rest (indent+2) genRepr) +
- idt + "}" + newline
- else
- (PrintAllocNewObjects heapInstMod indent) +
- (PrintVarAssignments heapInstMod indent) +
- (__ReprAssignments indent)
- | [] -> ""
-
-let PrintHeapCreationCode prog (comp,meth) sol indent genRepr =
- let idt = Indent indent
- let ghostPre = GetMethodGhostPrecondition meth
- if ghostPre = TrueLiteral then
- PrintHeapCreationCodeOld prog (comp,meth) sol indent genRepr
- else
- (ghostPre |> SplitIntoConjunts |> PrintSep newline (fun e -> idt + "assume " + (PrintExpr 0 e) + ";")) + newline +
- (PrintHeapCreationCodeOld prog (comp,meth) sol indent genRepr)
-
-let GenConstructorCode prog comp mthd decreasesClause body genRepr =
- let validExpr = IdLiteral(validFuncName);
- match mthd with
- | Method(methodName,sign,_,_,isConstr) ->
- let preExpr = GetPreconditionForMethod mthd |> Desugar
- let postExpr = GetPostconditionForMethod prog mthd genRepr |> Desugar
- let thisObj = ThisObj comp
- " method " + methodName + (PrintSig sign) +
- (if IsModifiableObj thisObj (comp,mthd) then newline + " modifies this;" else "") +
- (PrintPrePost (newline + " requires ") preExpr) +
- (PrintPrePost (newline + " ensures ") postExpr) +
- newline +
- decreasesClause +
- " {" + newline +
- body +
- " }" + newline
- | _ -> ""
-
-let GetDecreasesClause (c,m) sol =
- if IsRecursiveSol (c,m) sol then
- " decreases Repr;" + newline
- else
- ""
-
-// solutions: (comp, constructor) |--> condition * heapInst
-let PrintImplCode prog solutions genRepr =
- PrintDafnyCodeSkeleton prog (fun comp ->
- let cname = GetComponentName comp
- solutions |> Map.fold (fun acc (c,m) sol ->
- if (GetComponentName c) = cname then
- let mthdBody,decr =
- match sol with
- | [] ->
- let body = " //unable to synthesize" +
- (PrintAssumePostcondition prog m genRepr (newline + " assume "))
- let decr = ""
- body,decr
- | _ ->
- let body = PrintHeapCreationCode prog (c,m) sol 4 genRepr
- let decr = GetDecreasesClause (c,m) sol
- body,decr
- acc + newline + (GenConstructorCode prog comp m decr mthdBody genRepr) + newline
-
- else
- acc) "") genRepr \ No newline at end of file
diff --git a/Jennisys/Jennisys/DafnyModelUtils.fs b/Jennisys/Jennisys/DafnyModelUtils.fs
deleted file mode 100644
index e734f3bb..00000000
--- a/Jennisys/Jennisys/DafnyModelUtils.fs
+++ /dev/null
@@ -1,455 +0,0 @@
-// #########################################################################
-/// Utilities for reading/building models from Boogie Visual Debugger files
-///
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// #########################################################################
-
-module DafnyModelUtils
-
-(*
- The heap maps objects and fields to locations.
- heap: Const * VarDecl option |--> Const
-
- The environment maps locations to values (except that it can also
- be locations to locations, because not all values are explicitly
- present in the model.
- envMap: Const |--> Const
-
- The context is just a list of equality constraints collected on the way
- ctx: Set<Set<Const>>, where the inner set contains exactly two constants
-*)
-
-open Ast
-open Getters
-open AstUtils
-open Utils
-
-open Microsoft.Boogie
-
-let HEAP_SELECT_FNAME = "MapType1Select"
-let SEQ_BUILD_FNAME = "Seq#Build"
-let SEQ_APPEND_FNAME = "Seq#Append"
-let SEQ_LENGTH_FNAME = "Seq#Length"
-let SEQ_INDEX_FNAME = "Seq#Index"
-let SET_EMPTY_FNAME = "Set#Empty"
-let SET_SELECT_FNAME = "MapType0Select"
-let UNBOX_FNAME = "$Unbox"
-let BOOL_2_U_FNAME = "bool_2_U"
-let U_2_BOOL_FNAME = "U_2_bool"
-let INT_2_U_FNAME = "int_2_U"
-let U_2_INT_FNAME = "U_2_int"
-let DTYPE_FNAME = "dtype"
-let NULL_FNAME = "null"
-
-type HeapModel = {
- heap : Map<Const * VarDecl, Const>;
- env : Map<Const, Const>;
- ctx : Set<Set<Const>>;
-}
-
-let MkHeapModel heap env ctx =
- { heap = heap; env = env; ctx = ctx }
-
-let GetElemFullName (elem: Model.Element) =
- elem.Names |> Seq.filter (fun ft -> ft.Func.Arity = 0)
- |> Seq.choose (fun ft -> Some(ft.Func.Name))
- |> Utils.SeqToOption
-
-let GetRefName (ref: Model.Element) =
- match ref with
- | :? Model.Uninterpreted as uref -> uref.Name
- | _ -> failwith ("not a ref (Uninterpreted) but: " + ref.GetType().Name)
-
-let GetInt (elem: Model.Element) =
- let __NotIntFail e = failwith ("not an int element: " + elem.ToString())
- let rec __GetIntStrict (e: Model.Element) cont =
- match e with
- | :? Model.Number as ival -> ival.AsInt()
- | _ -> cont e
- __GetIntStrict elem (fun e ->
- let f = e.Model.MkFunc(U_2_INT_FNAME, 1)
- let matches = f.Apps |> Seq.filter (fun ft -> ft.Args.[0] = e) |> Seq.map (fun ft -> ft.Result)
- if matches |> Seq.isEmpty then
- __NotIntFail e
- else
- __GetIntStrict (matches |> Seq.nth 0) __NotIntFail)
-
-let GetBool (elem: Model.Element) =
- let __NotBoolFail e = failwith ("not a bool element: " + elem.ToString())
- let rec __GetBoolStrict (e: Model.Element) cont =
- match e with
- | :? Model.Boolean as bval -> bval.Value
- | _ -> cont e
- __GetBoolStrict elem (fun e ->
- let f = e.Model.MkFunc(U_2_BOOL_FNAME, 1)
- let matches = f.Apps |> Seq.filter (fun ft -> ft.Args.[0] = e) |> Seq.map (fun ft -> ft.Result)
- if matches |> Seq.isEmpty then
- __NotBoolFail e
- else
- __GetBoolStrict (matches |> Seq.nth 0) __NotBoolFail)
-
-let ConvertValue (refVal: Model.Element) =
- match refVal with
- | :? Model.Number as ival -> IntConst(ival.AsInt())
- | :? Model.Boolean as bval -> BoolConst(bval.Value)
- | :? Model.Array as aval -> failwith "reading array values from model not implemented"
- | :? Model.Uninterpreted as uval ->
- try BoolConst(GetBool refVal)
- with _ -> try IntConst(GetInt refVal)
- with _ -> Unresolved(uval.Name) (* just a symbolic name for now, which we'll hopefully resolve later*)
- | _ -> failwith ("unexpected model element kind: " + refVal.ToString())
-
-let LastDotSplit (str: string) =
- let dotIdx = str.LastIndexOf(".")
- let s1 = if dotIdx = -1 then "" else str.Substring(0, dotIdx)
- let s2 = str.Substring(dotIdx + 1)
- s1,s2
-
-let GetType (e: Model.Element) prog =
- let fNameOpt = GetElemFullName e
- match fNameOpt with
- | Some(fname) -> match fname with
- | "intType" -> Some(IntType)
- | Prefix "class." clsName ->
- let _,shortClsName = LastDotSplit clsName
- match FindComponent prog shortClsName with
- | Some(comp) -> Some(GetClassType comp)
- | None -> None
- | _ -> None
- | None -> None
-
-let GetLoc (e: Model.Element) =
- Unresolved(GetRefName e)
-
-let FindOrCreateSeq env key len =
- match Map.tryFind key env with
- | Some(SeqConst(lst)) -> lst,env
- | None ->
- let emptyList = Utils.GenList len NoneConst
- let newSeq = SeqConst(emptyList)
- let newMap = env |> Map.add key newSeq
- emptyList,newMap
- | Some(_) as x-> failwith ("not a SeqConst but: " + x.ToString())
-
-let FindSeqInEnv env key =
- match Map.find key env with
- | SeqConst(lst) -> lst
- | _ as x-> failwith ("not a SeqConst but: " + x.ToString())
-
-let TryFindSetInEnv env key =
- match Map.tryFind key env with
- | Some(SetConst(s)) -> Some(s)
- | Some(x) -> failwith ("not a SetConst but: " + x.ToString())
- | None -> None
-
-let AddConstr c1 c2 ctx =
- if c1 = c2 then
- ctx
- else
- match c1, c2 with
- | Unresolved(_), _ | _, Unresolved(_) ->
- // find partitions
- let s1Opt = ctx |> Set.filter (fun ss -> Set.contains c1 ss) |> Utils.SetToOption
- let s2Opt = ctx |> Set.filter (fun ss -> Set.contains c2 ss) |> Utils.SetToOption
- match s1Opt, s2Opt with
- // both already exist --> so just merge them
- | Some(s1), Some(s2) -> ctx |> Set.remove s1 |> Set.remove s2 |> Set.add (Set.union s1 s2)
- // exactly one already exists --> add to existing
- | Some(s1), None -> ctx |> Set.remove s1 |> Set.add (Set.add c2 s1)
- | None, Some(s2) -> ctx |> Set.remove s2 |> Set.add (Set.add c1 s2)
- // neither exists --> create a new one
- | None, None -> ctx |> Set.add (Set.ofList [c1; c2])
- | _ -> failwith ("trying to add an equality constraint between two constants: " + c1.ToString() + ", and " + c2.ToString())
-
-let rec UpdateContext lst1 lst2 ctx =
- match lst1, lst2 with
- | fs1 :: rest1, fs2 :: rest2 ->
- match fs1, fs2 with
- | NoneConst,_ | _,NoneConst -> UpdateContext rest1 rest2 ctx
- | _ -> UpdateContext rest1 rest2 (AddConstr fs1 fs2 ctx)
- | [], [] -> ctx
- | _ -> failwith "lists are not of the same length"
-
-let UnboxIfNeeded (model: Microsoft.Boogie.Model) (e: Model.Element) =
- let f_unbox = model.MkFunc(UNBOX_FNAME, 2)
- let unboxed = f_unbox.Apps |> Seq.filter (fun ft -> if (GetLoc ft.Args.[1]) = (GetLoc e) then true else false)
- |> Seq.choose (fun ft -> Some(ft.Result))
- |> Utils.SeqToOption
- match unboxed with
- | Some(e) -> ConvertValue e
- | None -> GetLoc e
-
-let ReadHeap (model: Microsoft.Boogie.Model) prog =
- let f_heap_select = model.MkFunc(HEAP_SELECT_FNAME, 3)
- let values = f_heap_select.Apps
- values |> Seq.fold (fun acc ft ->
- assert (ft.Args.Length = 3)
- let ref = ft.Args.[1]
- let fld = ft.Args.[2]
- assert (Seq.length fld.Names = 1)
- let fldFullName = (Seq.nth 0 fld.Names).Func.Name
- let pfix,fldName = LastDotSplit fldFullName
- let _,clsName = LastDotSplit pfix
- let refVal = ft.Result
- let refObj = Unresolved(GetRefName ref)
- let nonebuilder = CascadingBuilder<_>(None)
- let fldVarOpt = nonebuilder {
- let! comp = FindComponent prog clsName
- if fldName.StartsWith("old_") then
- let fn = RenameFromOld fldName
- let! var = FindVar comp fn
- return Some(MakeOldVar var)
- else
- return FindVar comp fldName
- }
- match fldVarOpt with
- | Some(fldVar) ->
- let fldType = GetVarType fldVar
- let fldVal = ConvertValue refVal
- acc |> Map.add (refObj, fldVar) fldVal
- | None -> acc
- ) Map.empty
-
-// ====================================================================
-/// Reads values that were assigned to given arguments. Those values
-/// can be in functions with the same name as the argument name appended
-/// with an "#" and some number after it.
-// ====================================================================
-let rec ReadArgValues (model: Microsoft.Boogie.Model) args =
- match args with
- | v :: rest ->
- let name = GetVarName v
- let farg = model.Functions |> Seq.filter (fun f -> f.Arity = 0 && f.Name.StartsWith(name + "#")) |> Utils.SeqToOption
- match farg with
- | Some(func) ->
- let fldVar = v
- assert (Seq.length func.Apps = 1)
- let ft = Seq.head func.Apps
- let fldVal = ConvertValue (ft.Result)
- ReadArgValues model rest |> Map.add (VarConst(name)) fldVal
- | None -> failwith ("cannot find corresponding function for parameter " + name)
- | [] -> Map.empty
-
-// ==============================================================
-/// Reads stuff about sequences from a given model and ads it to
-/// the given "envMap" map and a "ctx" set. The relevant stuff is
-/// fetched from the following functions:
-/// Seq#Length, Seq#Index, Seq#Build, Seq#Append
-// ==============================================================
-let ReadSeq (model: Microsoft.Boogie.Model) (envMap,ctx) =
- // reads stuff from Seq#Length
- let rec __ReadSeqLen (model: Microsoft.Boogie.Model) (len_tuples: Model.FuncTuple list) (envMap,ctx) =
- match len_tuples with
- | ft :: rest ->
- let len = GetInt ft.Result
- let emptyList = Utils.GenList len NoneConst
- let newMap = envMap |> Map.add (GetLoc ft.Args.[0]) (SeqConst(emptyList))
- __ReadSeqLen model rest (newMap,ctx)
- | _ -> (envMap,ctx)
-
- // reads stuff from Seq#Index
- let rec __ReadSeqIndex (model: Microsoft.Boogie.Model) (idx_tuples: Model.FuncTuple list) (envMap,ctx) =
- match idx_tuples with
- | ft :: rest ->
- let srcLstKey = GetLoc ft.Args.[0]
- let idx = GetInt ft.Args.[1]
- let oldLst,envMap = FindOrCreateSeq envMap srcLstKey (idx+1)
- let lstElem = UnboxIfNeeded model ft.Result
- let newLst = Utils.ListSet idx lstElem oldLst
- let newCtx = UpdateContext oldLst newLst ctx
- let newEnv = envMap |> Map.add srcLstKey (SeqConst(newLst))
- __ReadSeqIndex model rest (newEnv,newCtx)
- | _ -> (envMap,ctx)
-
- // reads stuff from Seq#Build
- let rec __ReadSeqBuild (model: Microsoft.Boogie.Model) (bld_tuples: Model.FuncTuple list) (envMap,ctx) =
- match bld_tuples with
- | ft :: rest ->
- let srcLstLoc = GetLoc ft.Args.[0]
- let lstElemVal = UnboxIfNeeded model ft.Args.[1]
- let dstLstLoc = GetLoc ft.Result
- let oldLst = FindSeqInEnv envMap srcLstLoc
- let dstLst = FindSeqInEnv envMap dstLstLoc
- let newLst = oldLst @ [lstElemVal]
- let newCtx = UpdateContext dstLst newLst ctx
- let newEnv = envMap |> Map.add dstLstLoc (SeqConst(newLst))
- __ReadSeqBuild model rest (newEnv,newCtx)
- | _ -> (envMap,ctx)
-
- // reads stuff from Seq#Append
- let rec __ReadSeqAppend (model: Microsoft.Boogie.Model) (app_tuples: Model.FuncTuple list) (envMap,ctx) =
- match app_tuples with
- | ft :: rest ->
- let srcLst1Loc = GetLoc ft.Args.[0]
- let srcLst2Loc = GetLoc ft.Args.[1]
- let dstLstLoc = GetLoc ft.Result
- let oldLst1 = FindSeqInEnv envMap srcLst1Loc
- let oldLst2 = FindSeqInEnv envMap srcLst2Loc
- let dstLst = FindSeqInEnv envMap dstLstLoc
- let newLst = oldLst1 @ oldLst2
- let newCtx = UpdateContext dstLst newLst ctx
- let newEnv = envMap |> Map.add dstLstLoc (SeqConst(newLst))
- __ReadSeqAppend model rest (newEnv,newCtx)
- | _ -> (envMap,ctx)
-
- // keeps reading from Seq#Build and Seq#Append until fixpoint
- let rec __ReadUntilFixpoint hmodel =
- let f_seq_bld = model.MkFunc(SEQ_BUILD_FNAME, 2)
- let f_seq_app = model.MkFunc(SEQ_APPEND_FNAME, 2)
- let hmodel' = hmodel |> __ReadSeqBuild model (List.ofSeq f_seq_bld.Apps)
- |> __ReadSeqAppend model (List.ofSeq f_seq_app.Apps)
- if hmodel' = hmodel then
- hmodel'
- else
- __ReadUntilFixpoint hmodel'
-
- let f_seq_len = model.MkFunc(SEQ_LENGTH_FNAME, 1)
- let f_seq_idx = model.MkFunc(SEQ_INDEX_FNAME, 2)
- let hmodel = (envMap,ctx)
- let hmodel' = hmodel |> __ReadSeqLen model (List.ofSeq f_seq_len.Apps)
- |> __ReadSeqIndex model (List.ofSeq f_seq_idx.Apps)
- __ReadUntilFixpoint hmodel'
-
-
-
-// =====================================================
-/// Reads stuff about sets from a given model and adds it
-/// to the given "envMap" map and "ctx" set.
-// =====================================================
-let ReadSet (model: Microsoft.Boogie.Model) (envMap,ctx) =
- // reads stuff from Set#Empty
- let rec __ReadSetEmpty (empty_tuples: Model.FuncTuple list) (envMap,ctx) =
- match empty_tuples with
- | ft :: rest ->
- let newMap = envMap |> Map.add (GetLoc ft.Result) (SetConst(Set.empty))
- __ReadSetEmpty rest (newMap,ctx)
- | [] -> (envMap,ctx)
-
- // reads stuff from [2]
- let rec __ReadSetMembership (set_tuples: Model.FuncTuple list) (env,ctx) =
- match set_tuples with
- | ft :: rest ->
- if GetBool ft.Result then
- let srcSetKey = GetLoc ft.Args.[0]
- let srcSet = match TryFindSetInEnv env srcSetKey with
- | Some(s) -> s
- | None -> Set.empty
- let elem = UnboxIfNeeded model ft.Args.[1]
- let newEnv = env |> Map.add srcSetKey (SetConst(Set.add elem srcSet))
- __ReadSetMembership rest (newEnv,ctx)
- else
- __ReadSetMembership rest (env,ctx)
- | [] -> (env,ctx)
-
- let t_set_empty = Seq.toList (model.MkFunc(SET_EMPTY_FNAME, 1).Apps)
- let t_set = Seq.toList (model.MkFunc(SET_SELECT_FNAME, 2).Apps)
- (envMap,ctx) |> __ReadSetEmpty t_set_empty
- |> __ReadSetMembership t_set
-
-(* More complicated way which now doesn't seem to be necessary *)
-//let ReadSet (model: Microsoft.Boogie.Model) (envMap,ctx) =
-// // reads stuff from Set#Empty
-// let rec __ReadSetEmpty (empty_tuples: Model.FuncTuple list) (envMap,ctx) =
-// match empty_tuples with
-// | ft :: rest ->
-// let newMap = envMap |> Map.add (GetLoc ft.Result) (SetConst(Set.empty))
-// __ReadSetEmpty rest (newMap,ctx)
-// | [] -> (envMap,ctx)
-//
-// // reads stuff from Set#UnionOne and Set#Union
-// let rec __ReadSetUnions (envMap,ctx) =
-// // this one goes through a given list of "UnionOne" tuples, updates
-// // the env for those set that it was able to resolve, and returns a
-// // list of tuples for which it wasn't able to resolve sets
-// let rec ___RSU1 (tuples: Model.FuncTuple list) env unprocessed =
-// match tuples with
-// | ft :: rest ->
-// let srcSetKey = GetLoc ft.Args.[0]
-// match TryFindSetInEnv env srcSetKey with
-// | Some(oldSet) ->
-// let elem = UnboxIfNeeded model ft.Args.[1]
-// let newSet = Set.add elem oldSet
-// // update contex?
-// let newEnv = env |> Map.add (GetLoc ft.Result) (SetConst(newSet))
-// ___RSU1 rest newEnv unprocessed
-// | None -> ___RSU1 rest env (ft :: unprocessed)
-// | [] -> (env,unprocessed)
-// // this one goes through a given list of "Union" tuples, updates
-// // the env for those set that it was able to resolve, and returns a
-// // list of tuples for which it wasn't able to resolve sets
-// let rec ___RSU (tuples: Model.FuncTuple list) env unprocessed =
-// match tuples with
-// | ft :: rest ->
-// let set1Key = GetLoc ft.Args.[0]
-// let set2Key = GetLoc ft.Args.[1]
-// match TryFindSetInEnv env set1Key, TryFindSetInEnv env set2Key with
-// | Some(oldSet1), Some(oldSet2) ->
-// let newSet = Set.union oldSet1 oldSet2
-// // update contex?
-// let newEnv = env |> Map.add (GetLoc ft.Result) (SetConst(newSet))
-// ___RSU rest newEnv unprocessed
-// | _ -> ___RSU rest env (ft :: unprocessed)
-// | [] -> (env,unprocessed)
-// // this one keeps looping as loong as the list of unprocessed tuples
-// // is decreasing, it ends when if falls down to 0, or fails if
-// // the list stops decreasing
-// let rec ___RSU_until_fixpoint u1tuples utuples env =
-// let newEnv1,unprocessed1 = ___RSU1 u1tuples env []
-// let newEnv2,unprocessed2 = ___RSU utuples newEnv1 []
-// let oldLen = (List.length u1tuples) + (List.length utuples)
-// let totalUnprocLen = (List.length unprocessed1) + (List.length unprocessed2)
-// if totalUnprocLen = 0 then
-// newEnv2
-// elif totalUnprocLen < oldLen then
-// ___RSU_until_fixpoint unprocessed1 unprocessed2 newEnv2
-// else
-// failwith "cannot resolve all sets in Set#UnionOne/Set#Union"
-// // finally, just invoke the fixpoint function for UnionOne and Union tuples
-// let t_union_one = Seq.toList (model.MkFunc("Set#UnionOne", 2).Apps)
-// let t_union = Seq.toList (model.MkFunc("Set#Union", 2).Apps)
-// let newEnv = ___RSU_until_fixpoint t_union_one t_union envMap
-// (newEnv,ctx)
-//
-// let f_set_empty = model.MkFunc("Set#Empty", 1)
-// (envMap,ctx) |> __ReadSetEmpty (List.ofSeq f_set_empty.Apps)
-// |> __ReadSetUnions
-
-// ======================================================
-/// Reads staff about the null constant from a given model
-/// and adds it to the given "envMap" map and "ctx" set.
-// ======================================================
-let ReadNull (model: Microsoft.Boogie.Model) (envMap,ctx) =
- let f_null = model.MkFunc(NULL_FNAME, 0)
- assert (f_null.AppCount = 1)
- let e = (f_null.Apps |> Seq.nth 0).Result
- let newEnv = envMap |> Map.add (GetLoc e) NullConst
- (newEnv,ctx)
-
-// ============================================================================================
-/// Reads the evinronment map and the context set.
-///
-/// It starts by reading the model for the "dtype" function to discover all objects on the heap,
-/// and then proceeds by reading stuff about the null constant, about sequences, and about sets.
-// ============================================================================================
-let ReadEnv (model: Microsoft.Boogie.Model) prog =
- let f_dtype = model.MkFunc(DTYPE_FNAME, 1)
- let refs = f_dtype.Apps |> Seq.choose (fun ft -> Some(ft.Args.[0]))
- let envMap = f_dtype.Apps |> Seq.fold (fun acc ft ->
- let locName = GetRefName ft.Args.[0]
- let elemName = GetElemFullName ft.Args.[0]
- let loc = Unresolved(locName)
- let locType = GetType ft.Result prog
- let value = match elemName with
- | Some(n) when n.StartsWith("this") -> ThisConst(locName.Replace("*", ""), locType)
- | _ -> NewObj(locName.Replace("*", ""), locType)
- acc |> Map.add loc value
- ) Map.empty
- (envMap, Set.ofList([])) |> ReadNull model
- |> ReadSeq model
- |> ReadSet model
-
-let ReadFieldValuesFromModel (model: Microsoft.Boogie.Model) prog comp meth =
- let heap = ReadHeap model prog
- let env0,ctx = ReadEnv model prog
- let env = env0 |> Utils.MapAddAll (ReadArgValues model (GetMethodArgs meth))
- MkHeapModel heap env ctx \ No newline at end of file
diff --git a/Jennisys/Jennisys/DafnyPrinter.fs b/Jennisys/Jennisys/DafnyPrinter.fs
deleted file mode 100644
index f2e71e8b..00000000
--- a/Jennisys/Jennisys/DafnyPrinter.fs
+++ /dev/null
@@ -1,135 +0,0 @@
-module DafnyPrinter
-
-open Ast
-open Getters
-open AstUtils
-open PrintUtils
-
-let rec PrintType ty =
- match ty with
- | IntType -> "int"
- | BoolType -> "bool"
- | SeqType(t) -> sprintf "seq<%s>" (PrintType t)
- | SetType(t) -> sprintf "set<%s>" (PrintType t)
- | NamedType(id,args) -> if List.isEmpty args then id else sprintf "%s<%s>" id (PrintSep ", " (fun s -> s) args)
- | InstantiatedType(id,args) -> if List.isEmpty args then id else sprintf "%s<%s>" id (PrintSep ", " (fun t -> PrintType t) args)
-
-let PrintVarDecl vd =
- let name = GetExtVarName vd
- match GetVarType vd with
- | None -> name
- | Some(ty) -> sprintf "%s: %s" name (PrintType ty)
-
-let rec PrintExpr ctx expr =
- match expr with
- | IntLiteral(d) -> sprintf "%d" d
- | BoolLiteral(b) -> sprintf "%b" b
- | BoxLiteral(id) -> sprintf "box_%s" id
- | ObjLiteral(id)
- | VarLiteral(id)
- | IdLiteral(id) -> id
- | VarDeclExpr(vlist, declare) ->
- let decl = if declare then "var " else ""
- let vars = PrintSep ", " PrintVarDecl vlist
- sprintf "%s%s" decl vars
- | Star -> "*"
- | Dot(e,id) -> sprintf "%s.%s" (PrintExpr 100 e) id
- | LCIntervalExpr(e) -> sprintf "%s.." (PrintExpr 90 e)
- | OldExpr(e) -> sprintf "old(%s)" (PrintExpr 90 e)
- | UnaryExpr(op,UnaryExpr(op2, e2)) -> sprintf "%s(%s)" op (PrintExpr 90 (UnaryExpr(op2, e2)))
- | UnaryExpr(op,e) -> sprintf "%s%s" op (PrintExpr 90 e)
- | BinaryExpr(strength,"in",lhs,BinaryExpr(_,"...",lo,hi)) ->
- let needParens = strength <= ctx
- let openParen = if needParens then "(" else ""
- let closeParen = if needParens then ")" else ""
- let loStr = PrintExpr strength lo
- let hiStr = PrintExpr strength hi
- let lhsStr = PrintExpr strength lhs
- sprintf "%s%s <= %s && %s <= %s%s" openParen loStr lhsStr lhsStr hiStr closeParen
- | BinaryExpr(strength,op,e0,e1) ->
- let op =
- match op with
- | "=" -> "=="
- | "div" -> "/"
- | "mod" -> "%"
- | _ -> op
- let needParens = strength <= ctx
- let openParen = if needParens then "(" else ""
- let closeParen = if needParens then ")" else ""
- sprintf "%s%s %s %s%s" openParen (PrintExpr strength e0) op (PrintExpr strength e1) closeParen
- | IteExpr(c,e1,e2) -> sprintf "(if %s then %s else %s)" (PrintExpr 25 c) (PrintExpr 25 e1) (PrintExpr 25 e2)
- | SelectExpr(e,i) -> sprintf "%s[%s]" (PrintExpr 100 e) (PrintExpr 0 i)
- | UpdateExpr(e,i,v) -> sprintf "%s[%s := %s]" (PrintExpr 100 e) (PrintExpr 0 i) (PrintExpr 0 v)
- | SequenceExpr(ee) -> sprintf "[%s]" (ee |> PrintSep ", " (PrintExpr 0))
- | SeqLength(e) -> sprintf "|%s|" (PrintExpr 0 e)
- | SetExpr(ee) -> sprintf "{%s}" (ee |> PrintSep ", " (PrintExpr 0))
- | AssertExpr(e) -> sprintf "assert %s" (PrintExpr 0 e)
- | AssumeExpr(e) -> sprintf "assume %s" (PrintExpr 0 e)
- | ForallExpr(vv,e) ->
- let needParens = true
- let openParen = if needParens then "(" else ""
- let closeParen = if needParens then ")" else ""
- sprintf "%sforall %s :: %s%s" openParen (vv |> PrintSep ", " PrintVarDecl) (PrintExpr 0 e) closeParen
- | MethodCall(rcv,_,name,aparams) ->
- sprintf "%s.%s(%s)" (PrintExpr 0 rcv) name (aparams |> PrintSep ", " (PrintExpr 0))
- | MethodOutSelect(mth,name) ->
- // TODO: this can only work if there is only 1 out parameter
- sprintf "%s" (PrintExpr 0 mth)
-
-let rec PrintConst cst =
- match cst with
- | IntConst(v) -> sprintf "%d" v
- | BoolConst(b) -> sprintf "%b" b
- | BoxConst(id) -> sprintf "box_%s" id
- | VarConst(v) -> sprintf "%s" v
- | SetConst(cset) -> sprintf "{%s}" (PrintSep ", " (fun c -> PrintConst c) (Set.toList cset))
- | SeqConst(cseq) -> sprintf "[%s]" (PrintSep ", " (fun c -> PrintConst c) cseq)
- | NullConst -> "null"
- | NoneConst -> "<none>"
- | ThisConst(_,_) -> "this"
- | NewObj(name,_) -> PrintGenSym name
- | Unresolved(name) -> sprintf "Unresolved(%s)" name
-
-let PrintSig signature =
- match signature with
- | Sig(ins, outs) ->
- let returnClause =
- if outs <> [] then sprintf " returns (%s)" (outs |> PrintSep ", " PrintVarDecl)
- else ""
- sprintf "(%s)%s" (ins |> PrintSep ", " PrintVarDecl) returnClause
-
-let PrintTypeParams typeParams =
- match typeParams with
- | [] -> ""
- | _ -> sprintf "<%s>" (typeParams |> PrintSep ", " (fun tp -> tp))
-
-let PrintFields vars indent ghost =
- let ghostStr = if ghost then "ghost " else ""
- vars |> List.fold (fun acc v -> match GetVarType v with
- | None -> acc + (sprintf "%s%svar %s;%s" (Indent indent) ghostStr (GetExtVarName v) newline)
- | Some(tp) -> acc + (sprintf "%s%svar %s: %s;%s" (Indent indent) ghostStr (GetExtVarName v) (PrintType tp) newline)) ""
-
-let rec _PrintStmt stmt indent printNewline =
- let idt = Indent indent
- let nl = if printNewline then newline else ""
- match stmt with
- | Block(stmts) ->
- idt + "{" + nl +
- (_PrintStmtList stmts (indent + 2) true) +
- idt + "}" + nl
- | Assign(lhs,rhs) -> sprintf "%s%s := %s;%s" idt (PrintExpr 0 lhs) (PrintExpr 0 rhs) nl
- | ExprStmt(expr) -> sprintf "%s%s;%s" idt (PrintExpr 0 expr) nl
-and _PrintStmtList stmts indent printNewLine =
- let idt = Indent indent
- let str = stmts |> PrintSep newline (fun s -> _PrintStmt s indent false)
- if printNewLine then
- str + newline
- else
- str
-
-let PrintStmt stmt indent printNewline =
- let stmts = PullUpMethodCalls stmt
- _PrintStmtList stmts indent printNewline
-
-let PrintStmtList stmts indent printNewLine =
- stmts |> List.fold (fun acc s -> acc + (PrintStmt s indent printNewLine)) "" \ No newline at end of file
diff --git a/Jennisys/Jennisys/EnvUtils.fs b/Jennisys/Jennisys/EnvUtils.fs
deleted file mode 100644
index 0b840311..00000000
--- a/Jennisys/Jennisys/EnvUtils.fs
+++ /dev/null
@@ -1,9 +0,0 @@
-module EnvUtils
-
-open Ast
-
-let GetThisLoc env =
- Map.findKey (fun k v ->
- match v with
- | ThisConst(_) -> true
- | _ -> false) env \ No newline at end of file
diff --git a/Jennisys/Jennisys/FixpointSolver.fs b/Jennisys/Jennisys/FixpointSolver.fs
deleted file mode 100644
index 1ca3b057..00000000
--- a/Jennisys/Jennisys/FixpointSolver.fs
+++ /dev/null
@@ -1,374 +0,0 @@
-module FixpointSolver
-
-open Ast
-open AstUtils
-open Printer
-open Resolver
-open Utils
-
-/////////////
-
-type UnifDirection = LTR | RTL
-
-exception CannotUnify
-
-let rec SelectiveUnifyImplies okToUnifyFunc lhs rhs dir unifs =
- ///
- let __AddOrNone unifs name e =
- if okToUnifyFunc name then
- Some(unifs |> Utils.MapAddNew name e)
- else
- None
-
- ///
- let __UnifLists lstL lstR =
- if List.length lstL = List.length lstR then
- try
- let unifs2 = List.fold2 (fun acc elL elR -> match SelectiveUnifyImplies okToUnifyFunc elL elR dir acc with
- | Some(u) -> u
- | None -> raise CannotUnify) unifs lstL lstR
- Some(unifs2)
- with
- | CannotUnify -> None
- else
- None
-
- ///
- let __ApplyUnifs unifs exprList =
- exprList |> List.fold (fun acc e ->
- let e' = e |> Rewrite (fun e ->
- match e with
- | VarLiteral(id) when Map.containsKey id unifs -> Some(unifs |> Map.find id)
- | _ -> None)
- acc |> Set.add e'
- ) Set.empty
-
- if lhs = FalseLiteral || rhs = TrueLiteral then
- Some(unifs)
- else
- try
- let l,r = match dir with
- | LTR -> lhs,rhs
- | RTL -> rhs,lhs
- match l, r with
- | VarLiteral(vname), rhs -> __AddOrNone unifs vname rhs
- | IntLiteral(nL), IntLiteral(nR) when nL = nR ->
- Some(unifs)
- | BoolLiteral(bL), BoolLiteral(bR) when bL = bR ->
- Some(unifs)
- | SetExpr(elistL), SetExpr(elistR) ->
- let s1 = elistL |> __ApplyUnifs unifs
- let s2 = elistR |> Set.ofList
- if (s1 = s2) then
- Some(unifs)
- else
- __UnifLists elistL elistR
- | SequenceExpr(elistL), SequenceExpr(elistR) when List.length elistL = List.length elistR ->
- __UnifLists elistL elistR
- | _ when l = r ->
- Some(unifs)
- | _ ->
- let __TryUnifyPair x1 a1 x2 a2 unifs =
- let builder = new Utils.CascadingBuilder<_>(None)
- builder {
- let! unifsLhs = SelectiveUnifyImplies okToUnifyFunc x1 a1 dir unifs
- let! unifsRhs = SelectiveUnifyImplies okToUnifyFunc x2 a2 dir unifsLhs
- return Some(unifsRhs)
- }
-
- // target implies candidate!
- let rec ___f2 consequence premise unifs =
- match consequence, premise with
- // same operators + commutative -> try both
- | BinaryExpr(_, opT, lhsT, rhsT), BinaryExpr(_, opC, lhsC, rhsC) when opT = opC && IsCommutativeOp opT ->
- match __TryUnifyPair lhsC lhsT rhsC rhsT unifs with
- | Some(x) -> Some(x)
- | None -> __TryUnifyPair lhsC rhsT rhsC lhsT unifs
- // operators are the same
- | BinaryExpr(_, opT, lhsT, rhsT), BinaryExpr(_, opC, lhsC, rhsC) when opC = opT ->
- __TryUnifyPair lhsC lhsT rhsC rhsT unifs
- // operators are exactly the invers of one another
- | BinaryExpr(_, opT, lhsT, rhsT), BinaryExpr(_, opC, lhsC, rhsC) when AreInverseOps opC opT ->
- __TryUnifyPair lhsC rhsT rhsC lhsT unifs
- //
- | BinaryExpr(_, opT, lhsT, rhsT), BinaryExpr(_, opC, lhsC, rhsC) when DoesImplyOp opC opT ->
- __TryUnifyPair lhsC lhsT rhsC rhsT unifs
- | UnaryExpr(opC, subC), UnaryExpr(opP, subP) when opC = opP ->
- SelectiveUnifyImplies okToUnifyFunc subP subC dir unifs
- | SelectExpr(lstC, idxC), SelectExpr(lstP, idxP) ->
- __TryUnifyPair lstP lstC idxP idxC unifs
- | SeqLength(lstC), SeqLength(lstP) ->
- SelectiveUnifyImplies okToUnifyFunc lstP lstC dir unifs
- | Dot(exprC, fldNameC), Dot(exprP, fldNameP) when fldNameC = fldNameP ->
- SelectiveUnifyImplies okToUnifyFunc exprP exprC dir unifs
- | _ -> None
-
- let rec ___f1 targetLst candidateLst unifs =
- match targetLst, candidateLst with
- | targetExpr :: targetRest, candExpr :: candRest ->
- // trying to find a unification for "targetExpr"
- let uOpt = match ___f2 targetExpr candExpr unifs with
- // found -> just return
- | Some(unifs2) -> Some(unifs2)
- // not found -> keep looking in the rest of the candidate expressions
- | None -> ___f1 [targetExpr] candRest unifs
- match uOpt with
- // found -> try find for the rest of the target expressions
- | Some(unifs2) -> ___f1 targetRest candidateLst unifs2
- // not found -> fail
- | None -> None
- | targetExpr :: _, [] ->
- // no more candidates for unification for this targetExpr -> fail
- None
- | [], _ ->
- // we've found unifications for all target expressions -> return the current unifications map
- Some(unifs)
-
- let __HasSetExpr e = DescendExpr2 (fun ex acc -> if acc then true else match ex with SetExpr(_) -> true | _ -> false) e false
- let __PreprocSplitSort e = e |> DesugarAndRemove |> DistributeNegation |> SplitIntoConjunts |> List.sortBy (fun e -> if __HasSetExpr e then 1 else 0)
- let lhsConjs = lhs |> __PreprocSplitSort
- let rhsConjs = rhs |> __PreprocSplitSort
- ___f1 rhsConjs lhsConjs unifs
- with
- | CannotUnify
- | KeyAlreadyExists -> None
-
-let UnifyImplies lhs rhs dir unifs = SelectiveUnifyImplies (fun e -> true) lhs rhs dir unifs
-
-////////////////////////////////////////////
-
-let rec ComputeClosure heapInst expandExprFunc premises =
- let bogusExpr = VarLiteral("!@#$%^&*()")
-
- let ApplyUnifs unifs expr =
- Rewrite (function
- | VarLiteral(id) when unifs |> Map.containsKey id ->
- Some(unifs |> Map.find id)
- | _ -> None
- ) expr
-
- let FindMatches expr except premises =
- //Logger.TraceLine ("finding matches for: " + (PrintExpr 0 expr) + "; #premises = " + (Set.count premises |> sprintf "%i"))
- let okToUnifyFunc = fun (varName: string) -> varName.StartsWith("$")
- if expr = TrueLiteral then
- []
- else
- let matches =
- premises |> Set.toList
- |> List.choose (function BinaryExpr(_,"=",lhs,rhs) ->
- if lhs = expr && not (rhs = except) then
- Some(rhs)
- elif rhs = expr && not (lhs = except) then
- Some(lhs)
- else
- match SelectiveUnifyImplies okToUnifyFunc lhs expr LTR Map.empty with
- | Some(unifs) -> Some(ApplyUnifs unifs rhs)
- | None ->
- match SelectiveUnifyImplies okToUnifyFunc rhs expr LTR Map.empty with
- | Some(unifs) -> Some(ApplyUnifs unifs lhs)
- | None -> None
- | _ -> None)
- //Logger.TraceLine (sprintf "Number of matches for %s: %i" (PrintExpr 0 expr) (List.length matches))
- matches
-
- let MySetAdd expr set =
- let x = Printer.PrintExpr 0 expr
- if x.Contains("$") || not (expandExprFunc expr) then
- set
- else
- match expr with
- | BinaryExpr(p,op,lhs,rhs) when IsCommutativeOp op && Set.contains (BinaryExpr(p,op,rhs,lhs)) set -> set
- | BinaryExpr(p,op,lhs,rhs) when IsCommutativeOp op && rhs = lhs -> set
- | _ -> Set.add expr set
-
- let SelectExprCombinerFunc lst idx =
- // distribute the indexing operation if possible
- let rec __fff lst idx =
- //Logger.TraceLine ("SelectExpr fff for " + (PrintExpr 0 lst))
- let selExpr = SelectExpr(lst, idx)
- match lst with
- | BinaryExpr(_,"+",lhs,rhs) ->
- let idxVal = EvalFull heapInst idx |> Expr2Int
- let lhsVal = EvalFull heapInst lhs |> Expr2List
- let rhsVal = EvalFull heapInst rhs |> Expr2List
- if idxVal < List.length lhsVal then
- __fff lhs idx
- else
- __fff rhs (BinarySub idx (IntLiteral(List.length lhsVal)))
- | SequenceExpr(elist) ->
- let idxVal = EvalFull heapInst idx |> Expr2Int
- [elist.[idxVal]]
- | _ -> [selExpr]
- __fff lst idx
-
- let SeqLenCombinerFunc lst =
- // distribute the SeqLength operation if possible
- let rec __fff lst =
- //Logger.TraceLine ("SeqLen fff for " + (PrintExpr 0 lst))
- let lenExpr = SeqLength(lst)
- match lst with
- | BinaryExpr(_,"+",lhs,rhs) ->
- BinaryAdd (__fff lhs) (__fff rhs) //TODO: this ought to be incorrect!
- | SequenceExpr(elist) ->
- IntLiteral(List.length elist)
- | _ -> lenExpr
- [__fff lst]
-
- let BinaryInCombiner lhs rhs =
- // distribute the "in" operation if possible
- let rec __fff lhs rhs =
- //Logger.TraceLine ("In fff for " + (PrintExpr 0 lhs) + " and " + (PrintExpr 0 rhs))
- let binInExpr = BinaryIn lhs rhs
-// match rhs with
-// | BinaryExpr(_,"+",BinaryExpr(_,"+",SetExpr(_), Dot(_)), Dot(_)) -> Logger.Trace ""
-// | _ -> ()//TODO: remove
-
- match rhs with
- | BinaryExpr(_,"+",l,r) ->
-// let lhsVal = EvalFull heapInst lhs
-// let lVal = EvalFull heapInst l
-// let rVal = EvalFull heapInst r
-// match lVal,rVal with
-// | SequenceExpr(elist), _ | _, SequenceExpr(elist)
-// | SetExpr(elist), _ | _, SetExpr(elist) ->
-// if elist |> Utils.ListContains lhsVal then
-// __fff lhs l
-// else
-// __fff lhs r
-// | _ -> [binInExpr]
-///////////////////////////////
-// [BinaryOr (BinaryIn lhs l) (BinaryIn lhs r)]
- let opt1 = BinaryIn lhs l
- let opt2 = BinaryIn lhs r
- match EvalFull heapInst opt1 with
- | BoolLiteral(true) -> [opt1]
- | _ -> match EvalFull heapInst opt2 with
- | BoolLiteral(true) -> [opt2]
- | _ -> Utils.ListCombine BinaryOr (__fff lhs l) (__fff lhs r)
- //[BinaryOr (BinaryIn lhs l)(BinaryIn lhs r)]
- | SequenceExpr(elist) ->
- let len = elist |> List.length
- if len = 0 then
- [FalseLiteral]
- elif len = 1 then
- [BinaryEq lhs elist.[0]]
- else
- let lhsVal = EvalFull heapInst lhs
- let lst0Val = EvalFull heapInst elist.[0]
- if lhsVal = lst0Val then
- [BinaryEq lhs elist.[0]]
- else
- __fff lhs (SequenceExpr(elist |> List.tail))
- //[BinaryIn lhs (SequenceExpr(elist |> List.tail))]
- | SetExpr(elist) ->
- let evalElist = elist |> List.map (EvalFull heapInst)
- let evalLhs = EvalFull heapInst lhs
- try
- let idx = evalElist |> List.findIndex (fun e -> e = evalLhs)
- [BinaryEq lhs elist.[idx]]
- with
- | _ -> [binInExpr]
- | _ -> [binInExpr]
- __fff lhs rhs
-
- let BinaryNotInCombiner lhs rhs =
- // distribute the "!in" operation if possible
- let rec __fff lhs rhs =
- //Logger.TraceLine ("NotIn fff for " + (PrintExpr 0 lhs) + " and " + (PrintExpr 0 rhs))
- let binNotInExpr = BinaryNotIn lhs rhs
- match rhs with
- | BinaryExpr(_,"+",l,r) ->
-// let lhsVal = EvalFull heapInst lhs
-// let lVal = EvalFull heapInst l
-// let rVal = EvalFull heapInst r
-// match lVal,rVal with
-// | SequenceExpr(elistL), SequenceExpr(elistR)
-// | SetExpr(elistL), SetExpr(elistR) ->
-// (__fff lhs l) @
-// (__fff lhs r)
-// | _ -> [binNotInExpr]
- __fff lhs l @ __fff lhs r
- | SequenceExpr(elist) ->
- let len = elist |> List.length
- if len = 0 then
- [TrueLiteral]
- elif len = 1 then
- [BinaryNeq lhs elist.[0]]
- else
- let lhsVal = EvalFull heapInst lhs
- let lst0Val = EvalFull heapInst elist.[0]
- [BinaryNeq lhs elist.[0]] @
- __fff lhs (SequenceExpr(elist |> List.tail))
- //[BinaryNotIn lhs (SequenceExpr(elist |> List.tail))]
- | _ -> [binNotInExpr]
- __fff lhs rhs
-
- let rec __CombineAllMatches expr premises =
- //Logger.TraceLine ("Combining all matches for: " + (PrintExpr 0 expr))
- let lst0 = FindMatches expr bogusExpr premises
- let lstCombined =
- match expr with
- | BinaryExpr(p,op,lhs,rhs) ->
- let lhsMatches = __CombineAllMatches lhs premises
- let rhsMatches = __CombineAllMatches rhs premises
- let lst1 = Utils.ListCombine (fun e1 e2 -> BinaryExpr(p,op,e1,e2)) lhsMatches rhsMatches
- let lst2 =
- if op = "in" then
- Utils.ListCombineMult BinaryInCombiner lhsMatches rhsMatches
- elif op = "!in" then
- Utils.ListCombineMult BinaryNotInCombiner lhsMatches rhsMatches
- else
- []
- lst1 @ lst2
- | UnaryExpr(op,sub) ->
- __CombineAllMatches sub premises |> List.map (fun e -> UnaryExpr(op,e))
- | SelectExpr(lst,idx) ->
- let lstMatches = __CombineAllMatches lst premises
- let idxMatches = __CombineAllMatches idx premises
- Utils.ListCombineMult SelectExprCombinerFunc lstMatches idxMatches
- | SeqLength(lst) ->
- __CombineAllMatches lst premises |> List.map SeqLenCombinerFunc |> List.concat
- // TODO: other cases
- | _ -> []
- expr :: (lst0 @ lstCombined)
-
- let rec __ExpandPremise expr premises =
- let __AddToPremisses exprLst premises = exprLst |> List.fold (fun acc e -> MySetAdd e acc) premises
- let allMatches = lazy(__CombineAllMatches expr premises)
- match expr with
- | BinaryExpr(p,op,lhs,rhs) when IsRelationalOp op ->
- let x = allMatches.Force()
- __AddToPremisses x premises
- | SelectExpr(lst, idx) ->
- let x = allMatches.Force()
- __AddToPremisses x premises
- | _ -> premises
-
- let rec __Iter exprLst premises =
- match exprLst with
- | expr :: rest ->
- let newPremises =
- if expandExprFunc expr then
- //Logger.TraceLine ("expanding " + (PrintExpr 0 expr))
- __ExpandPremise expr premises
- else
- premises
- __Iter rest newPremises
- | [] -> premises
-
- (* --- function body starts here --- *)
- let iterOnceFunc p = __Iter (p |> Set.toList) p
- // TODO: iterate only 3 times, instead of to full closure
- let p1 = iterOnceFunc premises
- let p2 = p1 |> iterOnceFunc
- //let p3 = p2 |> iterOnceFunc
- p2
-// let premises' = iterOnceFunc premises
-// if premises' = premises then
-// premises'
-// else
-// Logger.TraceLine "-------closure----------------"
-// //premises' |> Set.iter (fun e -> Logger.TraceLine (Printer.PrintExpr 0 e))
-// ComputeClosure heapInst expandExprFunc premises'
-
-
diff --git a/Jennisys/Jennisys/Getters.fs b/Jennisys/Jennisys/Getters.fs
deleted file mode 100644
index 2e2732af..00000000
--- a/Jennisys/Jennisys/Getters.fs
+++ /dev/null
@@ -1,284 +0,0 @@
-module Getters
-
-open Ast
-
-let RenameToOld name =
- "old_" + name
-
-let RenameFromOld (name: string) =
- if name.StartsWith("old_") then
- name.Substring(4)
- else
- name
-
-// --- search functions ---
-
-// ==================================
-/// Returns variable name
-// ==================================
-let GetVarName var =
- match var with
- | Var(name,_,_) -> name
-
-let GetExtVarName var =
- match var with
- | Var(id, _, false) -> id
- | Var(id, _, true) -> RenameToOld id
-
-let IsOldVar var =
- match var with
- | Var(_,_,isOld) -> isOld
-
-// ==================================
-/// Returns variable type
-// ==================================
-let GetVarType var =
- match var with
- | Var(_,t,_) -> t
-
-// ===============================================
-/// Returns whether there exists a variable
-/// in a given VarDecl list with a given name (id)
-// ===============================================
-let IsInVarList varLst id =
- varLst |> List.exists (fun var -> GetVarName var = id)
-
-
-// =========================================================
-/// Out of all "members" returns only those that are "Field"s
-// =========================================================
-let FilterFieldMembers members =
- members |> List.choose (function Field(vd) -> Some(vd) | _ -> None)
-
-// =============================================================
-/// Out of all "members" returns only those that are constructors
-// =============================================================
-let FilterConstructorMembers members =
- members |> List.choose (function Method(_,_,_,_, true) as m -> Some(m) | _ -> None)
-
-// =============================================================
-/// Out of all "members" returns only those that are
-/// constructors and have at least one input parameter
-// =============================================================
-let FilterConstructorMembersWithParams members =
- members |> List.choose (function Method(_,Sig(ins,outs),_,_, true) as m when not (List.isEmpty ins) -> Some(m) | _ -> None)
-
-// ==========================================================
-/// Out of all "members" returns only those that are "Method"s
-// ==========================================================
-let FilterMethodMembers members =
- members |> List.choose (function Method(_,_,_,_,_) as m -> Some(m) | _ -> None)
-
-// =======================================================================
-/// Returns all members of the program "prog" that pass the filter "filter"
-// =======================================================================
-let FilterMembers prog filter =
- match prog with
- | Program(components) ->
- components |> List.fold (fun acc comp ->
- match comp with
- | Component(Interface(_,_,members),_,_) -> List.concat [acc ; members |> filter |> List.choose (fun m -> Some(comp, m))]
- | _ -> acc) []
-
-let GetAbstractFields comp =
- match comp with
- | Component(Interface(_,_,members), _, _) -> FilterFieldMembers members
- | _ -> failwithf "internal error: invalid component: %O" comp
-
-let GetConcreteFields comp =
- match comp with
- | Component(_, DataModel(_,_,cVars,_,_), _) -> cVars
- | _ -> failwithf "internal error: invalid component: %O" comp
-
-// =================================
-/// Returns all fields of a component
-// =================================
-let GetAllFields comp =
- List.concat [GetAbstractFields comp; GetConcreteFields comp]
-
-// ===========================================================
-/// Returns a map (Type |--> Set<Var>) where all
-/// the given fields are grouped by their type
-///
-/// ensures: forall v :: v in ret.values.elems ==> v in fields
-/// ensures: forall k :: k in ret.keys ==>
-/// forall v1, v2 :: v1, v2 in ret[k].elems ==>
-/// v1.type = v2.type
-// ===========================================================
-let rec GroupFieldsByType fields =
- match fields with
- | Var(name, ty, old) :: rest ->
- let map = GroupFieldsByType rest
- let fldSet = Map.tryFind ty map |> Utils.ExtractOptionOr Set.empty
- map |> Map.add ty (fldSet |> Set.add (Var(name, ty, old)))
- | [] -> Map.empty
-
-let IsConcreteField comp fldName = GetConcreteFields comp |> List.exists (fun var -> GetVarName var = fldName)
-let IsAbstractField comp fldName = GetAbstractFields comp |> List.exists (fun var -> GetVarName var = fldName)
-
-// =================================
-/// Returns class name of a component
-// =================================
-let GetClassName comp =
- match comp with
- | Component(Interface(name,_,_),_,_) -> name
- | _ -> failwith ("unrecognized component: " + comp.ToString())
-
-let GetClassType comp =
- match comp with
- | Component(Interface(name,typeParams,_),_,_) -> NamedType(name, typeParams)
- | _ -> failwith ("unrecognized component: " + comp.ToString())
-
-// ========================
-/// Returns name of a method
-// ========================
-let GetMethodName mthd =
- match mthd with
- | Method(name,_,_,_,_) -> name
- | _ -> failwith ("not a method: " + mthd.ToString())
-
-// ===========================================================
-/// Returns full name of a method (= <class_name>.<method_name>
-// ===========================================================
-let GetMethodFullName comp mthd =
- (GetClassName comp) + "." + (GetMethodName mthd)
-
-// =============================
-/// Returns signature of a method
-// =============================
-let GetMethodSig mthd =
- match mthd with
- | Method(_,sgn,_,_,_) -> sgn
- | _ -> failwith ("not a method: " + mthd.ToString())
-
-// =========================================================
-/// Returns all arguments of a method (both input and output)
-// =========================================================
-let GetSigVars sign =
- match sign with
- | Sig(ins, outs) -> List.concat [ins; outs]
-
-let GetMethodInArgs mthd =
- match mthd with
- | Method(_,Sig(ins, _),_,_,_) -> ins
- | _ -> failwith ("not a method: " + mthd.ToString())
-
-let GetMethodOutArgs mthd =
- match mthd with
- | Method(_,Sig(_, outs),_,_,_) -> outs
- | _ -> failwith ("not a method: " + mthd.ToString())
-
-let GetMethodArgs mthd =
- let ins = GetMethodInArgs mthd
- let outs = GetMethodOutArgs mthd
- List.concat [ins; outs]
-
-let IsConstructor mthd =
- match mthd with
- | Method(_,_,_,_,isConstr) -> isConstr
- | _ -> failwithf "expected a method but got %O" mthd
-
-let rec GetTypeShortName ty =
- match ty with
- | IntType -> "int"
- | BoolType -> "bool"
- | SetType(_) -> "set"
- | SeqType(_) -> "seq"
- | NamedType(n,_) | InstantiatedType(n,_) -> n
-
-// ==================================
-/// Returns component name
-// ==================================
-let GetComponentName comp =
- match comp with
- | Component(Interface(name,_,_),_,_) -> name
- | _ -> failwithf "invalid component %O" comp
-
-let GetComponentTypeParameters comp =
- match comp with
- | Component(Interface(_,tp,_),_,_) -> tp
- | _ -> failwithf "invalid component %O" comp
-
-
-// ==================================
-/// Returns all members of a component
-// ==================================
-let GetMembers comp =
- match comp with
- | Component(Interface(_,_,members),_,_) -> members
- | _ -> failwith ("unrecognized component: " + comp.ToString())
-
-// ====================================================
-/// Finds a component of a program that has a given name
-// ====================================================
-let FindComponent (prog: Program) clsName =
- match prog with
- | Program(comps) -> comps |> List.filter (function Component(Interface(name,_,_),_,_) when name = clsName -> true | _ -> false)
- |> Utils.ListToOption
-
-let FindComponentForType prog ty =
- FindComponent prog (GetTypeShortName ty)
-
-let FindComponentForTypeOpt prog tyOpt =
- match tyOpt with
- | Some(ty) -> FindComponentForType prog ty
- | None -> None
-
-let CheckSameCompType comp ty =
- GetComponentName comp = GetTypeShortName ty
-
-let GetComponentType comp =
- NamedType(GetComponentName comp, GetComponentTypeParameters comp)
-
-// ===================================================
-/// Finds a method of a component that has a given name
-// ===================================================
-let FindMethod comp methodName =
- let x = GetMembers comp
- let y = x |> FilterMethodMembers
- let z = y |> List.filter (function Method(name,_,_,_,_) when name = methodName -> true | _ -> false)
- GetMembers comp |> FilterMethodMembers |> List.filter (function Method(name,_,_,_,_) when name = methodName -> true | _ -> false)
- |> Utils.ListToOption
-
-// ==============================================
-/// Finds a field of a class that has a given name
-// ==============================================
-//let FindCompVar prog clsName fldName =
-// let copt = FindComponent prog clsName
-// match copt with
-// | Some(comp) ->
-// GetAllFields comp |> List.filter (function Var(name,_) when name = fldName -> true | _ -> false)
-// |> Utils.ListToOption
-// | None -> None
-
-let FindVar comp fldName =
- GetAllFields comp |> List.filter (fun var -> GetVarName var = fldName)
- |> Utils.ListToOption
-
-// ======================================
-/// Returns the frame of a given component
-// ======================================
-let GetFrame comp =
- match comp with
- | Component(_, DataModel(_,_,_,frame,_), _) -> frame
- | _ -> failwithf "not a valid component %O" comp
-
-let GetFrameFields comp =
- let frame = GetFrame comp
- frame |> List.choose (function IdLiteral(name) -> Some(name) | _ -> None) // TODO: is it really enough to handle only IdLiteral's
- |> List.choose (fun varName ->
- let v = FindVar comp varName
- Utils.ExtractOptionMsg ("field not found: " + varName) v |> ignore
- v
- )
-
-// ==============================================
-/// Checks whether two given methods are the same.
-///
-/// Methods are the same if their names are the
-/// same and their components have the same name.
-// ==============================================
-let CheckSameMethods (c1,m1) (c2,m2) =
- GetComponentName c1 = GetComponentName c2 && GetMethodName m1 = GetMethodName m2
-
-//////////////////////// \ No newline at end of file
diff --git a/Jennisys/Jennisys/Jennisys.fs b/Jennisys/Jennisys/Jennisys.fs
deleted file mode 100644
index b10c9cfc..00000000
--- a/Jennisys/Jennisys/Jennisys.fs
+++ /dev/null
@@ -1,72 +0,0 @@
-// This project type requires the F# PowerPack at http://fsharppowerpack.codeplex.com/releases
-// Learn more about F# at http://fsharp.net
-// Original project template by Jomo Fisher based on work of Brian McNamara, Don Syme and Matt Valerio
-// This posting is provided "AS IS" with no warranties, and confers no rights.
-module Main
-
-open System
-open System.IO
-open Microsoft.FSharp.Text.Lexing
-
-open Ast
-open AstUtils
-open Lexer
-open Options
-open Parser
-open Printer
-open TypeChecker
-open Analyzer
-
-let readAndProcess (filename: string) =
- printfn "// Jennisys, Copyright (c) 2011, Microsoft."
- // lex
- let f = if filename = null then Console.In else new StreamReader(filename) :> TextReader
- let lexbuf = LexBuffer<char>.FromTextReader(f)
- lexbuf.EndPos <- { pos_bol = 0;
- pos_fname=if filename = null then "stdin" else filename;
- pos_cnum=0;
- pos_lnum=1 }
-
- let sprog =
- try
- // parse
- Parser.start Lexer.tokenize lexbuf
- with
- | ex ->
- let pos = lexbuf.EndPos
- printfn " [PARSE ERROR]: %s(%d,%d): %s" pos.FileName pos.Line pos.Column ex.Message
- Environment.Exit(1)
- failwith ""
- match TypeCheck sprog with
- | None -> () // errors have already been reported
- | Some(prog) ->
- Analyze prog filename
-
-
-try
- let args = Environment.GetCommandLineArgs()
- ParseCmdLineArgs (List.ofArray args |> List.tail)
- if CONFIG.breakIntoDebugger then ignore (System.Diagnostics.Debugger.Launch()) else ()
- if CONFIG.help then
- printfn "%s" PrintHelpMsg
- else
- if CONFIG.inputFilename = "" then
- printfn "*** Error: No input file was specified."
- else
- readAndProcess CONFIG.inputFilename
-with
- | InvalidCmdLineOption(msg)
- | InvalidCmdLineArg(msg) as ex ->
- printfn " [ERROR] %s" msg;
- printfn "%s" PrintHelpMsg
- | EvalFailed(msg) as ex ->
- printfn " [EVALUATION ERROR] %s" msg
- printfn "%O" ex.StackTrace
-
-//let mc = MethodOutSelect (MethodCall(IdLiteral("left"),"SetNode","Find",[VarLiteral("n")]), "ret")
-//let expr = BinaryOr (BinaryOr (BinaryEq (VarLiteral("a")) (VarLiteral("b"))) mc) (mc)
-//printfn "%s" (PrintExpr 0 expr)
-//printfn ""
-//
-//let stmt = ExprStmt(expr)
-//printfn "%s" (DafnyPrinter.PrintStmt stmt 0 false) \ No newline at end of file
diff --git a/Jennisys/Jennisys/Jennisys.fsproj b/Jennisys/Jennisys/Jennisys.fsproj
deleted file mode 100644
index d3493749..00000000
--- a/Jennisys/Jennisys/Jennisys.fsproj
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{f2ff4b3a-2fe8-474a-88df-6950f7d78908}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <RootNamespace>Language</RootNamespace>
- <AssemblyName>Jennisys</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <TargetFrameworkProfile>Client</TargetFrameworkProfile>
- <Name>Language</Name>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <Tailcalls>false</Tailcalls>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <WarningLevel>3</WarningLevel>
- <PlatformTarget>x86</PlatformTarget>
- <DocumentationFile>bin\Debug\Language.XML</DocumentationFile>
- <StartArguments>examples/oopsla12/IntSet.jen /method:IntSet.Singleton</StartArguments>
- <StartWorkingDirectory>C:\boogie\Jennisys\Jennisys\</StartWorkingDirectory>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <Tailcalls>true</Tailcalls>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <WarningLevel>3</WarningLevel>
- <PlatformTarget>x86</PlatformTarget>
- <DocumentationFile>bin\Release\Language.XML</DocumentationFile>
- </PropertyGroup>
- <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" />
- <Import Project="$(MSBuildExtensionsPath32)\..\FSharpPowerPack-2.0.0.0\bin\FSharp.PowerPack.targets" />
- <PropertyGroup>
- <FsLexOutputFolder>$(IntermediateOutputPath)</FsLexOutputFolder>
- <FsYaccOutputFolder>$(IntermediateOutputPath)</FsYaccOutputFolder>
- </PropertyGroup>
- <ItemGroup>
- <Compile Include="SymGen.fs" />
- <Compile Include="Logger.fs" />
- <Compile Include="Utils.fs" />
- <Compile Include="Options.fs" />
- <Compile Include="PipelineUtils.fs" />
- <Compile Include="Ast.fs" />
- <Compile Include="Getters.fs" />
- <Compile Include="AstUtils.fs" />
- <Compile Include="$(IntermediateOutputPath)\Parser.fs">
- <Visible>false</Visible>
- <Link>Parser.fs</Link>
- </Compile>
- <Compile Include="$(IntermediateOutputPath)\Lexer.fs">
- <Visible>false</Visible>
- <Link>Lexer.fs</Link>
- </Compile>
- <Compile Include="DafnyModelUtils.fs" />
- <Compile Include="EnvUtils.fs" />
- <FsYacc Include="Parser.fsy">
- <OtherFlags>--module Parser</OtherFlags>
- </FsYacc>
- <FsLex Include="Lexer.fsl">
- <OtherFlags>--unicode</OtherFlags>
- </FsLex>
- <Compile Include="PrintUtils.fs" />
- <Compile Include="Printer.fs" />
- <Compile Include="DafnyPrinter.fs" />
- <Compile Include="TypeChecker.fs" />
- <Compile Include="Resolver.fs" />
- <Compile Include="FixpointSolver.fs" />
- <Compile Include="MethodUnifier.fs" />
- <Compile Include="Modularizer.fs" />
- <Compile Include="CodeGen.fs" />
- <Compile Include="Analyzer.fs" />
- <Compile Include="Jennisys.fs" />
- </ItemGroup>
- <ItemGroup>
- <Reference Include="Boogie">
- <HintPath>..\..\Binaries\Boogie.exe</HintPath>
- </Reference>
- <Reference Include="FSharp.PowerPack">
- <HintPath>C:\Program Files\FSharpPowerPack-1.9.9.9\bin\FSharp.PowerPack.dll</HintPath>
- </Reference>
- <Reference Include="mscorlib" />
- <Reference Include="FSharp.Core" />
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Numerics" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Source\Model\Model.csproj">
- <Name>Model</Name>
- <Project>{acef88d5-dadd-46da-bae1-2144d63f4c83}</Project>
- <Private>True</Private>
- </ProjectReference>
- </ItemGroup>
- <!--
- <ItemGroup>
- <ProjectReference Include="..\..\Source\Model\Model.csproj">
- <Name>Model</Name>
- <Project>{acef88d5-dadd-46da-bae1-2144d63f4c83}</Project>
- <Private>True</Private>
- </ProjectReference>
- </ItemGroup>
- -->
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/Jennisys/Jennisys/Lexer.fsl b/Jennisys/Jennisys/Lexer.fsl
deleted file mode 100644
index e1d4795b..00000000
--- a/Jennisys/Jennisys/Lexer.fsl
+++ /dev/null
@@ -1,83 +0,0 @@
-{
-module Lexer
-open System
-open Parser
-open Microsoft.FSharp.Text.Lexing
-
-let lexeme lexbuf =
- LexBuffer<char>.LexemeString lexbuf
-}
-
-// These are some regular expression definitions
-let digit = ['0'-'9']
-let nondigit = [ 'a'-'z' 'A'-'Z' '_' ]
-let idchar = (nondigit | digit)
-let whitespace = [' ' '\t' ]
-let newline = ('\n' | '\r' '\n')
-
-rule tokenize = parse
-| whitespace { tokenize lexbuf }
-| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; tokenize lexbuf }
-// TODO: | "//"[-newline]* { tokenize lexbuf }
-// keywords
-| "interface" { INTERFACE }
-| "datamodel" { DATAMODEL }
-| "code" { CODE }
-| "var" { VAR }
-| "constructor" { CONSTRUCTOR }
-| "method" { METHOD }
-| "frame" { FRAME }
-| "invariant" { INVARIANT }
-| "returns" { RETURNS }
-| "requires" { REQUIRES }
-| "ensures" { ENSURES }
-| "forall" { FORALL }
-// Types
-| "int" { INTTYPE }
-| "bool" { BOOLTYPE }
-| "seq" { SEQTYPE }
-| "set" { SETTYPE }
-// Operators
-| "..." { DOTDOTDOT }
-| ".." { DOTDOT }
-| "." { DOT }
-| "old" { OLD }
-| "+" { PLUS }
-| "-" { MINUS }
-| "*" { STAR }
-| "div" { DIV }
-| "mod" { MOD }
-| "&&" { AND }
-| "||" { OR }
-| "!" { NOT }
-| "==>" { IMPLIES }
-| "<==>" { IFF }
-| "<" { LESS }
-| "<=" { ATMOST }
-| "=" { EQ }
-| "!=" { NEQ }
-| ">=" { ATLEAST }
-| ">" { GREATER }
-| "in" { IN }
-| "!in" { NOTIN }
-// Misc
-| ":=" { GETS }
-| "(" { LPAREN }
-| ")" { RPAREN }
-| "[" { LBRACKET }
-| "]" { RBRACKET }
-| "{" { LCURLY }
-| "}" { RCURLY }
-| "|" { VERTBAR }
-| ":" { COLON }
-| "::" { COLONCOLON }
-| "," { COMMA }
-| "?" { QMARK }
-// Numberic constants
-| digit+ { INTEGER (System.Convert.ToInt32(lexeme lexbuf)) }
-// identifiers
-| idchar+ { ID (LexBuffer<char>.LexemeString lexbuf) }
-// EOF
-| eof { EOF }
-| _ { printfn "Unrecognized input character: %s" (lexeme lexbuf) ; EOF }
-
diff --git a/Jennisys/Jennisys/Logger.fs b/Jennisys/Jennisys/Logger.fs
deleted file mode 100644
index dbf762cd..00000000
--- a/Jennisys/Jennisys/Logger.fs
+++ /dev/null
@@ -1,41 +0,0 @@
-// #######################################################
-/// Simple logging facility
-///
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// #######################################################
-
-module Logger
-
-let newline = System.Environment.NewLine
-
-let _ALL = 100
-let _TRACE = 90
-let _DEBUG = 70
-let _INFO = 50
-let _WARN = 40
-let _ERROR = 20
-let _NONE = 0
-
-let logLevel = _ALL
-
-let Log level msg =
- if logLevel >= level then
- printf "%s" msg
-
-let LogLine level msg =
- Log level (msg + newline)
-
-let Trace msg = Log _TRACE msg
-let TraceLine msg = LogLine _TRACE msg
-
-let Debug msg = Log _DEBUG msg
-let DebugLine msg = LogLine _DEBUG msg
-
-let Info msg = Log _INFO msg
-let InfoLine msg = LogLine _INFO msg
-
-let Warn msg = Log _WARN msg
-let WarnLine msg = LogLine _WARN msg
-
-let Error msg = Log _ERROR msg
-let ErrorLine msg = LogLine _ERROR msg \ No newline at end of file
diff --git a/Jennisys/Jennisys/MethodUnifier.fs b/Jennisys/Jennisys/MethodUnifier.fs
deleted file mode 100644
index d2b1db68..00000000
--- a/Jennisys/Jennisys/MethodUnifier.fs
+++ /dev/null
@@ -1,107 +0,0 @@
-module MethodUnifier
-
-open Ast
-open Getters
-open AstUtils
-open FixpointSolver
-open PrintUtils
-open Resolver
-open Utils
-
-let TryUnify targetMthd candMethod =
- let targetPre,targetPost = GetMethodPrePost targetMthd
- let targetPre = BinaryAnd targetPre (GetMethodGhostPrecondition targetMthd)
- let candPre,candPost = GetMethodPrePost candMethod
- let candPre = BinaryAnd candPre (GetMethodGhostPrecondition candMethod)
- let builder = new CascadingBuilder<_>(None)
- builder {
- let! unifs1 = UnifyImplies targetPre candPre RTL Map.empty
- let! unifs2 = UnifyImplies candPost targetPost LTR unifs1
- return Some(unifs2)
- }
-
-let rec TryFindAMatch targetMthd candidateMethods =
- let targetMthdName = GetMethodName targetMthd
- match candidateMethods with
- | candMthd :: rest ->
- if GetMethodName candMthd = targetMthdName then
- // skip if it is the same method
- TryFindAMatch targetMthd rest
- else
- match TryUnify targetMthd candMthd with
- | Some(unifs) -> Some(candMthd,unifs)
- | None -> TryFindAMatch targetMthd rest
- | [] -> None
-
-let TryFindExistingOpt comp targetMthd =
- TryFindAMatch targetMthd (GetMembers comp |> FilterMethodMembers)
-
-let TryFindExisting comp targetMthd =
- match TryFindAMatch targetMthd (GetMembers comp |> FilterMethodMembers) with
- | Some(m,unifs) -> m,unifs
- | None -> targetMthd, Map.empty
-
-let ApplyMethodUnifs receiver (c,m) unifs =
- let __Apply args = args |> List.map (fun var ->
- let name = GetExtVarName var
- match Map.tryFind name unifs with
- | Some(e) -> e
- | None -> VarLiteral(name))
- let ins = GetMethodInArgs m |> __Apply
- let outs = GetMethodOutArgs m |> __Apply
-
- let retVars, asgs = outs |> List.fold (fun (acc1,acc2) e ->
- let vname = SymGen.NewSymFake e
- let v = Var(vname, None, false)
- let acc1' = acc1 @ [v]
- let acc2' = acc2 @ [ArbitraryStatement(Assign(VarLiteral(vname), e))]
- acc1', acc2'
- ) ([],[])
- let mcallExpr = MethodCall(receiver, GetComponentName c, GetMethodName m, ins)
- match retVars, outs with
- | [], [] -> [ArbitraryStatement(ExprStmt(mcallExpr))]
- | [_], [VarLiteral(vn2)] -> [ArbitraryStatement(Assign(VarDeclExpr([Var(vn2, None, false)], false), mcallExpr))]
- | _ ->
- let mcall = ArbitraryStatement(Assign(VarDeclExpr(retVars, true), mcallExpr))
- mcall :: asgs
-
-// ====================================================
-///
-// ====================================================
-let TryFindExistingAndConvertToSolution indent comp m cond callGraph =
- let __Calls caller callee =
- let keyOpt = callGraph |> Map.tryFindKey (fun (cc,mm) mset -> CheckSameMethods (comp,caller) (cc,mm))
- match keyOpt with
- | Some(k) -> callGraph |> Map.find k |> Set.contains ((GetComponentName comp),(GetMethodName callee))
- | None -> false
- (* --- function body starts here --- *)
- if not Options.CONFIG.genMod then
- None
- else
- let idt = Indent indent
- let candidateMethods = GetMembers comp |> List.filter (fun cm ->
- match cm with
- | Method(mname,_,_,_,_) when not (__Calls cm m) -> true
- | _ -> false)
- match TryFindAMatch m candidateMethods with
- | Some(m',unifs) ->
- Logger.InfoLine (idt + " - substitution method found:")
- Logger.InfoLine (Printer.PrintMethodSignFull (indent+6) comp m')
- Logger.DebugLine (idt + " Unifications: ")
- let idtt = idt + " "
- unifs |> Map.fold (fun acc k v -> acc + (sprintf "%s%s -> %s%s" idtt k (Printer.PrintExpr 0 v) newline)) "" |> Logger.Debug
- let obj = { name = "this"; objType = GetClassType comp }
- let modObjs = if IsModifiableObj obj (comp,m) then Set.singleton obj else Set.empty
- let body = ApplyMethodUnifs ThisLiteral (comp,m') unifs
- let hInst = { objs = Utils.MapSingleton obj.name obj;
- modifiableObjs = modObjs;
- assignments = body;
- concreteValues = body;
- methodArgs = Map.empty;
- methodRetVals = Map.empty;
- concreteMethodRetVals = Map.empty;
- globals = Map.empty }
- Some(Map.empty |> Map.add (comp,m) [cond, hInst]
- |> Map.add (comp,m') [])
- | None -> None
-
diff --git a/Jennisys/Jennisys/Modularizer.fs b/Jennisys/Jennisys/Modularizer.fs
deleted file mode 100644
index f5d7e7b7..00000000
--- a/Jennisys/Jennisys/Modularizer.fs
+++ /dev/null
@@ -1,206 +0,0 @@
-module Modularizer
-
-open Ast
-open Getters
-open AstUtils
-open MethodUnifier
-open PrintUtils
-open Resolver
-open Utils
-
-// =======================================================================
-/// Merges two solution maps so that if there are multiple entries for a
-/// single (comp,method) pair it concatenates them (corresponds to multiple
-/// branches).
-// =======================================================================
-let MergeSolutions sol1 sol2 =
- let rec __Merge sol1map sol2lst res =
- match sol2lst with
- | ((c2,m2), lst2) :: rest ->
- match sol1map |> Map.tryFindKey (fun (c1,m1) lst1 -> CheckSameMethods (c1,m1) (c2,m2)) with
- | Some(c1,m1) ->
- let lst1 = sol1map |> Map.find(c1,m1)
- let newRes = res |> Map.add (c1,m1) (lst1@lst2)
- __Merge sol1map rest newRes
- | None ->
- let newRes = res |> Map.add (c2,m2) lst2
- __Merge sol1map rest newRes
- | [] -> res
- (* --- function body starts here --- *)
- __Merge sol1 (sol2 |> Map.toList) sol1
-
-// ===========================================
-///
-// ===========================================
-let rec MakeModular indent prog comp meth cond hInst callGraph =
- let directChildren = lazy (GetDirectModifiableChildren hInst)
-
- let __IsAbstractField ty var =
- let builder = CascadingBuilder<_>(false)
- let varName = GetVarName var
- builder {
- let! comp = FindComponent prog (GetTypeShortName ty)
- let! fld = GetAbstractFields comp |> List.fold (fun acc v -> if GetVarName v = varName then Some(varName) else acc) None
- return true
- }
-
- let __FindObj objName =
- try
- //hInst.assignments |> List.find (fun ((obj,_),_) -> obj.name = objName) |> fst |> fst
- hInst.assignments |> List.choose (function FieldAssignment((obj,_),_) ->
- if (obj.name = objName) then Some(obj) else None
- | _ -> None)
- |> List.head
- with
- | ex -> failwithf "obj %s not found for method %s" objName (GetMethodFullName comp meth)
-
- let __GetObjLitType objLitName =
- (__FindObj objLitName).objType
-
- // ===============================================================================
- /// Goes through the assignments of the heapInstance and returns only those
- /// assignments that correspond to abstract fields of the given "objLitName" object
- // ===============================================================================
- let __GetAbsFldAssignments objLitName =
- hInst.assignments |> List.choose (function
- FieldAssignment ((obj,var),e) ->
- if obj.name = objLitName && __IsAbstractField obj.objType var then
- Some(var,e)
- else
- None
- | _ -> None)
-
- // ===============================================================================
- /// The given assignment is:
- /// x := e
- ///
- /// If e is an object (e.g. gensym32) with e.g. two abstract fields "a" and "b",
- /// with values 3 and 8 respectively, then the "x := e" spec is fixed as following:
- /// x.a := 3 && x.b := 8
- ///
- /// List values are handled similarly, e.g.:
- /// x := [gensym32]
- /// is translated into
- /// |x| = 1 && x[0].a = 3 && x[0].b = 8
- // ===============================================================================
- let rec __ExamineAndFix x e =
- match e with
- | ObjLiteral(id) when not (Utils.ListContains e (directChildren.Force())) -> //TODO: is it really only non-direct children?
- let absFlds = __GetAbsFldAssignments id
- absFlds |> List.fold (fun acc (var,vval) -> BinaryAnd acc (BinaryEq (Dot(x, GetVarName var)) vval)) TrueLiteral
- | SequenceExpr(elist) ->
- let rec __fff lst acc cnt =
- match lst with
- | fsExpr :: rest ->
- let acc = BinaryAnd acc (__ExamineAndFix (SelectExpr(x, IntLiteral(cnt))) fsExpr)
- __fff rest acc (cnt+1)
- | [] ->
- let lenExpr = BinaryEq (SeqLength(x)) (IntLiteral(cnt))
- BinaryAnd lenExpr acc
- __fff elist TrueLiteral 0
- | _ -> BinaryEq x e
-
- // ================================================================================
- /// The spec for an object consists of assignments to its abstract fields with one
- /// caveat: if some assignments include non-direct children objects of "this", then
- /// those objects cannot be used directly in the spec; instead, their properties must
- /// be expanded and embeded (that's what the "ExamineAndFix" function does)
- // ================================================================================
- let __GetSpecFor objLitName =
- let absFieldAssignments = __GetAbsFldAssignments objLitName
- let absFldAssgnExpr = absFieldAssignments |> List.fold (fun acc (var,e) -> BinaryAnd acc (__ExamineAndFix (IdLiteral(GetVarName var)) e)) TrueLiteral
- let retValExpr = hInst.methodRetVals |> Map.fold (fun acc varName varValueExpr -> BinaryAnd acc (BinaryEq (VarLiteral(varName)) varValueExpr)) TrueLiteral
- BinaryAnd absFldAssgnExpr retValExpr
-
- // ================================================================================================
- /// Simply traverses a given expression and returns all arguments of the "meth" method that are used
- // ================================================================================================
- let __GetArgsUsed expr =
- let args = GetMethodArgs meth
- let argSet = DescendExpr2 (fun e acc ->
- match e with
- | VarLiteral(vname) ->
- match args |> List.tryFind (fun var -> GetVarName var = vname) with
- | Some(var) -> acc |> Set.add var
- | None -> acc
- | _ -> acc
- ) expr Set.empty
- argSet |> Set.toList
-
- let rec __GetDelegateMethods objs acc =
- match objs with
- | ObjLiteral(name) as obj :: rest ->
- let mName = sprintf "_synth_%s_%s" (GetMethodFullName comp meth |> String.map (fun c -> if c = '.' then '_' else c)) name
- let pre,_ = GetMethodPrePost meth //TrueLiteral
- let post = __GetSpecFor name
- let ins = __GetArgsUsed (BinaryAnd pre post)
- let sgn = Sig(ins, [])
- let m = Method(mName, sgn, pre, post, true)
- let c = FindComponent prog (name |> __GetObjLitType |> GetTypeShortName) |> Utils.ExtractOption
- let m',unifs = TryFindExisting c m
- let args = ApplyMethodUnifs obj (c,m') unifs
- __GetDelegateMethods rest (acc |> Map.add obj (c,m',args))
- | _ :: rest -> failwith "internal error: expected to see only ObjLiterals"
- | [] -> acc
-
- // =======================================================================
- /// Tries to make a given solution for a given method into more modular,
- /// by delegating some statements (initialization of inner objects) to
- /// method calls.
- // =======================================================================
- let __GetModularBranch =
- let delegateMethods = __GetDelegateMethods (directChildren.Force()) Map.empty
- let initChildrenExprList = delegateMethods |> Map.toList
- |> List.map (fun (_, (_,_,asgs)) -> asgs)
- |> List.concat
- let newAssgns = hInst.assignments |> List.filter (function FieldAssignment((obj,_),_) -> obj.name = "this" | _ -> false)
- let newMethodsLst = delegateMethods |> Map.fold (fun acc receiver (c,newMthd,_) ->
- (c,newMthd) :: acc
- ) []
- newMethodsLst, { hInst with assignments = initChildrenExprList @ newAssgns }
-
- (* --- function body starts here --- *)
- let idt = Indent indent
- if Options.CONFIG.genMod then
- Logger.InfoLine (idt + " - delegating to method calls ...")
- // first try to find a match for the entire method (based on the given solution)
- let postSpec = __GetSpecFor "this"
- let meth' = match meth with
- | Method (mname, msig, mpre, _, isConstr) -> Method(mname, msig, mpre, postSpec, isConstr)
- | _ -> failwithf "internal error: expected a Method but got %O" meth
- match TryFindExistingAndConvertToSolution indent comp meth' cond callGraph with
- | Some(sol) -> sol |> FixSolution comp meth
- | None ->
- // if not found, try to split into parts
- let newMthdLst, newHeapInst = __GetModularBranch
- let msol = Utils.MapSingleton (comp,meth) [cond, newHeapInst]
- newMthdLst |> List.fold (fun acc (c,m) ->
- acc |> MergeSolutions (Utils.MapSingleton (c,m) [])
- ) msol
- else
- Utils.MapSingleton (comp,meth) [cond, hInst]
-
-//let GetModularSol prog sol =
-// let comp = fst (fst sol)
-// let meth = snd (fst sol)
-// let rec __xxx prog lst =
-// match lst with
-// | (cond, hInst) :: rest ->
-// let newProg, newComp, newMthdLst, newhInst = GetModularBranch prog comp meth hInst
-// let newProg, newRest = __xxx newProg rest
-// newProg, ((cond, newhInst) :: newRest)
-// | [] -> prog, []
-// let newProg, newSolutions = __xxx prog (snd sol)
-// let newComp = FindComponent newProg (GetComponentName comp) |> Utils.ExtractOption
-// newProg, ((newComp, meth), newSolutions)
-//
-//let Modularize prog solutions =
-// let rec __Modularize prog sols acc =
-// match sols with
-// | sol :: rest ->
-// let (newProg, newSol) = GetModularSol prog sol
-// let newAcc = acc |> Map.add (fst newSol) (snd newSol)
-// __Modularize newProg rest newAcc
-// | [] -> (prog, acc)
-// (* --- function body starts here --- *)
-// __Modularize prog (Map.toList solutions) Map.empty
diff --git a/Jennisys/Jennisys/Options.fs b/Jennisys/Jennisys/Options.fs
deleted file mode 100644
index fe640f48..00000000
--- a/Jennisys/Jennisys/Options.fs
+++ /dev/null
@@ -1,162 +0,0 @@
-// ####################################################################
-/// This module is intended to store and handle configuration options
-///
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// ####################################################################
-
-module Options
-
-open Utils
-
-type Config = {
- help : bool;
- inputFilename : string;
- methodToSynth : string;
- constructorsOnly : bool;
- inferConditionals : bool;
- verifyPartialSolutions : bool;
- verifySolutions : bool;
- checkUnifications : bool;
- genRepr : bool;
- genMod : bool;
- timeout : int;
- numLoopUnrolls : int;
- recursiveValid : bool;
- breakIntoDebugger : bool;
- minimizeGuards : bool;
-}
-
-type CfgOption<'a> = {
- optionName: string;
- optionType: string;
- optionSetter: 'a -> Config -> Config;
- descr: string;
-}
-
-exception InvalidCmdLineArg of string
-exception InvalidCmdLineOption of string
-
-let CheckNonEmpty value optName =
- if value = "" then raise (InvalidCmdLineArg("A value for option " + optName + " must not be empty")) else value
-
-let CheckInt value optName =
- try
- System.Int32.Parse value
- with
- | ex -> raise (InvalidCmdLineArg("A value for option " + optName + " must be a boolean"))
-
-let CheckBool value optName =
- if value = "" then
- true
- else
- try
- System.Boolean.Parse value
- with
- | ex -> raise (InvalidCmdLineArg("A value for option " + optName + " must be an integer"))
-
-let cfgOptions = [
- { optionName = "help"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with help = CheckBool v "help"}); descr = "prints out the available switches"; }
- { optionName = "method"; optionType = "string"; optionSetter = (fun v (cfg: Config) -> {cfg with methodToSynth = CheckNonEmpty v "method"}); descr = "select methods to synthesize; method names are in the form <ClassName>.<MethodName>; multiple methods can be given as a list of comma separated values"; }
- { optionName = "constrOnly"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with constructorsOnly = CheckBool v "constrOnly"}); descr = "synthesize constructors only"; }
- { optionName = "inferConds"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with inferConditionals = CheckBool v "inferConds"}); descr = "try to infer conditions"; }
- { optionName = "noInferConds"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with inferConditionals = not (CheckBool v "inferConds")}); descr = "don't try to infer conditions"; }
- { optionName = "verifyParSol"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with verifyPartialSolutions = CheckBool v "verifyParSol"}); descr = "verify partial solutions"; }
- { optionName = "noVerifyParSol"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with verifyPartialSolutions = not (CheckBool v "verifyParSol")}); descr = "don't verify partial solutions"; }
- { optionName = "verifySol"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with verifySolutions = CheckBool v "verifySol"}); descr = "verify final solution"; }
- { optionName = "noVerifySol"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with verifySolutions = not (CheckBool v "verifySol")}); descr = "don't verify final solution"; }
- { optionName = "checkUnifs"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with checkUnifications = CheckBool v "checkUnifs"}); descr = "verify unifications"; }
- { optionName = "noCheckUnifs"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with checkUnifications = not (CheckBool v "noCheckUnifs")}); descr = "don't verify unifications"; }
- { optionName = "genRepr"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with genRepr = CheckBool v "genRepr"}); descr = "generate Repr field"; }
- { optionName = "noGenRepr"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with genRepr = not (CheckBool v "noGenRepr")}); descr = "don't generate Repr field"; }
- { optionName = "genMod"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with genMod = CheckBool v "genMod"}); descr = "generate modular code (delegate to methods)"; }
- { optionName = "noGenMod"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with genMod = not (CheckBool v "noGenMod")}); descr = "dont generate modular code (delegate to methods)"; }
- { optionName = "timeout"; optionType = "int"; optionSetter = (fun v (cfg: Config) -> {cfg with timeout = CheckInt v "timeout"}); descr = "timeout"; }
- { optionName = "unrolls"; optionType = "int"; optionSetter = (fun v (cfg: Config) -> {cfg with numLoopUnrolls = CheckInt v "unrolls"}); descr = "number of unrolls of the Valid() function"; }
- { optionName = "recValid"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with recursiveValid = CheckBool v "recValid"}); descr = "generate recursive Valid() function"; }
- { optionName = "noRecValid"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with recursiveValid = not (CheckBool v "noRecValid")}); descr = "unroll Valid() function"; }
- { optionName = "break"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with breakIntoDebugger = CheckBool v "break"}); descr = "launches debugger upon start-up"; }
- { optionName = "minGuards"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with minimizeGuards = CheckBool v "minGuards"}); descr = "tries to remove unnecessary clauses from the inferred guards"; }
- { optionName = "noMinGuards"; optionType = "bool"; optionSetter = (fun v (cfg: Config) -> {cfg with minimizeGuards = not (CheckBool v "noMinGuards")}); descr = "don't minimize guards"; }
-]
-
-let cfgOptMap = cfgOptions |> List.fold (fun acc o -> acc |> Map.add o.optionName o) Map.empty
-
-let newline = System.Environment.NewLine
-
-let PrintHelpMsg =
- let maxw = cfgOptions |> List.fold (fun acc o -> if String.length o.optionName > acc then String.length o.optionName else acc) 0
- let maxwStr = sprintf "%d" (maxw + 2)
- let strf = new Printf.StringFormat<_>(" %-" + maxwStr + "s: %-6s | %s")
- let rec __PrintHelp optLst =
- match optLst with
- | fs :: [] -> (sprintf strf fs.optionName fs.optionType fs.descr)
- | fs :: rest -> (sprintf strf fs.optionName fs.optionType fs.descr) + newline + (__PrintHelp rest)
- | [] -> ""
- (* --- function body starts here --- *)
- newline +
- "Jennisys usage: Jennisys [ option ... ] filename" + newline +
- " where <option> is one of " + newline + newline +
- " ----- General options -----------------------------------------------------" + newline +
- " (available switches are: /, -, --)" + newline + newline +
- (__PrintHelp cfgOptions)
-
-let defaultConfig: Config = {
- help = false;
- inputFilename = "";
- inferConditionals = true;
- methodToSynth = "*";
- constructorsOnly = false;
- verifyPartialSolutions = true;
- verifySolutions = true;
- checkUnifications = false;
- genRepr = true;
- genMod = false;
- timeout = 0;
- numLoopUnrolls = 2;
- recursiveValid = true;
- breakIntoDebugger = false;
- minimizeGuards = true;
-}
-
-/// Should not be mutated outside the ParseCmdLineArgs method, which is
-/// typically called only once at the beginning of the program execution
-let mutable CONFIG = defaultConfig
-
-let ParseCmdLineArgs args =
- let __StripSwitches str =
- match str with
- | Prefix "--" x
- | Prefix "-" x
- | Prefix "/" x -> x
- | _ -> str
-
- let __Split (str: string) =
- let stripped = __StripSwitches str
- if stripped = str then
- ("",str)
- else
- let splits = stripped.Split([| ':' |])
- if splits.Length > 2 then raise (InvalidCmdLineOption("more than 2 colons in " + str))
- if splits.Length = 2 then
- let opt = splits.[0]
- let value = splits.[1]
- (opt,value)
- else
- let x = __StripSwitches splits.[0]
- (x, "")
-
- let rec __Parse args cfg =
- match args with
- | fs :: rest ->
- let opt,value = __Split fs
- if opt = "" then
- __Parse rest { cfg with inputFilename = CheckNonEmpty value opt }
- else
- match Map.tryFind opt cfgOptMap with
- | Some(opt) -> __Parse rest (opt.optionSetter value cfg)
- | None -> raise (InvalidCmdLineOption("Unknown option: " + opt))
- | [] -> cfg
-
- (* --- function body starts here --- *)
- CONFIG <- __Parse args defaultConfig
-
diff --git a/Jennisys/Jennisys/Parser.fsy b/Jennisys/Jennisys/Parser.fsy
deleted file mode 100644
index de8e1fb8..00000000
--- a/Jennisys/Jennisys/Parser.fsy
+++ /dev/null
@@ -1,214 +0,0 @@
-%{
-
-open Ast
-open Getters
-open AstUtils
-
-let rec MyFold ee acc =
- match ee with
- | [] -> acc
- | x::rest -> BinaryAnd x (MyFold rest acc)
-
-%}
-
-// The start token becomes a parser function in the compiled code:
-%start start
-
-// These are the terminal tokens of the grammar along with the types of
-// the data carried by each token:
-%token <string> ID
-%token <int> INTEGER
-%token DOT
-%token NOT
-%token STAR DIV MOD
-%token PLUS MINUS
-%token OLD
-%token DOTDOT DOTDOTDOT
-%token EQ NEQ LESS ATMOST ATLEAST GREATER IN NOTIN
-%token AND OR
-%token IMPLIES
-%token IFF
-%token LPAREN RPAREN LBRACKET RBRACKET LCURLY RCURLY VERTBAR
-%token GETS COLON COLONCOLON COMMA QMARK
-%token INTERFACE DATAMODEL CODE
-%token VAR CONSTRUCTOR METHOD FRAME INVARIANT RETURNS REQUIRES ENSURES FORALL
-%token INTTYPE BOOLTYPE SEQTYPE SETTYPE
-%token EOF
-
-// This is the type of the data produced by a successful reduction of the 'start'
-// symbol:
-%type < Ast.SyntacticProgram > start
-
-%%
-
-// These are the rules of the grammar along with the F# code of the
-// actions executed as rules are reduced. In this case the actions
-// produce data using F# data construction terms.
-start: TopLevelDecls EOF { SProgram($1) }
-
-TopLevelDecls:
- | { [] }
- | TopLevelDecl TopLevelDecls { $1 :: $2 }
-
-TopLevelDecl:
- | INTERFACE ID TypeParams LCURLY Members RCURLY { Interface($2, $3, $5) }
- | DATAMODEL ID TypeParams LCURLY FrameMembers RCURLY { match $5 with (vv,fr,inv) -> DataModel($2, $3, vv, fr, inv) }
- | CODE ID TypeParams LCURLY RCURLY { Code($2, $3) }
-
-TypeParams:
- | { [] }
- | LBRACKET IdList RBRACKET { $2 }
-
-IdList:
- | ID { [$1] }
- | ID IdList { $1 :: $2 }
-
-Members:
- | { [] }
- | Member Members { $1 :: $2 }
-
-Signature:
- | LPAREN VarDeclList RPAREN { Sig($2, []) }
- | LPAREN VarDeclList RPAREN RETURNS LPAREN VarDeclList RPAREN { Sig($2, $6) }
-
-Pre:
- | { TrueLiteral }
- | REQUIRES Expr Pre { BinaryAnd $2 $3 }
-
-Post:
- | { TrueLiteral }
- | ENSURES Expr Post { BinaryAnd $2 $3 }
- | ID GETS Expr Post { BinaryAnd (BinaryExpr(40,"=",IdLiteral($1),$3)) $4 }
-
-StmtList:
- | { [] }
- | Stmt StmtList { $1 :: $2 }
-
-Stmt:
- | BlockStmt { $1 }
- | Expr GETS Expr { Assign($1, $3) }
-
-BlockStmt:
- | LCURLY StmtList RCURLY { Block $2 }
-
-Member:
- | VAR VarDecl { Field($2) }
- | CONSTRUCTOR ID Signature Pre Post { Method($2, $3, RewriteVars (GetSigVars $3) $4, RewriteVars (GetSigVars $3) $5, true) }
- | METHOD ID Signature Pre Post { Method($2, $3, RewriteVars (GetSigVars $3) $4, RewriteVars (GetSigVars $3) $5, false) }
- | INVARIANT ExprList { Invariant($2) }
-
-FrameMembers:
- | { [], [], TrueLiteral }
- | VAR VarDecl FrameMembers { match $3 with (vv,fr,inv) -> $2 :: vv, fr, inv }
- | FRAME FrameMembers { $2 }
- | FRAME FramePartitionList FrameMembers { match $3 with (vv,fr,inv) -> vv, List.append $2 fr, inv }
- | INVARIANT ExprList FrameMembers { match $3 with (vv,fr,inv) -> vv, fr, MyFold $2 inv }
-
-FramePartitionList:
- | FramePartition { $1 }
- | FramePartition FramePartitionList { List.append $1 $2 }
-
-VarDeclList:
- | { [] }
- | VarDecl { [$1] }
- | VarDecl COMMA VarDeclList { $1 :: $3 }
-
-VarDecl:
- | ID { Var($1,None, false) }
- | ID COLON Type { Var($1,Some($3), false) }
-
-Type:
- | INTTYPE { IntType }
- | BOOLTYPE { BoolType }
- | ID { NamedType($1, []) }
- | SEQTYPE LBRACKET Type RBRACKET { SeqType($3) }
- | SETTYPE LBRACKET Type RBRACKET { SetType($3) }
- | ID LBRACKET Type RBRACKET { InstantiatedType($1, [$3]) }
-
-ExprList:
- | { [] }
- | Expr { [$1] }
- | Expr ExprList { $1 :: $2 }
-
-Expr:
- | Expr10 { $1 }
-
-Expr10:
- | Expr20 { $1 }
- | Expr10 IFF Expr20 { BinaryExpr(10,"<==>",$1,$3) }
-
-Expr20:
- | Expr25 { $1 }
- | Expr25 IMPLIES Expr20 { BinaryExpr(20,"==>",$1,$3) }
-
-Expr25:
- | Expr30 { $1 }
- | Expr30 QMARK Expr25 COLON Expr25 { IteExpr($1,$3,$5) }
-Expr30:
- | Expr40 { $1 }
- | Expr40 AND Expr30and { BinaryAnd $1 $3 }
- | Expr40 OR Expr30or { BinaryOr $1 $3 }
-Expr30and:
- | Expr40 { $1 }
- | Expr40 AND Expr30and { BinaryAnd $1 $3 }
-Expr30or:
- | Expr40 { $1 }
- | Expr40 AND Expr30or { BinaryOr $1 $3 }
-
-Expr40:
- | Expr50 { $1 }
- | Expr50 EQ Expr50 { BinaryExpr(40,"=",$1,$3) }
- | Expr50 NEQ Expr50 { BinaryExpr(40,"!=",$1,$3) }
- | Expr50 LESS Expr50 { BinaryExpr(40,"<",$1,$3) }
- | Expr50 ATMOST Expr50 { BinaryExpr(40,"<=",$1,$3) }
- | Expr50 ATLEAST Expr50 { BinaryExpr(40,">=",$1,$3) }
- | Expr50 GREATER Expr50 { BinaryExpr(40,">",$1,$3) }
- | Expr50 IN Expr50 { BinaryExpr(40,"in",$1,$3) }
- | Expr50 NOTIN Expr50 { BinaryExpr(40,"!in",$1,$3) }
-
-Expr50:
- | Expr55 { $1 }
- | Expr55 DOTDOTDOT Expr55 { BinaryExpr(50,"...",$1,$3) }
-
-Expr55:
- | Expr60 { $1 }
- | Expr55 PLUS Expr60 { BinaryExpr(55,"+",$1,$3) }
- | Expr55 MINUS Expr60 { BinaryExpr(55,"-",$1,$3) }
-
-Expr60:
- | Expr90 { $1 }
- | Expr60 STAR Expr90 { BinaryExpr(60,"*",$1,$3) }
- | Expr60 DIV Expr90 { BinaryExpr(60,"div",$1,$3) }
- | Expr60 MOD Expr90 { BinaryExpr(60,"mod",$1,$3) }
-
-Expr90:
- | Expr100 { $1 }
- | OLD LPAREN Expr90 RPAREN { OldExpr($3) }
- | NOT Expr90 { UnaryExpr("!", $2) }
- | MINUS Expr90 { UnaryExpr("-", $2) }
- | Expr90 DOTDOT { LCIntervalExpr($1) }
-
-Expr100:
- | INTEGER { IntLiteral($1) }
- | ID { if $1 = "this" then
- ObjLiteral("this")
- elif $1 = "null" then
- ObjLiteral("null")
- else
- IdLiteral($1) }
- | Expr100 DOT ID { Dot($1, $3) }
- | Expr100 LBRACKET StarExpr RBRACKET { SelectExpr($1, $3) }
- | Expr100 LBRACKET Expr GETS Expr RBRACKET { UpdateExpr($1, $3, $5) }
- | LPAREN Expr RPAREN { $2 }
- | LBRACKET ExprList RBRACKET { SequenceExpr($2) }
- | LCURLY ExprList RCURLY { SetExpr($2) }
- | VERTBAR Expr VERTBAR { SeqLength($2) }
- | FORALL VarDeclList COLONCOLON Expr { ForallExpr($2, RewriteVars $2 $4) }
-
-StarExpr:
- | STAR { Star }
- | Expr { $1 }
-
-FramePartition:
- | Expr100 { [$1] }
- | Expr100 STAR FramePartition { $1 :: $3 }
diff --git a/Jennisys/Jennisys/PipelineUtils.fs b/Jennisys/Jennisys/PipelineUtils.fs
deleted file mode 100644
index a87d442f..00000000
--- a/Jennisys/Jennisys/PipelineUtils.fs
+++ /dev/null
@@ -1,63 +0,0 @@
-// ####################################################################
-/// Utility functions for executing shell commands and
-/// running Dafny in particular
-///
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// ####################################################################
-
-module PipelineUtils
-
-open Logger
-
-let dafnyScratchSuffix = "scratch"
-let dafnyVerifySuffix = "verify"
-let dafnyUnifSuffix = "unif"
-let dafnySynthFileNameTemplate = @"c:\tmp\jennisys-synth_###.dfy"
-let dafnyModularSynthFileNameTemplate = @"c:\tmp\jennisys-synth_###_mod.dfy"
-
-let mutable lastDafnyExitCode = 0 //TODO: how to avoid this muttable state?
-
-let CreateEmptyModelFile modelFile =
- use mfile = System.IO.File.CreateText(modelFile)
- fprintf mfile ""
-
-// =======================================================
-/// Runs Dafny on the given "inputFile" and prints
-/// the resulting model to the given "modelFile"
-// =======================================================
-let RunDafny inputFile modelFile =
- //TraceLine "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Running Dafny @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
- CreateEmptyModelFile modelFile
- async {
- use proc = new System.Diagnostics.Process()
- proc.StartInfo.FileName <- @"c:\tmp\StartDafny-jen.bat"
- proc.StartInfo.Arguments <- (sprintf "/mv:%s /timeLimit:%d %s" modelFile Options.CONFIG.timeout inputFile)
- proc.StartInfo.WindowStyle <- System.Diagnostics.ProcessWindowStyle.Hidden
- assert proc.Start()
- proc.WaitForExit()
- lastDafnyExitCode <- proc.ExitCode
- } |> Async.RunSynchronously
-
-// =======================================================
-/// Runs Dafny on the given "dafnyCode" and returns models
-// =======================================================
-let RunDafnyProgram dafnyProgram suffix =
- let inFileName = @"c:\tmp\jennisys-" + suffix + ".dfy"
- let modelFileName = @"c:\tmp\jennisys-" + suffix + ".bvd"
- use file = System.IO.File.CreateText(inFileName)
- file.AutoFlush <- true
- fprintfn file "%s" dafnyProgram
- file.Close()
- // run Dafny
- RunDafny inFileName modelFileName
- // read models from the model file
- use modelFile = System.IO.File.OpenText(modelFileName)
- Microsoft.Boogie.Model.ParseModels modelFile
-
-// =======================================================
-/// Checks whether the given dafny program verifies
-// =======================================================
-let CheckDafnyProgram dafnyProgram suffix =
- let models = RunDafnyProgram dafnyProgram suffix
- // if there are no models, verification was successful
- lastDafnyExitCode = 0 && models.Count = 0
diff --git a/Jennisys/Jennisys/PrintUtils.fs b/Jennisys/Jennisys/PrintUtils.fs
deleted file mode 100644
index 138b5e77..00000000
--- a/Jennisys/Jennisys/PrintUtils.fs
+++ /dev/null
@@ -1,12 +0,0 @@
-module PrintUtils
-
-let newline = System.Environment.NewLine // "\r\n"
-
-let rec Indent i =
- if i = 0 then "" else " " + (Indent (i-1))
-
-let rec PrintSep sep f list =
- match list with
- | [] -> ""
- | [a] -> f a
- | a :: more -> (f a) + sep + (PrintSep sep f more) \ No newline at end of file
diff --git a/Jennisys/Jennisys/Printer.fs b/Jennisys/Jennisys/Printer.fs
deleted file mode 100644
index 32ae21ac..00000000
--- a/Jennisys/Jennisys/Printer.fs
+++ /dev/null
@@ -1,156 +0,0 @@
-module Printer
-
-open Ast
-open Getters
-open AstUtils
-open PrintUtils
-
-let rec PrintType ty =
- match ty with
- | IntType -> "int"
- | BoolType -> "bool"
- | NamedType(id, args) -> if List.isEmpty args then id else (PrintSep ", " (fun s -> s) args)
- | SeqType(t) -> sprintf "seq[%s]" (PrintType t)
- | SetType(t) -> sprintf "set[%s]" (PrintType t)
- | InstantiatedType(id,args) -> sprintf "%s[%s]" id (PrintSep ", " (fun a -> PrintType a) args)
-
-let PrintVarDecl vd =
- let name = GetExtVarName vd
- match GetVarType vd with
- | None -> name
- | Some(ty) -> sprintf "%s: %s" name (PrintType ty)
-
-let rec PrintExpr ctx expr =
- match expr with
- | IntLiteral(d) -> sprintf "%d" d
- | BoolLiteral(b) -> sprintf "%b" b
- | BoxLiteral(id) -> sprintf "box_%s" id
- | ObjLiteral(id)
- | VarLiteral(id)
- | IdLiteral(id) -> id
- | VarDeclExpr(vlist, declare) ->
- let decl = if declare then "var " else ""
- let vars = PrintSep ", " PrintVarDecl vlist
- sprintf "%s%s" decl vars
- | Star -> "*"
- | Dot(e,id) -> sprintf "%s.%s" (PrintExpr 100 e) id
- | LCIntervalExpr(e) -> sprintf "%s.." (PrintExpr 90 e)
- | OldExpr(e) -> sprintf "old(%s)" (PrintExpr 90 e)
- | UnaryExpr(op,UnaryExpr(op2, e2)) -> sprintf "%s(%s)" op (PrintExpr 90 (UnaryExpr(op2, e2)))
- | UnaryExpr(op,e) -> sprintf "%s%s" op (PrintExpr 90 e)
- | BinaryExpr(strength,op,e0,e1) ->
- let needParens = strength <= ctx
- let openParen = if needParens then "(" else ""
- let closeParen = if needParens then ")" else ""
- sprintf "%s%s %s %s%s" openParen (PrintExpr strength e0) op (PrintExpr strength e1) closeParen
- | IteExpr(c,e1,e2) -> sprintf "%s ? %s : %s" (PrintExpr 25 c) (PrintExpr 25 e1) (PrintExpr 25 e2)
- | SelectExpr(e,i) -> sprintf "%s[%s]" (PrintExpr 100 e) (PrintExpr 0 i)
- | UpdateExpr(e,i,v) -> sprintf "%s[%s := %s]" (PrintExpr 100 e) (PrintExpr 0 i) (PrintExpr 0 v)
- | SequenceExpr(ee) -> sprintf "[%s]" (ee |> PrintSep " " (PrintExpr 0))
- | SeqLength(e) -> sprintf "|%s|" (PrintExpr 0 e)
- | SetExpr(ee) -> sprintf "{%s}" (ee |> PrintSep " " (PrintExpr 0))
- | AssertExpr(e) -> sprintf "assert %s" (PrintExpr 0 e)
- | AssumeExpr(e) -> sprintf "assume %s" (PrintExpr 0 e)
- | ForallExpr(vv,e) ->
- let needParens = ctx <> 0
- let openParen = if needParens then "(" else ""
- let closeParen = if needParens then ")" else ""
- sprintf "%sforall %s :: %s%s" openParen (vv |> PrintSep ", " PrintVarDecl) (PrintExpr 0 e) closeParen
- | MethodCall(rcv,_,name,aparams) ->
- sprintf "%s.%s(%s)" (PrintExpr 0 rcv) name (aparams |> PrintSep ", " (PrintExpr 0))
- | MethodOutSelect(mth,name) ->
- sprintf "%s[\"%s\"]" (PrintExpr 0 mth) name
-
-let rec PrintConst cst =
- match cst with
- | IntConst(v) -> sprintf "%d" v
- | BoolConst(b) -> sprintf "%b" b
- | BoxConst(id) -> sprintf "box_%s" id
- | VarConst(v) -> sprintf "%s" v
- | SetConst(cset) -> sprintf "{%s}" (PrintSep " " (fun c -> PrintConst c) (Set.toList cset))
- | SeqConst(cseq) -> sprintf "[%s]" (PrintSep " " (fun c -> PrintConst c) cseq)
- | NullConst -> "null"
- | NoneConst -> "<none>"
- | ThisConst(_,_) -> "this"
- | NewObj(name,_) -> PrintGenSym name
- | Unresolved(name) -> sprintf "Unresolved(%s)" name
-
-let PrintSig signature =
- match signature with
- | Sig(ins, outs) ->
- let returnClause =
- if outs <> [] then sprintf " returns (%s)" (outs |> PrintSep ", " PrintVarDecl)
- else ""
- sprintf "(%s)%s" (ins |> PrintSep ", " PrintVarDecl) returnClause
-
-let rec PrintStmt stmt indent printNewline =
- let idt = (Indent indent)
- let nl = if printNewline then newline else ""
- match stmt with
- | Block(stmts) ->
- idt + "{" + nl +
- (PrintStmtList stmts (indent + 2) true) +
- idt + "}" + nl
- | Assign(lhs,rhs) -> sprintf "%s%s := %s%s" idt (PrintExpr 0 lhs) (PrintExpr 0 rhs) nl
- | ExprStmt(expr) -> sprintf "%s%s%s" idt (PrintExpr 0 expr) nl
-and PrintStmtList stmts indent printNewline =
- stmts |> List.fold (fun acc s -> acc + (PrintStmt s indent printNewline)) ""
-
-let PrintRoutine signature pre body =
- let preStr = pre |> ForeachConjunct (fun e -> sprintf " requires %s%s" (PrintExpr 0 e) newline)
- sprintf "%s%s%s%s" (PrintSig signature) newline preStr (PrintExpr 0 body)
-
-let PrintMember m =
- match m with
- | Field(vd) -> sprintf " var %s%s" (PrintVarDecl vd) newline
- | Method(id,signature,pre,body,true) -> sprintf " constructor %s%s" id (PrintRoutine signature pre body)
- | Method(id,signature,pre,body,false) -> sprintf " method %s%s" id (PrintRoutine signature pre body)
- | Invariant(_) -> "" // invariants are handled separately
-
-let PrintTopLevelDeclHeader kind id typeParams =
- let typeParamStr =
- match typeParams with
- | [] -> ""
- | _ -> sprintf "[%s]" (typeParams |> PrintSep ", " (fun tp -> tp))
- sprintf "%s %s%s {%s" kind id typeParamStr newline
-
-let PrintDecl d =
- match d with
- | Interface(id,typeParams,members) ->
- sprintf "%s%s}%s" (PrintTopLevelDeclHeader "interface" id typeParams)
- (List.fold (fun acc m -> acc + (PrintMember m)) "" members)
- newline
- | DataModel(id,typeParams,vars,frame,inv) ->
- (PrintTopLevelDeclHeader "model" id typeParams) +
- (vars |> List.fold (fun acc vd -> acc + " var " + (PrintVarDecl vd) + newline) "") +
- " frame" + newline +
- (frame |> List.fold (fun acc fr -> acc + " " + (PrintExpr 0 fr) + newline) "") +
- " invariant" + newline +
- (inv |> ForeachConjunct (fun e -> " " + (PrintExpr 0 e) + newline)) +
- "}" + newline
- | Code(id,typeParams) ->
- (PrintTopLevelDeclHeader "code" id typeParams) + "}" + newline
-
-let PrintMethodSignFull indent comp m =
- let idt = Indent indent
- let __PrintPrePost pfix expr = SplitIntoConjunts expr |> PrintSep newline (fun e -> pfix + (PrintExpr 0 e) + ";")
- let compName = GetComponentName comp
- match m with
- | Method(methodName, sgn, pre, post, isConstr) ->
- let mc = if isConstr then "constructor" else "method"
- let preStr = (__PrintPrePost (idt + " requires ") pre)
- let postStr = (__PrintPrePost (idt + " ensures ") post)
- idt + mc + " " + compName + "." + methodName + (PrintSig sgn) + newline +
- preStr + (if preStr = "" then "" else newline) +
- postStr
- | _ -> failwithf "not a method: %O" m
-
-let Print prog =
- match prog with
- | SProgram(decls) -> List.fold (fun acc d -> acc + (PrintDecl d)) "" decls
-
-let PrintObjRefName o =
- match o with
- | ThisConst(_,_) -> "this";
- | NewObj(name, _) -> PrintGenSym name
- | _ -> failwith ("unresolved object ref: " + o.ToString()) \ No newline at end of file
diff --git a/Jennisys/Jennisys/README.txt b/Jennisys/Jennisys/README.txt
deleted file mode 100644
index 30f91b2e..00000000
--- a/Jennisys/Jennisys/README.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-1. Installation instructions
-----------------------------
-
- - download the entire boogie source distribution and place it in c:\boogie
- - create c:\tmp folder
- - copy the Jennisys\scripts\StartDafny-jen.bat script into c:\tmp
-
-2. Running the examples
-----------------------------
-
- $ cd Jennisys
- $ bin/Debug/Jennisys.exe examples/<name>.jen
-
- The most current and complete set of examples is in the
- "examples/oopsla12" folder. No additional Jennisys switches need be
- passed for either of them.
-
- Synthesized programs will be generated in "c:\tmp", and their file
- names will follow the following pattern:
-
- "jennisys-synth_<example-name>.dfy"
-
- To verify the correctness of the synthesized programs, run
-
- $ Dafny /compile:0 jennisys-synth_<example-name>.dfy
-
- Expected outputs (i.e., synthesized Dafny programs) for the examples
- in "examples/oopsla12" can be found in the same folder.
diff --git a/Jennisys/Jennisys/Resolver.fs b/Jennisys/Jennisys/Resolver.fs
deleted file mode 100644
index bc330520..00000000
--- a/Jennisys/Jennisys/Resolver.fs
+++ /dev/null
@@ -1,380 +0,0 @@
-// ####################################################################
-/// Utilities for resolving the "Unresolved" constants with respect to
-/// a given context (heap/env/ctx)
-///
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// ####################################################################
-
-module Resolver
-
-open Ast
-open Getters
-open AstUtils
-open Printer
-open EnvUtils
-open DafnyModelUtils
-
-type Obj = { name: string; objType: Type }
-
-type AssignmentType =
- | FieldAssignment of (Obj * VarDecl) * Expr // the first string is the symbolic name of an object literal
- | ArbitraryStatement of Stmt
-
-type HeapInstance = {
- objs : Map<string, Obj>;
- modifiableObjs : Set<Obj>;
- assignments : AssignmentType list;
- concreteValues : AssignmentType list;
- methodArgs : Map<string, Const>;
- methodRetVals : Map<string, Expr>;
- concreteMethodRetVals : Map<string, Expr>;
- globals : Map<string, Expr>;
-}
-
-let NoObj = { name = ""; objType = NamedType("", []) }
-let ThisObj comp = {name = "this"; objType = GetComponentType comp}
-
-let ExtractAllExpressions asg =
- match asg with
- | FieldAssignment(_,e) -> [e]
- | ArbitraryStatement(s) -> ExtractTopLevelExpressions s
-
-// use the orginal method, not the one with an extra precondition
-let FixSolution origComp origMeth sol =
- sol |> Map.fold (fun acc (cc,mm) v ->
- if CheckSameMethods (cc,mm) (origComp,origMeth) then
- acc |> Map.add (origComp,origMeth) v
- else
- acc |> Map.add (cc,mm) v) Map.empty
-
-let ConvertToStatements heapInst onModifiableObjsOnly =
- let stmtLst1 = heapInst.assignments |> List.choose (fun asgn ->
- match asgn with
- | FieldAssignment((o,f),e) when (not onModifiableObjsOnly || Set.contains o heapInst.modifiableObjs) ->
- if IsOldVar f then
- None
- else
- let fldName = GetVarName f
- if fldName = "" then
- Some(ExprStmt(e))
- else
- Some(Assign(Dot(ObjLiteral(o.name), fldName), e))
- | ArbitraryStatement(stmt) -> Some(stmt)
- | _ -> None)
- let stmtLst2 = heapInst.methodRetVals |> Map.toList
- |> List.map (fun (retVarName, retVarVal) -> Assign(VarLiteral(retVarName), retVarVal))
- stmtLst1 @ stmtLst2
-
-// resolving values
-exception ConstResolveFailed of string
-
-// ================================================================
-/// Resolves a given Const (cst) with respect to a given env/ctx.
-///
-/// If unable to resolve, it just delegates the task to the
-/// failResolver function
-// ================================================================
-let rec ResolveCont hModel failResolver cst =
- match cst with
- | Unresolved(_) as u ->
- // see if it is in the env map first
- let envVal = Map.tryFind cst hModel.env
- match envVal with
- | Some(c) -> ResolveCont hModel failResolver c
- | None ->
- // not found in the env map --> check the equality sets
- let eq = hModel.ctx |> Set.filter (fun eqSet -> Set.contains u eqSet)
- |> Utils.SetToOption
- match eq with
- | Some(eqSet) ->
- let cOpt = eqSet |> Set.filter (function Unresolved(_) -> false | _ -> true)
- |> Utils.SetToOption
- match cOpt with
- | Some(c) -> c
- | _ -> failResolver cst hModel
- | None ->
- failResolver cst hModel
-// // finally, see if it's an *input* (have no way of telling input from output params here) method argument
-// let m = hModel.env |> Map.filter (fun k v -> v = u && match k with VarConst(name) -> true | _ -> false) |> Map.toList
-// match m with
-// | (vc,_) :: [] -> vc
-// | _ -> failResolver cst hModel
- | SeqConst(cseq) ->
- let resolvedLst = cseq |> List.rev |> List.fold (fun acc c -> ResolveCont hModel failResolver c :: acc) []
- SeqConst(resolvedLst)
- | SetConst(cset) ->
- let resolvedSet = cset |> Set.fold (fun acc c -> acc |> Set.add (ResolveCont hModel failResolver c)) Set.empty
- SetConst(resolvedSet)
- | _ -> cst
-
-// =====================================================================
-/// Tries to resolve a given Const (cst) with respect to a given env/ctx.
-///
-/// If unable to resolve, just returns the original Unresolved const.
-// =====================================================================
-let TryResolve hModel cst =
- ResolveCont hModel (fun c _ -> c) cst
-
-// ==============================================================
-/// Resolves a given Const (cst) with respect to a given env/ctx.
-///
-/// If unable to resolve, raises a ConstResolveFailed exception
-// ==============================================================
-let Resolve hModel cst =
- ResolveCont hModel (fun c _ ->
- match c with
- | Unresolved(id) -> BoxConst(id)
- | _ -> failwithf "internal error: expected Unresolved but got %O" c
- ) cst //fun c _ -> raise (ConstResolveFailed("failed to resolve " + c.ToString()))
-
-// ==================================================================
-/// Evaluates a given expression with respect to a given heap instance
-// ==================================================================
-
-let rec _EvalResolver heapInst useConcrete resolveExprFunc expr fldNameOpt =
- let rec __FurtherResolve expr =
- match expr with
- | SetExpr(elist) -> SetExpr(elist |> List.map __FurtherResolve)
- | SequenceExpr(elist) -> SequenceExpr(elist |> List.map __FurtherResolve)
- | VarLiteral(_) ->
- try
- _EvalResolver heapInst useConcrete resolveExprFunc expr None
- with
- | _ -> expr
- | IdLiteral(id) when not (id = "this" || id = "null") ->
- try
- _EvalResolver heapInst useConcrete resolveExprFunc expr None
- with
- | _ -> expr
- | _ -> expr
-
- (* --- function body starts here --- *)
- let ex = match fldNameOpt with
- | None -> expr
- | Some(n) -> Dot(expr, n)
- if not (resolveExprFunc ex) then
- ex
- else
- match fldNameOpt with
- | None ->
- match expr with
- | ObjLiteral("this") | ObjLiteral("null") -> expr
- | IdLiteral("this") | IdLiteral("null") -> failwith "should never happen anymore" //TODO
- | VarLiteral(id) ->
- match heapInst.methodArgs |> Map.tryFind id with
- | Some(argValue) -> argValue |> Const2Expr
- | None ->
- let retVals = if useConcrete then heapInst.concreteMethodRetVals else heapInst.methodRetVals
- match retVals |> Map.tryFind id with
- | Some(e) -> e |> __FurtherResolve
- | None -> raise (EvalFailed("cannot find value for method parameter " + id))
- | IdLiteral(id) ->
- let globalVal = heapInst.globals |> Map.tryFind id
- match globalVal with
- | Some(e) -> e
- | None -> _EvalResolver heapInst useConcrete resolveExprFunc ThisLiteral (Some(id))
- | _ -> raise (EvalFailed(sprintf "I'm not supposed to resolve %O" expr))
- | Some(fldName) ->
- match expr with
- | ObjLiteral(objName) ->
- let asgs = if useConcrete then heapInst.concreteValues else heapInst.assignments
- let h2 = asgs |> List.filter (function FieldAssignment((o, var), v) -> o.name = objName && GetExtVarName var = fldName | _ -> false)
- match h2 with
- | FieldAssignment((_,_),x) :: [] -> __FurtherResolve x
- | _ :: _ -> raise (EvalFailed(sprintf "can't evaluate expression deterministically: %s.%s resolves to multiple locations" objName fldName))
- | [] -> raise (EvalFailed(sprintf "can't find value for %s.%s" objName fldName)) // TODO: what if that value doesn't matter for the solution, and that's why it's not present in the model???
- | _ -> Dot(expr, fldName)
-
-let _Eval heapInst resolveExprFunc returnFunc expr =
- (* --- function body starts here --- *)
- //EvalSym (__EvalResolver resolveExprFunc) expr
- EvalSymRet (_EvalResolver heapInst false resolveExprFunc) returnFunc expr
-
-/// Resolves nothing
-let EvalNone heapInst expr =
- EvalSym (_EvalResolver heapInst false (fun e -> false)) expr
-
-let fullResolver heapInst = _EvalResolver heapInst true (fun e -> true)
-
-/// Resolves everything
-let EvalFull heapInst expr =
- EvalSym (fullResolver heapInst) expr
- //_Eval heapInst (fun _ -> true) (fun e -> e) expr
-
-let Eval heapInst resolveExprFunc expr =
- let returnFunc = fun expr -> match expr with IdLiteral(id) -> Dot(ThisLiteral, id) | _ -> expr
- EvalSymRet (fullResolver heapInst) (_EvalResolver heapInst false resolveExprFunc) returnFunc expr
-
-let EvalAndCheckTrue heapInst resolveExprFunc expr =
- let returnFunc = fun expr ->
- let expr =
- match expr with
- //| IteExpr(c,t,e) ->
- // let cond = c |> EvalFull heapInst |> Expr2Bool
- // if cond then t else e
- //| ForallExpr(vars, sub) -> expr
- // TODO: this is just to ensure that all field accesses to this object are prefixed with "this."
- // this is not the best place to do it, though
- | IdLiteral(id) -> Dot(ThisLiteral, id)
- | _ -> expr
-
- // TODO: infer type of expr and then re-execute only if its type is Bool
- let e1 = EvalFull heapInst expr //EvalSym (_EvalResolver heapInst true (fun _ -> true)) expr
- match e1 with
- | BoolLiteral(b) ->
- if b then
- expr
- else
- FalseLiteral
- //UnaryNot expr
- | _ -> expr
- EvalSymRet (fullResolver heapInst) (_EvalResolver heapInst false resolveExprFunc) returnFunc expr
- //_Eval heapInst resolveExprFunc returnFunc expr
-
-// =====================================================================
-/// Takes an unresolved model of the heap (HeapModel), resolves all
-/// references in the model and returns an instance of the heap
-/// (HeapInstance), where all fields for all objects have explicit
-/// assignments.
-// =====================================================================
-let ResolveModel hModel (comp,meth) =
- let outArgs = GetMethodOutArgs meth
- let hmap = hModel.heap |> Map.fold (fun acc (o,f) l ->
- let objName, objTypeOpt = match Resolve hModel o with
- | ThisConst(_,t) -> "this", t;
- | NewObj(name, t) -> PrintGenSym name, t
- | _ -> failwith ("unresolved object ref: " + o.ToString())
- let objType = objTypeOpt |> Utils.ExtractOptionMsg "unknown object type"
- let obj = {name = objName; objType = objType}
- let value = TryResolve hModel l |> Const2Expr
- Utils.ListMapAdd (obj, f) value acc
- ) []
- |> List.map (fun el -> FieldAssignment(el))
- let objs, modObjs = hmap |> List.fold (fun (acc1,acc2) asgn ->
- match asgn with
- | FieldAssignment((obj,_),_) ->
- let acc1' = acc1 |> Map.add obj.name obj
- let acc2' =
- if IsModifiableObj obj (comp,meth) then
- acc2 |> Set.add obj
- else
- acc2
- acc1',acc2'
- | _ -> acc1,acc2
- ) (Map.empty, Set.empty)
- let argmap, retvals = hModel.env |> Map.fold (fun (acc1,acc2) k v ->
- match k with
- | VarConst(name) ->
- let resolvedValExpr = Resolve hModel v
- if outArgs |> List.exists (fun var -> GetVarName var = name) then
- acc1, acc2 |> Map.add name (resolvedValExpr |> Const2Expr)
- else
- acc1 |> Map.add name resolvedValExpr, acc2
- | _ -> acc1, acc2
- ) (Map.empty, Map.empty)
- { objs = objs;
- modifiableObjs = modObjs;
- assignments = hmap;
- concreteValues = hmap;
- methodArgs = argmap;
- methodRetVals = retvals;
- concreteMethodRetVals = retvals;
- globals = Map.empty }
-
-let rec GetCallGraph solutions graph =
- let rec __SearchExprsForMethodCalls elist acc =
- match elist with
- | e :: rest ->
- match e with
- // no need to descend for, just check if the top-level one is MEthodCall
- | MethodCall(_,cname,mname,_) -> __SearchExprsForMethodCalls rest (acc |> Set.add (cname,mname))
- | _ -> __SearchExprsForMethodCalls rest acc
- | [] -> acc
- match solutions with
- | ((comp,m), sol) :: rest ->
- let callees = sol |> List.fold (fun acc (cond, hInst) ->
- hInst.assignments |> List.fold (fun acc asgn ->
- match asgn with
- | FieldAssignment(_,e) ->
- __SearchExprsForMethodCalls [e] acc
- | ArbitraryStatement(stmt) ->
- let exprs = ExtractTopLevelExpressions stmt
- __SearchExprsForMethodCalls exprs acc
- ) acc
- ) Set.empty
- let graph' = graph |> Map.add (comp,m) callees
- GetCallGraph rest graph'
- | [] -> graph
-
-//////////////////////////////
-
-//TODO: below here should really go to a different module
-
-let __Is1stLevelExpr methodsOk heapInst expr =
- DescendExpr2 (fun expr acc ->
- if not acc then
- false
- else
- match expr with
- | Dot(discr, fldName) ->
- try
- let obj = EvalFull heapInst discr
- match obj with
- | ObjLiteral(id) -> id = "this"
- | _ -> failwithf "Didn't expect the discriminator of a Dot to not be ObjLiteral"
- with
- | _ -> false
- | MethodCall(_) -> methodsOk
- | _ -> true
- ) expr true
-
-let Is1stLevelExpr = __Is1stLevelExpr true
-
-let IsSolution1stLevelOnly heapInst =
- let rec __IsSol1stLevel stmts =
- match stmts with
- | stmt :: rest ->
- match stmt with
- | Assign(_, e)
- | ExprStmt(e) ->
- let ok = Is1stLevelExpr heapInst e
- ok && __IsSol1stLevel rest
- | Block(stmts) -> __IsSol1stLevel (stmts @ rest)
- | [] -> true
- (* --- function body starts here --- *)
- __IsSol1stLevel (ConvertToStatements heapInst true)
-
-let IsRecursiveSol (c,m) sol =
- let compName = GetComponentName c
- let methName = GetMethodName m
- let allAssignments = sol |> List.map (fun (_,hInst) -> hInst.assignments) |> List.concat
- let allExprs = (allAssignments |> List.map ExtractAllExpressions |> List.concat) @
- (sol |> List.map (fun (_,hInst) -> hInst.methodRetVals |> Map.toList |> List.map snd) |> List.concat)
- let singleExpr = allExprs |> List.fold BinaryAnd TrueLiteral
- DescendExpr2 (fun expr acc ->
- if acc then
- true
- else
- match expr with
- | MethodCall(_, cn, mn, elst) when cn = compName && mn = methName ->
- true
- | _ -> false
- ) singleExpr false
-
-/// Returns a list of direct modifiable children objects with respect to "this" object
-///
-/// All returned expressions are of type ObjLiteral
-///
-/// ensures: forall e :: e in ret ==> e is ObjInstance
-let GetDirectModifiableChildren hInst =
- let rec __AddDirectChildren e acc =
- match e with
- | ObjLiteral(_) when not (e = ThisLiteral || e = NullLiteral) -> acc |> Set.add e
- | SequenceExpr(elist)
- | SetExpr(elist) -> elist |> List.fold (fun acc2 e2 -> __AddDirectChildren e2 acc2) acc
- | _ -> acc
-
- (* --- function body starts here --- *)
- let thisRhsExprs = hInst.assignments |> List.choose (function FieldAssignment((obj,_),e) when obj.name = "this" && Set.contains obj hInst.modifiableObjs -> Some(e) | _ -> None)
- thisRhsExprs |> List.fold (fun acc e -> __AddDirectChildren e acc) Set.empty
- |> Set.toList
diff --git a/Jennisys/Jennisys/SymGen.fs b/Jennisys/Jennisys/SymGen.fs
deleted file mode 100644
index b736ef31..00000000
--- a/Jennisys/Jennisys/SymGen.fs
+++ /dev/null
@@ -1,9 +0,0 @@
-module SymGen
-
-let incr =
- let counter = ref 0
- fun () ->
- counter := !counter + 1
- !counter
-
-let NewSymFake expr = sprintf "x_%d" (incr()) \ No newline at end of file
diff --git a/Jennisys/Jennisys/TypeChecker.fs b/Jennisys/Jennisys/TypeChecker.fs
deleted file mode 100644
index cef88072..00000000
--- a/Jennisys/Jennisys/TypeChecker.fs
+++ /dev/null
@@ -1,67 +0,0 @@
-module TypeChecker
-
-open Ast
-open Getters
-open AstUtils
-open Printer
-open System.Collections.Generic
-
-let GetClass name decls =
- match decls |> List.tryFind (function Interface(n,_,_) when n = name -> true | _ -> false) with
- | Some(cl) -> cl
- | None -> Interface(name,[],[])
-
-let GetModel name decls =
- match decls |> List.tryFind (function DataModel(n,_,_,_,_) when n = name -> true | _ -> false) with
- | Some(m) -> m
- | None -> DataModel(name,[],[],[],BoolLiteral(true))
-
-let GetCode name decls =
- match decls |> List.tryFind (function Code(n,_) when n = name -> true | _ -> false) with
- | Some(c) -> c
- | None -> Code(name,[])
-
-let IsUserType prog tpo =
- match tpo with
- | Some(tp) ->
- let tpname = match tp with
- | NamedType(tname,_) -> tname
- | InstantiatedType(tname, _) -> tname
- | _ -> ""
- match prog with
- | Program(components) -> components |> List.filter (function Component(Interface(name,_,_),_,_) when name = tpname -> true
- | _ -> false) |> List.isEmpty |> not
- | None -> false
-
-let TypeCheck prog =
- match prog with
- | SProgram(decls) ->
- let componentNames = decls |> List.choose (function Interface(name,_,_) -> Some(name) | _ -> None)
- let clist = componentNames |> List.map (fun name -> Component(GetClass name decls, GetModel name decls, GetCode name decls))
- Some(Program(clist))
-
-let MethodArgChecker prog meth varName =
- let ins = GetMethodInArgs meth
- let outs = GetMethodOutArgs meth
- ins @ outs |> List.choose (fun var -> if GetVarName var = varName then GetVarType var |> FindComponentForTypeOpt prog else None) |> Utils.ListToOption
-
-// TODO: implement this
-let rec InferType prog thisComp checkLocalFunc expr =
- let __FindVar comp fldName =
- let var = FindVar comp fldName |> Utils.ExtractOption
- let c = FindComponentForType prog (Utils.ExtractOption (GetVarType var)) |> Utils.ExtractOption
- Some(c)
-
- try
- match expr with
- | ObjLiteral("this") -> Some(thisComp)
- | ObjLiteral("null") -> None
- | IdLiteral(id) -> __FindVar thisComp id
- | VarLiteral(id) -> checkLocalFunc id
- | Dot(discr, fldName) ->
- match InferType prog thisComp checkLocalFunc discr with
- | Some(comp) -> __FindVar comp fldName
- | None -> None
- | _ -> None
- with
- | ex -> None \ No newline at end of file
diff --git a/Jennisys/Jennisys/Utils.fs b/Jennisys/Jennisys/Utils.fs
deleted file mode 100644
index 56b6b779..00000000
--- a/Jennisys/Jennisys/Utils.fs
+++ /dev/null
@@ -1,368 +0,0 @@
-// ####################################################################
-/// Various utility functions
-///
-/// author: Aleksandar Milicevic (t-alekm@microsoft.com)
-// ####################################################################
-
-module Utils
-
-// -------------------------------------------
-// ----------- collection util funcs ---------
-// -------------------------------------------
-
-// =====================================
-/// ensures: ret = b ? Some(b) : None
-// =====================================
-let BoolToOption b =
- if b then
- Some(b)
- else
- None
-
-// =====================================
-/// ensures: ret = (opt == Some(_))
-// =====================================
-let OptionToBool opt =
- match opt with
- | Some(_) -> true
- | None -> false
-
-// =====================================
-/// ensures: ret = (opt == Some(_))
-// =====================================
-let IsSomeOption opt =
- match opt with
- | Some(_) -> true
- | None -> false
-
-// =====================================
-/// ensures: ret = (opt == None)
-// =====================================
-let IsNoneOption opt = IsSomeOption opt |> not
-
-// =====================================
-/// requres: x = Some(a) or failswith msg
-/// ensures: ret = a
-// =====================================
-let ExtractOptionMsg msg x =
- match x with
- | Some(a) -> a
- | None -> failwith msg
-
-// ====================
-/// requres: x = Some(a)
-/// ensures: ret = a
-// ====================
-let ExtractOption x =
- ExtractOptionMsg "can't extract anything from a None" x
-
-// ====================================
-/// ensures: res = Some(a) ==> ret = a
-/// ensures: res = None ==> ret = defVal
-// ====================================
-let ExtractOptionOr defVal opt =
- match opt with
- | Some(a) -> a
- | None -> defVal
-
-// ==========================================================
-/// requres: List.length lst <= 1, otherwise fails with errMsg
-/// ensures: if |lst| = 0 then
-/// ret = None
-/// else
-/// ret = Some(lst[0])
-// ==========================================================
-let ListToOptionMsg lst errMsg =
- if List.length lst > 1 then
- failwith errMsg
- if List.isEmpty lst then
- None
- else
- Some(lst.[0])
-
-let ListToOption lst = ListToOptionMsg lst "given list contains more than one element"
-
-let ListDeduplicate lst =
- let rec __Dedup lst (visitedSet: System.Collections.Generic.HashSet<_>) acc =
- match lst with
- | fs :: rest ->
- let newAcc =
- if visitedSet.Add(fs) then
- acc @ [fs]
- else
- acc
- __Dedup rest visitedSet newAcc
- | _ -> acc
- __Dedup lst (new System.Collections.Generic.HashSet<_>()) []
-
-let rec ListCombine combinerFunc lst1 lst2 =
- match lst1 with
- | e1 :: rest ->
- let resLst1 = lst2 |> List.fold (fun acc e2 -> acc @ [combinerFunc e1 e2]) []
- List.concat [resLst1; ListCombine combinerFunc rest lst2]
- | [] -> []
-
-let rec ListCombineMult combinerFunc lst1 lst2 =
- match lst1 with
- | e1 :: rest ->
- let resLst1 = lst2 |> List.fold (fun acc e2 -> acc @ combinerFunc e1 e2) []
- List.concat [resLst1; ListCombineMult combinerFunc rest lst2]
- | [] -> []
-
-// =============================================================
-/// ensures: forall i :: 0 <= i < |lst| ==> ret[i] = Some(lst[i])
-// =============================================================
-let rec ConvertToOptionList lst =
- match lst with
- | fs :: rest -> Some(fs) :: ConvertToOptionList rest
- | [] -> []
-
-// =========================================================
-/// requres: Seq.length seq <= 1, otherwise fails with errMsg
-/// ensures: if |seq| = 0 then
-/// ret = None
-/// else
-/// ret = Some(seq[0])
-// =========================================================
-let SeqToOptionMsg seq errMsg =
- if Seq.length seq > 1 then
- failwith errMsg
- if Seq.isEmpty seq then
- None
- else
- Some(Seq.nth 0 seq)
-
-let SeqToOption seq = SeqToOptionMsg seq "given seq contains more than one element"
-
-// =========================================================
-/// requires: Set.count set <= 1, otherwise fails with errMsg
-/// ensures: if |set| = 0 then
-/// ret = None
-/// else
-/// ret = Some(set[0])
-// =========================================================
-let SetToOptionMsg set errMsg =
- if Set.count set > 1 then
- failwith errMsg
- if (Set.isEmpty set) then
- None
- else
- Some(set |> Set.toList |> List.head)
-
-let SetToOption set = SetToOptionMsg set "give set contains more than one value"
-
-// ============================================================
-/// requires: n >= 0
-/// ensures: |ret| = n && forall i :: 0 <= i < n ==> ret[i] = e
-// ============================================================
-let rec GenList n e =
- if n < 0 then
- failwith "n must be positive"
- if n = 0 then
- []
- else
- e :: (GenList (n-1) e)
-
-// =======================================
-/// ensures: forall i :: 0 <= i < |lst| ==>
-/// if lst[i] = oldElem then
-/// ret[i] = newElem
-/// else
-/// ret[i] = lst[i]
-// =======================================
-let ListReplace oldElem newElem lst =
- lst |> List.map (fun e -> if e = oldElem then newElem else e)
-
-// =================================================
-/// if (exists (k,v) :: (k,v) in lst && k = key) then
-/// ret = Some(v)
-/// else
-/// ret = None
-// =================================================
-let ListMapTryFind key lst =
- let filtered = lst |> List.filter (fun (k,v) -> k = key)
- match filtered with
- | fs :: rest -> Some(snd fs)
- | [] -> None
-
-// ==================================================
-/// Replaces the first occurence of the given key in
-/// the given list with the given value, or appends
-/// (key,value) if key does not exist in the list
-// ==================================================
-let rec ListMapAdd key value lst =
- match lst with
- | (k,v) :: rest -> if k = key then (k, value) :: rest else (k,v) :: (ListMapAdd key value rest)
- | [] -> [(key,value)]
-
-// ==========================
-/// ensures: ret = elem in lst
-// ==========================
-let ListContains elem lst =
- lst |> List.exists (fun e -> e = elem)
-
-// ====================================================
-/// Removes all elements in lst that are equal to "elem"
-// ====================================================
-let ListRemove elem lst =
- lst |> List.choose (fun e -> if e = elem then None else Some(e))
-
-let rec ListRemoveIdx idx lst =
- if idx = 0 then
- List.tail lst
- else
- List.head lst :: ListRemoveIdx (idx - 1) (List.tail lst)
-
-// ===============================================================
-/// ensures: |ret| = max(|lst| - cnt, 0)
-/// ensures: forall i :: cnt <= i < |lst| ==> ret[i] = lst[i-cnt]
-// ===============================================================
-let rec ListSkip cnt lst =
- if cnt = 0 then
- lst
- else
- match lst with
- | fs :: rest -> ListSkip (cnt-1) rest
- | [] -> []
-
-// ===============================================================
-/// ensures: forall i :: 0 <= i < max(|srcList|, |dstList|) ==>
-/// if i = idx then
-/// ret[i] = v
-/// elif i < |srcList| then
-/// ret[i] = srcList[i]
-/// else
-/// ret[i] = dstList[i]
-// ===============================================================
-let rec ListBuild srcList idx v dstList =
- match srcList, dstList with
- | fs1 :: rest1, fs2 :: rest2 -> if idx = 0 then
- v :: List.concat [rest1 ; ListSkip (List.length rest1) rest2]
- else
- fs1 :: ListBuild rest1 (idx-1) v rest2
- | [], fs2 :: rest2 -> if idx = 0 then
- v :: rest2
- else
- fs2 :: ListBuild [] (idx-1) v rest2
- | _, [] -> failwith "index out of range"
-
-// =======================================
-/// ensures: forall i :: 0 <= i < |lst| ==>
-/// if i = idx then
-/// ret[i] = v
-/// else
-/// ret[i] = lst[i]
-// =======================================
-let rec ListSet idx v lst =
- match lst with
- | fs :: rest -> if idx = 0 then
- v :: rest
- else
- fs :: ListSet (idx-1) v rest
- | [] -> failwith "index out of range"
-
-exception KeyAlreadyExists
-
-// =======================================
-/// requires (key |--> value) !in map
-///
-/// ensures ret = map ++ (key |--> value)
-// =======================================
-let MapAddNew key value map =
- match Map.tryFind key map with
- | Some(existingValue) ->
- if existingValue = value then
- map
- else
- raise KeyAlreadyExists
- | None ->
- map |> Map.add key value
-
-// =======================================
-/// ensures: forall k,v ::
-/// if k,v in map2 then
-// k,v in ret
-/// elif k,v in map1 then
-/// k,v in ret
-/// else
-/// k,v !in ret
-// =======================================
-let rec MapAddAll map1 map2 =
- map2 |> Map.fold (fun acc k v -> acc |> Map.add k v) map1
-
-// =======================================
-/// ensures: |ret| = 1
-/// ensures: (key -> value) in ret
-// =======================================
-let MapSingleton key value =
- Map.empty |> Map.add key value
-
-let MapKeys map =
- map |> Map.toList |> List.map (fun (k,v) -> k)
-
-let MapReplaceKey oldKey newKey newVal map =
- map |> Map.toList |> List.fold (fun acc (k,v) -> if k = oldKey then acc |> Map.add newKey newVal else acc |> Map.add k v) Map.empty
-
-// -------------------------------------------
-// ------------ algorithms -------------------
-// -------------------------------------------
-
-// =======================================================================
-/// Topologically sorts a given list
-///
-/// ensures: |ret| = |lst|
-/// ensures: forall e in lst :: e in ret
-/// ensures: forall i,j :: 0 <= i < j < ==> not (followsFunc ret[j] ret[i])
-// =======================================================================
-let rec TopSort followsFunc lst =
- match lst with
- | [] -> []
- | fs :: [] -> [fs]
- | fs :: rest ->
- let min = rest |> List.fold (fun acc elem -> if followsFunc acc elem then elem else acc) fs
- min :: TopSort followsFunc (ListRemove min lst)
-
-// -------------------------------------------
-// ------ string active patterns -------------
-// -------------------------------------------
-
-let (|Prefix|_|) (p:string) (s:string) =
- if s.StartsWith(p) then
- Some(s.Substring(p.Length))
- else
- None
-
-// -------------------------------------------
-// --------------- workflow ------------------
-// -------------------------------------------
-
-let IfDo1 cond func1 a =
- if cond then
- func1 a
- else
- a
-
-let IfDo2 cond func2 (a1,a2) =
- if cond then
- func2 a1 a2
- else
- a1,a2
-
-let Ite cond f1 f2 =
- if cond then
- f1
- else
- f2
-
-type CascadingBuilder<'a>(failVal: 'a) =
- member this.Bind(v, f) =
- match v with
- | Some(x) -> f x
- | None -> failVal
- member this.Return(v) = v
-
-// -------------------------------------------
-// --------------- random --------------------
-// -------------------------------------------
-
-let Iden x = x \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/BHeap.jen b/Jennisys/Jennisys/examples/BHeap.jen
deleted file mode 100644
index 55258bde..00000000
--- a/Jennisys/Jennisys/examples/BHeap.jen
+++ /dev/null
@@ -1,33 +0,0 @@
-interface BHeap {
- var elems: set[int]
-
- constructor Singleton(x: int)
- ensures elems = {x}
-
- constructor Dupleton(a: int, b: int)
- requires a != b
- ensures elems = {a b}
-
- constructor Tripleton(x: int, y: int, z: int)
- requires x != y && y != z && z != x
- ensures elems = {x y z}
-
- method Find(n: int) returns (ret: bool)
- ensures ret = (n in elems)
-}
-
-datamodel BHeap {
- var data: int
- var left: BHeap
- var right: BHeap
-
- frame
- left * right
-
- invariant
- elems = {data} + (left != null ? left.elems : {}) + (right != null ? right.elems : {})
- left != null ==> forall e :: e in left.elems ==> e < data
- right != null ==> forall e :: e in right.elems ==> e < data
- left = null ==> right = null
- (left != null && right = null) ==> left.elems = {left.data}
-}
diff --git a/Jennisys/Jennisys/examples/DList.jen b/Jennisys/Jennisys/examples/DList.jen
deleted file mode 100644
index 43337ca8..00000000
--- a/Jennisys/Jennisys/examples/DList.jen
+++ /dev/null
@@ -1,39 +0,0 @@
-interface DNode[T] {
- var list: seq[T]
-
- invariant
- |list| > 0
-
- constructor Init(t: T)
- ensures list = [t]
-
- constructor Double(p: T, q: T)
- ensures list = [p q]
-
- method List() returns (ret: seq[T])
- ensures ret = list
-
- method Size() returns (ret: int)
- ensures ret = |list|
-
- method Get(idx: int) returns (ret: T)
- requires idx >= 0 && idx < |list|
- ensures ret = list[idx]
-
- method Find(n: T) returns (ret: bool)
- ensures ret = (n in list)
-}
-
-datamodel DNode[T] {
- var data: T
- var next: DNode[T]
- var prev: DNode[T]
-
- frame
- next
-
- invariant
- next = null ==> list = [data]
- next != null ==> (list = [data] + next.list && next.prev = this)
- prev != null ==> prev.next = this
-}
diff --git a/Jennisys/Jennisys/examples/List.jen b/Jennisys/Jennisys/examples/List.jen
deleted file mode 100644
index 85a3b692..00000000
--- a/Jennisys/Jennisys/examples/List.jen
+++ /dev/null
@@ -1,77 +0,0 @@
-interface List[T] {
- var list: seq[T]
-
- constructor Empty()
- ensures list = []
-
- constructor Singleton(t: T)
- ensures list = [t]
-
- constructor Double(p: T, q: T)
- ensures list = [p q]
-}
-
-datamodel List[T] {
- var root: Node[T]
-
- frame
- root
-
- invariant
- root = null ==> |list| = 0
- root != null ==> list = root.list
-}
-
-interface Node[T] {
- var list: seq[T]
-
- invariant
- |list| > 0
-
- constructor Init(t: T)
- ensures list = [t]
-
- constructor Double(p: T, q: T)
- ensures list = [p q]
-
- method List() returns (ret: seq[T])
- ensures ret = list
-
- method Tail() returns (tail: Node[T])
- ensures |list| = 1 ==> tail = null
- ensures |list| > 1 ==> tail != null && tail.list = list[1..]
-
- method Size() returns (ret: int)
- ensures ret = |list|
-
- method SkipFew(num: int) returns (ret: Node[T])
- requires num >= 0
- ensures num >= |list| ==> ret = null
- ensures num < |list| ==> ret != null && ret.list = list[num..]
-
- method Get(idx: int) returns (ret: T)
- requires idx >= 0 && idx < |list|
- ensures ret = list[idx]
-
- method Index(n: T) returns (ret: int)
- ensures n !in list ==> ret = -1
- ensures n in list ==> ret >= 0 && ret < |list| && list[ret] = n
-
- method Find(n: T) returns (ret: bool)
- ensures ret = (n in list)
-
- method Insert(n: T)
- ensures list = old(list) + [n]
-}
-
-datamodel Node[T] {
- var data: T
- var next: Node[T]
-
- frame
- next
-
- invariant
- next = null ==> list = [data]
- next != null ==> list = [data] + next.list
-}
diff --git a/Jennisys/Jennisys/examples/List2.jen b/Jennisys/Jennisys/examples/List2.jen
deleted file mode 100644
index 3bd527fb..00000000
--- a/Jennisys/Jennisys/examples/List2.jen
+++ /dev/null
@@ -1,68 +0,0 @@
-interface IntList {
- var list: seq[int]
-
- constructor Empty()
- ensures list = []
-
- constructor SingletonTwo()
- ensures list = [2]
-
- constructor OneTwo()
- ensures list = [1 2]
-
- constructor Singleton(p: int)
- ensures list = [p]
-
- constructor TwoConsecutive(p: int)
- ensures list = [p] + [p+1]
-
- constructor Double(p: int, q: int)
- ensures list = [p] + [q]
-
- constructor Sum(p: int, q: int)
- ensures list = [p + q]
-}
-
-datamodel IntList {
- var root: IntNode
-
- frame
- root
-
- invariant
- root = null <==> |list| = 0
- root != null ==> list = root.list
-}
-
-interface IntNode {
- var list: seq[int]
-
- invariant
- |list| > 0
-
- constructor SingletonZero()
- ensures list = [0]
-
- constructor Init(x: int)
- ensures list = [x]
-
- constructor Double(x: int, y: int)
- ensures list = [x y]
-
- method Max() returns (ret: int)
- ensures ret in list
- ensures forall t :: t in list ==> ret >= t
-
-}
-
-datamodel IntNode {
- var data: int
- var next: IntNode
-
- frame
- next
-
- invariant
- next = null ==> list = [data]
- next != null ==> list = [data] + next.list
-}
diff --git a/Jennisys/Jennisys/examples/List3.jen b/Jennisys/Jennisys/examples/List3.jen
deleted file mode 100644
index 9130f82a..00000000
--- a/Jennisys/Jennisys/examples/List3.jen
+++ /dev/null
@@ -1,71 +0,0 @@
-interface IntList {
- var list: seq[int]
-
- constructor Empty()
- ensures list = []
-
- constructor SingletonTwo()
- ensures list = [2]
-
- constructor OneTwo()
- ensures list = [1 2]
-
- constructor Singleton(p: int)
- ensures list = [p]
-
- constructor TwoConsecutive(p: int)
- ensures list = [p] + [p+1]
-
- constructor Double(p: int, q: int)
- ensures list = [p] + [q]
-
- constructor Sum(p: int, q: int)
- ensures list = [p + q]
-}
-
-datamodel IntList {
- var root: IntNode
-
- frame
- root
-
- invariant
- root = null ==> |list| = 0
- root != null ==> (|list| = |root.succ| + 1 &&
- list[0] = root.data &&
- (forall i :: i in 1 ... |root.succ| ==> (root.succ[i-1] != null && list[i] = root.succ[i-1].data)))
-}
-
-interface IntNode {
- var succ: seq[IntNode]
- var data: int
-
- constructor Zero()
- ensures data = 0
- ensures succ = []
-
- constructor OneTwo()
- ensures data = 1
- ensures |succ| = 1 && succ[0] != null && succ[0].data = 2
-
- constructor Init(p: int)
- ensures data = p
-
- constructor InitInc(p: int)
- ensures data = p + 1
-
-
- invariant
- !(null in succ)
-}
-
-datamodel IntNode {
- var next: IntNode
-
- frame
- next
-
- invariant
- next = null ==> |succ| = 0
- next != null ==> (succ = [next] + next.succ)
-}
diff --git a/Jennisys/Jennisys/examples/Number.jen b/Jennisys/Jennisys/examples/Number.jen
deleted file mode 100644
index e31613bd..00000000
--- a/Jennisys/Jennisys/examples/Number.jen
+++ /dev/null
@@ -1,44 +0,0 @@
-interface Number {
- var num: int
-
- constructor Init(p: int)
- ensures num = p
-
- constructor Double(p: int)
- ensures num = 2*p
-
- constructor Sum(a: int, b: int)
- ensures num = a + b
-
- constructor Min2(a: int, b: int)
- ensures a < b ==> num = a
- ensures a >= b ==> num = b
-
- constructor Min22(a: int, b: int)
- ensures num in {a b}
- ensures num <= a && num <= b
-
- constructor Min3(a: int, b: int, c: int)
- ensures num in {a b c}
- ensures num <= a && num <= b && num <= c
-
- constructor Min32(a: int, b: int, c: int)
- ensures num in {a b c}
- ensures forall x :: x in {a b c} ==> num <= x
-
- constructor MinSum(a: int, b: int, c: int)
- ensures num in {a+b a+c b+c}
- ensures num <= a+b && num <= b+c && num <= a+c
-
- constructor Min4(a: int, b: int, c: int, d: int)
- ensures num in {a b c d}
- ensures forall x :: x in {a b c d} ==> num <= x
-
- constructor Abs(a: int)
- ensures num in {a (-a)} && num >= 0
-
-}
-
-datamodel Number {
-
-} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/NumberMethods.jen b/Jennisys/Jennisys/examples/NumberMethods.jen
deleted file mode 100644
index f9b17f74..00000000
--- a/Jennisys/Jennisys/examples/NumberMethods.jen
+++ /dev/null
@@ -1,40 +0,0 @@
-interface NumberMethods {
-
- method Double(p: int) returns (ret: int)
- ensures ret = 2*p
-
- method Sum(a: int, b: int) returns (ret: int)
- ensures ret = a + b
-
- method Min2(a: int, b: int) returns (ret: int)
- ensures a < b ==> ret = a
- ensures a >= b ==> ret = b
-
- method Min22(a: int, b: int) returns (ret: int)
- ensures ret in {a b}
- ensures ret <= a && ret <= b
-
- method Min3(a: int, b: int, c: int) returns (ret: int)
- ensures ret in {a b c}
- ensures ret <= a && ret <= b && ret <= c
-
- method Min32(a: int, b: int, c: int) returns (ret: int)
- ensures ret in {a b c}
- ensures forall x :: x in {a b c} ==> ret <= x
-
- method MinSum(a: int, b: int, c: int) returns (ret: int)
- ensures ret in {a+b a+c b+c}
- ensures ret <= a+b && ret <= b+c && ret <= a+c
-
- method Min4(a: int, b: int, c: int, d: int) returns (ret: int)
- ensures ret in {a b c d}
- ensures forall x :: x in {a b c d} ==> ret <= x
-
- method Abs(a: int) returns (ret: int)
- ensures ret in {a (-a)} && ret >= 0
-
-}
-
-datamodel NumberMethods {
-
-} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/Set.jen b/Jennisys/Jennisys/examples/Set.jen
deleted file mode 100644
index 01532f96..00000000
--- a/Jennisys/Jennisys/examples/Set.jen
+++ /dev/null
@@ -1,72 +0,0 @@
-interface Set {
- var elems: set[int]
-
- constructor Empty()
- ensures elems = {}
-
- constructor SingletonZero()
- ensures elems = {0}
-
- constructor Singleton(t: int)
- ensures elems = {t}
-
- constructor Sum(p: int, q: int)
- ensures elems = {p + q}
-
- constructor Double(p: int, q: int)
- requires p != q
- ensures elems = {p q}
-
-}
-
-datamodel Set {
- var root: SetNode
-
- frame
- root
-
- invariant
- root = null ==> elems = {}
- root != null ==> elems = root.elems
-}
-
-interface SetNode {
- var elems: set[int]
-
- constructor Init(x: int)
- ensures elems = {x}
-
- constructor Double(a: int, b: int)
- requires a != b
- ensures elems = {a b}
-
- constructor DoubleBase(x: int, y: int)
- requires x > y
- ensures elems = {x y}
-
- constructor Triple(x: int, y: int, z: int)
- requires x != y && y != z && z != x
- ensures elems = {x y z}
-
- constructor TripleBase(x: int, y: int, z: int)
- requires x < y && y < z
- ensures elems = {x y z}
-
- method Find(n: int) returns (ret: bool)
- ensures ret = (n in elems)
-
-}
-
-datamodel SetNode {
- var data: int
- var left: SetNode
- var right: SetNode
-
- frame
- left * right
-
- invariant
- elems = {data} + (left != null ? left.elems : {}) + (right != null ? right.elems : {})
- left != null ==> forall e :: e in left.elems ==> e < data
- right != null ==> forall e :: e in right.elems ==> e > data
-}
diff --git a/Jennisys/Jennisys/examples/Set2.jen b/Jennisys/Jennisys/examples/Set2.jen
deleted file mode 100644
index cfbcbce7..00000000
--- a/Jennisys/Jennisys/examples/Set2.jen
+++ /dev/null
@@ -1,60 +0,0 @@
-class Set { var elems: seq[int]
-
- constructor Empty()
- ensures elems = []
-
- constructor Singleton(t: int)
- ensures elems = [t]
-
- constructor Sum(p: int, q: int)
- ensures elems = [p + q]
-
-}
-
-model Set {
- var root: SetNode
-
- frame
- root
-
- invariant
- root = null ==> elems = []
- root != null ==> elems = root.elems
-}
-
-class SetNode {
- var elems: seq[int]
-
- constructor Init(x: int)
- ensures elems = [x]
-
- constructor Double(a: int, b: int)
- requires a != b
- ensures |elems| = 2 && a in elems && b in elems
-
- constructor DoubleBase(x: int, y: int)
- requires x < y
- ensures elems = [x y]
-
- constructor Triple(x: int, y: int, z: int)
- requires x != y && y != z && z != x
- ensures |elems| = 3 && x in elems && y in elems && z in elems
-
- constructor TripleBase(x: int, y: int, z: int)
- requires x < y && y < z
- ensures elems = [x y z]
-}
-
-model SetNode {
- var data: int
- var left: SetNode
- var right: SetNode
-
- frame
- left * right
-
- invariant
- elems = (left != null ? left.elems : []) + [data] + (right != null ? right.elems : [])
- left != null ==> forall e :: e in left.elems ==> e < data
- right != null ==> forall e :: e in right.elems ==> e > data
-}
diff --git a/Jennisys/Jennisys/examples/Simple.jen b/Jennisys/Jennisys/examples/Simple.jen
deleted file mode 100644
index 2f5e7feb..00000000
--- a/Jennisys/Jennisys/examples/Simple.jen
+++ /dev/null
@@ -1,31 +0,0 @@
-interface Simple {
- var a: int
-
- method Inc(p: int)
- a := old(a) + p
-
- method Init(n: int)
- a := n
-
- method Max(x: int, y: int)
- ensures x < y ==> a = y
- ensures x >= y ==> a = x
-
-
- method Max2(x: int, y: int)
- ensures a = x || a = y
- ensures forall t :: t in {x y} ==> a >= t
-
- method Max3__mod__(x: int, y: int)
- ensures a in {x y}
- ensures forall t :: t in {x y} ==> a >= t
-
- method MaxAll__mod__(x: seq[int])
- ensures a in x
- ensures forall t :: t in x ==> a >= t
-}
-
-datamodel Simple {
- var c: int
- invariant a = c
-} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/jennisys-synth_List.dfy b/Jennisys/Jennisys/examples/jennisys-synth_List.dfy
deleted file mode 100644
index 0611c78b..00000000
--- a/Jennisys/Jennisys/examples/jennisys-synth_List.dfy
+++ /dev/null
@@ -1,147 +0,0 @@
-class List<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var root: Node<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> |list| == 0) &&
- (root != null ==> list == root.list)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- {
- this.list := [];
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method Singleton(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- {
- var gensym65 := new Node<T>;
- gensym65.data := t;
- gensym65.list := [t];
- gensym65.next := null;
- this.list := [t];
- this.root := gensym65;
- // repr stuff
- gensym65.Repr := {gensym65};
- this.Repr := {this} + this.root.Repr;
- }
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- {
- var gensym66 := new Node<T>;
- var gensym67 := new Node<T>;
- gensym66.data := p;
- gensym66.list := [p, q];
- gensym66.next := gensym67;
- gensym67.data := q;
- gensym67.list := [q];
- gensym67.next := null;
- this.list := [p, q];
- this.root := gensym66;
- // repr stuff
- gensym67.Repr := {gensym67};
- gensym66.Repr := {gensym66} + gensym66.next.Repr;
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class Node<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var data: T;
- var next: Node<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null <==> list == [data] && list[0] == data) &&
- (next != null ==> list == [data] + next.list) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid_self() && (next.next != null ==> next.next.Valid_self()))
- }
-
- method Init(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- {
- this.data := t;
- this.list := [t];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- {
- var gensym71 := new Node<T>;
- gensym71.data := q;
- gensym71.list := [q];
- gensym71.next := null;
- this.data := p;
- this.list := [p, q];
- this.next := gensym71;
- // repr stuff
- gensym71.Repr := {gensym71};
- this.Repr := {this} + this.next.Repr;
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/jennisys-synth_List2.dfy b/Jennisys/Jennisys/examples/jennisys-synth_List2.dfy
deleted file mode 100644
index 13e521a8..00000000
--- a/Jennisys/Jennisys/examples/jennisys-synth_List2.dfy
+++ /dev/null
@@ -1,207 +0,0 @@
-class IntList {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var root: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null <==> |list| == 0) &&
- (root != null ==> list == root.list)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- {
- this.list := [];
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method SingletonTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [2];
- {
- var gensym65 := new IntNode;
- gensym65.data := 2;
- gensym65.list := [2];
- gensym65.next := null;
- this.list := [2];
- this.root := gensym65;
- // repr stuff
- gensym65.Repr := {gensym65};
- this.Repr := {this} + this.root.Repr;
- }
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [1] + [2];
- {
- var gensym62 := new IntNode;
- var gensym69 := new IntNode;
- gensym62.data := 1;
- gensym62.list := [1, 2];
- gensym62.next := gensym69;
- gensym69.data := 2;
- gensym69.list := [2];
- gensym69.next := null;
- this.list := [1, 2];
- this.root := gensym62;
- // repr stuff
- gensym69.Repr := {gensym69};
- gensym62.Repr := {gensym62} + gensym62.next.Repr;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Singleton(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p];
- {
- var gensym66 := new IntNode;
- gensym66.data := p;
- gensym66.list := [p];
- gensym66.next := null;
- this.list := [p];
- this.root := gensym66;
- // repr stuff
- gensym66.Repr := {gensym66};
- this.Repr := {this} + this.root.Repr;
- }
-
- method TwoConsecutive(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [p + 1];
- {
- var gensym63 := new IntNode;
- var gensym71 := new IntNode;
- gensym63.data := p;
- gensym63.list := [p] + [p + 1];
- gensym63.next := gensym71;
- gensym71.data := p + 1;
- gensym71.list := [p + 1];
- gensym71.next := null;
- this.list := [p] + [p + 1];
- this.root := gensym63;
- // repr stuff
- gensym71.Repr := {gensym71};
- gensym63.Repr := {gensym63} + gensym63.next.Repr;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Double(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [q];
- {
- var gensym64 := new IntNode;
- var gensym71 := new IntNode;
- gensym64.data := p;
- gensym64.list := [p] + [q];
- gensym64.next := gensym71;
- gensym71.data := q;
- gensym71.list := [q];
- gensym71.next := null;
- this.list := [p] + [q];
- this.root := gensym64;
- // repr stuff
- gensym71.Repr := {gensym71};
- gensym64.Repr := {gensym64} + gensym64.next.Repr;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p + q];
- {
- var gensym67 := new IntNode;
- gensym67.data := p + q;
- gensym67.list := [p + q];
- gensym67.next := null;
- this.list := [p + q];
- this.root := gensym67;
- // repr stuff
- gensym67.Repr := {gensym67};
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class IntNode {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var data: int;
- var next: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> list == [data] && list[0] == data) &&
- (next != null ==> list == [data] + next.list) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid_self() && (next.next != null ==> next.next.Valid_self()))
- }
-
- method SingletonZero()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [0];
- {
- this.data := 0;
- this.list := [0];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/jennisys-synth_List3.dfy b/Jennisys/Jennisys/examples/jennisys-synth_List3.dfy
deleted file mode 100644
index e202412f..00000000
--- a/Jennisys/Jennisys/examples/jennisys-synth_List3.dfy
+++ /dev/null
@@ -1,255 +0,0 @@
-class IntList {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var root: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> |list| == 0) &&
- (root != null ==> |list| == |root.succ| + 1 && (list[0] == root.data && (forall i: int :: 0 < i && i <= |root.succ| ==> root.succ[i - 1] != null && list[i] == root.succ[i - 1].data)))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- {
- this.list := [];
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method SingletonTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [2];
- {
- var gensym65 := new IntNode;
- gensym65.data := 2;
- gensym65.next := null;
- gensym65.succ := [];
- this.list := [2];
- this.root := gensym65;
- // repr stuff
- gensym65.Repr := {gensym65};
- this.Repr := {this} + this.root.Repr;
- }
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [1] + [2];
- {
- var gensym63 := new IntNode;
- var gensym75 := new IntNode;
- gensym63.data := 1;
- gensym63.next := gensym75;
- gensym63.succ := [gensym75];
- gensym75.data := 2;
- gensym75.next := null;
- gensym75.succ := [];
- this.list := [1, 2];
- this.root := gensym63;
- // repr stuff
- gensym75.Repr := {gensym75};
- gensym63.Repr := {gensym63} + gensym63.next.Repr;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Singleton(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p];
- {
- var gensym66 := new IntNode;
- gensym66.data := p;
- gensym66.next := null;
- gensym66.succ := [];
- this.list := [p];
- this.root := gensym66;
- // repr stuff
- gensym66.Repr := {gensym66};
- this.Repr := {this} + this.root.Repr;
- }
-
- method TwoConsecutive(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [p + 1];
- {
- var gensym64 := new IntNode;
- var gensym75 := new IntNode;
- gensym64.data := p;
- gensym64.next := gensym75;
- gensym64.succ := [gensym75];
- gensym75.data := p + 1;
- gensym75.next := null;
- gensym75.succ := [];
- this.list := [p] + [p + 1];
- this.root := gensym64;
- // repr stuff
- gensym75.Repr := {gensym75};
- gensym64.Repr := {gensym64} + gensym64.next.Repr;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Double(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [q];
- {
- var gensym65 := new IntNode;
- var gensym77 := new IntNode;
- gensym65.data := p;
- gensym65.next := gensym77;
- gensym65.succ := [gensym77];
- gensym77.data := q;
- gensym77.next := null;
- gensym77.succ := [];
- this.list := [p] + [q];
- this.root := gensym65;
- // repr stuff
- gensym77.Repr := {gensym77};
- gensym65.Repr := {gensym65} + gensym65.next.Repr;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p + q];
- {
- var gensym67 := new IntNode;
- gensym67.data := p + q;
- gensym67.next := null;
- gensym67.succ := [];
- this.list := [p + q];
- this.root := gensym67;
- // repr stuff
- gensym67.Repr := {gensym67};
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class IntNode {
- ghost var Repr: set<object>;
- ghost var succ: seq<IntNode>;
- ghost var data: int;
-
- var next: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> |succ| == 0) &&
- (next != null ==> succ == [next] + next.succ) &&
- (!(null in succ))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid_self() && (next.next != null ==> next.next.Valid_self()))
- }
-
- method Zero()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 0;
- ensures succ == [];
- {
- this.data := 0;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 1;
- ensures |succ| == 1;
- ensures succ[0] != null;
- ensures succ[0].data == 2;
- {
- var gensym71 := new IntNode;
- gensym71.data := 2;
- gensym71.next := null;
- gensym71.succ := [];
- this.data := 1;
- this.next := gensym71;
- this.succ := [gensym71];
- // repr stuff
- gensym71.Repr := {gensym71};
- this.Repr := {this} + this.next.Repr;
- }
-
- method Init(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- {
- this.data := p;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
- method InitInc(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p + 1;
- {
- this.data := p + 1;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/jennisys-synth_Number.dfy b/Jennisys/Jennisys/examples/jennisys-synth_Number.dfy
deleted file mode 100644
index 5ede7f5c..00000000
--- a/Jennisys/Jennisys/examples/jennisys-synth_Number.dfy
+++ /dev/null
@@ -1,202 +0,0 @@
-class Number {
- ghost var Repr: set<object>;
- ghost var num: int;
-
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- true
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- true
- }
-
- method Init(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == p;
- {
- this.num := p;
- // repr stuff
- this.Repr := {this};
- }
-
- method Double(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == 2 * p;
- {
- this.num := 2 * p;
- // repr stuff
- this.Repr := {this};
- }
-
- method Sum(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == a + b;
- {
- this.num := a + b;
- // repr stuff
- this.Repr := {this};
- }
-
- method Min2(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures a < b ==> num == a;
- ensures a >= b ==> num == b;
- {
- if (a >= b ==> a == b) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
-
- method Min22(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b};
- ensures num <= a;
- ensures num <= b;
- {
- if (a <= b) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
-
- method Min3(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c};
- ensures num <= a;
- ensures num <= b;
- ensures num <= c;
- {
- if (a <= b && a <= c) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- if (c <= a && c <= b) {
- this.num := c;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
-
- method MinSum(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a + b, a + c, b + c};
- ensures num <= a + b;
- ensures num <= b + c;
- ensures num <= a + c;
- {
- if (a + b <= b + c && a + b <= a + c) {
- this.num := a + b;
- // repr stuff
- this.Repr := {this};
- } else {
- if (a + c <= a + b && a + c <= b + c) {
- this.num := a + c;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b + c;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
-
- method Min4(a: int, b: int, c: int, d: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c, d};
- ensures num <= a;
- ensures num <= b;
- ensures num <= c;
- ensures num <= d;
- {
- if (a <= b && (a <= c && a <= d)) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- if (d <= a && (d <= b && d <= c)) {
- this.num := d;
- // repr stuff
- this.Repr := {this};
- } else {
- if (c <= a && (c <= b && c <= d)) {
- this.num := c;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
- }
-
- method Abs(a: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures a < 0 ==> num == -a;
- ensures a >= 0 ==> num == a;
- {
- if (!(a >= 0)) {
- this.num := -a;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/jennisys-synth_Set.dfy b/Jennisys/Jennisys/examples/jennisys-synth_Set.dfy
deleted file mode 100644
index efc9aa07..00000000
--- a/Jennisys/Jennisys/examples/jennisys-synth_Set.dfy
+++ /dev/null
@@ -1,344 +0,0 @@
-class Set {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var root: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> elems == {}) &&
- (root != null ==> elems == root.elems)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {};
- {
- this.elems := {};
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method Singleton(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- var gensym66 := new SetNode;
- gensym66.data := t;
- gensym66.elems := {t};
- gensym66.left := null;
- gensym66.right := null;
- this.elems := {t};
- this.root := gensym66;
- // repr stuff
- gensym66.Repr := {gensym66};
- this.Repr := {this} + this.root.Repr;
- }
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p + q};
- {
- var gensym68 := new SetNode;
- gensym68.data := p + q;
- gensym68.elems := {p + q};
- gensym68.left := null;
- gensym68.right := null;
- this.elems := {p + q};
- this.root := gensym68;
- // repr stuff
- gensym68.Repr := {gensym68};
- this.Repr := {this} + this.root.Repr;
- }
-
- method Double(p: int, q: int)
- modifies this;
- requires p != q;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- if (q < p) {
- var gensym71 := new SetNode;
- var gensym75 := new SetNode;
- gensym71.data := p;
- gensym71.elems := {p, q};
- gensym71.left := gensym75;
- gensym71.right := null;
- gensym75.data := q;
- gensym75.elems := {q};
- gensym75.left := null;
- gensym75.right := null;
- this.elems := {p, q};
- this.root := gensym71;
- // repr stuff
- gensym75.Repr := {gensym75};
- gensym71.Repr := {gensym71} + gensym71.left.Repr;
- this.Repr := {this} + this.root.Repr;
- } else {
- var gensym71 := new SetNode;
- var gensym75 := new SetNode;
- gensym71.data := q;
- gensym71.elems := {p, q};
- gensym71.left := gensym75;
- gensym71.right := null;
- gensym75.data := p;
- gensym75.elems := {p};
- gensym75.left := null;
- gensym75.right := null;
- this.elems := {p, q};
- this.root := gensym71;
- // repr stuff
- gensym75.Repr := {gensym75};
- gensym71.Repr := {gensym71} + gensym71.left.Repr;
- this.Repr := {this} + this.root.Repr;
- }
- }
-
-}
-
-class SetNode {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var data: int;
- var left: SetNode;
- var right: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (left != null ==> left in Repr && left.Repr <= Repr && this !in left.Repr) &&
- (right != null ==> right in Repr && right.Repr <= Repr && this !in right.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (elems == ({data} + (if left != null then left.elems else {})) + (if right != null then right.elems else {})) &&
- (left != null ==> (forall e :: e in left.elems ==> e < data)) &&
- (right != null ==> (forall e :: e in right.elems ==> e > data))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (left != null ==> left.Valid_self() && (left.left != null ==> left.left.Valid_self())) &&
- (right != null ==> right.Valid_self() && (right.right != null ==> right.right.Valid_self()))
- }
-
- method Init(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- this.data := t;
- this.elems := {t};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method Double(p: int, q: int)
- modifies this;
- requires p != q;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- if (q > p) {
- var gensym79 := new SetNode;
- gensym79.data := q;
- gensym79.elems := {q};
- gensym79.left := null;
- gensym79.right := null;
- this.data := p;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym79;
- // repr stuff
- gensym79.Repr := {gensym79};
- this.Repr := {this} + this.right.Repr;
- } else {
- var gensym79 := new SetNode;
- gensym79.data := p;
- gensym79.elems := {p};
- gensym79.left := null;
- gensym79.right := null;
- this.data := q;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym79;
- // repr stuff
- gensym79.Repr := {gensym79};
- this.Repr := {this} + this.right.Repr;
- }
- }
-
- method Triple(p: int, q: int, r: int)
- modifies this;
- requires p != q;
- requires q != r;
- requires r != p;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q, r};
- {
- if (p < q && r > q) {
- var gensym83 := new SetNode;
- var gensym84 := new SetNode;
- gensym83.data := r;
- gensym83.elems := {r};
- gensym83.left := null;
- gensym83.right := null;
- gensym84.data := p;
- gensym84.elems := {p};
- gensym84.left := null;
- gensym84.right := null;
- this.data := q;
- this.elems := {p, q, r};
- this.left := gensym84;
- this.right := gensym83;
- // repr stuff
- gensym83.Repr := {gensym83};
- gensym84.Repr := {gensym84};
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (p < r && q > r) {
- var gensym85 := new SetNode;
- var gensym86 := new SetNode;
- gensym85.data := q;
- gensym85.elems := {q};
- gensym85.left := null;
- gensym85.right := null;
- gensym86.data := p;
- gensym86.elems := {p};
- gensym86.left := null;
- gensym86.right := null;
- this.data := r;
- this.elems := {p, q, r};
- this.left := gensym86;
- this.right := gensym85;
- // repr stuff
- gensym85.Repr := {gensym85};
- gensym86.Repr := {gensym86};
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (r < p && q > p) {
- var gensym84 := new SetNode;
- var gensym85 := new SetNode;
- gensym84.data := q;
- gensym84.elems := {q};
- gensym84.left := null;
- gensym84.right := null;
- gensym85.data := r;
- gensym85.elems := {r};
- gensym85.left := null;
- gensym85.right := null;
- this.data := p;
- this.elems := {p, q, r};
- this.left := gensym85;
- this.right := gensym84;
- // repr stuff
- gensym84.Repr := {gensym84};
- gensym85.Repr := {gensym85};
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (q < p && r > p) {
- var gensym82 := new SetNode;
- var gensym83 := new SetNode;
- gensym82.data := r;
- gensym82.elems := {r};
- gensym82.left := null;
- gensym82.right := null;
- gensym83.data := q;
- gensym83.elems := {q};
- gensym83.left := null;
- gensym83.right := null;
- this.data := p;
- this.elems := {p, q, r};
- this.left := gensym83;
- this.right := gensym82;
- // repr stuff
- gensym82.Repr := {gensym82};
- gensym83.Repr := {gensym83};
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (q < r && p > r) {
- var gensym85 := new SetNode;
- var gensym86 := new SetNode;
- gensym85.data := p;
- gensym85.elems := {p};
- gensym85.left := null;
- gensym85.right := null;
- gensym86.data := q;
- gensym86.elems := {q};
- gensym86.left := null;
- gensym86.right := null;
- this.data := r;
- this.elems := {p, q, r};
- this.left := gensym86;
- this.right := gensym85;
- // repr stuff
- gensym85.Repr := {gensym85};
- gensym86.Repr := {gensym86};
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- var gensym82 := new SetNode;
- var gensym83 := new SetNode;
- gensym82.data := p;
- gensym82.elems := {p};
- gensym82.left := null;
- gensym82.right := null;
- gensym83.data := r;
- gensym83.elems := {r};
- gensym83.left := null;
- gensym83.right := null;
- this.data := q;
- this.elems := {p, q, r};
- this.left := gensym83;
- this.right := gensym82;
- // repr stuff
- gensym82.Repr := {gensym82};
- gensym83.Repr := {gensym83};
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- }
- }
- }
- }
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod/jennisys-synth_List.dfy b/Jennisys/Jennisys/examples/mod/jennisys-synth_List.dfy
deleted file mode 100644
index 474eb9f1..00000000
--- a/Jennisys/Jennisys/examples/mod/jennisys-synth_List.dfy
+++ /dev/null
@@ -1,202 +0,0 @@
-class List<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var root: Node<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> |list| == 0) &&
- (root != null ==> list == root.list)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- {
- var gensym68 := new Node<T>;
- gensym68._synth_List_Double_gensym68(p, q);
- this.list := [p, q];
- this.root := gensym68;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- {
- this.list := [];
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Singleton(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- {
- var gensym69 := new Node<T>;
- gensym69._synth_List_Singleton_gensym69(t);
- this.list := [t];
- this.root := gensym69;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class Node<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var data: T;
- var next: Node<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null <==> list == [data] && list[0] == data) &&
- (next != null ==> list == [data] + next.list) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Init(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- {
- this.data := t;
- this.list := [t];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_List_Double_gensym68(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 2;
- ensures list[0] == p;
- ensures list[1] == q;
- {
- var gensym75 := new Node<T>;
- gensym75._synth_Node__synth_List_Double_gensym68_gensym75(q);
- this.data := p;
- this.list := [p, q];
- this.next := gensym75;
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_List_Singleton_gensym69(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == t;
- {
- this.data := t;
- this.list := [t];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- {
- var gensym73 := new Node<T>;
- gensym73._synth_Node_Double_gensym73(q);
- this.data := p;
- this.list := [p, q];
- this.next := gensym73;
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_Node_Double_gensym73(q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == q;
- {
- this.data := q;
- this.list := [q];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_Node__synth_List_Double_gensym68_gensym75(q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == q;
- {
- this.data := q;
- this.list := [q];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod/jennisys-synth_List2.dfy b/Jennisys/Jennisys/examples/mod/jennisys-synth_List2.dfy
deleted file mode 100644
index 46213b46..00000000
--- a/Jennisys/Jennisys/examples/mod/jennisys-synth_List2.dfy
+++ /dev/null
@@ -1,323 +0,0 @@
-class IntList {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var root: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null <==> |list| == 0) &&
- (root != null ==> list == root.list)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [q];
- {
- var gensym67 := new IntNode;
- gensym67._synth_IntList_Double_gensym67(p, q);
- this.list := [p] + [q];
- this.root := gensym67;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- {
- this.list := [];
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [1, 2];
- {
- var gensym65 := new IntNode;
- gensym65._synth_IntList_OneTwo_gensym65();
- this.list := [1, 2];
- this.root := gensym65;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Singleton(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p];
- {
- var gensym70 := new IntNode;
- gensym70._synth_IntList_Singleton_gensym70(p);
- this.list := [p];
- this.root := gensym70;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method SingletonTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [2];
- {
- var gensym69 := new IntNode;
- gensym69._synth_IntList_SingletonTwo_gensym69();
- this.list := [2];
- this.root := gensym69;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p + q];
- {
- var gensym71 := new IntNode;
- gensym71._synth_IntList_Sum_gensym71(p, q);
- this.list := [p + q];
- this.root := gensym71;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method TwoConsecutive(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [p + 1];
- {
- var gensym66 := new IntNode;
- gensym66._synth_IntList_TwoConsecutive_gensym66(p);
- this.list := [p] + [p + 1];
- this.root := gensym66;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class IntNode {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var data: int;
- var next: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> list == [data] && list[0] == data) &&
- (next != null ==> list == [data] + next.list) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method SingletonZero()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [0];
- {
- this.data := 0;
- this.list := [0];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_Double_gensym67(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [q];
- {
- var gensym78 := new IntNode;
- gensym78._synth_IntNode__synth_IntList_Double_gensym67_gensym78(q);
- this.data := p;
- this.list := [p] + [q];
- this.next := gensym78;
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_IntList_OneTwo_gensym65()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 2;
- ensures list[0] == 1;
- ensures list[1] == 2;
- {
- var gensym75 := new IntNode;
- gensym75._synth_IntNode__synth_IntList_OneTwo_gensym65_gensym75();
- this.data := 1;
- this.list := [1, 2];
- this.next := gensym75;
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_IntList_SingletonTwo_gensym69()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == 2;
- {
- this.data := 2;
- this.list := [2];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_Singleton_gensym70(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == p;
- {
- this.data := p;
- this.list := [p];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_Sum_gensym71(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == p + q;
- {
- this.data := p + q;
- this.list := [p + q];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_TwoConsecutive_gensym66(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [p + 1];
- {
- var gensym78 := new IntNode;
- gensym78._synth_IntNode__synth_IntList_TwoConsecutive_gensym66_gensym78(p);
- this.data := p;
- this.list := [p] + [p + 1];
- this.next := gensym78;
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_IntNode__synth_IntList_Double_gensym67_gensym78(q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == q;
- {
- this.data := q;
- this.list := [q];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntNode__synth_IntList_OneTwo_gensym65_gensym75()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == 2;
- {
- this.data := 2;
- this.list := [2];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntNode__synth_IntList_TwoConsecutive_gensym66_gensym78(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures |list| == 1;
- ensures list[0] == p + 1;
- {
- this.data := p + 1;
- this.list := [p + 1];
- this.next := null;
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod/jennisys-synth_List3.dfy b/Jennisys/Jennisys/examples/mod/jennisys-synth_List3.dfy
deleted file mode 100644
index e079b608..00000000
--- a/Jennisys/Jennisys/examples/mod/jennisys-synth_List3.dfy
+++ /dev/null
@@ -1,393 +0,0 @@
-class IntList {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var root: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> |list| == 0) &&
- (root != null ==> |list| == |root.succ| + 1 && (list[0] == root.data && (forall i :: 1 <= i && i <= |root.succ| ==> root.succ[i - 1] != null && list[i] == root.succ[i - 1].data)))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [q];
- {
- var gensym68 := new IntNode;
- gensym68._synth_IntList_Double_gensym68(p, q);
- this.list := [p] + [q];
- this.root := gensym68;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- {
- this.list := [];
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [1, 2];
- {
- var gensym65 := new IntNode;
- gensym65._synth_IntList_OneTwo_gensym65();
- this.list := [1, 2];
- this.root := gensym65;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Singleton(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p];
- {
- var gensym70 := new IntNode;
- gensym70._synth_IntList_Singleton_gensym70(p);
- this.list := [p];
- this.root := gensym70;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method SingletonTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [2];
- {
- var gensym69 := new IntNode;
- gensym69._synth_IntList_SingletonTwo_gensym69();
- this.list := [2];
- this.root := gensym69;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p + q];
- {
- var gensym71 := new IntNode;
- gensym71._synth_IntList_Sum_gensym71(p, q);
- this.list := [p + q];
- this.root := gensym71;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method TwoConsecutive(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [p + 1];
- {
- var gensym67 := new IntNode;
- gensym67._synth_IntList_TwoConsecutive_gensym67(p);
- this.list := [p] + [p + 1];
- this.root := gensym67;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class IntNode {
- ghost var Repr: set<object>;
- ghost var succ: seq<IntNode>;
- ghost var data: int;
-
- var next: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> |succ| == 0) &&
- (next != null ==> succ == [next] + next.succ) &&
- (!(null in succ))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Init(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- {
- this.data := p;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method InitInc(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p + 1;
- {
- this.data := p + 1;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Zero()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 0;
- ensures succ == [];
- {
- this.data := 0;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_Double_gensym68(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- ensures |succ| == 1;
- ensures succ[0].data == q;
- ensures succ[0].succ == [];
- {
- var gensym80 := new IntNode;
- gensym80._synth_IntNode__synth_IntList_Double_gensym68_gensym80(q);
- this.data := p;
- this.next := gensym80;
- this.succ := [gensym80];
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_IntList_OneTwo_gensym65()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 1;
- ensures |succ| == 1;
- ensures succ[0].data == 2;
- ensures succ[0].succ == [];
- {
- var gensym78 := new IntNode;
- gensym78._synth_IntNode__synth_IntList_OneTwo_gensym65_gensym78();
- this.data := 1;
- this.next := gensym78;
- this.succ := [gensym78];
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_IntList_SingletonTwo_gensym69()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 2;
- ensures |succ| == 0;
- {
- this.data := 2;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_Singleton_gensym70(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- ensures |succ| == 0;
- {
- this.data := p;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_Sum_gensym71(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p + q;
- ensures |succ| == 0;
- {
- this.data := p + q;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_TwoConsecutive_gensym67(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- ensures |succ| == 1;
- ensures succ[0].data == p + 1;
- ensures succ[0].succ == [];
- {
- var gensym79 := new IntNode;
- gensym79._synth_IntNode__synth_IntList_TwoConsecutive_gensym67_gensym79(p);
- this.data := p;
- this.next := gensym79;
- this.succ := [gensym79];
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 1;
- ensures |succ| == 1;
- ensures succ[0] != null;
- ensures succ[0].data == 2;
- {
- var gensym73 := new IntNode;
- gensym73._synth_IntNode_OneTwo_gensym73();
- this.data := 1;
- this.next := gensym73;
- this.succ := [gensym73];
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- }
-
-
- method _synth_IntNode_OneTwo_gensym73()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 2;
- ensures |succ| == 0;
- {
- this.data := 2;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntNode__synth_IntList_Double_gensym68_gensym80(q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == q;
- ensures |succ| == 0;
- {
- this.data := q;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntNode__synth_IntList_OneTwo_gensym65_gensym78()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 2;
- ensures |succ| == 0;
- {
- this.data := 2;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntNode__synth_IntList_TwoConsecutive_gensym67_gensym79(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p + 1;
- ensures |succ| == 0;
- {
- this.data := p + 1;
- this.next := null;
- this.succ := [];
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod/jennisys-synth_Number.dfy b/Jennisys/Jennisys/examples/mod/jennisys-synth_Number.dfy
deleted file mode 100644
index 3f1e6b4b..00000000
--- a/Jennisys/Jennisys/examples/mod/jennisys-synth_Number.dfy
+++ /dev/null
@@ -1,233 +0,0 @@
-class Number {
- ghost var Repr: set<object>;
- ghost var num: int;
-
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- true
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- true
- }
-
-
- method Double(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == 2 * p;
- {
- this.num := 2 * p;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Init(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == p;
- {
- this.num := p;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Sum(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == a + b;
- {
- this.num := a + b;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Abs(a: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, -a};
- ensures num >= 0;
- {
- if (a >= 0) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := -a;
- // repr stuff
- this.Repr := {this};
- }
- }
-
-
- method Min4(a: int, b: int, c: int, d: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c, d};
- ensures (forall x :: x in {a, b, c, d} ==> num <= x);
- {
- if (a <= b && (a <= c && a <= d)) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- if (d <= a && (d <= b && d <= c)) {
- this.num := d;
- // repr stuff
- this.Repr := {this};
- } else {
- if (c <= a && (c <= b && c <= d)) {
- this.num := c;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
- }
-
-
- method MinSum(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a + b, a + c, b + c};
- ensures num <= a + b;
- ensures num <= b + c;
- ensures num <= a + c;
- {
- if (a + b <= b + c && a + b <= a + c) {
- this.num := a + b;
- // repr stuff
- this.Repr := {this};
- } else {
- if (a + c <= a + b && a + c <= b + c) {
- this.num := a + c;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b + c;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
-
-
- method Min32(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c};
- ensures (forall x :: x in {a, b, c} ==> num <= x);
- {
- if (a <= b && a <= c) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- if (c <= a && c <= b) {
- this.num := c;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
-
-
- method Min3(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c};
- ensures num <= a;
- ensures num <= b;
- ensures num <= c;
- {
- if (a <= b && a <= c) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- if (c <= a && c <= b) {
- this.num := c;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
-
-
- method Min22(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b};
- ensures num <= a;
- ensures num <= b;
- {
- if (a <= b) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
-
-
- method Min2(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures a < b ==> num == a;
- ensures a >= b ==> num == b;
- {
- if (a >= b ==> a == b) {
- this.num := a;
- // repr stuff
- this.Repr := {this};
- } else {
- this.num := b;
- // repr stuff
- this.Repr := {this};
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod/jennisys-synth_Set.dfy b/Jennisys/Jennisys/examples/mod/jennisys-synth_Set.dfy
deleted file mode 100644
index 40404bfb..00000000
--- a/Jennisys/Jennisys/examples/mod/jennisys-synth_Set.dfy
+++ /dev/null
@@ -1,388 +0,0 @@
-class Set {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var root: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> elems == {}) &&
- (root != null ==> elems == root.elems)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- var gensym67 := new SetNode;
- gensym67._synth_Set_Double_gensym67(p, q);
- this.elems := {p, q};
- this.root := gensym67;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {};
- {
- this.elems := {};
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Singleton(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- var gensym67 := new SetNode;
- gensym67._synth_Set_Singleton_gensym67(t);
- this.elems := {t};
- this.root := gensym67;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p + q};
- {
- var gensym69 := new SetNode;
- gensym69._synth_Set_Sum_gensym69(p, q);
- this.elems := {p + q};
- this.root := gensym69;
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class SetNode {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var data: int;
- var left: SetNode;
- var right: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (left != null ==> left in Repr && left.Repr <= Repr && this !in left.Repr) &&
- (right != null ==> right in Repr && right.Repr <= Repr && this !in right.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (elems == ({data} + (if left != null then left.elems else {})) + (if right != null then right.elems else {})) &&
- (left != null ==> (forall e :: e in left.elems ==> e < data)) &&
- (right != null ==> (forall e :: e in right.elems ==> e > data))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (left != null ==> left.Valid_self()) &&
- (right != null ==> right.Valid_self()) &&
- (left != null && left.left != null ==> left.left.Valid_self()) &&
- (left != null && left.right != null ==> left.right.Valid_self()) &&
- (right != null && right.left != null ==> right.left.Valid_self()) &&
- (right != null && right.right != null ==> right.right.Valid_self())
- }
-
-
- method Double(p: int, q: int)
- modifies this;
- requires p != q;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- if (q > p) {
- var gensym77 := new SetNode;
- gensym77._synth_SetNode_Double_gensym77(q);
- this.data := p;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym77;
- // repr stuff
- this.Repr := {this} + this.right.Repr;
- } else {
- var gensym77 := new SetNode;
- gensym77._synth_SetNode_Double_gensym77(p);
- this.data := q;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym77;
- // repr stuff
- this.Repr := {this} + this.right.Repr;
- }
- }
-
-
- method _synth_SetNode_Double_gensym77(q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {q};
- {
- this.data := q;
- this.elems := {q};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_SetNode_Triple_gensym80(r: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {r};
- {
- this.data := r;
- this.elems := {r};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Triple(p: int, q: int, r: int)
- modifies this;
- requires p != q;
- requires q != r;
- requires r != p;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q, r};
- {
- if (p < q && r > q) {
- var gensym80 := new SetNode;
- var gensym81 := new SetNode;
- gensym80._synth_SetNode_Triple_gensym80(r);
- gensym81._synth_SetNode_Triple_gensym81(p);
- this.data := q;
- this.elems := {p, q, r};
- this.left := gensym81;
- this.right := gensym80;
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (r < p && q > p) {
- var gensym80 := new SetNode;
- var gensym81 := new SetNode;
- gensym80._synth_SetNode_Triple_gensym80(q);
- gensym81._synth_SetNode_Triple_gensym81(r);
- this.data := p;
- this.elems := {p, q, r};
- this.left := gensym81;
- this.right := gensym80;
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (p < r && q > r) {
- var gensym80 := new SetNode;
- var gensym81 := new SetNode;
- gensym80._synth_SetNode_Triple_gensym80(q);
- gensym81._synth_SetNode_Triple_gensym81(p);
- this.data := r;
- this.elems := {p, q, r};
- this.left := gensym81;
- this.right := gensym80;
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (r < q && p > q) {
- var gensym80 := new SetNode;
- var gensym81 := new SetNode;
- gensym80._synth_SetNode_Triple_gensym80(p);
- gensym81._synth_SetNode_Triple_gensym81(r);
- this.data := q;
- this.elems := {p, q, r};
- this.left := gensym81;
- this.right := gensym80;
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (q < r && p > r) {
- var gensym80 := new SetNode;
- var gensym81 := new SetNode;
- gensym80._synth_SetNode_Triple_gensym80(p);
- gensym81._synth_SetNode_Triple_gensym81(q);
- this.data := r;
- this.elems := {p, q, r};
- this.left := gensym81;
- this.right := gensym80;
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- var gensym80 := new SetNode;
- var gensym81 := new SetNode;
- gensym80._synth_SetNode_Triple_gensym80(r);
- gensym81._synth_SetNode_Triple_gensym81(q);
- this.data := p;
- this.elems := {p, q, r};
- this.left := gensym81;
- this.right := gensym80;
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- }
- }
- }
- }
- }
- }
-
-
- method _synth_SetNode_Triple_gensym81(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p};
- {
- this.data := p;
- this.elems := {p};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Init(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- this.data := t;
- this.elems := {t};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_SetNode__synth_Set_Double_gensym67_gensym77(q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {q};
- {
- this.data := q;
- this.elems := {q};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_Set_Double_gensym67(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- if (q > p) {
- var gensym77 := new SetNode;
- gensym77._synth_SetNode__synth_Set_Double_gensym67_gensym77(q);
- this.data := p;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym77;
- // repr stuff
- this.Repr := {this} + this.right.Repr;
- } else {
- if (p > q) {
- var gensym77 := new SetNode;
- gensym77._synth_SetNode__synth_Set_Double_gensym67_gensym77(p);
- this.data := q;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym77;
- // repr stuff
- this.Repr := {this} + this.right.Repr;
- } else {
- this.data := q;
- this.elems := {p, q};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
- }
- }
-
-
- method _synth_Set_Singleton_gensym67(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- this.data := t;
- this.elems := {t};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_Set_Sum_gensym69(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p + q};
- {
- this.data := p + q;
- this.elems := {p + q};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod2/jennisys-synth_DList.dfy b/Jennisys/Jennisys/examples/mod2/jennisys-synth_DList.dfy
deleted file mode 100644
index 3e1aa99f..00000000
--- a/Jennisys/Jennisys/examples/mod2/jennisys-synth_DList.dfy
+++ /dev/null
@@ -1,255 +0,0 @@
-class DList<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var root: DNode<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> |list| == 0) &&
- (root != null ==> list == root.list)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym79 := new DNode<T>;
- var gensym85 := new DNode<T>;
- this.list := [p, q];
- this.root := gensym79;
- gensym79.data := p;
- gensym79.list := [p, q];
- gensym79.next := gensym85;
- gensym79.prev := null;
- gensym85.data := q;
- gensym85.list := [q];
- gensym85.next := null;
- gensym85.prev := gensym79;
-
- // repr stuff
- gensym85.Repr := {gensym85};
- gensym79.Repr := {gensym79} + {gensym85};
- this.Repr := {this} + ({gensym79} + {gensym85});
- // assert repr objects are valid (helps verification)
- assert gensym79.Valid() && gensym85.Valid();
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- ensures |list| == 0;
- {
- this.list := [];
- this.root := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Singleton(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- ensures list[0] == t;
- ensures |list| == 1;
- {
- var gensym78 := new DNode<T>;
- this.list := [t];
- this.root := gensym78;
- gensym78.data := t;
- gensym78.list := [t];
- gensym78.next := null;
- gensym78.prev := null;
-
- // repr stuff
- gensym78.Repr := {gensym78};
- this.Repr := {this} + {gensym78};
- // assert repr objects are valid (helps verification)
- assert gensym78.Valid();
- }
-
-}
-
-class DNode<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var data: T;
- var next: DNode<T>;
- var prev: DNode<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> (list == [data] && list[0] == data) && |list| == 1) &&
- (next != null ==> list == [data] + next.list && next.prev == this) &&
- (prev != null ==> prev.next == this) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid()) &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym95 := new DNode<T>;
- this.data := p;
- this.list := [p, q];
- this.next := gensym95;
- this.prev := null;
- gensym95.data := q;
- gensym95.list := [q];
- gensym95.next := null;
- gensym95.prev := this;
-
- // repr stuff
- this.Repr := {this} + {gensym95};
- gensym95.Repr := {gensym95};
- // assert repr objects are valid (helps verification)
- assert gensym95.Valid();
- }
-
-
- method Find(n: T) returns (ret: bool)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == (n in list);
- decreases Repr;
- {
- if (this.next == null) {
- ret := n == this.data;
- } else {
- var x_5 := this.next.Find(n);
- ret := n == this.data || x_5;
- }
- }
-
-
- method Get(idx: int) returns (ret: T)
- requires Valid();
- requires idx >= 0;
- requires idx < |list|;
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list[idx];
- decreases Repr;
- {
- if (this.next == null) {
- ret := this.data;
- } else {
- if (idx == 0) {
- ret := this.data;
- } else {
- var x_6 := this.next.Get(idx - 1);
- ret := x_6;
- }
- }
- }
-
-
- method Init(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- ensures list[0] == t;
- ensures |list| == 1;
- {
- this.data := t;
- this.list := [t];
- this.next := null;
- this.prev := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method List() returns (ret: seq<T>)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list;
- decreases Repr;
- {
- if (this.next == null) {
- ret := [this.data];
- } else {
- var x_7 := this.next.List();
- ret := [this.data] + x_7;
- }
- }
-
-
- method Size() returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == |list|;
- decreases Repr;
- {
- if (this.next == null) {
- ret := 1;
- } else {
- var x_8 := this.next.Size();
- ret := 1 + x_8;
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod2/jennisys-synth_List.dfy b/Jennisys/Jennisys/examples/mod2/jennisys-synth_List.dfy
deleted file mode 100644
index 9939dcc2..00000000
--- a/Jennisys/Jennisys/examples/mod2/jennisys-synth_List.dfy
+++ /dev/null
@@ -1,249 +0,0 @@
-class List<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var root: Node<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> |list| == 0) &&
- (root != null ==> list == root.list)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym78 := new Node<T>;
- gensym78.Double(p, q);
- this.list := [p, q];
- this.root := gensym78;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym78.Valid();
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- ensures |list| == 0;
- {
- this.list := [];
- this.root := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Singleton(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- ensures list[0] == t;
- ensures |list| == 1;
- {
- var gensym77 := new Node<T>;
- gensym77.Init(t);
- this.list := [t];
- this.root := gensym77;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym77.Valid();
- }
-
-}
-
-class Node<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var data: T;
- var next: Node<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> (list == [data] && list[0] == data) && |list| == 1) &&
- (next != null ==> list == [data] + next.list) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid()) &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym87 := new Node<T>;
- gensym87.Init(q);
- this.data := p;
- this.list := [p, q];
- this.next := gensym87;
-
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym87.Valid();
- }
-
-
- method Find(n: T) returns (ret: bool)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == (n in list);
- decreases Repr;
- {
- if (n != this.data && this.next == null) {
- ret := n == this.data;
- } else {
- if (this.next != null) {
- var x_6 := this.next.Find(n);
- ret := n == this.data || x_6;
- } else {
- ret := true;
- }
- }
- }
-
-
- method Get(idx: int) returns (ret: T)
- requires Valid();
- requires idx >= 0;
- requires idx < |list|;
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list[idx];
- decreases Repr;
- {
- if (this.next == null) {
- ret := this.data;
- } else {
- if (idx == 0) {
- ret := this.data;
- } else {
- var x_7 := this.next.Get(idx - 1);
- ret := x_7;
- }
- }
- }
-
-
- method Init(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- ensures list[0] == t;
- ensures |list| == 1;
- {
- this.data := t;
- this.list := [t];
- this.next := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method List() returns (ret: seq<T>)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list;
- decreases Repr;
- {
- if (this.next == null) {
- ret := [this.data];
- } else {
- var x_8 := this.next.List();
- ret := [this.data] + x_8;
- }
- }
-
-
- method Size() returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == |list|;
- decreases Repr;
- {
- if (this.next == null) {
- ret := 1;
- } else {
- var x_9 := this.next.Size();
- ret := 1 + x_9;
- }
- }
-
-
- method Tail() returns (tail: Node<T>)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures |list| == 1 ==> tail == null;
- ensures |list| > 1 ==> tail != null && tail.list == list[1..];
- ensures tail != null ==> tail.Valid();
- {
- tail := this.next;
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod2/jennisys-synth_List2.dfy b/Jennisys/Jennisys/examples/mod2/jennisys-synth_List2.dfy
deleted file mode 100644
index f994186b..00000000
--- a/Jennisys/Jennisys/examples/mod2/jennisys-synth_List2.dfy
+++ /dev/null
@@ -1,225 +0,0 @@
-class IntList {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var root: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null <==> |list| == 0) &&
- (root != null ==> list == root.list)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym74 := new IntNode;
- gensym74.Double(p, q);
- this.list := [p] + [q];
- this.root := gensym74;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym74.Valid();
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- ensures |list| == 0;
- {
- this.list := [];
- this.root := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [1, 2];
- ensures list[0] == 1;
- ensures list[1] == 2;
- ensures |list| == 2;
- {
- this.Double(1, 2);
- }
-
-
- method Singleton(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p];
- ensures list[0] == p;
- ensures |list| == 1;
- {
- var gensym73 := new IntNode;
- gensym73.Init(p);
- this.list := [p];
- this.root := gensym73;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym73.Valid();
- }
-
-
- method SingletonTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [2];
- ensures list[0] == 2;
- ensures |list| == 1;
- {
- this.Singleton(2);
- }
-
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p + q];
- ensures list[0] == p + q;
- ensures |list| == 1;
- {
- this.Singleton(p + q);
- }
-
-
- method TwoConsecutive(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [p + 1];
- ensures list[0] == p;
- ensures list[1] == p + 1;
- ensures |list| == 2;
- {
- this.Double(p, p + 1);
- }
-
-}
-
-class IntNode {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var data: int;
- var next: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> (list == [data] && list[0] == data) && |list| == 1) &&
- (next != null ==> list == [data] + next.list) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid()) &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Double(x: int, y: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [x, y];
- ensures list[0] == x;
- ensures list[1] == y;
- ensures |list| == 2;
- {
- var gensym87 := new IntNode;
- gensym87.Init(y);
- this.data := x;
- this.list := [x, y];
- this.next := gensym87;
-
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym87.Valid();
- }
-
-
- method Init(x: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [x];
- ensures list[0] == x;
- ensures |list| == 1;
- {
- this.data := x;
- this.list := [x];
- this.next := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method SingletonZero()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [0];
- ensures list[0] == 0;
- ensures |list| == 1;
- {
- this.Init(0);
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod2/jennisys-synth_List3.dfy b/Jennisys/Jennisys/examples/mod2/jennisys-synth_List3.dfy
deleted file mode 100644
index 65e308bd..00000000
--- a/Jennisys/Jennisys/examples/mod2/jennisys-synth_List3.dfy
+++ /dev/null
@@ -1,309 +0,0 @@
-class IntList {
- ghost var Repr: set<object>;
- ghost var list: seq<int>;
-
- var root: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> |list| == 0) &&
- (root != null ==> |list| == |root.succ| + 1 && (list[0] == root.data && (forall i :: 1 <= i && i <= |root.succ| ==> root.succ[i - 1] != null && list[i] == root.succ[i - 1].data)))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym79 := new IntNode;
- gensym79._synth_IntList_Double_gensym79(p, q);
- this.list := [p] + [q];
- this.root := gensym79;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym79.Valid();
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [];
- ensures |list| == 0;
- {
- this.list := [];
- this.root := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [1, 2];
- ensures list[0] == 1;
- ensures list[1] == 2;
- ensures |list| == 2;
- {
- this.Double(1, 2);
- }
-
-
- method Singleton(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p];
- ensures list[0] == p;
- ensures |list| == 1;
- {
- var gensym77 := new IntNode;
- gensym77._synth_IntList_Singleton_gensym77(p);
- this.list := [p];
- this.root := gensym77;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym77.Valid();
- }
-
-
- method SingletonTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [2];
- ensures list[0] == 2;
- ensures |list| == 1;
- {
- this.Singleton(2);
- }
-
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p + q];
- ensures list[0] == p + q;
- ensures |list| == 1;
- {
- this.Singleton(p + q);
- }
-
-
- method TwoConsecutive(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p] + [p + 1];
- ensures list[0] == p;
- ensures list[1] == p + 1;
- ensures |list| == 2;
- {
- this.Double(p, p + 1);
- }
-
-}
-
-class IntNode {
- ghost var Repr: set<object>;
- ghost var succ: seq<IntNode>;
- ghost var data: int;
-
- var next: IntNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> |succ| == 0) &&
- (next != null ==> succ == [next] + next.succ) &&
- (!(null in succ))
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid()) &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Init(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- {
- this.data := p;
- this.next := null;
- this.succ := [];
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method InitInc(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p + 1;
- {
- this.Init(p + 1);
- }
-
-
- method OneTwo()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 1;
- ensures |succ| == 1;
- ensures succ[0] != null;
- ensures succ[0].data == 2;
- {
- var gensym83 := new IntNode;
- gensym83._synth_IntNode_OneTwo_gensym83();
- this.data := 1;
- this.next := gensym83;
- this.succ := [gensym83];
-
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym83.Valid();
- }
-
-
- method Zero()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 0;
- ensures succ == [];
- ensures |succ| == 0;
- {
- this.data := 0;
- this.next := null;
- this.succ := [];
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntList_Double_gensym79(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- ensures |succ| == 1;
- ensures succ[0].data == q;
- ensures succ[0].succ == [];
- ensures |succ[0].succ| == 0;
- {
- var gensym93 := new IntNode;
- gensym93._synth_IntNode__synth_IntList_Double_gensym79_gensym93(q);
- this.data := p;
- this.next := gensym93;
- this.succ := [gensym93];
-
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym93.Valid();
- }
-
-
- method _synth_IntList_Singleton_gensym77(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == p;
- ensures |succ| == 0;
- {
- this.data := p;
- this.next := null;
- this.succ := [];
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntNode_OneTwo_gensym83()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == 2;
- ensures |succ| == 0;
- {
- this.data := 2;
- this.next := null;
- this.succ := [];
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method _synth_IntNode__synth_IntList_Double_gensym79_gensym93(q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures data == q;
- ensures |succ| == 0;
- {
- this.data := q;
- this.next := null;
- this.succ := [];
-
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod2/jennisys-synth_Number.dfy b/Jennisys/Jennisys/examples/mod2/jennisys-synth_Number.dfy
deleted file mode 100644
index 9bb3c398..00000000
--- a/Jennisys/Jennisys/examples/mod2/jennisys-synth_Number.dfy
+++ /dev/null
@@ -1,181 +0,0 @@
-class Number {
- ghost var Repr: set<object>;
- ghost var num: int;
-
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- true
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- true
- }
-
-
- method Abs(a: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, -a};
- ensures num >= 0;
- {
- if (a >= 0) {
- this.Init(a);
- } else {
- this.Init(-a);
- }
- }
-
-
- method Double(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == 2 * p;
- {
- this.Init(2 * p);
- }
-
-
- method Init(p: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == p;
- {
- this.num := p;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Min2(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures a < b ==> num == a;
- ensures a >= b ==> num == b;
- {
- if (a < b) {
- this.Init(a);
- } else {
- this.Init(b);
- }
- }
-
-
- method Min22(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b};
- ensures num <= a;
- ensures num <= b;
- {
- if (a <= b) {
- this.Init(a);
- } else {
- this.Init(b);
- }
- }
-
-
- method Min3(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c};
- ensures num <= a;
- ensures num <= b;
- ensures num <= c;
- {
- this.Min32(a, b, c);
- }
-
-
- method Min32(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c};
- ensures num <= a;
- ensures num <= b;
- ensures num <= c;
- {
- if (a <= b && a <= c) {
- this.Init(a);
- } else {
- if (c <= a && c <= b) {
- this.Init(c);
- } else {
- this.Init(b);
- }
- }
- }
-
-
- method Min4(a: int, b: int, c: int, d: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a, b, c, d};
- ensures num <= a;
- ensures num <= b;
- ensures num <= c;
- ensures num <= d;
- {
- if ((a <= b && a <= c) && a <= d) {
- this.Init(a);
- } else {
- if ((d <= a && d <= b) && d <= c) {
- this.Init(d);
- } else {
- if ((c <= a && c <= b) && c <= d) {
- this.Init(c);
- } else {
- this.Init(b);
- }
- }
- }
- }
-
-
- method MinSum(a: int, b: int, c: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num in {a + b, a + c, b + c};
- ensures num <= a + b;
- ensures num <= b + c;
- ensures num <= a + c;
- {
- this.Min3(a + b, b + c, a + c);
- }
-
-
- method Sum(a: int, b: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures num == a + b;
- {
- this.Init(a + b);
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod2/jennisys-synth_NumberMethods.dfy b/Jennisys/Jennisys/examples/mod2/jennisys-synth_NumberMethods.dfy
deleted file mode 100644
index b20e2741..00000000
--- a/Jennisys/Jennisys/examples/mod2/jennisys-synth_NumberMethods.dfy
+++ /dev/null
@@ -1,167 +0,0 @@
-class NumberMethods {
- ghost var Repr: set<object>;
-
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- true
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- true
- }
-
-
- method Abs(a: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a, -a};
- ensures ret >= 0;
- {
- if (-a >= 0) {
- ret := -a;
- } else {
- ret := a;
- }
- }
-
-
- method Double(p: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == 2 * p;
- {
- ret := 2 * p;
- }
-
-
- method Min2(a: int, b: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures a < b ==> ret == a;
- ensures a >= b ==> ret == b;
- {
- if (a < b) {
- ret := a;
- } else {
- ret := b;
- }
- }
-
-
- method Min22(a: int, b: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a, b};
- ensures ret <= a;
- ensures ret <= b;
- {
- if (a <= b) {
- ret := a;
- } else {
- ret := b;
- }
- }
-
-
- method Min3(a: int, b: int, c: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a, b, c};
- ensures ret <= a;
- ensures ret <= b;
- ensures ret <= c;
- {
- ret := this.Min32(a, b, c);
- }
-
-
- method Min32(a: int, b: int, c: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a, b, c};
- ensures ret <= a;
- ensures ret <= b;
- ensures ret <= c;
- {
- if (a <= b && a <= c) {
- ret := a;
- } else {
- if (c <= a && c <= b) {
- ret := c;
- } else {
- ret := b;
- }
- }
- }
-
-
- method Min4(a: int, b: int, c: int, d: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a, b, c, d};
- ensures ret <= a;
- ensures ret <= b;
- ensures ret <= c;
- ensures ret <= d;
- {
- if ((a <= b && a <= c) && a <= d) {
- ret := a;
- } else {
- if ((d <= a && d <= b) && d <= c) {
- ret := d;
- } else {
- if ((c <= a && c <= b) && c <= d) {
- ret := c;
- } else {
- ret := b;
- }
- }
- }
- }
-
-
- method MinSum(a: int, b: int, c: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a + b, a + c, b + c};
- ensures ret <= a + b;
- ensures ret <= b + c;
- ensures ret <= a + c;
- {
- ret := this.Min3(a + b, b + c, a + c);
- }
-
-
- method Sum(a: int, b: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == a + b;
- {
- ret := a + b;
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/mod2/jennisys-synth_Set.dfy b/Jennisys/Jennisys/examples/mod2/jennisys-synth_Set.dfy
deleted file mode 100644
index fea364d6..00000000
--- a/Jennisys/Jennisys/examples/mod2/jennisys-synth_Set.dfy
+++ /dev/null
@@ -1,304 +0,0 @@
-class Set {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var root: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> elems == {}) &&
- (root != null ==> elems == root.elems)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
-
- method Double(p: int, q: int)
- modifies this;
- requires p != q;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- var gensym80 := new SetNode;
- gensym80.Double(p, q);
- this.elems := {q, p};
- this.root := gensym80;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym80.Valid();
- }
-
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {};
- {
- this.elems := {};
- this.root := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Singleton(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- var gensym75 := new SetNode;
- gensym75.Init(t);
- this.elems := {t};
- this.root := gensym75;
-
- // repr stuff
- this.Repr := {this} + this.root.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym75.Valid();
- }
-
-
- method SingletonZero()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {0};
- {
- this.Singleton(0);
- }
-
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p + q};
- {
- this.Singleton(p + q);
- }
-
-}
-
-class SetNode {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var data: int;
- var left: SetNode;
- var right: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (left != null ==> left in Repr && left.Repr <= Repr && this !in left.Repr) &&
- (right != null ==> right in Repr && right.Repr <= Repr && this !in right.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (elems == ({data} + (if left != null then left.elems else {})) + (if right != null then right.elems else {})) &&
- (left != null ==> (forall e :: e in left.elems ==> e < data)) &&
- (right != null ==> (forall e :: e in right.elems ==> e > data))
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (left != null ==> left.Valid()) &&
- (right != null ==> right.Valid()) &&
- (left != null ==> left.Valid_self()) &&
- (right != null ==> right.Valid_self()) &&
- (left != null && left.left != null ==> left.left.Valid_self()) &&
- (left != null && left.right != null ==> left.right.Valid_self()) &&
- (right != null && right.left != null ==> right.left.Valid_self()) &&
- (right != null && right.right != null ==> right.right.Valid_self())
- }
-
-
- method Double(a: int, b: int)
- modifies this;
- requires a != b;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {a, b};
- {
- if (b > a) {
- this.DoubleBase(b, a);
- } else {
- var gensym88 := new SetNode;
- gensym88.Init(a);
- this.data := b;
- this.elems := {b, a};
- this.left := null;
- this.right := gensym88;
-
- // repr stuff
- this.Repr := {this} + this.right.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym88.Valid();
- }
- }
-
-
- method DoubleBase(x: int, y: int)
- modifies this;
- requires x > y;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x, y};
- {
- var gensym88 := new SetNode;
- gensym88.Init(x);
- this.data := y;
- this.elems := {y, x};
- this.left := null;
- this.right := gensym88;
-
- // repr stuff
- this.Repr := {this} + this.right.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym88.Valid();
- }
-
-
- method Find(n: int) returns (ret: bool)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == (n in elems);
- decreases Repr;
- {
- if (this.left != null && this.right != null) {
- var x_9 := this.left.Find(n);
- var x_10 := this.right.Find(n);
- ret := (n == this.data || x_9) || x_10;
- } else {
- if (this.left != null && this.right == null) {
- var x_11 := this.left.Find(n);
- ret := n == this.data || x_11;
- } else {
- if (this.right != null && this.left == null) {
- var x_12 := this.right.Find(n);
- ret := n == this.data || x_12;
- } else {
- ret := n == this.data;
- }
- }
- }
- }
-
-
- method Init(x: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x};
- {
- this.data := x;
- this.elems := {x};
- this.left := null;
- this.right := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Triple(x: int, y: int, z: int)
- modifies this;
- requires x != y;
- requires y != z;
- requires z != x;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x, y, z};
- {
- if (z < x && y > x) {
- this.TripleBase(z, x, y);
- } else {
- if (x < y && z > y) {
- this.TripleBase(x, y, z);
- } else {
- if (x < z && y > z) {
- this.TripleBase(x, z, y);
- } else {
- if (y < z && x > z) {
- this.TripleBase(y, z, x);
- } else {
- if (z < y && x > y) {
- this.TripleBase(z, y, x);
- } else {
- var gensym82 := new SetNode;
- var gensym83 := new SetNode;
- gensym82.Init(y);
- gensym83.Init(z);
- this.data := x;
- this.elems := {y, x, z};
- this.left := gensym82;
- this.right := gensym83;
-
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym82.Valid() && gensym83.Valid();
- }
- }
- }
- }
- }
- }
-
-
- method TripleBase(x: int, y: int, z: int)
- modifies this;
- requires x < y;
- requires y < z;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x, y, z};
- {
- var gensym89 := new SetNode;
- var gensym90 := new SetNode;
- gensym89.Init(z);
- gensym90.Init(x);
- this.data := y;
- this.elems := {x, y, z};
- this.left := gensym90;
- this.right := gensym89;
-
- // repr stuff
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym89.Valid() && gensym90.Valid();
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/oopsla12/BHeap.jen b/Jennisys/Jennisys/examples/oopsla12/BHeap.jen
deleted file mode 100644
index 41ebec85..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/BHeap.jen
+++ /dev/null
@@ -1,34 +0,0 @@
-interface BHeap {
- var elems: set[int]
-
- constructor Singleton(x: int)
- elems := {x}
-
- constructor Dupleton(a: int, b: int)
- requires a != b
- elems := {a b}
-
- constructor Tripleton(x: int, y: int, z: int)
- requires x != y && y != z && z != x
- elems := {x y z}
-
- method Find(n: int) returns (ret: bool)
- ret := n in elems
-}
-
-datamodel BHeap {
- var data: int
- var left: BHeap
- var right: BHeap
-
- frame
- left * right
-
- invariant
- elems = {data} + (left != null ? left.elems : {})
- + (right != null ? right.elems : {})
- left != null ==> forall e :: e in left.elems ==> e < data
- right != null ==> forall e :: e in right.elems ==> e < data
- left = null ==> right = null
- left != null && right = null ==> left.elems = {left.data}
-} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/oopsla12/BHeap_synth.dfy b/Jennisys/Jennisys/examples/oopsla12/BHeap_synth.dfy
deleted file mode 100644
index addba4ae..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/BHeap_synth.dfy
+++ /dev/null
@@ -1,220 +0,0 @@
-class BHeap {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var data: int;
- var left: BHeap;
- var right: BHeap;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (left != null ==> left in Repr && left.Repr <= Repr && this !in left.Repr) &&
- (right != null ==> right in Repr && right.Repr <= Repr && this !in right.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (elems == ({data} + (if left != null then left.elems else {})) + (if right != null then right.elems else {})) &&
- (left != null ==> (forall e :: e in left.elems ==> e < data)) &&
- (right != null ==> (forall e :: e in right.elems ==> e < data)) &&
- (left == null ==> right == null) &&
- (left != null && right == null ==> left.elems == {left.data})
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (left != null ==> left.Valid()) &&
- (right != null ==> right.Valid()) &&
- (left != null ==> left.Valid_self()) &&
- (right != null ==> right.Valid_self()) &&
- (left != null && left.left != null ==> left.left.Valid_self()) &&
- (left != null && left.right != null ==> left.right.Valid_self()) &&
- (right != null && right.left != null ==> right.left.Valid_self()) &&
- (right != null && right.right != null ==> right.right.Valid_self())
- }
-
-
- method Dupleton(a: int, b: int)
- modifies this;
- requires a != b;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {a, b};
- {
- if (b < a) {
- var gensym71 := new BHeap;
- var gensym73 := new BHeap;
- this.data := a;
- this.elems := {b, a};
- this.left := gensym73;
- this.right := gensym71;
- gensym71.data := b;
- gensym71.elems := {b};
- gensym71.left := null;
- gensym71.right := null;
- gensym73.data := b;
- gensym73.elems := {b};
- gensym73.left := null;
- gensym73.right := null;
-
- // repr stuff
- gensym71.Repr := {gensym71};
- gensym73.Repr := {gensym73};
- this.Repr := ({this} + {gensym73}) + {gensym71};
- // assert repr objects are valid (helps verification)
- assert gensym71.Valid() && gensym73.Valid();
- } else {
- var gensym71 := new BHeap;
- var gensym73 := new BHeap;
- this.data := b;
- this.elems := {a, b};
- this.left := gensym73;
- this.right := gensym71;
- gensym71.data := a;
- gensym71.elems := {a};
- gensym71.left := null;
- gensym71.right := null;
- gensym73.data := a;
- gensym73.elems := {a};
- gensym73.left := null;
- gensym73.right := null;
-
- // repr stuff
- gensym71.Repr := {gensym71};
- gensym73.Repr := {gensym73};
- this.Repr := ({this} + {gensym73}) + {gensym71};
- // assert repr objects are valid (helps verification)
- assert gensym71.Valid() && gensym73.Valid();
- }
- }
-
-
- method Find(n: int) returns (ret: bool)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == (n in elems);
- decreases Repr;
- {
- if (this.left == null) {
- ret := n == this.data;
- } else {
- if (this.right != null) {
- var x_10 := this.left.Find(n);
- var x_11 := this.right.Find(n);
- ret := (n == this.data || x_10) || x_11;
- } else {
- var x_12 := this.left.Find(n);
- ret := n == this.data || x_12;
- }
- }
- }
-
-
- method Singleton(x: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x};
- {
- this.data := x;
- this.elems := {x};
- this.left := null;
- this.right := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Tripleton(x: int, y: int, z: int)
- modifies this;
- requires x != y;
- requires y != z;
- requires z != x;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x, y, z};
- {
- if (z < y && x < y) {
- var gensym75 := new BHeap;
- var gensym77 := new BHeap;
- this.data := y;
- this.elems := {z, x, y};
- this.left := gensym77;
- this.right := gensym75;
- gensym75.data := x;
- gensym75.elems := {x};
- gensym75.left := null;
- gensym75.right := null;
- gensym77.data := z;
- gensym77.elems := {z};
- gensym77.left := null;
- gensym77.right := null;
-
- // repr stuff
- gensym75.Repr := {gensym75};
- gensym77.Repr := {gensym77};
- this.Repr := ({this} + {gensym77}) + {gensym75};
- // assert repr objects are valid (helps verification)
- assert gensym75.Valid() && gensym77.Valid();
- } else {
- if (x < z) {
- var gensym75 := new BHeap;
- var gensym77 := new BHeap;
- this.data := z;
- this.elems := {x, y, z};
- this.left := gensym77;
- this.right := gensym75;
- gensym75.data := x;
- gensym75.elems := {x};
- gensym75.left := null;
- gensym75.right := null;
- gensym77.data := y;
- gensym77.elems := {y};
- gensym77.left := null;
- gensym77.right := null;
-
- // repr stuff
- gensym75.Repr := {gensym75};
- gensym77.Repr := {gensym77};
- this.Repr := ({this} + {gensym77}) + {gensym75};
- // assert repr objects are valid (helps verification)
- assert gensym75.Valid() && gensym77.Valid();
- } else {
- var gensym75 := new BHeap;
- var gensym77 := new BHeap;
- this.data := x;
- this.elems := {z, y, x};
- this.left := gensym77;
- this.right := gensym75;
- gensym75.data := y;
- gensym75.elems := {y};
- gensym75.left := null;
- gensym75.right := null;
- gensym77.data := z;
- gensym77.elems := {z};
- gensym77.left := null;
- gensym77.right := null;
-
- // repr stuff
- gensym75.Repr := {gensym75};
- gensym77.Repr := {gensym77};
- this.Repr := ({this} + {gensym77}) + {gensym75};
- // assert repr objects are valid (helps verification)
- assert gensym75.Valid() && gensym77.Valid();
- }
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/oopsla12/DList.jen b/Jennisys/Jennisys/examples/oopsla12/DList.jen
deleted file mode 100644
index 7e087f95..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/DList.jen
+++ /dev/null
@@ -1,40 +0,0 @@
-interface DList[T] {
- var list: seq[T]
-
- invariant
- |list| > 0
-
- constructor Init(t: T)
- list := [t]
-
- constructor Double(p: T, q: T)
- list := [p q]
-
- method List() returns (ret: seq[T])
- ret := list
-
- method Size() returns (ret: int)
- ret := |list|
-
- method Get(idx: int) returns (ret: T)
- requires 0 <= idx && idx < |list|
- ret := list[idx]
-
- method Find(n: T) returns (ret: bool)
- ret := n in list
-}
-
-datamodel DList[T] {
- var data: T
- var next: DList[T]
- var prev: DList[T]
-
- frame
- next
-
- invariant
- next = null ==> list = [data]
- next != null ==> (list = [data] + next.list
- && next.prev = this)
- prev != null ==> prev.next = this
-} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/oopsla12/DList_synth.dfy b/Jennisys/Jennisys/examples/oopsla12/DList_synth.dfy
deleted file mode 100644
index 897a6de0..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/DList_synth.dfy
+++ /dev/null
@@ -1,154 +0,0 @@
-class DList<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var data: T;
- var next: DList<T>;
- var prev: DList<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> (list == [data] && list[0] == data) && |list| == 1) &&
- (next != null ==> list == [data] + next.list && next.prev == this) &&
- (prev != null ==> prev.next == this) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid()) &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Double(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym71 := new DList<T>;
- this.data := p;
- this.list := [p, q];
- this.next := gensym71;
- this.prev := null;
- gensym71.data := q;
- gensym71.list := [q];
- gensym71.next := null;
- gensym71.prev := this;
-
- // repr stuff
- this.Repr := {this} + {gensym71};
- gensym71.Repr := {gensym71};
- // assert repr objects are valid (helps verification)
- assert gensym71.Valid();
- }
-
-
- method Find(n: T) returns (ret: bool)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == (n in list);
- decreases Repr;
- {
- if (this.next == null) {
- ret := n == this.data;
- } else {
- var x_5 := this.next.Find(n);
- ret := n == this.data || x_5;
- }
- }
-
-
- method Get(idx: int) returns (ret: T)
- requires Valid();
- requires 0 <= idx;
- requires idx < |list|;
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list[idx];
- decreases Repr;
- {
- if (this.next == null) {
- ret := this.data;
- } else {
- if (idx == 0) {
- ret := this.data;
- } else {
- var x_6 := this.next.Get(idx - 1);
- ret := x_6;
- }
- }
- }
-
-
- method Init(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- ensures list[0] == t;
- ensures |list| == 1;
- {
- this.data := t;
- this.list := [t];
- this.next := null;
- this.prev := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method List() returns (ret: seq<T>)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list;
- decreases Repr;
- {
- if (this.next == null) {
- ret := [this.data];
- } else {
- var x_7 := this.next.List();
- ret := [this.data] + x_7;
- }
- }
-
-
- method Size() returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == |list|;
- decreases Repr;
- {
- if (this.next == null) {
- ret := 1;
- } else {
- var x_8 := this.next.Size();
- ret := 1 + x_8;
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/oopsla12/IntSet.jen b/Jennisys/Jennisys/examples/oopsla12/IntSet.jen
deleted file mode 100644
index 4800371e..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/IntSet.jen
+++ /dev/null
@@ -1,30 +0,0 @@
-interface IntSet {
- var elems: set[int]
-
- constructor Singleton(x: int)
- elems := {x}
-
- constructor Dupleton(x: int, y: int)
- requires x != y
- elems := {x y}
-
- method Find(x: int) returns (ret: bool)
- ret := x in elems
-}
-
-datamodel IntSet {
- var data: int
- var left: IntSet
- var right: IntSet
-
- frame left * right
-
- invariant
- elems = {data} +
- (left != null ? left.elems : {}) +
- (right != null ? right.elems : {})
- left != null ==>
- (forall e :: e in left.elems ==> e < data)
- right != null ==>
- (forall e :: e in right.elems ==> data < e)
-} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/oopsla12/IntSet_synth.dfy b/Jennisys/Jennisys/examples/oopsla12/IntSet_synth.dfy
deleted file mode 100644
index 55523e79..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/IntSet_synth.dfy
+++ /dev/null
@@ -1,130 +0,0 @@
-class IntSet {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var data: int;
- var left: IntSet;
- var right: IntSet;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (left != null ==> left in Repr && left.Repr <= Repr && this !in left.Repr) &&
- (right != null ==> right in Repr && right.Repr <= Repr && this !in right.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (elems == ({data} + (if left != null then left.elems else {})) + (if right != null then right.elems else {})) &&
- (left != null ==> (forall e :: e in left.elems ==> e < data)) &&
- (right != null ==> (forall e :: e in right.elems ==> data < e))
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (left != null ==> left.Valid()) &&
- (right != null ==> right.Valid()) &&
- (left != null ==> left.Valid_self()) &&
- (right != null ==> right.Valid_self()) &&
- (left != null && left.left != null ==> left.left.Valid_self()) &&
- (left != null && left.right != null ==> left.right.Valid_self()) &&
- (right != null && right.left != null ==> right.left.Valid_self()) &&
- (right != null && right.right != null ==> right.right.Valid_self())
- }
-
-
- method Dupleton(x: int, y: int)
- modifies this;
- requires x != y;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x, y};
- {
- if (x < y) {
- var gensym73 := new IntSet;
- this.data := x;
- this.elems := {x, y};
- this.left := null;
- this.right := gensym73;
- gensym73.data := y;
- gensym73.elems := {y};
- gensym73.left := null;
- gensym73.right := null;
-
- // repr stuff
- gensym73.Repr := {gensym73};
- this.Repr := {this} + {gensym73};
- // assert repr objects are valid (helps verification)
- assert gensym73.Valid();
- } else {
- var gensym73 := new IntSet;
- this.data := y;
- this.elems := {y, x};
- this.left := null;
- this.right := gensym73;
- gensym73.data := x;
- gensym73.elems := {x};
- gensym73.left := null;
- gensym73.right := null;
-
- // repr stuff
- gensym73.Repr := {gensym73};
- this.Repr := {this} + {gensym73};
- // assert repr objects are valid (helps verification)
- assert gensym73.Valid();
- }
- }
-
-
- method Find(x: int) returns (ret: bool)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == (x in elems);
- decreases Repr;
- {
- if (this.left != null && this.right != null) {
- var x_13 := this.left.Find(x);
- var x_14 := this.right.Find(x);
- ret := (x == this.data || x_13) || x_14;
- } else {
- if (this.left != null) {
- var x_15 := this.left.Find(x);
- ret := x == this.data || x_15;
- } else {
- if (this.right != null) {
- var x_16 := this.right.Find(x);
- ret := x == this.data || x_16;
- } else {
- ret := x == this.data;
- }
- }
- }
- }
-
-
- method Singleton(x: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {x};
- {
- this.data := x;
- this.elems := {x};
- this.left := null;
- this.right := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/oopsla12/List.jen b/Jennisys/Jennisys/examples/oopsla12/List.jen
deleted file mode 100644
index 10a70050..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/List.jen
+++ /dev/null
@@ -1,29 +0,0 @@
-interface List[T] {
- var list: seq[T]
- invariant |list| > 0
-
- constructor Singleton(t: T)
- list := [t]
- constructor Dupleton(p: T, q: T)
- list := [p q]
- method Elems() returns (ret: seq[T])
- ret := list
- method Get(idx: int) returns (ret: T)
- requires 0 <= idx && idx < |list|
- ret := list[idx]
- method Find(n: T) returns (ret: bool)
- ret := n in list
- method Size() returns (ret: int)
- ret := |list|
-}
-
-datamodel List[T] {
- var data: T
- var next: List[T]
-
- frame next
-
- invariant
- next = null ==> list = [data]
- next != null ==> list = [data] + next.list
-} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/oopsla12/List_synth.dfy b/Jennisys/Jennisys/examples/oopsla12/List_synth.dfy
deleted file mode 100644
index 5cbfa10e..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/List_synth.dfy
+++ /dev/null
@@ -1,146 +0,0 @@
-class List<T> {
- ghost var Repr: set<object>;
- ghost var list: seq<T>;
-
- var data: T;
- var next: List<T>;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (next != null ==> next in Repr && next.Repr <= Repr && this !in next.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (next == null ==> (list == [data] && list[0] == data) && |list| == 1) &&
- (next != null ==> list == [data] + next.list) &&
- (|list| > 0)
- }
-
- function Valid(): bool
- reads *;
- decreases Repr;
- {
- this.Valid_self() &&
- (next != null ==> next.Valid()) &&
- (next != null ==> next.Valid_self()) &&
- (next != null && next.next != null ==> next.next.Valid_self())
- }
-
-
- method Dupleton(p: T, q: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [p, q];
- ensures list[0] == p;
- ensures list[1] == q;
- ensures |list| == 2;
- {
- var gensym71 := new List<T>;
- gensym71.Singleton(q);
- this.data := p;
- this.list := [p, q];
- this.next := gensym71;
-
- // repr stuff
- this.Repr := {this} + this.next.Repr;
- // assert repr objects are valid (helps verification)
- assert gensym71.Valid();
- }
-
-
- method Elems() returns (ret: seq<T>)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list;
- decreases Repr;
- {
- if (this.next == null) {
- ret := [this.data];
- } else {
- var x_5 := this.next.Elems();
- ret := [this.data] + x_5;
- }
- }
-
-
- method Find(n: T) returns (ret: bool)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == (n in list);
- decreases Repr;
- {
- if (this.next == null) {
- ret := n == this.data;
- } else {
- var x_6 := this.next.Find(n);
- ret := n == this.data || x_6;
- }
- }
-
-
- method Get(idx: int) returns (ret: T)
- requires Valid();
- requires 0 <= idx;
- requires idx < |list|;
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == list[idx];
- decreases Repr;
- {
- if (this.next == null) {
- ret := this.data;
- } else {
- if (idx == 0) {
- ret := this.data;
- } else {
- var x_7 := this.next.Get(idx - 1);
- ret := x_7;
- }
- }
- }
-
-
- method Singleton(t: T)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures list == [t];
- ensures list[0] == t;
- ensures |list| == 1;
- {
- this.data := t;
- this.list := [t];
- this.next := null;
-
- // repr stuff
- this.Repr := {this};
- }
-
-
- method Size() returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret == |list|;
- decreases Repr;
- {
- if (this.next == null) {
- ret := 1;
- } else {
- var x_8 := this.next.Size();
- ret := 1 + x_8;
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/oopsla12/Math.jen b/Jennisys/Jennisys/examples/oopsla12/Math.jen
deleted file mode 100644
index 0cc772b3..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/Math.jen
+++ /dev/null
@@ -1,20 +0,0 @@
-interface Math {
- method Min2(a: int, b: int) returns (ret: int)
- ensures a < b ==> ret = a
- ensures a >= b ==> ret = b
-
- method Min3Sum(a: int, b: int, c: int)
- returns (ret: int)
- ensures ret in {a+b a+c b+c}
- ensures forall x :: x in {a+b a+c b+c} ==> ret <= x
-
- method Min4(a: int, b: int, c: int, d: int)
- returns (ret: int)
- ensures ret in {a b c d}
- ensures forall x :: x in {a b c d} ==> ret <= x
-
- method Abs(a: int) returns (ret: int)
- ensures ret in {a (-a)} && ret >= 0
-}
-
-datamodel Math {} \ No newline at end of file
diff --git a/Jennisys/Jennisys/examples/oopsla12/Math_synth.dfy b/Jennisys/Jennisys/examples/oopsla12/Math_synth.dfy
deleted file mode 100644
index 68893b3d..00000000
--- a/Jennisys/Jennisys/examples/oopsla12/Math_synth.dfy
+++ /dev/null
@@ -1,105 +0,0 @@
-class Math {
- ghost var Repr: set<object>;
-
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- true
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- true
- }
-
-
- method Abs(a: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a, -a};
- ensures ret >= 0;
- {
- if (a >= 0) {
- ret := a;
- } else {
- ret := -a;
- }
- }
-
-
- method Min2(a: int, b: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures a < b ==> ret == a;
- ensures a >= b ==> ret == b;
- {
- if (a < b) {
- ret := a;
- } else {
- ret := b;
- }
- }
-
-
- method Min3Sum(a: int, b: int, c: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a + b, a + c, b + c};
- ensures ret <= a + b;
- ensures ret <= a + c;
- ensures ret <= b + c;
- {
- if (a + b <= a + c && a + b <= b + c) {
- ret := a + b;
- } else {
- if (b + c <= a + c) {
- ret := b + c;
- } else {
- ret := a + c;
- }
- }
- }
-
-
- method Min4(a: int, b: int, c: int, d: int) returns (ret: int)
- requires Valid();
- ensures fresh(Repr - old(Repr));
- ensures Valid();
- ensures ret in {a, b, c, d};
- ensures ret <= a;
- ensures ret <= b;
- ensures ret <= c;
- ensures ret <= d;
- {
- if ((a <= b && a <= c) && a <= d) {
- ret := a;
- } else {
- if (d <= b && d <= c) {
- ret := d;
- } else {
- if (c <= b) {
- ret := c;
- } else {
- ret := b;
- }
- }
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/examples/set.dfy b/Jennisys/Jennisys/examples/set.dfy
deleted file mode 100644
index 627f1ecb..00000000
--- a/Jennisys/Jennisys/examples/set.dfy
+++ /dev/null
@@ -1,246 +0,0 @@
-class Set {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var root: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (root != null ==> root in Repr && root.Repr <= Repr && this !in root.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (root == null ==> elems == {}) &&
- (root != null ==> elems == root.elems)
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (root != null ==> root.Valid())
- }
-
- method Empty()
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {};
- {
- this.elems := {};
- this.root := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method Singleton(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- var gensym66 := new SetNode;
- gensym66.Init(t);
- this.elems := {t};
- this.root := gensym66;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Sum(p: int, q: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p + q};
- {
- var gensym68 := new SetNode;
- gensym68.Init(p+q);
- this.elems := {p + q};
- this.root := gensym68;
- this.Repr := {this} + this.root.Repr;
- }
-
- method Double(p: int, q: int)
- modifies this;
- requires p != q;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- var gensym71 := new SetNode;
- gensym71.Double(p, q);
- this.elems := {p, q};
- this.root := gensym71;
- this.Repr := {this} + this.root.Repr;
- }
-
-}
-
-class SetNode {
- ghost var Repr: set<object>;
- ghost var elems: set<int>;
-
- var data: int;
- var left: SetNode;
- var right: SetNode;
-
- function Valid_repr(): bool
- reads *;
- {
- this in Repr &&
- null !in Repr &&
- (left != null ==> left in Repr && left.Repr <= Repr && this !in left.Repr) &&
- (right != null ==> right in Repr && right.Repr <= Repr && this !in right.Repr)
- }
-
- function Valid_self(): bool
- reads *;
- {
- Valid_repr() &&
- (elems == ({data} + (if left != null then left.elems else {})) + (if right != null then right.elems else {})) &&
- (left != null ==> (forall e :: e in left.elems ==> e < data)) &&
- (right != null ==> (forall e :: e in right.elems ==> e > data))
- }
-
- function Valid(): bool
- reads *;
- {
- this.Valid_self() &&
- (left != null ==> left.Valid_self() && (left.left != null ==> left.left.Valid_self())) &&
- (right != null ==> right.Valid_self() && (right.right != null ==> right.right.Valid_self()))
- }
-
- method Init(t: int)
- modifies this;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {t};
- {
- this.data := t;
- this.elems := {t};
- this.left := null;
- this.right := null;
- // repr stuff
- this.Repr := {this};
- }
-
- method Double(p: int, q: int)
- modifies this;
-// requires p != q;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q};
- {
- if (q > p) {
- var gensym79 := new SetNode;
- gensym79.Init(q);
- this.data := p;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym79;
- this.Repr := {this} + this.right.Repr;
- } else if (q < p) {
- var gensym79 := new SetNode;
- gensym79.Init(p);
- this.data := q;
- this.elems := {p, q};
- this.left := null;
- this.right := gensym79;
- this.Repr := {this} + this.right.Repr;
- } else {
- this.data := p;
- this.elems := {p};
- this.left := null;
- this.right := null;
- this.Repr := {this};
- }
- }
-
- method Triple(p: int, q: int, r: int)
- modifies this;
- requires p != q;
- requires q != r;
- requires r != p;
- ensures fresh(Repr - {this});
- ensures Valid();
- ensures elems == {p, q, r};
- {
- if (p < q && r > q) {
- var gensym83 := new SetNode;
- var gensym84 := new SetNode;
- gensym83.Init(r);
- gensym84.Init(p);
- this.data := q;
- this.elems := {p, q, r};
- this.left := gensym84;
- this.right := gensym83;
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (p < r && q > r) {
- var gensym85 := new SetNode;
- var gensym86 := new SetNode;
- gensym85.Init(q);
- gensym86.Init(p);
- this.data := r;
- this.elems := {p, q, r};
- this.left := gensym86;
- this.right := gensym85;
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (r < p && q > p) {
- var gensym84 := new SetNode;
- var gensym85 := new SetNode;
- gensym84.Init(q);
- gensym85.Init(r);
- this.data := p;
- this.elems := {p, q, r};
- this.left := gensym85;
- this.right := gensym84;
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (q < p && r > p) {
- var gensym82 := new SetNode;
- var gensym83 := new SetNode;
- gensym82.Init(r);
- gensym83.Init(q);
- this.data := p;
- this.elems := {p, q, r};
- this.left := gensym83;
- this.right := gensym82;
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- if (q < r && p > r) {
- var gensym85 := new SetNode;
- var gensym86 := new SetNode;
- gensym85.Init(p);
- gensym86.Init(q);
- this.data := r;
- this.elems := {p, q, r};
- this.left := gensym86;
- this.right := gensym85;
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- } else {
- var gensym82 := new SetNode;
- var gensym83 := new SetNode;
- gensym82.Init(p);
- gensym83.Init(r);
- this.data := q;
- this.elems := {p, q, r};
- this.left := gensym83;
- this.right := gensym82;
- this.Repr := ({this} + this.left.Repr) + this.right.Repr;
- }
- }
- }
- }
- }
- }
-
-}
-
-
diff --git a/Jennisys/Jennisys/scripts/StartDafny-jen.bat b/Jennisys/Jennisys/scripts/StartDafny-jen.bat
deleted file mode 100644
index 6f44ec4c..00000000
--- a/Jennisys/Jennisys/scripts/StartDafny-jen.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-"c:/boogie/Binaries/Dafny.exe" -nologo -compile:0 /print:xxx.bpl -timeLimit:60 %* > c:\tmp\jen-doo.out
diff --git a/Source/Dafny/Cloner.cs b/Source/Dafny/Cloner.cs
deleted file mode 100644
index 38c793c5..00000000
--- a/Source/Dafny/Cloner.cs
+++ /dev/null
@@ -1,539 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Numerics;
-using System.Diagnostics.Contracts;
-using IToken = Microsoft.Boogie.IToken;
-
-namespace Microsoft.Dafny
-{
- class Cloner
- {
- public ModuleDefinition CloneModuleDefinition(ModuleDefinition m, string name) {
- ModuleDefinition nw;
- if (m is DefaultModuleDecl) {
- nw = new DefaultModuleDecl();
- } else {
- nw = new ModuleDefinition(Tok(m.tok), name, m.IsGhost, m.IsAbstract, m.RefinementBaseName, CloneAttributes(m.Attributes), true);
- }
- foreach (var d in m.TopLevelDecls) {
- nw.TopLevelDecls.Add(CloneDeclaration(d, nw));
- }
- nw.RefinementBase = m.RefinementBase;
- nw.Height = m.Height;
- return nw;
- }
- public TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition m) {
- Contract.Requires(d != null);
- Contract.Requires(m != null);
-
- if (d is ArbitraryTypeDecl) {
- var dd = (ArbitraryTypeDecl)d;
- return new ArbitraryTypeDecl(Tok(dd.tok), dd.Name, m, dd.EqualitySupport, CloneAttributes(dd.Attributes));
- } else if (d is IndDatatypeDecl) {
- var dd = (IndDatatypeDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var ctors = dd.Ctors.ConvertAll(CloneCtor);
- var dt = new IndDatatypeDecl(Tok(dd.tok), dd.Name, m, tps, ctors, CloneAttributes(dd.Attributes));
- return dt;
- } else if (d is CoDatatypeDecl) {
- var dd = (CoDatatypeDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var ctors = dd.Ctors.ConvertAll(CloneCtor);
- var dt = new CoDatatypeDecl(Tok(dd.tok), dd.Name, m, tps, ctors, CloneAttributes(dd.Attributes));
- return dt;
- } else if (d is IteratorDecl) {
- var dd = (IteratorDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var ins = dd.Ins.ConvertAll(CloneFormal);
- var outs = dd.Outs.ConvertAll(CloneFormal);
- var reads = CloneSpecFrameExpr(dd.Reads);
- var mod = CloneSpecFrameExpr(dd.Modifies);
- var decr = CloneSpecExpr(dd.Decreases);
- var req = dd.Requires.ConvertAll(CloneMayBeFreeExpr);
- var yreq = dd.YieldRequires.ConvertAll(CloneMayBeFreeExpr);
- var ens = dd.Ensures.ConvertAll(CloneMayBeFreeExpr);
- var yens = dd.YieldEnsures.ConvertAll(CloneMayBeFreeExpr);
- var body = CloneBlockStmt(dd.Body);
- var iter = new IteratorDecl(Tok(dd.tok), dd.Name, dd.Module,
- tps, ins, outs, reads, mod, decr,
- req, ens, yreq, yens,
- body, CloneAttributes(dd.Attributes), dd.SignatureIsOmitted);
- return iter;
- } else if (d is ClassDecl) {
- if (d is DefaultClassDecl) {
- var dd = (ClassDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var mm = dd.Members.ConvertAll(CloneMember);
- var cl = new DefaultClassDecl(m, mm);
- return cl;
- } else {
- var dd = (ClassDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var mm = dd.Members.ConvertAll(CloneMember);
- var cl = new ClassDecl(Tok(dd.tok), dd.Name, m, tps, mm, CloneAttributes(dd.Attributes));
- return cl;
- }
- } else if (d is ModuleDecl) {
- if (d is LiteralModuleDecl) {
- var l = new LiteralModuleDecl(((LiteralModuleDecl)d).ModuleDef, m);
- l.Signature = ((ModuleDecl)d).Signature;
- return l;
- } else if (d is AliasModuleDecl) {
- var a = (AliasModuleDecl)d;
- var alias = new AliasModuleDecl(a.Path, a.tok, m, a.Opened);
- alias.ModuleReference = a.ModuleReference;
- alias.Signature = a.Signature;
- return alias;
- } else if (d is AbstractModuleDecl) {
- var a = (AbstractModuleDecl)d;
- var abs = new AbstractModuleDecl(a.Path, a.tok, m, a.CompilePath, a.Opened);
- abs.Signature = a.Signature;
- abs.OriginalSignature = a.OriginalSignature;
- return abs;
- } else {
- Contract.Assert(false); // unexpected declaration
- return null; // to please compiler
- }
- } else {
- Contract.Assert(false); // unexpected declaration
- return null; // to please compiler
- }
- }
-
- public DatatypeCtor CloneCtor(DatatypeCtor ct) {
- return new DatatypeCtor(Tok(ct.tok), ct.Name, ct.Formals.ConvertAll(CloneFormal), CloneAttributes(ct.Attributes));
- }
-
- public TypeParameter CloneTypeParam(TypeParameter tp) {
- return new TypeParameter(Tok(tp.tok), tp.Name, tp.EqualitySupport);
- }
-
- public MemberDecl CloneMember(MemberDecl member) {
- if (member is Field) {
- Contract.Assert(!(member is SpecialField)); // we don't expect a SpecialField to be cloned (or do we?)
- var f = (Field)member;
- return new Field(Tok(f.tok), f.Name, f.IsGhost, f.IsMutable, f.IsUserMutable, CloneType(f.Type), CloneAttributes(f.Attributes));
- } else if (member is Function) {
- var f = (Function)member;
- return CloneFunction(f);
- } else {
- var m = (Method)member;
- return CloneMethod(m);
- }
- }
-
- public Type CloneType(Type t) {
- if (t is BasicType) {
- return t;
- } else if (t is SetType) {
- var tt = (SetType)t;
- return new SetType(CloneType(tt.Arg));
- } else if (t is SeqType) {
- var tt = (SeqType)t;
- return new SeqType(CloneType(tt.Arg));
- } else if (t is MultiSetType) {
- var tt = (MultiSetType)t;
- return new MultiSetType(CloneType(tt.Arg));
- } else if (t is MapType) {
- var tt = (MapType)t;
- return new MapType(CloneType(tt.Domain), CloneType(tt.Range));
- } else if (t is UserDefinedType) {
- var tt = (UserDefinedType)t;
- return new UserDefinedType(Tok(tt.tok), tt.Name, tt.TypeArgs.ConvertAll(CloneType), tt.Path.ConvertAll(x => Tok(x)));
- } else if (t is InferredTypeProxy) {
- return new InferredTypeProxy();
- } else if (t is ParamTypeProxy) {
- return new ParamTypeProxy(CloneTypeParam(((ParamTypeProxy)t).orig));
- } else {
- Contract.Assert(false); // unexpected type (e.g., no other type proxies are expected at this time)
- return null; // to please compiler
- }
- }
-
- public Formal CloneFormal(Formal formal) {
- return new Formal(Tok(formal.tok), formal.Name, CloneType(formal.Type), formal.InParam, formal.IsGhost);
- }
-
- public BoundVar CloneBoundVar(BoundVar bv) {
- return new BoundVar(Tok(bv.tok), bv.Name, CloneType(bv.Type));
- }
-
- public Specification<Expression> CloneSpecExpr(Specification<Expression> spec) {
- var ee = spec.Expressions == null ? null : spec.Expressions.ConvertAll(CloneExpr);
- return new Specification<Expression>(ee, CloneAttributes(spec.Attributes));
- }
-
- public Specification<FrameExpression> CloneSpecFrameExpr(Specification<FrameExpression> frame) {
- var ee = frame.Expressions == null ? null : frame.Expressions.ConvertAll(CloneFrameExpr);
- return new Specification<FrameExpression>(ee, CloneAttributes(frame.Attributes));
- }
-
- public FrameExpression CloneFrameExpr(FrameExpression frame) {
- return new FrameExpression(Tok(frame.tok), CloneExpr(frame.E), frame.FieldName);
- }
- public Attributes CloneAttributes(Attributes attrs) {
- if (attrs == null) {
- return null;
- } else {
- return new Attributes(attrs.Name, attrs.Args.ConvertAll(CloneAttrArg), CloneAttributes(attrs.Prev));
- }
- }
- public Attributes.Argument CloneAttrArg(Attributes.Argument aa) {
- if (aa.E != null) {
- return new Attributes.Argument(Tok(aa.Tok), CloneExpr(aa.E));
- } else {
- return new Attributes.Argument(Tok(aa.Tok), aa.S);
- }
- }
-
- public MaybeFreeExpression CloneMayBeFreeExpr(MaybeFreeExpression expr) {
- var mfe = new MaybeFreeExpression(CloneExpr(expr.E), expr.IsFree);
- mfe.Attributes = CloneAttributes(expr.Attributes);
- return mfe;
- }
-
- public virtual Expression CloneExpr(Expression expr) {
- if (expr == null) {
- return null;
- } else if (expr is LiteralExpr) {
- var e = (LiteralExpr)expr;
- if (e.Value == null) {
- return new LiteralExpr(Tok(e.tok));
- } else if (e.Value is bool) {
- return new LiteralExpr(Tok(e.tok), (bool)e.Value);
- } else {
- return new LiteralExpr(Tok(e.tok), (BigInteger)e.Value);
- }
-
- } else if (expr is ThisExpr) {
- if (expr is ImplicitThisExpr) {
- return new ImplicitThisExpr(Tok(expr.tok));
- } else {
- return new ThisExpr(Tok(expr.tok));
- }
-
- } else if (expr is IdentifierExpr) {
- var e = (IdentifierExpr)expr;
- return new IdentifierExpr(Tok(e.tok), e.Name);
-
- } else if (expr is DatatypeValue) {
- var e = (DatatypeValue)expr;
- return new DatatypeValue(Tok(e.tok), e.DatatypeName, e.MemberName, e.Arguments.ConvertAll(CloneExpr));
-
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- if (expr is SetDisplayExpr) {
- return new SetDisplayExpr(Tok(e.tok), e.Elements.ConvertAll(CloneExpr));
- } else if (expr is MultiSetDisplayExpr) {
- return new MultiSetDisplayExpr(Tok(e.tok), e.Elements.ConvertAll(CloneExpr));
- } else {
- Contract.Assert(expr is SeqDisplayExpr);
- return new SeqDisplayExpr(Tok(e.tok), e.Elements.ConvertAll(CloneExpr));
- }
-
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- List<ExpressionPair> pp = new List<ExpressionPair>();
- foreach (ExpressionPair p in e.Elements) {
- pp.Add(new ExpressionPair(CloneExpr(p.A), CloneExpr(p.B)));
- }
- return new MapDisplayExpr(Tok(expr.tok), pp);
- } else if (expr is ExprDotName) {
- var e = (ExprDotName)expr;
- return new ExprDotName(Tok(e.tok), CloneExpr(e.Obj), e.SuffixName);
-
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- return new FieldSelectExpr(Tok(e.tok), CloneExpr(e.Obj), e.FieldName);
-
- } else if (expr is SeqSelectExpr) {
- var e = (SeqSelectExpr)expr;
- return new SeqSelectExpr(Tok(e.tok), e.SelectOne, CloneExpr(e.Seq), CloneExpr(e.E0), CloneExpr(e.E1));
-
- } else if (expr is MultiSelectExpr) {
- var e = (MultiSelectExpr)expr;
- return new MultiSelectExpr(Tok(e.tok), CloneExpr(e.Array), e.Indices.ConvertAll(CloneExpr));
-
- } else if (expr is SeqUpdateExpr) {
- var e = (SeqUpdateExpr)expr;
- return new SeqUpdateExpr(Tok(e.tok), CloneExpr(e.Seq), CloneExpr(e.Index), CloneExpr(e.Value));
-
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- return new FunctionCallExpr(Tok(e.tok), e.Name, CloneExpr(e.Receiver), e.OpenParen == null ? null : Tok(e.OpenParen), e.Args.ConvertAll(CloneExpr));
-
- } else if (expr is OldExpr) {
- var e = (OldExpr)expr;
- return new OldExpr(Tok(e.tok), CloneExpr(e.E));
-
- } else if (expr is MultiSetFormingExpr) {
- var e = (MultiSetFormingExpr)expr;
- return new MultiSetFormingExpr(Tok(e.tok), CloneExpr(e.E));
-
- } else if (expr is FreshExpr) {
- var e = (FreshExpr)expr;
- return new FreshExpr(Tok(e.tok), CloneExpr(e.E));
-
- } else if (expr is UnaryExpr) {
- var e = (UnaryExpr)expr;
- return new UnaryExpr(Tok(e.tok), e.Op, CloneExpr(e.E));
-
- } else if (expr is BinaryExpr) {
- var e = (BinaryExpr)expr;
- return new BinaryExpr(Tok(e.tok), e.Op, CloneExpr(e.E0), CloneExpr(e.E1));
-
- } else if (expr is ChainingExpression) {
- var e = (ChainingExpression)expr;
- return CloneExpr(e.E); // just clone the desugaring, since it's already available
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- return new LetExpr(Tok(e.tok), e.Vars.ConvertAll(CloneBoundVar), e.RHSs.ConvertAll(CloneExpr), CloneExpr(e.Body));
-
- } else if (expr is NamedExpr) {
- var e = (NamedExpr)expr;
- return new NamedExpr(Tok(e.tok), e.Name, CloneExpr(e.Body));
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- var tk = Tok(e.tok);
- var bvs = e.BoundVars.ConvertAll(CloneBoundVar);
- var range = CloneExpr(e.Range);
- var term = CloneExpr(e.Term);
- if (e is ForallExpr) {
- return new ForallExpr(tk, bvs, range, term, CloneAttributes(e.Attributes));
- } else if (e is ExistsExpr) {
- return new ExistsExpr(tk, bvs, range, term, CloneAttributes(e.Attributes));
- } else if (e is MapComprehension) {
- return new MapComprehension(tk, bvs, range, term);
- } else {
- Contract.Assert(e is SetComprehension);
- return new SetComprehension(tk, bvs, range, term);
- }
-
- } else if (expr is WildcardExpr) {
- return new WildcardExpr(Tok(expr.tok));
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- if (e is AssertExpr) {
- return new AssertExpr(Tok(e.tok), CloneExpr(e.Guard), CloneExpr(e.Body));
- } else {
- Contract.Assert(e is AssumeExpr);
- return new AssumeExpr(Tok(e.tok), CloneExpr(e.Guard), CloneExpr(e.Body));
- }
-
- } else if (expr is ITEExpr) {
- var e = (ITEExpr)expr;
- return new ITEExpr(Tok(e.tok), CloneExpr(e.Test), CloneExpr(e.Thn), CloneExpr(e.Els));
-
- } else if (expr is ParensExpression) {
- var e = (ParensExpression)expr;
- return CloneExpr(e.E); // skip the parentheses in the clone
-
- } else if (expr is IdentifierSequence) {
- var e = (IdentifierSequence)expr;
- var aa = e.Arguments == null ? null : e.Arguments.ConvertAll(CloneExpr);
- return new IdentifierSequence(e.Tokens.ConvertAll(tk => Tok(tk)), e.OpenParen == null ? null : Tok(e.OpenParen), aa);
-
- } else if (expr is MatchExpr) {
- var e = (MatchExpr)expr;
- return new MatchExpr(Tok(e.tok), CloneExpr(e.Source),
- e.Cases.ConvertAll(c => new MatchCaseExpr(Tok(c.tok), c.Id, c.Arguments.ConvertAll(CloneBoundVar), CloneExpr(c.Body))));
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
-
- public AssignmentRhs CloneRHS(AssignmentRhs rhs) {
- AssignmentRhs c;
- if (rhs is ExprRhs) {
- var r = (ExprRhs)rhs;
- c = new ExprRhs(CloneExpr(r.Expr));
- } else if (rhs is HavocRhs) {
- c = new HavocRhs(Tok(rhs.Tok));
- } else {
- var r = (TypeRhs)rhs;
- if (r.ArrayDimensions != null) {
- c = new TypeRhs(Tok(r.Tok), CloneType(r.EType), r.ArrayDimensions.ConvertAll(CloneExpr));
- } else if (r.InitCall != null) {
- c = new TypeRhs(Tok(r.Tok), CloneType(r.EType), (CallStmt)CloneStmt(r.InitCall));
- } else {
- c = new TypeRhs(Tok(r.Tok), CloneType(r.EType));
- }
- }
- c.Attributes = CloneAttributes(rhs.Attributes);
- return c;
- }
-
- public BlockStmt CloneBlockStmt(BlockStmt stmt) {
- if (stmt == null) {
- return null;
- } else {
- return new BlockStmt(Tok(stmt.Tok), stmt.Body.ConvertAll(CloneStmt));
- }
- }
-
- public Statement CloneStmt(Statement stmt) {
- if (stmt == null) {
- return null;
- }
-
- Statement r;
- if (stmt is AssertStmt) {
- var s = (AssertStmt)stmt;
- r = new AssertStmt(Tok(s.Tok), CloneExpr(s.Expr), null);
-
- } else if (stmt is AssumeStmt) {
- var s = (AssumeStmt)stmt;
- r = new AssumeStmt(Tok(s.Tok), CloneExpr(s.Expr), null);
-
- } else if (stmt is PrintStmt) {
- var s = (PrintStmt)stmt;
- r = new PrintStmt(Tok(s.Tok), s.Args.ConvertAll(CloneAttrArg));
-
- } else if (stmt is BreakStmt) {
- var s = (BreakStmt)stmt;
- if (s.TargetLabel != null) {
- r = new BreakStmt(Tok(s.Tok), s.TargetLabel);
- } else {
- r = new BreakStmt(Tok(s.Tok), s.BreakCount);
- }
-
- } else if (stmt is ReturnStmt) {
- var s = (ReturnStmt)stmt;
- r = new ReturnStmt(Tok(s.Tok), s.rhss == null ? null : s.rhss.ConvertAll(CloneRHS));
-
- } else if (stmt is YieldStmt) {
- var s = (YieldStmt)stmt;
- r = new YieldStmt(Tok(s.Tok), s.rhss == null ? null : s.rhss.ConvertAll(CloneRHS));
-
- } else if (stmt is AssignStmt) {
- var s = (AssignStmt)stmt;
- r = new AssignStmt(Tok(s.Tok), CloneExpr(s.Lhs), CloneRHS(s.Rhs));
-
- } else if (stmt is VarDecl) {
- var s = (VarDecl)stmt;
- r = new VarDecl(Tok(s.Tok), s.Name, CloneType(s.OptionalType), s.IsGhost);
-
- } else if (stmt is CallStmt) {
- var s = (CallStmt)stmt;
- r = new CallStmt(Tok(s.Tok), s.Lhs.ConvertAll(CloneExpr), CloneExpr(s.Receiver), s.MethodName, s.Args.ConvertAll(CloneExpr));
-
- } else if (stmt is BlockStmt) {
- r = CloneBlockStmt((BlockStmt)stmt);
-
- } else if (stmt is IfStmt) {
- var s = (IfStmt)stmt;
- r = new IfStmt(Tok(s.Tok), CloneExpr(s.Guard), CloneBlockStmt(s.Thn), CloneStmt(s.Els));
-
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- r = new AlternativeStmt(Tok(s.Tok), s.Alternatives.ConvertAll(CloneGuardedAlternative));
-
- } else if (stmt is WhileStmt) {
- var s = (WhileStmt)stmt;
- r = new WhileStmt(Tok(s.Tok), CloneExpr(s.Guard), s.Invariants.ConvertAll(CloneMayBeFreeExpr), CloneSpecExpr(s.Decreases), CloneSpecFrameExpr(s.Mod), CloneBlockStmt(s.Body));
-
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- r = new AlternativeLoopStmt(Tok(s.Tok), s.Invariants.ConvertAll(CloneMayBeFreeExpr), CloneSpecExpr(s.Decreases), CloneSpecFrameExpr(s.Mod), s.Alternatives.ConvertAll(CloneGuardedAlternative));
-
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- r = new ParallelStmt(Tok(s.Tok), s.BoundVars.ConvertAll(CloneBoundVar), null, CloneExpr(s.Range), s.Ens.ConvertAll(CloneMayBeFreeExpr), CloneStmt(s.Body));
-
- } else if (stmt is CalcStmt) {
- var s = (CalcStmt)stmt;
- r = new CalcStmt(Tok(s.Tok), s.Op, s.Lines.ConvertAll(CloneExpr), s.Hints.ConvertAll(CloneBlockStmt), new List<Nullable<BinaryExpr.Opcode>>(s.CustomOps));
-
- } else if (stmt is MatchStmt) {
- var s = (MatchStmt)stmt;
- r = new MatchStmt(Tok(s.Tok), CloneExpr(s.Source),
- s.Cases.ConvertAll(c => new MatchCaseStmt(Tok(c.tok), c.Id, c.Arguments.ConvertAll(CloneBoundVar), c.Body.ConvertAll(CloneStmt))));
-
- } else if (stmt is AssignSuchThatStmt) {
- var s = (AssignSuchThatStmt)stmt;
- r = new AssignSuchThatStmt(Tok(s.Tok), s.Lhss.ConvertAll(CloneExpr), CloneExpr(s.Expr), s.AssumeToken == null ? null : Tok(s.AssumeToken));
-
- } else if (stmt is UpdateStmt) {
- var s = (UpdateStmt)stmt;
- r = new UpdateStmt(Tok(s.Tok), s.Lhss.ConvertAll(CloneExpr), s.Rhss.ConvertAll(CloneRHS), s.CanMutateKnownState);
-
- } else if (stmt is VarDeclStmt) {
- var s = (VarDeclStmt)stmt;
- r = new VarDeclStmt(Tok(s.Tok), s.Lhss.ConvertAll(c => (VarDecl)CloneStmt(c)), (ConcreteUpdateStatement)CloneStmt(s.Update));
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
- }
-
- // add labels to the cloned statement
- AddStmtLabels(r, stmt.Labels);
- r.Attributes = CloneAttributes(stmt.Attributes);
-
- return r;
- }
-
- public void AddStmtLabels(Statement s, LList<Label> node) {
- if (node != null) {
- AddStmtLabels(s, node.Next);
- if (node.Data.Name == null) {
- // this indicates an implicit-target break statement that has been resolved; don't add it
- } else {
- s.Labels = new LList<Label>(new Label(Tok(node.Data.Tok), node.Data.Name), s.Labels);
- }
- }
- }
-
- public GuardedAlternative CloneGuardedAlternative(GuardedAlternative alt) {
- return new GuardedAlternative(Tok(alt.Tok), CloneExpr(alt.Guard), alt.Body.ConvertAll(CloneStmt));
- }
-
- public Function CloneFunction(Function f) {
- var tps = f.TypeArgs.ConvertAll(CloneTypeParam);
- var formals = f.Formals.ConvertAll(CloneFormal);
- var req = f.Req.ConvertAll(CloneExpr);
- var reads = f.Reads.ConvertAll(CloneFrameExpr);
- var decreases = CloneSpecExpr(f.Decreases);
- var ens = f.Ens.ConvertAll(CloneExpr);
- var body = CloneExpr(f.Body);
-
- if (f is Predicate) {
- return new Predicate(Tok(f.tok), f.Name, f.IsStatic, f.IsGhost, tps, f.OpenParen, formals,
- req, reads, ens, decreases, body, Predicate.BodyOriginKind.OriginalOrInherited, CloneAttributes(f.Attributes), false);
- } else if (f is CoPredicate) {
- return new CoPredicate(Tok(f.tok), f.Name, f.IsStatic, tps, f.OpenParen, formals,
- req, reads, ens, body, CloneAttributes(f.Attributes), false);
- } else {
- return new Function(Tok(f.tok), f.Name, f.IsStatic, f.IsGhost, tps, f.OpenParen, formals, CloneType(f.ResultType),
- req, reads, ens, decreases, body, CloneAttributes(f.Attributes), false);
- }
- }
-
- public Method CloneMethod(Method m) {
- Contract.Requires(m != null);
-
- var tps = m.TypeArgs.ConvertAll(CloneTypeParam);
- var ins = m.Ins.ConvertAll(CloneFormal);
- var req = m.Req.ConvertAll(CloneMayBeFreeExpr);
- var mod = CloneSpecFrameExpr(m.Mod);
- var decreases = CloneSpecExpr(m.Decreases);
-
- var ens = m.Ens.ConvertAll(CloneMayBeFreeExpr);
-
- var body = CloneBlockStmt(m.Body);
- if (m is Constructor) {
- return new Constructor(Tok(m.tok), m.Name, tps, ins,
- req, mod, ens, decreases, body, CloneAttributes(m.Attributes), false);
- } else {
- return new Method(Tok(m.tok), m.Name, m.IsStatic, m.IsGhost, tps, ins, m.Outs.ConvertAll(CloneFormal),
- req, mod, ens, decreases, body, CloneAttributes(m.Attributes), false);
- }
- }
- public virtual IToken Tok(IToken tok) {
- return tok;
- }
- }
-} \ No newline at end of file
diff --git a/Source/Dafny/Compiler.cs b/Source/Dafny/Compiler.cs
deleted file mode 100644
index 4c334033..00000000
--- a/Source/Dafny/Compiler.cs
+++ /dev/null
@@ -1,2432 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Numerics;
-using System.IO;
-using System.Diagnostics.Contracts;
-using Bpl = Microsoft.Boogie;
-using System.Text;
-
-namespace Microsoft.Dafny {
- public class Compiler {
- public Compiler(TextWriter wr) {
- Contract.Requires(wr != null);
- this.wr = wr;
- }
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(wr!=null);
- }
-
- TextWriter wr;
- Method enclosingMethod; // non-null when a method body is being translated
-
- public int ErrorCount;
- void Error(string msg, params object[] args) {
- Contract.Requires(msg != null);
- Contract.Requires(args != null);
-
- string s = string.Format("Compilation error: " + msg, args);
- Console.WriteLine(s);
- wr.WriteLine("/* {0} */", s);
- ErrorCount++;
- }
-
- void ReadRuntimeSystem() {
- string codebase = cce.NonNull( System.IO.Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location)));
- string path = System.IO.Path.Combine(codebase, "DafnyRuntime.cs");
- using (TextReader rd = new StreamReader(new FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read)))
- {
- while (true) {
- string s = rd.ReadLine();
- if (s == null)
- return;
- wr.WriteLine(s);
- }
- }
- }
-
- readonly int IndentAmount = 2;
- void Indent(int ind) {
- string spaces = " ";
- for (; spaces.Length < ind; ind -= spaces.Length) {
- wr.Write(spaces);
- }
- wr.Write(spaces.Substring(0, ind));
- }
-
- public void Compile(Program program) {Contract.Requires(program != null);
- wr.WriteLine("// Dafny program {0} compiled into C#", program.Name);
- wr.WriteLine();
- ReadRuntimeSystem();
- CompileBuiltIns(program.BuiltIns);
-
- foreach (ModuleDefinition m in program.CompileModules) {
- if (m.IsGhost) {
- // the purpose of a ghost module is to skip compilation
- continue;
- }
- int indent = 0;
- if (!m.IsDefaultModule) {
- wr.WriteLine("namespace @{0} {{", m.CompileName);
- indent += IndentAmount;
- }
- foreach (TopLevelDecl d in m.TopLevelDecls) {
- wr.WriteLine();
- if (d is ArbitraryTypeDecl) {
- var at = (ArbitraryTypeDecl)d;
- Error("Arbitrary type ('{0}') cannot be compiled", at.CompileName);
- } else if (d is DatatypeDecl) {
- var dt = (DatatypeDecl)d;
- Indent(indent);
- wr.Write("public abstract class Base_{0}", dt.CompileName);
- if (dt.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
- }
- wr.WriteLine(" { }");
- CompileDatatypeConstructors(dt, indent);
- CompileDatatypeStruct(dt, indent);
- } else if (d is IteratorDecl) {
- var iter = (IteratorDecl)d;
- // An iterator is compiled as follows:
- // public class MyIteratorExample<T>
- // {
- // public T q; // in-parameter
- // public T x; // yield-parameter
- // public int y; // yield-parameter
- // IEnumerator<object> _iter;
- //
- // public void _MyIteratorExample(T q) {
- // this.q = q;
- // _iter = TheIterator();
- // }
- //
- // public void MoveNext(out bool more) {
- // more =_iter.MoveNext();
- // }
- //
- // private IEnumerator<object> TheIterator() {
- // // the translation of the body of the iterator, with each "yield" turning into a "yield return null;"
- // yield break;
- // }
- // }
-
- Indent(indent);
- wr.Write("public class @{0}", iter.CompileName);
- if (iter.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(iter.TypeArgs));
- }
- wr.WriteLine(" {");
- var ind = indent + IndentAmount;
- // here come the fields
- Constructor ct = null;
- foreach (var member in iter.Members) {
- var f = member as Field;
- if (f != null && !f.IsGhost) {
- Indent(ind);
- wr.WriteLine("public {0} @{1} = {2};", TypeName(f.Type), f.CompileName, DefaultValue(f.Type));
- } else if (member is Constructor) {
- Contract.Assert(ct == null); // we're expecting just one constructor
- ct = (Constructor)member;
- }
- }
- Contract.Assert(ct != null); // we do expect a constructor
- Indent(ind); wr.WriteLine("System.Collections.Generic.IEnumerator<object> __iter;");
-
- // here's the initializer method
- Indent(ind); wr.Write("public void @{0}(", ct.CompileName);
- string sep = "";
- foreach (var p in ct.Ins) {
- if (!p.IsGhost) {
- // here we rely on the parameters and the corresponding fields having the same names
- wr.Write("{0}{1} @{2}", sep, TypeName(p.Type), p.CompileName);
- sep = ", ";
- }
- }
- wr.WriteLine(") {");
- foreach (var p in ct.Ins) {
- if (!p.IsGhost) {
- Indent(ind + IndentAmount);
- wr.WriteLine("this.@{0} = @{0};", p.CompileName);
- }
- }
- Indent(ind + IndentAmount); wr.WriteLine("__iter = TheIterator();");
- Indent(ind); wr.WriteLine("}");
- // here are the enumerator methods
- Indent(ind); wr.WriteLine("public void MoveNext(out bool more) { more = __iter.MoveNext(); }");
- Indent(ind); wr.WriteLine("private System.Collections.Generic.IEnumerator<object> TheIterator() {");
- if (iter.Body == null) {
- Error("Iterator {0} has no body", iter.FullName);
- } else {
- TrStmt(iter.Body, ind + IndentAmount);
- }
- Indent(ind + IndentAmount); wr.WriteLine("yield break;");
- Indent(ind); wr.WriteLine("}");
- // end of the class
- Indent(indent); wr.WriteLine("}");
-
- } else if (d is ClassDecl) {
- var cl = (ClassDecl)d;
- Indent(indent);
- wr.Write("public class @{0}", cl.CompileName);
- if (cl.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(cl.TypeArgs));
- }
- wr.WriteLine(" {");
- CompileClassMembers(cl, indent+IndentAmount);
- Indent(indent); wr.WriteLine("}");
- } else if (d is ModuleDecl) {
- // nop
- } else { Contract.Assert(false); }
- }
- if (!m.IsDefaultModule) {
- wr.WriteLine("}} // end of namespace {0}", m.CompileName);
- }
- }
- }
-
- void CompileBuiltIns(BuiltIns builtIns) {
- wr.WriteLine("namespace Dafny {");
- Indent(IndentAmount);
- wr.WriteLine("public partial class Helpers {");
- foreach (var decl in builtIns.SystemModule.TopLevelDecls) {
- if (decl is ArrayClassDecl) {
- int dims = ((ArrayClassDecl)decl).Dims;
- // public static T[,] InitNewArray2<T>(BigInteger size0, BigInteger size1) {
- Indent(3 * IndentAmount);
- wr.Write("public static T[");
- RepeatWrite(wr, dims, "", ",");
- wr.Write("] InitNewArray{0}<T>(", dims);
- RepeatWrite(wr, dims, "BigInteger size{0}", ", ");
- wr.WriteLine(") {");
- // int s0 = (int)size0;
- for (int i = 0; i < dims; i++) {
- Indent(4 * IndentAmount);
- wr.WriteLine("int s{0} = (int)size{0};", i);
- }
- // T[,] a = new T[s0, s1];
- Indent(4 * IndentAmount);
- wr.Write("T[");
- RepeatWrite(wr, dims, "", ",");
- wr.Write("] a = new T[");
- RepeatWrite(wr, dims, "s{0}", ",");
- wr.WriteLine("];");
- // BigInteger[,] b = a as BigInteger[,];
- Indent(4 * IndentAmount);
- wr.Write("BigInteger[");
- RepeatWrite(wr, dims, "", ",");
- wr.Write("] b = a as BigInteger[");
- RepeatWrite(wr, dims, "", ",");
- wr.WriteLine("];");
- // if (b != null) {
- Indent(4 * IndentAmount);
- wr.WriteLine("if (b != null) {");
- // BigInteger z = new BigInteger(0);
- Indent(5 * IndentAmount);
- wr.WriteLine("BigInteger z = new BigInteger(0);");
- // for (int i0 = 0; i0 < s0; i0++)
- // for (int i1 = 0; i1 < s1; i1++)
- for (int i = 0; i < dims; i++) {
- Indent((5+i) * IndentAmount);
- wr.WriteLine("for (int i{0} = 0; i{0} < s{0}; i{0}++)", i);
- }
- // b[i0,i1] = z;
- Indent((5+dims) * IndentAmount);
- wr.Write("b[");
- RepeatWrite(wr, dims, "i{0}", ",");
- wr.WriteLine("] = z;");
- // }
- Indent(4 * IndentAmount);
- wr.WriteLine("}");
- // return a;
- Indent(4 * IndentAmount);
- wr.WriteLine("return a;");
- // }
- Indent(3 * IndentAmount);
- wr.WriteLine("}"); // end of method
- }
- }
- Indent(IndentAmount);
- wr.WriteLine("}"); // end of class Helpers
- wr.WriteLine("}"); // end of namespace
- }
-
- static void RepeatWrite(TextWriter wr, int times, string template, string separator) {
- Contract.Requires(1 <= times);
- string s = "";
- for (int i = 0; i < times; i++) {
- wr.Write(s);
- wr.Write(template, i);
- s = separator;
- }
- }
-
- void CompileDatatypeConstructors(DatatypeDecl dt, int indent)
- {
- Contract.Requires(dt != null);
-
- string typeParams = dt.TypeArgs.Count == 0 ? "" : string.Format("<{0}>", TypeParameters(dt.TypeArgs));
- if (dt is CoDatatypeDecl) {
- // public class Dt__Lazy<T> : Base_Dt<T> {
- // public delegate Base_Dt<T> Computer();
- // public delegate Computer ComputerComputer();
- // Computer c;
- // public Dt__Lazy(Computer c) { this.c = c; }
- // public Base_Dt<T> Get() { return c(); }
- // }
- Indent(indent);
- wr.WriteLine("public class {0}__Lazy{1} : Base_{0}{1} {{", dt.CompileName, typeParams);
- int ind = indent + IndentAmount;
- Indent(ind);
- wr.WriteLine("public delegate Base_{0}{1} Computer();", dt.CompileName, typeParams);
- Indent(ind);
- wr.WriteLine("public delegate Computer ComputerComputer();");
- Indent(ind);
- wr.WriteLine("Computer c;");
- Indent(ind);
- wr.WriteLine("public {0}__Lazy(Computer c) {{ this.c = c; }}", dt.CompileName);
- Indent(ind);
- wr.WriteLine("public Base_{0}{1} Get() {{ return c(); }}", dt.CompileName, typeParams);
- Indent(indent);
- wr.WriteLine("}");
- }
-
- int constructorIndex = 0; // used to give each constructor a different
- foreach (DatatypeCtor ctor in dt.Ctors) {
- // class Dt_Ctor<T,U> : Base_Dt<T> {
- // Fields;
- // public Dt_Ctor(arguments) {
- // Fields = arguments;
- // }
- // public override bool Equals(object other) {
- // var oth = other as Dt_Dtor;
- // return oth != null && equals(_field0, oth._field0) && ... ;
- // }
- // public override int GetHashCode() {
- // return base.GetHashCode(); // surely this can be improved
- // }
- // public override string ToString() { // only for inductive datatypes
- // // ...
- // }
- // }
- Indent(indent);
- wr.Write("public class {0}", DtCtorDeclarationName(ctor, dt.TypeArgs));
- wr.WriteLine(" : Base_{0}{1} {{", dt.CompileName, typeParams);
- int ind = indent + IndentAmount;
-
- int i = 0;
- foreach (Formal arg in ctor.Formals) {
- if (!arg.IsGhost) {
- Indent(ind);
- wr.WriteLine("public readonly {0} @{1};", TypeName(arg.Type), FormalName(arg, i));
- i++;
- }
- }
-
- Indent(ind);
- wr.Write("public {0}(", DtCtorDeclartionName(ctor));
- WriteFormals("", ctor.Formals);
- wr.WriteLine(") {");
- i = 0;
- foreach (Formal arg in ctor.Formals) {
- if (!arg.IsGhost) {
- Indent(ind + IndentAmount);
- wr.WriteLine("this.@{0} = @{0};", FormalName(arg, i));
- i++;
- }
- }
- Indent(ind); wr.WriteLine("}");
-
- // Equals method
- Indent(ind); wr.WriteLine("public override bool Equals(object other) {");
- Indent(ind + IndentAmount);
- wr.Write("var oth = other as {0}", DtCtorName(ctor, dt.TypeArgs));
- wr.WriteLine(";");
- Indent(ind + IndentAmount);
- wr.Write("return oth != null");
- i = 0;
- foreach (Formal arg in ctor.Formals) {
- if (!arg.IsGhost) {
- string nm = FormalName(arg, i);
- if (arg.Type.IsDatatype || arg.Type.IsTypeParameter) {
- wr.Write(" && this.@{0}.Equals(oth.@{0})", nm);
- } else {
- wr.Write(" && this.@{0} == oth.@{0}", nm);
- }
- i++;
- }
- }
- wr.WriteLine(";");
- Indent(ind); wr.WriteLine("}");
-
- // GetHashCode method
- Indent(ind); wr.WriteLine("public override int GetHashCode() {");
- Indent(ind + IndentAmount); wr.Write("return " + constructorIndex);
-
- i = 0;
- foreach (Formal arg in ctor.Formals) {
- if (!arg.IsGhost) {
- string nm = FormalName(arg, i);
- wr.Write(" ^ this.@{0}.GetHashCode()", nm);
- i++;
- }
- }
- wr.WriteLine(";");
- Indent(ind); wr.WriteLine("}");
-
- if (dt is IndDatatypeDecl) {
- Indent(ind); wr.WriteLine("public override string ToString() {");
- string nm = (dt.Module.IsDefaultModule ? "" : dt.Module.CompileName + ".") + dt.CompileName + "." + ctor.CompileName;
- Indent(ind + IndentAmount); wr.WriteLine("string s = \"{0}\";", nm);
- if (ctor.Formals.Count != 0) {
- Indent(ind + IndentAmount); wr.WriteLine("s += \"(\";");
- i = 0;
- foreach (var arg in ctor.Formals) {
- if (!arg.IsGhost) {
- if (i != 0) {
- Indent(ind + IndentAmount); wr.WriteLine("s += \", \";");
- }
- Indent(ind + IndentAmount); wr.WriteLine("s += @{0}.ToString();", FormalName(arg, i));
- i++;
- }
- }
- Indent(ind + IndentAmount); wr.WriteLine("s += \")\";");
- }
- Indent(ind + IndentAmount); wr.WriteLine("return s;");
- Indent(ind); wr.WriteLine("}");
- }
-
- Indent(indent); wr.WriteLine("}");
- }
- constructorIndex ++;
- }
-
- void CompileDatatypeStruct(DatatypeDecl dt, int indent) {
- Contract.Requires(dt != null);
-
- // public struct Dt<T> : IDatatype{
- // Base_Dt<T> _d;
- // public Base_Dt<T> _D {
- // get {
- // if (_d == null) {
- // _d = Default;
- // } else if (_d is Dt__Lazy<T>) { // co-datatypes only
- // _d = ((Dt__Lazy<T>)_d).Get(); // co-datatypes only
- // }
- // return _d;
- // }
- // }
- // public Dt(Base_Dt<T> d) { this._d = d; }
- // static Base_Dt<T> theDefault;
- // public static Base_Dt<T> Default {
- // get {
- // if (theDefault == null) {
- // theDefault = ...;
- // }
- // return theDefault;
- // }
- // }
- // public override bool Equals(object other) {
- // return other is Dt<T> && _D.Equals(((Dt<T>)other)._D);
- // }
- // public override int GetHashCode() { return _D.GetHashCode(); }
- // public override string ToString() { return _D.ToString(); } // only for inductive datatypes
- //
- // public bool is_Ctor0 { get { return _D is Dt_Ctor0; } }
- // ...
- //
- // public T0 dtor_Dtor0 { get { return ((DT_Ctor)_D).@Dtor0; } }
- // ...
- // }
- string DtT = dt.CompileName;
- string DtT_TypeArgs = "";
- if (dt.TypeArgs.Count != 0) {
- DtT_TypeArgs = "<" + TypeParameters(dt.TypeArgs) + ">";
- DtT += DtT_TypeArgs;
- }
-
- Indent(indent);
- wr.WriteLine("public struct @{0} {{", DtT);
- int ind = indent + IndentAmount;
-
- Indent(ind);
- wr.WriteLine("Base_{0} _d;", DtT);
-
- Indent(ind);
- wr.WriteLine("public Base_{0} _D {{", DtT);
- Indent(ind + IndentAmount);
- wr.WriteLine("get {");
- Indent(ind + 2 * IndentAmount);
- wr.WriteLine("if (_d == null) {");
- Indent(ind + 3 * IndentAmount);
- wr.WriteLine("_d = Default;");
- if (dt is CoDatatypeDecl) {
- string typeParams = dt.TypeArgs.Count == 0 ? "" : string.Format("<{0}>", TypeParameters(dt.TypeArgs));
- Indent(ind + 2 * IndentAmount);
- wr.WriteLine("}} else if (_d is {0}__Lazy{1}) {{", dt.CompileName, typeParams);
- Indent(ind + 3 * IndentAmount);
- wr.WriteLine("_d = (({0}__Lazy{1})_d).Get();", dt.CompileName, typeParams);
- }
- Indent(ind + 2 * IndentAmount); wr.WriteLine("}");
- Indent(ind + 2 * IndentAmount); wr.WriteLine("return _d;");
- Indent(ind + IndentAmount); wr.WriteLine("}");
- Indent(ind); wr.WriteLine("}");
-
- Indent(ind);
- wr.WriteLine("public @{0}(Base_{1} d) {{ this._d = d; }}", dt.CompileName, DtT);
-
- Indent(ind);
- wr.WriteLine("static Base_{0} theDefault;", DtT);
-
- Indent(ind);
- wr.WriteLine("public static Base_{0} Default {{", DtT);
- Indent(ind + IndentAmount);
- wr.WriteLine("get {");
- Indent(ind + 2 * IndentAmount);
- wr.WriteLine("if (theDefault == null) {");
- Indent(ind + 3 * IndentAmount);
- wr.Write("theDefault = ");
-
- DatatypeCtor defaultCtor;
- if (dt is IndDatatypeDecl) {
- defaultCtor = ((IndDatatypeDecl)dt).DefaultCtor;
- } else {
- defaultCtor = ((CoDatatypeDecl)dt).Ctors[0]; // pick any one of them
- }
- wr.Write("new {0}", DtCtorName(defaultCtor, dt.TypeArgs));
- wr.Write("(");
- string sep = "";
- foreach (Formal f in defaultCtor.Formals) {
- if (!f.IsGhost) {
- wr.Write("{0}{1}", sep, DefaultValue(f.Type));
- sep = ", ";
- }
- }
- wr.Write(")");
-
- wr.WriteLine(";");
- Indent(ind + 2 * IndentAmount);
- wr.WriteLine("}");
- Indent(ind + 2 * IndentAmount);
- wr.WriteLine("return theDefault;");
- Indent(ind + IndentAmount); wr.WriteLine("}");
-
- Indent(ind); wr.WriteLine("}");
-
- Indent(ind); wr.WriteLine("public override bool Equals(object other) {");
- Indent(ind + IndentAmount);
- wr.WriteLine("return other is @{0} && _D.Equals(((@{0})other)._D);", DtT);
- Indent(ind); wr.WriteLine("}");
-
- Indent(ind);
- wr.WriteLine("public override int GetHashCode() { return _D.GetHashCode(); }");
- if (dt is IndDatatypeDecl) {
- Indent(ind);
- wr.WriteLine("public override string ToString() { return _D.ToString(); }");
- }
-
- // query properties
- foreach (var ctor in dt.Ctors) {
- // public bool is_Ctor0 { get { return _D is Dt_Ctor0; } }
- Indent(ind);
- wr.WriteLine("public bool is_{0} {{ get {{ return _D is {1}_{0}{2}; }} }}", ctor.CompileName, dt.CompileName, DtT_TypeArgs);
- }
- if (dt.HasFinitePossibleValues) {
- Indent(ind);
- wr.WriteLine("public static System.Collections.Generic.IEnumerable<@{0}> AllSingletonConstructors {{", DtT);
- Indent(ind + IndentAmount);
- wr.WriteLine("get {");
- foreach (var ctr in dt.Ctors) {
- if (ctr.Formals.Count == 0) {
- Indent(ind + IndentAmount + IndentAmount);
- wr.WriteLine("yield return new @{0}(new {2}_{1}());", DtT, ctr.CompileName, dt.CompileName);
- }
- }
- Indent(ind + IndentAmount + IndentAmount);
- wr.WriteLine("yield break;");
- Indent(ind + IndentAmount);
- wr.WriteLine("}");
- Indent(ind);
- wr.WriteLine("}");
- }
-
- // destructors
- foreach (var ctor in dt.Ctors) {
- foreach (var arg in ctor.Formals) {
- if (!arg.IsGhost && arg.HasName) {
- // public T0 @Dtor0 { get { return ((DT_Ctor)_D).@Dtor0; } }
- Indent(ind);
- wr.WriteLine("public {0} dtor_{1} {{ get {{ return (({2}_{3}{4})_D).@{1}; }} }}", TypeName(arg.Type), arg.CompileName, dt.CompileName, ctor.CompileName, DtT_TypeArgs);
- }
- }
- }
-
- Indent(indent);
- wr.WriteLine("}");
- }
-
- int WriteFormals(string sep, List<Formal/*!*/>/*!*/ formals)
- {
- Contract.Requires(sep != null);
- Contract.Requires(cce.NonNullElements(formals));
- int i = 0;
- foreach (Formal arg in formals) {
- if (!arg.IsGhost) {
- string name = FormalName(arg, i);
- wr.Write("{0}{1}{2} @{3}", sep, arg.InParam ? "" : "out ", TypeName(arg.Type), name);
- sep = ", ";
- i++;
- }
- }
- return i; // the number of formals written
- }
-
- string FormalName(Formal formal, int i) {
- Contract.Requires(formal != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return formal.HasName ? formal.CompileName : "_a" + i;
- }
-
- string DtName(DatatypeDecl decl) {
- return decl.Module.IsDefaultModule ? decl.CompileName : decl.FullCompileName;
- }
- string DtCtorName(DatatypeCtor ctor) {
- Contract.Requires(ctor != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return DtName(ctor.EnclosingDatatype) + "_" + ctor.CompileName;
- }
- string DtCtorDeclartionName(DatatypeCtor ctor) {
- Contract.Requires(ctor != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return ctor.EnclosingDatatype.CompileName + "_" + ctor.CompileName;
- }
-
- string DtCtorName(DatatypeCtor ctor, List<TypeParameter> typeParams) {
- Contract.Requires(ctor != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- var s = DtCtorName(ctor);
- if (typeParams != null && typeParams.Count != 0) {
- s += "<" + TypeParameters(typeParams) + ">";
- }
- return s;
- }
- string DtCtorDeclarationName(DatatypeCtor ctor, List<TypeParameter> typeParams) {
- Contract.Requires(ctor != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- var s = DtCtorDeclartionName(ctor);
- if (typeParams != null && typeParams.Count != 0) {
- s += "<" + TypeParameters(typeParams) + ">";
- }
- return s;
- }
-
- string DtCtorName(DatatypeCtor ctor, List<Type> typeArgs) {
- Contract.Requires(ctor != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- var s = DtCtorName(ctor);
- if (typeArgs != null && typeArgs.Count != 0) {
- s += "<" + TypeNames(typeArgs) + ">";
- }
- return s;
- }
-
- public bool HasMain(Program program) {
- foreach (var module in program.Modules) {
- foreach (var decl in module.TopLevelDecls) {
- var c = decl as ClassDecl;
- if (c != null) {
- foreach (var member in c.Members) {
- var m = member as Method;
- if (m != null) {
- if (!m.IsGhost && m.Name == "Main" && m.Ins.Count == 0 && m.Outs.Count == 0) {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- void CompileClassMembers(ClassDecl c, int indent)
- {
- Contract.Requires(c != null);
- foreach (MemberDecl member in c.Members) {
- if (member is Field) {
- Field f = (Field)member;
- if (!f.IsGhost) {
- Indent(indent);
- wr.WriteLine("public {0} @{1} = {2};", TypeName(f.Type), f.CompileName, DefaultValue(f.Type));
- }
-
- } else if (member is Function) {
- Function f = (Function)member;
- if (f.IsGhost) {
- // nothing to compile
- } else if (f.Body == null) {
- Error("Function {0} has no body", f.FullName);
- } else {
- Indent(indent);
- wr.Write("public {0}{1} @{2}", f.IsStatic ? "static " : "", TypeName(f.ResultType), f.CompileName);
- if (f.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(f.TypeArgs));
- }
- wr.Write("(");
- WriteFormals("", f.Formals);
- wr.WriteLine(") {");
- CompileReturnBody(f.Body, indent + IndentAmount);
- Indent(indent); wr.WriteLine("}");
- }
-
- } else if (member is Method) {
- Method m = (Method)member;
- if (!m.IsGhost) {
- Indent(indent);
- wr.Write("public {0}void @{1}", m.IsStatic ? "static " : "", m.CompileName);
- if (m.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(m.TypeArgs));
- }
- wr.Write("(");
- int nIns = WriteFormals("", m.Ins);
- WriteFormals(nIns == 0 ? "" : ", ", m.Outs);
- wr.WriteLine(")");
- Indent(indent); wr.WriteLine("{");
- foreach (Formal p in m.Outs) {
- if (!p.IsGhost) {
- Indent(indent + IndentAmount);
- wr.WriteLine("@{0} = {1};", p.CompileName, DefaultValue(p.Type));
- }
- }
- if (m.Body == null) {
- Error("Method {0} has no body", m.FullName);
- } else {
- if (m.IsTailRecursive) {
- Indent(indent); wr.WriteLine("TAIL_CALL_START: ;");
- if (!m.IsStatic) {
- Indent(indent + IndentAmount); wr.WriteLine("var _this = this;");
- }
- }
- Contract.Assert(enclosingMethod == null);
- enclosingMethod = m;
- TrStmtList(m.Body.Body, indent);
- Contract.Assert(enclosingMethod == m);
- enclosingMethod = null;
- }
- Indent(indent); wr.WriteLine("}");
-
- // allow the Main method to be an instance method
- if (m.Name == "Main" && m.Ins.Count == 0 && m.Outs.Count == 0) {
- Indent(indent);
- wr.WriteLine("public static void Main(string[] args) {");
- Contract.Assert(m.EnclosingClass == c);
- Indent(indent + IndentAmount);
- wr.Write("@{0} b = new @{0}", c.CompileName);
- if (c.TypeArgs.Count != 0) {
- // instantiate every parameter, it doesn't particularly matter how
- wr.Write("<");
- string sep = "";
- for (int i = 0; i < c.TypeArgs.Count; i++) {
- wr.Write("{0}int", sep);
- sep = ", ";
- }
- wr.Write(">");
- }
- wr.WriteLine("();");
- Indent(indent + IndentAmount); wr.WriteLine("b.Main();");
- Indent(indent); wr.WriteLine("}");
- }
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member
- }
- }
- }
-
- void CompileReturnBody(Expression body, int indent) {
- body = body.Resolved;
- if (body is MatchExpr) {
- MatchExpr me = (MatchExpr)body;
- // Type source = e;
- // if (source.is_Ctor0) {
- // FormalType f0 = ((Dt_Ctor0)source._D).a0;
- // ...
- // return Body0;
- // } else if (...) {
- // ...
- // } else if (true) {
- // ...
- // }
-
- SpillLetVariableDecls(me.Source, indent);
- string source = "_source" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("{0} {1} = ", TypeName(cce.NonNull(me.Source.Type)), source);
- TrExpr(me.Source);
- wr.WriteLine(";");
-
- if (me.Cases.Count == 0) {
- // the verifier would have proved we never get here; still, we need some code that will compile
- Indent(indent);
- wr.WriteLine("throw new System.Exception();");
- } else {
- int i = 0;
- var sourceType = (UserDefinedType)me.Source.Type;
- foreach (MatchCaseExpr mc in me.Cases) {
- MatchCasePrelude(source, sourceType, cce.NonNull(mc.Ctor), mc.Arguments, i, me.Cases.Count, indent + IndentAmount);
- CompileReturnBody(mc.Body, indent + IndentAmount);
- i++;
- }
- Indent(indent); wr.WriteLine("}");
- }
-
- } else {
- SpillLetVariableDecls(body, indent);
- Indent(indent);
- wr.Write("return ");
- TrExpr(body);
- wr.WriteLine(";");
- }
- }
-
- void SpillLetVariableDecls(Expression expr, int indent) {
- Contract.Requires(0 <= indent);
- if (expr == null) {
- // allow "null" as an argument; nothing to do
- return;
- }
- if (expr is LetExpr) {
- var e = (LetExpr)expr;
- foreach (var v in e.Vars) {
- Indent(indent);
- wr.WriteLine("{0} @{1};", TypeName(v.Type), v.CompileName);
- }
- }
- foreach (var ee in expr.SubExpressions) {
- SpillLetVariableDecls(ee, indent);
- }
- }
-
- // ----- Type ---------------------------------------------------------------------------------
-
- readonly string DafnySetClass = "Dafny.Set";
- readonly string DafnyMultiSetClass = "Dafny.MultiSet";
- readonly string DafnySeqClass = "Dafny.Sequence";
- readonly string DafnyMapClass = "Dafny.Map";
-
- string TypeName(Type type)
- {
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- while (true) {
- TypeProxy tp = type as TypeProxy;
- if (tp == null) {
- break;
- } else if (tp.T == null) {
- // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
- return "object";
- } else {
- type = tp.T;
- }
- }
-
- if (type is BoolType) {
- return "bool";
- } else if (type is IntType) {
- return "BigInteger";
- } else if (type is ObjectType) {
- return "object";
- } else if (type.IsArrayType) {
- ArrayClassDecl at = type.AsArrayType;
- Contract.Assert(at != null); // follows from type.IsArrayType
- Type elType = UserDefinedType.ArrayElementType(type);
- string name = TypeName(elType) + "[";
- for (int i = 1; i < at.Dims; i++) {
- name += ",";
- }
- return name + "]";
- } else if (type is UserDefinedType) {
- UserDefinedType udt = (UserDefinedType)type;
- string s = "@" + udt.FullCompileName;
- if (udt.TypeArgs.Count != 0) {
- if (Contract.Exists(udt.TypeArgs, argType =>argType is ObjectType)) {
- Error("compilation does not support type 'object' as a type parameter; consider introducing a ghost");
- }
- s += "<" + TypeNames(udt.TypeArgs) + ">";
- }
- return s;
- } else if (type is SetType) {
- Type argType = ((SetType)type).Arg;
- if (argType is ObjectType) {
- Error("compilation of set<object> is not supported; consider introducing a ghost");
- }
- return DafnySetClass + "<" + TypeName(argType) + ">";
- } else if (type is SeqType) {
- Type argType = ((SeqType)type).Arg;
- if (argType is ObjectType) {
- Error("compilation of seq<object> is not supported; consider introducing a ghost");
- }
- return DafnySeqClass + "<" + TypeName(argType) + ">";
- } else if (type is MultiSetType) {
- Type argType = ((MultiSetType)type).Arg;
- if (argType is ObjectType) {
- Error("compilation of seq<object> is not supported; consider introducing a ghost");
- }
- return DafnyMultiSetClass + "<" + TypeName(argType) + ">";
- } else if (type is MapType) {
- Type domType = ((MapType)type).Domain;
- Type ranType = ((MapType)type).Range;
- if (domType is ObjectType || ranType is ObjectType) {
- Error("compilation of map<object, _> or map<_, object> is not supported; consider introducing a ghost");
- }
- return DafnyMapClass + "<" + TypeName(domType) + "," + TypeName(ranType) + ">";
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- string/*!*/ TypeNames(List<Type/*!*/>/*!*/ types) {
- Contract.Requires(cce.NonNullElements(types));
- Contract.Ensures(Contract.Result<string>() != null);
-
- string s = "";
- string sep = "";
- foreach (Type t in types) {
- s += sep + TypeName(t);
- sep = ",";
- }
- return s;
- }
-
- string/*!*/ TypeParameters(List<TypeParameter/*!*/>/*!*/ targs) {
- Contract.Requires(cce.NonNullElements(targs));
- Contract.Ensures(Contract.Result<string>() != null);
-
- string s = "";
- string sep = "";
- foreach (TypeParameter tp in targs) {
- s += sep + "@" + tp.CompileName;
- sep = ",";
- }
- return s;
- }
-
- string DefaultValue(Type type)
- {
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- while (true) {
- TypeProxy tp = type as TypeProxy;
- if (tp == null) {
- break;
- } else if (tp.T == null) {
- // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
- return "null";
- } else {
- type = tp.T;
- }
- }
-
- if (type is BoolType) {
- return "false";
- } else if (type is IntType) {
- return "new BigInteger(0)";
- } else if (type.IsRefType) {
- return string.Format("({0})null", TypeName(type));
- } else if (type.IsDatatype) {
- UserDefinedType udt = (UserDefinedType)type;
- string s = "@" + udt.FullCompileName;
- if (udt.TypeArgs.Count != 0) {
- s += "<" + TypeNames(udt.TypeArgs) + ">";
- }
- return string.Format("new {0}()", s);
- } else if (type.IsTypeParameter) {
- UserDefinedType udt = (UserDefinedType)type;
- return "default(@" + udt.FullCompileName + ")";
- } else if (type is SetType) {
- return DafnySetClass + "<" + TypeName(((SetType)type).Arg) + ">.Empty";
- } else if (type is MultiSetType) {
- return DafnyMultiSetClass + "<" + TypeName(((MultiSetType)type).Arg) + ">.Empty";
- } else if (type is SeqType) {
- return DafnySeqClass + "<" + TypeName(((SeqType)type).Arg) + ">.Empty";
- } else if (type is MapType) {
- return TypeName(type)+".Empty";
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- // ----- Stmt ---------------------------------------------------------------------------------
-
- void CheckHasNoAssumes(Statement stmt) {
- Contract.Requires(stmt != null);
- if (stmt is AssumeStmt) {
- Error("an assume statement cannot be compiled (line {0})", stmt.Tok.line);
- } else if (stmt is AssignSuchThatStmt) {
- var s = (AssignSuchThatStmt)stmt;
- if (s.AssumeToken != null) {
- Error("an assume statement cannot be compiled (line {0})", s.AssumeToken.line);
- }
- } else {
- foreach (var ss in stmt.SubStatements) {
- CheckHasNoAssumes(ss);
- }
- }
- }
-
- void TrStmt(Statement stmt, int indent)
- {
- Contract.Requires(stmt != null);
- if (stmt.IsGhost) {
- CheckHasNoAssumes(stmt);
- return;
- }
-
- if (stmt is PrintStmt) {
- PrintStmt s = (PrintStmt)stmt;
- foreach (Attributes.Argument arg in s.Args) {
- SpillLetVariableDecls(arg.E, indent);
- Indent(indent);
- wr.Write("System.Console.Write(");
- if (arg.S != null) {
- wr.Write("\"{0}\"", arg.S);
- } else {
- Contract.Assert(arg.E != null);
- TrExpr(arg.E);
- }
- wr.WriteLine(");");
- }
- } else if (stmt is BreakStmt) {
- var s = (BreakStmt)stmt;
- Indent(indent);
- wr.WriteLine("goto after_{0};", s.TargetStmt.Labels.Data.UniqueId);
- } else if (stmt is ProduceStmt) {
- var s = (ProduceStmt)stmt;
- if (s.hiddenUpdate != null)
- TrStmt(s.hiddenUpdate, indent);
- Indent(indent);
- if (s is YieldStmt) {
- wr.WriteLine("yield return null;");
- } else {
- wr.WriteLine("return;");
- }
- } else if (stmt is UpdateStmt) {
- var s = (UpdateStmt)stmt;
- var resolved = s.ResolvedStatements;
- if (resolved.Count == 1) {
- TrStmt(resolved[0], indent);
- } else {
- // multi-assignment
- Contract.Assert(s.Lhss.Count == resolved.Count);
- Contract.Assert(s.Rhss.Count == resolved.Count);
- var lvalues = new List<string>();
- var rhss = new List<string>();
- for (int i = 0; i < resolved.Count; i++) {
- if (!resolved[i].IsGhost) {
- var lhs = s.Lhss[i];
- var rhs = s.Rhss[i];
- if (!(rhs is HavocRhs)) {
- lvalues.Add(CreateLvalue(lhs, indent));
-
- string target = "_rhs" + tmpVarCount;
- tmpVarCount++;
- rhss.Add(target);
- TrRhs("var " + target, null, rhs, indent);
- }
- }
- }
- Contract.Assert(lvalues.Count == rhss.Count);
- for (int i = 0; i < lvalues.Count; i++) {
- Indent(indent);
- wr.WriteLine("{0} = {1};", lvalues[i], rhss[i]);
- }
- }
-
- } else if (stmt is AssignStmt) {
- AssignStmt s = (AssignStmt)stmt;
- Contract.Assert(!(s.Lhs is SeqSelectExpr) || ((SeqSelectExpr)s.Lhs).SelectOne); // multi-element array assignments are not allowed
- TrRhs(null, s.Lhs, s.Rhs, indent);
-
- } else if (stmt is AssignSuchThatStmt) {
- var s = (AssignSuchThatStmt)stmt;
- foreach (var lhs in s.Lhss) {
- // assigning to a local ghost variable or to a ghost field is okay
- if (!AssignStmt.LhsIsToGhost(lhs)) {
- Error("compiling an assign-such-that statement with a non-ghost left-hand side is currently not supported (line {0})", stmt.Tok.line);
- break; // no need to say more
- }
- }
-
- } else if (stmt is VarDecl) {
- TrVarDecl((VarDecl)stmt, true, indent);
-
- } else if (stmt is CallStmt) {
- CallStmt s = (CallStmt)stmt;
- TrCallStmt(s, null, indent);
-
- } else if (stmt is BlockStmt) {
- Indent(indent); wr.WriteLine("{");
- TrStmtList(((BlockStmt)stmt).Body, indent);
- Indent(indent); wr.WriteLine("}");
-
- } else if (stmt is IfStmt) {
- IfStmt s = (IfStmt)stmt;
- if (s.Guard == null) {
- // we can compile the branch of our choice
- if (s.Els == null) {
- // let's compile the "else" branch, since that involves no work
- // (still, let's leave a marker in the source code to indicate that this is what we did)
- Indent(indent);
- wr.WriteLine("if (!false) { }");
- } else {
- // let's compile the "then" branch
- Indent(indent);
- wr.WriteLine("if (true)");
- TrStmt(s.Thn, indent);
- }
- } else {
- SpillLetVariableDecls(s.Guard, indent);
- Indent(indent); wr.Write("if (");
- TrExpr(s.Guard);
- wr.WriteLine(")");
-
- TrStmt(s.Thn, indent);
- if (s.Els != null) {
- Indent(indent); wr.WriteLine("else");
- TrStmt(s.Els, indent);
- }
- }
-
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- foreach (var alternative in s.Alternatives) {
- SpillLetVariableDecls(alternative.Guard, indent);
- }
- Indent(indent);
- foreach (var alternative in s.Alternatives) {
- wr.Write("if (");
- TrExpr(alternative.Guard);
- wr.WriteLine(") {");
- TrStmtList(alternative.Body, indent);
- Indent(indent);
- wr.Write("} else ");
- }
- wr.WriteLine("{ /*unreachable alternative*/ }");
-
- } else if (stmt is WhileStmt) {
- WhileStmt s = (WhileStmt)stmt;
- if (s.Guard == null) {
- Indent(indent);
- wr.WriteLine("while (false) { }");
- } else {
- SpillLetVariableDecls(s.Guard, indent);
- Indent(indent);
- wr.Write("while (");
- TrExpr(s.Guard);
- wr.WriteLine(")");
- TrStmt(s.Body, indent);
- }
-
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- if (s.Alternatives.Count != 0) {
- Indent(indent);
- wr.WriteLine("while (true) {");
- int ind = indent + IndentAmount;
- foreach (var alternative in s.Alternatives) {
- SpillLetVariableDecls(alternative.Guard, ind);
- }
- Indent(ind);
- foreach (var alternative in s.Alternatives) {
- wr.Write("if (");
- TrExpr(alternative.Guard);
- wr.WriteLine(") {");
- TrStmtList(alternative.Body, ind);
- Indent(ind);
- wr.Write("} else ");
- }
- wr.WriteLine("{ break; }");
- Indent(indent);
- wr.WriteLine("}");
- }
-
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- if (s.Kind != ParallelStmt.ParBodyKind.Assign) {
- // Call and Proof have no side effects, so they can simply be optimized away.
- return;
- } else if (s.BoundVars.Count == 0) {
- // the bound variables just spell out a single point, so the parallel statement is equivalent to one execution of the body
- TrStmt(s.Body, indent);
- return;
- }
- var s0 = (AssignStmt)s.S0;
- if (s0.Rhs is HavocRhs) {
- // The parallel statement says to havoc a bunch of things. This can be efficiently compiled
- // into doing nothing.
- return;
- }
- var rhs = ((ExprRhs)s0.Rhs).Expr;
-
- // Compile:
- // parallel (w,x,y,z | Range(w,x,y,z)) {
- // LHS(w,x,y,z) := RHS(w,x,y,z);
- // }
- // where w,x,y,z have types seq<W>,set<X>,int,bool and LHS has L-1 top-level subexpressions
- // (that is, L denotes the number of top-level subexpressions of LHS plus 1),
- // into:
- // var ingredients = new List< L-Tuple >();
- // foreach (W w in sq.UniqueElements) {
- // foreach (X x in st.Elements) {
- // for (BigInteger y = Lo; j < Hi; j++) {
- // for (bool z in Helper.AllBooleans) {
- // if (Range(w,x,y,z)) {
- // ingredients.Add(new L-Tuple( LHS0(w,x,y,z), LHS1(w,x,y,z), ..., RHS(w,x,y,z) ));
- // }
- // }
- // }
- // }
- // }
- // foreach (L-Tuple l in ingredients) {
- // LHS[ l0, l1, l2, ..., l(L-2) ] = l(L-1);
- // }
- //
- // Note, because the .NET Tuple class only supports up to 8 components, the compiler implementation
- // here supports arrays only up to 6 dimensions. This does not seem like a serious practical limitation.
- // However, it may be more noticeable if the parallel statement supported parallel assignments in its
- // body. To support cases where tuples would need more than 8 components, .NET Tuple's would have to
- // be nested.
-
- // Temporary names
- string ingredients = "_ingredients" + tmpVarCount;
- string tup = "_tup" + tmpVarCount;
- tmpVarCount++;
-
- // Compute L
- int L;
- string tupleTypeArgs;
- if (s0.Lhs is FieldSelectExpr) {
- var lhs = (FieldSelectExpr)s0.Lhs;
- L = 2;
- tupleTypeArgs = TypeName(lhs.Obj.Type);
- } else if (s0.Lhs is SeqSelectExpr) {
- var lhs = (SeqSelectExpr)s0.Lhs;
- L = 3;
- // note, we might as well do the BigInteger-to-int cast for array indices here, before putting things into the Tuple rather than when they are extracted from the Tuple
- tupleTypeArgs = TypeName(lhs.Seq.Type) + ",int";
- } else {
- var lhs = (MultiSelectExpr)s0.Lhs;
- L = 2 + lhs.Indices.Count;
- if (8 < L) {
- Error("compiler currently does not support assignments to more-than-6-dimensional arrays in parallel statements");
- return;
- }
- tupleTypeArgs = TypeName(lhs.Array.Type);
- for (int i = 0; i < lhs.Indices.Count; i++) {
- // note, we might as well do the BigInteger-to-int cast for array indices here, before putting things into the Tuple rather than when they are extracted from the Tuple
- tupleTypeArgs += ",int";
- }
- }
- tupleTypeArgs += "," + TypeName(rhs.Type);
-
- // declare and construct "ingredients"
- Indent(indent);
- wr.WriteLine("var {0} = new System.Collections.Generic.List<System.Tuple<{1}>>();", ingredients, tupleTypeArgs);
-
- var n = s.BoundVars.Count;
- Contract.Assert(s.Bounds.Count == n);
- for (int i = 0; i < n; i++) {
- var ind = indent + i * IndentAmount;
- var bound = s.Bounds[i];
- var bv = s.BoundVars[i];
- if (bound is ComprehensionExpr.BoolBoundedPool) {
- Indent(ind);
- wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
- } else if (bound is ComprehensionExpr.IntBoundedPool) {
- var b = (ComprehensionExpr.IntBoundedPool)bound;
- SpillLetVariableDecls(b.LowerBound, ind);
- SpillLetVariableDecls(b.UpperBound, ind);
- Indent(ind);
- wr.Write("for (var @{0} = ", bv.CompileName);
- TrExpr(b.LowerBound);
- wr.Write("; @{0} < ", bv.CompileName);
- TrExpr(b.UpperBound);
- wr.Write("; @{0}++) {{ ", bv.CompileName);
- } else if (bound is ComprehensionExpr.SetBoundedPool) {
- var b = (ComprehensionExpr.SetBoundedPool)bound;
- SpillLetVariableDecls(b.Set, ind);
- Indent(ind);
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Set);
- wr.Write(").Elements) { ");
- } else if (bound is ComprehensionExpr.SeqBoundedPool) {
- var b = (ComprehensionExpr.SeqBoundedPool)bound;
- SpillLetVariableDecls(b.Seq, ind);
- Indent(ind);
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Seq);
- wr.Write(").UniqueElements) { ");
- } else if (bound is ComprehensionExpr.DatatypeBoundedPool) {
- var b = (ComprehensionExpr.DatatypeBoundedPool)bound;
- wr.Write("foreach (var @{0} in {1}.AllSingletonConstructors) {{", bv.CompileName, TypeName(bv.Type));
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
- }
- wr.WriteLine();
- }
-
- // if (range) {
- // ingredients.Add(new L-Tuple( LHS0(w,x,y,z), LHS1(w,x,y,z), ..., RHS(w,x,y,z) ));
- // }
- SpillLetVariableDecls(s.Range, indent + n * IndentAmount);
- Indent(indent + n * IndentAmount);
- wr.Write("if ");
- TrParenExpr(s.Range);
- wr.WriteLine(" {");
-
- var indFinal = indent + (n + 1) * IndentAmount;
- SpillLetVariableDecls(s0.Lhs, indFinal);
- SpillLetVariableDecls(rhs, indFinal);
- Indent(indFinal);
- wr.Write("{0}.Add(new System.Tuple<{1}>(", ingredients, tupleTypeArgs);
- if (s0.Lhs is FieldSelectExpr) {
- var lhs = (FieldSelectExpr)s0.Lhs;
- TrExpr(lhs.Obj);
- } else if (s0.Lhs is SeqSelectExpr) {
- var lhs = (SeqSelectExpr)s0.Lhs;
- TrExpr(lhs.Seq);
- wr.Write(", (int)(");
- TrExpr(lhs.E0);
- wr.Write(")");
- } else {
- var lhs = (MultiSelectExpr)s0.Lhs;
- TrExpr(lhs.Array);
- for (int i = 0; i < lhs.Indices.Count; i++) {
- wr.Write(", (int)(");
- TrExpr(lhs.Indices[i]);
- wr.Write(")");
- }
- wr.WriteLine("] = {0}.Item{1};", tup, L);
- }
- wr.Write(", ");
- TrExpr(rhs);
- wr.WriteLine("));");
-
- Indent(indent + n * IndentAmount);
- wr.WriteLine("}");
-
- for (int i = n; 0 <= --i; ) {
- Indent(indent + i * IndentAmount);
- wr.WriteLine("}");
- }
-
- // foreach (L-Tuple l in ingredients) {
- // LHS[ l0, l1, l2, ..., l(L-2) ] = l(L-1);
- // }
- Indent(indent);
- wr.WriteLine("foreach (var {0} in {1}) {{", tup, ingredients);
- Indent(indent + IndentAmount);
- if (s0.Lhs is FieldSelectExpr) {
- var lhs = (FieldSelectExpr)s0.Lhs;
- wr.WriteLine("{0}.Item1.@{1} = {0}.Item2;", tup, lhs.FieldName);
- } else if (s0.Lhs is SeqSelectExpr) {
- var lhs = (SeqSelectExpr)s0.Lhs;
- wr.WriteLine("{0}.Item1[{0}.Item2] = {0}.Item3;", tup);
- } else {
- var lhs = (MultiSelectExpr)s0.Lhs;
- wr.Write("{0}.Item1[");
- string sep = "";
- for (int i = 0; i < lhs.Indices.Count; i++) {
- wr.Write("{0}{1}.Item{2}", sep, tup, i + 2);
- sep = ", ";
- }
- wr.WriteLine("] = {0}.Item{1};", tup, L);
- }
- Indent(indent);
- wr.WriteLine("}");
-
- } else if (stmt is MatchStmt) {
- MatchStmt s = (MatchStmt)stmt;
- // Type source = e;
- // if (source.is_Ctor0) {
- // FormalType f0 = ((Dt_Ctor0)source._D).a0;
- // ...
- // Body0;
- // } else if (...) {
- // ...
- // } else if (true) {
- // ...
- // }
- if (s.Cases.Count != 0) {
- var sourceType = (UserDefinedType)s.Source.Type;
-
- SpillLetVariableDecls(s.Source, indent);
- string source = "_source" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("{0} {1} = ", TypeName(cce.NonNull(s.Source.Type)), source);
- TrExpr(s.Source);
- wr.WriteLine(";");
-
- int i = 0;
- foreach (MatchCaseStmt mc in s.Cases) {
- MatchCasePrelude(source, sourceType, cce.NonNull(mc.Ctor), mc.Arguments, i, s.Cases.Count, indent);
- TrStmtList(mc.Body, indent);
- i++;
- }
- Indent(indent); wr.WriteLine("}");
- }
-
- } else if (stmt is ConcreteSyntaxStatement) {
- var s = (ConcreteSyntaxStatement)stmt;
- foreach (var ss in s.ResolvedStatements) {
- TrStmt(ss, indent);
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
- }
- }
-
- string CreateLvalue(Expression lhs, int indent) {
- lhs = lhs.Resolved;
- SpillLetVariableDecls(lhs, indent);
- if (lhs is IdentifierExpr) {
- var ll = (IdentifierExpr)lhs;
- return "@" + ll.Var.CompileName;
- } else if (lhs is FieldSelectExpr) {
- var ll = (FieldSelectExpr)lhs;
- string obj = "_obj" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("var {0} = ", obj);
- TrExpr(ll.Obj);
- wr.WriteLine(";");
- return string.Format("{0}.@{1}", obj, ll.Field.CompileName);
- } else if (lhs is SeqSelectExpr) {
- var ll = (SeqSelectExpr)lhs;
- string arr = "_arr" + tmpVarCount;
- string index = "_index" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("var {0} = ", arr);
- TrExpr(ll.Seq);
- wr.WriteLine(";");
- Indent(indent);
- wr.Write("var {0} = ", index);
- TrExpr(ll.E0);
- wr.WriteLine(";");
- return string.Format("{0}[(int){1}]", arr, index);
- } else {
- var ll = (MultiSelectExpr)lhs;
- string arr = "_arr" + tmpVarCount;
- Indent(indent);
- wr.Write("var {0} = ", arr);
- TrExpr(ll.Array);
- wr.WriteLine(";");
- string fullString = arr + "[";
- string sep = "";
- int i = 0;
- foreach (var idx in ll.Indices) {
- string index = "_index" + i + "_" + tmpVarCount;
- Indent(indent);
- wr.Write("var {0} = ", index);
- TrExpr(idx);
- wr.WriteLine(";");
- fullString += sep + "(int)" + index;
- sep = ", ";
- i++;
- }
- tmpVarCount++;
- return fullString + "]";
- }
- }
-
- void TrRhs(string target, Expression targetExpr, AssignmentRhs rhs, int indent) {
- Contract.Requires((target == null) != (targetExpr == null));
- SpillLetVariableDecls(targetExpr, indent);
- var tRhs = rhs as TypeRhs;
- if (tRhs != null && tRhs.InitCall != null) {
- string nw = "_nw" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("var {0} = ", nw);
- TrAssignmentRhs(rhs); // in this case, this call will not require us to spill any let variables first
- wr.WriteLine(";");
- TrCallStmt(tRhs.InitCall, nw, indent);
- Indent(indent);
- if (target != null) {
- wr.Write(target);
- } else {
- TrExpr(targetExpr);
- }
- wr.WriteLine(" = {0};", nw);
- } else if (rhs is HavocRhs) {
- // do nothing
- } else {
- if (rhs is ExprRhs) {
- SpillLetVariableDecls(((ExprRhs)rhs).Expr, indent);
- } else if (tRhs != null && tRhs.ArrayDimensions != null) {
- foreach (Expression dim in tRhs.ArrayDimensions) {
- SpillLetVariableDecls(dim, indent);
- }
- }
- Indent(indent);
- if (target != null) {
- wr.Write(target);
- } else {
- TrExpr(targetExpr);
- }
- wr.Write(" = ");
- TrAssignmentRhs(rhs);
- wr.WriteLine(";");
- }
- }
-
- void TrCallStmt(CallStmt s, string receiverReplacement, int indent) {
- Contract.Requires(s != null);
- Contract.Assert(s.Method != null); // follows from the fact that stmt has been successfully resolved
-
- if (s.Method == enclosingMethod && enclosingMethod.IsTailRecursive) {
- // compile call as tail-recursive
-
- // assign the actual in-parameters to temporary variables
- var inTmps = new List<string>();
- for (int i = 0; i < s.Method.Ins.Count; i++) {
- Formal p = s.Method.Ins[i];
- if (!p.IsGhost) {
- SpillLetVariableDecls(s.Args[i], indent);
- }
- }
- if (receiverReplacement != null) {
- // TODO: What to do here? When does this happen, what does it mean?
- } else if (!s.Method.IsStatic) {
- SpillLetVariableDecls(s.Receiver, indent);
-
- string inTmp = "_in" + tmpVarCount;
- tmpVarCount++;
- inTmps.Add(inTmp);
- Indent(indent);
- wr.Write("var {0} = ", inTmp);
- TrExpr(s.Receiver);
- wr.WriteLine(";");
- }
- for (int i = 0; i < s.Method.Ins.Count; i++) {
- Formal p = s.Method.Ins[i];
- if (!p.IsGhost) {
- string inTmp = "_in" + tmpVarCount;
- tmpVarCount++;
- inTmps.Add(inTmp);
- Indent(indent);
- wr.Write("var {0} = ", inTmp);
- TrExpr(s.Args[i]);
- wr.WriteLine(";");
- }
- }
- // Now, assign to the formals
- int n = 0;
- if (!s.Method.IsStatic) {
- Indent(indent);
- wr.WriteLine("_this = {0};", inTmps[n]);
- n++;
- }
- foreach (var p in s.Method.Ins) {
- if (!p.IsGhost) {
- Indent(indent);
- wr.WriteLine("{0} = {1};", p.CompileName, inTmps[n]);
- n++;
- }
- }
- Contract.Assert(n == inTmps.Count);
- // finally, the jump back to the head of the method
- Indent(indent);
- wr.WriteLine("goto TAIL_CALL_START;");
-
- } else {
- // compile call as a regular call
-
- var lvalues = new List<string>();
- Contract.Assert(s.Lhs.Count == s.Method.Outs.Count);
- for (int i = 0; i < s.Method.Outs.Count; i++) {
- Formal p = s.Method.Outs[i];
- if (!p.IsGhost) {
- lvalues.Add(CreateLvalue(s.Lhs[i], indent));
- }
- }
- var outTmps = new List<string>();
- for (int i = 0; i < s.Method.Outs.Count; i++) {
- Formal p = s.Method.Outs[i];
- if (!p.IsGhost) {
- string target = "_out" + tmpVarCount;
- tmpVarCount++;
- outTmps.Add(target);
- Indent(indent);
- wr.WriteLine("{0} {1};", TypeName(s.Lhs[i].Type), target);
- }
- }
- Contract.Assert(lvalues.Count == outTmps.Count);
-
- for (int i = 0; i < s.Method.Ins.Count; i++) {
- Formal p = s.Method.Ins[i];
- if (!p.IsGhost) {
- SpillLetVariableDecls(s.Args[i], indent);
- }
- }
- if (receiverReplacement != null) {
- Indent(indent);
- wr.Write("@" + receiverReplacement);
- } else if (s.Method.IsStatic) {
- Indent(indent);
- wr.Write(TypeName(cce.NonNull(s.Receiver.Type)));
- } else {
- SpillLetVariableDecls(s.Receiver, indent);
- Indent(indent);
- TrParenExpr(s.Receiver);
- }
- wr.Write(".@{0}(", s.Method.CompileName);
-
- string sep = "";
- for (int i = 0; i < s.Method.Ins.Count; i++) {
- Formal p = s.Method.Ins[i];
- if (!p.IsGhost) {
- wr.Write(sep);
- TrExpr(s.Args[i]);
- sep = ", ";
- }
- }
-
- foreach (var outTmp in outTmps) {
- wr.Write("{0}out {1}", sep, outTmp);
- sep = ", ";
- }
- wr.WriteLine(");");
-
- // assign to the actual LHSs
- for (int j = 0; j < lvalues.Count; j++) {
- Indent(indent);
- wr.WriteLine("{0} = {1};", lvalues[j], outTmps[j]);
- }
- }
- }
-
- int tmpVarCount = 0;
-
- /// <summary>
- /// Before calling TrAssignmentRhs(rhs), the caller must have spilled the let variables declared in "rhs".
- /// </summary>
- void TrAssignmentRhs(AssignmentRhs rhs) {
- Contract.Requires(rhs != null);
- Contract.Requires(!(rhs is HavocRhs));
- if (rhs is ExprRhs) {
- ExprRhs e = (ExprRhs)rhs;
- TrExpr(e.Expr);
-
- } else {
- TypeRhs tp = (TypeRhs)rhs;
- if (tp.ArrayDimensions == null) {
- wr.Write("new {0}()", TypeName(tp.EType));
- } else {
- if (tp.EType is IntType || tp.EType.IsTypeParameter) {
- // Because the default constructor for BigInteger does not generate a valid BigInteger, we have
- // to excplicitly initialize the elements of an integer array. This is all done in a helper routine.
- wr.Write("Dafny.Helpers.InitNewArray{0}<{1}>", tp.ArrayDimensions.Count, TypeName(tp.EType));
- string prefix = "(";
- foreach (Expression dim in tp.ArrayDimensions) {
- wr.Write(prefix);
- TrParenExpr(dim);
- prefix = ", ";
- }
- wr.Write(")");
- } else {
- wr.Write("new {0}", TypeName(tp.EType));
- string prefix = "[";
- foreach (Expression dim in tp.ArrayDimensions) {
- wr.Write("{0}(int)", prefix);
- TrParenExpr(dim);
- prefix = ", ";
- }
- wr.Write("]");
- }
- }
- }
- }
-
- void TrStmtList(List<Statement/*!*/>/*!*/ stmts, int indent) {Contract.Requires(cce.NonNullElements(stmts));
- foreach (Statement ss in stmts) {
- TrStmt(ss, indent + IndentAmount);
- if (ss.Labels != null) {
- Indent(indent); // labels are not indented as much as the statements
- wr.WriteLine("after_{0}: ;", ss.Labels.Data.UniqueId);
- }
- }
- }
-
- void TrVarDecl(VarDecl s, bool alwaysInitialize, int indent) {
- Contract.Requires(s != null);
- if (s.IsGhost) {
- // only emit non-ghosts (we get here only for local variables introduced implicitly by call statements)
- return;
- }
-
- Indent(indent);
- wr.Write("{0} @{1}", TypeName(s.Type), s.CompileName);
- if (alwaysInitialize) {
- // produce a default value
- wr.WriteLine(" = {0};", DefaultValue(s.Type));
- } else {
- wr.WriteLine(";");
- }
- }
-
- void MatchCasePrelude(string source, UserDefinedType sourceType, DatatypeCtor ctor, List<BoundVar/*!*/>/*!*/ arguments, int caseIndex, int caseCount, int indent) {
- Contract.Requires(source != null);
- Contract.Requires(sourceType != null);
- Contract.Requires(ctor != null);
- Contract.Requires(cce.NonNullElements(arguments));
- // if (source.is_Ctor0) {
- // FormalType f0 = ((Dt_Ctor0)source._D).a0;
- // ...
- Indent(indent);
- wr.Write("{0}if (", caseIndex == 0 ? "" : "} else ");
- if (caseIndex == caseCount - 1) {
- wr.Write("true");
- } else {
- wr.Write("{0}.is_{1}", source, ctor.CompileName);
- }
- wr.WriteLine(") {");
-
- int k = 0; // number of processed non-ghost arguments
- for (int m = 0; m < ctor.Formals.Count; m++) {
- Formal arg = ctor.Formals[m];
- if (!arg.IsGhost) {
- BoundVar bv = arguments[m];
- // FormalType f0 = ((Dt_Ctor0)source._D).a0;
- Indent(indent + IndentAmount);
- wr.WriteLine("{0} @{1} = (({2}){3}._D).@{4};",
- TypeName(bv.Type), bv.CompileName, DtCtorName(ctor, sourceType.TypeArgs), source, FormalName(arg, k));
- k++;
- }
- }
- }
-
- // ----- Expression ---------------------------------------------------------------------------
-
- /// <summary>
- /// Before calling TrParenExpr(expr), the caller must have spilled the let variables declared in "expr".
- /// </summary>
- void TrParenExpr(string prefix, Expression expr) {
- Contract.Requires(prefix != null);
- Contract.Requires(expr != null);
- wr.Write(prefix);
- TrParenExpr(expr);
- }
-
- /// <summary>
- /// Before calling TrParenExpr(expr), the caller must have spilled the let variables declared in "expr".
- /// </summary>
- void TrParenExpr(Expression expr) {
- Contract.Requires(expr != null);
- wr.Write("(");
- TrExpr(expr);
- wr.Write(")");
- }
-
- /// <summary>
- /// Before calling TrExprList(exprs), the caller must have spilled the let variables declared in expressions in "exprs".
- /// </summary>
- void TrExprList(List<Expression/*!*/>/*!*/ exprs) {
- Contract.Requires(cce.NonNullElements(exprs));
- wr.Write("(");
- string sep = "";
- foreach (Expression e in exprs) {
- wr.Write(sep);
- TrExpr(e);
- sep = ", ";
- }
- wr.Write(")");
- }
- void TrExprPairList(List<ExpressionPair/*!*/>/*!*/ exprs) {
- Contract.Requires(cce.NonNullElements(exprs));
- wr.Write("(");
- string sep = "";
- foreach (ExpressionPair p in exprs) {
- wr.Write(sep);
- wr.Write("new Dafny.Pair<");
- wr.Write(TypeName(p.A.Type));
- wr.Write(",");
- wr.Write(TypeName(p.B.Type));
- wr.Write(">(");
- TrExpr(p.A);
- wr.Write(",");
- TrExpr(p.B);
- wr.Write(")");
- sep = ", ";
- }
- wr.Write(")");
- }
-
- /// <summary>
- /// Before calling TrExpr(expr), the caller must have spilled the let variables declared in "expr".
- /// </summary>
- void TrExpr(Expression expr)
- {
- Contract.Requires(expr != null);
- if (expr is LiteralExpr) {
- LiteralExpr e = (LiteralExpr)expr;
- if (e.Value == null) {
- wr.Write("({0})null", TypeName(e.Type));
- } else if (e.Value is bool) {
- wr.Write((bool)e.Value ? "true" : "false");
- } else if (e.Value is BigInteger) {
- BigInteger i = (BigInteger)e.Value;
- if (new BigInteger(int.MinValue) <= i && i <= new BigInteger(int.MaxValue)) {
- wr.Write("new BigInteger({0})", i);
- } else {
- wr.Write("BigInteger.Parse(\"{0}\")", i);
- }
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected literal
- }
-
- } else if (expr is ThisExpr) {
- wr.Write(enclosingMethod != null && enclosingMethod.IsTailRecursive ? "_this" : "this");
-
- } else if (expr is IdentifierExpr) {
- IdentifierExpr e = (IdentifierExpr)expr;
- wr.Write("@" + e.Var.CompileName);
-
- } else if (expr is SetDisplayExpr) {
- SetDisplayExpr e = (SetDisplayExpr)expr;
- Type elType = cce.NonNull((SetType)e.Type).Arg;
- wr.Write("{0}<{1}>.FromElements", DafnySetClass, TypeName(elType));
- TrExprList(e.Elements);
-
- } else if (expr is MultiSetDisplayExpr) {
- MultiSetDisplayExpr e = (MultiSetDisplayExpr)expr;
- Type elType = cce.NonNull((MultiSetType)e.Type).Arg;
- wr.Write("{0}<{1}>.FromElements", DafnyMultiSetClass, TypeName(elType));
- TrExprList(e.Elements);
-
- } else if (expr is SeqDisplayExpr) {
- SeqDisplayExpr e = (SeqDisplayExpr)expr;
- Type elType = cce.NonNull((SeqType)e.Type).Arg;
- wr.Write("{0}<{1}>.FromElements", DafnySeqClass, TypeName(elType));
- TrExprList(e.Elements);
-
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- wr.Write("{0}.FromElements", TypeName(e.Type));
- TrExprPairList(e.Elements);
-
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr e = (FieldSelectExpr)expr;
- SpecialField sf = e.Field as SpecialField;
- if (sf != null) {
- wr.Write(sf.PreString);
- TrParenExpr(e.Obj);
- wr.Write(".{0}", sf.CompiledName);
- wr.Write(sf.PostString);
- } else {
- TrParenExpr(e.Obj);
- wr.Write(".@{0}", e.Field.CompileName);
- }
-
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- Contract.Assert(e.Seq.Type != null);
- if (e.Seq.Type.IsArrayType) {
- if (e.SelectOne) {
- Contract.Assert(e.E0 != null && e.E1 == null);
- TrParenExpr(e.Seq);
- wr.Write("[(int)");
- TrParenExpr(e.E0);
- wr.Write("]");
- } else {
- TrParenExpr("Dafny.Helpers.SeqFromArray", e.Seq);
- if (e.E1 != null) {
- TrParenExpr(".Take", e.E1);
- }
- if (e.E0 != null) {
- TrParenExpr(".Drop", e.E0);
- }
- }
- } else if (e.SelectOne) {
- Contract.Assert(e.E0 != null && e.E1 == null);
- TrParenExpr(e.Seq);
- TrParenExpr(".Select", e.E0);
- } else {
- TrParenExpr(e.Seq);
- if (e.E1 != null) {
- TrParenExpr(".Take", e.E1);
- }
- if (e.E0 != null) {
- TrParenExpr(".Drop", e.E0);
- }
- }
- } else if (expr is MultiSetFormingExpr) {
- MultiSetFormingExpr e = (MultiSetFormingExpr)expr;
- wr.Write("{0}<{1}>", DafnyMultiSetClass, TypeName(((CollectionType)e.E.Type).Arg));
- if (e.E.Type is SeqType) {
- TrParenExpr(".FromSeq", e.E);
- } else if (e.E.Type is SetType) {
- TrParenExpr(".FromSet", e.E);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException();
- }
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
- TrParenExpr(e.Array);
- string prefix = "[";
- foreach (Expression idx in e.Indices) {
- wr.Write("{0}(int)", prefix);
- TrParenExpr(idx);
- prefix = ", ";
- }
- wr.Write("]");
-
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- TrParenExpr(e.Seq);
- wr.Write(".Update(");
- TrExpr(e.Index);
- wr.Write(", ");
- TrExpr(e.Value);
- wr.Write(")");
-
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- CompileFunctionCallExpr(e, wr, TrExpr);
-
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- Contract.Assert(dtv.Ctor != null); // since dtv has been successfully resolved
- var typeParams = dtv.InferredTypeArgs.Count == 0 ? "" : string.Format("<{0}>", TypeNames(dtv.InferredTypeArgs));
-
- wr.Write("new {0}{1}(", DtName(dtv.Ctor.EnclosingDatatype), typeParams);
- if (!dtv.IsCoCall) {
- // For an ordinary constructor (that is, one that does not guard any co-recursive calls), generate:
- // new Dt_Cons<T>( args )
- wr.Write("new {0}(", DtCtorName(dtv.Ctor, dtv.InferredTypeArgs));
- string sep = "";
- for (int i = 0; i < dtv.Arguments.Count; i++) {
- Formal formal = dtv.Ctor.Formals[i];
- if (!formal.IsGhost) {
- wr.Write(sep);
- TrExpr(dtv.Arguments[i]);
- sep = ", ";
- }
- }
- wr.Write(")");
- } else {
- // In the case of a co-recursive call, generate:
- // new Dt__Lazy<T>( new Dt__Lazy<T>.ComputerComputer( LAMBDA )() )
- // where LAMBDA is:
- // () => { var someLocals = eagerlyEvaluatedArguments;
- // return () => { return Dt_Cons<T>( ...args...using someLocals and including function calls to be evaluated lazily... ); };
- // }
- wr.Write("new {0}__Lazy{1}", dtv.DatatypeName, typeParams);
- wr.Write("(new {0}__Lazy{1}.ComputerComputer(() => {{ ", dtv.DatatypeName, typeParams);
-
- // locals
- string args = "";
- string sep = "";
- for (int i = 0; i < dtv.Arguments.Count; i++) {
- Formal formal = dtv.Ctor.Formals[i];
- if (!formal.IsGhost) {
- Expression actual = dtv.Arguments[i].Resolved;
- string arg;
- var fce = actual as FunctionCallExpr;
- if (fce == null || fce.CoCall != FunctionCallExpr.CoCallResolution.Yes) {
- string varName = "_ac" + tmpVarCount;
- tmpVarCount++;
- arg = varName;
-
- wr.Write("var {0} = ", varName);
- TrExpr(actual);
- wr.Write("; ");
- } else {
- var sw = new StringWriter();
- CompileFunctionCallExpr(fce, sw, (exp) => {
- string varName = "_ac" + tmpVarCount;
- tmpVarCount++;
- sw.Write(varName);
-
- wr.Write("var {0} = ", varName);
- TrExpr(exp);
- wr.Write("; ");
-
- });
- arg = sw.ToString();
- }
- args += sep + arg;
- sep = ", ";
- }
- }
-
- wr.Write("return () => { return ");
-
- wr.Write("new {0}({1}", DtCtorName(dtv.Ctor, dtv.InferredTypeArgs), args);
- wr.Write("); }; })())");
- }
- wr.Write(")");
-
- } else if (expr is OldExpr) {
- Contract.Assert(false); throw new cce.UnreachableException(); // 'old' is always a ghost (right?)
-
- } else if (expr is FreshExpr) {
- Contract.Assert(false); throw new cce.UnreachableException(); // 'fresh' is always a ghost
-
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- switch (e.Op) {
- case UnaryExpr.Opcode.Not:
- wr.Write("!");
- TrParenExpr(e.E);
- break;
- case UnaryExpr.Opcode.SetChoose:
- TrParenExpr(e.E);
- wr.Write(".Choose()");
- break;
- case UnaryExpr.Opcode.SeqLength:
- if (cce.NonNull(e.E.Type).IsArrayType) {
- wr.Write("new BigInteger(");
- TrParenExpr(e.E);
- wr.Write(".Length)");
- } else {
- TrParenExpr(e.E);
- wr.Write(".Length");
- }
- break;
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected unary expression
- }
-
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- string opString = null;
- string preOpString = "";
- string callString = null;
-
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.Iff:
- opString = "=="; break;
- case BinaryExpr.ResolvedOpcode.Imp:
- preOpString = "!"; opString = "||"; break;
- case BinaryExpr.ResolvedOpcode.Or:
- opString = "||"; break;
- case BinaryExpr.ResolvedOpcode.And:
- opString = "&&"; break;
-
- case BinaryExpr.ResolvedOpcode.EqCommon: {
- Type t = cce.NonNull(e.E0.Type);
- if (t.IsDatatype || t.IsTypeParameter) {
- callString = "Equals";
- } else if (t.IsRefType) {
- // Dafny's type rules are slightly different C#, so we may need a cast here.
- // For example, Dafny allows x==y if x:array<T> and y:array<int> and T is some
- // type parameter.
- opString = "== (object)";
- } else {
- opString = "==";
- }
- break;
- }
- case BinaryExpr.ResolvedOpcode.NeqCommon: {
- Type t = cce.NonNull(e.E0.Type);
- if (t.IsDatatype || t.IsTypeParameter) {
- preOpString = "!";
- callString = "Equals";
- } else if (t.IsRefType) {
- // Dafny's type rules are slightly different C#, so we may need a cast here.
- // For example, Dafny allows x==y if x:array<T> and y:array<int> and T is some
- // type parameter.
- opString = "!= (object)";
- } else {
- opString = "!=";
- }
- break;
- }
-
- case BinaryExpr.ResolvedOpcode.Lt:
- opString = "<"; break;
- case BinaryExpr.ResolvedOpcode.Le:
- opString = "<="; break;
- case BinaryExpr.ResolvedOpcode.Ge:
- opString = ">="; break;
- case BinaryExpr.ResolvedOpcode.Gt:
- opString = ">"; break;
- case BinaryExpr.ResolvedOpcode.Add:
- opString = "+"; break;
- case BinaryExpr.ResolvedOpcode.Sub:
- opString = "-"; break;
- case BinaryExpr.ResolvedOpcode.Mul:
- opString = "*"; break;
- case BinaryExpr.ResolvedOpcode.Div:
- wr.Write("Dafny.Helpers.EuclideanDivision(");
- TrParenExpr(e.E0);
- wr.Write(", ");
- TrExpr(e.E1);
- wr.Write(")");
- break;
- case BinaryExpr.ResolvedOpcode.Mod:
- wr.Write("Dafny.Helpers.EuclideanModulus(");
- TrParenExpr(e.E0);
- wr.Write(", ");
- TrExpr(e.E1);
- wr.Write(")");
- break;
- case BinaryExpr.ResolvedOpcode.SetEq:
- case BinaryExpr.ResolvedOpcode.MultiSetEq:
- case BinaryExpr.ResolvedOpcode.SeqEq:
- case BinaryExpr.ResolvedOpcode.MapEq:
- callString = "Equals"; break;
- case BinaryExpr.ResolvedOpcode.SetNeq:
- case BinaryExpr.ResolvedOpcode.MultiSetNeq:
- case BinaryExpr.ResolvedOpcode.SeqNeq:
- case BinaryExpr.ResolvedOpcode.MapNeq:
- preOpString = "!"; callString = "Equals"; break;
- case BinaryExpr.ResolvedOpcode.ProperSubset:
- case BinaryExpr.ResolvedOpcode.ProperMultiSubset:
- callString = "IsProperSubsetOf"; break;
- case BinaryExpr.ResolvedOpcode.Subset:
- case BinaryExpr.ResolvedOpcode.MultiSubset:
- callString = "IsSubsetOf"; break;
- case BinaryExpr.ResolvedOpcode.Superset:
- case BinaryExpr.ResolvedOpcode.MultiSuperset:
- callString = "IsSupersetOf"; break;
- case BinaryExpr.ResolvedOpcode.ProperSuperset:
- case BinaryExpr.ResolvedOpcode.ProperMultiSuperset:
- callString = "IsProperSupersetOf"; break;
- case BinaryExpr.ResolvedOpcode.Disjoint:
- case BinaryExpr.ResolvedOpcode.MultiSetDisjoint:
- case BinaryExpr.ResolvedOpcode.MapDisjoint:
- callString = "IsDisjointFrom"; break;
- case BinaryExpr.ResolvedOpcode.InSet:
- case BinaryExpr.ResolvedOpcode.InMultiSet:
- case BinaryExpr.ResolvedOpcode.InMap:
- TrParenExpr(e.E1);
- wr.Write(".Contains(");
- TrExpr(e.E0);
- wr.Write(")");
- break;
- case BinaryExpr.ResolvedOpcode.NotInSet:
- case BinaryExpr.ResolvedOpcode.NotInMultiSet:
- case BinaryExpr.ResolvedOpcode.NotInMap:
- wr.Write("!");
- TrParenExpr(e.E1);
- wr.Write(".Contains(");
- TrExpr(e.E0);
- wr.Write(")");
- break;
- case BinaryExpr.ResolvedOpcode.Union:
- case BinaryExpr.ResolvedOpcode.MultiSetUnion:
- callString = "Union"; break;
- case BinaryExpr.ResolvedOpcode.Intersection:
- case BinaryExpr.ResolvedOpcode.MultiSetIntersection:
- callString = "Intersect"; break;
- case BinaryExpr.ResolvedOpcode.SetDifference:
- case BinaryExpr.ResolvedOpcode.MultiSetDifference:
- callString = "Difference"; break;
-
- case BinaryExpr.ResolvedOpcode.ProperPrefix:
- callString = "IsProperPrefixOf"; break;
- case BinaryExpr.ResolvedOpcode.Prefix:
- callString = "IsPrefixOf"; break;
- case BinaryExpr.ResolvedOpcode.Concat:
- callString = "Concat"; break;
- case BinaryExpr.ResolvedOpcode.InSeq:
- TrParenExpr(e.E1);
- wr.Write(".Contains(");
- TrExpr(e.E0);
- wr.Write(")");
- break;
- case BinaryExpr.ResolvedOpcode.NotInSeq:
- wr.Write("!");
- TrParenExpr(e.E1);
- wr.Write(".Contains(");
- TrExpr(e.E0);
- wr.Write(")");
- break;
-
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected binary expression
- }
- if (opString != null) {
- wr.Write(preOpString);
- TrParenExpr(e.E0);
- wr.Write(" {0} ", opString);
- TrParenExpr(e.E1);
- } else if (callString != null) {
- wr.Write(preOpString);
- TrParenExpr(e.E0);
- wr.Write(".{0}(", callString);
- TrExpr(e.E1);
- wr.Write(")");
- }
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- // The Dafny "let" expression
- // var x := G; E
- // is translated into C# as:
- // ExpressionSequence(x = G, E)
- // preceded by the declaration of x.
- Contract.Assert(e.Vars.Count == e.RHSs.Count); // checked by resolution
- for (int i = 0; i < e.Vars.Count; i++) {
- wr.Write("Dafny.Helpers.ExpressionSequence(@{0} = ", e.Vars[i].CompileName);
- TrExpr(e.RHSs[i]);
- wr.Write(", ");
- }
- TrExpr(e.Body);
- for (int i = 0; i < e.Vars.Count; i++) {
- wr.Write(")");
- }
-
- } else if (expr is QuantifierExpr) {
- var e = (QuantifierExpr)expr;
- Contract.Assert(e.Bounds != null); // for non-ghost quantifiers, the resolver would have insisted on finding bounds
- var n = e.BoundVars.Count;
- Contract.Assert(e.Bounds.Count == n);
- for (int i = 0; i < n; i++) {
- var bound = e.Bounds[i];
- var bv = e.BoundVars[i];
- // emit: Dafny.Helpers.QuantX(boundsInformation, isForall, bv => body)
- if (bound is ComprehensionExpr.BoolBoundedPool) {
- wr.Write("Dafny.Helpers.QuantBool(");
- } else if (bound is ComprehensionExpr.IntBoundedPool) {
- var b = (ComprehensionExpr.IntBoundedPool)bound;
- wr.Write("Dafny.Helpers.QuantInt(");
- TrExpr(b.LowerBound);
- wr.Write(", ");
- TrExpr(b.UpperBound);
- wr.Write(", ");
- } else if (bound is ComprehensionExpr.SetBoundedPool) {
- var b = (ComprehensionExpr.SetBoundedPool)bound;
- wr.Write("Dafny.Helpers.QuantSet(");
- TrExpr(b.Set);
- wr.Write(", ");
- } else if (bound is ComprehensionExpr.MapBoundedPool) {
- var b = (ComprehensionExpr.MapBoundedPool)bound;
- wr.Write("Dafny.Helpers.QuantMap(");
- TrExpr(b.Map);
- wr.Write(", ");
- } else if (bound is ComprehensionExpr.SeqBoundedPool) {
- var b = (ComprehensionExpr.SeqBoundedPool)bound;
- wr.Write("Dafny.Helpers.QuantSeq(");
- TrExpr(b.Seq);
- wr.Write(", ");
- } else if (bound is ComprehensionExpr.DatatypeBoundedPool) {
- var b = (ComprehensionExpr.DatatypeBoundedPool)bound;
- wr.Write("Dafny.Helpers.QuantDatatype(");
-
- wr.Write("{0}.AllSingletonConstructors, ", DtName(b.Decl));
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
- }
- wr.Write("{0}, ", expr is ForallExpr ? "true" : "false");
- wr.Write("@{0} => ", bv.CompileName);
- }
- TrExpr(e.LogicalBody());
- for (int i = 0; i < n; i++) {
- wr.Write(")");
- }
-
- } else if (expr is SetComprehension) {
- var e = (SetComprehension)expr;
- // For "set i,j,k,l | R(i,j,k,l) :: Term(i,j,k,l)" where the term has type "G", emit something like:
- // ((ComprehensionDelegate<G>)delegate() {
- // var _coll = new List<G>();
- // foreach (L l in sq.Elements) {
- // foreach (K k in st.Elements) {
- // for (BigInteger j = Lo; j < Hi; j++) {
- // for (bool i in Helper.AllBooleans) {
- // if (R(i,j,k,l)) {
- // _coll.Add(Term(i,j,k,l));
- // }
- // }
- // }
- // }
- // }
- // return Dafny.Set<G>.FromCollection(_coll);
- // })()
- Contract.Assert(e.Bounds != null); // the resolver would have insisted on finding bounds
- var typeName = TypeName(((SetType)e.Type).Arg);
- wr.Write("((Dafny.Helpers.ComprehensionDelegate<{0}>)delegate() {{ ", typeName);
- wr.Write("var _coll = new System.Collections.Generic.List<{0}>(); ", typeName);
- var n = e.BoundVars.Count;
- Contract.Assert(e.Bounds.Count == n);
- for (int i = 0; i < n; i++) {
- var bound = e.Bounds[i];
- var bv = e.BoundVars[i];
- if (bound is ComprehensionExpr.BoolBoundedPool) {
- wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
- } else if (bound is ComprehensionExpr.IntBoundedPool) {
- var b = (ComprehensionExpr.IntBoundedPool)bound;
- wr.Write("for (var @{0} = ", bv.CompileName);
- TrExpr(b.LowerBound);
- wr.Write("; @{0} < ", bv.CompileName);
- TrExpr(b.UpperBound);
- wr.Write("; @{0}++) {{ ", bv.CompileName);
- } else if (bound is ComprehensionExpr.SetBoundedPool) {
- var b = (ComprehensionExpr.SetBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Set);
- wr.Write(").Elements) { ");
- } else if (bound is ComprehensionExpr.MapBoundedPool) {
- var b = (ComprehensionExpr.MapBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Map);
- wr.Write(").Domain) { ");
- } else if (bound is ComprehensionExpr.SeqBoundedPool) {
- var b = (ComprehensionExpr.SeqBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Seq);
- wr.Write(").Elements) { ");
- } else if (bound is ComprehensionExpr.DatatypeBoundedPool) {
- var b = (ComprehensionExpr.DatatypeBoundedPool)bound;
- wr.Write("foreach (var @{0} in {1}.AllSingletonConstructors) {{", bv.CompileName, TypeName(bv.Type));
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
- }
- }
- wr.Write("if (");
- TrExpr(e.Range);
- wr.Write(") { _coll.Add(");
- TrExpr(e.Term);
- wr.Write("); }");
- for (int i = 0; i < n; i++) {
- wr.Write("}");
- }
- wr.Write("return Dafny.Set<{0}>.FromCollection(_coll); ", typeName);
- wr.Write("})()");
-
- } else if (expr is MapComprehension) {
- var e = (MapComprehension)expr;
- // For "map i | R(i) :: Term(i)" where the term has type "V" and i has type "U", emit something like:
- // ((MapComprehensionDelegate<U, V>)delegate() {
- // var _coll = new List<Pair<U,V>>();
- // foreach (L l in sq.Elements) {
- // foreach (K k in st.Elements) {
- // for (BigInteger j = Lo; j < Hi; j++) {
- // for (bool i in Helper.AllBooleans) {
- // if (R(i,j,k,l)) {
- // _coll.Add(new Pair(i, Term(i));
- // }
- // }
- // }
- // }
- // }
- // return Dafny.Map<U, V>.FromElements(_coll);
- // })()
- Contract.Assert(e.Bounds != null); // the resolver would have insisted on finding bounds
- var domtypeName = TypeName(((MapType)e.Type).Domain);
- var rantypeName = TypeName(((MapType)e.Type).Range);
- wr.Write("((Dafny.Helpers.MapComprehensionDelegate<{0},{1}>)delegate() {{ ", domtypeName, rantypeName);
- wr.Write("var _coll = new System.Collections.Generic.List<Dafny.Pair<{0},{1}>>(); ", domtypeName, rantypeName);
- var n = e.BoundVars.Count;
- Contract.Assert(e.Bounds.Count == n && n == 1);
- var bound = e.Bounds[0];
- var bv = e.BoundVars[0];
- if (bound is ComprehensionExpr.BoolBoundedPool) {
- wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
- } else if (bound is ComprehensionExpr.IntBoundedPool) {
- var b = (ComprehensionExpr.IntBoundedPool)bound;
- wr.Write("for (var @{0} = ", bv.CompileName);
- TrExpr(b.LowerBound);
- wr.Write("; @{0} < ", bv.CompileName);
- TrExpr(b.UpperBound);
- wr.Write("; @{0}++) {{ ", bv.CompileName);
- } else if (bound is ComprehensionExpr.SetBoundedPool) {
- var b = (ComprehensionExpr.SetBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Set);
- wr.Write(").Elements) { ");
- } else if (bound is ComprehensionExpr.MapBoundedPool) {
- var b = (ComprehensionExpr.MapBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Map);
- wr.Write(").Domain) { ");
- } else if (bound is ComprehensionExpr.SeqBoundedPool) {
- var b = (ComprehensionExpr.SeqBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.CompileName);
- TrExpr(b.Seq);
- wr.Write(").Elements) { ");
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
- }
- wr.Write("if (");
- TrExpr(e.Range);
- wr.Write(") { ");
- wr.Write("_coll.Add(new Dafny.Pair<{0},{1}>(@{2},", domtypeName, rantypeName, bv.CompileName);
- TrExpr(e.Term);
- wr.Write(")); }");
- wr.Write("}");
- wr.Write("return Dafny.Map<{0},{1}>.FromCollection(_coll); ", domtypeName, rantypeName);
- wr.Write("})()");
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- TrExpr(e.Body);
-
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- wr.Write("(");
- TrExpr(e.Test);
- wr.Write(") ? (");
- TrExpr(e.Thn);
- wr.Write(") : (");
- TrExpr(e.Els);
- wr.Write(")");
-
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- TrExpr(e.ResolvedExpression);
-
- } else if (expr is NamedExpr) {
- TrExpr(((NamedExpr)expr).Body);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
-
- delegate void FCE_Arg_Translator(Expression e);
-
- void CompileFunctionCallExpr(FunctionCallExpr e, TextWriter twr, FCE_Arg_Translator tr) {
- Function f = cce.NonNull(e.Function);
- if (f.IsStatic) {
- twr.Write(TypeName(cce.NonNull(e.Receiver.Type)));
- } else {
- twr.Write("(");
- tr(e.Receiver);
- twr.Write(")");
- }
- twr.Write(".@{0}", f.CompileName);
- twr.Write("(");
- string sep = "";
- for (int i = 0; i < e.Args.Count; i++) {
- if (!e.Function.Formals[i].IsGhost) {
- twr.Write(sep);
- tr(e.Args[i]);
- sep = ", ";
- }
- }
- twr.Write(")");
- }
- }
-}
diff --git a/Source/Dafny/Dafny.atg b/Source/Dafny/Dafny.atg
deleted file mode 100644
index 4c425497..00000000
--- a/Source/Dafny/Dafny.atg
+++ /dev/null
@@ -1,1990 +0,0 @@
-/*-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------*/
-/*---------------------------------------------------------------------------
-// Dafny
-// Rustan Leino, first created 25 January 2008
-//--------------------------------------------------------------------------*/
-using System.Collections.Generic;
-using System.Numerics;
-using Microsoft.Boogie;
-using System.IO;
-using System.Text;
-COMPILER Dafny
-/*--------------------------------------------------------------------------*/
-readonly Expression/*!*/ dummyExpr;
-readonly AssignmentRhs/*!*/ dummyRhs;
-readonly FrameExpression/*!*/ dummyFrameExpr;
-readonly Statement/*!*/ dummyStmt;
-readonly Attributes.Argument/*!*/ dummyAttrArg;
-readonly ModuleDecl theModule;
-readonly BuiltIns theBuiltIns;
-int anonymousIds = 0;
-
-struct MemberModifiers {
- public bool IsGhost;
- public bool IsStatic;
-}
-// helper routine for parsing call statements
-///<summary>
-/// Parses top-level things (modules, classes, datatypes, class members) from "filename"
-/// and appends them in appropriate form to "module".
-/// Returns the number of parsing errors encountered.
-/// Note: first initialize the Scanner.
-///</summary>
-public static int Parse (string/*!*/ filename, ModuleDecl module, BuiltIns builtIns) /* throws System.IO.IOException */ {
- Contract.Requires(filename != null);
- Contract.Requires(module != null);
- string s;
- if (filename == "stdin.dfy") {
- s = Microsoft.Boogie.ParserHelper.Fill(System.Console.In, new List<string>());
- return Parse(s, filename, module, builtIns);
- } else {
- using (System.IO.StreamReader reader = new System.IO.StreamReader(filename)) {
- s = Microsoft.Boogie.ParserHelper.Fill(reader, new List<string>());
- return Parse(s, filename, module, builtIns);
- }
- }
-}
-///<summary>
-/// Parses top-level things (modules, classes, datatypes, class members)
-/// and appends them in appropriate form to "module".
-/// Returns the number of parsing errors encountered.
-/// Note: first initialize the Scanner.
-///</summary>
-public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module, BuiltIns builtIns) {
- Contract.Requires(s != null);
- Contract.Requires(filename != null);
- Contract.Requires(module != null);
- Errors errors = new Errors();
- return Parse(s, filename, module, builtIns, errors);
-}
-///<summary>
-/// Parses top-level things (modules, classes, datatypes, class members)
-/// and appends them in appropriate form to "module".
-/// Returns the number of parsing errors encountered.
-/// Note: first initialize the Scanner with the given Errors sink.
-///</summary>
-public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module, BuiltIns builtIns,
- Errors/*!*/ errors) {
- Contract.Requires(s != null);
- Contract.Requires(filename != null);
- Contract.Requires(module != null);
- Contract.Requires(errors != null);
- byte[]/*!*/ buffer = cce.NonNull( UTF8Encoding.Default.GetBytes(s));
- MemoryStream ms = new MemoryStream(buffer,false);
- Scanner scanner = new Scanner(ms, errors, filename);
- Parser parser = new Parser(scanner, errors, module, builtIns);
- parser.Parse();
- return parser.errors.count;
-}
-public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors, ModuleDecl module, BuiltIns builtIns)
- : this(scanner, errors) // the real work
-{
- // initialize readonly fields
- dummyExpr = new LiteralExpr(Token.NoToken);
- dummyRhs = new ExprRhs(dummyExpr, null);
- dummyFrameExpr = new FrameExpression(dummyExpr.tok, dummyExpr, null);
- dummyStmt = new ReturnStmt(Token.NoToken, null);
- dummyAttrArg = new Attributes.Argument(Token.NoToken, "dummyAttrArg");
- theModule = module;
- theBuiltIns = builtIns;
-}
-
-bool IsAttribute() {
- Token x = scanner.Peek();
- return la.kind == _lbrace && x.kind == _colon;
-}
-/*--------------------------------------------------------------------------*/
-CHARACTERS
- letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
- digit = "0123456789".
- posDigit = "123456789".
- special = "'_?\\".
- glyph = "`~!@#$%^&*()-_=+[{]}|;:',<.>/?\\".
- cr = '\r'.
- lf = '\n'.
- tab = '\t'.
- space = ' '.
- quote = '"'.
- nondigit = letter + special.
- idchar = nondigit + digit.
- nonquote = letter + digit + space + glyph.
- /* exclude the characters in 'array' */
- nondigitMinusA = nondigit - 'a'.
- idcharMinusA = idchar - 'a'.
- idcharMinusR = idchar - 'r'.
- idcharMinusY = idchar - 'y'.
- idcharMinusPosDigit = idchar - posDigit.
-/*------------------------------------------------------------------------*/
-TOKENS
- ident = nondigitMinusA {idchar} /* if char 0 is not an 'a', then anything else is fine */
- | 'a' [ idcharMinusR {idchar} ] /* if char 0 is an 'a', then either there is no char 1 or char 1 is not an 'r' */
- | 'a' 'r' [ idcharMinusR {idchar} ] /* etc. */
- | 'a' 'r' 'r' [ idcharMinusA {idchar} ]
- | 'a' 'r' 'r' 'a' [ idcharMinusY {idchar} ]
- | 'a' 'r' 'r' 'a' 'y' idcharMinusPosDigit {idchar}
- | 'a' 'r' 'r' 'a' 'y' posDigit {idchar} nondigit {idchar}.
- digits = digit {digit}.
- arrayToken = 'a' 'r' 'r' 'a' 'y' [posDigit {digit}].
- string = quote {nonquote} quote.
- colon = ':'.
- lbrace = '{'.
- rbrace = '}'.
-COMMENTS FROM "/*" TO "*/" NESTED
-COMMENTS FROM "//" TO lf
-IGNORE cr + lf + tab
-/*------------------------------------------------------------------------*/
-PRODUCTIONS
-Dafny
-= (. ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
- List<MemberDecl/*!*/> membersDefaultClass = new List<MemberDecl/*!*/>();
- ModuleDecl submodule;
- // to support multiple files, create a default module only if theModule is null
- DefaultModuleDecl defaultModule = (DefaultModuleDecl)((LiteralModuleDecl)theModule).ModuleDef;
- // theModule should be a DefaultModuleDecl (actually, the singular DefaultModuleDecl)
- Contract.Assert(defaultModule != null);
- bool isGhost;
- .)
- { (. isGhost = false; .)
- [ "ghost" (. isGhost = true; .) ]
-
- ( SubModuleDecl<defaultModule, isGhost, out submodule>
- (. defaultModule.TopLevelDecls.Add(submodule); .)
- | (. if (isGhost) { SemErr(t, "a class is not allowed to be declared as 'ghost'"); } .)
- ClassDecl<defaultModule, out c> (. defaultModule.TopLevelDecls.Add(c); .)
- | (. if (isGhost) { SemErr(t, "a datatype/codatatype is not allowed to be declared as 'ghost'"); } .)
- DatatypeDecl<defaultModule, out dt> (. defaultModule.TopLevelDecls.Add(dt); .)
- | (. if (isGhost) { SemErr(t, "a type is not allowed to be declared as 'ghost'"); } .)
- ArbitraryTypeDecl<defaultModule, out at> (. defaultModule.TopLevelDecls.Add(at); .)
- | (. if (isGhost) { SemErr(t, "an iterator is not allowed to be declared as 'ghost'"); } .)
- IteratorDecl<defaultModule, out iter> (. defaultModule.TopLevelDecls.Add(iter); .)
- | ClassMemberDecl<membersDefaultClass, isGhost, false>
- )
- }
- (. // find the default class in the default module, then append membersDefaultClass to its member list
- DefaultClassDecl defaultClass = null;
- foreach (TopLevelDecl topleveldecl in defaultModule.TopLevelDecls) {
- defaultClass = topleveldecl as DefaultClassDecl;
- if (defaultClass != null) {
- defaultClass.Members.AddRange(membersDefaultClass);
- break;
- }
- }
- if (defaultClass == null) { // create the default class here, because it wasn't found
- defaultClass = new DefaultClassDecl(defaultModule, membersDefaultClass);
- defaultModule.TopLevelDecls.Add(defaultClass);
- } .)
- EOF
- .
-SubModuleDecl<ModuleDefinition parent, bool isOverallModuleGhost, out ModuleDecl submodule>
-= (. ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
- Attributes attrs = null; IToken/*!*/ id;
- List<MemberDecl/*!*/> namedModuleDefaultClassMembers = new List<MemberDecl>();;
- List<IToken> idRefined = null, idPath = null, idAssignment = null;
- bool isGhost = false;
- ModuleDefinition module;
- ModuleDecl sm;
- submodule = null; // appease compiler
- bool opened = false;
- .)
- ( "module"
- { Attribute<ref attrs> }
- NoUSIdent<out id>
-
- [ "refines" QualifiedName<out idRefined> ] (. module = new ModuleDefinition(id, id.val, isOverallModuleGhost, false, idRefined == null ? null : idRefined, attrs, false); .)
- "{" (. module.BodyStartTok = t; .)
- { (. isGhost = false; .)
- [ "ghost" (. isGhost = true; .) ]
- ( SubModuleDecl<module, isGhost, out sm> (. module.TopLevelDecls.Add(sm); .)
- | (. if (isGhost) { SemErr(t, "a class is not allowed to be declared as 'ghost'"); } .)
- ClassDecl<module, out c> (. module.TopLevelDecls.Add(c); .)
- | (. if (isGhost) { SemErr(t, "a datatype/codatatype is not allowed to be declared as 'ghost'"); } .)
- DatatypeDecl<module, out dt> (. module.TopLevelDecls.Add(dt); .)
- | (. if (isGhost) { SemErr(t, "a type is not allowed to be declared as 'ghost'"); } .)
- ArbitraryTypeDecl<module, out at> (. module.TopLevelDecls.Add(at); .)
- | (. if (isGhost) { SemErr(t, "an iterator is not allowed to be declared as 'ghost'"); } .)
- IteratorDecl<module, out iter> (. module.TopLevelDecls.Add(iter); .)
- | ClassMemberDecl<namedModuleDefaultClassMembers, isGhost, false>
- )
- }
- "}" (. module.BodyEndTok = t;
- module.TopLevelDecls.Add(new DefaultClassDecl(module, namedModuleDefaultClassMembers));
- submodule = new LiteralModuleDecl(module, parent); .)
- |
- "import" ["opened" (.opened = true;.)]
- ( NoUSIdent<out id> ( "=" QualifiedName<out idPath> ";"
- (. submodule = new AliasModuleDecl(idPath, id, parent, opened); .)
- | ";"
- (. idPath = new List<IToken>(); idPath.Add(id); submodule = new AliasModuleDecl(idPath, id, parent, opened); .)
- | "as" QualifiedName<out idPath> ["default" QualifiedName<out idAssignment> ] ";"
- (.submodule = new AbstractModuleDecl(idPath, id, parent, idAssignment, opened); .)
- )
- )
- )
-.
-
-QualifiedName<.out List<IToken> ids.>
-= (. IToken id; ids = new List<IToken>(); .)
- Ident<out id> (. ids.Add(id); .)
- { "." Ident<out id> (. ids.Add(id); .)
- }
- .
-
-ClassDecl<ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c>
-= (. Contract.Requires(module != null);
- Contract.Ensures(Contract.ValueAtReturn(out c) != null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
- List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
- IToken bodyStart;
- .)
- SYNC
- "class"
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- [ GenericParameters<typeArgs> ]
- "{" (. bodyStart = t; .)
- { ClassMemberDecl<members, false, true>
- }
- "}"
- (. c = new ClassDecl(id, id.val, module, typeArgs, members, attrs);
- c.BodyStartTok = bodyStart;
- c.BodyEndTok = t;
- .)
- .
-ClassMemberDecl<.List<MemberDecl/*!*/>/*!*/ mm, bool isAlreadyGhost, bool allowConstructors.>
-= (. Contract.Requires(cce.NonNullElements(mm));
- Method/*!*/ m;
- Function/*!*/ f;
- MemberModifiers mmod = new MemberModifiers();
- mmod.IsGhost = isAlreadyGhost;
- .)
- { "ghost" (. mmod.IsGhost = true; .)
- | "static" (. mmod.IsStatic = true; .)
- }
- ( FieldDecl<mmod, mm>
- | FunctionDecl<mmod, out f> (. mm.Add(f); .)
- | MethodDecl<mmod, allowConstructors, out m> (. mm.Add(m); .)
- )
- .
-DatatypeDecl<ModuleDefinition/*!*/ module, out DatatypeDecl/*!*/ dt>
-= (. Contract.Requires(module != null);
- Contract.Ensures(Contract.ValueAtReturn(out dt)!=null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
- List<DatatypeCtor/*!*/> ctors = new List<DatatypeCtor/*!*/>();
- IToken bodyStart = Token.NoToken; // dummy assignment
- bool co = false;
- .)
- SYNC
- ( "datatype"
- | "codatatype" (. co = true; .)
- )
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- [ GenericParameters<typeArgs> ]
- "=" (. bodyStart = t; .)
- DatatypeMemberDecl<ctors>
- { "|" DatatypeMemberDecl<ctors> }
- SYNC ";"
- (. if (co) {
- dt = new CoDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
- } else {
- dt = new IndDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
- }
- dt.BodyStartTok = bodyStart;
- dt.BodyEndTok = t;
- .)
- .
-DatatypeMemberDecl<.List<DatatypeCtor/*!*/>/*!*/ ctors.>
-= (. Contract.Requires(cce.NonNullElements(ctors));
- Attributes attrs = null;
- IToken/*!*/ id;
- List<Formal/*!*/> formals = new List<Formal/*!*/>();
- .)
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- [ FormalsOptionalIds<formals> ]
- (. ctors.Add(new DatatypeCtor(id, id.val, formals, attrs)); .)
- .
-FieldDecl<.MemberModifiers mmod, List<MemberDecl/*!*/>/*!*/ mm.>
-= (. Contract.Requires(cce.NonNullElements(mm));
- Attributes attrs = null;
- IToken/*!*/ id; Type/*!*/ ty;
- .)
- SYNC
- "var"
- (. if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
- .)
- { Attribute<ref attrs> }
- IdentType<out id, out ty, false> (. mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs)); .)
- { "," IdentType<out id, out ty, false> (. mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs)); .)
- }
- SYNC ";"
- .
-ArbitraryTypeDecl<ModuleDefinition/*!*/ module, out ArbitraryTypeDecl at>
-= (. IToken/*!*/ id;
- Attributes attrs = null;
- var eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
- .)
- "type"
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- [ "(" "==" ")" (. eqSupport = TypeParameter.EqualitySupportValue.Required; .)
- ] (. at = new ArbitraryTypeDecl(id, id.val, module, eqSupport, attrs); .)
- SYNC ";"
- .
-GIdentType<bool allowGhostKeyword, out IToken/*!*/ id, out Type/*!*/ ty, out bool isGhost>
-/* isGhost always returns as false if allowGhostKeyword is false */
-= (. Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
- isGhost = false; .)
- [ "ghost" (. if (allowGhostKeyword) { isGhost = true; } else { SemErr(t, "formal cannot be declared 'ghost' in this context"); } .)
- ]
- IdentType<out id, out ty, true>
- .
-IdentType<out IToken/*!*/ id, out Type/*!*/ ty, bool allowWildcardId>
-= (.Contract.Ensures(Contract.ValueAtReturn(out id) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);.)
- WildIdent<out id, allowWildcardId>
- ":"
- Type<out ty>
- .
-LocalIdentTypeOptional<out VarDecl/*!*/ var, bool isGhost>
-= (. IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
- .)
- WildIdent<out id, true>
- [ ":" Type<out ty> (. optType = ty; .)
- ]
- (. var = new VarDecl(id, id.val, optType == null ? new InferredTypeProxy() : optType, isGhost); .)
- .
-IdentTypeOptional<out BoundVar/*!*/ var>
-= (. Contract.Ensures(Contract.ValueAtReturn(out var)!=null); IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
- .)
- WildIdent<out id, true>
- [ ":" Type<out ty> (. optType = ty; .)
- ]
- (. var = new BoundVar(id, id.val, optType == null ? new InferredTypeProxy() : optType); .)
- .
-TypeIdentOptional<out IToken/*!*/ id, out string/*!*/ identName, out Type/*!*/ ty, out bool isGhost>
-= (.Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out identName)!=null);
- string name = null; isGhost = false; .)
- [ "ghost" (. isGhost = true; .)
- ]
- TypeAndToken<out id, out ty>
- [ ":"
- (. /* try to convert ty to an identifier */
- UserDefinedType udt = ty as UserDefinedType;
- if (udt != null && udt.TypeArgs.Count == 0) {
- name = udt.Name;
- } else {
- SemErr(id, "invalid formal-parameter name in datatype constructor");
- }
- .)
- Type<out ty>
- ]
- (. if (name != null) {
- identName = name;
- } else {
- identName = "#" + anonymousIds++;
- }
- .)
- .
-/*------------------------------------------------------------------------*/
-IteratorDecl<ModuleDefinition module, out IteratorDecl/*!*/ iter>
-= (. Contract.Ensures(Contract.ValueAtReturn(out iter) != null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/>/*!*/ typeArgs = new List<TypeParameter/*!*/>();
- IToken openParen;
- List<Formal/*!*/> ins = new List<Formal/*!*/>();
- List<Formal/*!*/> outs = new List<Formal/*!*/>();
- List<FrameExpression/*!*/> reads = new List<FrameExpression/*!*/>();
- List<FrameExpression/*!*/> mod = new List<FrameExpression/*!*/>();
- List<Expression/*!*/> decreases = new List<Expression>();
- List<MaybeFreeExpression/*!*/> req = new List<MaybeFreeExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> ens = new List<MaybeFreeExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> yieldReq = new List<MaybeFreeExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> yieldEns = new List<MaybeFreeExpression/*!*/>();
- List<Expression/*!*/> dec = new List<Expression/*!*/>();
- Attributes readsAttrs = null;
- Attributes modAttrs = null;
- Attributes decrAttrs = null;
- BlockStmt body = null;
- bool signatureOmitted = false;
- IToken bodyStart = Token.NoToken;
- IToken bodyEnd = Token.NoToken;
- .)
- SYNC
- "iterator"
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- (
- [ GenericParameters<typeArgs> ]
- Formals<true, true, ins, out openParen>
- [ "yields"
- Formals<false, true, outs, out openParen>
- ]
- | "..." (. signatureOmitted = true; openParen = Token.NoToken; .)
- )
- { IteratorSpec<reads, mod, decreases, req, ens, yieldReq, yieldEns, ref readsAttrs, ref modAttrs, ref decrAttrs> }
- [ BlockStmt<out body, out bodyStart, out bodyEnd>
- ]
- (. iter = new IteratorDecl(id, id.val, module, typeArgs, ins, outs,
- new Specification<FrameExpression>(reads, readsAttrs),
- new Specification<FrameExpression>(mod, modAttrs),
- new Specification<Expression>(decreases, decrAttrs),
- req, ens, yieldReq, yieldEns,
- body, attrs, signatureOmitted);
- iter.BodyStartTok = bodyStart;
- iter.BodyEndTok = bodyEnd;
- .)
- .
-/*------------------------------------------------------------------------*/
-GenericParameters<.List<TypeParameter/*!*/>/*!*/ typeArgs.>
-= (. Contract.Requires(cce.NonNullElements(typeArgs));
- IToken/*!*/ id;
- TypeParameter.EqualitySupportValue eqSupport;
- .)
- "<"
- NoUSIdent<out id> (. eqSupport = TypeParameter.EqualitySupportValue.Unspecified; .)
- [ "(" "==" ")" (. eqSupport = TypeParameter.EqualitySupportValue.Required; .)
- ] (. typeArgs.Add(new TypeParameter(id, id.val, eqSupport)); .)
- { "," NoUSIdent<out id> (. eqSupport = TypeParameter.EqualitySupportValue.Unspecified; .)
- [ "(" "==" ")" (. eqSupport = TypeParameter.EqualitySupportValue.Required; .)
- ] (. typeArgs.Add(new TypeParameter(id, id.val, eqSupport)); .)
- }
- ">"
- .
-/*------------------------------------------------------------------------*/
-MethodDecl<MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m>
-= (. Contract.Ensures(Contract.ValueAtReturn(out m) !=null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/>/*!*/ typeArgs = new List<TypeParameter/*!*/>();
- IToken openParen;
- List<Formal/*!*/> ins = new List<Formal/*!*/>();
- List<Formal/*!*/> outs = new List<Formal/*!*/>();
- List<MaybeFreeExpression/*!*/> req = new List<MaybeFreeExpression/*!*/>();
- List<FrameExpression/*!*/> mod = new List<FrameExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> ens = new List<MaybeFreeExpression/*!*/>();
- List<Expression/*!*/> dec = new List<Expression/*!*/>();
- Attributes decAttrs = null;
- Attributes modAttrs = null;
- BlockStmt body = null;
- bool isConstructor = false;
- bool signatureOmitted = false;
- IToken bodyStart = Token.NoToken;
- IToken bodyEnd = Token.NoToken;
- .)
- SYNC
- ( "method"
- | "constructor" (. if (allowConstructor) {
- isConstructor = true;
- } else {
- SemErr(t, "constructors are only allowed in classes");
- }
- .)
- )
- (. if (isConstructor) {
- if (mmod.IsGhost) {
- SemErr(t, "constructors cannot be declared 'ghost'");
- }
- if (mmod.IsStatic) {
- SemErr(t, "constructors cannot be declared 'static'");
- }
- }
- .)
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- (
- [ GenericParameters<typeArgs> ]
- Formals<true, !mmod.IsGhost, ins, out openParen>
- [ "returns" (. if (isConstructor) { SemErr(t, "constructors cannot have out-parameters"); } .)
- Formals<false, !mmod.IsGhost, outs, out openParen>
- ]
- | "..." (. signatureOmitted = true; openParen = Token.NoToken; .)
- )
- { MethodSpec<req, mod, ens, dec, ref decAttrs, ref modAttrs> }
- [ BlockStmt<out body, out bodyStart, out bodyEnd>
- ]
- (. if (isConstructor) {
- m = new Constructor(id, id.val, typeArgs, ins,
- req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureOmitted);
- } else {
- m = new Method(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs,
- req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureOmitted);
- }
- m.BodyStartTok = bodyStart;
- m.BodyEndTok = bodyEnd;
- .)
- .
-MethodSpec<.List<MaybeFreeExpression/*!*/>/*!*/ req, List<FrameExpression/*!*/>/*!*/ mod, List<MaybeFreeExpression/*!*/>/*!*/ ens,
- List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes modAttrs.>
-= (. Contract.Requires(cce.NonNullElements(req)); Contract.Requires(cce.NonNullElements(mod)); Contract.Requires(cce.NonNullElements(ens)); Contract.Requires(cce.NonNullElements(decreases));
- Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; Attributes ensAttrs = null;
- .)
- SYNC
- ( "modifies" { IF(IsAttribute()) Attribute<ref modAttrs> }
- [ FrameExpression<out fe> (. mod.Add(fe); .)
- { "," FrameExpression<out fe> (. mod.Add(fe); .)
- }
- ] SYNC ";"
- | [ "free" (. isFree = true; .)
- ]
- ( "requires" Expression<out e> SYNC ";" (. req.Add(new MaybeFreeExpression(e, isFree)); .)
- | "ensures" { IF(IsAttribute()) Attribute<ref ensAttrs> } Expression<out e> SYNC ";" (. ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs)); .)
- )
- | "decreases" { IF(IsAttribute()) Attribute<ref decAttrs> } DecreasesList<decreases, true> SYNC ";"
- )
- .
-IteratorSpec<.List<FrameExpression/*!*/>/*!*/ reads, List<FrameExpression/*!*/>/*!*/ mod, List<Expression/*!*/> decreases,
- List<MaybeFreeExpression/*!*/>/*!*/ req, List<MaybeFreeExpression/*!*/>/*!*/ ens,
- List<MaybeFreeExpression/*!*/>/*!*/ yieldReq, List<MaybeFreeExpression/*!*/>/*!*/ yieldEns,
- ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs.>
-= (. Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; bool isYield = false; Attributes ensAttrs = null;
- .)
- SYNC
- ( "reads" { IF(IsAttribute()) Attribute<ref readsAttrs> }
- [ FrameExpression<out fe> (. reads.Add(fe); .)
- { "," FrameExpression<out fe> (. reads.Add(fe); .)
- }
- ] SYNC ";"
- | "modifies" { IF(IsAttribute()) Attribute<ref modAttrs> }
- [ FrameExpression<out fe> (. mod.Add(fe); .)
- { "," FrameExpression<out fe> (. mod.Add(fe); .)
- }
- ] SYNC ";"
- | [ "free" (. isFree = true; .)
- ]
- [ "yield" (. isYield = true; .)
- ]
- ( "requires" Expression<out e> SYNC ";" (. if (isYield) {
- yieldReq.Add(new MaybeFreeExpression(e, isFree));
- } else {
- req.Add(new MaybeFreeExpression(e, isFree));
- }
- .)
- | "ensures" { IF(IsAttribute()) Attribute<ref ensAttrs> }
- Expression<out e> SYNC ";" (. if (isYield) {
- yieldEns.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
- } else {
- ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
- }
- .)
- )
- | "decreases" { IF(IsAttribute()) Attribute<ref decrAttrs> } DecreasesList<decreases, false> SYNC ";"
- )
- .
-Formals<.bool incoming, bool allowGhostKeyword, List<Formal/*!*/>/*!*/ formals, out IToken openParen.>
-= (. Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; bool isGhost; .)
- "(" (. openParen = t; .)
- [
- GIdentType<allowGhostKeyword, out id, out ty, out isGhost> (. formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); .)
- { "," GIdentType<allowGhostKeyword, out id, out ty, out isGhost> (. formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); .)
- }
- ]
- ")"
- .
-FormalsOptionalIds<.List<Formal/*!*/>/*!*/ formals.>
-= (. Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; string/*!*/ name; bool isGhost; .)
- "("
- [
- TypeIdentOptional<out id, out name, out ty, out isGhost> (. formals.Add(new Formal(id, name, ty, true, isGhost)); .)
- { "," TypeIdentOptional<out id, out name, out ty, out isGhost> (. formals.Add(new Formal(id, name, ty, true, isGhost)); .)
- }
- ]
- ")"
- .
-/*------------------------------------------------------------------------*/
-Type<out Type/*!*/ ty>
-= (. Contract.Ensures(Contract.ValueAtReturn(out ty) != null); IToken/*!*/ tok; .)
- TypeAndToken<out tok, out ty>
- .
-TypeAndToken<out IToken/*!*/ tok, out Type/*!*/ ty>
-= (. Contract.Ensures(Contract.ValueAtReturn(out tok)!=null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null); tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
- .)
- ( "bool" (. tok = t; .)
- | "nat" (. tok = t; ty = new NatType(); .)
- | "int" (. tok = t; ty = new IntType(); .)
- | "set" (. tok = t; gt = new List<Type/*!*/>(); .)
- GenericInstantiation<gt> (. if (gt.Count != 1) {
- SemErr("set type expects exactly one type argument");
- }
- ty = new SetType(gt[0]);
- .)
- | "multiset" (. tok = t; gt = new List<Type/*!*/>(); .)
- GenericInstantiation<gt> (. if (gt.Count != 1) {
- SemErr("multiset type expects exactly one type argument");
- }
- ty = new MultiSetType(gt[0]);
- .)
- | "seq" (. tok = t; gt = new List<Type/*!*/>(); .)
- GenericInstantiation<gt> (. if (gt.Count != 1) {
- SemErr("seq type expects exactly one type argument");
- }
- ty = new SeqType(gt[0]);
- .)
- | "map" (. tok = t; gt = new List<Type/*!*/>(); .)
- GenericInstantiation<gt> (. if (gt.Count != 2) {
- SemErr("map type expects exactly two type arguments");
- }
- else { ty = new MapType(gt[0], gt[1]); }
- .)
- | ReferenceType<out tok, out ty>
- )
- .
-ReferenceType<out IToken/*!*/ tok, out Type/*!*/ ty>
-= (. Contract.Ensures(Contract.ValueAtReturn(out tok) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
- tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
- List<IToken> path;
- .)
- ( "object" (. tok = t; ty = new ObjectType(); .)
- | arrayToken (. tok = t; gt = new List<Type/*!*/>(); .)
- GenericInstantiation<gt> (. if (gt.Count != 1) {
- SemErr("array type expects exactly one type argument");
- }
- int dims = 1;
- if (tok.val.Length != 5) {
- dims = int.Parse(tok.val.Substring(5));
- }
- ty = theBuiltIns.ArrayType(tok, dims, gt[0], true);
- .)
- | Ident<out tok> (. gt = new List<Type/*!*/>();
- path = new List<IToken>(); .)
- { (. path.Add(tok); .)
- "." Ident<out tok>
- }
- [ GenericInstantiation<gt> ] (. ty = new UserDefinedType(tok, tok.val, gt, path); .)
- )
- .
-GenericInstantiation<.List<Type/*!*/>/*!*/ gt.>
-= (. Contract.Requires(cce.NonNullElements(gt)); Type/*!*/ ty; .)
- "<"
- Type<out ty> (. gt.Add(ty); .)
- { "," Type<out ty> (. gt.Add(ty); .)
- }
- ">"
- .
-/*------------------------------------------------------------------------*/
-FunctionDecl<MemberModifiers mmod, out Function/*!*/ f>
-= (. Contract.Ensures(Contract.ValueAtReturn(out f)!=null);
- Attributes attrs = null;
- IToken/*!*/ id = Token.NoToken; // to please compiler
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
- List<Formal/*!*/> formals = new List<Formal/*!*/>();
- Type/*!*/ returnType = new BoolType();
- List<Expression/*!*/> reqs = new List<Expression/*!*/>();
- List<Expression/*!*/> ens = new List<Expression/*!*/>();
- List<FrameExpression/*!*/> reads = new List<FrameExpression/*!*/>();
- List<Expression/*!*/> decreases;
- Expression body = null;
- bool isPredicate = false; bool isCoPredicate = false;
- bool isFunctionMethod = false;
- IToken openParen = null;
- IToken bodyStart = Token.NoToken;
- IToken bodyEnd = Token.NoToken;
- bool signatureOmitted = false;
- .)
- /* ----- function ----- */
- ( "function"
- [ "method" (. isFunctionMethod = true; .)
- ]
- (. if (mmod.IsGhost) { SemErr(t, "functions cannot be declared 'ghost' (they are ghost by default)"); }
- .)
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- (
- [ GenericParameters<typeArgs> ]
- Formals<true, isFunctionMethod, formals, out openParen>
- ":"
- Type<out returnType>
- | "..." (. signatureOmitted = true;
- openParen = Token.NoToken; .)
- )
-
- /* ----- predicate ----- */
- | "predicate" (. isPredicate = true; .)
- [ "method" (. isFunctionMethod = true; .)
- ]
- (. if (mmod.IsGhost) { SemErr(t, "predicates cannot be declared 'ghost' (they are ghost by default)"); }
- .)
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- (
- [ GenericParameters<typeArgs> ]
- [ Formals<true, isFunctionMethod, formals, out openParen>
- [ ":" (. SemErr(t, "predicates do not have an explicitly declared return type; it is always bool"); .)
- ]
- ]
- | "..." (. signatureOmitted = true;
- openParen = Token.NoToken; .)
- )
-
- /* ----- copredicate ----- */
- | "copredicate" (. isCoPredicate = true; .)
- (. if (mmod.IsGhost) { SemErr(t, "copredicates cannot be declared 'ghost' (they are ghost by default)"); }
- .)
- { Attribute<ref attrs> }
- NoUSIdent<out id>
- (
- [ GenericParameters<typeArgs> ]
- [ Formals<true, isFunctionMethod, formals, out openParen>
- [ ":" (. SemErr(t, "copredicates do not have an explicitly declared return type; it is always bool"); .)
- ]
- ]
- | "..." (. signatureOmitted = true;
- openParen = Token.NoToken; .)
- )
- )
-
- (. decreases = isCoPredicate ? null : new List<Expression/*!*/>(); .)
- { FunctionSpec<reqs, reads, ens, decreases> }
- [ FunctionBody<out body, out bodyStart, out bodyEnd>
- ]
- (. if (isPredicate) {
- f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals,
- reqs, reads, ens, new Specification<Expression>(decreases, null), body, Predicate.BodyOriginKind.OriginalOrInherited, attrs, signatureOmitted);
- } else if (isCoPredicate) {
- f = new CoPredicate(id, id.val, mmod.IsStatic, typeArgs, openParen, formals,
- reqs, reads, ens, body, attrs, signatureOmitted);
- } else {
- f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals, returnType,
- reqs, reads, ens, new Specification<Expression>(decreases, null), body, attrs, signatureOmitted);
- }
- f.BodyStartTok = bodyStart;
- f.BodyEndTok = bodyEnd;
- .)
- .
-FunctionSpec<.List<Expression/*!*/>/*!*/ reqs, List<FrameExpression/*!*/>/*!*/ reads, List<Expression/*!*/>/*!*/ ens, List<Expression/*!*/> decreases.>
-= (. Contract.Requires(cce.NonNullElements(reqs));
- Contract.Requires(cce.NonNullElements(reads));
- Contract.Requires(decreases == null || cce.NonNullElements(decreases));
- Expression/*!*/ e; FrameExpression/*!*/ fe; .)
- (
- SYNC
- "requires" Expression<out e> SYNC ";" (. reqs.Add(e); .)
- | "reads" [ PossiblyWildFrameExpression<out fe> (. reads.Add(fe); .)
- { "," PossiblyWildFrameExpression<out fe> (. reads.Add(fe); .)
- }
- ] SYNC ";"
- | "ensures" Expression<out e> SYNC ";" (. ens.Add(e); .)
- | "decreases" (. if (decreases == null) {
- SemErr(t, "'decreases' clauses are meaningless for copredicates, so they are not allowed");
- decreases = new List<Expression/*!*/>();
- }
- .)
- DecreasesList<decreases, false> SYNC ";"
- )
- .
-PossiblyWildExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e)!=null);
- e = dummyExpr; .)
- /* A decreases clause on a loop asks that no termination check be performed.
- * Use of this feature is sound only with respect to partial correctness.
- */
- ( "*" (. e = new WildcardExpr(t); .)
- | Expression<out e>
- )
- .
-PossiblyWildFrameExpression<out FrameExpression/*!*/ fe>
-= (. Contract.Ensures(Contract.ValueAtReturn(out fe) != null); fe = dummyFrameExpr; .)
- /* A reads clause can list a wildcard, which allows the enclosing function to
- * read anything. 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).
- */
- ( "*" (. fe = new FrameExpression(t, new WildcardExpr(t), null); .)
- | FrameExpression<out fe>
- )
- .
-FrameExpression<out FrameExpression/*!*/ fe>
-= (. Contract.Ensures(Contract.ValueAtReturn(out fe) != null);
- Expression/*!*/ e;
- IToken/*!*/ id;
- string fieldName = null; IToken feTok = null;
- fe = null;
- .)
- (( Expression<out e> (. feTok = e.tok; .)
- [ "`" Ident<out id> (. fieldName = id.val; feTok = id; .)
- ]
- (. fe = new FrameExpression(feTok, e, fieldName); .)
- ) |
- ( "`" Ident<out id> (. fieldName = id.val; .)
- (. fe = new FrameExpression(id, new ImplicitThisExpr(id), fieldName); .)
- ))
- .
-FunctionBody<out Expression/*!*/ e, out IToken bodyStart, out IToken bodyEnd>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); e = dummyExpr; .)
- "{" (. bodyStart = t; .)
- Expression<out e>
- "}" (. bodyEnd = t; .)
- .
-/*------------------------------------------------------------------------*/
-BlockStmt<out BlockStmt/*!*/ block, out IToken bodyStart, out IToken bodyEnd>
-= (. Contract.Ensures(Contract.ValueAtReturn(out block) != null);
- List<Statement/*!*/> body = new List<Statement/*!*/>();
- .)
- "{" (. bodyStart = t; .)
- { Stmt<body>
- }
- "}" (. bodyEnd = t;
- block = new BlockStmt(bodyStart, body); .)
- .
-Stmt<.List<Statement/*!*/>/*!*/ ss.>
-= (. Statement/*!*/ s;
- .)
- OneStmt<out s> (. ss.Add(s); .)
- .
-OneStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; IToken/*!*/ id; string label = null;
- s = dummyStmt; /* to please the compiler */
- BlockStmt bs;
- IToken bodyStart, bodyEnd;
- int breakCount;
- .)
- SYNC
- ( BlockStmt<out bs, out bodyStart, out bodyEnd> (. s = bs; .)
- | AssertStmt<out s>
- | AssumeStmt<out s>
- | PrintStmt<out s>
- | UpdateStmt<out s>
- | VarDeclStatement<out s>
- | IfStmt<out s>
- | WhileStmt<out s>
- | MatchStmt<out s>
- | ParallelStmt<out s>
- | CalcStmt<out s>
- | "label" (. x = t; .)
- NoUSIdent<out id> ":"
- OneStmt<out s> (. s.Labels = new LList<Label>(new Label(x, id.val), s.Labels); .)
- | "break" (. x = t; breakCount = 1; label = null; .)
- ( NoUSIdent<out id> (. label = id.val; .)
- | { "break" (. breakCount++; .)
- }
- )
- SYNC
- ";" (. s = label != null ? new BreakStmt(x, label) : new BreakStmt(x, breakCount); .)
- | ReturnStmt<out s>
- | SkeletonStmt<out s>
- ";"
- )
- .
-
-SkeletonStmt<out Statement s>
-= (. List<IToken> names = null;
- List<Expression> exprs = null;
- IToken tok, dotdotdot, whereTok;
- Expression e; .)
- "..." (. dotdotdot = t; .)
- ["where" (. names = new List<IToken>(); exprs = new List<Expression>(); whereTok = t;.)
- Ident<out tok> (. names.Add(tok); .)
- {"," Ident<out tok> (. names.Add(tok); .)
- }
- ":="
- Expression<out e> (. exprs.Add(e); .)
- {"," Expression<out e> (. exprs.Add(e); .)
- }
- (. if (exprs.Count != names.Count) {
- SemErr(whereTok, exprs.Count < names.Count ? "not enough expressions" : "too many expressions");
- names = null; exprs = null;
- }
- .)
- ]
- (. s = new SkeletonStatement(dotdotdot, names, exprs); .)
- .
-ReturnStmt<out Statement/*!*/ s>
-= (.
- IToken returnTok = null;
- List<AssignmentRhs> rhss = null;
- AssignmentRhs r;
- bool isYield = false;
- .)
- ( "return" (. returnTok = t; .)
- | "yield" (. returnTok = t; isYield = true; .)
- )
- [
- Rhs<out r, null> (. rhss = new List<AssignmentRhs>(); rhss.Add(r); .)
- { "," Rhs<out r, null> (. rhss.Add(r); .)
- }
- ]
- ";" (. if (isYield) {
- s = new YieldStmt(returnTok, rhss);
- } else {
- s = new ReturnStmt(returnTok, rhss);
- }
- .)
- .
-UpdateStmt<out Statement/*!*/ s>
-= (. List<Expression> lhss = new List<Expression>();
- List<AssignmentRhs> rhss = new List<AssignmentRhs>();
- Expression e; AssignmentRhs r;
- Expression lhs0;
- IToken x;
- Attributes attrs = null;
- IToken suchThatAssume = null;
- Expression suchThat = null;
- .)
- Lhs<out e> (. x = e.tok; .)
- ( { Attribute<ref attrs> }
- ";" (. rhss.Add(new ExprRhs(e, attrs)); .)
- | (. lhss.Add(e); lhs0 = e; .)
- { "," Lhs<out e> (. lhss.Add(e); .)
- }
- ( ":=" (. x = t; .)
- Rhs<out r, lhs0> (. rhss.Add(r); .)
- { "," Rhs<out r, lhs0> (. rhss.Add(r); .)
- }
- | ":|" (. x = t; .)
- [ "assume" (. suchThatAssume = t; .)
- ]
- Expression<out suchThat>
- )
- ";"
- | ":" (. SemErr(t, "invalid statement (did you forget the 'label' keyword?)"); .)
- )
- (. if (suchThat != null) {
- s = new AssignSuchThatStmt(x, lhss, suchThat, suchThatAssume);
- } else {
- if (lhss.Count == 0 && rhss.Count == 0) {
- s = new BlockStmt(x, new List<Statement>()); // error, give empty statement
- } else {
- s = new UpdateStmt(x, lhss, rhss);
- }
- }
- .)
- .
-Rhs<out AssignmentRhs r, Expression receiverForInitCall>
-= (. Contract.Ensures(Contract.ValueAtReturn<AssignmentRhs>(out r) != null);
- IToken/*!*/ x, newToken; Expression/*!*/ e;
- List<Expression> ee = null;
- Type ty = null;
- CallStmt initCall = null;
- List<Expression> args;
- r = dummyRhs; // to please compiler
- Attributes attrs = null;
- .)
- ( "new" (. newToken = t; .)
- TypeAndToken<out x, out ty>
- [ "[" (. ee = new List<Expression>(); .)
- Expressions<ee>
- "]" (. // make sure an array class with this dimensionality exists
- UserDefinedType tmp = theBuiltIns.ArrayType(x, ee.Count, new IntType(), true);
- .)
- | "." Ident<out x>
- "(" (. // This case happens when we have type<typeargs>.Constructor(args)
- // There is no ambiguity about where the constructor is or whether one exists.
- args = new List<Expression/*!*/>(); .)
- [ Expressions<args> ]
- ")" (. initCall = new CallStmt(x, new List<Expression>(), receiverForInitCall, x.val, args); .)
- | "(" (. var udf = ty as UserDefinedType;
- if (udf != null && 0 < udf.Path.Count && udf.TypeArgs.Count == 0) {
- // The parsed name had the form "A.B.Ctr", so treat "A.B" as the name of the type and "Ctr" as
- // the name of the constructor that's being invoked.
- x = udf.tok;
- ty = new UserDefinedType(udf.Path[0], udf.Path[udf.Path.Count-1].val, new List<Type>(), udf.Path.GetRange(0,udf.Path.Count-1));
- } else {
- SemErr(t, "expected '.'");
- x = null;
- }
- args = new List<Expression/*!*/>(); .)
- [ Expressions<args> ]
- ")" (. if (x != null) {
- initCall = new CallStmt(x, new List<Expression>(), receiverForInitCall, x.val, args);
- }
- .)
- ]
- (. if (ee != null) {
- r = new TypeRhs(newToken, ty, ee);
- } else {
- r = new TypeRhs(newToken, ty, initCall);
- }
- .)
- /* One day, the choose expression should be treated just as a special case of a method call. */
- | "choose" (. x = t; .)
- Expression<out e> (. r = new ExprRhs(new UnaryExpr(x, UnaryExpr.Opcode.SetChoose, e)); .)
- | "*" (. r = new HavocRhs(t); .)
- | Expression<out e> (. r = new ExprRhs(e); .)
- )
- { Attribute<ref attrs> } (. r.Attributes = attrs; .)
- .
-VarDeclStatement<.out Statement/*!*/ s.>
-= (. IToken x = null, assignTok = null; bool isGhost = false;
- VarDecl/*!*/ d;
- AssignmentRhs r; IdentifierExpr lhs0;
- List<VarDecl> lhss = new List<VarDecl>();
- List<AssignmentRhs> rhss = new List<AssignmentRhs>();
- IToken suchThatAssume = null;
- Expression suchThat = null;
- .)
- [ "ghost" (. isGhost = true; x = t; .)
- ]
- "var" (. if (!isGhost) { x = t; } .)
- LocalIdentTypeOptional<out d, isGhost> (. lhss.Add(d); .)
- { ","
- LocalIdentTypeOptional<out d, isGhost> (. lhss.Add(d); .)
- }
- [ ":=" (. assignTok = t;
- lhs0 = new IdentifierExpr(lhss[0].Tok, lhss[0].Name);
- lhs0.Var = lhss[0]; lhs0.Type = lhss[0].OptionalType; // resolve here
- .)
- Rhs<out r, lhs0> (. rhss.Add(r); .)
- { "," Rhs<out r, lhs0> (. rhss.Add(r); .)
- }
- | ":|" (. assignTok = t; .)
- [ "assume" (. suchThatAssume = t; .)
- ]
- Expression<out suchThat>
- ]
- ";"
- (. ConcreteUpdateStatement update;
- if (suchThat != null) {
- var ies = new List<Expression>();
- foreach (var lhs in lhss) {
- ies.Add(new IdentifierExpr(lhs.Tok, lhs.Name));
- }
- update = new AssignSuchThatStmt(assignTok, ies, suchThat, suchThatAssume);
- } else if (rhss.Count == 0) {
- update = null;
- } else {
- var ies = new List<Expression>();
- foreach (var lhs in lhss) {
- ies.Add(new AutoGhostIdentifierExpr(lhs.Tok, lhs.Name));
- }
- update = new UpdateStmt(assignTok, ies, rhss);
- }
- s = new VarDeclStmt(x, lhss, update);
- .)
- .
-IfStmt<out Statement/*!*/ ifStmt>
-= (. Contract.Ensures(Contract.ValueAtReturn(out ifStmt) != null); IToken/*!*/ x;
- Expression guard = null; bool guardOmitted = false;
- BlockStmt/*!*/ thn;
- BlockStmt/*!*/ bs;
- Statement/*!*/ s;
- Statement els = null;
- IToken bodyStart, bodyEnd;
- List<GuardedAlternative> alternatives;
- ifStmt = dummyStmt; // to please the compiler
- .)
- "if" (. x = t; .)
- (
- ( Guard<out guard>
- | "..." (. guardOmitted = true; .)
- )
- BlockStmt<out thn, out bodyStart, out bodyEnd>
- [ "else"
- ( IfStmt<out s> (. els = s; .)
- | BlockStmt<out bs, out bodyStart, out bodyEnd> (. els = bs; .)
- )
- ]
- (. if (guardOmitted) {
- ifStmt = new SkeletonStatement(new IfStmt(x, guard, thn, els), true, false);
- } else {
- ifStmt = new IfStmt(x, guard, thn, els);
- }
- .)
- |
- AlternativeBlock<out alternatives>
- (. ifStmt = new AlternativeStmt(x, alternatives); .)
- )
- .
-AlternativeBlock<.out List<GuardedAlternative> alternatives.>
-= (. alternatives = new List<GuardedAlternative>();
- IToken x;
- Expression e;
- List<Statement> body;
- .)
- "{"
- { "case" (. x = t; .)
- Expression<out e>
- "=>"
- (. body = new List<Statement>(); .)
- { Stmt<body> }
- (. alternatives.Add(new GuardedAlternative(x, e, body)); .)
- }
- "}"
- .
-WhileStmt<out Statement/*!*/ stmt>
-= (. Contract.Ensures(Contract.ValueAtReturn(out stmt) != null); IToken/*!*/ x;
- Expression guard = null; bool guardOmitted = false;
- List<MaybeFreeExpression/*!*/> invariants = new List<MaybeFreeExpression/*!*/>();
- List<Expression/*!*/> decreases = new List<Expression/*!*/>();
- Attributes decAttrs = null;
- Attributes modAttrs = null;
- List<FrameExpression/*!*/> mod = null;
- BlockStmt/*!*/ body = null; bool bodyOmitted = false;
- IToken bodyStart = null, bodyEnd = null;
- List<GuardedAlternative> alternatives;
- stmt = dummyStmt; // to please the compiler
- .)
- "while" (. x = t; .)
- (
- ( Guard<out guard> (. Contract.Assume(guard == null || cce.Owner.None(guard)); .)
- | "..." (. guardOmitted = true; .)
- )
- LoopSpec<out invariants, out decreases, out mod, ref decAttrs, ref modAttrs>
- ( BlockStmt<out body, out bodyStart, out bodyEnd>
- | "..." (. bodyOmitted = true; .)
- )
- (.
- if (guardOmitted || bodyOmitted) {
- if (mod != null) {
- SemErr(mod[0].E.tok, "'modifies' clauses are not allowed on refining loops");
- }
- if (body == null) {
- body = new BlockStmt(x, new List<Statement>());
- }
- stmt = new WhileStmt(x, guard, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(null, null), body);
- stmt = new SkeletonStatement(stmt, guardOmitted, bodyOmitted);
- } else {
- // The following statement protects against crashes in case of parsing errors
- body = body ?? new BlockStmt(x, new List<Statement>());
- stmt = new WhileStmt(x, guard, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(mod, modAttrs), body);
- }
- .)
- |
- LoopSpec<out invariants, out decreases, out mod, ref decAttrs, ref modAttrs>
- AlternativeBlock<out alternatives>
- (. stmt = new AlternativeLoopStmt(x, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(mod, modAttrs), alternatives); .)
- )
- .
-LoopSpec<.out List<MaybeFreeExpression/*!*/> invariants, out List<Expression/*!*/> decreases, out List<FrameExpression/*!*/> mod, ref Attributes decAttrs, ref Attributes modAttrs.>
-= (. FrameExpression/*!*/ fe;
- invariants = new List<MaybeFreeExpression/*!*/>();
- MaybeFreeExpression invariant = null;
- decreases = new List<Expression/*!*/>();
- mod = null;
- .)
- {
- Invariant<out invariant> SYNC ";" (. invariants.Add(invariant); .)
- | SYNC "decreases"
- { IF(IsAttribute()) Attribute<ref decAttrs> }
- DecreasesList<decreases, true> SYNC ";"
- | SYNC "modifies"
- { IF(IsAttribute()) Attribute<ref modAttrs> } (. mod = mod ?? new List<FrameExpression>(); .)
- [ FrameExpression<out fe> (. mod.Add(fe); .)
- { "," FrameExpression<out fe> (. mod.Add(fe); .)
- }
- ] SYNC ";"
- }
- .
-Invariant<out MaybeFreeExpression/*!*/ invariant>
-= (. bool isFree = false; Expression/*!*/ e; List<string> ids = new List<string>(); invariant = null; Attributes attrs = null; .)
- SYNC
- ["free" (. isFree = true; .)
- ]
- "invariant" { IF(IsAttribute()) Attribute<ref attrs> } Expression<out e> (. invariant = new MaybeFreeExpression(e, isFree, attrs); .)
- .
-DecreasesList<.List<Expression/*!*/> decreases, bool allowWildcard.>
-= (. Expression/*!*/ e; .)
- PossiblyWildExpression<out e> (. if (!allowWildcard && e is WildcardExpr) {
- SemErr(e.tok, "'decreases *' is only allowed on loops and tail-recursive methods");
- } else {
- decreases.Add(e);
- }
- .)
- { "," PossiblyWildExpression<out e> (. if (!allowWildcard && e is WildcardExpr) {
- SemErr(e.tok, "'decreases *' is only allowed on loops and tail-recursive methods");
- } else {
- decreases.Add(e);
- }
- .)
- }
- .
-Guard<out Expression e> /* null represents demonic-choice */
-= (. Expression/*!*/ ee; e = null; .)
- "("
- ( "*" (. e = null; .)
- | Expression<out ee> (. e = ee; .)
- )
- ")"
- .
-MatchStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- Token x; Expression/*!*/ e; MatchCaseStmt/*!*/ c;
- List<MatchCaseStmt/*!*/> cases = new List<MatchCaseStmt/*!*/>(); .)
- "match" (. x = t; .)
- Expression<out e>
- "{"
- { CaseStatement<out c> (. cases.Add(c); .)
- }
- "}"
- (. s = new MatchStmt(x, e, cases); .)
- .
-CaseStatement<out MatchCaseStmt/*!*/ c>
-= (. Contract.Ensures(Contract.ValueAtReturn(out c) != null);
- IToken/*!*/ x, id;
- List<BoundVar/*!*/> arguments = new List<BoundVar/*!*/>();
- BoundVar/*!*/ bv;
- List<Statement/*!*/> body = new List<Statement/*!*/>();
- .)
- "case" (. x = t; .)
- Ident<out id>
- [ "("
- IdentTypeOptional<out bv> (. arguments.Add(bv); .)
- { "," IdentTypeOptional<out bv> (. arguments.Add(bv); .)
- }
- ")" ]
- "=>"
- { Stmt<body> }
- (. c = new MatchCaseStmt(x, id.val, arguments, body); .)
- .
-/*------------------------------------------------------------------------*/
-AssertStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x;
- Expression e = null; Attributes attrs = null;
- .)
- "assert" (. x = t; .)
- { IF(IsAttribute()) Attribute<ref attrs> }
- ( Expression<out e>
- | "..."
- )
- ";"
- (. if (e == null) {
- s = new SkeletonStatement(new AssertStmt(x, new LiteralExpr(x, true), attrs), true, false);
- } else {
- s = new AssertStmt(x, e, attrs);
- }
- .)
- .
-AssumeStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x;
- Expression e = null; Attributes attrs = null;
- .)
- "assume" (. x = t; .)
- { IF(IsAttribute()) Attribute<ref attrs> }
- ( Expression<out e>
- | "..."
- )
- (. if (e == null) {
- s = new SkeletonStatement(new AssumeStmt(x, new LiteralExpr(x, true), attrs), true, false);
- } else {
- s = new AssumeStmt(x, e, attrs);
- }
- .)
- ";"
- .
-PrintStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Attributes.Argument/*!*/ arg;
- List<Attributes.Argument/*!*/> args = new List<Attributes.Argument/*!*/>();
- .)
- "print" (. x = t; .)
- AttributeArg<out arg> (. args.Add(arg); .)
- { "," AttributeArg<out arg> (. args.Add(arg); .)
- }
- ";" (. s = new PrintStmt(x, args); .)
- .
-
-ParallelStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- IToken/*!*/ x;
- List<BoundVar/*!*/> bvars = null;
- Attributes attrs = null;
- Expression range = null;
- var ens = new List<MaybeFreeExpression/*!*/>();
- bool isFree;
- Expression/*!*/ e;
- BlockStmt/*!*/ block;
- IToken bodyStart, bodyEnd;
- .)
- "parallel" (. x = t; .)
- "("
- [ (. List<BoundVar/*!*/> bvarsX; Attributes attrsX; Expression rangeX; .)
- QuantifierDomain<out bvarsX, out attrsX, out rangeX>
- (. bvars = bvarsX; attrs = attrsX; range = rangeX;
- .)
- ]
- (. if (bvars == null) { bvars = new List<BoundVar>(); }
- if (range == null) { range = new LiteralExpr(x, true); }
- .)
- ")"
- { (. isFree = false; .)
- [ "free" (. isFree = true; .)
- ]
- "ensures" Expression<out e> ";" (. ens.Add(new MaybeFreeExpression(e, isFree)); .)
- }
- BlockStmt<out block, out bodyStart, out bodyEnd>
- (. s = new ParallelStmt(x, bvars, attrs, range, ens, block); .)
- .
-
-CalcStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- Token x;
- BinaryExpr.Opcode op, calcOp = BinaryExpr.Opcode.Eq, resOp = BinaryExpr.Opcode.Eq;
- var lines = new List<Expression/*!*/>();
- var hints = new List<BlockStmt/*!*/>();
- var customOps = new List<BinaryExpr.Opcode?>();
- BinaryExpr.Opcode? maybeOp;
- Expression/*!*/ e;
- BlockStmt/*!*/ h;
- IToken opTok;
- .)
- "calc" (. x = t; .)
- [ CalcOp<out opTok, out calcOp> (. maybeOp = Microsoft.Dafny.CalcStmt.ResultOp(calcOp, calcOp); // guard against non-trasitive calcOp (like !=)
- if (maybeOp == null) {
- SemErr(opTok, "the main operator of a calculation must be transitive");
- }
- resOp = calcOp;
- .)
- ]
- "{"
- [ Expression<out e> (. lines.Add(e); .)
- ";"
- {
- Hint<out h> (. hints.Add(h); .)
- ( CalcOp<out opTok, out op> (. maybeOp = Microsoft.Dafny.CalcStmt.ResultOp(resOp, op);
- if (maybeOp == null) {
- customOps.Add(null); // pretend the operator was not there to satisfy the precondition of the CalcStmt contructor
- SemErr(opTok, "this operator cannot continue this calculation");
- } else {
- customOps.Add(op);
- resOp = (BinaryExpr.Opcode)maybeOp;
- }
- .)
- | (. customOps.Add(null); .)
- )
- Expression<out e> (. lines.Add(e); .)
- ";"
- }
- ]
- "}"
- (. s = new CalcStmt(x, calcOp, lines, hints, customOps); .)
- .
-CalcOp<out IToken x, out BinaryExpr.Opcode/*!*/ op>
-= (. Contract.Ensures(Microsoft.Dafny.CalcStmt.ValidOp(Contract.ValueAtReturn(out op)));
- op = BinaryExpr.Opcode.Eq; // Returns Eq if parsing fails because it is compatible with any other operator
- x = null;
- .)
- ( "==" (. x = t; op = BinaryExpr.Opcode.Eq; .)
- | "<" (. x = t; op = BinaryExpr.Opcode.Lt; .)
- | ">" (. x = t; op = BinaryExpr.Opcode.Gt; .)
- | "<=" (. x = t; op = BinaryExpr.Opcode.Le; .)
- | ">=" (. x = t; op = BinaryExpr.Opcode.Ge; .)
- | "!=" (. x = t; op = BinaryExpr.Opcode.Neq; .)
- | '\u2260' (. x = t; op = BinaryExpr.Opcode.Neq; .)
- | '\u2264' (. x = t; op = BinaryExpr.Opcode.Le; .)
- | '\u2265' (. x = t; op = BinaryExpr.Opcode.Ge; .)
- | EquivOp (. x = t; op = BinaryExpr.Opcode.Iff; .)
- | ImpliesOp (. x = t; op = BinaryExpr.Opcode.Imp; .)
- )
- .
-Hint<out BlockStmt s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); // returns an empty block statement if the hint is empty
- var subhints = new List<Statement/*!*/>();
- IToken bodyStart, bodyEnd;
- BlockStmt/*!*/ block;
- Statement/*!*/ calc;
- Token x = la;
- .)
- { BlockStmt<out block, out bodyStart, out bodyEnd> (. subhints.Add(block); .)
- | CalcStmt<out calc> (. subhints.Add(calc); .)
- }
- (. s = new BlockStmt(x, subhints); // if the hint is empty x is the first token of the next line, but it doesn't matter cause the block statement is just used as a container
- .)
- .
-/*------------------------------------------------------------------------*/
-Expression<out Expression/*!*/ e>
-=
- EquivExpression<out e>
- .
-/*------------------------------------------------------------------------*/
-EquivExpression<out Expression/*!*/ e0>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; .)
- ImpliesExpression<out e0>
- { EquivOp (. x = t; .)
- ImpliesExpression<out e1> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Iff, e0, e1); .)
- }
- .
-EquivOp = "<==>" | '\u21d4'.
-/*------------------------------------------------------------------------*/
-ImpliesExpression<out Expression/*!*/ e0>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; .)
- LogicalExpression<out e0>
- [ ImpliesOp (. x = t; .)
- ImpliesExpression<out e1> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Imp, e0, e1); .)
- ]
- .
-ImpliesOp = "==>" | '\u21d2'.
-/*------------------------------------------------------------------------*/
-LogicalExpression<out Expression/*!*/ e0>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; .)
- RelationalExpression<out e0>
- [ AndOp (. x = t; .)
- RelationalExpression<out e1> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1); .)
- { AndOp (. x = t; .)
- RelationalExpression<out e1> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1); .)
- }
- | OrOp (. x = t; .)
- RelationalExpression<out e1> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1); .)
- { OrOp (. x = t; .)
- RelationalExpression<out e1> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1); .)
- }
- ]
- .
-AndOp = "&&" | '\u2227'.
-OrOp = "||" | '\u2228'.
-/*------------------------------------------------------------------------*/
-RelationalExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken x, firstOpTok = null; Expression e0, e1, acc = null; BinaryExpr.Opcode op;
- List<Expression> chain = null;
- List<BinaryExpr.Opcode> ops = null;
- int kind = 0; // 0 ("uncommitted") indicates chain of ==, possibly with one !=
- // 1 ("ascending") indicates chain of ==, <, <=, possibly with one !=
- // 2 ("descending") indicates chain of ==, >, >=, possibly with one !=
- // 3 ("illegal") indicates illegal chain
- // 4 ("disjoint") indicates chain of disjoint set operators
- bool hasSeenNeq = false;
- .)
- Term<out e0> (. e = e0; .)
- [ RelOp<out x, out op> (. firstOpTok = x; .)
- Term<out e1> (. e = new BinaryExpr(x, op, e0, e1);
- if (op == BinaryExpr.Opcode.Disjoint)
- acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, e0, e1); // accumulate first two operands.
- .)
- { (. if (chain == null) {
- chain = new List<Expression>();
- ops = new List<BinaryExpr.Opcode>();
- chain.Add(e0); ops.Add(op); chain.Add(e1);
- switch (op) {
- case BinaryExpr.Opcode.Eq:
- kind = 0; break;
- case BinaryExpr.Opcode.Neq:
- kind = 0; hasSeenNeq = true; break;
- case BinaryExpr.Opcode.Lt:
- case BinaryExpr.Opcode.Le:
- kind = 1; break;
- case BinaryExpr.Opcode.Gt:
- case BinaryExpr.Opcode.Ge:
- kind = 2; break;
- case BinaryExpr.Opcode.Disjoint:
- kind = 4; break;
- default:
- kind = 3; break;
- }
- }
- e0 = e1;
- .)
- RelOp<out x, out op> (. switch (op) {
- case BinaryExpr.Opcode.Eq:
- if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "chaining not allowed from the previous operator"); }
- break;
- case BinaryExpr.Opcode.Neq:
- if (hasSeenNeq) { SemErr(x, "a chain cannot have more than one != operator"); }
- if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "this operator cannot continue this chain"); }
- hasSeenNeq = true; break;
- case BinaryExpr.Opcode.Lt:
- case BinaryExpr.Opcode.Le:
- if (kind == 0) { kind = 1; }
- else if (kind != 1) { SemErr(x, "this operator chain cannot continue with an ascending operator"); }
- break;
- case BinaryExpr.Opcode.Gt:
- case BinaryExpr.Opcode.Ge:
- if (kind == 0) { kind = 2; }
- else if (kind != 2) { SemErr(x, "this operator chain cannot continue with a descending operator"); }
- break;
- case BinaryExpr.Opcode.Disjoint:
- if (kind != 4) { SemErr(x, "can only chain disjoint (!!) with itself."); kind = 3; }
- break;
- default:
- SemErr(x, "this operator cannot be part of a chain");
- kind = 3; break;
- }
- .)
- Term<out e1> (. ops.Add(op); chain.Add(e1);
- if (op == BinaryExpr.Opcode.Disjoint) {
- e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, acc, e1));
- acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, acc, e1); //e0 has already been added.
- }
- else
- e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, e0, e1));
- .)
- }
- ]
- (. if (chain != null) {
- e = new ChainingExpression(firstOpTok, chain, ops, e);
- }
- .)
- .
-RelOp<out IToken/*!*/ x, out BinaryExpr.Opcode op>
-= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null);
- x = Token.NoToken; op = BinaryExpr.Opcode.Add/*(dummy)*/;
- IToken y;
- .)
- ( "==" (. x = t; op = BinaryExpr.Opcode.Eq; .)
- | "<" (. x = t; op = BinaryExpr.Opcode.Lt; .)
- | ">" (. x = t; op = BinaryExpr.Opcode.Gt; .)
- | "<=" (. x = t; op = BinaryExpr.Opcode.Le; .)
- | ">=" (. x = t; op = BinaryExpr.Opcode.Ge; .)
- | "!=" (. x = t; op = BinaryExpr.Opcode.Neq; .)
- | "!!" (. x = t; op = BinaryExpr.Opcode.Disjoint; .)
- | "in" (. x = t; op = BinaryExpr.Opcode.In; .)
- | /* The next operator is "!in", but Coco evidently parses "!in" even when it is a prefix of, say, "!initialized".
- * The reason for this seems to be that the first character of "!in" is not a letter. So, here is the workaround:
- */
- "!" (. x = t; y = Token.NoToken; .)
- [ "in" (. y = t; .)
- ] (. if (y == Token.NoToken) {
- SemErr(x, "invalid RelOp");
- } else if (y.pos != x.pos + 1) {
- SemErr(x, "invalid RelOp (perhaps you intended \"!in\" with no intervening whitespace?)");
- } else {
- x.val = "!in";
- op = BinaryExpr.Opcode.NotIn;
- }
- .)
- | '\u2260' (. x = t; op = BinaryExpr.Opcode.Neq; .)
- | '\u2264' (. x = t; op = BinaryExpr.Opcode.Le; .)
- | '\u2265' (. x = t; op = BinaryExpr.Opcode.Ge; .)
- )
- .
-/*------------------------------------------------------------------------*/
-Term<out Expression/*!*/ e0>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op; .)
- Factor<out e0>
- { AddOp<out x, out op>
- Factor<out e1> (. e0 = new BinaryExpr(x, op, e0, e1); .)
- }
- .
-AddOp<out IToken/*!*/ x, out BinaryExpr.Opcode op>
-= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null); x = Token.NoToken; op=BinaryExpr.Opcode.Add/*(dummy)*/; .)
- ( "+" (. x = t; op = BinaryExpr.Opcode.Add; .)
- | "-" (. x = t; op = BinaryExpr.Opcode.Sub; .)
- )
- .
-/*------------------------------------------------------------------------*/
-Factor<out Expression/*!*/ e0>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op; .)
- UnaryExpression<out e0>
- { MulOp<out x, out op>
- UnaryExpression<out e1> (. e0 = new BinaryExpr(x, op, e0, e1); .)
- }
- .
-MulOp<out IToken/*!*/ x, out BinaryExpr.Opcode op>
-= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null); x = Token.NoToken; op = BinaryExpr.Opcode.Add/*(dummy)*/; .)
- ( "*" (. x = t; op = BinaryExpr.Opcode.Mul; .)
- | "/" (. x = t; op = BinaryExpr.Opcode.Div; .)
- | "%" (. x = t; op = BinaryExpr.Opcode.Mod; .)
- )
- .
-/*------------------------------------------------------------------------*/
-UnaryExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr; .)
- ( "-" (. x = t; .)
- UnaryExpression<out e> (. e = new BinaryExpr(x, BinaryExpr.Opcode.Sub, new LiteralExpr(x, 0), e); .)
- | NegOp (. x = t; .)
- UnaryExpression<out e> (. e = new UnaryExpr(x, UnaryExpr.Opcode.Not, e); .)
- | EndlessExpression<out e> /* these have no further suffix */
- | DottedIdentifiersAndFunction<out e>
- { Suffix<ref e> }
- | DisplayExpr<out e>
- { Suffix<ref e> }
- | MultiSetExpr<out e>
- { Suffix<ref e> }
- | "map" (. x = t; .)
- ( MapDisplayExpr<x, out e>
- { Suffix<ref e> }
- | MapComprehensionExpr<x, out e>
- | (. SemErr("map must be followed by literal in brackets or comprehension."); .)
- )
- | ConstAtomExpression<out e>
- { Suffix<ref e> }
- )
- .
-Lhs<out Expression e>
-= (. e = dummyExpr; // the assignment is to please the compiler, the dummy value to satisfy contracts in the event of a parse error
- .)
- ( DottedIdentifiersAndFunction<out e>
- { Suffix<ref e> }
- | ConstAtomExpression<out e>
- Suffix<ref e>
- { Suffix<ref e> }
- )
- .
-NegOp = "!" | '\u00ac'.
-/* A ConstAtomExpression is never an l-value. Also, a ConstAtomExpression is never followed by
- * an open paren (but could very well have a suffix that starts with a period or a square bracket).
- * (The "Also..." part may change if expressions in Dafny could yield functions.)
- */
-ConstAtomExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken/*!*/ x; BigInteger n;
- e = dummyExpr;
- .)
- ( "false" (. e = new LiteralExpr(t, false); .)
- | "true" (. e = new LiteralExpr(t, true); .)
- | "null" (. e = new LiteralExpr(t); .)
- | Nat<out n> (. e = new LiteralExpr(t, n); .)
- | "this" (. e = new ThisExpr(t); .)
- | "fresh" (. x = t; .)
- "(" Expression<out e> ")" (. e = new FreshExpr(x, e); .)
- | "old" (. x = t; .)
- "(" Expression<out e> ")" (. e = new OldExpr(x, e); .)
- | "|" (. x = t; .)
- Expression<out e> (. e = new UnaryExpr(x, UnaryExpr.Opcode.SeqLength, e); .)
- "|"
- | "(" (. x = t; .)
- Expression<out e> (. e = new ParensExpression(x, e); .)
- ")"
- )
- .
-DisplayExpr<out Expression e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken/*!*/ x = null; List<Expression/*!*/>/*!*/ elements;
- e = dummyExpr;
- .)
- ( "{" (. x = t; elements = new List<Expression/*!*/>(); .)
- [ Expressions<elements> ] (. e = new SetDisplayExpr(x, elements);.)
- "}"
- | "[" (. x = t; elements = new List<Expression/*!*/>(); .)
- [ Expressions<elements> ] (. e = new SeqDisplayExpr(x, elements); .)
- "]"
- )
- .
-MultiSetExpr<out Expression e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken/*!*/ x = null; List<Expression/*!*/>/*!*/ elements;
- e = dummyExpr;
- .)
- "multiset" (. x = t; .)
- ( "{" (. elements = new List<Expression/*!*/>(); .)
- [ Expressions<elements> ] (. e = new MultiSetDisplayExpr(x, elements);.)
- "}"
- | "(" (. x = t; elements = new List<Expression/*!*/>(); .)
- Expression<out e> (. e = new MultiSetFormingExpr(x, e); .)
- ")"
- | (. SemErr("multiset must be followed by multiset literal or expression to coerce in parentheses."); .)
- )
- .
-MapDisplayExpr<IToken/*!*/ mapToken, out Expression e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- List<ExpressionPair/*!*/>/*!*/ elements= new List<ExpressionPair/*!*/>() ;
- e = dummyExpr;
- .)
- "["
- [ MapLiteralExpressions<out elements> ] (. e = new MapDisplayExpr(mapToken, elements);.)
- "]"
- .
-MapLiteralExpressions<.out List<ExpressionPair> elements.>
-= (. Expression/*!*/ d, r;
- elements = new List<ExpressionPair/*!*/>(); .)
- Expression<out d> ":=" Expression<out r> (. elements.Add(new ExpressionPair(d,r)); .)
- { "," Expression<out d> ":=" Expression<out r>(. elements.Add(new ExpressionPair(d,r)); .)
- }
- .
-MapComprehensionExpr<IToken/*!*/ mapToken, out Expression e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- BoundVar/*!*/ bv;
- List<BoundVar/*!*/> bvars = new List<BoundVar/*!*/>();
- Expression range = null;
- Expression body;
- .)
- IdentTypeOptional<out bv> (. bvars.Add(bv); .)
- [ "|" Expression<out range> ]
- QSep
- Expression<out body>
- (. e = new MapComprehension(mapToken, bvars, range ?? new LiteralExpr(mapToken, true), body);
- .)
- .
-EndlessExpression<out Expression e>
-= (. IToken/*!*/ x;
- Expression e0, e1;
- e = dummyExpr;
- .)
- ( "if" (. x = t; .)
- Expression<out e>
- "then" Expression<out e0>
- "else" Expression<out e1> (. e = new ITEExpr(x, e, e0, e1); .)
- | MatchExpression<out e>
- | QuantifierGuts<out e>
- | ComprehensionExpr<out e>
- | "assert" (. x = t; .)
- Expression<out e0> ";"
- Expression<out e1> (. e = new AssertExpr(x, e0, e1); .)
- | "assume" (. x = t; .)
- Expression<out e0> ";"
- Expression<out e1> (. e = new AssumeExpr(x, e0, e1); .)
- | LetExpr<out e>
- | NamedExpr<out e>
- )
- .
-
-LetExpr<out Expression e>
-= (. IToken/*!*/ x;
- e = dummyExpr;
- BoundVar d;
- List<BoundVar> letVars; List<Expression> letRHSs;
- .)
- "var" (. x = t;
- letVars = new List<BoundVar>();
- letRHSs = new List<Expression>(); .)
- IdentTypeOptional<out d> (. letVars.Add(d); .)
- { "," IdentTypeOptional<out d> (. letVars.Add(d); .)
- }
- ":="
- Expression<out e> (. letRHSs.Add(e); .)
- { "," Expression<out e> (. letRHSs.Add(e); .)
- }
- ";"
- Expression<out e> (. e = new LetExpr(x, letVars, letRHSs, e); .)
- .
-
-NamedExpr<out Expression e>
-= (. IToken/*!*/ x, d;
- e = dummyExpr;
- Expression expr;
- .)
- "label" (. x = t; .)
- NoUSIdent<out d>
- ":"
- Expression<out e> (. expr = e;
- e = new NamedExpr(x, d.val, expr); .)
- .
-
-MatchExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; MatchCaseExpr/*!*/ c;
- List<MatchCaseExpr/*!*/> cases = new List<MatchCaseExpr/*!*/>();
- .)
- "match" (. x = t; .)
- Expression<out e>
- /* Note: The following gives rise to a '"case" is start & successor of deletable structure' error,
- but it's okay, because we want this closer match expression to bind as much as possible--use
- parens around it to limit its scope. */
- { CaseExpression<out c> (. cases.Add(c); .)
- }
- (. e = new MatchExpr(x, e, cases); .)
- .
-CaseExpression<out MatchCaseExpr/*!*/ c>
-= (. Contract.Ensures(Contract.ValueAtReturn(out c) != null); IToken/*!*/ x, id;
- List<BoundVar/*!*/> arguments = new List<BoundVar/*!*/>();
- BoundVar/*!*/ bv;
- Expression/*!*/ body;
- .)
- "case" (. x = t; .)
- Ident<out id>
- [ "("
- IdentTypeOptional<out bv> (. arguments.Add(bv); .)
- { "," IdentTypeOptional<out bv> (. arguments.Add(bv); .)
- }
- ")" ]
- "=>"
- Expression<out body> (. c = new MatchCaseExpr(x, id.val, arguments, body); .)
- .
-/*------------------------------------------------------------------------*/
-DottedIdentifiersAndFunction<out Expression e>
-= (. IToken id; IToken openParen = null;
- List<Expression> args = null;
- List<IToken> idents = new List<IToken>();
- .)
- Ident<out id> (. idents.Add(id); .)
- { "."
- Ident<out id> (. idents.Add(id); .)
- }
- [ "(" (. openParen = t; args = new List<Expression>(); .)
- [ Expressions<args> ]
- ")"
- ]
- (. e = new IdentifierSequence(idents, openParen, args); .)
- .
-Suffix<ref Expression/*!*/ e>
-= (. Contract.Requires(e != null); Contract.Ensures(e!=null); IToken/*!*/ id, x; List<Expression/*!*/>/*!*/ args;
- Expression e0 = null; Expression e1 = null; Expression/*!*/ ee; bool anyDots = false;
- List<Expression> multipleIndices = null;
- bool func = false;
- .)
- ( "."
- Ident<out id>
- [ "(" (. IToken openParen = t; args = new List<Expression/*!*/>(); func = true; .)
- [ Expressions<args> ]
- ")" (. e = new FunctionCallExpr(id, id.val, e, openParen, args); .)
- ] (. if (!func) { e = new ExprDotName(id, e, id.val); } .)
- | "[" (. x = t; .)
- ( Expression<out ee> (. e0 = ee; .)
- ( ".." (. anyDots = true; .)
- [ Expression<out ee> (. e1 = ee; .)
- ]
- | ":="
- Expression<out ee> (. e1 = ee; .)
- | { "," Expression<out ee> (. if (multipleIndices == null) {
- multipleIndices = new List<Expression>();
- multipleIndices.Add(e0);
- }
- multipleIndices.Add(ee);
- .)
- }
- )
- | ".." (. anyDots = true; .)
- [ Expression<out ee> (. e1 = ee; .)
- ]
- )
- (. if (multipleIndices != null) {
- e = new MultiSelectExpr(x, e, multipleIndices);
- // make sure an array class with this dimensionality exists
- UserDefinedType tmp = theBuiltIns.ArrayType(x, multipleIndices.Count, new IntType(), true);
- } else {
- if (!anyDots && e0 == null) {
- /* a parsing error occurred */
- e0 = dummyExpr;
- }
- Contract.Assert(anyDots || e0 != null);
- if (anyDots) {
- //Contract.Assert(e0 != null || e1 != null);
- e = new SeqSelectExpr(x, false, e, e0, e1);
- } else if (e1 == null) {
- Contract.Assert(e0 != null);
- e = new SeqSelectExpr(x, true, e, e0, null);
- } else {
- Contract.Assert(e0 != null);
- e = new SeqUpdateExpr(x, e, e0, e1);
- }
- }
- .)
- "]"
- )
- .
-/*------------------------------------------------------------------------*/
-QuantifierGuts<out Expression/*!*/ q>
-= (. Contract.Ensures(Contract.ValueAtReturn(out q) != null); IToken/*!*/ x = Token.NoToken;
- bool univ = false;
- List<BoundVar/*!*/> bvars;
- Attributes attrs;
- Expression range;
- Expression/*!*/ body;
- .)
- ( Forall (. x = t; univ = true; .)
- | Exists (. x = t; .)
- )
- QuantifierDomain<out bvars, out attrs, out range>
- QSep
- Expression<out body>
- (. if (univ) {
- q = new ForallExpr(x, bvars, range, body, attrs);
- } else {
- q = new ExistsExpr(x, bvars, range, body, attrs);
- }
- .)
- .
-
-Forall = "forall" | '\u2200'.
-Exists = "exists" | '\u2203'.
-QSep = "::" | '\u2022'.
-
-QuantifierDomain<.out List<BoundVar/*!*/> bvars, out Attributes attrs, out Expression range.>
-= (.
- bvars = new List<BoundVar/*!*/>();
- BoundVar/*!*/ bv;
- attrs = null;
- range = null;
- .)
- IdentTypeOptional<out bv> (. bvars.Add(bv); .)
- { ","
- IdentTypeOptional<out bv> (. bvars.Add(bv); .)
- }
- { Attribute<ref attrs> }
- [ "|"
- Expression<out range>
- ]
- .
-
-ComprehensionExpr<out Expression/*!*/ q>
-= (. Contract.Ensures(Contract.ValueAtReturn(out q) != null);
- IToken/*!*/ x = Token.NoToken;
- BoundVar/*!*/ bv;
- List<BoundVar/*!*/> bvars = new List<BoundVar/*!*/>();
- Expression/*!*/ range;
- Expression body = null;
- .)
- "set" (. x = t; .)
- IdentTypeOptional<out bv> (. bvars.Add(bv); .)
- { ","
- IdentTypeOptional<out bv> (. bvars.Add(bv); .)
- }
- "|" Expression<out range>
- [
- QSep
- Expression<out body>
- ]
- (. if (body == null && bvars.Count != 1) { SemErr(t, "a set comprehension with more than one bound variable must have a term expression"); }
- q = new SetComprehension(x, bvars, range, body);
- .)
- .
-Expressions<.List<Expression/*!*/>/*!*/ args.>
-= (. Contract.Requires(cce.NonNullElements(args)); Expression/*!*/ e; .)
- Expression<out e> (. args.Add(e); .)
- { "," Expression<out e> (. args.Add(e); .)
- }
- .
-/*------------------------------------------------------------------------*/
-Attribute<ref Attributes attrs>
-= "{"
- AttributeBody<ref attrs>
- "}"
- .
-AttributeBody<ref Attributes attrs>
-= (. string aName;
- List<Attributes.Argument/*!*/> aArgs = new List<Attributes.Argument/*!*/>();
- Attributes.Argument/*!*/ aArg;
- .)
- ":" ident (. aName = t.val; .)
- [ AttributeArg<out aArg> (. aArgs.Add(aArg); .)
- { "," AttributeArg<out aArg> (. aArgs.Add(aArg); .)
- }
- ] (. attrs = new Attributes(aName, aArgs, attrs); .)
- .
-AttributeArg<out Attributes.Argument/*!*/ arg>
-= (. Contract.Ensures(Contract.ValueAtReturn(out arg) != null); Expression/*!*/ e; arg = dummyAttrArg; .)
- ( string (. arg = new Attributes.Argument(t, t.val.Substring(1, t.val.Length-2)); .)
- | Expression<out e> (. arg = new Attributes.Argument(t, e); .)
- )
- .
-/*------------------------------------------------------------------------*/
-Ident<out IToken/*!*/ x>
-= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null); .)
- ident (. x = t; .)
- .
-// Identifier, disallowing leading underscores
-NoUSIdent<out IToken/*!*/ x>
-= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null); .)
- ident (. x = t;
- if (x.val.StartsWith("_")) {
- SemErr("cannot declare identifier beginning with underscore");
- }
- .)
- .
-
-// Identifier, disallowing leading underscores, except possibly the "wildcard" identifier "_"
-WildIdent<out IToken/*!*/ x, bool allowWildcardId>
-= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null); .)
- ident (. x = t;
- if (x.val.StartsWith("_")) {
- if (allowWildcardId && x.val.Length == 1) {
- t.val = "_v" + anonymousIds++;
- } else {
- SemErr("cannot declare identifier beginning with underscore");
- }
- }
- .)
- .
-
-Nat<out BigInteger n>
-=
- digits
- (. try {
- n = BigInteger.Parse(t.val);
- } catch (System.FormatException) {
- SemErr("incorrectly formatted number");
- n = BigInteger.Zero;
- }
- .)
- .
-END Dafny.
diff --git a/Source/Dafny/DafnyAst.cs b/Source/Dafny/DafnyAst.cs
deleted file mode 100644
index 345fc6fa..00000000
--- a/Source/Dafny/DafnyAst.cs
+++ /dev/null
@@ -1,4472 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Text;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Numerics;
-using Microsoft.Boogie;
-
-namespace Microsoft.Dafny {
- public class Program {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Name != null);
- Contract.Invariant(DefaultModule != null);
- }
-
- public readonly string Name;
- public List<ModuleDefinition/*!*/>/*!*/ Modules; // filled in during resolution.
- // Resolution essentially flattens the module hierarchy, for
- // purposes of translation and compilation.
- public List<ModuleDefinition> CompileModules; // filled in during resolution.
- // Contains the definitions to be used for compilation.
-
- public readonly ModuleDecl DefaultModule;
- public readonly ModuleDefinition DefaultModuleDef;
- public readonly BuiltIns BuiltIns;
- public readonly List<TranslationTask> TranslationTasks;
- public Program(string name, [Captured] ModuleDecl module, [Captured] BuiltIns builtIns) {
- Contract.Requires(name != null);
- Contract.Requires(module != null);
- Contract.Requires(module is LiteralModuleDecl);
- Name = name;
- DefaultModule = module;
- DefaultModuleDef = (DefaultModuleDecl)((LiteralModuleDecl)module).ModuleDef;
- BuiltIns = builtIns;
- Modules = new List<ModuleDefinition>();
- CompileModules = new List<ModuleDefinition>();
- TranslationTasks = new List<TranslationTask>();
- }
- }
-
- public class BuiltIns
- {
- public readonly ModuleDefinition SystemModule = new ModuleDefinition(Token.NoToken, "_System", false, false, null, null, true);
- Dictionary<int, ClassDecl/*!*/> arrayTypeDecls = new Dictionary<int, ClassDecl>();
- public readonly ClassDecl ObjectDecl;
- public BuiltIns() {
- // create class 'object'
- ObjectDecl = new ClassDecl(Token.NoToken, "object", SystemModule, new List<TypeParameter>(), new List<MemberDecl>(), null);
- SystemModule.TopLevelDecls.Add(ObjectDecl);
- // add one-dimensional arrays, since they may arise during type checking
- UserDefinedType tmp = ArrayType(Token.NoToken, 1, Type.Int, true);
- }
-
- public UserDefinedType ArrayType(int dims, Type arg) {
- return ArrayType(Token.NoToken, dims, arg, false);
- }
- public UserDefinedType ArrayType(IToken tok, int dims, Type arg, bool allowCreationOfNewClass) {
- Contract.Requires(tok != null);
- Contract.Requires(1 <= dims);
- Contract.Requires(arg != null);
- Contract.Ensures(Contract.Result<UserDefinedType>() != null);
-
- List<Type/*!*/> typeArgs = new List<Type/*!*/>();
- typeArgs.Add(arg);
- UserDefinedType udt = new UserDefinedType(tok, ArrayClassName(dims), typeArgs, null);
- if (allowCreationOfNewClass && !arrayTypeDecls.ContainsKey(dims)) {
- ArrayClassDecl arrayClass = new ArrayClassDecl(dims, SystemModule);
- for (int d = 0; d < dims; d++) {
- string name = dims == 1 ? "Length" : "Length" + d;
- string compiledName = dims == 1 ? "Length" : "GetLength(" + d + ")";
- Field len = new SpecialField(Token.NoToken, name, compiledName, "new BigInteger(", ")", false, false, false, Type.Int, null);
- len.EnclosingClass = arrayClass; // resolve here
- arrayClass.Members.Add(len);
- }
- arrayTypeDecls.Add(dims, arrayClass);
- SystemModule.TopLevelDecls.Add(arrayClass);
- }
- udt.ResolvedClass = arrayTypeDecls[dims];
- return udt;
- }
-
- public static string ArrayClassName(int dims) {
- Contract.Requires(1 <= dims);
- if (dims == 1) {
- return "array";
- } else {
- return "array" + dims;
- }
- }
- }
-
- public class Attributes {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Name != null);
- Contract.Invariant(cce.NonNullElements(Args));
- }
-
- public readonly string Name;
- /*Frozen*/
- public readonly List<Argument/*!*/>/*!*/ Args;
- public readonly Attributes Prev;
-
- public Attributes(string name, [Captured] List<Argument/*!*/>/*!*/ args, Attributes prev) {
- Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(args));
- Name = name;
- Args = args;
- Prev = prev;
- }
-
- public static bool Contains(Attributes attrs, string nm) {
- Contract.Requires(nm != null);
- for (; attrs != null; attrs = attrs.Prev) {
- if (attrs.Name == nm) {
- return true;
- }
- }
- return false;
- }
-
- /// <summary>
- /// Returns true if "nm" is a specified attribute. If it is, then:
- /// - if the attribute is {:nm true}, then value==true
- /// - if the attribute is {:nm false}, then value==false
- /// - if the attribute is anything else, then value returns as whatever it was passed in as.
- /// </summary>
- public static bool ContainsBool(Attributes attrs, string nm, ref bool value) {
- Contract.Requires(nm != null);
- for (; attrs != null; attrs = attrs.Prev) {
- if (attrs.Name == nm) {
- if (attrs.Args.Count == 1) {
- var arg = attrs.Args[0].E as LiteralExpr;
- if (arg != null && arg.Value is bool) {
- value = (bool)arg.Value;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- public class Argument
- {
- public readonly IToken Tok;
- public readonly string S;
- public readonly Expression E;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Tok != null);
- Contract.Invariant((S == null) != (E == null));
- }
-
- public Argument(IToken tok, string s) {
- Contract.Requires(tok != null);
- Contract.Requires(s != null);
- Tok = tok;
- S = s;
- }
- public Argument(IToken tok, Expression e) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Tok = tok;
- E = e;
- }
- }
- }
-
- // ------------------------------------------------------------------------------------------------------
-
- public abstract class Type {
- public static readonly BoolType Bool = new BoolType();
- public static readonly IntType Int = new IntType();
- /// <summary>
- /// Used in error situations in order to reduce further error messages.
- /// </summary>
- //[Pure(false)]
- public static Type Flexible {
- get {
- Contract.Ensures(Contract.Result<Type>() != null);
- return new InferredTypeProxy();
- }
- }
-
- [Pure]
- public abstract string TypeName(ModuleDefinition/*?*/ context);
- [Pure]
- public override string ToString() {
- return TypeName(null);
- }
-
- /// <summary>
- /// Return the most constrained version of "this".
- /// </summary>
- /// <returns></returns>
- public Type Normalize() {
- Contract.Ensures(Contract.Result<Type>() != null);
- Type type = this;
- while (true) {
- TypeProxy pt = type as TypeProxy;
- if (pt != null && pt.T != null) {
- type = pt.T;
- } else {
- return type;
- }
- }
- }
-
- public bool IsSubrangeType {
- get { return this is NatType; }
- }
-
- public bool IsRefType {
- get {
- if (this is ObjectType) {
- return true;
- } else {
- UserDefinedType udt = this as UserDefinedType;
- return udt != null && udt.ResolvedParam == null && udt.ResolvedClass is ClassDecl;
- }
- }
- }
- public bool IsArrayType {
- get {
- return AsArrayType != null;
- }
- }
- public ArrayClassDecl/*?*/ AsArrayType {
- get {
- UserDefinedType udt = UserDefinedType.DenotesClass(this);
- return udt == null ? null : udt.ResolvedClass as ArrayClassDecl;
- }
- }
- public bool IsDatatype {
- get {
- return AsDatatype != null;
- }
- }
- public DatatypeDecl AsDatatype {
- get {
- UserDefinedType udt = this as UserDefinedType;
- if (udt == null) {
- return null;
- } else {
- return udt.ResolvedClass as DatatypeDecl;
- }
- }
- }
- public bool IsIndDatatype {
- get {
- return AsIndDatatype != null;
- }
- }
- public IndDatatypeDecl AsIndDatatype {
- get {
- UserDefinedType udt = this as UserDefinedType;
- if (udt == null) {
- return null;
- } else {
- return udt.ResolvedClass as IndDatatypeDecl;
- }
- }
- }
- public bool IsCoDatatype {
- get {
- return AsCoDatatype != null;
- }
- }
- public CoDatatypeDecl AsCoDatatype {
- get {
- UserDefinedType udt = this as UserDefinedType;
- if (udt == null) {
- return null;
- } else {
- return udt.ResolvedClass as CoDatatypeDecl;
- }
- }
- }
- public bool InvolvesCoDatatype {
- get {
- return IsCoDatatype; // TODO: should really check structure of the type recursively
- }
- }
- public bool IsTypeParameter {
- get {
- return AsTypeParameter != null;
- }
- }
- public TypeParameter AsTypeParameter {
- get {
- UserDefinedType ct = this as UserDefinedType;
- return ct == null ? null : ct.ResolvedParam;
- }
- }
- public virtual bool SupportsEquality {
- get {
- return true;
- }
- }
- }
-
- /// <summary>
- /// A NonProxy type is a fully constrained type. It may contain members.
- /// </summary>
- public abstract class NonProxyType : Type
- {
- }
-
- public abstract class BasicType : NonProxyType
- {
- }
-
- public class BoolType : BasicType {
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- return "bool";
- }
- }
-
- public class IntType : BasicType {
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- return "int";
- }
- }
-
- public class NatType : IntType
- {
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- return "nat";
- }
- }
-
- public class ObjectType : BasicType
- {
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- return "object";
- }
- }
-
- public abstract class CollectionType : NonProxyType
- {
- public readonly Type Arg; // denotes the Domain type for a Map
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Arg != null);
- }
- public CollectionType(Type arg) {
- Contract.Requires(arg != null);
- this.Arg = arg;
- }
- public override bool SupportsEquality {
- get {
- return Arg.SupportsEquality;
- }
- }
- }
-
- public class SetType : CollectionType {
- public SetType(Type arg) : base(arg) {
- Contract.Requires(arg != null);
- }
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- Contract.Ensures(Contract.Result<string>() != null);
- Contract.Assume(cce.IsPeerConsistent(Arg));
- return "set<" + base.Arg.TypeName(context) + ">";
- }
- }
-
- public class MultiSetType : CollectionType
- {
- public MultiSetType(Type arg) : base(arg) {
- Contract.Requires(arg != null);
- }
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- Contract.Ensures(Contract.Result<string>() != null);
- Contract.Assume(cce.IsPeerConsistent(Arg));
- return "multiset<" + base.Arg.TypeName(context) + ">";
- }
- }
-
- public class SeqType : CollectionType {
- public SeqType(Type arg) : base(arg) {
- Contract.Requires(arg != null);
-
- }
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- Contract.Ensures(Contract.Result<string>() != null);
- Contract.Assume(cce.IsPeerConsistent(Arg));
- return "seq<" + base.Arg.TypeName(context) + ">";
- }
- }
- public class MapType : CollectionType
- {
- public Type Range;
- public MapType(Type domain, Type range) : base(domain) {
- Contract.Requires(domain != null && range != null);
- Range = range;
- }
- public Type Domain {
- get { return Arg; }
- }
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- Contract.Ensures(Contract.Result<string>() != null);
- Contract.Assume(cce.IsPeerConsistent(Domain));
- Contract.Assume(cce.IsPeerConsistent(Range));
- return "map<" + Domain.TypeName(context) + ", " + Range.TypeName(context) + ">";
- }
- }
-
- public class UserDefinedType : NonProxyType
- {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(tok != null);
- Contract.Invariant(Name != null);
- Contract.Invariant(cce.NonNullElements(TypeArgs));
- Contract.Invariant(cce.NonNullElements(Path));
- }
-
- public readonly List<IToken> Path; // may be null
- public readonly IToken tok; // token of the Name
- public readonly string Name;
- [Rep]
- public readonly List<Type/*!*/>/*!*/ TypeArgs;
-
- public string FullName {
- get {
- if (ResolvedClass != null && !ResolvedClass.Module.IsDefaultModule) {
- return ResolvedClass.Module.Name + "." + Name;
- } else {
- return Name;
- }
- }
- }
-
- string compileName;
- public string CompileName {
- get {
- if (compileName == null) {
- compileName = NonglobalVariable.CompilerizeName(Name);
- }
- return compileName;
- }
- }
- public string FullCompileName {
- get {
- if (ResolvedClass != null && !ResolvedClass.Module.IsDefaultModule) {
- return ResolvedClass.Module.CompileName + "." + CompileName;
- } else {
- return CompileName;
- }
- }
- }
-
- public TopLevelDecl ResolvedClass; // filled in by resolution, if Name denotes a class/datatype/iterator and TypeArgs match the type parameters of that class/datatype/iterator
- public TypeParameter ResolvedParam; // filled in by resolution, if Name denotes an enclosing type parameter and TypeArgs is the empty list
-
- public UserDefinedType(IToken/*!*/ tok, string/*!*/ name, [Captured] List<Type/*!*/>/*!*/ typeArgs, List<IToken> moduleName) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(moduleName == null || cce.NonNullElements(moduleName));
- if (moduleName != null) this.Path = moduleName;
- else this.Path = new List<IToken>();
- this.tok = tok;
- this.Name = name;
- this.TypeArgs = typeArgs;
- }
-
- /// <summary>
- /// This constructor constructs a resolved class/datatype/iterator type
- /// </summary>
- public UserDefinedType(IToken/*!*/ tok, string/*!*/ name, TopLevelDecl/*!*/ cd, [Captured] List<Type/*!*/>/*!*/ typeArgs) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(cd != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- this.tok = tok;
- this.Name = name;
- this.TypeArgs = typeArgs;
- this.ResolvedClass = cd;
- this.Path = new List<IToken>();
- }
-
- /// <summary>
- /// This constructor constructs a resolved type parameter
- /// </summary>
- public UserDefinedType(IToken/*!*/ tok, string/*!*/ name, TypeParameter/*!*/ tp) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(tp != null);
- this.tok = tok;
- this.Name = name;
- this.TypeArgs = new List<Type/*!*/>();
- this.ResolvedParam = tp;
- this.Path = new List<IToken>();
- }
-
- /// <summary>
- /// If type denotes a resolved class type, then return that class type.
- /// Otherwise, return null.
- /// </summary>
- public static UserDefinedType DenotesClass(Type/*!*/ type) {
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<UserDefinedType>() == null || Contract.Result<UserDefinedType>().ResolvedClass is ClassDecl);
- type = type.Normalize();
- UserDefinedType ct = type as UserDefinedType;
- if (ct != null && ct.ResolvedClass is ClassDecl) {
- return ct;
- } else {
- return null;
- }
- }
-
- public static Type ArrayElementType(Type type) {
- Contract.Requires(type.IsArrayType);
-
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<Type>() != null);
-
- UserDefinedType udt = DenotesClass(type);
- Contract.Assert(udt != null);
- Contract.Assert(udt.TypeArgs.Count == 1); // holds true of all array types
- return udt.TypeArgs[0];
- }
-
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- Contract.Ensures(Contract.Result<string>() != null);
- string s = "";
- foreach (var t in Path) {
- if (context != null && t == context.tok) {
- // drop the prefix up to here
- s = "";
- } else {
- s += t.val + ".";
- }
- }
- s += Name;
- if (TypeArgs.Count != 0) {
- s += "<" + Util.Comma(",", TypeArgs, ty => ty.TypeName(context)) + ">";
- }
- return s;
- }
-
- public override bool SupportsEquality {
- get {
- if (ResolvedClass is ClassDecl) {
- return true;
- } else if (ResolvedClass is CoDatatypeDecl) {
- return false;
- } else if (ResolvedClass is IndDatatypeDecl) {
- var dt = (IndDatatypeDecl)ResolvedClass;
- Contract.Assume(dt.EqualitySupport != IndDatatypeDecl.ES.NotYetComputed);
- if (dt.EqualitySupport == IndDatatypeDecl.ES.Never) {
- return false;
- }
- Contract.Assert(dt.TypeArgs.Count == TypeArgs.Count);
- var i = 0;
- foreach (var tp in dt.TypeArgs) {
- if (tp.NecessaryForEqualitySupportOfSurroundingInductiveDatatype && !TypeArgs[i].SupportsEquality) {
- return false;
- }
- i++;
- }
- return true;
- } else if (ResolvedParam != null) {
- return ResolvedParam.MustSupportEquality;
- }
- Contract.Assume(false); // the SupportsEquality getter requires the Type to have been successfully resolved
- return true;
- }
- }
- }
-
- public abstract class TypeProxy : Type {
- public Type T; // filled in during resolution
- internal TypeProxy() {
- }
-
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- Contract.Ensures(Contract.Result<string>() != null);
-
- Contract.Assume(T == null || cce.IsPeerConsistent(T));
- return T == null ? "?" : T.TypeName(context);
- }
- public override bool SupportsEquality {
- get {
- if (T != null) {
- return T.SupportsEquality;
- } else {
- return base.SupportsEquality;
- }
- }
- }
- }
-
- public abstract class UnrestrictedTypeProxy : TypeProxy {
- }
-
- /// <summary>
- /// This proxy stands for any type.
- /// </summary>
- public class InferredTypeProxy : UnrestrictedTypeProxy {
- }
-
- /// <summary>
- /// This proxy stands for any type, but it originates from an instantiated type parameter.
- /// </summary>
- public class ParamTypeProxy : UnrestrictedTypeProxy {
- public TypeParameter orig;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(orig != null);
- }
-
- public ParamTypeProxy(TypeParameter orig) {
- Contract.Requires(orig != null);
- this.orig = orig;
- }
- }
-
- public abstract class RestrictedTypeProxy : TypeProxy {
- /// <summary>
- /// The OrderID is used to simplify the unification code. Each restricted type proxy should use its
- /// own OrderID.
- /// </summary>
- public abstract int OrderID {
- get;
- }
- }
-
- /// <summary>
- /// This proxy stands for any datatype.
- /// </summary>
- public class DatatypeProxy : RestrictedTypeProxy {
- public override int OrderID {
- get {
- return 0;
- }
- }
- }
-
- /// <summary>
- /// This proxy stands for object or any class/array type.
- /// </summary>
- public class ObjectTypeProxy : RestrictedTypeProxy {
- public override int OrderID {
- get {
- return 1;
- }
- }
- }
-
- /// <summary>
- /// This proxy stands for:
- /// set(Arg) or seq(Arg) or map(Arg, Range)
- /// </summary>
- public class CollectionTypeProxy : RestrictedTypeProxy {
- public readonly Type Arg;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Arg != null);
- }
-
- public CollectionTypeProxy(Type arg) {
- Contract.Requires(arg != null);
- Arg = arg;
- }
- public override int OrderID {
- get {
- return 2;
- }
- }
- }
-
- /// <summary>
- /// This proxy stands for either:
- /// int or set or multiset or seq
- /// if AllowSeq, or:
- /// int or set or multiset
- /// if !AllowSeq.
- /// </summary>
- public class OperationTypeProxy : RestrictedTypeProxy {
- public readonly bool AllowSeq;
- public OperationTypeProxy(bool allowSeq) {
- AllowSeq = allowSeq;
- }
- public override int OrderID {
- get {
- return 3;
- }
- }
- }
-
- /// <summary>
- /// This proxy stands for:
- /// seq(Arg) or array(Arg) or map(Arg, Range)
- /// </summary>
- public class IndexableTypeProxy : RestrictedTypeProxy {
- public readonly Type Arg, Domain;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Arg != null);
- }
-
- public IndexableTypeProxy(Type arg, Type domain) {
- Contract.Requires(arg != null);
- Arg = arg;
- Domain = domain;
- }
- public override int OrderID {
- get {
- return 4;
- }
- }
- }
-
- // ------------------------------------------------------------------------------------------------------
-
- public abstract class Declaration {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(tok != null);
- Contract.Invariant(Name != null);
- }
-
- public IToken/*!*/ tok;
- public IToken BodyStartTok = Token.NoToken;
- public IToken BodyEndTok = Token.NoToken;
- public readonly string/*!*/ Name;
- string compileName;
- public virtual string CompileName {
- get {
- if (compileName == null) {
- compileName = NonglobalVariable.CompilerizeName(Name);
- }
- return compileName;
- }
- }
- public readonly Attributes Attributes;
-
- public Declaration(IToken tok, string name, Attributes attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- this.tok = tok;
- this.Name = name;
- this.Attributes = attributes;
- }
-
- [Pure]
- public override string ToString() {
- Contract.Ensures(Contract.Result<string>() != null);
- return Name;
- }
- }
-
- public class TypeParameter : Declaration {
- public interface ParentType {
- }
- [Peer]
- ParentType parent;
- public ParentType Parent {
- get {
- return parent;
- }
- [param: Captured]
- set {
- Contract.Requires(Parent == null); // set it only once
- Contract.Requires(value != null);
- // BUGBUG: The following line is a workaround to tell the verifier that 'value' is not of an Immutable type.
- // A proper solution would be to be able to express that in the program (in a specification or attribute) or
- // to be able to declare 'parent' as [PeerOrImmutable].
- Contract.Requires(value is TopLevelDecl || value is Function || value is Method || value is DatatypeCtor);
- //modifies parent;
- parent = value;
- }
- }
- public enum EqualitySupportValue { Required, InferredRequired, Unspecified }
- public EqualitySupportValue EqualitySupport; // the resolver may change this value from Unspecified to InferredRequired (for some signatures that may immediately imply that equality support is required)
- public bool MustSupportEquality {
- get { return EqualitySupport != EqualitySupportValue.Unspecified; }
- }
-
- public bool NecessaryForEqualitySupportOfSurroundingInductiveDatatype = false; // computed during resolution; relevant only when Parent denotes an IndDatatypeDecl
-
- public bool IsAbstractTypeDeclaration { // true if this type parameter represents t in type t;
- get { return parent == null; }
- }
- public bool IsToplevelScope { // true if this type parameter is on a toplevel (ie. class C<T>), and false if it is on a member (ie. method m<T>(...))
- get { return parent is TopLevelDecl; }
- }
- public int PositionalIndex; // which type parameter this is (ie. in C<S, T, U>, S is 0, T is 1 and U is 2).
-
- public TypeParameter(IToken tok, string name, EqualitySupportValue equalitySupport = EqualitySupportValue.Unspecified)
- : base(tok, name, null) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- EqualitySupport = equalitySupport;
- }
- }
-
- // Represents a submodule declaration at module level scope
- abstract public class ModuleDecl : TopLevelDecl
- {
- public ModuleSignature Signature; // filled in by resolution, in topological order.
- public int Height;
- public readonly bool Opened;
- public ModuleDecl(IToken tok, string name, ModuleDefinition parent, bool opened)
- : base(tok, name, parent, new List<TypeParameter>(), null) {
- Height = -1;
- Signature = null;
- Opened = opened;
- }
- }
- // Represents module X { ... }
- public class LiteralModuleDecl : ModuleDecl
- {
- public readonly ModuleDefinition ModuleDef;
- public LiteralModuleDecl(ModuleDefinition module, ModuleDefinition parent)
- : base(module.tok, module.Name, parent, false) {
- ModuleDef = module;
- }
- }
- // Represents "module name = path;", where name is a identifier and path is a possibly qualified name.
- public class AliasModuleDecl : ModuleDecl
- {
- public ModuleDecl ModuleReference; // should refer to another declaration somewhere. NOTE: cyclicity is possible, and should
- // be detected and warned.
- public readonly List<IToken> Path; // generated by the parser, this is looked up
- public ModuleDecl Root; // the moduleDecl that Path[0] refers to.
- public AliasModuleDecl(List<IToken> path, IToken name, ModuleDefinition parent, bool opened)
- : base(name, name.val, parent, opened) {
- Contract.Requires(path != null && path.Count > 0);
- Path = path;
- ModuleReference = null;
- }
- }
- // Represents "module name as path [ = compilePath];", where name is a identifier and path is a possibly qualified name.
- public class AbstractModuleDecl : ModuleDecl
- {
- public ModuleDecl Root;
- public readonly List<IToken> Path;
- public ModuleDecl CompileRoot;
- public readonly List<IToken> CompilePath;
- public ModuleSignature OriginalSignature;
-
- public AbstractModuleDecl(List<IToken> path, IToken name, ModuleDefinition parent, List<IToken> compilePath, bool opened)
- : base(name, name.val, parent, opened) {
- Path = path;
- Root = null;
- CompilePath = compilePath;
- }
- }
-
- public class ModuleSignature {
-
- public readonly Dictionary<string, TopLevelDecl> TopLevels = new Dictionary<string, TopLevelDecl>();
- public readonly Dictionary<string, Tuple<DatatypeCtor, bool>> Ctors = new Dictionary<string, Tuple<DatatypeCtor, bool>>();
- public readonly Dictionary<string, MemberDecl> StaticMembers = new Dictionary<string, MemberDecl>();
- public ModuleDefinition ModuleDef = null; // Note: this is null if this signature does not correspond to a specific definition (i.e.
- // it is abstract). Otherwise, it points to that definition.
- public ModuleSignature CompileSignature = null; // This is the version of the signature that should be used at compile time.
- public ModuleSignature Refines = null;
- public bool IsGhost = false;
- public ModuleSignature() {}
-
- public bool FindSubmodule(string name, out ModuleSignature pp) {
- TopLevelDecl top;
- pp = null;
- if (TopLevels.TryGetValue(name, out top)) {
- if (top is ModuleDecl) {
- pp = ((ModuleDecl)top).Signature;
- return true;
- } else return false;
- } else return false;
- }
-
-
- }
- public class ModuleDefinition : Declaration {
- public readonly List<IToken> RefinementBaseName; // null if no refinement base
- public ModuleDecl RefinementBaseRoot; // filled in early during resolution, corresponds to RefinementBaseName[0]
- public ModuleDefinition RefinementBase; // filled in during resolution (null if no refinement base)
-
- public readonly List<TopLevelDecl/*!*/> TopLevelDecls = new List<TopLevelDecl/*!*/>(); // filled in by the parser; readonly after that
- public readonly Graph<MemberDecl/*!*/> CallGraph = new Graph<MemberDecl/*!*/>(); // filled in during resolution
- public int Height; // height in the topological sorting of modules; filled in during resolution
- public readonly bool IsGhost;
- public readonly bool IsAbstract; // True iff this module represents an abstract interface
- private readonly bool IsBuiltinName; // true if this is something like _System that shouldn't have it's name mangled.
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(TopLevelDecls));
- Contract.Invariant(CallGraph != null);
- }
-
- public ModuleDefinition(IToken tok, string name, bool isGhost, bool isAbstract, List<IToken> refinementBase, Attributes attributes, bool isBuiltinName)
- : base(tok, name, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- RefinementBaseName = refinementBase;
- IsGhost = isGhost;
- IsAbstract = isAbstract;
- RefinementBaseRoot = null;
- RefinementBase = null;
- IsBuiltinName = isBuiltinName;
- }
- public virtual bool IsDefaultModule {
- get {
- return false;
- }
- }
- string compileName;
- new public string CompileName {
- get {
- if (compileName == null) {
- if (IsBuiltinName)
- compileName = Name;
- else
- compileName = "_" + Height.ToString() + "_" + NonglobalVariable.CompilerizeName(Name);
- }
- return compileName;
- }
- }
-
- public static IEnumerable<Function> AllFunctions(List<TopLevelDecl> declarations) {
- foreach (var d in declarations) {
- var cl = d as ClassDecl;
- if (cl != null) {
- foreach (var member in cl.Members) {
- var fn = member as Function;
- if (fn != null) {
- yield return fn;
- }
- }
- }
- }
- }
- }
-
- public class DefaultModuleDecl : ModuleDefinition {
- public DefaultModuleDecl() : base(Token.NoToken, "_module", false, false, null, null, true) {
- }
- public override bool IsDefaultModule {
- get {
- return true;
- }
- }
- }
-
- public abstract class TopLevelDecl : Declaration, TypeParameter.ParentType {
- public readonly ModuleDefinition Module;
- public readonly List<TypeParameter/*!*/>/*!*/ TypeArgs;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(TypeArgs));
- }
-
- public TopLevelDecl(IToken/*!*/ tok, string/*!*/ name, ModuleDefinition module, List<TypeParameter/*!*/>/*!*/ typeArgs, Attributes attributes)
- : base(tok, name, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Module = module;
- TypeArgs = typeArgs;
- }
-
- public string FullName {
- get {
- return Module.Name + "." + Name;
- }
- }
- public string FullNameInContext(ModuleDefinition context) {
- if (Module == context) {
- return Name;
- } else {
- return Module.Name + "." + Name;
- }
- }
- public string FullCompileName {
- get {
- return Module.CompileName + "." + CompileName;
- }
- }
- }
-
- public class ClassDecl : TopLevelDecl {
- public readonly List<MemberDecl/*!*/>/*!*/ Members;
- public bool HasConstructor; // filled in (early) during resolution; true iff there exists a member that is a Constructor
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Members));
- }
-
- public ClassDecl(IToken/*!*/ tok, string/*!*/ name, ModuleDefinition/*!*/ module,
- List<TypeParameter/*!*/>/*!*/ typeArgs, [Captured] List<MemberDecl/*!*/>/*!*/ members, Attributes attributes)
- : base(tok, name, module, typeArgs, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(module != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(cce.NonNullElements(members));
- Members = members;
- }
- public virtual bool IsDefaultClass {
- get {
- return false;
- }
- }
- }
-
- public class DefaultClassDecl : ClassDecl {
- public DefaultClassDecl(ModuleDefinition/*!*/ module, [Captured] List<MemberDecl/*!*/>/*!*/ members)
- : base(Token.NoToken, "_default", module, new List<TypeParameter/*!*/>(), members, null) {
- Contract.Requires(module != null);
- Contract.Requires(cce.NonNullElements(members));
- }
- public override bool IsDefaultClass {
- get {
- return true;
- }
- }
- }
-
- public class ArrayClassDecl : ClassDecl {
- public readonly int Dims;
- public ArrayClassDecl(int dims, ModuleDefinition module)
- : base(Token.NoToken, BuiltIns.ArrayClassName(dims), module,
- new List<TypeParameter>(new TypeParameter[]{new TypeParameter(Token.NoToken, "arg")}),
- new List<MemberDecl>(), null)
- {
- Contract.Requires(1 <= dims);
- Contract.Requires(module != null);
-
- Dims = dims;
- }
- }
-
- public abstract class DatatypeDecl : TopLevelDecl {
- public readonly List<DatatypeCtor/*!*/>/*!*/ Ctors;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Ctors));
- Contract.Invariant(1 <= Ctors.Count);
- }
-
- public DatatypeDecl(IToken/*!*/ tok, string/*!*/ name, ModuleDefinition/*!*/ module, List<TypeParameter/*!*/>/*!*/ typeArgs,
- [Captured] List<DatatypeCtor/*!*/>/*!*/ ctors, Attributes attributes)
- : base(tok, name, module, typeArgs, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(module != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(cce.NonNullElements(ctors));
- Contract.Requires(1 <= ctors.Count);
- Ctors = ctors;
- }
- public bool HasFinitePossibleValues {
- get {
- return (TypeArgs.Count == 0 && Ctors.TrueForAll(ctr => ctr.Formals.Count == 0));
- }
- }
- }
-
- public class IndDatatypeDecl : DatatypeDecl
- {
- public DatatypeCtor DefaultCtor; // set during resolution
- public bool[] TypeParametersUsedInConstructionByDefaultCtor; // set during resolution; has same length as the number of type arguments
-
- public enum ES { NotYetComputed, Never, ConsultTypeArguments }
- public ES EqualitySupport = ES.NotYetComputed;
-
- public IndDatatypeDecl(IToken/*!*/ tok, string/*!*/ name, ModuleDefinition/*!*/ module, List<TypeParameter/*!*/>/*!*/ typeArgs,
- [Captured] List<DatatypeCtor/*!*/>/*!*/ ctors, Attributes attributes)
- : base(tok, name, module, typeArgs, ctors, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(module != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(cce.NonNullElements(ctors));
- Contract.Requires(1 <= ctors.Count);
- }
- }
-
- public class CoDatatypeDecl : DatatypeDecl
- {
- public CoDatatypeDecl(IToken/*!*/ tok, string/*!*/ name, ModuleDefinition/*!*/ module, List<TypeParameter/*!*/>/*!*/ typeArgs,
- [Captured] List<DatatypeCtor/*!*/>/*!*/ ctors, Attributes attributes)
- : base(tok, name, module, typeArgs, ctors, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(module != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(cce.NonNullElements(ctors));
- Contract.Requires(1 <= ctors.Count);
- }
- }
-
- public class DatatypeCtor : Declaration, TypeParameter.ParentType
- {
- public readonly List<Formal/*!*/>/*!*/ Formals;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Formals));
- Contract.Invariant(Destructors != null);
- Contract.Invariant(
- Destructors.Count == 0 || // this is until resolution
- Destructors.Count == Formals.Count); // after resolution
- }
-
- // TODO: One could imagine having a precondition on datatype constructors
- public DatatypeDecl EnclosingDatatype; // filled in during resolution
- public SpecialField QueryField; // filled in during resolution
- public List<SpecialField/*may be null*/> Destructors = new List<SpecialField/*may be null*/>(); // contents filled in during resolution
-
- public DatatypeCtor(IToken/*!*/ tok, string/*!*/ name, [Captured] List<Formal/*!*/>/*!*/ formals, Attributes attributes)
- : base(tok, name, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(formals));
- this.Formals = formals;
- }
-
- public string FullName {
- get {
- Contract.Requires(EnclosingDatatype != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return "#" + EnclosingDatatype.FullCompileName + "." + Name;
- }
- }
- }
-
- public interface ICodeContext : ICallable
- {
- bool IsGhost { get; }
- bool IsStatic { get; }
- List<TypeParameter> TypeArgs { get; }
- List<Formal> Ins { get ; }
- List<Formal> Outs { get; }
- Specification<FrameExpression> Modifies { get; }
- Specification<Expression> Decreases { get; }
- ModuleDefinition EnclosingModule { get; } // to be called only after signature-resolution is complete
- bool MustReverify { get; }
- }
-
- public class IteratorDecl : ClassDecl, ICodeContext
- {
- public readonly List<Formal> Ins;
- public readonly List<Formal> Outs;
- public readonly Specification<FrameExpression> Reads;
- public readonly Specification<FrameExpression> Modifies;
- public readonly Specification<Expression> Decreases;
- public bool InferredDecreases; // fill in during resolution/registration
- public readonly List<MaybeFreeExpression> Requires;
- public readonly List<MaybeFreeExpression> Ensures;
- public readonly List<MaybeFreeExpression> YieldRequires;
- public readonly List<MaybeFreeExpression> YieldEnsures;
- public readonly BlockStmt Body;
- public readonly bool SignatureIsOmitted;
- public readonly List<Field> OutsFields;
- public readonly List<Field> OutsHistoryFields; // these are the 'xs' variables
- public readonly List<Field> DecreasesFields; // filled in during resolution
- public SpecialField Member_Modifies; // filled in during resolution
- public SpecialField Member_Reads; // filled in during resolution
- public SpecialField Member_New; // filled in during resolution
- public Constructor Member_Init; // created during registration phase of resolution; its specification is filled in during resolution
- public Predicate Member_Valid; // created during registration phase of resolution; its specification is filled in during resolution
- public Method Member_MoveNext; // created during registration phase of resolution; its specification is filled in during resolution
- public IteratorDecl(IToken tok, string name, ModuleDefinition module, List<TypeParameter> typeArgs,
- List<Formal> ins, List<Formal> outs,
- Specification<FrameExpression> reads, Specification<FrameExpression> mod, Specification<Expression> decreases,
- List<MaybeFreeExpression> requires,
- List<MaybeFreeExpression> ensures,
- List<MaybeFreeExpression> yieldRequires,
- List<MaybeFreeExpression> yieldEnsures,
- BlockStmt body, Attributes attributes, bool signatureIsOmitted)
- : base(tok, name, module, typeArgs, new List<MemberDecl>(), attributes)
- {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(module != null);
- Contract.Requires(typeArgs != null);
- Contract.Requires(ins != null);
- Contract.Requires(outs != null);
- Contract.Requires(reads != null);
- Contract.Requires(mod != null);
- Contract.Requires(decreases != null);
- Contract.Requires(requires != null);
- Contract.Requires(ensures != null);
- Contract.Requires(yieldRequires != null);
- Contract.Requires(yieldEnsures != null);
- Ins = ins;
- Outs = outs;
- Reads = reads;
- Modifies = mod;
- Decreases = decreases;
- Requires = requires;
- Ensures = ensures;
- YieldRequires = yieldRequires;
- YieldEnsures = yieldEnsures;
- Body = body;
- SignatureIsOmitted = signatureIsOmitted;
-
- OutsFields = new List<Field>();
- OutsHistoryFields = new List<Field>();
- DecreasesFields = new List<Field>();
- }
-
- bool ICodeContext.IsGhost { get { return false; } }
- bool ICodeContext.IsStatic { get { return true; } }
- List<TypeParameter> ICodeContext.TypeArgs { get { return this.TypeArgs; } }
- List<Formal> ICodeContext.Ins { get { return this.Ins; } }
- List<Formal> ICodeContext.Outs { get { return this.Outs; } }
- Specification<FrameExpression> ICodeContext.Modifies { get { return this.Modifies; } }
- Specification<Expression> ICodeContext.Decreases { get { return this.Decreases; } }
- ModuleDefinition ICodeContext.EnclosingModule { get { return this.Module; } }
- bool ICodeContext.MustReverify { get { return false; } }
- }
-
- /// <summary>
- /// An "ICallable" is a function, method, or iterator.
- /// </summary>
- public interface ICallable { }
-
- public abstract class MemberDecl : Declaration {
- public readonly bool IsStatic;
- public readonly bool IsGhost;
- public TopLevelDecl EnclosingClass; // filled in during resolution
-
- public MemberDecl(IToken tok, string name, bool isStatic, bool isGhost, Attributes attributes)
- : base(tok, name, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- IsStatic = isStatic;
- IsGhost = isGhost;
- }
- /// <summary>
- /// Returns className+"."+memberName. Available only after resolution.
- /// </summary>
- public string FullName {
- get {
- Contract.Requires(EnclosingClass != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return EnclosingClass.FullName + "." + Name;
- }
- }
- public string FullNameInContext(ModuleDefinition context) {
- Contract.Requires(EnclosingClass != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return EnclosingClass.FullNameInContext(context) + "." + Name;
- }
- public override string CompileName {
- get {
- var nm = base.CompileName;
- if (this.Name == EnclosingClass.Name) {
- nm = "_" + nm;
- }
- return nm;
- }
- }
- public string FullCompileName {
- get {
- Contract.Requires(EnclosingClass != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return EnclosingClass.FullCompileName + "." + CompileName;
- }
- }
- }
-
- public class Field : MemberDecl {
- public readonly bool IsMutable; // says whether or not the field can ever change values
- public readonly bool IsUserMutable; // says whether or not code is allowed to assign to the field (IsUserMutable implies IsMutable)
- public readonly Type Type;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Type != null);
- Contract.Invariant(!IsUserMutable || IsMutable); // IsUserMutable ==> IsMutable
- }
-
- public Field(IToken tok, string name, bool isGhost, Type type, Attributes attributes)
- : this(tok, name, isGhost, true, true, type, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(type != null);
- }
-
- public Field(IToken tok, string name, bool isGhost, bool isMutable, bool isUserMutable, Type type, Attributes attributes)
- : base(tok, name, false, isGhost, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(type != null);
- Contract.Requires(!isUserMutable || isMutable);
- IsMutable = isMutable;
- IsUserMutable = isUserMutable;
- Type = type;
- }
- }
-
- public class SpecialField : Field
- {
- public readonly string CompiledName;
- public readonly string PreString;
- public readonly string PostString;
- public SpecialField(IToken tok, string name, string compiledName, string preString, string postString, bool isGhost, bool isMutable, bool isUserMutable, Type type, Attributes attributes)
- : base(tok, name, isGhost, isMutable, isUserMutable, type, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(compiledName != null);
- Contract.Requires(preString != null);
- Contract.Requires(postString != null);
- Contract.Requires(!isUserMutable || isMutable);
- Contract.Requires(type != null);
-
- CompiledName = compiledName;
- PreString = preString;
- PostString = postString;
- }
- }
-
- public class DatatypeDestructor : SpecialField
- {
- public readonly DatatypeCtor EnclosingCtor;
- public readonly Formal CorrespondingFormal;
-
- public DatatypeDestructor(IToken tok, DatatypeCtor enclosingCtor, Formal correspondingFormal, string name, string compiledName, string preString, string postString, bool isGhost, Type type, Attributes attributes)
- : base(tok, name, compiledName, preString, postString, isGhost, false, false, type, attributes)
- {
- Contract.Requires(tok != null);
- Contract.Requires(enclosingCtor != null);
- Contract.Requires(correspondingFormal != null);
- Contract.Requires(name != null);
- Contract.Requires(compiledName != null);
- Contract.Requires(preString != null);
- Contract.Requires(postString != null);
- Contract.Requires(type != null);
- EnclosingCtor = enclosingCtor;
- CorrespondingFormal = correspondingFormal;
- }
- }
-
- public class ArbitraryTypeDecl : TopLevelDecl, TypeParameter.ParentType
- {
- public readonly TypeParameter TheType;
- public TypeParameter.EqualitySupportValue EqualitySupport {
- get { return TheType.EqualitySupport; }
- }
- public bool MustSupportEquality {
- get { return TheType.MustSupportEquality; }
- }
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(TheType != null && Name == TheType.Name);
- }
-
- public ArbitraryTypeDecl(IToken/*!*/ tok, string/*!*/ name, ModuleDefinition/*!*/ module, TypeParameter.EqualitySupportValue equalitySupport, Attributes attributes)
- : base(tok, name, module, new List<TypeParameter>(), attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(module != null);
- TheType = new TypeParameter(tok, name, equalitySupport);
- }
- }
-
- [ContractClass(typeof(IVariableContracts))]
- public interface IVariable {
- string/*!*/ Name {
- get;
- }
- string/*!*/ DisplayName { // what the user thinks he wrote
- get;
- }
- string/*!*/ UniqueName {
- get;
- }
- string/*!*/ CompileName {
- get;
- }
- Type/*!*/ Type {
- get;
- }
- bool IsMutable {
- get;
- }
- bool IsGhost {
- get;
- }
- }
- [ContractClassFor(typeof(IVariable))]
- public abstract class IVariableContracts : IVariable {
- public string Name {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
- }
- }
- public string DisplayName {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
- }
- }
- public string UniqueName {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
- }
- }
- public string CompileName {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
- }
- }
- public Type Type {
- get {
- Contract.Ensures(Contract.Result<Type>() != null);
- throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
- }
- }
- public bool IsMutable {
- get {
- throw new NotImplementedException();
- }
- }
- public bool IsGhost {
- get {
- throw new NotImplementedException();
- }
- }
- }
-
- public abstract class NonglobalVariable : IVariable {
- public readonly IToken tok;
- readonly string name;
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(tok != null);
- Contract.Invariant(name != null);
- Contract.Invariant(type != null);
- }
-
- public string Name {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- return name;
- }
- }
- public string/*!*/ DisplayName {
- get { return VarDecl.DisplayNameHelper(this); }
- }
- readonly int varId = varIdCount++;
- public string UniqueName {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- return name + "#" + varId;
- }
- }
- static char[] specialChars = new char[] { '\'', '_', '?', '\\' };
- public static string CompilerizeName(string nm) {
- string name = null;
- int i = 0;
- while (true) {
- int j = nm.IndexOfAny(specialChars, i);
- if (j == -1) {
- if (i == 0) {
- return nm; // this is the common case
- } else {
- return name + nm.Substring(i);
- }
- } else {
- string nxt = nm.Substring(i, j - i);
- name = name == null ? nxt : name + nxt;
- switch (nm[j]) {
- case '\'': name += "_k"; break;
- case '_': name += "__"; break;
- case '?': name += "_q"; break;
- case '\\': name += "_b"; break;
- default:
- Contract.Assume(false); // unexpected character
- break;
- }
- i = j + 1;
- if (i == nm.Length) {
- return name;
- }
- }
- }
- }
- protected string compileName;
- public virtual string CompileName {
- get {
- if (compileName == null) {
- compileName = string.Format("_{0}_{1}", varId, CompilerizeName(name));
- }
- return compileName;
- }
- }
- Type type;
- //[Pure(false)] // TODO: if Type gets the status of [Frozen], then this attribute is not needed
- public Type/*!*/ Type {
- get {
- Contract.Ensures(Contract.Result<Type>() != null);
- return type.Normalize();
- }
- }
- public abstract bool IsMutable {
- get;
- }
- bool isGhost; // readonly, except for BoundVar's of match expressions/statements during resolution
- public bool IsGhost {
- get {
- return isGhost;
- }
- set {
- isGhost = value;
- }
- }
-
- public NonglobalVariable(IToken tok, string name, Type type, bool isGhost) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(type != null);
- this.tok = tok;
- this.name = name;
- this.type = type;
- this.isGhost = isGhost;
- }
-
- internal static int varIdCount; // this varIdCount is used for both NonglobalVariable's and VarDecl's.
- }
-
- public class Formal : NonglobalVariable {
- public readonly bool InParam; // true to in-parameter, false for out-parameter
- public override bool IsMutable {
- get {
- return !InParam;
- }
- }
-
- public Formal(IToken/*!*/ tok, string/*!*/ name, Type/*!*/ type, bool inParam, bool isGhost)
- : base(tok, name, type, isGhost) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(type != null);
- InParam = inParam;
- }
-
- public bool HasName {
- get {
- return !Name.StartsWith("#");
- }
- }
- public override string CompileName {
- get {
- if (compileName == null) {
- compileName = CompilerizeName(Name);
- }
- return compileName;
- }
- }
- }
-
- /// <summary>
- /// A "ThisSurrogate" is used during translation time to make the treatment of the receiver more similar to
- /// the treatment of other in-parameters.
- /// </summary>
- public class ThisSurrogate : Formal
- {
- public ThisSurrogate(IToken tok, Type type)
- : base(tok, "this", type, true, false) {
- Contract.Requires(tok != null);
- Contract.Requires(type != null);
- }
- }
-
- public class BoundVar : NonglobalVariable {
- public override bool IsMutable {
- get {
- return false;
- }
- }
-
- public BoundVar(IToken/*!*/ tok, string/*!*/ name, Type/*!*/ type)
- : base(tok, name, type, false) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(type != null);
- }
- }
-
- public class Function : MemberDecl, TypeParameter.ParentType, ICallable {
- public bool IsRecursive; // filled in during resolution
- public readonly List<TypeParameter/*!*/>/*!*/ TypeArgs;
- public readonly IToken OpenParen; // can be null (for predicates), if there are no formals
- public readonly List<Formal/*!*/>/*!*/ Formals;
- public readonly Type/*!*/ ResultType;
- public readonly List<Expression/*!*/>/*!*/ Req;
- public readonly List<FrameExpression/*!*/>/*!*/ Reads;
- public readonly List<Expression/*!*/>/*!*/ Ens;
- public readonly Specification<Expression>/*!*/ Decreases;
- public Expression Body; // an extended expression; Body is readonly after construction, except for any kind of rewrite that may take place around the time of resolution
- public readonly bool SignatureIsOmitted; // is "false" for all Function objects that survive into resolution
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(TypeArgs));
- Contract.Invariant(cce.NonNullElements(Formals));
- Contract.Invariant(ResultType != null);
- Contract.Invariant(cce.NonNullElements(Req));
- Contract.Invariant(cce.NonNullElements(Reads));
- Contract.Invariant(cce.NonNullElements(Ens));
- Contract.Invariant(Decreases != null);
- }
-
- /// <summary>
- /// Note, functions are "ghost" by default; a non-ghost function is called a "function method".
- /// </summary>
- public Function(IToken tok, string name, bool isStatic, bool isGhost,
- List<TypeParameter> typeArgs, IToken openParen, List<Formal> formals, Type resultType,
- List<Expression> req, List<FrameExpression> reads, List<Expression> ens, Specification<Expression> decreases,
- Expression body, Attributes attributes, bool signatureOmitted)
- : base(tok, name, isStatic, isGhost, attributes) {
-
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(cce.NonNullElements(formals));
- Contract.Requires(resultType != null);
- Contract.Requires(cce.NonNullElements(req));
- Contract.Requires(cce.NonNullElements(reads));
- Contract.Requires(cce.NonNullElements(ens));
- Contract.Requires(decreases != null);
- this.TypeArgs = typeArgs;
- this.OpenParen = openParen;
- this.Formals = formals;
- this.ResultType = resultType;
- this.Req = req;
- this.Reads = reads;
- this.Ens = ens;
- this.Decreases = decreases;
- this.Body = body;
- this.SignatureIsOmitted = signatureOmitted;
- }
- }
-
- public class Predicate : Function
- {
- public enum BodyOriginKind
- {
- OriginalOrInherited, // this predicate definition is new (and the predicate may or may not have a body), or the predicate's body (whether or not it exists) is being inherited unmodified (from the previous refinement--it may be that the inherited body was itself an extension, for example)
- DelayedDefinition, // this predicate declaration provides, for the first time, a body--the declaration refines a previously declared predicate, but the previous one had no body
- Extension // this predicate extends the definition of a predicate with a body in a module being refined
- }
- public readonly BodyOriginKind BodyOrigin;
- public Predicate(IToken tok, string name, bool isStatic, bool isGhost,
- List<TypeParameter> typeArgs, IToken openParen, List<Formal> formals,
- List<Expression> req, List<FrameExpression> reads, List<Expression> ens, Specification<Expression> decreases,
- Expression body, BodyOriginKind bodyOrigin, Attributes attributes, bool signatureOmitted)
- : base(tok, name, isStatic, isGhost, typeArgs, openParen, formals, new BoolType(), req, reads, ens, decreases, body, attributes, signatureOmitted) {
- Contract.Requires(bodyOrigin == Predicate.BodyOriginKind.OriginalOrInherited || body != null);
- BodyOrigin = bodyOrigin;
- }
- }
-
- public class CoPredicate : Function
- {
- public readonly List<FunctionCallExpr> Uses = new List<FunctionCallExpr>(); // filled in during resolution, used by verifier
-
- public CoPredicate(IToken tok, string name, bool isStatic,
- List<TypeParameter> typeArgs, IToken openParen, List<Formal> formals,
- List<Expression> req, List<FrameExpression> reads, List<Expression> ens,
- Expression body, Attributes attributes, bool signatureOmitted)
- : base(tok, name, isStatic, true, typeArgs, openParen, formals, new BoolType(),
- req, reads, ens, new Specification<Expression>(new List<Expression>(), null), body, attributes, signatureOmitted) {
- }
- }
-
- public class Method : MemberDecl, TypeParameter.ParentType, ICodeContext
- {
- public readonly bool SignatureIsOmitted;
- public bool MustReverify;
- public readonly List<TypeParameter/*!*/>/*!*/ TypeArgs;
- public readonly List<Formal/*!*/>/*!*/ Ins;
- public readonly List<Formal/*!*/>/*!*/ Outs;
- public readonly List<MaybeFreeExpression/*!*/>/*!*/ Req;
- public readonly Specification<FrameExpression>/*!*/ Mod;
- public readonly List<MaybeFreeExpression/*!*/>/*!*/ Ens;
- public readonly Specification<Expression>/*!*/ Decreases;
- public BlockStmt Body; // Body is readonly after construction, except for any kind of rewrite that may take place around the time of resolution
- public bool IsTailRecursive; // filled in during resolution
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(TypeArgs));
- Contract.Invariant(cce.NonNullElements(Ins));
- Contract.Invariant(cce.NonNullElements(Outs));
- Contract.Invariant(cce.NonNullElements(Req));
- Contract.Invariant(Mod != null);
- Contract.Invariant(cce.NonNullElements(Ens));
- Contract.Invariant(Decreases != null);
- }
-
- public Method(IToken tok, string name,
- bool isStatic, bool isGhost,
- [Captured] List<TypeParameter/*!*/>/*!*/ typeArgs,
- [Captured] List<Formal/*!*/>/*!*/ ins, [Captured] List<Formal/*!*/>/*!*/ outs,
- [Captured] List<MaybeFreeExpression/*!*/>/*!*/ req, [Captured] Specification<FrameExpression>/*!*/ mod,
- [Captured] List<MaybeFreeExpression/*!*/>/*!*/ ens,
- [Captured] Specification<Expression>/*!*/ decreases,
- [Captured] BlockStmt body,
- Attributes attributes, bool signatureOmitted)
- : base(tok, name, isStatic, isGhost, attributes) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(cce.NonNullElements(ins));
- Contract.Requires(cce.NonNullElements(outs));
- Contract.Requires(cce.NonNullElements(req));
- Contract.Requires(mod != null);
- Contract.Requires(cce.NonNullElements(ens));
- Contract.Requires(decreases != null);
- this.TypeArgs = typeArgs;
- this.Ins = ins;
- this.Outs = outs;
- this.Req = req;
- this.Mod = mod;
- this.Ens = ens;
- this.Decreases = decreases;
- this.Body = body;
- this.SignatureIsOmitted = signatureOmitted;
- MustReverify = false;
- }
-
- bool ICodeContext.IsGhost { get { return this.IsGhost; } }
- bool ICodeContext.IsStatic { get { return this.IsStatic; } }
- List<TypeParameter> ICodeContext.TypeArgs { get { return this.TypeArgs; } }
- List<Formal> ICodeContext.Ins { get { return this.Ins; } }
- List<Formal> ICodeContext.Outs { get { return this.Outs; } }
- Specification<FrameExpression> ICodeContext.Modifies { get { return Mod; } }
- Specification<Expression> ICodeContext.Decreases { get { return this.Decreases; } }
- ModuleDefinition ICodeContext.EnclosingModule {
- get {
- Contract.Assert(this.EnclosingClass != null); // this getter is supposed to be called only after signature-resolution is complete
- return this.EnclosingClass.Module;
- }
- }
- bool ICodeContext.MustReverify { get { return this.MustReverify; } }
- }
-
- public class Constructor : Method
- {
- public Constructor(IToken tok, string name,
- [Captured] List<TypeParameter/*!*/>/*!*/ typeArgs,
- [Captured] List<Formal/*!*/>/*!*/ ins,
- [Captured] List<MaybeFreeExpression/*!*/>/*!*/ req, [Captured] Specification<FrameExpression>/*!*/ mod,
- [Captured] List<MaybeFreeExpression/*!*/>/*!*/ ens,
- [Captured] Specification<Expression>/*!*/ decreases,
- [Captured] BlockStmt body,
- Attributes attributes, bool signatureOmitted)
- : base(tok, name, false, false, typeArgs, ins, new List<Formal>(), req, mod, ens, decreases, body, attributes, signatureOmitted) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
- Contract.Requires(cce.NonNullElements(ins));
- Contract.Requires(cce.NonNullElements(req));
- Contract.Requires(mod != null);
- Contract.Requires(cce.NonNullElements(ens));
- Contract.Requires(decreases != null);
- }
- }
-
- // ------------------------------------------------------------------------------------------------------
-
- public abstract class Statement {
- public readonly IToken Tok;
- public LList<Label> Labels; // mutable during resolution
-
- private Attributes attributes;
- public Attributes Attributes {
- get {
- return attributes;
- }
- set {
- attributes = value;
- }
- }
-
- public bool HasAttributes() {
- return Attributes != null;
- }
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Tok != null);
- }
-
- public bool IsGhost; // filled in by resolution
-
- public Statement(IToken tok, Attributes attrs) {
- Contract.Requires(tok != null);
- this.Tok = tok;
- this.attributes = attrs;
- }
-
- public Statement(IToken tok)
- : this(tok, null) {
- Contract.Requires(tok != null);
- this.Tok = tok;
- }
-
- /// <summary>
- /// Returns the non-null substatements of the Statements.
- /// </summary>
- public virtual IEnumerable<Statement> SubStatements {
- get { yield break; }
- }
-
- /// <summary>
- /// Returns the non-null expressions of this statement proper (that is, do not include the expressions of substatements).
- /// </summary>
- public virtual IEnumerable<Expression> SubExpressions {
- get { yield break; }
- }
- }
-
- public class LList<T>
- {
- public readonly T Data;
- public readonly LList<T> Next;
- const LList<T> Empty = null;
-
- public LList(T d, LList<T> next) {
- Data = d;
- Next = next;
- }
-
- public static LList<T> Append(LList<T> a, LList<T> b) {
- if (a == null) return b;
- return new LList<T>(a.Data, Append(a.Next, b));
- // pretend this is ML
- }
- public static int Count(LList<T> n) {
- int count = 0;
- while (n != null) {
- count++;
- n = n.Next;
- }
- return count;
- }
- }
-
- public class Label
- {
- public readonly IToken Tok;
- public readonly string Name;
- public readonly int UniqueId;
- static int nodes = 0;
-
- public Label(IToken tok, string label) {
- Contract.Requires(tok != null);
- Tok = tok;
- Name = label;
- UniqueId = nodes++;
- }
- }
-
- public abstract class PredicateStmt : Statement
- {
- public readonly Expression Expr;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Expr != null);
- }
-
- public PredicateStmt(IToken tok, Expression expr, Attributes attrs)
- : base(tok, attrs) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- this.Expr = expr;
- }
-
- public PredicateStmt(IToken tok, Expression expr)
- : this(tok, expr, null) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- this.Expr = expr;
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Expr;
- }
- }
- }
-
- public class AssertStmt : PredicateStmt {
- public AssertStmt(IToken/*!*/ tok, Expression/*!*/ expr, Attributes attrs)
- : base(tok, expr, attrs) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- }
- }
-
- public class AssumeStmt : PredicateStmt {
- public AssumeStmt(IToken/*!*/ tok, Expression/*!*/ expr, Attributes attrs)
- : base(tok, expr, attrs) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- }
- }
-
- public class PrintStmt : Statement {
- public readonly List<Attributes.Argument/*!*/>/*!*/ Args;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Args));
- }
-
- public PrintStmt(IToken tok, List<Attributes.Argument/*!*/>/*!*/ args)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(args));
-
- Args = args;
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- foreach (var arg in Args) {
- if (arg.E != null) {
- yield return arg.E;
- }
- }
- }
- }
- }
-
- public class BreakStmt : Statement {
- public readonly string TargetLabel;
- public readonly int BreakCount;
- public Statement TargetStmt; // filled in during resolution
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(TargetLabel != null || 1 <= BreakCount);
- }
-
- public BreakStmt(IToken tok, string targetLabel)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(targetLabel != null);
- this.TargetLabel = targetLabel;
- }
- public BreakStmt(IToken tok, int breakCount)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(1 <= breakCount);
- this.BreakCount = breakCount;
- }
- }
-
- public abstract class ProduceStmt : Statement
- {
- public List<AssignmentRhs> rhss;
- public UpdateStmt hiddenUpdate;
- public ProduceStmt(IToken tok, List<AssignmentRhs> rhss)
- : base(tok) {
- Contract.Requires(tok != null);
- this.rhss = rhss;
- hiddenUpdate = null;
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- if (rhss != null) {
- foreach (var rhs in rhss) {
- foreach (var ee in rhs.SubExpressions) {
- yield return ee;
- }
- }
- }
- }
- }
- }
-
- public class ReturnStmt : ProduceStmt
- {
- public ReturnStmt(IToken tok, List<AssignmentRhs> rhss)
- : base(tok, rhss) {
- Contract.Requires(tok != null);
- }
- }
-
- public class YieldStmt : ProduceStmt
- {
- public YieldStmt(IToken tok, List<AssignmentRhs> rhss)
- : base(tok, rhss) {
- Contract.Requires(tok != null);
- }
- }
-
- public abstract class AssignmentRhs
- {
- public readonly IToken Tok;
-
- private Attributes attributes;
- public Attributes Attributes
- {
- get
- {
- return attributes;
- }
- set
- {
- attributes = value;
- }
- }
-
- public bool HasAttributes()
- {
- return Attributes != null;
- }
-
- internal AssignmentRhs(IToken tok, Attributes attrs = null) {
- Tok = tok;
- Attributes = attrs;
- }
- public abstract bool CanAffectPreviouslyKnownExpressions { get; }
- /// <summary>
- /// Returns the non-null subexpressions of the AssignmentRhs.
- /// </summary>
- public virtual IEnumerable<Expression> SubExpressions {
- get { yield break; }
- }
- /// <summary>
- /// Returns the non-null sub-statements of the AssignmentRhs.
- /// </summary>
- public virtual IEnumerable<Statement> SubStatements{
- get { yield break; }
- }
- }
-
- public class ExprRhs : AssignmentRhs
- {
- public readonly Expression Expr;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Expr != null);
- }
-
- public ExprRhs(Expression expr, Attributes attrs = null)
- : base(expr.tok, attrs)
- {
- Contract.Requires(expr != null);
- Expr = expr;
- }
- public override bool CanAffectPreviouslyKnownExpressions { get { return false; } }
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Expr;
- }
- }
- }
-
- public class TypeRhs : AssignmentRhs
- {
- public readonly Type EType;
- public readonly List<Expression> ArrayDimensions;
- public CallStmt InitCall; // may be null (and is definitely null for arrays)
- public Type Type; // filled in during resolution
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(EType != null);
- Contract.Invariant(ArrayDimensions == null || 1 <= ArrayDimensions.Count);
- Contract.Invariant(ArrayDimensions == null || InitCall == null);
- }
-
- public TypeRhs(IToken tok, Type type)
- : base(tok)
- {
- Contract.Requires(type != null);
- EType = type;
- }
- public TypeRhs(IToken tok, Type type, CallStmt initCall)
- : base(tok)
- {
- Contract.Requires(type != null);
- EType = type;
- InitCall = initCall;
- }
- public TypeRhs(IToken tok, Type type, List<Expression> arrayDimensions)
- : base(tok)
- {
- Contract.Requires(type != null);
- Contract.Requires(arrayDimensions != null && 1 <= arrayDimensions.Count);
- EType = type;
- ArrayDimensions = arrayDimensions;
- }
- public override bool CanAffectPreviouslyKnownExpressions {
- get {
- if (InitCall != null) {
- foreach (var mod in InitCall.Method.Mod.Expressions) {
- if (!(mod.E is ThisExpr)) {
- return true;
- }
- }
- }
- return false;
- }
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- if (ArrayDimensions != null) {
- foreach (var e in ArrayDimensions) {
- yield return e;
- }
- }
- }
- }
- public override IEnumerable<Statement> SubStatements {
- get {
- if (InitCall != null) {
- yield return InitCall;
- }
- }
- }
- }
-
- public class CallRhs : AssignmentRhs
- {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Receiver != null);
- Contract.Invariant(MethodName != null);
- Contract.Invariant(cce.NonNullElements(Args));
- }
-
- public readonly Expression/*!*/ Receiver;
- public readonly string/*!*/ MethodName;
- public readonly List<Expression/*!*/>/*!*/ Args;
- public Method Method; // filled in by resolution
-
- public CallRhs(IToken tok, Expression/*!*/ receiver, string/*!*/ methodName, List<Expression/*!*/>/*!*/ args)
- : base(tok)
- {
- Contract.Requires(tok != null);
- Contract.Requires(receiver != null);
- Contract.Requires(methodName != null);
- Contract.Requires(cce.NonNullElements(args));
-
- this.Receiver = receiver;
- this.MethodName = methodName;
- this.Args = args;
- }
- // TODO: Investigate this. For an initialization, this is true. But for existing objects, this is not true.
- public override bool CanAffectPreviouslyKnownExpressions {
- get {
- foreach (var mod in Method.Mod.Expressions) {
- if (!(mod.E is ThisExpr)) {
- return true;
- }
- }
- return false;
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Receiver;
- foreach (var e in Args) {
- yield return e;
- }
- }
- }
- }
-
- public class HavocRhs : AssignmentRhs {
- public HavocRhs(IToken tok)
- : base(tok)
- {
- }
- public override bool CanAffectPreviouslyKnownExpressions { get { return false; } }
- }
-
- public abstract class ConcreteSyntaxStatement : Statement
- {
- public List<Statement> ResolvedStatements = new List<Statement>(); // contents filled in during resolution
- public ConcreteSyntaxStatement(IToken tok)
- : base(tok) {
- }
-
- public override IEnumerable<Statement> SubStatements {
- get { return ResolvedStatements; }
- }
- }
-
- public class VarDeclStmt : ConcreteSyntaxStatement
- {
- public readonly List<VarDecl> Lhss;
- public readonly ConcreteUpdateStatement Update;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Lhss));
- }
-
- public VarDeclStmt(IToken tok, List<VarDecl> lhss, ConcreteUpdateStatement update)
- : base(tok)
- {
- Contract.Requires(lhss != null);
-
- Lhss = lhss;
- Update = update;
- }
- }
-
- /// <summary>
- /// Common superclass of UpdateStmt and AssignSuchThatStmt.
- /// </summary>
- public abstract class ConcreteUpdateStatement : ConcreteSyntaxStatement
- {
- public readonly List<Expression> Lhss;
- public ConcreteUpdateStatement(IToken tok, List<Expression> lhss)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(lhss));
- Lhss = lhss;
- }
- }
-
- public class AssignSuchThatStmt : ConcreteUpdateStatement
- {
- public readonly Expression Expr;
- public readonly IToken AssumeToken;
- /// <summary>
- /// "assumeToken" is allowed to be "null", in which case the verifier will check that a RHS value exists.
- /// If "assumeToken" is non-null, then it should denote the "assume" keyword used in the statement.
- /// </summary>
- public AssignSuchThatStmt(IToken tok, List<Expression> lhss, Expression expr, IToken assumeToken)
- : base(tok, lhss) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(lhss));
- Contract.Requires(lhss.Count != 0);
- Contract.Requires(expr != null);
- Expr = expr;
- if (assumeToken != null) {
- AssumeToken = assumeToken;
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Expr;
- foreach (var lhs in Lhss) {
- yield return lhs;
- }
- }
- }
- }
-
- public class UpdateStmt : ConcreteUpdateStatement
- {
- public readonly List<AssignmentRhs> Rhss;
- public readonly bool CanMutateKnownState;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Lhss));
- Contract.Invariant(cce.NonNullElements(Rhss));
- }
- public UpdateStmt(IToken tok, List<Expression> lhss, List<AssignmentRhs> rhss)
- : base(tok, lhss)
- {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(lhss));
- Contract.Requires(cce.NonNullElements(rhss));
- Contract.Requires(lhss.Count != 0 || rhss.Count == 1);
- Rhss = rhss;
- CanMutateKnownState = false;
- }
- public UpdateStmt(IToken tok, List<Expression> lhss, List<AssignmentRhs> rhss, bool mutate)
- : base(tok, lhss)
- {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(lhss));
- Contract.Requires(cce.NonNullElements(rhss));
- Contract.Requires(lhss.Count != 0 || rhss.Count == 1);
- Rhss = rhss;
- CanMutateKnownState = mutate;
- }
- }
-
- public class AssignStmt : Statement {
- public readonly Expression/*!*/ Lhs;
- public readonly AssignmentRhs/*!*/ Rhs;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Lhs != null);
- Contract.Invariant(Rhs != null);
- }
-
- public AssignStmt(IToken tok, Expression lhs, AssignmentRhs rhs)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(lhs != null);
- Contract.Requires(rhs != null);
- this.Lhs = lhs;
- this.Rhs = rhs;
- }
-
- public override IEnumerable<Statement> SubStatements {
- get {
- var trhs = Rhs as TypeRhs;
- if (trhs != null && trhs.InitCall != null) {
- yield return trhs.InitCall;
- }
- }
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Lhs;
- foreach (var ee in Rhs.SubExpressions) {
- yield return ee;
- }
- }
- }
-
- /// <summary>
- /// This method assumes "lhs" has been successfully resolved.
- /// </summary>
- public static bool LhsIsToGhost(Expression lhs) {
- Contract.Requires(lhs != null);
- lhs = lhs.Resolved;
- if (lhs is IdentifierExpr) {
- var x = (IdentifierExpr)lhs;
- return x.Var.IsGhost;
- } else if (lhs is FieldSelectExpr) {
- var x = (FieldSelectExpr)lhs;
- return x.Field.IsGhost;
- } else {
- // LHS denotes an array element, which is always non-ghost
- return false;
- }
- }
- }
-
- public class VarDecl : Statement, IVariable {
- readonly string/*!*/ name;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(name != null);
- Contract.Invariant(OptionalType != null);
- }
-
- public VarDecl(IToken tok, string name, Type type, bool isGhost)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(type != null); // can be a proxy, though
-
- this.name = name;
- this.OptionalType = type;
- this.IsGhost = isGhost;
- }
-
- public string/*!*/ Name {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- return name;
- }
- }
- public static bool HasWildcardName(IVariable v) {
- Contract.Requires(v != null);
- return v.Name.StartsWith("_");
- }
- public static string DisplayNameHelper(IVariable v) {
- Contract.Requires(v != null);
- return HasWildcardName(v) ? "_" : v.Name;
- }
- public string/*!*/ DisplayName {
- get { return DisplayNameHelper(this); }
- }
- readonly int varId = NonglobalVariable.varIdCount++;
- public string/*!*/ UniqueName {
- get {
- Contract.Ensures(Contract.Result<string>() != null);
- return name + "#" + varId;
- }
- }
- string compileName;
- public string CompileName {
- get {
- if (compileName == null) {
- compileName = string.Format("_{0}_{1}", varId, NonglobalVariable.CompilerizeName(name));
- }
- return compileName;
- }
- }
- public readonly Type OptionalType; // this is the type mentioned in the declaration, if any
- internal Type type; // this is the declared or inferred type of the variable; it is non-null after resolution (even if resolution fails)
- //[Pure(false)]
- public Type Type {
- get {
- Contract.Ensures(Contract.Result<Type>() != null);
-
- Contract.Assume(type != null); /* we assume object has been resolved */
- return type.Normalize();
- }
- }
- public bool IsMutable {
- get {
- return true;
- }
- }
- bool IVariable.IsGhost {
- get {
- return base.IsGhost;
- }
- }
- /// <summary>
- /// This method retrospectively makes the VarDecl a ghost. It is to be used only during resolution.
- /// </summary>
- public void MakeGhost() {
- base.IsGhost = true;
- }
- }
-
- public class CallStmt : Statement {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- //Contract.Invariant(Receiver != null);
- Contract.Invariant(MethodName != null);
- Contract.Invariant(cce.NonNullElements(Lhs));
- Contract.Invariant(cce.NonNullElements(Args));
- }
-
- public readonly List<Expression/*!*/>/*!*/ Lhs;
- public Expression/*!*/ Receiver;
- public readonly string/*!*/ MethodName;
- public readonly List<Expression/*!*/>/*!*/ Args;
- public Dictionary<TypeParameter, Type> TypeArgumentSubstitutions; // create, initialized, and used by resolution (could be deleted once all of resolution is done)
- public Method Method; // filled in by resolution
-
- public CallStmt(IToken tok, List<Expression/*!*/>/*!*/ lhs, Expression/*!*/ receiver,
- string/*!*/ methodName, List<Expression/*!*/>/*!*/ args)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(lhs));
- Contract.Requires(methodName != null);
- Contract.Requires(cce.NonNullElements(args));
-
- this.Lhs = lhs;
- this.Receiver = receiver;
- this.MethodName = methodName;
- this.Args = args;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- foreach (var ee in Lhs) {
- yield return ee;
- }
- yield return Receiver;
- foreach (var ee in Args) {
- yield return ee;
- }
- }
- }
- }
-
- public class BlockStmt : Statement {
- public readonly List<Statement/*!*/>/*!*/ Body;
- public BlockStmt(IToken/*!*/ tok, [Captured] List<Statement/*!*/>/*!*/ body)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(body));
- this.Body = body;
- }
-
- public override IEnumerable<Statement> SubStatements {
- get { return Body; }
- }
- }
-
- public class IfStmt : Statement {
- public readonly Expression Guard;
- public readonly BlockStmt Thn;
- public readonly Statement Els;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Thn != null);
- Contract.Invariant(Els == null || Els is BlockStmt || Els is IfStmt || Els is SkeletonStatement);
- }
- public IfStmt(IToken tok, Expression guard, BlockStmt thn, Statement els)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(thn != null);
- Contract.Requires(els == null || els is BlockStmt || els is IfStmt || els is SkeletonStatement);
- this.Guard = guard;
- this.Thn = thn;
- this.Els = els;
- }
- public override IEnumerable<Statement> SubStatements {
- get {
- yield return Thn;
- if (Els != null) {
- yield return Els;
- }
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- if (Guard != null) {
- yield return Guard;
- }
- }
- }
- }
-
- public class GuardedAlternative
- {
- public readonly IToken Tok;
- public readonly Expression Guard;
- public readonly List<Statement> Body;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Tok != null);
- Contract.Invariant(Guard != null);
- Contract.Invariant(Body != null);
- }
- public GuardedAlternative(IToken tok, Expression guard, List<Statement> body)
- {
- Contract.Requires(tok != null);
- Contract.Requires(guard != null);
- Contract.Requires(body != null);
- this.Tok = tok;
- this.Guard = guard;
- this.Body = body;
- }
- }
-
- public class AlternativeStmt : Statement
- {
- public readonly List<GuardedAlternative> Alternatives;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Alternatives != null);
- }
- public AlternativeStmt(IToken tok, List<GuardedAlternative> alternatives)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(alternatives != null);
- this.Alternatives = alternatives;
- }
- public override IEnumerable<Statement> SubStatements {
- get {
- foreach (var alt in Alternatives) {
- foreach (var s in alt.Body) {
- yield return s;
- }
- }
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- foreach (var alt in Alternatives) {
- yield return alt.Guard;
- }
- }
- }
- }
-
- public abstract class LoopStmt : Statement
- {
- public readonly List<MaybeFreeExpression/*!*/>/*!*/ Invariants;
- public readonly Specification<Expression>/*!*/ Decreases;
- public readonly Specification<FrameExpression>/*!*/ Mod;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Invariants));
- Contract.Invariant(Decreases != null);
- Contract.Invariant(Mod != null);
- }
- public LoopStmt(IToken tok, List<MaybeFreeExpression/*!*/>/*!*/ invariants, Specification<Expression>/*!*/ decreases, Specification<FrameExpression>/*!*/ mod)
- : base(tok)
- {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(invariants));
- Contract.Requires(decreases != null);
- Contract.Requires(mod != null);
-
- this.Invariants = invariants;
- this.Decreases = decreases;
- this.Mod = mod;
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- foreach (var mfe in Invariants) {
- yield return mfe.E;
- }
- if (Decreases.Expressions != null) {
- foreach (var e in Decreases.Expressions) {
- yield return e;
- }
- }
- if (Mod.Expressions != null) {
- foreach (var fe in Mod.Expressions) {
- yield return fe.E;
- }
- }
- }
- }
- }
-
- public class WhileStmt : LoopStmt
- {
- public readonly Expression Guard;
- public readonly BlockStmt/*!*/ Body;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Body != null);
- }
-
- public WhileStmt(IToken tok, Expression guard,
- List<MaybeFreeExpression/*!*/>/*!*/ invariants, Specification<Expression>/*!*/ decreases, Specification<FrameExpression>/*!*/ mod,
- BlockStmt/*!*/ body)
- : base(tok, invariants, decreases, mod) {
- Contract.Requires(tok != null);
- Contract.Requires(body != null);
- this.Guard = guard;
- this.Body = body;
- }
-
- public override IEnumerable<Statement> SubStatements {
- get {
- yield return Body;
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- if (Guard != null) {
- yield return Guard;
- }
- foreach (var e in base.SubExpressions) {
- yield return e;
- }
- }
- }
- }
-
- /// <summary>
- /// This class is really just a WhileStmt, except that it serves the purpose of remembering if the object was created as the result of a refinement
- /// merge.
- /// </summary>
- public class RefinedWhileStmt : WhileStmt
- {
- public RefinedWhileStmt(IToken tok, Expression guard,
- List<MaybeFreeExpression/*!*/>/*!*/ invariants, Specification<Expression>/*!*/ decreases, Specification<FrameExpression>/*!*/ mod,
- BlockStmt/*!*/ body)
- : base(tok, guard, invariants, decreases, mod, body) {
- Contract.Requires(tok != null);
- Contract.Requires(body != null);
- }
- }
-
- public class AlternativeLoopStmt : LoopStmt
- {
- public readonly List<GuardedAlternative> Alternatives;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Alternatives != null);
- }
- public AlternativeLoopStmt(IToken tok,
- List<MaybeFreeExpression/*!*/>/*!*/ invariants, Specification<Expression>/*!*/ decreases, Specification<FrameExpression>/*!*/ mod,
- List<GuardedAlternative> alternatives)
- : base(tok, invariants, decreases, mod) {
- Contract.Requires(tok != null);
- Contract.Requires(alternatives != null);
- this.Alternatives = alternatives;
- }
- public override IEnumerable<Statement> SubStatements {
- get {
- foreach (var alt in Alternatives) {
- foreach (var s in alt.Body) {
- yield return s;
- }
- }
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- foreach (var alt in Alternatives) {
- yield return alt.Guard;
- }
- foreach (var e in base.SubExpressions) {
- yield return e;
- }
- }
- }
- }
-
- public class ParallelStmt : Statement
- {
- public readonly List<BoundVar/*!*/> BoundVars; // note, can be the empty list, in which case Range denotes "true"
- public readonly Expression/*!*/ Range;
- public readonly List<MaybeFreeExpression/*!*/>/*!*/ Ens;
- public readonly Statement Body; // used only until resolution; afterwards, use BodyAssign
-
- public List<ComprehensionExpr.BoundedPool> Bounds; // initialized and filled in by resolver
- // invariant: if successfully resolved, Bounds.Count == BoundVars.Count;
-
- /// <summary>
- /// Assign means there are no ensures clauses and the body consists of one update statement,
- /// either to an object field or to an array.
- /// Call means there are no ensures clauses and the body consists of a single call to a (presumably
- /// ghost, but non-ghost is also allowed) method with no out-parameters and an empty modifies
- /// clause.
- /// Proof means there is at least one ensures clause, and the body consists of any (presumably ghost,
- /// but non-ghost is also allowed) code without side effects on variables (including fields and array
- /// elements) declared outside the body itself.
- /// Notes:
- /// * More kinds may be allowed in the future.
- /// * One could also allow Call to call non-ghost methods without side effects. However, that
- /// would seem pointless in the program, so they are disallowed (to avoid any confusion that
- /// such use of the parallel statement might actually have a point).
- /// * One could allow Proof even without ensures clauses that "export" what was learned.
- /// However, that might give the false impression that the body is nevertheless exported.
- /// </summary>
- public enum ParBodyKind { Assign, Call, Proof }
- public ParBodyKind Kind; // filled in during resolution
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(BoundVars != null);
- Contract.Invariant(Range != null);
- Contract.Invariant(BoundVars.Count != 0 || LiteralExpr.IsTrue(Range));
- Contract.Invariant(Ens != null);
- Contract.Invariant(Body != null);
- }
-
- public ParallelStmt(IToken tok, List<BoundVar> boundVars, Attributes attrs, Expression range, List<MaybeFreeExpression/*!*/>/*!*/ ens, Statement body)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(boundVars));
- Contract.Requires(range != null);
- Contract.Requires(boundVars.Count != 0 || LiteralExpr.IsTrue(range));
- Contract.Requires(cce.NonNullElements(ens));
- Contract.Requires(body != null);
- this.BoundVars = boundVars;
- this.Attributes = attrs;
- this.Range = range;
- this.Ens = ens;
- this.Body = body;
- }
-
- public Statement S0 {
- get {
- // dig into Body to find a single statement
- Statement s = this.Body;
- while (true) {
- var block = s as BlockStmt;
- if (block != null && block.Body.Count == 1) {
- s = block.Body[0];
- } else {
- var conc = s as ConcreteSyntaxStatement;
- if (conc != null && conc.ResolvedStatements.Count == 1) {
- s = conc.ResolvedStatements[0];
- } else {
- return s;
- }
- }
- }
- }
- }
-
- public override IEnumerable<Statement> SubStatements {
- get {
- yield return Body;
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Range;
- foreach (var ee in Ens) {
- yield return ee.E;
- }
- }
- }
- }
-
- public class CalcStmt : Statement
- {
- public readonly BinaryExpr.Opcode/*!*/ Op; // main operator of the calculation
- public readonly List<Expression/*!*/> Lines;
- public readonly List<BlockStmt/*!*/> Hints; // Hints[i] comes after line i; block statement is used as a container for multiple sub-hints
- public readonly List<BinaryExpr.Opcode?> CustomOps; // CustomOps[i] comes after line i; null denotes the absence of a custom operator
- public readonly List<BinaryExpr/*!*/> Steps; // expressions li op l<i + 1>, filled in during resolution in order to get the correct op
- public BinaryExpr Result; // expression l0 op ln, filled in during resolution in order to get the correct op
-
- public static readonly BinaryExpr.Opcode/*!*/ DefaultOp = BinaryExpr.Opcode.Eq;
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(ValidOp(Op));
- Contract.Invariant(Lines != null);
- Contract.Invariant(Hints != null);
- Contract.Invariant(CustomOps != null);
- Contract.Invariant(Steps != null);
- Contract.Invariant(Hints.Count == Math.Max(Lines.Count - 1, 0));
- Contract.Invariant(CustomOps.Count == Hints.Count);
- }
-
- public CalcStmt(IToken tok, BinaryExpr.Opcode/*!*/ op, List<Expression/*!*/> lines, List<BlockStmt/*!*/> hints, List<BinaryExpr.Opcode?> customOps)
- : base(tok)
- {
- Contract.Requires(tok != null);
- Contract.Requires(ValidOp(op));
- Contract.Requires(lines != null);
- Contract.Requires(hints != null);
- Contract.Requires(customOps != null);
- Contract.Requires(cce.NonNullElements(lines));
- Contract.Requires(cce.NonNullElements(hints));
- Contract.Requires(hints.Count == Math.Max(lines.Count - 1, 0));
- Contract.Requires(customOps.Count == hints.Count);
- this.Op = op;
- this.Lines = lines;
- this.Hints = hints;
- this.CustomOps = customOps;
- this.Steps = new List<BinaryExpr>();
- this.Result = null;
- }
-
- public override IEnumerable<Statement> SubStatements
- {
- get {
- foreach (var h in Hints) {
- yield return h;
- }
- }
- }
- public override IEnumerable<Expression> SubExpressions
- {
- get {
- foreach (var l in Lines) {
- yield return l;
- }
- }
- }
-
- /// <summary>
- /// Is op a valid calculation operator (i.e. a transitive relational operator)?
- /// </summary>
- [Pure]
- public static bool ValidOp(BinaryExpr.Opcode op) {
- return op == BinaryExpr.Opcode.Eq || op == BinaryExpr.Opcode.Lt || op == BinaryExpr.Opcode.Le || op == BinaryExpr.Opcode.Gt || op == BinaryExpr.Opcode.Ge
- || op == BinaryExpr.Opcode.Neq
- || op == BinaryExpr.Opcode.Iff || op == BinaryExpr.Opcode.Imp;
- }
-
- /// <summary>
- /// Does op1 subsume op2 (i.e. forall x, y, z :: (x op1 y op2 z) || (x op2 y op1 z) ==> x op1 z)?
- /// </summary>
- [Pure]
- private static bool Subsumes(BinaryExpr.Opcode op1, BinaryExpr.Opcode op2) {
- Contract.Requires(ValidOp(op1) && ValidOp(op2));
- if (op1 == BinaryExpr.Opcode.Neq || op2 == BinaryExpr.Opcode.Neq)
- return op2 == BinaryExpr.Opcode.Eq;
- if (op1 == op2)
- return true;
- if (op1 == BinaryExpr.Opcode.Iff || op1 == BinaryExpr.Opcode.Imp || op2 == BinaryExpr.Opcode.Iff || op2 == BinaryExpr.Opcode.Imp)
- return op2 == BinaryExpr.Opcode.Eq ||
- (op1 == BinaryExpr.Opcode.Imp && op2 == BinaryExpr.Opcode.Iff) ||
- (op1 == BinaryExpr.Opcode.Eq && op2 == BinaryExpr.Opcode.Iff);
- return op2 == BinaryExpr.Opcode.Eq ||
- (op1 == BinaryExpr.Opcode.Lt && op2 == BinaryExpr.Opcode.Le) ||
- (op1 == BinaryExpr.Opcode.Gt && op2 == BinaryExpr.Opcode.Ge);
- }
-
- /// <summary>
- /// Resulting operator x op z if x op1 y op2 z.
- /// (Least upper bound in the Subsumes order).
- /// Returns null if neither of op1 or op2 subsumes the other.
- /// </summary>
- [Pure]
- public static BinaryExpr.Opcode? ResultOp(BinaryExpr.Opcode op1, BinaryExpr.Opcode op2) {
- Contract.Requires(ValidOp(op1) && ValidOp(op2));
- Contract.Ensures(Contract.Result<BinaryExpr.Opcode?>() == null || ValidOp((BinaryExpr.Opcode)Contract.Result<BinaryExpr.Opcode?>()));
- if (Subsumes(op1, op2)) {
- return op1;
- } else if (Subsumes(op2, op1)) {
- return op2;
- }
- return null;
- }
- }
-
- public class MatchStmt : Statement
- {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Source != null);
- Contract.Invariant(cce.NonNullElements(Cases));
- Contract.Invariant(cce.NonNullElements(MissingCases));
- }
-
- public readonly Expression Source;
- public readonly List<MatchCaseStmt/*!*/>/*!*/ Cases;
- public readonly List<DatatypeCtor/*!*/> MissingCases = new List<DatatypeCtor>(); // filled in during resolution
-
- public MatchStmt(IToken tok, Expression source, [Captured] List<MatchCaseStmt/*!*/>/*!*/ cases)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(source != null);
- Contract.Requires(cce.NonNullElements(cases));
- this.Source = source;
- this.Cases = cases;
- }
-
- public override IEnumerable<Statement> SubStatements {
- get {
- foreach (var kase in Cases) {
- foreach (var s in kase.Body) {
- yield return s;
- }
- }
- }
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Source;
- }
- }
- }
-
- public class MatchCaseStmt : MatchCase
- {
- public readonly List<Statement/*!*/>/*!*/ Body;
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Body));
- }
-
- public MatchCaseStmt(IToken tok, string id, [Captured] List<BoundVar/*!*/>/*!*/ arguments, [Captured] List<Statement/*!*/>/*!*/ body)
- : base(tok, id, arguments)
- {
- Contract.Requires(tok != null);
- Contract.Requires(id != null);
- Contract.Requires(cce.NonNullElements(arguments));
- Contract.Requires(cce.NonNullElements(body));
- this.Body = body;
- }
- }
-
- /// <summary>
- /// The class represents several possible scenarios:
- /// * ...;
- /// S == null
- /// * assert ...
- /// ConditionOmitted == true
- /// * assume ...
- /// ConditionOmitted == true
- /// * if ... { Stmt }
- /// if ... { Stmt } else ElseStmt
- /// ConditionOmitted == true
- /// * while ... invariant J;
- /// ConditionOmitted == true && BodyOmitted == true
- /// * while ... invariant J; { Stmt }
- /// ConditionOmitted == true && BodyOmitted == false
- /// </summary>
- public class SkeletonStatement : Statement
- {
- public readonly Statement S;
- public readonly bool ConditionOmitted;
- public readonly bool BodyOmitted;
- public readonly List<IToken> NameReplacements;
- public readonly List<Expression> ExprReplacements;
- public SkeletonStatement(IToken tok)
- : base(tok)
- {
- Contract.Requires(tok != null);
- S = null;
- }
- public SkeletonStatement(Statement s, bool conditionOmitted, bool bodyOmitted)
- : base(s.Tok)
- {
- Contract.Requires(s != null);
- S = s;
- ConditionOmitted = conditionOmitted;
- BodyOmitted = bodyOmitted;
- }
- public SkeletonStatement(IToken tok, List<IToken> nameReplacements, List<Expression> exprReplacements)
- : base(tok) {
- Contract.Requires(tok != null);
- NameReplacements = nameReplacements;
- ExprReplacements = exprReplacements;
-
- }
- public override IEnumerable<Statement> SubStatements {
- get {
- // The SkeletonStatement is really a modification of its inner statement S. Therefore,
- // we don't consider S to be a substatement. Instead, the substatements of S are the
- // substatements of the SkeletonStatement. In the case the SkeletonStatement modifies
- // S by omitting its body (which is true only for loops), there are no substatements.
- if (!BodyOmitted) {
- foreach (var s in S.SubStatements) {
- yield return s;
- }
- }
- }
- }
- }
-
- // ------------------------------------------------------------------------------------------------------
-
- public abstract class TokenWrapper : IToken
- {
- protected readonly IToken WrappedToken;
- protected TokenWrapper(IToken wrappedToken) {
- Contract.Requires(wrappedToken != null);
- WrappedToken = wrappedToken;
- }
-
- public int col {
- get { return WrappedToken.col; }
- set { throw new NotSupportedException(); }
- }
- public virtual string filename {
- get { return WrappedToken.filename; }
- set { throw new NotSupportedException(); }
- }
- public bool IsValid {
- get { return WrappedToken.IsValid; }
- }
- public int kind {
- get { return WrappedToken.kind; }
- set { throw new NotSupportedException(); }
- }
- public int line {
- get { return WrappedToken.line; }
- set { throw new NotSupportedException(); }
- }
- public int pos {
- get { return WrappedToken.pos; }
- set { throw new NotSupportedException(); }
- }
- public string val {
- get { return WrappedToken.val; }
- set { throw new NotSupportedException(); }
- }
- }
-
- public class NestedToken : TokenWrapper
- {
- public NestedToken(IToken outer, IToken inner)
- : base(outer)
- {
- Contract.Requires(outer != null);
- Contract.Requires(inner != null);
- Inner = inner;
- }
- public IToken Outer { get { return WrappedToken; } }
- public readonly IToken Inner;
- }
-
- // ------------------------------------------------------------------------------------------------------
-
- public abstract class Expression
- {
- public readonly IToken tok;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(tok != null);
- }
-
- [Pure]
- public bool WasResolved()
- {
- return Type != null;
- }
-
- public Expression Resolved {
- get {
- Contract.Requires(WasResolved()); // should be called only on resolved expressions; this approximates that precondition
- Expression r = this;
- while (true) {
- var rr = r as ConcreteSyntaxExpression;
- if (rr == null) { break; }
- r = rr.ResolvedExpression;
- }
- return r;
- }
- }
-
- protected Type type;
- public Type Type { // filled in during resolution
- [Verify(false)] // TODO: how do we allow Type.get to modify type and still be [Pure]?
- [Additive] // validity of proper subclasses is not required
- get {
- Contract.Ensures(type != null || Contract.Result<Type>() == null); // useful in conjunction with postcondition of constructor
- return type == null ? null : type.Normalize();
- }
- [NoDefaultContract] // no particular validity of 'this' is required, except that it not be committed
- set {
- Contract.Requires(cce.IsValid(this));
- Contract.Requires(!WasResolved()); // set it only once
- Contract.Requires(value != null);
- //modifies type;
- type = value.Normalize();
- }
- }
-
- public Expression(IToken tok) {
- Contract.Requires(tok != null);
- Contract.Ensures(type == null); // we would have liked to have written Type==null, but that's not admissible or provable
-
- this.tok = tok;
- }
-
- /// <summary>
- /// Returns the non-null subexpressions of the Expression.
- /// </summary>
- public virtual IEnumerable<Expression> SubExpressions {
- get { yield break; }
- }
- }
-
- /// <summary>
- /// Instances of this class are introduced during resolution to indicate that a static method or function has
- /// been invoked without specifying a receiver (that is, by just giving the name of the enclosing class).
- /// </summary>
- public class StaticReceiverExpr : LiteralExpr
- {
- public StaticReceiverExpr(IToken tok, ClassDecl cl)
- : base(tok) // constructs a LiteralExpr representing the 'null' literal
- {
- Contract.Requires(tok != null);
- Contract.Requires(cl != null);
- var typeArgs = new List<Type>();
- foreach (var ta in cl.TypeArgs) {
- typeArgs.Add(new InferredTypeProxy());
- }
- Type = new UserDefinedType(tok, cl.Name, cl, typeArgs);
- }
- }
-
- public class LiteralExpr : Expression {
- public readonly object Value;
-
- [Pure]
- public static bool IsTrue(Expression e) {
- Contract.Requires(e != null);
- if (e is LiteralExpr) {
- LiteralExpr le = (LiteralExpr)e;
- return le.Value is bool && (bool)le.Value;
- } else {
- return false;
- }
- }
-
- public LiteralExpr(IToken tok)
- : base(tok) { // represents the Dafny literal "null"
- Contract.Requires(tok != null);
- this.Value = null;
- }
-
- public LiteralExpr(IToken tok, BigInteger n)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(0 <= n.Sign);
-
- this.Value = n;
- }
-
- public LiteralExpr(IToken tok, int n) :base(tok){
- Contract.Requires(tok != null);
- Contract.Requires(0 <= n);
-
- this.Value = new BigInteger(n);
- }
-
- public LiteralExpr(IToken tok, bool b)
- : base(tok) {
- Contract.Requires(tok != null);
- this.Value = b;
-
- }
- }
-
- public class DatatypeValue : Expression {
- public readonly string DatatypeName;
- public readonly string MemberName;
- public readonly List<Expression/*!*/>/*!*/ Arguments;
- public DatatypeCtor Ctor; // filled in by resolution
- public List<Type/*!*/> InferredTypeArgs = new List<Type>(); // filled in by resolution
- public bool IsCoCall; // filled in by resolution
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(DatatypeName != null);
- Contract.Invariant(MemberName != null);
- Contract.Invariant(cce.NonNullElements(Arguments));
- Contract.Invariant(cce.NonNullElements(InferredTypeArgs));
- }
-
- public DatatypeValue(IToken tok, string datatypeName, string memberName, [Captured] List<Expression/*!*/>/*!*/ arguments)
- : base(tok) {
- Contract.Requires(cce.NonNullElements(arguments));
- Contract.Requires(tok != null);
- Contract.Requires(datatypeName != null);
- Contract.Requires(memberName != null);
- this.DatatypeName = datatypeName;
- this.MemberName = memberName;
- this.Arguments = arguments;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { return Arguments; }
- }
- }
-
- public class ThisExpr : Expression {
- public ThisExpr(IToken tok)
- : base(tok) {
- Contract.Requires(tok != null);
- }
- }
- public class ExpressionPair {
- public Expression A, B;
- public ExpressionPair(Expression a, Expression b) {
- Contract.Requires(a != null);
- Contract.Requires(b != null);
- A = a;
- B = b;
- }
- }
-
- public class ImplicitThisExpr : ThisExpr {
- public ImplicitThisExpr(IToken tok)
- : base(tok) {
- Contract.Requires(tok != null);
- }
- }
-
- public class IdentifierExpr : Expression
- {
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Name != null);
- }
-
- public readonly string Name;
- public IVariable Var; // filled in by resolution
-
- public IdentifierExpr(IToken tok, string name)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Name = name;
- }
- }
-
- /// <summary>
- /// If an "AutoGhostIdentifierExpr" is used as the out-parameter of a ghost method or
- /// a method with a ghost parameter, resolution will change the .Var's .IsGhost to true
- /// automatically. This class is intended to be used only as a communicate between the
- /// parser and parts of the resolver.
- /// </summary>
- public class AutoGhostIdentifierExpr : IdentifierExpr
- {
- public AutoGhostIdentifierExpr(IToken tok, string name)
- : base(tok, name) { }
- }
-
- public abstract class DisplayExpression : Expression {
- public readonly List<Expression/*!*/>/*!*/ Elements;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Elements));
- }
-
- public DisplayExpression(IToken tok, List<Expression/*!*/>/*!*/ elements)
- : base(tok) {
- Contract.Requires(cce.NonNullElements(elements));
- Elements = elements;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { return Elements; }
- }
- }
-
- public class SetDisplayExpr : DisplayExpression {
- public SetDisplayExpr(IToken tok, List<Expression/*!*/>/*!*/ elements)
- : base(tok, elements) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(elements));
- }
- }
-
- public class MultiSetDisplayExpr : DisplayExpression {
- public MultiSetDisplayExpr(IToken tok, List<Expression/*!*/>/*!*/ elements) : base(tok, elements) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(elements));
- }
- }
-
- public class MapDisplayExpr : Expression {
- public List<ExpressionPair/*!*/>/*!*/ Elements;
- public MapDisplayExpr(IToken tok, List<ExpressionPair/*!*/>/*!*/ elements)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(elements));
- Elements = elements;
- }
- }
- public class SeqDisplayExpr : DisplayExpression {
- public SeqDisplayExpr(IToken tok, List<Expression/*!*/>/*!*/ elements)
- : base(tok, elements) {
- Contract.Requires(cce.NonNullElements(elements));
- Contract.Requires(tok != null);
- }
- }
-
- public class FieldSelectExpr : Expression {
- public readonly Expression Obj;
- public readonly string FieldName;
- public Field Field; // filled in by resolution
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Obj != null);
- Contract.Invariant(FieldName != null);
- }
-
- public FieldSelectExpr(IToken tok, Expression obj, string fieldName)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(obj != null);
- Contract.Requires(fieldName != null);
- this.Obj = obj;
- this.FieldName = fieldName;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { yield return Obj; }
- }
- }
-
- public class SeqSelectExpr : Expression {
- public readonly bool SelectOne; // false means select a range
- public readonly Expression Seq;
- public readonly Expression E0;
- public readonly Expression E1;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Seq != null);
- Contract.Invariant(!SelectOne || E1 == null);
- }
-
- public SeqSelectExpr(IToken tok, bool selectOne, Expression seq, Expression e0, Expression e1)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(seq != null);
- Contract.Requires(!selectOne || e1 == null);
-
- SelectOne = selectOne;
- Seq = seq;
- E0 = e0;
- E1 = e1;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Seq;
- if (E0 != null) yield return E0;
- if (E1 != null) yield return E1;
- }
- }
- }
-
- public class MultiSelectExpr : Expression {
- public readonly Expression Array;
- public readonly List<Expression> Indices;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Array != null);
- Contract.Invariant(cce.NonNullElements(Indices));
- Contract.Invariant(1 <= Indices.Count);
- }
-
- public MultiSelectExpr(IToken tok, Expression array, List<Expression> indices)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(array != null);
- Contract.Requires(cce.NonNullElements(indices) && 1 <= indices.Count);
-
- Array = array;
- Indices = indices;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Array;
- foreach (var e in Indices) {
- yield return e;
- }
- }
- }
- }
-
- public class SeqUpdateExpr : Expression {
- public readonly Expression Seq;
- public readonly Expression Index;
- public readonly Expression Value;
-
- public SeqUpdateExpr(IToken tok, Expression seq, Expression index, Expression val)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(seq != null);
- Contract.Requires(index != null);
- Contract.Requires(val != null);
- Seq = seq;
- Index = index;
- Value = val;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Seq;
- yield return Index;
- yield return Value;
- }
- }
- }
-
- public class FunctionCallExpr : Expression {
- public readonly string/*!*/ Name;
- public readonly Expression/*!*/ Receiver;
- public readonly IToken OpenParen; // can be null if Args.Count == 0
- public readonly List<Expression/*!*/>/*!*/ Args;
- public Dictionary<TypeParameter, Type> TypeArgumentSubstitutions; // created, initialized, and used by resolution (could be deleted once all of resolution is done)
- public enum CoCallResolution { No, Yes, NoBecauseFunctionHasSideEffects, NoBecauseRecursiveCallsAreNotAllowedInThisContext, NoBecauseIsNotGuarded }
- public CoCallResolution CoCall = CoCallResolution.No; // indicates whether or not the call is a co-recursive call; filled in by resolution
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Name != null);
- Contract.Invariant(Receiver != null);
- Contract.Invariant(cce.NonNullElements(Args));
- }
-
- public Function Function; // filled in by resolution
-
- [Captured]
- public FunctionCallExpr(IToken tok, string fn, Expression receiver, IToken openParen, [Captured] List<Expression/*!*/>/*!*/ args)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(fn != null);
- Contract.Requires(receiver != null);
- Contract.Requires(cce.NonNullElements(args));
- Contract.Requires(openParen != null || args.Count == 0);
- Contract.Ensures(type == null);
- Contract.Ensures(cce.Owner.Same(this, receiver));
-
- this.Name = fn;
- cce.Owner.AssignSame(this, receiver);
- this.Receiver = receiver;
- this.OpenParen = openParen;
- this.Args = args;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- if (!Function.IsStatic) {
- yield return Receiver;
- }
- foreach (var e in Args) {
- yield return e;
- }
- }
- }
- }
-
- public class OldExpr : Expression {
- [Peer]
- public readonly Expression E;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- }
-
- [Captured]
- public OldExpr(IToken tok, Expression expr)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- cce.Owner.AssignSame(this, expr);
- E = expr;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { yield return E; }
- }
- }
-
- public class MultiSetFormingExpr : Expression
- {
- [Peer]
- public readonly Expression E;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- }
-
- [Captured]
- public MultiSetFormingExpr(IToken tok, Expression expr)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- cce.Owner.AssignSame(this, expr);
- E = expr;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { yield return E; }
- }
- }
- public class FreshExpr : Expression {
- public readonly Expression E;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- }
-
- public FreshExpr(IToken tok, Expression expr)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- E = expr;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { yield return E; }
- }
- }
-
- public class UnaryExpr : Expression
- {
- public enum Opcode {
- Not,
- SetChoose, // Important: SetChoose is not a function, so it can only be used in a statement context (in particular, the RHS of an assignment)
- SeqLength
- }
- public readonly Opcode Op;
- public readonly Expression E;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- }
-
- public UnaryExpr(IToken tok, Opcode op, Expression e)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- this.Op = op;
- this.E = e;
-
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { yield return E; }
- }
- }
-
- public class BinaryExpr : Expression {
- public enum Opcode {
- Iff,
- Imp,
- And,
- Or,
- Eq,
- Neq,
- Lt,
- Le,
- Ge,
- Gt,
- Disjoint,
- In,
- NotIn,
- Add,
- Sub,
- Mul,
- Div,
- Mod
- }
- public readonly Opcode Op;
- public enum ResolvedOpcode {
- // logical operators
- Iff,
- Imp,
- And,
- Or,
- // non-collection types
- EqCommon,
- NeqCommon,
- // integers
- Lt,
- Le,
- Ge,
- Gt,
- Add,
- Sub,
- Mul,
- Div,
- Mod,
- // sets
- SetEq,
- SetNeq,
- ProperSubset,
- Subset,
- Superset,
- ProperSuperset,
- Disjoint,
- InSet,
- NotInSet,
- Union,
- Intersection,
- SetDifference,
- // multi-sets
- MultiSetEq,
- MultiSetNeq,
- MultiSubset,
- MultiSuperset,
- ProperMultiSubset,
- ProperMultiSuperset,
- MultiSetDisjoint,
- InMultiSet,
- NotInMultiSet,
- MultiSetUnion,
- MultiSetIntersection,
- MultiSetDifference,
- // Sequences
- SeqEq,
- SeqNeq,
- ProperPrefix,
- Prefix,
- Concat,
- InSeq,
- NotInSeq,
- // Maps
- MapEq,
- MapNeq,
- InMap,
- NotInMap,
- MapDisjoint,
- MapUnion,
- // datatypes
- RankLt,
- RankGt
- }
- public ResolvedOpcode ResolvedOp; // filled in by resolution
-
- public static Opcode ResolvedOp2SyntacticOp(ResolvedOpcode rop) {
- switch (rop) {
- case ResolvedOpcode.Iff: return Opcode.Iff;
- case ResolvedOpcode.Imp: return Opcode.Imp;
- case ResolvedOpcode.And: return Opcode.And;
- case ResolvedOpcode.Or: return Opcode.Or;
-
- case ResolvedOpcode.EqCommon:
- case ResolvedOpcode.SetEq:
- case ResolvedOpcode.MultiSetEq:
- case ResolvedOpcode.SeqEq:
- case ResolvedOpcode.MapEq:
- return Opcode.Eq;
-
- case ResolvedOpcode.NeqCommon:
- case ResolvedOpcode.SetNeq:
- case ResolvedOpcode.MultiSetNeq:
- case ResolvedOpcode.SeqNeq:
- case ResolvedOpcode.MapNeq:
- return Opcode.Neq;
-
- case ResolvedOpcode.Lt:
- case ResolvedOpcode.ProperSubset:
- case ResolvedOpcode.ProperMultiSuperset:
- case ResolvedOpcode.ProperPrefix:
- case ResolvedOpcode.RankLt:
- return Opcode.Lt;
-
- case ResolvedOpcode.Le:
- case ResolvedOpcode.Subset:
- case ResolvedOpcode.MultiSubset:
- case ResolvedOpcode.Prefix:
- return Opcode.Le;
-
- case ResolvedOpcode.Ge:
- case ResolvedOpcode.Superset:
- case ResolvedOpcode.MultiSuperset:
- return Opcode.Ge;
-
- case ResolvedOpcode.Gt:
- case ResolvedOpcode.ProperSuperset:
- case ResolvedOpcode.ProperMultiSubset:
- case ResolvedOpcode.RankGt:
- return Opcode.Gt;
-
- case ResolvedOpcode.Add:
- case ResolvedOpcode.Union:
- case ResolvedOpcode.MultiSetUnion:
- case ResolvedOpcode.MapUnion:
- case ResolvedOpcode.Concat:
- return Opcode.Add;
-
- case ResolvedOpcode.Sub:
- case ResolvedOpcode.SetDifference:
- case ResolvedOpcode.MultiSetDifference:
- return Opcode.Sub;
-
- case ResolvedOpcode.Mul:
- case ResolvedOpcode.Intersection:
- case ResolvedOpcode.MultiSetIntersection:
- return Opcode.Mul;
-
- case ResolvedOpcode.Div: return Opcode.Div;
- case ResolvedOpcode.Mod: return Opcode.Mod;
-
- case ResolvedOpcode.Disjoint:
- case ResolvedOpcode.MultiSetDisjoint:
- case ResolvedOpcode.MapDisjoint:
- return Opcode.Disjoint;
-
- case ResolvedOpcode.InSet:
- case ResolvedOpcode.InMultiSet:
- case ResolvedOpcode.InSeq:
- case ResolvedOpcode.InMap:
- return Opcode.In;
-
- case ResolvedOpcode.NotInSet:
- case ResolvedOpcode.NotInMultiSet:
- case ResolvedOpcode.NotInSeq:
- case ResolvedOpcode.NotInMap:
- return Opcode.NotIn;
-
- default:
- Contract.Assert(false); // unexpected ResolvedOpcode
- return Opcode.Add; // please compiler
- }
- }
-
- public static string OpcodeString(Opcode op) {
- Contract.Ensures(Contract.Result<string>() != null);
-
- switch (op) {
- case Opcode.Iff:
- return "<==>";
- case Opcode.Imp:
- return "==>";
- case Opcode.And:
- return "&&";
- case Opcode.Or:
- return "||";
- case Opcode.Eq:
- return "==";
- case Opcode.Lt:
- return "<";
- case Opcode.Gt:
- return ">";
- case Opcode.Le:
- return "<=";
- case Opcode.Ge:
- return ">=";
- case Opcode.Neq:
- return "!=";
- case Opcode.Disjoint:
- return "!!";
- case Opcode.In:
- return "in";
- case Opcode.NotIn:
- return "!in";
- case Opcode.Add:
- return "+";
- case Opcode.Sub:
- return "-";
- case Opcode.Mul:
- return "*";
- case Opcode.Div:
- return "/";
- case Opcode.Mod:
- return "%";
- default:
- Contract.Assert(false);
- throw new cce.UnreachableException(); // unexpected operator
- }
- }
- public readonly Expression E0;
- public readonly Expression E1;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E0 != null);
- Contract.Invariant(E1 != null);
- }
-
-
- public BinaryExpr(IToken tok, Opcode op, Expression e0, Expression e1)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- this.Op = op;
- this.E0 = e0;
- this.E1 = e1;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return E0;
- yield return E1;
- }
- }
- }
-
- public class LetExpr : Expression
- {
- public readonly List<BoundVar> Vars;
- public readonly List<Expression> RHSs;
- public readonly Expression Body;
- public LetExpr(IToken tok, List<BoundVar> vars, List<Expression> rhss, Expression body)
- : base(tok) {
- Vars = vars;
- RHSs = rhss;
- Body = body;
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- foreach (var rhs in RHSs) {
- yield return rhs;
- }
- yield return Body;
- }
- }
- }
- // Represents expr Name: Body
- // or expr Name: (assert Body == Contract; Body)
- public class NamedExpr : Expression
- {
- public readonly string Name;
- public readonly Expression Body;
- public readonly Expression Contract;
- public readonly IToken ReplacerToken;
-
- public NamedExpr(IToken tok, string p, Expression body)
- : base(tok) {
- Name = p;
- Body = body;
- }
- public NamedExpr(IToken tok, string p, Expression body, Expression contract, IToken token)
- : base(tok) {
- Name = p;
- Body = body;
- Contract = contract;
- ReplacerToken = token;
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Body;
- if (Contract != null) yield return Contract;
- }
- }
- }
-
- /// <summary>
- /// A ComprehensionExpr has the form:
- /// BINDER x Attributes | Range(x) :: Term(x)
- /// When BINDER is "forall" or "exists", the range may be "null" (which stands for the logical value "true").
- /// For other BINDERs (currently, "set"), the range is non-null.
- /// where "Attributes" is optional, and "| Range(x)" is optional and defaults to "true".
- /// Currently, BINDER is one of the logical quantifiers "exists" or "forall".
- /// </summary>
- public abstract class ComprehensionExpr : Expression {
- public readonly List<BoundVar/*!*/>/*!*/ BoundVars;
- public readonly Expression Range;
- public readonly Expression/*!*/ Term;
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(BoundVars != null);
- Contract.Invariant(Term != null);
- }
-
- public readonly Attributes Attributes;
-
- public abstract class BoundedPool { }
- public class IntBoundedPool : BoundedPool
- {
- public readonly Expression LowerBound;
- public readonly Expression UpperBound;
- public IntBoundedPool(Expression lowerBound, Expression upperBound) {
- LowerBound = lowerBound;
- UpperBound = upperBound;
- }
- }
- public class SetBoundedPool : BoundedPool
- {
- public readonly Expression Set;
- public SetBoundedPool(Expression set) { Set = set; }
- }
- public class SuperSetBoundedPool : BoundedPool
- {
- public readonly Expression LowerBound;
- public SuperSetBoundedPool(Expression set) { LowerBound = set; }
- }
- public class MapBoundedPool : BoundedPool
- {
- public readonly Expression Map;
- public MapBoundedPool(Expression map) { Map = map; }
- }
- public class SeqBoundedPool : BoundedPool
- {
- public readonly Expression Seq;
- public SeqBoundedPool(Expression seq) { Seq = seq; }
- }
- public class BoolBoundedPool : BoundedPool
- {
- }
- public class DatatypeBoundedPool : BoundedPool
- {
- public readonly DatatypeDecl Decl;
- public DatatypeBoundedPool(DatatypeDecl d) { Decl = d; }
- }
-
- public List<BoundedPool> Bounds; // initialized and filled in by resolver
- // invariant Bounds == null || Bounds.Count == BoundVars.Count;
- public List<BoundVar> MissingBounds; // filled in during resolution; remains "null" if bounds can be found
- // invariant Bounds == null || MissingBounds == null;
-
- public ComprehensionExpr(IToken/*!*/ tok, List<BoundVar/*!*/>/*!*/ bvars, Expression range, Expression/*!*/ term, Attributes attrs)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(bvars));
- Contract.Requires(term != null);
-
- this.BoundVars = bvars;
- this.Range = range;
- this.Term = term;
- this.Attributes = attrs;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- if (Range != null) { yield return Range; }
- yield return Term;
- }
- }
- }
-
- public abstract class QuantifierExpr : ComprehensionExpr {
- public QuantifierExpr(IToken/*!*/ tok, List<BoundVar/*!*/>/*!*/ bvars, Expression range, Expression/*!*/ term, Attributes attrs)
- : base(tok, bvars, range, term, attrs) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(bvars));
- Contract.Requires(term != null);
- }
- public abstract Expression/*!*/ LogicalBody();
- }
-
- public class ForallExpr : QuantifierExpr {
- public ForallExpr(IToken tok, List<BoundVar/*!*/>/*!*/ bvars, Expression range, Expression term, Attributes attrs)
- : base(tok, bvars, range, term, attrs) {
- Contract.Requires(cce.NonNullElements(bvars));
- Contract.Requires(tok != null);
- Contract.Requires(term != null);
- }
- public override Expression/*!*/ LogicalBody() {
- if (Range == null) {
- return Term;
- }
- var body = new BinaryExpr(Term.tok, BinaryExpr.Opcode.Imp, Range, Term);
- body.ResolvedOp = BinaryExpr.ResolvedOpcode.Imp;
- body.Type = Term.Type;
- return body;
- }
- }
-
- public class ExistsExpr : QuantifierExpr {
- public ExistsExpr(IToken tok, List<BoundVar/*!*/>/*!*/ bvars, Expression range, Expression term, Attributes attrs)
- : base(tok, bvars, range, term, attrs) {
- Contract.Requires(cce.NonNullElements(bvars));
- Contract.Requires(tok != null);
- Contract.Requires(term != null);
- }
- public override Expression/*!*/ LogicalBody() {
- if (Range == null) {
- return Term;
- }
- var body = new BinaryExpr(Term.tok, BinaryExpr.Opcode.And, Range, Term);
- body.ResolvedOp = BinaryExpr.ResolvedOpcode.And;
- body.Type = Term.Type;
- return body;
- }
- }
-
- public class SetComprehension : ComprehensionExpr
- {
- public readonly bool TermIsImplicit;
-
- public SetComprehension(IToken/*!*/ tok, List<BoundVar/*!*/>/*!*/ bvars, Expression/*!*/ range, Expression term)
- : base(tok, bvars, range, term ?? new IdentifierExpr(tok, bvars[0].Name), null) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(bvars));
- Contract.Requires(1 <= bvars.Count);
- Contract.Requires(range != null);
-
- TermIsImplicit = term == null;
- }
- }
- public class MapComprehension : ComprehensionExpr
- {
- public MapComprehension(IToken/*!*/ tok, List<BoundVar/*!*/>/*!*/ bvars, Expression/*!*/ range, Expression term)
- : base(tok, bvars, range, term, null) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(bvars));
- Contract.Requires(1 <= bvars.Count);
- Contract.Requires(range != null);
- Contract.Requires(term != null);
- }
- }
-
- public class WildcardExpr : Expression
- { // a WildcardExpr can occur only in reads clauses and a loop's decreases clauses (with different meanings)
- public WildcardExpr(IToken tok)
- : base(tok) {
- Contract.Requires(tok != null);
- }
- }
-
- public abstract class PredicateExpr : Expression
- {
- public readonly Expression Guard;
- public readonly Expression Body;
- public PredicateExpr(IToken tok, Expression guard, Expression body)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(guard != null);
- Contract.Requires(body != null);
- Guard = guard;
- Body = body;
- }
- public abstract string Kind { get; }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Guard;
- yield return Body;
- }
- }
- }
-
- public class AssertExpr : PredicateExpr
- {
- public AssertExpr(IToken tok, Expression guard, Expression body)
- : base(tok, guard, body) {
- Contract.Requires(tok != null);
- Contract.Requires(guard != null);
- Contract.Requires(body != null);
- }
- public override string Kind { get { return "assert"; } }
- }
-
- public class AssumeExpr : PredicateExpr
- {
- public AssumeExpr(IToken tok, Expression guard, Expression body)
- : base(tok, guard, body) {
- Contract.Requires(tok != null);
- Contract.Requires(guard != null);
- Contract.Requires(body != null);
- }
- public override string Kind { get { return "assume"; } }
- }
-
- public class ITEExpr : Expression
- {
- public readonly Expression Test;
- public readonly Expression Thn;
- public readonly Expression Els;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Test != null);
- Contract.Invariant(Thn != null);
- Contract.Invariant(Els != null);
- }
-
- public ITEExpr(IToken tok, Expression test, Expression thn, Expression els)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(test != null);
- Contract.Requires(thn != null);
- Contract.Requires(els != null);
- this.Test = test;
- this.Thn = thn;
- this.Els = els;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Test;
- yield return Thn;
- yield return Els;
- }
- }
- }
-
- public class MatchExpr : Expression { // a MatchExpr is an "extended expression" and is only allowed in certain places
- public readonly Expression Source;
- public readonly List<MatchCaseExpr/*!*/>/*!*/ Cases;
- public readonly List<DatatypeCtor/*!*/> MissingCases = new List<DatatypeCtor>(); // filled in during resolution
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Source != null);
- Contract.Invariant(cce.NonNullElements(Cases));
- Contract.Invariant(cce.NonNullElements(MissingCases));
- }
-
- public MatchExpr(IToken tok, Expression source, [Captured] List<MatchCaseExpr/*!*/>/*!*/ cases)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(source != null);
- Contract.Requires(cce.NonNullElements(cases));
- this.Source = source;
- this.Cases = cases;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get {
- yield return Source;
- foreach (var mc in Cases) {
- yield return mc.Body;
- }
- }
- }
- }
-
- public abstract class MatchCase
- {
- public readonly IToken tok;
- public readonly string Id;
- public DatatypeCtor Ctor; // filled in by resolution
- public readonly List<BoundVar/*!*/>/*!*/ Arguments;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(tok != null);
- Contract.Invariant(Id != null);
- Contract.Invariant(cce.NonNullElements(Arguments));
- }
-
- public MatchCase(IToken tok, string id, [Captured] List<BoundVar/*!*/>/*!*/ arguments) {
- Contract.Requires(tok != null);
- Contract.Requires(id != null);
- Contract.Requires(cce.NonNullElements(arguments));
- this.tok = tok;
- this.Id = id;
- this.Arguments = arguments;
- }
- }
-
- public class MatchCaseExpr : MatchCase
- {
- public readonly Expression/*!*/ Body;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Body != null);
- }
-
- public MatchCaseExpr(IToken tok, string id, [Captured] List<BoundVar/*!*/>/*!*/ arguments, Expression body)
- : base(tok, id, arguments)
- {
- Contract.Requires(tok != null);
- Contract.Requires(id != null);
- Contract.Requires(cce.NonNullElements(arguments));
- Contract.Requires(body != null);
- this.Body = body;
- }
- }
-
- public class BoxingCastExpr : Expression { // a BoxingCastExpr is used only as a temporary placeholding during translation
- public readonly Expression E;
- public readonly Type FromType;
- public readonly Type ToType;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- Contract.Invariant(FromType != null);
- Contract.Invariant(ToType != null);
- }
-
- public BoxingCastExpr(Expression e, Type fromType, Type toType)
- : base(e.tok) {
- Contract.Requires(e != null);
- Contract.Requires(fromType != null);
- Contract.Requires(toType != null);
-
- E = e;
- FromType = fromType;
- ToType = toType;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { yield return E; }
- }
- }
-
- public class UnboxingCastExpr : Expression { // an UnboxingCastExpr is used only as a temporary placeholding during translation
- public readonly Expression E;
- public readonly Type FromType;
- public readonly Type ToType;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- Contract.Invariant(FromType != null);
- Contract.Invariant(ToType != null);
- }
-
- public UnboxingCastExpr(Expression e, Type fromType, Type toType)
- : base(e.tok) {
- Contract.Requires(e != null);
- Contract.Requires(fromType != null);
- Contract.Requires(toType != null);
-
- E = e;
- FromType = fromType;
- ToType = toType;
- }
-
- public override IEnumerable<Expression> SubExpressions {
- get { yield return E; }
- }
- }
-
-
- public class MaybeFreeExpression {
- public readonly Expression E;
- public readonly bool IsFree;
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- }
-
- private Attributes attributes;
- public Attributes Attributes {
- get {
- return attributes;
- }
- set {
- attributes = value;
- }
- }
-
- public bool HasAttributes() {
- return Attributes != null;
- }
-
- public MaybeFreeExpression(Expression e)
- : this(e, false, null)
- {
- Contract.Requires(e != null);
- }
-
- public MaybeFreeExpression(Expression e, bool isFree)
- : this(e, isFree, null)
- {
- Contract.Requires(e != null);
- }
-
- public MaybeFreeExpression(Expression e, bool isFree, Attributes attrs) {
- Contract.Requires(e != null);
- E = e;
- IsFree = isFree;
- Attributes = attrs;
- }
- }
-
-
- public class FrameExpression {
- public readonly IToken tok;
- public readonly Expression E; // may be a WildcardExpr
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(E != null);
- Contract.Invariant(!(E is WildcardExpr) || FieldName == null && Field == null);
- }
-
- public readonly string FieldName;
- public Field Field; // filled in during resolution (but is null if FieldName is)
-
- /// <summary>
- /// If a "fieldName" is given, then "tok" denotes its source location. Otherwise, "tok"
- /// denotes the source location of "e".
- /// </summary>
- public FrameExpression(IToken tok, Expression e, string fieldName) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(!(e is WildcardExpr) || fieldName == null);
- this.tok = tok;
- E = e;
- FieldName = fieldName;
- }
- }
-
- /// <summary>
- /// This class represents a piece of concrete syntax in the parse tree. During resolution,
- /// it gets "replaced" by the expression in "ResolvedExpression".
- /// </summary>
- public abstract class ConcreteSyntaxExpression : Expression
- {
- public Expression ResolvedExpression; // filled in during resolution; after resolution, manipulation of "this" should proceed as with manipulating "this.ResolvedExpression"
- public ConcreteSyntaxExpression(IToken tok)
- : base(tok) {
- }
- public override IEnumerable<Expression> SubExpressions {
- get {
- if (ResolvedExpression != null) {
- yield return ResolvedExpression;
- }
- }
- }
- }
-
- public class ParensExpression : ConcreteSyntaxExpression
- {
- public readonly Expression E;
- public ParensExpression(IToken tok, Expression e)
- : base(tok) {
- E = e;
- }
- }
-
- public class ChainingExpression : ConcreteSyntaxExpression
- {
- public readonly List<Expression> Operands;
- public readonly List<BinaryExpr.Opcode> Operators;
- public readonly Expression E;
- public ChainingExpression(IToken tok, List<Expression> operands, List<BinaryExpr.Opcode> operators, Expression desugaring)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(operands != null);
- Contract.Requires(operators != null);
- Contract.Requires(desugaring != null);
- Contract.Requires(operands.Count == operators.Count + 1);
-
- Operands = operands;
- Operators = operators;
- E = desugaring;
- }
- }
-
- /// <summary>
- /// An ExprDotName desugars into either a FieldSelectExpr or a FunctionCallExpr (with a parameterless predicate function).
- /// </summary>
- public class ExprDotName : ConcreteSyntaxExpression
- {
- public readonly Expression Obj;
- public readonly string SuffixName;
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(Obj != null);
- Contract.Invariant(SuffixName != null);
- }
-
- public ExprDotName(IToken tok, Expression obj, string suffixName)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(obj != null);
- Contract.Requires(suffixName != null);
- this.Obj = obj;
- this.SuffixName = suffixName;
- }
- }
-
- public class IdentifierSequence : ConcreteSyntaxExpression
- {
- public readonly List<IToken> Tokens;
- public readonly IToken OpenParen;
- public readonly List<Expression> Arguments;
- public IdentifierSequence(List<IToken> tokens, IToken openParen, List<Expression> args)
- : base(tokens[0]) {
- Contract.Requires(tokens != null && 1 <= tokens.Count);
- /* "args" is null to indicate the absence of a parenthesized suffix */
- Contract.Requires(args == null || openParen != null);
-
- Tokens = tokens;
- OpenParen = openParen;
- Arguments = args;
- }
- }
-
-
- public class Specification<T> where T : class
- {
- public readonly List<T> Expressions;
-
- [ContractInvariantMethod]
- private void ObjectInvariant()
- {
- Contract.Invariant(Expressions == null || cce.NonNullElements<T>(Expressions));
- }
-
-
- public Specification(List<T> exprs, Attributes attrs)
- {
- Contract.Requires(exprs == null || cce.NonNullElements<T>(exprs));
- Expressions = exprs;
- Attributes = attrs;
- }
-
- private Attributes attributes;
- public Attributes Attributes
- {
- get
- {
- return attributes;
- }
- set
- {
- attributes = value;
- }
- }
-
- public bool HasAttributes()
- {
- return Attributes != null;
- }
- }
- public abstract class TranslationTask
- {
-
- }
- public class MethodCheck : TranslationTask
- {
- public readonly Method Refined;
- public readonly Method Refining;
- public MethodCheck(Method a, Method b) {
- Refined = b;
- Refining = a;
- }
- }
- public class FunctionCheck : TranslationTask
- {
- public readonly Function Refined;
- public readonly Function Refining;
- public FunctionCheck(Function a, Function b) {
- Refined = b;
- Refining = a;
- }
- }
-}
diff --git a/Source/Dafny/DafnyMain.cs b/Source/Dafny/DafnyMain.cs
deleted file mode 100644
index 6091e522..00000000
--- a/Source/Dafny/DafnyMain.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using Bpl = Microsoft.Boogie;
-
-namespace Microsoft.Dafny {
- public class Main {
- /// <summary>
- /// Returns null on success, or an error string otherwise.
- /// </summary>
- public static string ParseCheck(List<string/*!*/>/*!*/ fileNames, string/*!*/ programName, out Program program)
- //modifies Bpl.CommandLineOptions.Clo.XmlSink.*;
- {
- Contract.Requires(programName != null);
- Contract.Requires(fileNames != null);
- program = null;
- ModuleDecl module = new LiteralModuleDecl(new DefaultModuleDecl(), null);
- BuiltIns builtIns = new BuiltIns();
- foreach (string dafnyFileName in fileNames){
- Contract.Assert(dafnyFileName != null);
- if (Bpl.CommandLineOptions.Clo.XmlSink != null && Bpl.CommandLineOptions.Clo.XmlSink.IsOpen) {
- Bpl.CommandLineOptions.Clo.XmlSink.WriteFileFragment(dafnyFileName);
- }
- if (Bpl.CommandLineOptions.Clo.Trace)
- {
- Console.WriteLine("Parsing " + dafnyFileName);
- }
-
- int errorCount;
- try
- {
- errorCount = Dafny.Parser.Parse(dafnyFileName, module, builtIns);
- if (errorCount != 0)
- {
- return string.Format("{0} parse errors detected in {1}", errorCount, dafnyFileName);
- }
- }
- catch (IOException e)
- {
- return string.Format("Error opening file \"{0}\": {1}", dafnyFileName, e.Message);
- }
- }
-
- program = new Program(programName, module, builtIns);
-
- if (DafnyOptions.O.DafnyPrintFile != null) {
- string filename = DafnyOptions.O.DafnyPrintFile;
- if (filename == "-") {
- Printer pr = new Printer(System.Console.Out);
- pr.PrintProgram(program);
- } else {
- using (TextWriter writer = new System.IO.StreamWriter(filename)) {
- Printer pr = new Printer(writer);
- pr.PrintProgram(program);
- }
- }
- }
-
- if (Bpl.CommandLineOptions.Clo.NoResolve || Bpl.CommandLineOptions.Clo.NoTypecheck) { return null; }
-
- Dafny.Resolver r = new Dafny.Resolver(program);
- r.ResolveProgram(program);
- if (DafnyOptions.O.DafnyPrintResolvedFile != null) {
- string filename = DafnyOptions.O.DafnyPrintResolvedFile;
- if (filename == "-") {
- Printer pr = new Printer(System.Console.Out);
- pr.PrintProgram(program);
- } else {
- using (TextWriter writer = new System.IO.StreamWriter(filename)) {
- Printer pr = new Printer(writer);
- pr.PrintProgram(program);
- }
- }
- }
- if (r.ErrorCount != 0) {
- return string.Format("{0} resolution/type errors detected in {1}", r.ErrorCount, programName);
- }
-
- return null; // success
- }
- }
-}
diff --git a/Source/Dafny/DafnyOptions.cs b/Source/Dafny/DafnyOptions.cs
deleted file mode 100644
index d5057017..00000000
--- a/Source/Dafny/DafnyOptions.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics.Contracts;
-using Bpl = Microsoft.Boogie;
-
-namespace Microsoft.Dafny
-{
- public class DafnyOptions : Bpl.CommandLineOptions
- {
- public DafnyOptions()
- : base("Dafny", "Dafny program verifier") {
- }
-
- private static DafnyOptions clo;
- public static DafnyOptions O {
- get { return clo; }
- }
-
- public static void Install(DafnyOptions options) {
- Contract.Requires(options != null);
- clo = options;
- Bpl.CommandLineOptions.Install(options);
- }
-
- public bool DisallowSoundnessCheating = false;
- public int Induction = 3;
- public int InductionHeuristic = 6;
- public string DafnyPrelude = null;
- public string DafnyPrintFile = null;
- public string DafnyPrintResolvedFile = null;
- public bool Compile = true;
- public bool ForceCompile = false;
- public bool SpillTargetCode = false;
-
- protected override bool ParseOption(string name, Bpl.CommandLineOptionEngine.CommandLineParseState ps) {
- var args = ps.args; // convenient synonym
-
- switch (name) {
- case "dprelude":
- if (ps.ConfirmArgumentCount(1)) {
- DafnyPrelude = args[ps.i];
- }
- return true;
-
- case "dprint":
- if (ps.ConfirmArgumentCount(1)) {
- DafnyPrintFile = args[ps.i];
- }
- return true;
-
- case "rprint":
- if (ps.ConfirmArgumentCount(1)) {
- DafnyPrintResolvedFile = args[ps.i];
- }
- return true;
-
- case "compile": {
- int compile = 0;
- if (ps.GetNumericArgument(ref compile, 3)) {
- // convert option to two booleans
- Compile = compile == 1 || compile == 2;
- ForceCompile = compile == 2;
- }
- return true;
- }
-
- case "spillTargetCode": {
- int spill = 0;
- if (ps.GetNumericArgument(ref spill, 2)) {
- SpillTargetCode = spill != 0; // convert to a boolean
- }
- return true;
- }
-
- case "noCheating": {
- int cheat = 0; // 0 is default, allows cheating
- if (ps.GetNumericArgument(ref cheat, 2)) {
- DisallowSoundnessCheating = cheat == 1;
- }
- return true;
- }
-
- case "induction":
- ps.GetNumericArgument(ref Induction, 4);
- return true;
-
- case "inductionHeuristic":
- ps.GetNumericArgument(ref InductionHeuristic, 7);
- return true;
-
- default:
- break;
- }
- // not a Dafny-specific option, so defer to superclass
- return base.ParseOption(name, ps);
- }
-
- public override void ApplyDefaultOptions() {
- base.ApplyDefaultOptions();
-
- // expand macros in filenames, now that LogPrefix is fully determined
- ExpandFilename(ref DafnyPrelude, LogPrefix, FileTimestamp);
- ExpandFilename(ref DafnyPrintFile, LogPrefix, FileTimestamp);
- }
-
- public override void AttributeUsage() {
- // TODO: provide attribute help here
- }
-
- public override void Usage() {
- Console.WriteLine(@" ---- Dafny options ---------------------------------------------------------
-
- Multiple .dfy files supplied on the command line are concatenated into one
- Dafny program.
-
- /dprelude:<file>
- choose Dafny prelude file
- /dprint:<file>
- print Dafny program after parsing it
- (use - as <file> to print to console)
- /rprint:<file>
- print Dafny program after resolving it
- (use - as <file> to print to console)
- /compile:<n> 0 - do not compile Dafny program
- 1 (default) - upon successful verification of the Dafny
- program, compile Dafny program to C# program out.cs
- 2 - always attempt to compile Dafny program to C# program
- out.cs, regardless of verification outcome
- /spillTargetCode:<n>
- 0 (default) - don't write the compiled Dafny program (but
- still compile it, if /compile indicates to do so)
- 1 - write the compiled Dafny program as a .cs file
- /noCheating:<n>
- 0 (default) - allow assume statements and free invariants
- 1 - treat all assumptions as asserts, and drop free.
- /induction:<n>
- 0 - never do induction, not even when attributes request it
- 1 - only apply induction when attributes request it
- 2 - apply induction as requested (by attributes) and also
- for heuristically chosen quantifiers
- 3 (default) - apply induction as requested, and for
- heuristically chosen quantifiers and ghost methods
- /inductionHeuristic:<n>
- 0 - least discriminating induction heuristic (that is, lean
- toward applying induction more often)
- 1,2,3,4,5 - levels in between, ordered as follows as far as
- how discriminating they are: 0 < 1 < 2 < (3,4) < 5 < 6
- 6 (default) - most discriminating
-");
- base.Usage(); // also print the Boogie options
- }
- }
-}
diff --git a/Source/Dafny/DafnyPipeline.csproj b/Source/Dafny/DafnyPipeline.csproj
deleted file mode 100644
index b4c2ae1e..00000000
--- a/Source/Dafny/DafnyPipeline.csproj
+++ /dev/null
@@ -1,199 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{FE44674A-1633-4917-99F4-57635E6FA740}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>DafnyPipeline</RootNamespace>
- <AssemblyName>DafnyPipeline</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
- <SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\InterimKey.snk</AssemblyOriginatorKeyFile>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>3.5</OldToolsVersion>
- <UpgradeBackupLocation />
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- <TargetFrameworkProfile>
- </TargetFrameworkProfile>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
- <CodeContractsContainerAnalysis>False</CodeContractsContainerAnalysis>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly>
- </CodeContractsCustomRewriterAssembly>
- <CodeContractsCustomRewriterClass>
- </CodeContractsCustomRewriterClass>
- <CodeContractsLibPaths>
- </CodeContractsLibPaths>
- <CodeContractsExtraRewriteOptions>
- </CodeContractsExtraRewriteOptions>
- <CodeContractsExtraAnalysisOptions>
- </CodeContractsExtraAnalysisOptions>
- <CodeContractsBaseLineFile>
- </CodeContractsBaseLineFile>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\Checked\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
- <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
- <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
- <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly />
- <CodeContractsCustomRewriterClass />
- <CodeContractsLibPaths />
- <CodeContractsExtraRewriteOptions />
- <CodeContractsExtraAnalysisOptions />
- <CodeContractsBaseLineFile />
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Basetypes, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\Binaries\Basetypes.dll</HintPath>
- </Reference>
- <Reference Include="Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\Binaries\Core.dll</HintPath>
- </Reference>
- <Reference Include="ParserHelper">
- <HintPath>..\..\Binaries\ParserHelper.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.Numerics" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Cloner.cs" />
- <Compile Include="Util.cs" />
- <Compile Include="Compiler.cs" />
- <Compile Include="DafnyAst.cs" />
- <Compile Include="DafnyMain.cs" />
- <Compile Include="DafnyOptions.cs" />
- <Compile Include="Printer.cs" />
- <Compile Include="RefinementTransformer.cs" />
- <Compile Include="Resolver.cs" />
- <Compile Include="Rewriter.cs" />
- <Compile Include="SccGraph.cs" />
- <Compile Include="Translator.cs" />
- <Compile Include="..\version.cs" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="cce.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="Dafny.atg" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Parser.cs" />
- <Compile Include="Scanner.cs" />
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/Source/Dafny/Makefile b/Source/Dafny/Makefile
deleted file mode 100644
index 2013b4f9..00000000
--- a/Source/Dafny/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-COCO = Coco.exe
-
-# ###############################################################################
-# The frame files are no longer in this directory. They must be downloaded
-# from http://boogiepartners.codeplex.com/. Update the FRAME_DIR variable to
-# point to whatever directory you install that into.
-# ###############################################################################
-FRAME_DIR = ..\..\..\boogiepartners\CocoR\Modified
-
-# "all" depends on 2 files, really (Parser.cs and Scanner.cs), but they
-# are both generated in one go and I don't know a better way to tell
-# nmake that. --KRML
-all: Parser.cs
-
-Parser.cs: $(FRAME_DIR)\Scanner.frame $(FRAME_DIR)\Parser.frame Dafny.atg
- $(COCO) Dafny.atg -namespace Microsoft.Dafny -frames $(FRAME_DIR)
-
-clean:
- if exist Scanner.cs del Scanner.cs
- if exist Scanner.cs.old del Scanner.cs.old
- if exist Parser.cs del Parser.cs
- if exist Parser.cs.old del Parser.cs.old
diff --git a/Source/Dafny/Parser.cs b/Source/Dafny/Parser.cs
deleted file mode 100644
index 032b8a10..00000000
--- a/Source/Dafny/Parser.cs
+++ /dev/null
@@ -1,3470 +0,0 @@
-using System.Collections.Generic;
-using System.Numerics;
-using Microsoft.Boogie;
-using System.IO;
-using System.Text;
-
-
-using System;
-using System.Diagnostics.Contracts;
-
-namespace Microsoft.Dafny {
-
-
-
-public class Parser {
- public const int _EOF = 0;
- public const int _ident = 1;
- public const int _digits = 2;
- public const int _arrayToken = 3;
- public const int _string = 4;
- public const int _colon = 5;
- public const int _lbrace = 6;
- public const int _rbrace = 7;
- public const int maxT = 115;
-
- const bool T = true;
- const bool x = false;
- const int minErrDist = 2;
-
- public Scanner/*!*/ scanner;
- public Errors/*!*/ errors;
-
- public Token/*!*/ t; // last recognized token
- public Token/*!*/ la; // lookahead token
- int errDist = minErrDist;
-
-readonly Expression/*!*/ dummyExpr;
-readonly AssignmentRhs/*!*/ dummyRhs;
-readonly FrameExpression/*!*/ dummyFrameExpr;
-readonly Statement/*!*/ dummyStmt;
-readonly Attributes.Argument/*!*/ dummyAttrArg;
-readonly ModuleDecl theModule;
-readonly BuiltIns theBuiltIns;
-int anonymousIds = 0;
-
-struct MemberModifiers {
- public bool IsGhost;
- public bool IsStatic;
-}
-// helper routine for parsing call statements
-///<summary>
-/// Parses top-level things (modules, classes, datatypes, class members) from "filename"
-/// and appends them in appropriate form to "module".
-/// Returns the number of parsing errors encountered.
-/// Note: first initialize the Scanner.
-///</summary>
-public static int Parse (string/*!*/ filename, ModuleDecl module, BuiltIns builtIns) /* throws System.IO.IOException */ {
- Contract.Requires(filename != null);
- Contract.Requires(module != null);
- string s;
- if (filename == "stdin.dfy") {
- s = Microsoft.Boogie.ParserHelper.Fill(System.Console.In, new List<string>());
- return Parse(s, filename, module, builtIns);
- } else {
- using (System.IO.StreamReader reader = new System.IO.StreamReader(filename)) {
- s = Microsoft.Boogie.ParserHelper.Fill(reader, new List<string>());
- return Parse(s, filename, module, builtIns);
- }
- }
-}
-///<summary>
-/// Parses top-level things (modules, classes, datatypes, class members)
-/// and appends them in appropriate form to "module".
-/// Returns the number of parsing errors encountered.
-/// Note: first initialize the Scanner.
-///</summary>
-public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module, BuiltIns builtIns) {
- Contract.Requires(s != null);
- Contract.Requires(filename != null);
- Contract.Requires(module != null);
- Errors errors = new Errors();
- return Parse(s, filename, module, builtIns, errors);
-}
-///<summary>
-/// Parses top-level things (modules, classes, datatypes, class members)
-/// and appends them in appropriate form to "module".
-/// Returns the number of parsing errors encountered.
-/// Note: first initialize the Scanner with the given Errors sink.
-///</summary>
-public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module, BuiltIns builtIns,
- Errors/*!*/ errors) {
- Contract.Requires(s != null);
- Contract.Requires(filename != null);
- Contract.Requires(module != null);
- Contract.Requires(errors != null);
- byte[]/*!*/ buffer = cce.NonNull( UTF8Encoding.Default.GetBytes(s));
- MemoryStream ms = new MemoryStream(buffer,false);
- Scanner scanner = new Scanner(ms, errors, filename);
- Parser parser = new Parser(scanner, errors, module, builtIns);
- parser.Parse();
- return parser.errors.count;
-}
-public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors, ModuleDecl module, BuiltIns builtIns)
- : this(scanner, errors) // the real work
-{
- // initialize readonly fields
- dummyExpr = new LiteralExpr(Token.NoToken);
- dummyRhs = new ExprRhs(dummyExpr, null);
- dummyFrameExpr = new FrameExpression(dummyExpr.tok, dummyExpr, null);
- dummyStmt = new ReturnStmt(Token.NoToken, null);
- dummyAttrArg = new Attributes.Argument(Token.NoToken, "dummyAttrArg");
- theModule = module;
- theBuiltIns = builtIns;
-}
-
-bool IsAttribute() {
- Token x = scanner.Peek();
- return la.kind == _lbrace && x.kind == _colon;
-}
-/*--------------------------------------------------------------------------*/
-
-
- public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors) {
- this.scanner = scanner;
- this.errors = errors;
- Token/*!*/ tok = new Token();
- tok.val = "";
- this.la = tok;
- this.t = new Token(); // just to satisfy its non-null constraint
- }
-
- void SynErr (int n) {
- if (errDist >= minErrDist) errors.SynErr(la.filename, la.line, la.col, n);
- errDist = 0;
- }
-
- public void SemErr (string/*!*/ msg) {
- Contract.Requires(msg != null);
- if (errDist >= minErrDist) errors.SemErr(t, msg);
- errDist = 0;
- }
-
- public void SemErr(IToken/*!*/ tok, string/*!*/ msg) {
- Contract.Requires(tok != null);
- Contract.Requires(msg != null);
- errors.SemErr(tok, msg);
- }
-
- void Get () {
- for (;;) {
- t = la;
- la = scanner.Scan();
- if (la.kind <= maxT) { ++errDist; break; }
-
- la = t;
- }
- }
-
- void Expect (int n) {
- if (la.kind==n) Get(); else { SynErr(n); }
- }
-
- bool StartOf (int s) {
- return set[s, la.kind];
- }
-
- void ExpectWeak (int n, int follow) {
- if (la.kind == n) Get();
- else {
- SynErr(n);
- while (!StartOf(follow)) Get();
- }
- }
-
-
- bool WeakSeparator(int n, int syFol, int repFol) {
- int kind = la.kind;
- if (kind == n) {Get(); return true;}
- else if (StartOf(repFol)) {return false;}
- else {
- SynErr(n);
- while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
- Get();
- kind = la.kind;
- }
- return StartOf(syFol);
- }
- }
-
-
- void Dafny() {
- ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
- List<MemberDecl/*!*/> membersDefaultClass = new List<MemberDecl/*!*/>();
- ModuleDecl submodule;
- // to support multiple files, create a default module only if theModule is null
- DefaultModuleDecl defaultModule = (DefaultModuleDecl)((LiteralModuleDecl)theModule).ModuleDef;
- // theModule should be a DefaultModuleDecl (actually, the singular DefaultModuleDecl)
- Contract.Assert(defaultModule != null);
- bool isGhost;
-
- while (StartOf(1)) {
- isGhost = false;
- if (la.kind == 8) {
- Get();
- isGhost = true;
- }
- switch (la.kind) {
- case 9: case 11: {
- SubModuleDecl(defaultModule, isGhost, out submodule);
- defaultModule.TopLevelDecls.Add(submodule);
- break;
- }
- case 18: {
- if (isGhost) { SemErr(t, "a class is not allowed to be declared as 'ghost'"); }
- ClassDecl(defaultModule, out c);
- defaultModule.TopLevelDecls.Add(c);
- break;
- }
- case 20: case 21: {
- if (isGhost) { SemErr(t, "a datatype/codatatype is not allowed to be declared as 'ghost'"); }
- DatatypeDecl(defaultModule, out dt);
- defaultModule.TopLevelDecls.Add(dt);
- break;
- }
- case 25: {
- if (isGhost) { SemErr(t, "a type is not allowed to be declared as 'ghost'"); }
- ArbitraryTypeDecl(defaultModule, out at);
- defaultModule.TopLevelDecls.Add(at);
- break;
- }
- case 29: {
- if (isGhost) { SemErr(t, "an iterator is not allowed to be declared as 'ghost'"); }
- IteratorDecl(defaultModule, out iter);
- defaultModule.TopLevelDecls.Add(iter);
- break;
- }
- case 8: case 19: case 23: case 34: case 35: case 52: case 53: case 54: {
- ClassMemberDecl(membersDefaultClass, isGhost, false);
- break;
- }
- default: SynErr(116); break;
- }
- }
- DefaultClassDecl defaultClass = null;
- foreach (TopLevelDecl topleveldecl in defaultModule.TopLevelDecls) {
- defaultClass = topleveldecl as DefaultClassDecl;
- if (defaultClass != null) {
- defaultClass.Members.AddRange(membersDefaultClass);
- break;
- }
- }
- if (defaultClass == null) { // create the default class here, because it wasn't found
- defaultClass = new DefaultClassDecl(defaultModule, membersDefaultClass);
- defaultModule.TopLevelDecls.Add(defaultClass);
- }
- Expect(0);
- }
-
- void SubModuleDecl(ModuleDefinition parent, bool isOverallModuleGhost, out ModuleDecl submodule) {
- ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
- Attributes attrs = null; IToken/*!*/ id;
- List<MemberDecl/*!*/> namedModuleDefaultClassMembers = new List<MemberDecl>();;
- List<IToken> idRefined = null, idPath = null, idAssignment = null;
- bool isGhost = false;
- ModuleDefinition module;
- ModuleDecl sm;
- submodule = null; // appease compiler
- bool opened = false;
-
- if (la.kind == 9) {
- Get();
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 10) {
- Get();
- QualifiedName(out idRefined);
- }
- module = new ModuleDefinition(id, id.val, isOverallModuleGhost, false, idRefined == null ? null : idRefined, attrs, false);
- Expect(6);
- module.BodyStartTok = t;
- while (StartOf(1)) {
- isGhost = false;
- if (la.kind == 8) {
- Get();
- isGhost = true;
- }
- switch (la.kind) {
- case 9: case 11: {
- SubModuleDecl(module, isGhost, out sm);
- module.TopLevelDecls.Add(sm);
- break;
- }
- case 18: {
- if (isGhost) { SemErr(t, "a class is not allowed to be declared as 'ghost'"); }
- ClassDecl(module, out c);
- module.TopLevelDecls.Add(c);
- break;
- }
- case 20: case 21: {
- if (isGhost) { SemErr(t, "a datatype/codatatype is not allowed to be declared as 'ghost'"); }
- DatatypeDecl(module, out dt);
- module.TopLevelDecls.Add(dt);
- break;
- }
- case 25: {
- if (isGhost) { SemErr(t, "a type is not allowed to be declared as 'ghost'"); }
- ArbitraryTypeDecl(module, out at);
- module.TopLevelDecls.Add(at);
- break;
- }
- case 29: {
- if (isGhost) { SemErr(t, "an iterator is not allowed to be declared as 'ghost'"); }
- IteratorDecl(module, out iter);
- module.TopLevelDecls.Add(iter);
- break;
- }
- case 8: case 19: case 23: case 34: case 35: case 52: case 53: case 54: {
- ClassMemberDecl(namedModuleDefaultClassMembers, isGhost, false);
- break;
- }
- default: SynErr(117); break;
- }
- }
- Expect(7);
- module.BodyEndTok = t;
- module.TopLevelDecls.Add(new DefaultClassDecl(module, namedModuleDefaultClassMembers));
- submodule = new LiteralModuleDecl(module, parent);
- } else if (la.kind == 11) {
- Get();
- if (la.kind == 12) {
- Get();
- opened = true;
- }
- NoUSIdent(out id);
- if (la.kind == 13) {
- Get();
- QualifiedName(out idPath);
- Expect(14);
- submodule = new AliasModuleDecl(idPath, id, parent, opened);
- } else if (la.kind == 14) {
- Get();
- idPath = new List<IToken>(); idPath.Add(id); submodule = new AliasModuleDecl(idPath, id, parent, opened);
- } else if (la.kind == 15) {
- Get();
- QualifiedName(out idPath);
- if (la.kind == 16) {
- Get();
- QualifiedName(out idAssignment);
- }
- Expect(14);
- submodule = new AbstractModuleDecl(idPath, id, parent, idAssignment, opened);
- } else SynErr(118);
- } else SynErr(119);
- }
-
- void ClassDecl(ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c) {
- Contract.Requires(module != null);
- Contract.Ensures(Contract.ValueAtReturn(out c) != null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
- List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
- IToken bodyStart;
-
- while (!(la.kind == 0 || la.kind == 18)) {SynErr(120); Get();}
- Expect(18);
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 32) {
- GenericParameters(typeArgs);
- }
- Expect(6);
- bodyStart = t;
- while (StartOf(2)) {
- ClassMemberDecl(members, false, true);
- }
- Expect(7);
- c = new ClassDecl(id, id.val, module, typeArgs, members, attrs);
- c.BodyStartTok = bodyStart;
- c.BodyEndTok = t;
-
- }
-
- void DatatypeDecl(ModuleDefinition/*!*/ module, out DatatypeDecl/*!*/ dt) {
- Contract.Requires(module != null);
- Contract.Ensures(Contract.ValueAtReturn(out dt)!=null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
- List<DatatypeCtor/*!*/> ctors = new List<DatatypeCtor/*!*/>();
- IToken bodyStart = Token.NoToken; // dummy assignment
- bool co = false;
-
- while (!(la.kind == 0 || la.kind == 20 || la.kind == 21)) {SynErr(121); Get();}
- if (la.kind == 20) {
- Get();
- } else if (la.kind == 21) {
- Get();
- co = true;
- } else SynErr(122);
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 32) {
- GenericParameters(typeArgs);
- }
- Expect(13);
- bodyStart = t;
- DatatypeMemberDecl(ctors);
- while (la.kind == 22) {
- Get();
- DatatypeMemberDecl(ctors);
- }
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(123); Get();}
- Expect(14);
- if (co) {
- dt = new CoDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
- } else {
- dt = new IndDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
- }
- dt.BodyStartTok = bodyStart;
- dt.BodyEndTok = t;
-
- }
-
- void ArbitraryTypeDecl(ModuleDefinition/*!*/ module, out ArbitraryTypeDecl at) {
- IToken/*!*/ id;
- Attributes attrs = null;
- var eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
-
- Expect(25);
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 26) {
- Get();
- Expect(27);
- Expect(28);
- eqSupport = TypeParameter.EqualitySupportValue.Required;
- }
- at = new ArbitraryTypeDecl(id, id.val, module, eqSupport, attrs);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(124); Get();}
- Expect(14);
- }
-
- void IteratorDecl(ModuleDefinition module, out IteratorDecl/*!*/ iter) {
- Contract.Ensures(Contract.ValueAtReturn(out iter) != null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/>/*!*/ typeArgs = new List<TypeParameter/*!*/>();
- IToken openParen;
- List<Formal/*!*/> ins = new List<Formal/*!*/>();
- List<Formal/*!*/> outs = new List<Formal/*!*/>();
- List<FrameExpression/*!*/> reads = new List<FrameExpression/*!*/>();
- List<FrameExpression/*!*/> mod = new List<FrameExpression/*!*/>();
- List<Expression/*!*/> decreases = new List<Expression>();
- List<MaybeFreeExpression/*!*/> req = new List<MaybeFreeExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> ens = new List<MaybeFreeExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> yieldReq = new List<MaybeFreeExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> yieldEns = new List<MaybeFreeExpression/*!*/>();
- List<Expression/*!*/> dec = new List<Expression/*!*/>();
- Attributes readsAttrs = null;
- Attributes modAttrs = null;
- Attributes decrAttrs = null;
- BlockStmt body = null;
- bool signatureOmitted = false;
- IToken bodyStart = Token.NoToken;
- IToken bodyEnd = Token.NoToken;
-
- while (!(la.kind == 0 || la.kind == 29)) {SynErr(125); Get();}
- Expect(29);
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 26 || la.kind == 32) {
- if (la.kind == 32) {
- GenericParameters(typeArgs);
- }
- Formals(true, true, ins, out openParen);
- if (la.kind == 30) {
- Get();
- Formals(false, true, outs, out openParen);
- }
- } else if (la.kind == 31) {
- Get();
- signatureOmitted = true; openParen = Token.NoToken;
- } else SynErr(126);
- while (StartOf(3)) {
- IteratorSpec(reads, mod, decreases, req, ens, yieldReq, yieldEns, ref readsAttrs, ref modAttrs, ref decrAttrs);
- }
- if (la.kind == 6) {
- BlockStmt(out body, out bodyStart, out bodyEnd);
- }
- iter = new IteratorDecl(id, id.val, module, typeArgs, ins, outs,
- new Specification<FrameExpression>(reads, readsAttrs),
- new Specification<FrameExpression>(mod, modAttrs),
- new Specification<Expression>(decreases, decrAttrs),
- req, ens, yieldReq, yieldEns,
- body, attrs, signatureOmitted);
- iter.BodyStartTok = bodyStart;
- iter.BodyEndTok = bodyEnd;
-
- }
-
- void ClassMemberDecl(List<MemberDecl/*!*/>/*!*/ mm, bool isAlreadyGhost, bool allowConstructors) {
- Contract.Requires(cce.NonNullElements(mm));
- Method/*!*/ m;
- Function/*!*/ f;
- MemberModifiers mmod = new MemberModifiers();
- mmod.IsGhost = isAlreadyGhost;
-
- while (la.kind == 8 || la.kind == 19) {
- if (la.kind == 8) {
- Get();
- mmod.IsGhost = true;
- } else {
- Get();
- mmod.IsStatic = true;
- }
- }
- if (la.kind == 23) {
- FieldDecl(mmod, mm);
- } else if (la.kind == 52 || la.kind == 53 || la.kind == 54) {
- FunctionDecl(mmod, out f);
- mm.Add(f);
- } else if (la.kind == 34 || la.kind == 35) {
- MethodDecl(mmod, allowConstructors, out m);
- mm.Add(m);
- } else SynErr(127);
- }
-
- void Attribute(ref Attributes attrs) {
- Expect(6);
- AttributeBody(ref attrs);
- Expect(7);
- }
-
- void NoUSIdent(out IToken/*!*/ x) {
- Contract.Ensures(Contract.ValueAtReturn(out x) != null);
- Expect(1);
- x = t;
- if (x.val.StartsWith("_")) {
- SemErr("cannot declare identifier beginning with underscore");
- }
-
- }
-
- void QualifiedName(out List<IToken> ids) {
- IToken id; ids = new List<IToken>();
- Ident(out id);
- ids.Add(id);
- while (la.kind == 17) {
- Get();
- Ident(out id);
- ids.Add(id);
- }
- }
-
- void Ident(out IToken/*!*/ x) {
- Contract.Ensures(Contract.ValueAtReturn(out x) != null);
- Expect(1);
- x = t;
- }
-
- void GenericParameters(List<TypeParameter/*!*/>/*!*/ typeArgs) {
- Contract.Requires(cce.NonNullElements(typeArgs));
- IToken/*!*/ id;
- TypeParameter.EqualitySupportValue eqSupport;
-
- Expect(32);
- NoUSIdent(out id);
- eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
- if (la.kind == 26) {
- Get();
- Expect(27);
- Expect(28);
- eqSupport = TypeParameter.EqualitySupportValue.Required;
- }
- typeArgs.Add(new TypeParameter(id, id.val, eqSupport));
- while (la.kind == 24) {
- Get();
- NoUSIdent(out id);
- eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
- if (la.kind == 26) {
- Get();
- Expect(27);
- Expect(28);
- eqSupport = TypeParameter.EqualitySupportValue.Required;
- }
- typeArgs.Add(new TypeParameter(id, id.val, eqSupport));
- }
- Expect(33);
- }
-
- void FieldDecl(MemberModifiers mmod, List<MemberDecl/*!*/>/*!*/ mm) {
- Contract.Requires(cce.NonNullElements(mm));
- Attributes attrs = null;
- IToken/*!*/ id; Type/*!*/ ty;
-
- while (!(la.kind == 0 || la.kind == 23)) {SynErr(128); Get();}
- Expect(23);
- if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
-
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- IdentType(out id, out ty, false);
- mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
- while (la.kind == 24) {
- Get();
- IdentType(out id, out ty, false);
- mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
- }
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(129); Get();}
- Expect(14);
- }
-
- void FunctionDecl(MemberModifiers mmod, out Function/*!*/ f) {
- Contract.Ensures(Contract.ValueAtReturn(out f)!=null);
- Attributes attrs = null;
- IToken/*!*/ id = Token.NoToken; // to please compiler
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
- List<Formal/*!*/> formals = new List<Formal/*!*/>();
- Type/*!*/ returnType = new BoolType();
- List<Expression/*!*/> reqs = new List<Expression/*!*/>();
- List<Expression/*!*/> ens = new List<Expression/*!*/>();
- List<FrameExpression/*!*/> reads = new List<FrameExpression/*!*/>();
- List<Expression/*!*/> decreases;
- Expression body = null;
- bool isPredicate = false; bool isCoPredicate = false;
- bool isFunctionMethod = false;
- IToken openParen = null;
- IToken bodyStart = Token.NoToken;
- IToken bodyEnd = Token.NoToken;
- bool signatureOmitted = false;
-
- if (la.kind == 52) {
- Get();
- if (la.kind == 34) {
- Get();
- isFunctionMethod = true;
- }
- if (mmod.IsGhost) { SemErr(t, "functions cannot be declared 'ghost' (they are ghost by default)"); }
-
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 26 || la.kind == 32) {
- if (la.kind == 32) {
- GenericParameters(typeArgs);
- }
- Formals(true, isFunctionMethod, formals, out openParen);
- Expect(5);
- Type(out returnType);
- } else if (la.kind == 31) {
- Get();
- signatureOmitted = true;
- openParen = Token.NoToken;
- } else SynErr(130);
- } else if (la.kind == 53) {
- Get();
- isPredicate = true;
- if (la.kind == 34) {
- Get();
- isFunctionMethod = true;
- }
- if (mmod.IsGhost) { SemErr(t, "predicates cannot be declared 'ghost' (they are ghost by default)"); }
-
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (StartOf(4)) {
- if (la.kind == 32) {
- GenericParameters(typeArgs);
- }
- if (la.kind == 26) {
- Formals(true, isFunctionMethod, formals, out openParen);
- if (la.kind == 5) {
- Get();
- SemErr(t, "predicates do not have an explicitly declared return type; it is always bool");
- }
- }
- } else if (la.kind == 31) {
- Get();
- signatureOmitted = true;
- openParen = Token.NoToken;
- } else SynErr(131);
- } else if (la.kind == 54) {
- Get();
- isCoPredicate = true;
- if (mmod.IsGhost) { SemErr(t, "copredicates cannot be declared 'ghost' (they are ghost by default)"); }
-
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (StartOf(4)) {
- if (la.kind == 32) {
- GenericParameters(typeArgs);
- }
- if (la.kind == 26) {
- Formals(true, isFunctionMethod, formals, out openParen);
- if (la.kind == 5) {
- Get();
- SemErr(t, "copredicates do not have an explicitly declared return type; it is always bool");
- }
- }
- } else if (la.kind == 31) {
- Get();
- signatureOmitted = true;
- openParen = Token.NoToken;
- } else SynErr(132);
- } else SynErr(133);
- decreases = isCoPredicate ? null : new List<Expression/*!*/>();
- while (StartOf(5)) {
- FunctionSpec(reqs, reads, ens, decreases);
- }
- if (la.kind == 6) {
- FunctionBody(out body, out bodyStart, out bodyEnd);
- }
- if (isPredicate) {
- f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals,
- reqs, reads, ens, new Specification<Expression>(decreases, null), body, Predicate.BodyOriginKind.OriginalOrInherited, attrs, signatureOmitted);
- } else if (isCoPredicate) {
- f = new CoPredicate(id, id.val, mmod.IsStatic, typeArgs, openParen, formals,
- reqs, reads, ens, body, attrs, signatureOmitted);
- } else {
- f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals, returnType,
- reqs, reads, ens, new Specification<Expression>(decreases, null), body, attrs, signatureOmitted);
- }
- f.BodyStartTok = bodyStart;
- f.BodyEndTok = bodyEnd;
-
- }
-
- void MethodDecl(MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m) {
- Contract.Ensures(Contract.ValueAtReturn(out m) !=null);
- IToken/*!*/ id;
- Attributes attrs = null;
- List<TypeParameter/*!*/>/*!*/ typeArgs = new List<TypeParameter/*!*/>();
- IToken openParen;
- List<Formal/*!*/> ins = new List<Formal/*!*/>();
- List<Formal/*!*/> outs = new List<Formal/*!*/>();
- List<MaybeFreeExpression/*!*/> req = new List<MaybeFreeExpression/*!*/>();
- List<FrameExpression/*!*/> mod = new List<FrameExpression/*!*/>();
- List<MaybeFreeExpression/*!*/> ens = new List<MaybeFreeExpression/*!*/>();
- List<Expression/*!*/> dec = new List<Expression/*!*/>();
- Attributes decAttrs = null;
- Attributes modAttrs = null;
- BlockStmt body = null;
- bool isConstructor = false;
- bool signatureOmitted = false;
- IToken bodyStart = Token.NoToken;
- IToken bodyEnd = Token.NoToken;
-
- while (!(la.kind == 0 || la.kind == 34 || la.kind == 35)) {SynErr(134); Get();}
- if (la.kind == 34) {
- Get();
- } else if (la.kind == 35) {
- Get();
- if (allowConstructor) {
- isConstructor = true;
- } else {
- SemErr(t, "constructors are only allowed in classes");
- }
-
- } else SynErr(135);
- if (isConstructor) {
- if (mmod.IsGhost) {
- SemErr(t, "constructors cannot be declared 'ghost'");
- }
- if (mmod.IsStatic) {
- SemErr(t, "constructors cannot be declared 'static'");
- }
- }
-
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 26 || la.kind == 32) {
- if (la.kind == 32) {
- GenericParameters(typeArgs);
- }
- Formals(true, !mmod.IsGhost, ins, out openParen);
- if (la.kind == 36) {
- Get();
- if (isConstructor) { SemErr(t, "constructors cannot have out-parameters"); }
- Formals(false, !mmod.IsGhost, outs, out openParen);
- }
- } else if (la.kind == 31) {
- Get();
- signatureOmitted = true; openParen = Token.NoToken;
- } else SynErr(136);
- while (StartOf(6)) {
- MethodSpec(req, mod, ens, dec, ref decAttrs, ref modAttrs);
- }
- if (la.kind == 6) {
- BlockStmt(out body, out bodyStart, out bodyEnd);
- }
- if (isConstructor) {
- m = new Constructor(id, id.val, typeArgs, ins,
- req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureOmitted);
- } else {
- m = new Method(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs,
- req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureOmitted);
- }
- m.BodyStartTok = bodyStart;
- m.BodyEndTok = bodyEnd;
-
- }
-
- void DatatypeMemberDecl(List<DatatypeCtor/*!*/>/*!*/ ctors) {
- Contract.Requires(cce.NonNullElements(ctors));
- Attributes attrs = null;
- IToken/*!*/ id;
- List<Formal/*!*/> formals = new List<Formal/*!*/>();
-
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- NoUSIdent(out id);
- if (la.kind == 26) {
- FormalsOptionalIds(formals);
- }
- ctors.Add(new DatatypeCtor(id, id.val, formals, attrs));
- }
-
- void FormalsOptionalIds(List<Formal/*!*/>/*!*/ formals) {
- Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; string/*!*/ name; bool isGhost;
- Expect(26);
- if (StartOf(7)) {
- TypeIdentOptional(out id, out name, out ty, out isGhost);
- formals.Add(new Formal(id, name, ty, true, isGhost));
- while (la.kind == 24) {
- Get();
- TypeIdentOptional(out id, out name, out ty, out isGhost);
- formals.Add(new Formal(id, name, ty, true, isGhost));
- }
- }
- Expect(28);
- }
-
- void IdentType(out IToken/*!*/ id, out Type/*!*/ ty, bool allowWildcardId) {
- Contract.Ensures(Contract.ValueAtReturn(out id) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
- WildIdent(out id, allowWildcardId);
- Expect(5);
- Type(out ty);
- }
-
- void GIdentType(bool allowGhostKeyword, out IToken/*!*/ id, out Type/*!*/ ty, out bool isGhost) {
- Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
- isGhost = false;
- if (la.kind == 8) {
- Get();
- if (allowGhostKeyword) { isGhost = true; } else { SemErr(t, "formal cannot be declared 'ghost' in this context"); }
- }
- IdentType(out id, out ty, true);
- }
-
- void WildIdent(out IToken/*!*/ x, bool allowWildcardId) {
- Contract.Ensures(Contract.ValueAtReturn(out x) != null);
- Expect(1);
- x = t;
- if (x.val.StartsWith("_")) {
- if (allowWildcardId && x.val.Length == 1) {
- t.val = "_v" + anonymousIds++;
- } else {
- SemErr("cannot declare identifier beginning with underscore");
- }
- }
-
- }
-
- void Type(out Type/*!*/ ty) {
- Contract.Ensures(Contract.ValueAtReturn(out ty) != null); IToken/*!*/ tok;
- TypeAndToken(out tok, out ty);
- }
-
- void LocalIdentTypeOptional(out VarDecl/*!*/ var, bool isGhost) {
- IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
-
- WildIdent(out id, true);
- if (la.kind == 5) {
- Get();
- Type(out ty);
- optType = ty;
- }
- var = new VarDecl(id, id.val, optType == null ? new InferredTypeProxy() : optType, isGhost);
- }
-
- void IdentTypeOptional(out BoundVar/*!*/ var) {
- Contract.Ensures(Contract.ValueAtReturn(out var)!=null); IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
-
- WildIdent(out id, true);
- if (la.kind == 5) {
- Get();
- Type(out ty);
- optType = ty;
- }
- var = new BoundVar(id, id.val, optType == null ? new InferredTypeProxy() : optType);
- }
-
- void TypeIdentOptional(out IToken/*!*/ id, out string/*!*/ identName, out Type/*!*/ ty, out bool isGhost) {
- Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out identName)!=null);
- string name = null; isGhost = false;
- if (la.kind == 8) {
- Get();
- isGhost = true;
- }
- TypeAndToken(out id, out ty);
- if (la.kind == 5) {
- Get();
- UserDefinedType udt = ty as UserDefinedType;
- if (udt != null && udt.TypeArgs.Count == 0) {
- name = udt.Name;
- } else {
- SemErr(id, "invalid formal-parameter name in datatype constructor");
- }
-
- Type(out ty);
- }
- if (name != null) {
- identName = name;
- } else {
- identName = "#" + anonymousIds++;
- }
-
- }
-
- void TypeAndToken(out IToken/*!*/ tok, out Type/*!*/ ty) {
- Contract.Ensures(Contract.ValueAtReturn(out tok)!=null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null); tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
-
- switch (la.kind) {
- case 44: {
- Get();
- tok = t;
- break;
- }
- case 45: {
- Get();
- tok = t; ty = new NatType();
- break;
- }
- case 46: {
- Get();
- tok = t; ty = new IntType();
- break;
- }
- case 47: {
- Get();
- tok = t; gt = new List<Type/*!*/>();
- GenericInstantiation(gt);
- if (gt.Count != 1) {
- SemErr("set type expects exactly one type argument");
- }
- ty = new SetType(gt[0]);
-
- break;
- }
- case 48: {
- Get();
- tok = t; gt = new List<Type/*!*/>();
- GenericInstantiation(gt);
- if (gt.Count != 1) {
- SemErr("multiset type expects exactly one type argument");
- }
- ty = new MultiSetType(gt[0]);
-
- break;
- }
- case 49: {
- Get();
- tok = t; gt = new List<Type/*!*/>();
- GenericInstantiation(gt);
- if (gt.Count != 1) {
- SemErr("seq type expects exactly one type argument");
- }
- ty = new SeqType(gt[0]);
-
- break;
- }
- case 50: {
- Get();
- tok = t; gt = new List<Type/*!*/>();
- GenericInstantiation(gt);
- if (gt.Count != 2) {
- SemErr("map type expects exactly two type arguments");
- }
- else { ty = new MapType(gt[0], gt[1]); }
-
- break;
- }
- case 1: case 3: case 51: {
- ReferenceType(out tok, out ty);
- break;
- }
- default: SynErr(137); break;
- }
- }
-
- void Formals(bool incoming, bool allowGhostKeyword, List<Formal/*!*/>/*!*/ formals, out IToken openParen) {
- Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; bool isGhost;
- Expect(26);
- openParen = t;
- if (la.kind == 1 || la.kind == 8) {
- GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
- formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
- while (la.kind == 24) {
- Get();
- GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
- formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
- }
- }
- Expect(28);
- }
-
- void IteratorSpec(List<FrameExpression/*!*/>/*!*/ reads, List<FrameExpression/*!*/>/*!*/ mod, List<Expression/*!*/> decreases,
-List<MaybeFreeExpression/*!*/>/*!*/ req, List<MaybeFreeExpression/*!*/>/*!*/ ens,
-List<MaybeFreeExpression/*!*/>/*!*/ yieldReq, List<MaybeFreeExpression/*!*/>/*!*/ yieldEns,
-ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
- Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; bool isYield = false; Attributes ensAttrs = null;
-
- while (!(StartOf(8))) {SynErr(138); Get();}
- if (la.kind == 42) {
- Get();
- while (IsAttribute()) {
- Attribute(ref readsAttrs);
- }
- if (StartOf(9)) {
- FrameExpression(out fe);
- reads.Add(fe);
- while (la.kind == 24) {
- Get();
- FrameExpression(out fe);
- reads.Add(fe);
- }
- }
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(139); Get();}
- Expect(14);
- } else if (la.kind == 37) {
- Get();
- while (IsAttribute()) {
- Attribute(ref modAttrs);
- }
- if (StartOf(9)) {
- FrameExpression(out fe);
- mod.Add(fe);
- while (la.kind == 24) {
- Get();
- FrameExpression(out fe);
- mod.Add(fe);
- }
- }
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(140); Get();}
- Expect(14);
- } else if (StartOf(10)) {
- if (la.kind == 38) {
- Get();
- isFree = true;
- }
- if (la.kind == 43) {
- Get();
- isYield = true;
- }
- if (la.kind == 39) {
- Get();
- Expression(out e);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(141); Get();}
- Expect(14);
- if (isYield) {
- yieldReq.Add(new MaybeFreeExpression(e, isFree));
- } else {
- req.Add(new MaybeFreeExpression(e, isFree));
- }
-
- } else if (la.kind == 40) {
- Get();
- while (IsAttribute()) {
- Attribute(ref ensAttrs);
- }
- Expression(out e);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(142); Get();}
- Expect(14);
- if (isYield) {
- yieldEns.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
- } else {
- ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
- }
-
- } else SynErr(143);
- } else if (la.kind == 41) {
- Get();
- while (IsAttribute()) {
- Attribute(ref decrAttrs);
- }
- DecreasesList(decreases, false);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(144); Get();}
- Expect(14);
- } else SynErr(145);
- }
-
- void BlockStmt(out BlockStmt/*!*/ block, out IToken bodyStart, out IToken bodyEnd) {
- Contract.Ensures(Contract.ValueAtReturn(out block) != null);
- List<Statement/*!*/> body = new List<Statement/*!*/>();
-
- Expect(6);
- bodyStart = t;
- while (StartOf(11)) {
- Stmt(body);
- }
- Expect(7);
- bodyEnd = t;
- block = new BlockStmt(bodyStart, body);
- }
-
- void MethodSpec(List<MaybeFreeExpression/*!*/>/*!*/ req, List<FrameExpression/*!*/>/*!*/ mod, List<MaybeFreeExpression/*!*/>/*!*/ ens,
-List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes modAttrs) {
- Contract.Requires(cce.NonNullElements(req)); Contract.Requires(cce.NonNullElements(mod)); Contract.Requires(cce.NonNullElements(ens)); Contract.Requires(cce.NonNullElements(decreases));
- Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; Attributes ensAttrs = null;
-
- while (!(StartOf(12))) {SynErr(146); Get();}
- if (la.kind == 37) {
- Get();
- while (IsAttribute()) {
- Attribute(ref modAttrs);
- }
- if (StartOf(9)) {
- FrameExpression(out fe);
- mod.Add(fe);
- while (la.kind == 24) {
- Get();
- FrameExpression(out fe);
- mod.Add(fe);
- }
- }
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(147); Get();}
- Expect(14);
- } else if (la.kind == 38 || la.kind == 39 || la.kind == 40) {
- if (la.kind == 38) {
- Get();
- isFree = true;
- }
- if (la.kind == 39) {
- Get();
- Expression(out e);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(148); Get();}
- Expect(14);
- req.Add(new MaybeFreeExpression(e, isFree));
- } else if (la.kind == 40) {
- Get();
- while (IsAttribute()) {
- Attribute(ref ensAttrs);
- }
- Expression(out e);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(149); Get();}
- Expect(14);
- ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
- } else SynErr(150);
- } else if (la.kind == 41) {
- Get();
- while (IsAttribute()) {
- Attribute(ref decAttrs);
- }
- DecreasesList(decreases, true);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(151); Get();}
- Expect(14);
- } else SynErr(152);
- }
-
- void FrameExpression(out FrameExpression/*!*/ fe) {
- Contract.Ensures(Contract.ValueAtReturn(out fe) != null);
- Expression/*!*/ e;
- IToken/*!*/ id;
- string fieldName = null; IToken feTok = null;
- fe = null;
-
- if (StartOf(13)) {
- Expression(out e);
- feTok = e.tok;
- if (la.kind == 56) {
- Get();
- Ident(out id);
- fieldName = id.val; feTok = id;
- }
- fe = new FrameExpression(feTok, e, fieldName);
- } else if (la.kind == 56) {
- Get();
- Ident(out id);
- fieldName = id.val;
- fe = new FrameExpression(id, new ImplicitThisExpr(id), fieldName);
- } else SynErr(153);
- }
-
- void Expression(out Expression/*!*/ e) {
- EquivExpression(out e);
- }
-
- void DecreasesList(List<Expression/*!*/> decreases, bool allowWildcard) {
- Expression/*!*/ e;
- PossiblyWildExpression(out e);
- if (!allowWildcard && e is WildcardExpr) {
- SemErr(e.tok, "'decreases *' is only allowed on loops and tail-recursive methods");
- } else {
- decreases.Add(e);
- }
-
- while (la.kind == 24) {
- Get();
- PossiblyWildExpression(out e);
- if (!allowWildcard && e is WildcardExpr) {
- SemErr(e.tok, "'decreases *' is only allowed on loops and tail-recursive methods");
- } else {
- decreases.Add(e);
- }
-
- }
- }
-
- void GenericInstantiation(List<Type/*!*/>/*!*/ gt) {
- Contract.Requires(cce.NonNullElements(gt)); Type/*!*/ ty;
- Expect(32);
- Type(out ty);
- gt.Add(ty);
- while (la.kind == 24) {
- Get();
- Type(out ty);
- gt.Add(ty);
- }
- Expect(33);
- }
-
- void ReferenceType(out IToken/*!*/ tok, out Type/*!*/ ty) {
- Contract.Ensures(Contract.ValueAtReturn(out tok) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
- tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
- List<IToken> path;
-
- if (la.kind == 51) {
- Get();
- tok = t; ty = new ObjectType();
- } else if (la.kind == 3) {
- Get();
- tok = t; gt = new List<Type/*!*/>();
- GenericInstantiation(gt);
- if (gt.Count != 1) {
- SemErr("array type expects exactly one type argument");
- }
- int dims = 1;
- if (tok.val.Length != 5) {
- dims = int.Parse(tok.val.Substring(5));
- }
- ty = theBuiltIns.ArrayType(tok, dims, gt[0], true);
-
- } else if (la.kind == 1) {
- Ident(out tok);
- gt = new List<Type/*!*/>();
- path = new List<IToken>();
- while (la.kind == 17) {
- path.Add(tok);
- Get();
- Ident(out tok);
- }
- if (la.kind == 32) {
- GenericInstantiation(gt);
- }
- ty = new UserDefinedType(tok, tok.val, gt, path);
- } else SynErr(154);
- }
-
- void FunctionSpec(List<Expression/*!*/>/*!*/ reqs, List<FrameExpression/*!*/>/*!*/ reads, List<Expression/*!*/>/*!*/ ens, List<Expression/*!*/> decreases) {
- Contract.Requires(cce.NonNullElements(reqs));
- Contract.Requires(cce.NonNullElements(reads));
- Contract.Requires(decreases == null || cce.NonNullElements(decreases));
- Expression/*!*/ e; FrameExpression/*!*/ fe;
- if (la.kind == 39) {
- while (!(la.kind == 0 || la.kind == 39)) {SynErr(155); Get();}
- Get();
- Expression(out e);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(156); Get();}
- Expect(14);
- reqs.Add(e);
- } else if (la.kind == 42) {
- Get();
- if (StartOf(14)) {
- PossiblyWildFrameExpression(out fe);
- reads.Add(fe);
- while (la.kind == 24) {
- Get();
- PossiblyWildFrameExpression(out fe);
- reads.Add(fe);
- }
- }
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(157); Get();}
- Expect(14);
- } else if (la.kind == 40) {
- Get();
- Expression(out e);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(158); Get();}
- Expect(14);
- ens.Add(e);
- } else if (la.kind == 41) {
- Get();
- if (decreases == null) {
- SemErr(t, "'decreases' clauses are meaningless for copredicates, so they are not allowed");
- decreases = new List<Expression/*!*/>();
- }
-
- DecreasesList(decreases, false);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(159); Get();}
- Expect(14);
- } else SynErr(160);
- }
-
- void FunctionBody(out Expression/*!*/ e, out IToken bodyStart, out IToken bodyEnd) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); e = dummyExpr;
- Expect(6);
- bodyStart = t;
- Expression(out e);
- Expect(7);
- bodyEnd = t;
- }
-
- void PossiblyWildFrameExpression(out FrameExpression/*!*/ fe) {
- Contract.Ensures(Contract.ValueAtReturn(out fe) != null); fe = dummyFrameExpr;
- if (la.kind == 55) {
- Get();
- fe = new FrameExpression(t, new WildcardExpr(t), null);
- } else if (StartOf(9)) {
- FrameExpression(out fe);
- } else SynErr(161);
- }
-
- void PossiblyWildExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e)!=null);
- e = dummyExpr;
- if (la.kind == 55) {
- Get();
- e = new WildcardExpr(t);
- } else if (StartOf(13)) {
- Expression(out e);
- } else SynErr(162);
- }
-
- void Stmt(List<Statement/*!*/>/*!*/ ss) {
- Statement/*!*/ s;
-
- OneStmt(out s);
- ss.Add(s);
- }
-
- void OneStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; IToken/*!*/ id; string label = null;
- s = dummyStmt; /* to please the compiler */
- BlockStmt bs;
- IToken bodyStart, bodyEnd;
- int breakCount;
-
- while (!(StartOf(15))) {SynErr(163); Get();}
- switch (la.kind) {
- case 6: {
- BlockStmt(out bs, out bodyStart, out bodyEnd);
- s = bs;
- break;
- }
- case 75: {
- AssertStmt(out s);
- break;
- }
- case 63: {
- AssumeStmt(out s);
- break;
- }
- case 76: {
- PrintStmt(out s);
- break;
- }
- case 1: case 2: case 22: case 26: case 101: case 102: case 103: case 104: case 105: case 106: {
- UpdateStmt(out s);
- break;
- }
- case 8: case 23: {
- VarDeclStatement(out s);
- break;
- }
- case 68: {
- IfStmt(out s);
- break;
- }
- case 72: {
- WhileStmt(out s);
- break;
- }
- case 74: {
- MatchStmt(out s);
- break;
- }
- case 77: {
- ParallelStmt(out s);
- break;
- }
- case 78: {
- CalcStmt(out s);
- break;
- }
- case 57: {
- Get();
- x = t;
- NoUSIdent(out id);
- Expect(5);
- OneStmt(out s);
- s.Labels = new LList<Label>(new Label(x, id.val), s.Labels);
- break;
- }
- case 58: {
- Get();
- x = t; breakCount = 1; label = null;
- if (la.kind == 1) {
- NoUSIdent(out id);
- label = id.val;
- } else if (la.kind == 14 || la.kind == 58) {
- while (la.kind == 58) {
- Get();
- breakCount++;
- }
- } else SynErr(164);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(165); Get();}
- Expect(14);
- s = label != null ? new BreakStmt(x, label) : new BreakStmt(x, breakCount);
- break;
- }
- case 43: case 61: {
- ReturnStmt(out s);
- break;
- }
- case 31: {
- SkeletonStmt(out s);
- Expect(14);
- break;
- }
- default: SynErr(166); break;
- }
- }
-
- void AssertStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x;
- Expression e = null; Attributes attrs = null;
-
- Expect(75);
- x = t;
- while (IsAttribute()) {
- Attribute(ref attrs);
- }
- if (StartOf(13)) {
- Expression(out e);
- } else if (la.kind == 31) {
- Get();
- } else SynErr(167);
- Expect(14);
- if (e == null) {
- s = new SkeletonStatement(new AssertStmt(x, new LiteralExpr(x, true), attrs), true, false);
- } else {
- s = new AssertStmt(x, e, attrs);
- }
-
- }
-
- void AssumeStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x;
- Expression e = null; Attributes attrs = null;
-
- Expect(63);
- x = t;
- while (IsAttribute()) {
- Attribute(ref attrs);
- }
- if (StartOf(13)) {
- Expression(out e);
- } else if (la.kind == 31) {
- Get();
- } else SynErr(168);
- if (e == null) {
- s = new SkeletonStatement(new AssumeStmt(x, new LiteralExpr(x, true), attrs), true, false);
- } else {
- s = new AssumeStmt(x, e, attrs);
- }
-
- Expect(14);
- }
-
- void PrintStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Attributes.Argument/*!*/ arg;
- List<Attributes.Argument/*!*/> args = new List<Attributes.Argument/*!*/>();
-
- Expect(76);
- x = t;
- AttributeArg(out arg);
- args.Add(arg);
- while (la.kind == 24) {
- Get();
- AttributeArg(out arg);
- args.Add(arg);
- }
- Expect(14);
- s = new PrintStmt(x, args);
- }
-
- void UpdateStmt(out Statement/*!*/ s) {
- List<Expression> lhss = new List<Expression>();
- List<AssignmentRhs> rhss = new List<AssignmentRhs>();
- Expression e; AssignmentRhs r;
- Expression lhs0;
- IToken x;
- Attributes attrs = null;
- IToken suchThatAssume = null;
- Expression suchThat = null;
-
- Lhs(out e);
- x = e.tok;
- if (la.kind == 6 || la.kind == 14) {
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- Expect(14);
- rhss.Add(new ExprRhs(e, attrs));
- } else if (la.kind == 24 || la.kind == 60 || la.kind == 62) {
- lhss.Add(e); lhs0 = e;
- while (la.kind == 24) {
- Get();
- Lhs(out e);
- lhss.Add(e);
- }
- if (la.kind == 60) {
- Get();
- x = t;
- Rhs(out r, lhs0);
- rhss.Add(r);
- while (la.kind == 24) {
- Get();
- Rhs(out r, lhs0);
- rhss.Add(r);
- }
- } else if (la.kind == 62) {
- Get();
- x = t;
- if (la.kind == 63) {
- Get();
- suchThatAssume = t;
- }
- Expression(out suchThat);
- } else SynErr(169);
- Expect(14);
- } else if (la.kind == 5) {
- Get();
- SemErr(t, "invalid statement (did you forget the 'label' keyword?)");
- } else SynErr(170);
- if (suchThat != null) {
- s = new AssignSuchThatStmt(x, lhss, suchThat, suchThatAssume);
- } else {
- if (lhss.Count == 0 && rhss.Count == 0) {
- s = new BlockStmt(x, new List<Statement>()); // error, give empty statement
- } else {
- s = new UpdateStmt(x, lhss, rhss);
- }
- }
-
- }
-
- void VarDeclStatement(out Statement/*!*/ s) {
- IToken x = null, assignTok = null; bool isGhost = false;
- VarDecl/*!*/ d;
- AssignmentRhs r; IdentifierExpr lhs0;
- List<VarDecl> lhss = new List<VarDecl>();
- List<AssignmentRhs> rhss = new List<AssignmentRhs>();
- IToken suchThatAssume = null;
- Expression suchThat = null;
-
- if (la.kind == 8) {
- Get();
- isGhost = true; x = t;
- }
- Expect(23);
- if (!isGhost) { x = t; }
- LocalIdentTypeOptional(out d, isGhost);
- lhss.Add(d);
- while (la.kind == 24) {
- Get();
- LocalIdentTypeOptional(out d, isGhost);
- lhss.Add(d);
- }
- if (la.kind == 60 || la.kind == 62) {
- if (la.kind == 60) {
- Get();
- assignTok = t;
- lhs0 = new IdentifierExpr(lhss[0].Tok, lhss[0].Name);
- lhs0.Var = lhss[0]; lhs0.Type = lhss[0].OptionalType; // resolve here
-
- Rhs(out r, lhs0);
- rhss.Add(r);
- while (la.kind == 24) {
- Get();
- Rhs(out r, lhs0);
- rhss.Add(r);
- }
- } else {
- Get();
- assignTok = t;
- if (la.kind == 63) {
- Get();
- suchThatAssume = t;
- }
- Expression(out suchThat);
- }
- }
- Expect(14);
- ConcreteUpdateStatement update;
- if (suchThat != null) {
- var ies = new List<Expression>();
- foreach (var lhs in lhss) {
- ies.Add(new IdentifierExpr(lhs.Tok, lhs.Name));
- }
- update = new AssignSuchThatStmt(assignTok, ies, suchThat, suchThatAssume);
- } else if (rhss.Count == 0) {
- update = null;
- } else {
- var ies = new List<Expression>();
- foreach (var lhs in lhss) {
- ies.Add(new AutoGhostIdentifierExpr(lhs.Tok, lhs.Name));
- }
- update = new UpdateStmt(assignTok, ies, rhss);
- }
- s = new VarDeclStmt(x, lhss, update);
-
- }
-
- void IfStmt(out Statement/*!*/ ifStmt) {
- Contract.Ensures(Contract.ValueAtReturn(out ifStmt) != null); IToken/*!*/ x;
- Expression guard = null; bool guardOmitted = false;
- BlockStmt/*!*/ thn;
- BlockStmt/*!*/ bs;
- Statement/*!*/ s;
- Statement els = null;
- IToken bodyStart, bodyEnd;
- List<GuardedAlternative> alternatives;
- ifStmt = dummyStmt; // to please the compiler
-
- Expect(68);
- x = t;
- if (la.kind == 26 || la.kind == 31) {
- if (la.kind == 26) {
- Guard(out guard);
- } else {
- Get();
- guardOmitted = true;
- }
- BlockStmt(out thn, out bodyStart, out bodyEnd);
- if (la.kind == 69) {
- Get();
- if (la.kind == 68) {
- IfStmt(out s);
- els = s;
- } else if (la.kind == 6) {
- BlockStmt(out bs, out bodyStart, out bodyEnd);
- els = bs;
- } else SynErr(171);
- }
- if (guardOmitted) {
- ifStmt = new SkeletonStatement(new IfStmt(x, guard, thn, els), true, false);
- } else {
- ifStmt = new IfStmt(x, guard, thn, els);
- }
-
- } else if (la.kind == 6) {
- AlternativeBlock(out alternatives);
- ifStmt = new AlternativeStmt(x, alternatives);
- } else SynErr(172);
- }
-
- void WhileStmt(out Statement/*!*/ stmt) {
- Contract.Ensures(Contract.ValueAtReturn(out stmt) != null); IToken/*!*/ x;
- Expression guard = null; bool guardOmitted = false;
- List<MaybeFreeExpression/*!*/> invariants = new List<MaybeFreeExpression/*!*/>();
- List<Expression/*!*/> decreases = new List<Expression/*!*/>();
- Attributes decAttrs = null;
- Attributes modAttrs = null;
- List<FrameExpression/*!*/> mod = null;
- BlockStmt/*!*/ body = null; bool bodyOmitted = false;
- IToken bodyStart = null, bodyEnd = null;
- List<GuardedAlternative> alternatives;
- stmt = dummyStmt; // to please the compiler
-
- Expect(72);
- x = t;
- if (la.kind == 26 || la.kind == 31) {
- if (la.kind == 26) {
- Guard(out guard);
- Contract.Assume(guard == null || cce.Owner.None(guard));
- } else {
- Get();
- guardOmitted = true;
- }
- LoopSpec(out invariants, out decreases, out mod, ref decAttrs, ref modAttrs);
- if (la.kind == 6) {
- BlockStmt(out body, out bodyStart, out bodyEnd);
- } else if (la.kind == 31) {
- Get();
- bodyOmitted = true;
- } else SynErr(173);
- if (guardOmitted || bodyOmitted) {
- if (mod != null) {
- SemErr(mod[0].E.tok, "'modifies' clauses are not allowed on refining loops");
- }
- if (body == null) {
- body = new BlockStmt(x, new List<Statement>());
- }
- stmt = new WhileStmt(x, guard, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(null, null), body);
- stmt = new SkeletonStatement(stmt, guardOmitted, bodyOmitted);
- } else {
- // The following statement protects against crashes in case of parsing errors
- body = body ?? new BlockStmt(x, new List<Statement>());
- stmt = new WhileStmt(x, guard, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(mod, modAttrs), body);
- }
-
- } else if (StartOf(16)) {
- LoopSpec(out invariants, out decreases, out mod, ref decAttrs, ref modAttrs);
- AlternativeBlock(out alternatives);
- stmt = new AlternativeLoopStmt(x, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(mod, modAttrs), alternatives);
- } else SynErr(174);
- }
-
- void MatchStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- Token x; Expression/*!*/ e; MatchCaseStmt/*!*/ c;
- List<MatchCaseStmt/*!*/> cases = new List<MatchCaseStmt/*!*/>();
- Expect(74);
- x = t;
- Expression(out e);
- Expect(6);
- while (la.kind == 70) {
- CaseStatement(out c);
- cases.Add(c);
- }
- Expect(7);
- s = new MatchStmt(x, e, cases);
- }
-
- void ParallelStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- IToken/*!*/ x;
- List<BoundVar/*!*/> bvars = null;
- Attributes attrs = null;
- Expression range = null;
- var ens = new List<MaybeFreeExpression/*!*/>();
- bool isFree;
- Expression/*!*/ e;
- BlockStmt/*!*/ block;
- IToken bodyStart, bodyEnd;
-
- Expect(77);
- x = t;
- Expect(26);
- if (la.kind == 1) {
- List<BoundVar/*!*/> bvarsX; Attributes attrsX; Expression rangeX;
- QuantifierDomain(out bvarsX, out attrsX, out rangeX);
- bvars = bvarsX; attrs = attrsX; range = rangeX;
-
- }
- if (bvars == null) { bvars = new List<BoundVar>(); }
- if (range == null) { range = new LiteralExpr(x, true); }
-
- Expect(28);
- while (la.kind == 38 || la.kind == 40) {
- isFree = false;
- if (la.kind == 38) {
- Get();
- isFree = true;
- }
- Expect(40);
- Expression(out e);
- Expect(14);
- ens.Add(new MaybeFreeExpression(e, isFree));
- }
- BlockStmt(out block, out bodyStart, out bodyEnd);
- s = new ParallelStmt(x, bvars, attrs, range, ens, block);
- }
-
- void CalcStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- Token x;
- BinaryExpr.Opcode op, calcOp = BinaryExpr.Opcode.Eq, resOp = BinaryExpr.Opcode.Eq;
- var lines = new List<Expression/*!*/>();
- var hints = new List<BlockStmt/*!*/>();
- var customOps = new List<BinaryExpr.Opcode?>();
- BinaryExpr.Opcode? maybeOp;
- Expression/*!*/ e;
- BlockStmt/*!*/ h;
- IToken opTok;
-
- Expect(78);
- x = t;
- if (StartOf(17)) {
- CalcOp(out opTok, out calcOp);
- maybeOp = Microsoft.Dafny.CalcStmt.ResultOp(calcOp, calcOp); // guard against non-trasitive calcOp (like !=)
- if (maybeOp == null) {
- SemErr(opTok, "the main operator of a calculation must be transitive");
- }
- resOp = calcOp;
-
- }
- Expect(6);
- if (StartOf(13)) {
- Expression(out e);
- lines.Add(e);
- Expect(14);
- while (StartOf(18)) {
- Hint(out h);
- hints.Add(h);
- if (StartOf(17)) {
- CalcOp(out opTok, out op);
- maybeOp = Microsoft.Dafny.CalcStmt.ResultOp(resOp, op);
- if (maybeOp == null) {
- customOps.Add(null); // pretend the operator was not there to satisfy the precondition of the CalcStmt contructor
- SemErr(opTok, "this operator cannot continue this calculation");
- } else {
- customOps.Add(op);
- resOp = (BinaryExpr.Opcode)maybeOp;
- }
-
- } else if (StartOf(13)) {
- customOps.Add(null);
- } else SynErr(175);
- Expression(out e);
- lines.Add(e);
- Expect(14);
- }
- }
- Expect(7);
- s = new CalcStmt(x, calcOp, lines, hints, customOps);
- }
-
- void ReturnStmt(out Statement/*!*/ s) {
- IToken returnTok = null;
- List<AssignmentRhs> rhss = null;
- AssignmentRhs r;
- bool isYield = false;
-
- if (la.kind == 61) {
- Get();
- returnTok = t;
- } else if (la.kind == 43) {
- Get();
- returnTok = t; isYield = true;
- } else SynErr(176);
- if (StartOf(19)) {
- Rhs(out r, null);
- rhss = new List<AssignmentRhs>(); rhss.Add(r);
- while (la.kind == 24) {
- Get();
- Rhs(out r, null);
- rhss.Add(r);
- }
- }
- Expect(14);
- if (isYield) {
- s = new YieldStmt(returnTok, rhss);
- } else {
- s = new ReturnStmt(returnTok, rhss);
- }
-
- }
-
- void SkeletonStmt(out Statement s) {
- List<IToken> names = null;
- List<Expression> exprs = null;
- IToken tok, dotdotdot, whereTok;
- Expression e;
- Expect(31);
- dotdotdot = t;
- if (la.kind == 59) {
- Get();
- names = new List<IToken>(); exprs = new List<Expression>(); whereTok = t;
- Ident(out tok);
- names.Add(tok);
- while (la.kind == 24) {
- Get();
- Ident(out tok);
- names.Add(tok);
- }
- Expect(60);
- Expression(out e);
- exprs.Add(e);
- while (la.kind == 24) {
- Get();
- Expression(out e);
- exprs.Add(e);
- }
- if (exprs.Count != names.Count) {
- SemErr(whereTok, exprs.Count < names.Count ? "not enough expressions" : "too many expressions");
- names = null; exprs = null;
- }
-
- }
- s = new SkeletonStatement(dotdotdot, names, exprs);
- }
-
- void Rhs(out AssignmentRhs r, Expression receiverForInitCall) {
- Contract.Ensures(Contract.ValueAtReturn<AssignmentRhs>(out r) != null);
- IToken/*!*/ x, newToken; Expression/*!*/ e;
- List<Expression> ee = null;
- Type ty = null;
- CallStmt initCall = null;
- List<Expression> args;
- r = dummyRhs; // to please compiler
- Attributes attrs = null;
-
- if (la.kind == 64) {
- Get();
- newToken = t;
- TypeAndToken(out x, out ty);
- if (la.kind == 17 || la.kind == 26 || la.kind == 65) {
- if (la.kind == 65) {
- Get();
- ee = new List<Expression>();
- Expressions(ee);
- Expect(66);
- UserDefinedType tmp = theBuiltIns.ArrayType(x, ee.Count, new IntType(), true);
-
- } else if (la.kind == 17) {
- Get();
- Ident(out x);
- Expect(26);
- args = new List<Expression/*!*/>();
- if (StartOf(13)) {
- Expressions(args);
- }
- Expect(28);
- initCall = new CallStmt(x, new List<Expression>(), receiverForInitCall, x.val, args);
- } else {
- Get();
- var udf = ty as UserDefinedType;
- if (udf != null && 0 < udf.Path.Count && udf.TypeArgs.Count == 0) {
- // The parsed name had the form "A.B.Ctr", so treat "A.B" as the name of the type and "Ctr" as
- // the name of the constructor that's being invoked.
- x = udf.tok;
- ty = new UserDefinedType(udf.Path[0], udf.Path[udf.Path.Count-1].val, new List<Type>(), udf.Path.GetRange(0,udf.Path.Count-1));
- } else {
- SemErr(t, "expected '.'");
- x = null;
- }
- args = new List<Expression/*!*/>();
- if (StartOf(13)) {
- Expressions(args);
- }
- Expect(28);
- if (x != null) {
- initCall = new CallStmt(x, new List<Expression>(), receiverForInitCall, x.val, args);
- }
-
- }
- }
- if (ee != null) {
- r = new TypeRhs(newToken, ty, ee);
- } else {
- r = new TypeRhs(newToken, ty, initCall);
- }
-
- } else if (la.kind == 67) {
- Get();
- x = t;
- Expression(out e);
- r = new ExprRhs(new UnaryExpr(x, UnaryExpr.Opcode.SetChoose, e));
- } else if (la.kind == 55) {
- Get();
- r = new HavocRhs(t);
- } else if (StartOf(13)) {
- Expression(out e);
- r = new ExprRhs(e);
- } else SynErr(177);
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- r.Attributes = attrs;
- }
-
- void Lhs(out Expression e) {
- e = dummyExpr; // the assignment is to please the compiler, the dummy value to satisfy contracts in the event of a parse error
-
- if (la.kind == 1) {
- DottedIdentifiersAndFunction(out e);
- while (la.kind == 17 || la.kind == 65) {
- Suffix(ref e);
- }
- } else if (StartOf(20)) {
- ConstAtomExpression(out e);
- Suffix(ref e);
- while (la.kind == 17 || la.kind == 65) {
- Suffix(ref e);
- }
- } else SynErr(178);
- }
-
- void Expressions(List<Expression/*!*/>/*!*/ args) {
- Contract.Requires(cce.NonNullElements(args)); Expression/*!*/ e;
- Expression(out e);
- args.Add(e);
- while (la.kind == 24) {
- Get();
- Expression(out e);
- args.Add(e);
- }
- }
-
- void Guard(out Expression e) {
- Expression/*!*/ ee; e = null;
- Expect(26);
- if (la.kind == 55) {
- Get();
- e = null;
- } else if (StartOf(13)) {
- Expression(out ee);
- e = ee;
- } else SynErr(179);
- Expect(28);
- }
-
- void AlternativeBlock(out List<GuardedAlternative> alternatives) {
- alternatives = new List<GuardedAlternative>();
- IToken x;
- Expression e;
- List<Statement> body;
-
- Expect(6);
- while (la.kind == 70) {
- Get();
- x = t;
- Expression(out e);
- Expect(71);
- body = new List<Statement>();
- while (StartOf(11)) {
- Stmt(body);
- }
- alternatives.Add(new GuardedAlternative(x, e, body));
- }
- Expect(7);
- }
-
- void LoopSpec(out List<MaybeFreeExpression/*!*/> invariants, out List<Expression/*!*/> decreases, out List<FrameExpression/*!*/> mod, ref Attributes decAttrs, ref Attributes modAttrs) {
- FrameExpression/*!*/ fe;
- invariants = new List<MaybeFreeExpression/*!*/>();
- MaybeFreeExpression invariant = null;
- decreases = new List<Expression/*!*/>();
- mod = null;
-
- while (StartOf(21)) {
- if (la.kind == 38 || la.kind == 73) {
- Invariant(out invariant);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(180); Get();}
- Expect(14);
- invariants.Add(invariant);
- } else if (la.kind == 41) {
- while (!(la.kind == 0 || la.kind == 41)) {SynErr(181); Get();}
- Get();
- while (IsAttribute()) {
- Attribute(ref decAttrs);
- }
- DecreasesList(decreases, true);
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(182); Get();}
- Expect(14);
- } else {
- while (!(la.kind == 0 || la.kind == 37)) {SynErr(183); Get();}
- Get();
- while (IsAttribute()) {
- Attribute(ref modAttrs);
- }
- mod = mod ?? new List<FrameExpression>();
- if (StartOf(9)) {
- FrameExpression(out fe);
- mod.Add(fe);
- while (la.kind == 24) {
- Get();
- FrameExpression(out fe);
- mod.Add(fe);
- }
- }
- while (!(la.kind == 0 || la.kind == 14)) {SynErr(184); Get();}
- Expect(14);
- }
- }
- }
-
- void Invariant(out MaybeFreeExpression/*!*/ invariant) {
- bool isFree = false; Expression/*!*/ e; List<string> ids = new List<string>(); invariant = null; Attributes attrs = null;
- while (!(la.kind == 0 || la.kind == 38 || la.kind == 73)) {SynErr(185); Get();}
- if (la.kind == 38) {
- Get();
- isFree = true;
- }
- Expect(73);
- while (IsAttribute()) {
- Attribute(ref attrs);
- }
- Expression(out e);
- invariant = new MaybeFreeExpression(e, isFree, attrs);
- }
-
- void CaseStatement(out MatchCaseStmt/*!*/ c) {
- Contract.Ensures(Contract.ValueAtReturn(out c) != null);
- IToken/*!*/ x, id;
- List<BoundVar/*!*/> arguments = new List<BoundVar/*!*/>();
- BoundVar/*!*/ bv;
- List<Statement/*!*/> body = new List<Statement/*!*/>();
-
- Expect(70);
- x = t;
- Ident(out id);
- if (la.kind == 26) {
- Get();
- IdentTypeOptional(out bv);
- arguments.Add(bv);
- while (la.kind == 24) {
- Get();
- IdentTypeOptional(out bv);
- arguments.Add(bv);
- }
- Expect(28);
- }
- Expect(71);
- while (StartOf(11)) {
- Stmt(body);
- }
- c = new MatchCaseStmt(x, id.val, arguments, body);
- }
-
- void AttributeArg(out Attributes.Argument/*!*/ arg) {
- Contract.Ensures(Contract.ValueAtReturn(out arg) != null); Expression/*!*/ e; arg = dummyAttrArg;
- if (la.kind == 4) {
- Get();
- arg = new Attributes.Argument(t, t.val.Substring(1, t.val.Length-2));
- } else if (StartOf(13)) {
- Expression(out e);
- arg = new Attributes.Argument(t, e);
- } else SynErr(186);
- }
-
- void QuantifierDomain(out List<BoundVar/*!*/> bvars, out Attributes attrs, out Expression range) {
- bvars = new List<BoundVar/*!*/>();
- BoundVar/*!*/ bv;
- attrs = null;
- range = null;
-
- IdentTypeOptional(out bv);
- bvars.Add(bv);
- while (la.kind == 24) {
- Get();
- IdentTypeOptional(out bv);
- bvars.Add(bv);
- }
- while (la.kind == 6) {
- Attribute(ref attrs);
- }
- if (la.kind == 22) {
- Get();
- Expression(out range);
- }
- }
-
- void CalcOp(out IToken x, out BinaryExpr.Opcode/*!*/ op) {
- Contract.Ensures(Microsoft.Dafny.CalcStmt.ValidOp(Contract.ValueAtReturn(out op)));
- op = BinaryExpr.Opcode.Eq; // Returns Eq if parsing fails because it is compatible with any other operator
- x = null;
-
- switch (la.kind) {
- case 27: {
- Get();
- x = t; op = BinaryExpr.Opcode.Eq;
- break;
- }
- case 32: {
- Get();
- x = t; op = BinaryExpr.Opcode.Lt;
- break;
- }
- case 33: {
- Get();
- x = t; op = BinaryExpr.Opcode.Gt;
- break;
- }
- case 79: {
- Get();
- x = t; op = BinaryExpr.Opcode.Le;
- break;
- }
- case 80: {
- Get();
- x = t; op = BinaryExpr.Opcode.Ge;
- break;
- }
- case 81: {
- Get();
- x = t; op = BinaryExpr.Opcode.Neq;
- break;
- }
- case 82: {
- Get();
- x = t; op = BinaryExpr.Opcode.Neq;
- break;
- }
- case 83: {
- Get();
- x = t; op = BinaryExpr.Opcode.Le;
- break;
- }
- case 84: {
- Get();
- x = t; op = BinaryExpr.Opcode.Ge;
- break;
- }
- case 85: case 86: {
- EquivOp();
- x = t; op = BinaryExpr.Opcode.Iff;
- break;
- }
- case 87: case 88: {
- ImpliesOp();
- x = t; op = BinaryExpr.Opcode.Imp;
- break;
- }
- default: SynErr(187); break;
- }
- }
-
- void Hint(out BlockStmt s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); // returns an empty block statement if the hint is empty
- var subhints = new List<Statement/*!*/>();
- IToken bodyStart, bodyEnd;
- BlockStmt/*!*/ block;
- Statement/*!*/ calc;
- Token x = la;
-
- while (la.kind == 6 || la.kind == 78) {
- if (la.kind == 6) {
- BlockStmt(out block, out bodyStart, out bodyEnd);
- subhints.Add(block);
- } else {
- CalcStmt(out calc);
- subhints.Add(calc);
- }
- }
- s = new BlockStmt(x, subhints); // if the hint is empty x is the first token of the next line, but it doesn't matter cause the block statement is just used as a container
-
- }
-
- void EquivOp() {
- if (la.kind == 85) {
- Get();
- } else if (la.kind == 86) {
- Get();
- } else SynErr(188);
- }
-
- void ImpliesOp() {
- if (la.kind == 87) {
- Get();
- } else if (la.kind == 88) {
- Get();
- } else SynErr(189);
- }
-
- void EquivExpression(out Expression/*!*/ e0) {
- Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
- ImpliesExpression(out e0);
- while (la.kind == 85 || la.kind == 86) {
- EquivOp();
- x = t;
- ImpliesExpression(out e1);
- e0 = new BinaryExpr(x, BinaryExpr.Opcode.Iff, e0, e1);
- }
- }
-
- void ImpliesExpression(out Expression/*!*/ e0) {
- Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
- LogicalExpression(out e0);
- if (la.kind == 87 || la.kind == 88) {
- ImpliesOp();
- x = t;
- ImpliesExpression(out e1);
- e0 = new BinaryExpr(x, BinaryExpr.Opcode.Imp, e0, e1);
- }
- }
-
- void LogicalExpression(out Expression/*!*/ e0) {
- Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
- RelationalExpression(out e0);
- if (StartOf(22)) {
- if (la.kind == 89 || la.kind == 90) {
- AndOp();
- x = t;
- RelationalExpression(out e1);
- e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1);
- while (la.kind == 89 || la.kind == 90) {
- AndOp();
- x = t;
- RelationalExpression(out e1);
- e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1);
- }
- } else {
- OrOp();
- x = t;
- RelationalExpression(out e1);
- e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1);
- while (la.kind == 91 || la.kind == 92) {
- OrOp();
- x = t;
- RelationalExpression(out e1);
- e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1);
- }
- }
- }
- }
-
- void RelationalExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken x, firstOpTok = null; Expression e0, e1, acc = null; BinaryExpr.Opcode op;
- List<Expression> chain = null;
- List<BinaryExpr.Opcode> ops = null;
- int kind = 0; // 0 ("uncommitted") indicates chain of ==, possibly with one !=
- // 1 ("ascending") indicates chain of ==, <, <=, possibly with one !=
- // 2 ("descending") indicates chain of ==, >, >=, possibly with one !=
- // 3 ("illegal") indicates illegal chain
- // 4 ("disjoint") indicates chain of disjoint set operators
- bool hasSeenNeq = false;
-
- Term(out e0);
- e = e0;
- if (StartOf(23)) {
- RelOp(out x, out op);
- firstOpTok = x;
- Term(out e1);
- e = new BinaryExpr(x, op, e0, e1);
- if (op == BinaryExpr.Opcode.Disjoint)
- acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, e0, e1); // accumulate first two operands.
-
- while (StartOf(23)) {
- if (chain == null) {
- chain = new List<Expression>();
- ops = new List<BinaryExpr.Opcode>();
- chain.Add(e0); ops.Add(op); chain.Add(e1);
- switch (op) {
- case BinaryExpr.Opcode.Eq:
- kind = 0; break;
- case BinaryExpr.Opcode.Neq:
- kind = 0; hasSeenNeq = true; break;
- case BinaryExpr.Opcode.Lt:
- case BinaryExpr.Opcode.Le:
- kind = 1; break;
- case BinaryExpr.Opcode.Gt:
- case BinaryExpr.Opcode.Ge:
- kind = 2; break;
- case BinaryExpr.Opcode.Disjoint:
- kind = 4; break;
- default:
- kind = 3; break;
- }
- }
- e0 = e1;
-
- RelOp(out x, out op);
- switch (op) {
- case BinaryExpr.Opcode.Eq:
- if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "chaining not allowed from the previous operator"); }
- break;
- case BinaryExpr.Opcode.Neq:
- if (hasSeenNeq) { SemErr(x, "a chain cannot have more than one != operator"); }
- if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "this operator cannot continue this chain"); }
- hasSeenNeq = true; break;
- case BinaryExpr.Opcode.Lt:
- case BinaryExpr.Opcode.Le:
- if (kind == 0) { kind = 1; }
- else if (kind != 1) { SemErr(x, "this operator chain cannot continue with an ascending operator"); }
- break;
- case BinaryExpr.Opcode.Gt:
- case BinaryExpr.Opcode.Ge:
- if (kind == 0) { kind = 2; }
- else if (kind != 2) { SemErr(x, "this operator chain cannot continue with a descending operator"); }
- break;
- case BinaryExpr.Opcode.Disjoint:
- if (kind != 4) { SemErr(x, "can only chain disjoint (!!) with itself."); kind = 3; }
- break;
- default:
- SemErr(x, "this operator cannot be part of a chain");
- kind = 3; break;
- }
-
- Term(out e1);
- ops.Add(op); chain.Add(e1);
- if (op == BinaryExpr.Opcode.Disjoint) {
- e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, acc, e1));
- acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, acc, e1); //e0 has already been added.
- }
- else
- e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, e0, e1));
-
- }
- }
- if (chain != null) {
- e = new ChainingExpression(firstOpTok, chain, ops, e);
- }
-
- }
-
- void AndOp() {
- if (la.kind == 89) {
- Get();
- } else if (la.kind == 90) {
- Get();
- } else SynErr(190);
- }
-
- void OrOp() {
- if (la.kind == 91) {
- Get();
- } else if (la.kind == 92) {
- Get();
- } else SynErr(191);
- }
-
- void Term(out Expression/*!*/ e0) {
- Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
- Factor(out e0);
- while (la.kind == 96 || la.kind == 97) {
- AddOp(out x, out op);
- Factor(out e1);
- e0 = new BinaryExpr(x, op, e0, e1);
- }
- }
-
- void RelOp(out IToken/*!*/ x, out BinaryExpr.Opcode op) {
- Contract.Ensures(Contract.ValueAtReturn(out x) != null);
- x = Token.NoToken; op = BinaryExpr.Opcode.Add/*(dummy)*/;
- IToken y;
-
- switch (la.kind) {
- case 27: {
- Get();
- x = t; op = BinaryExpr.Opcode.Eq;
- break;
- }
- case 32: {
- Get();
- x = t; op = BinaryExpr.Opcode.Lt;
- break;
- }
- case 33: {
- Get();
- x = t; op = BinaryExpr.Opcode.Gt;
- break;
- }
- case 79: {
- Get();
- x = t; op = BinaryExpr.Opcode.Le;
- break;
- }
- case 80: {
- Get();
- x = t; op = BinaryExpr.Opcode.Ge;
- break;
- }
- case 81: {
- Get();
- x = t; op = BinaryExpr.Opcode.Neq;
- break;
- }
- case 93: {
- Get();
- x = t; op = BinaryExpr.Opcode.Disjoint;
- break;
- }
- case 94: {
- Get();
- x = t; op = BinaryExpr.Opcode.In;
- break;
- }
- case 95: {
- Get();
- x = t; y = Token.NoToken;
- if (la.kind == 94) {
- Get();
- y = t;
- }
- if (y == Token.NoToken) {
- SemErr(x, "invalid RelOp");
- } else if (y.pos != x.pos + 1) {
- SemErr(x, "invalid RelOp (perhaps you intended \"!in\" with no intervening whitespace?)");
- } else {
- x.val = "!in";
- op = BinaryExpr.Opcode.NotIn;
- }
-
- break;
- }
- case 82: {
- Get();
- x = t; op = BinaryExpr.Opcode.Neq;
- break;
- }
- case 83: {
- Get();
- x = t; op = BinaryExpr.Opcode.Le;
- break;
- }
- case 84: {
- Get();
- x = t; op = BinaryExpr.Opcode.Ge;
- break;
- }
- default: SynErr(192); break;
- }
- }
-
- void Factor(out Expression/*!*/ e0) {
- Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
- UnaryExpression(out e0);
- while (la.kind == 55 || la.kind == 98 || la.kind == 99) {
- MulOp(out x, out op);
- UnaryExpression(out e1);
- e0 = new BinaryExpr(x, op, e0, e1);
- }
- }
-
- void AddOp(out IToken/*!*/ x, out BinaryExpr.Opcode op) {
- Contract.Ensures(Contract.ValueAtReturn(out x) != null); x = Token.NoToken; op=BinaryExpr.Opcode.Add/*(dummy)*/;
- if (la.kind == 96) {
- Get();
- x = t; op = BinaryExpr.Opcode.Add;
- } else if (la.kind == 97) {
- Get();
- x = t; op = BinaryExpr.Opcode.Sub;
- } else SynErr(193);
- }
-
- void UnaryExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr;
- switch (la.kind) {
- case 97: {
- Get();
- x = t;
- UnaryExpression(out e);
- e = new BinaryExpr(x, BinaryExpr.Opcode.Sub, new LiteralExpr(x, 0), e);
- break;
- }
- case 95: case 100: {
- NegOp();
- x = t;
- UnaryExpression(out e);
- e = new UnaryExpr(x, UnaryExpr.Opcode.Not, e);
- break;
- }
- case 23: case 47: case 57: case 63: case 68: case 74: case 75: case 109: case 110: case 111: case 112: {
- EndlessExpression(out e);
- break;
- }
- case 1: {
- DottedIdentifiersAndFunction(out e);
- while (la.kind == 17 || la.kind == 65) {
- Suffix(ref e);
- }
- break;
- }
- case 6: case 65: {
- DisplayExpr(out e);
- while (la.kind == 17 || la.kind == 65) {
- Suffix(ref e);
- }
- break;
- }
- case 48: {
- MultiSetExpr(out e);
- while (la.kind == 17 || la.kind == 65) {
- Suffix(ref e);
- }
- break;
- }
- case 50: {
- Get();
- x = t;
- if (la.kind == 65) {
- MapDisplayExpr(x, out e);
- while (la.kind == 17 || la.kind == 65) {
- Suffix(ref e);
- }
- } else if (la.kind == 1) {
- MapComprehensionExpr(x, out e);
- } else if (StartOf(24)) {
- SemErr("map must be followed by literal in brackets or comprehension.");
- } else SynErr(194);
- break;
- }
- case 2: case 22: case 26: case 101: case 102: case 103: case 104: case 105: case 106: {
- ConstAtomExpression(out e);
- while (la.kind == 17 || la.kind == 65) {
- Suffix(ref e);
- }
- break;
- }
- default: SynErr(195); break;
- }
- }
-
- void MulOp(out IToken/*!*/ x, out BinaryExpr.Opcode op) {
- Contract.Ensures(Contract.ValueAtReturn(out x) != null); x = Token.NoToken; op = BinaryExpr.Opcode.Add/*(dummy)*/;
- if (la.kind == 55) {
- Get();
- x = t; op = BinaryExpr.Opcode.Mul;
- } else if (la.kind == 98) {
- Get();
- x = t; op = BinaryExpr.Opcode.Div;
- } else if (la.kind == 99) {
- Get();
- x = t; op = BinaryExpr.Opcode.Mod;
- } else SynErr(196);
- }
-
- void NegOp() {
- if (la.kind == 95) {
- Get();
- } else if (la.kind == 100) {
- Get();
- } else SynErr(197);
- }
-
- void EndlessExpression(out Expression e) {
- IToken/*!*/ x;
- Expression e0, e1;
- e = dummyExpr;
-
- switch (la.kind) {
- case 68: {
- Get();
- x = t;
- Expression(out e);
- Expect(107);
- Expression(out e0);
- Expect(69);
- Expression(out e1);
- e = new ITEExpr(x, e, e0, e1);
- break;
- }
- case 74: {
- MatchExpression(out e);
- break;
- }
- case 109: case 110: case 111: case 112: {
- QuantifierGuts(out e);
- break;
- }
- case 47: {
- ComprehensionExpr(out e);
- break;
- }
- case 75: {
- Get();
- x = t;
- Expression(out e0);
- Expect(14);
- Expression(out e1);
- e = new AssertExpr(x, e0, e1);
- break;
- }
- case 63: {
- Get();
- x = t;
- Expression(out e0);
- Expect(14);
- Expression(out e1);
- e = new AssumeExpr(x, e0, e1);
- break;
- }
- case 23: {
- LetExpr(out e);
- break;
- }
- case 57: {
- NamedExpr(out e);
- break;
- }
- default: SynErr(198); break;
- }
- }
-
- void DottedIdentifiersAndFunction(out Expression e) {
- IToken id; IToken openParen = null;
- List<Expression> args = null;
- List<IToken> idents = new List<IToken>();
-
- Ident(out id);
- idents.Add(id);
- while (la.kind == 17) {
- Get();
- Ident(out id);
- idents.Add(id);
- }
- if (la.kind == 26) {
- Get();
- openParen = t; args = new List<Expression>();
- if (StartOf(13)) {
- Expressions(args);
- }
- Expect(28);
- }
- e = new IdentifierSequence(idents, openParen, args);
- }
-
- void Suffix(ref Expression/*!*/ e) {
- Contract.Requires(e != null); Contract.Ensures(e!=null); IToken/*!*/ id, x; List<Expression/*!*/>/*!*/ args;
- Expression e0 = null; Expression e1 = null; Expression/*!*/ ee; bool anyDots = false;
- List<Expression> multipleIndices = null;
- bool func = false;
-
- if (la.kind == 17) {
- Get();
- Ident(out id);
- if (la.kind == 26) {
- Get();
- IToken openParen = t; args = new List<Expression/*!*/>(); func = true;
- if (StartOf(13)) {
- Expressions(args);
- }
- Expect(28);
- e = new FunctionCallExpr(id, id.val, e, openParen, args);
- }
- if (!func) { e = new ExprDotName(id, e, id.val); }
- } else if (la.kind == 65) {
- Get();
- x = t;
- if (StartOf(13)) {
- Expression(out ee);
- e0 = ee;
- if (la.kind == 108) {
- Get();
- anyDots = true;
- if (StartOf(13)) {
- Expression(out ee);
- e1 = ee;
- }
- } else if (la.kind == 60) {
- Get();
- Expression(out ee);
- e1 = ee;
- } else if (la.kind == 24 || la.kind == 66) {
- while (la.kind == 24) {
- Get();
- Expression(out ee);
- if (multipleIndices == null) {
- multipleIndices = new List<Expression>();
- multipleIndices.Add(e0);
- }
- multipleIndices.Add(ee);
-
- }
- } else SynErr(199);
- } else if (la.kind == 108) {
- Get();
- anyDots = true;
- if (StartOf(13)) {
- Expression(out ee);
- e1 = ee;
- }
- } else SynErr(200);
- if (multipleIndices != null) {
- e = new MultiSelectExpr(x, e, multipleIndices);
- // make sure an array class with this dimensionality exists
- UserDefinedType tmp = theBuiltIns.ArrayType(x, multipleIndices.Count, new IntType(), true);
- } else {
- if (!anyDots && e0 == null) {
- /* a parsing error occurred */
- e0 = dummyExpr;
- }
- Contract.Assert(anyDots || e0 != null);
- if (anyDots) {
- //Contract.Assert(e0 != null || e1 != null);
- e = new SeqSelectExpr(x, false, e, e0, e1);
- } else if (e1 == null) {
- Contract.Assert(e0 != null);
- e = new SeqSelectExpr(x, true, e, e0, null);
- } else {
- Contract.Assert(e0 != null);
- e = new SeqUpdateExpr(x, e, e0, e1);
- }
- }
-
- Expect(66);
- } else SynErr(201);
- }
-
- void DisplayExpr(out Expression e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken/*!*/ x = null; List<Expression/*!*/>/*!*/ elements;
- e = dummyExpr;
-
- if (la.kind == 6) {
- Get();
- x = t; elements = new List<Expression/*!*/>();
- if (StartOf(13)) {
- Expressions(elements);
- }
- e = new SetDisplayExpr(x, elements);
- Expect(7);
- } else if (la.kind == 65) {
- Get();
- x = t; elements = new List<Expression/*!*/>();
- if (StartOf(13)) {
- Expressions(elements);
- }
- e = new SeqDisplayExpr(x, elements);
- Expect(66);
- } else SynErr(202);
- }
-
- void MultiSetExpr(out Expression e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken/*!*/ x = null; List<Expression/*!*/>/*!*/ elements;
- e = dummyExpr;
-
- Expect(48);
- x = t;
- if (la.kind == 6) {
- Get();
- elements = new List<Expression/*!*/>();
- if (StartOf(13)) {
- Expressions(elements);
- }
- e = new MultiSetDisplayExpr(x, elements);
- Expect(7);
- } else if (la.kind == 26) {
- Get();
- x = t; elements = new List<Expression/*!*/>();
- Expression(out e);
- e = new MultiSetFormingExpr(x, e);
- Expect(28);
- } else if (StartOf(25)) {
- SemErr("multiset must be followed by multiset literal or expression to coerce in parentheses.");
- } else SynErr(203);
- }
-
- void MapDisplayExpr(IToken/*!*/ mapToken, out Expression e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- List<ExpressionPair/*!*/>/*!*/ elements= new List<ExpressionPair/*!*/>() ;
- e = dummyExpr;
-
- Expect(65);
- if (StartOf(13)) {
- MapLiteralExpressions(out elements);
- }
- e = new MapDisplayExpr(mapToken, elements);
- Expect(66);
- }
-
- void MapComprehensionExpr(IToken/*!*/ mapToken, out Expression e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- BoundVar/*!*/ bv;
- List<BoundVar/*!*/> bvars = new List<BoundVar/*!*/>();
- Expression range = null;
- Expression body;
-
- IdentTypeOptional(out bv);
- bvars.Add(bv);
- if (la.kind == 22) {
- Get();
- Expression(out range);
- }
- QSep();
- Expression(out body);
- e = new MapComprehension(mapToken, bvars, range ?? new LiteralExpr(mapToken, true), body);
-
- }
-
- void ConstAtomExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null);
- IToken/*!*/ x; BigInteger n;
- e = dummyExpr;
-
- switch (la.kind) {
- case 101: {
- Get();
- e = new LiteralExpr(t, false);
- break;
- }
- case 102: {
- Get();
- e = new LiteralExpr(t, true);
- break;
- }
- case 103: {
- Get();
- e = new LiteralExpr(t);
- break;
- }
- case 2: {
- Nat(out n);
- e = new LiteralExpr(t, n);
- break;
- }
- case 104: {
- Get();
- e = new ThisExpr(t);
- break;
- }
- case 105: {
- Get();
- x = t;
- Expect(26);
- Expression(out e);
- Expect(28);
- e = new FreshExpr(x, e);
- break;
- }
- case 106: {
- Get();
- x = t;
- Expect(26);
- Expression(out e);
- Expect(28);
- e = new OldExpr(x, e);
- break;
- }
- case 22: {
- Get();
- x = t;
- Expression(out e);
- e = new UnaryExpr(x, UnaryExpr.Opcode.SeqLength, e);
- Expect(22);
- break;
- }
- case 26: {
- Get();
- x = t;
- Expression(out e);
- e = new ParensExpression(x, e);
- Expect(28);
- break;
- }
- default: SynErr(204); break;
- }
- }
-
- void Nat(out BigInteger n) {
- Expect(2);
- try {
- n = BigInteger.Parse(t.val);
- } catch (System.FormatException) {
- SemErr("incorrectly formatted number");
- n = BigInteger.Zero;
- }
-
- }
-
- void MapLiteralExpressions(out List<ExpressionPair> elements) {
- Expression/*!*/ d, r;
- elements = new List<ExpressionPair/*!*/>();
- Expression(out d);
- Expect(60);
- Expression(out r);
- elements.Add(new ExpressionPair(d,r));
- while (la.kind == 24) {
- Get();
- Expression(out d);
- Expect(60);
- Expression(out r);
- elements.Add(new ExpressionPair(d,r));
- }
- }
-
- void QSep() {
- if (la.kind == 113) {
- Get();
- } else if (la.kind == 114) {
- Get();
- } else SynErr(205);
- }
-
- void MatchExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; MatchCaseExpr/*!*/ c;
- List<MatchCaseExpr/*!*/> cases = new List<MatchCaseExpr/*!*/>();
-
- Expect(74);
- x = t;
- Expression(out e);
- while (la.kind == 70) {
- CaseExpression(out c);
- cases.Add(c);
- }
- e = new MatchExpr(x, e, cases);
- }
-
- void QuantifierGuts(out Expression/*!*/ q) {
- Contract.Ensures(Contract.ValueAtReturn(out q) != null); IToken/*!*/ x = Token.NoToken;
- bool univ = false;
- List<BoundVar/*!*/> bvars;
- Attributes attrs;
- Expression range;
- Expression/*!*/ body;
-
- if (la.kind == 109 || la.kind == 110) {
- Forall();
- x = t; univ = true;
- } else if (la.kind == 111 || la.kind == 112) {
- Exists();
- x = t;
- } else SynErr(206);
- QuantifierDomain(out bvars, out attrs, out range);
- QSep();
- Expression(out body);
- if (univ) {
- q = new ForallExpr(x, bvars, range, body, attrs);
- } else {
- q = new ExistsExpr(x, bvars, range, body, attrs);
- }
-
- }
-
- void ComprehensionExpr(out Expression/*!*/ q) {
- Contract.Ensures(Contract.ValueAtReturn(out q) != null);
- IToken/*!*/ x = Token.NoToken;
- BoundVar/*!*/ bv;
- List<BoundVar/*!*/> bvars = new List<BoundVar/*!*/>();
- Expression/*!*/ range;
- Expression body = null;
-
- Expect(47);
- x = t;
- IdentTypeOptional(out bv);
- bvars.Add(bv);
- while (la.kind == 24) {
- Get();
- IdentTypeOptional(out bv);
- bvars.Add(bv);
- }
- Expect(22);
- Expression(out range);
- if (la.kind == 113 || la.kind == 114) {
- QSep();
- Expression(out body);
- }
- if (body == null && bvars.Count != 1) { SemErr(t, "a set comprehension with more than one bound variable must have a term expression"); }
- q = new SetComprehension(x, bvars, range, body);
-
- }
-
- void LetExpr(out Expression e) {
- IToken/*!*/ x;
- e = dummyExpr;
- BoundVar d;
- List<BoundVar> letVars; List<Expression> letRHSs;
-
- Expect(23);
- x = t;
- letVars = new List<BoundVar>();
- letRHSs = new List<Expression>();
- IdentTypeOptional(out d);
- letVars.Add(d);
- while (la.kind == 24) {
- Get();
- IdentTypeOptional(out d);
- letVars.Add(d);
- }
- Expect(60);
- Expression(out e);
- letRHSs.Add(e);
- while (la.kind == 24) {
- Get();
- Expression(out e);
- letRHSs.Add(e);
- }
- Expect(14);
- Expression(out e);
- e = new LetExpr(x, letVars, letRHSs, e);
- }
-
- void NamedExpr(out Expression e) {
- IToken/*!*/ x, d;
- e = dummyExpr;
- Expression expr;
-
- Expect(57);
- x = t;
- NoUSIdent(out d);
- Expect(5);
- Expression(out e);
- expr = e;
- e = new NamedExpr(x, d.val, expr);
- }
-
- void CaseExpression(out MatchCaseExpr/*!*/ c) {
- Contract.Ensures(Contract.ValueAtReturn(out c) != null); IToken/*!*/ x, id;
- List<BoundVar/*!*/> arguments = new List<BoundVar/*!*/>();
- BoundVar/*!*/ bv;
- Expression/*!*/ body;
-
- Expect(70);
- x = t;
- Ident(out id);
- if (la.kind == 26) {
- Get();
- IdentTypeOptional(out bv);
- arguments.Add(bv);
- while (la.kind == 24) {
- Get();
- IdentTypeOptional(out bv);
- arguments.Add(bv);
- }
- Expect(28);
- }
- Expect(71);
- Expression(out body);
- c = new MatchCaseExpr(x, id.val, arguments, body);
- }
-
- void Forall() {
- if (la.kind == 109) {
- Get();
- } else if (la.kind == 110) {
- Get();
- } else SynErr(207);
- }
-
- void Exists() {
- if (la.kind == 111) {
- Get();
- } else if (la.kind == 112) {
- Get();
- } else SynErr(208);
- }
-
- void AttributeBody(ref Attributes attrs) {
- string aName;
- List<Attributes.Argument/*!*/> aArgs = new List<Attributes.Argument/*!*/>();
- Attributes.Argument/*!*/ aArg;
-
- Expect(5);
- Expect(1);
- aName = t.val;
- if (StartOf(26)) {
- AttributeArg(out aArg);
- aArgs.Add(aArg);
- while (la.kind == 24) {
- Get();
- AttributeArg(out aArg);
- aArgs.Add(aArg);
- }
- }
- attrs = new Attributes(aName, aArgs, attrs);
- }
-
-
-
- public void Parse() {
- la = new Token();
- la.val = "";
- Get();
- Dafny();
- Expect(0);
-
- Expect(0);
- }
-
- static readonly bool[,]/*!*/ set = {
- {T,T,T,x, x,x,T,x, T,x,x,x, x,x,T,x, x,x,T,x, T,T,T,T, x,x,T,x, x,T,x,T, x,x,T,T, x,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,T, x,x,x,x, T,x,x,x, T,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, T,T,x,T, x,x,x,x, x,x,T,T, T,T,x,T, x,T,x,x, x,T,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {T,x,x,x, x,x,T,T, T,T,x,T, x,x,x,x, x,x,T,T, T,T,x,T, x,T,T,x, x,T,x,x, T,x,T,T, x,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,x,T, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,T,x, x,x,x,x, T,T,x,x, x,x,x,T, x,T,x,x, T,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, T,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,T,x, x,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,T, x,x,x,x, T,x,x,x, T,x,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x},
- {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,T,x, x,x,x,x, x,T,x,x, x,x,x,T, x,T,x,x, T,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, T,x,x,x, x},
- {x,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,T,x, x,x,x,T, T,T,x,x, x,x,x,T, x,T,x,x, T,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, T,x,x,x, x},
- {T,T,T,x, x,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,T, x,x,x,x, T,x,x,x, T,x,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,T,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,T, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,T,x, x,x,x,x, x,T,x,x, x,x,x,T, x,T,x,x, T,x,x,x, x,x,T,T, x,x,T,T, T,T,T,T, T,T,T,T, T,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, T,x,x,x, x},
- {x,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,T,x, x,x,x,T, x,T,x,x, x,x,x,T, T,T,x,T, T,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, T,x,x,x, x},
- {x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,T,T, x,x,x,x, x,x,T,x, x,x,x,x, x,x,T,x, T,x,x,T, T,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, T,x,x,x, x,x,T,x, x,T,T,T, x,x,x,x, x,x,x,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,x,x,x, x,x,x,T, T,x,x,x, x,T,T,x, x},
- {x,x,x,x, x,x,T,T, x,x,x,x, x,x,T,x, x,T,x,x, x,x,T,x, T,x,x,T, T,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, T,x,x,x, x,T,T,x, x,T,T,T, x,x,x,x, x,x,x,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,x,x,x, x,x,x,T, T,x,x,x, x,T,T,x, x},
- {x,T,T,x, T,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,T,x, x,x,x,x, x,T,x,x, x,x,x,T, x,T,x,x, T,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, T,x,x,x, x}
-
- };
-} // end Parser
-
-
-public class Errors {
- public int count = 0; // number of errors detected
- public System.IO.TextWriter/*!*/ errorStream = Console.Out; // error messages go to this stream
- public string errMsgFormat = "{0}({1},{2}): error: {3}"; // 0=filename, 1=line, 2=column, 3=text
- public string warningMsgFormat = "{0}({1},{2}): warning: {3}"; // 0=filename, 1=line, 2=column, 3=text
-
- public void SynErr(string filename, int line, int col, int n) {
- SynErr(filename, line, col, GetSyntaxErrorString(n));
- }
-
- public virtual void SynErr(string filename, int line, int col, string/*!*/ msg) {
- Contract.Requires(msg != null);
- errorStream.WriteLine(errMsgFormat, filename, line, col, msg);
- count++;
- }
-
- string GetSyntaxErrorString(int n) {
- string s;
- switch (n) {
- case 0: s = "EOF expected"; break;
- case 1: s = "ident expected"; break;
- case 2: s = "digits expected"; break;
- case 3: s = "arrayToken expected"; break;
- case 4: s = "string expected"; break;
- case 5: s = "colon expected"; break;
- case 6: s = "lbrace expected"; break;
- case 7: s = "rbrace expected"; break;
- case 8: s = "\"ghost\" expected"; break;
- case 9: s = "\"module\" expected"; break;
- case 10: s = "\"refines\" expected"; break;
- case 11: s = "\"import\" expected"; break;
- case 12: s = "\"opened\" expected"; break;
- case 13: s = "\"=\" expected"; break;
- case 14: s = "\";\" expected"; break;
- case 15: s = "\"as\" expected"; break;
- case 16: s = "\"default\" expected"; break;
- case 17: s = "\".\" expected"; break;
- case 18: s = "\"class\" expected"; break;
- case 19: s = "\"static\" expected"; break;
- case 20: s = "\"datatype\" expected"; break;
- case 21: s = "\"codatatype\" expected"; break;
- case 22: s = "\"|\" expected"; break;
- case 23: s = "\"var\" expected"; break;
- case 24: s = "\",\" expected"; break;
- case 25: s = "\"type\" expected"; break;
- case 26: s = "\"(\" expected"; break;
- case 27: s = "\"==\" expected"; break;
- case 28: s = "\")\" expected"; break;
- case 29: s = "\"iterator\" expected"; break;
- case 30: s = "\"yields\" expected"; break;
- case 31: s = "\"...\" expected"; break;
- case 32: s = "\"<\" expected"; break;
- case 33: s = "\">\" expected"; break;
- case 34: s = "\"method\" expected"; break;
- case 35: s = "\"constructor\" expected"; break;
- case 36: s = "\"returns\" expected"; break;
- case 37: s = "\"modifies\" expected"; break;
- case 38: s = "\"free\" expected"; break;
- case 39: s = "\"requires\" expected"; break;
- case 40: s = "\"ensures\" expected"; break;
- case 41: s = "\"decreases\" expected"; break;
- case 42: s = "\"reads\" expected"; break;
- case 43: s = "\"yield\" expected"; break;
- case 44: s = "\"bool\" expected"; break;
- case 45: s = "\"nat\" expected"; break;
- case 46: s = "\"int\" expected"; break;
- case 47: s = "\"set\" expected"; break;
- case 48: s = "\"multiset\" expected"; break;
- case 49: s = "\"seq\" expected"; break;
- case 50: s = "\"map\" expected"; break;
- case 51: s = "\"object\" expected"; break;
- case 52: s = "\"function\" expected"; break;
- case 53: s = "\"predicate\" expected"; break;
- case 54: s = "\"copredicate\" expected"; break;
- case 55: s = "\"*\" expected"; break;
- case 56: s = "\"`\" expected"; break;
- case 57: s = "\"label\" expected"; break;
- case 58: s = "\"break\" expected"; break;
- case 59: s = "\"where\" expected"; break;
- case 60: s = "\":=\" expected"; break;
- case 61: s = "\"return\" expected"; break;
- case 62: s = "\":|\" expected"; break;
- case 63: s = "\"assume\" expected"; break;
- case 64: s = "\"new\" expected"; break;
- case 65: s = "\"[\" expected"; break;
- case 66: s = "\"]\" expected"; break;
- case 67: s = "\"choose\" expected"; break;
- case 68: s = "\"if\" expected"; break;
- case 69: s = "\"else\" expected"; break;
- case 70: s = "\"case\" expected"; break;
- case 71: s = "\"=>\" expected"; break;
- case 72: s = "\"while\" expected"; break;
- case 73: s = "\"invariant\" expected"; break;
- case 74: s = "\"match\" expected"; break;
- case 75: s = "\"assert\" expected"; break;
- case 76: s = "\"print\" expected"; break;
- case 77: s = "\"parallel\" expected"; break;
- case 78: s = "\"calc\" expected"; break;
- case 79: s = "\"<=\" expected"; break;
- case 80: s = "\">=\" expected"; break;
- case 81: s = "\"!=\" expected"; break;
- case 82: s = "\"\\u2260\" expected"; break;
- case 83: s = "\"\\u2264\" expected"; break;
- case 84: s = "\"\\u2265\" expected"; break;
- case 85: s = "\"<==>\" expected"; break;
- case 86: s = "\"\\u21d4\" expected"; break;
- case 87: s = "\"==>\" expected"; break;
- case 88: s = "\"\\u21d2\" expected"; break;
- case 89: s = "\"&&\" expected"; break;
- case 90: s = "\"\\u2227\" expected"; break;
- case 91: s = "\"||\" expected"; break;
- case 92: s = "\"\\u2228\" expected"; break;
- case 93: s = "\"!!\" expected"; break;
- case 94: s = "\"in\" expected"; break;
- case 95: s = "\"!\" expected"; break;
- case 96: s = "\"+\" expected"; break;
- case 97: s = "\"-\" expected"; break;
- case 98: s = "\"/\" expected"; break;
- case 99: s = "\"%\" expected"; break;
- case 100: s = "\"\\u00ac\" expected"; break;
- case 101: s = "\"false\" expected"; break;
- case 102: s = "\"true\" expected"; break;
- case 103: s = "\"null\" expected"; break;
- case 104: s = "\"this\" expected"; break;
- case 105: s = "\"fresh\" expected"; break;
- case 106: s = "\"old\" expected"; break;
- case 107: s = "\"then\" expected"; break;
- case 108: s = "\"..\" expected"; break;
- case 109: s = "\"forall\" expected"; break;
- case 110: s = "\"\\u2200\" expected"; break;
- case 111: s = "\"exists\" expected"; break;
- case 112: s = "\"\\u2203\" expected"; break;
- case 113: s = "\"::\" expected"; break;
- case 114: s = "\"\\u2022\" expected"; break;
- case 115: s = "??? expected"; break;
- case 116: s = "invalid Dafny"; break;
- case 117: s = "invalid SubModuleDecl"; break;
- case 118: s = "invalid SubModuleDecl"; break;
- case 119: s = "invalid SubModuleDecl"; break;
- case 120: s = "this symbol not expected in ClassDecl"; break;
- case 121: s = "this symbol not expected in DatatypeDecl"; break;
- case 122: s = "invalid DatatypeDecl"; break;
- case 123: s = "this symbol not expected in DatatypeDecl"; break;
- case 124: s = "this symbol not expected in ArbitraryTypeDecl"; break;
- case 125: s = "this symbol not expected in IteratorDecl"; break;
- case 126: s = "invalid IteratorDecl"; break;
- case 127: s = "invalid ClassMemberDecl"; break;
- case 128: s = "this symbol not expected in FieldDecl"; break;
- case 129: s = "this symbol not expected in FieldDecl"; break;
- case 130: s = "invalid FunctionDecl"; break;
- case 131: s = "invalid FunctionDecl"; break;
- case 132: s = "invalid FunctionDecl"; break;
- case 133: s = "invalid FunctionDecl"; break;
- case 134: s = "this symbol not expected in MethodDecl"; break;
- case 135: s = "invalid MethodDecl"; break;
- case 136: s = "invalid MethodDecl"; break;
- case 137: s = "invalid TypeAndToken"; break;
- case 138: s = "this symbol not expected in IteratorSpec"; break;
- case 139: s = "this symbol not expected in IteratorSpec"; break;
- case 140: s = "this symbol not expected in IteratorSpec"; break;
- case 141: s = "this symbol not expected in IteratorSpec"; break;
- case 142: s = "this symbol not expected in IteratorSpec"; break;
- case 143: s = "invalid IteratorSpec"; break;
- case 144: s = "this symbol not expected in IteratorSpec"; break;
- case 145: s = "invalid IteratorSpec"; break;
- case 146: s = "this symbol not expected in MethodSpec"; break;
- case 147: s = "this symbol not expected in MethodSpec"; break;
- case 148: s = "this symbol not expected in MethodSpec"; break;
- case 149: s = "this symbol not expected in MethodSpec"; break;
- case 150: s = "invalid MethodSpec"; break;
- case 151: s = "this symbol not expected in MethodSpec"; break;
- case 152: s = "invalid MethodSpec"; break;
- case 153: s = "invalid FrameExpression"; break;
- case 154: s = "invalid ReferenceType"; break;
- case 155: s = "this symbol not expected in FunctionSpec"; break;
- case 156: s = "this symbol not expected in FunctionSpec"; break;
- case 157: s = "this symbol not expected in FunctionSpec"; break;
- case 158: s = "this symbol not expected in FunctionSpec"; break;
- case 159: s = "this symbol not expected in FunctionSpec"; break;
- case 160: s = "invalid FunctionSpec"; break;
- case 161: s = "invalid PossiblyWildFrameExpression"; break;
- case 162: s = "invalid PossiblyWildExpression"; break;
- case 163: s = "this symbol not expected in OneStmt"; break;
- case 164: s = "invalid OneStmt"; break;
- case 165: s = "this symbol not expected in OneStmt"; break;
- case 166: s = "invalid OneStmt"; break;
- case 167: s = "invalid AssertStmt"; break;
- case 168: s = "invalid AssumeStmt"; break;
- case 169: s = "invalid UpdateStmt"; break;
- case 170: s = "invalid UpdateStmt"; break;
- case 171: s = "invalid IfStmt"; break;
- case 172: s = "invalid IfStmt"; break;
- case 173: s = "invalid WhileStmt"; break;
- case 174: s = "invalid WhileStmt"; break;
- case 175: s = "invalid CalcStmt"; break;
- case 176: s = "invalid ReturnStmt"; break;
- case 177: s = "invalid Rhs"; break;
- case 178: s = "invalid Lhs"; break;
- case 179: s = "invalid Guard"; break;
- case 180: s = "this symbol not expected in LoopSpec"; break;
- case 181: s = "this symbol not expected in LoopSpec"; break;
- case 182: s = "this symbol not expected in LoopSpec"; break;
- case 183: s = "this symbol not expected in LoopSpec"; break;
- case 184: s = "this symbol not expected in LoopSpec"; break;
- case 185: s = "this symbol not expected in Invariant"; break;
- case 186: s = "invalid AttributeArg"; break;
- case 187: s = "invalid CalcOp"; break;
- case 188: s = "invalid EquivOp"; break;
- case 189: s = "invalid ImpliesOp"; break;
- case 190: s = "invalid AndOp"; break;
- case 191: s = "invalid OrOp"; break;
- case 192: s = "invalid RelOp"; break;
- case 193: s = "invalid AddOp"; break;
- case 194: s = "invalid UnaryExpression"; break;
- case 195: s = "invalid UnaryExpression"; break;
- case 196: s = "invalid MulOp"; break;
- case 197: s = "invalid NegOp"; break;
- case 198: s = "invalid EndlessExpression"; break;
- case 199: s = "invalid Suffix"; break;
- case 200: s = "invalid Suffix"; break;
- case 201: s = "invalid Suffix"; break;
- case 202: s = "invalid DisplayExpr"; break;
- case 203: s = "invalid MultiSetExpr"; break;
- case 204: s = "invalid ConstAtomExpression"; break;
- case 205: s = "invalid QSep"; break;
- case 206: s = "invalid QuantifierGuts"; break;
- case 207: s = "invalid Forall"; break;
- case 208: s = "invalid Exists"; break;
-
- default: s = "error " + n; break;
- }
- return s;
- }
-
- public void SemErr(IToken/*!*/ tok, string/*!*/ msg) { // semantic errors
- Contract.Requires(tok != null);
- Contract.Requires(msg != null);
- SemErr(tok.filename, tok.line, tok.col, msg);
- }
-
- public virtual void SemErr(string filename, int line, int col, string/*!*/ msg) {
- Contract.Requires(msg != null);
- errorStream.WriteLine(errMsgFormat, filename, line, col, msg);
- count++;
- }
-
- public virtual void Warning(string filename, int line, int col, string msg) {
- Contract.Requires(msg != null);
- errorStream.WriteLine(warningMsgFormat, filename, line, col, msg);
- }
-} // Errors
-
-
-public class FatalError: Exception {
- public FatalError(string m): base(m) {}
-}
-
-
-} \ No newline at end of file
diff --git a/Source/Dafny/Printer.cs b/Source/Dafny/Printer.cs
deleted file mode 100644
index 36658e2f..00000000
--- a/Source/Dafny/Printer.cs
+++ /dev/null
@@ -1,1410 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Numerics;
-using System.Linq;
-using Bpl = Microsoft.Boogie;
-
-namespace Microsoft.Dafny {
- public class Printer {
- TextWriter wr;
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(wr!=null);
- }
-
- public Printer(TextWriter wr) {
- Contract.Requires(wr != null);
- this.wr = wr;
- }
-
- public void PrintProgram(Program prog) {
- Contract.Requires(prog != null);
- if (Bpl.CommandLineOptions.Clo.ShowEnv != Bpl.CommandLineOptions.ShowEnvironment.Never) {
- wr.WriteLine("// " + Bpl.CommandLineOptions.Clo.Version);
- wr.WriteLine("// " + Bpl.CommandLineOptions.Clo.Environment);
- }
- wr.WriteLine("// {0}", prog.Name);
- wr.WriteLine();
- PrintTopLevelDecls(prog.DefaultModuleDef.TopLevelDecls, 0);
- }
-
- public void PrintTopLevelDecls(List<TopLevelDecl> decls, int indent) {
- Contract.Requires(decls!= null);
- int i = 0;
- foreach (TopLevelDecl d in decls) {
- Contract.Assert(d != null);
- if (d is ArbitraryTypeDecl) {
- var at = (ArbitraryTypeDecl)d;
- if (i++ != 0) { wr.WriteLine(); }
- Indent(indent);
- PrintClassMethodHelper("type", at.Attributes, at.Name, new List<TypeParameter>());
- if (at.EqualitySupport == TypeParameter.EqualitySupportValue.Required) {
- wr.Write("(==)");
- }
- wr.WriteLine(";");
- } else if (d is DatatypeDecl) {
- if (i++ != 0) { wr.WriteLine(); }
- PrintDatatype((DatatypeDecl)d, indent);
- } else if (d is IteratorDecl) {
- var iter = (IteratorDecl)d;
- Indent(indent);
- PrintClassMethodHelper("iterator", iter.Attributes, iter.Name, iter.TypeArgs);
- if (iter.SignatureIsOmitted) {
- wr.WriteLine(" ...");
- } else {
- PrintFormals(iter.Ins);
- if (iter.Outs.Count != 0) {
- if (iter.Ins.Count + iter.Outs.Count <= 3) {
- wr.Write(" yields ");
- } else {
- wr.WriteLine();
- Indent(indent + 2 * IndentAmount);
- wr.Write("yields ");
- }
- PrintFormals(iter.Outs);
- }
- wr.WriteLine();
- }
-
- int ind = indent + IndentAmount;
- PrintSpec("requires", iter.Requires, ind);
- if (iter.Reads.Expressions != null) {
- PrintFrameSpecLine("reads", iter.Reads.Expressions, ind, iter.Reads.HasAttributes() ? iter.Reads.Attributes : null);
- }
- if (iter.Modifies.Expressions != null) {
- PrintFrameSpecLine("modifies", iter.Modifies.Expressions, ind, iter.Modifies.HasAttributes() ? iter.Modifies.Attributes : null);
- }
- PrintSpec("yield requires", iter.YieldRequires, ind);
- PrintSpec("yield ensures", iter.YieldEnsures, ind);
- PrintSpec("ensures", iter.Ensures, ind);
- PrintDecreasesSpec(iter.Decreases, ind);
-
- if (iter.Body != null) {
- Indent(indent);
- PrintStatement(iter.Body, indent);
- wr.WriteLine();
- }
-
- if (DafnyOptions.O.DafnyPrintResolvedFile != null) {
- // also print the members that were created as part of the interpretation of the iterator
- Contract.Assert(iter.Members.Count != 0); // filled in during resolution
- wr.WriteLine("/*---------- iterator members ----------");
- PrintClassMethodHelper("class", null, iter.Name, iter.TypeArgs);
- wr.WriteLine(" {");
- PrintMembers(iter.Members, indent + IndentAmount);
- Indent(indent); wr.WriteLine("}");
- wr.WriteLine("---------- iterator members ----------*/");
- }
-
- } else if (d is ClassDecl) {
- ClassDecl cl = (ClassDecl)d;
- if (!cl.IsDefaultClass) {
- if (i++ != 0) { wr.WriteLine(); }
- PrintClass(cl, indent);
- } else if (cl.Members.Count == 0) {
- // print nothing
- } else {
- if (i++ != 0) { wr.WriteLine(); }
- PrintMembers(cl.Members, indent);
- }
-
- } else if (d is ModuleDecl) {
- wr.WriteLine();
- Indent(indent);
- if (d is LiteralModuleDecl) {
- ModuleDefinition module = ((LiteralModuleDecl)d).ModuleDef;
- wr.Write("module");
- PrintAttributes(module.Attributes);
- wr.Write(" {0} ", module.Name);
- if (module.RefinementBaseName != null) {
- wr.Write("refines {0} ", Util.Comma(".", module.RefinementBaseName, id => id.val));
- }
- if (module.TopLevelDecls.Count == 0) {
- wr.WriteLine("{ }");
- } else {
- wr.WriteLine("{");
- PrintTopLevelDecls(module.TopLevelDecls, indent + IndentAmount);
- Indent(indent);
- wr.WriteLine("}");
- }
- } else if (d is AliasModuleDecl) {
- wr.Write("import"); if (((AliasModuleDecl)d).Opened) wr.Write(" opened");
- wr.Write(" {0} ", ((AliasModuleDecl)d).Name);
- wr.WriteLine("= {0};", Util.Comma(".", ((AliasModuleDecl)d).Path, id => id.val));
- } else if (d is AbstractModuleDecl) {
- wr.Write("import"); if (((AbstractModuleDecl)d).Opened) wr.Write(" opened");
- wr.Write(" {0} ", ((AbstractModuleDecl)d).Name);
- wr.WriteLine("as {0};", Util.Comma(".", ((AbstractModuleDecl)d).Path, id => id.val));
- }
- } else {
- Contract.Assert(false); // unexpected TopLevelDecl
- }
- }
- }
-
- public void PrintClass(ClassDecl c, int indent) {
- Contract.Requires(c != null);
- Indent(indent);
- PrintClassMethodHelper("class", c.Attributes, c.Name, c.TypeArgs);
- if (c.Members.Count == 0) {
- wr.WriteLine(" { }");
- } else {
- wr.WriteLine(" {");
- PrintMembers(c.Members, indent + IndentAmount);
- Indent(indent);
- wr.WriteLine("}");
- }
- }
-
- public void PrintMembers(List<MemberDecl> members, int indent)
- {
- Contract.Requires(members != null);
-
- int state = 0; // 0 - no members yet; 1 - previous member was a field; 2 - previous member was non-field
- foreach (MemberDecl m in members) {
- if (m is Method) {
- if (state != 0) { wr.WriteLine(); }
- PrintMethod((Method)m, indent);
- state = 2;
- } else if (m is Field) {
- if (state == 2) { wr.WriteLine(); }
- PrintField((Field)m, indent);
- state = 1;
- } else if (m is Function) {
- if (state != 0) { wr.WriteLine(); }
- PrintFunction((Function)m, indent);
- state = 2;
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member
- }
- }
- }
-
- /// <summary>
- /// Prints no space before "kind", but does print a space before "attrs" and "name".
- /// </summary>
- void PrintClassMethodHelper(string kind, Attributes attrs, string name, List<TypeParameter> typeArgs) {
- Contract.Requires(kind != null);
- Contract.Requires(name != null);
- Contract.Requires(typeArgs != null);
- if (kind.Length != 0) {
- wr.Write(kind);
- }
-
- PrintAttributes(attrs);
-
- wr.Write(" {0}", name);
- if (typeArgs.Count != 0) {
- wr.Write("<" +
- Util.Comma(", ", typeArgs,
- tp => tp.Name + (tp.EqualitySupport == TypeParameter.EqualitySupportValue.Required? "(==)": ""))
- + ">");
- }
- }
-
- public void PrintDatatype(DatatypeDecl dt, int indent) {
- Contract.Requires(dt != null);
- Indent(indent);
- PrintClassMethodHelper(dt is IndDatatypeDecl ? "datatype" : "codatatype", dt.Attributes, dt.Name, dt.TypeArgs);
- wr.Write(" =");
- string sep = "";
- foreach (DatatypeCtor ctor in dt.Ctors) {
- wr.Write(sep);
- PrintClassMethodHelper("", ctor.Attributes, ctor.Name, new List<TypeParameter>());
- if (ctor.Formals.Count != 0) {
- PrintFormals(ctor.Formals);
- }
- sep = " |";
- }
- wr.WriteLine(";");
- }
-
- /// <summary>
- /// Prints a space before each attribute.
- /// </summary>
- public void PrintAttributes(Attributes a) {
- if (a != null) {
- PrintAttributes(a.Prev);
-
- wr.Write(" {{:{0}", a.Name);
- if (a.Args != null)
- {
- PrintAttributeArgs(a.Args);
- }
- wr.Write("}");
- }
- }
-
- public void PrintAttributeArgs(List<Attributes.Argument> args) {
- Contract.Requires(args != null);
- string prefix = " ";
- foreach (Attributes.Argument arg in args) {
- Contract.Assert(arg != null);
- wr.Write(prefix);
- prefix = ", ";
- if (arg.S != null) {
- wr.Write("\"{0}\"", arg.S);
- } else {
- Contract.Assert( arg.E != null);
- PrintExpression(arg.E);
- }
- }
- }
-
- public void PrintField(Field field, int indent) {
- Contract.Requires(field != null);
- Indent(indent);
- if (field.IsGhost) {
- wr.Write("ghost ");
- }
- wr.Write("var");
- PrintAttributes(field.Attributes);
- wr.Write(" {0}: ", field.Name);
- PrintType(field.Type);
- wr.Write(";");
- if (field.IsUserMutable) {
- // nothing more to say
- } else if (field.IsMutable) {
- wr.Write(" // may change, but not directly by program");
- } else {
- wr.Write(" // immutable");
- }
- wr.WriteLine();
- }
-
- public void PrintFunction(Function f, int indent) {
- Contract.Requires(f != null);
- var isPredicate = f is Predicate;
- Indent(indent);
- string k = isPredicate ? "predicate" : f is CoPredicate ? "copredicate" : "function";
- if (f.IsStatic) { k = "static " + k; }
- if (!f.IsGhost) { k += " method"; }
- PrintClassMethodHelper(k, f.Attributes, f.Name, f.TypeArgs);
- if (f.SignatureIsOmitted) {
- wr.WriteLine(" ...");
- } else {
- if (f.OpenParen != null) {
- PrintFormals(f.Formals);
- } else {
- Contract.Assert(isPredicate);
- }
- if (!isPredicate) {
- wr.Write(": ");
- PrintType(f.ResultType);
- }
- wr.WriteLine();
- }
-
- int ind = indent + IndentAmount;
- PrintSpec("requires", f.Req, ind);
- PrintFrameSpecLine("reads", f.Reads, ind, null);
- PrintSpec("ensures", f.Ens, ind);
- PrintDecreasesSpec(f.Decreases, ind);
- if (f.Body != null) {
- Indent(indent);
- wr.WriteLine("{");
- PrintExtendedExpr(f.Body, ind, true, false);
- Indent(indent);
- wr.WriteLine("}");
- }
- }
-
- // ----------------------------- PrintMethod -----------------------------
-
- const int IndentAmount = 2; // The amount of indent for each new scope
- const string BunchaSpaces = " ";
- void Indent(int amount)
- { Contract.Requires( 0 <= amount);
-
- while (0 < amount) {
- wr.Write(BunchaSpaces.Substring(0, amount));
- amount -= BunchaSpaces.Length;
- }
- }
-
- public void PrintMethod(Method method, int indent) {
- Contract.Requires(method != null);
-
- Indent(indent);
- string k = method is Constructor ? "constructor" : "method";
- if (method.IsStatic) { k = "static " + k; }
- if (method.IsGhost) { k = "ghost " + k; }
- PrintClassMethodHelper(k, method.Attributes, method.Name, method.TypeArgs);
- if (method.SignatureIsOmitted) {
- wr.WriteLine(" ...");
- } else {
- PrintFormals(method.Ins);
- if (method.Outs.Count != 0) {
- if (method.Ins.Count + method.Outs.Count <= 3) {
- wr.Write(" returns ");
- } else {
- wr.WriteLine();
- Indent(indent + 2 * IndentAmount);
- wr.Write("returns ");
- }
- PrintFormals(method.Outs);
- }
- wr.WriteLine();
- }
-
- int ind = indent + IndentAmount;
- PrintSpec("requires", method.Req, ind);
- if (method.Mod.Expressions != null)
- {
- PrintFrameSpecLine("modifies", method.Mod.Expressions, ind, method.Mod.HasAttributes() ? method.Mod.Attributes : null);
- }
- PrintSpec("ensures", method.Ens, ind);
- PrintDecreasesSpec(method.Decreases, ind);
-
- if (method.Body != null) {
- Indent(indent);
- PrintStatement(method.Body, indent);
- wr.WriteLine();
- }
- }
-
- void PrintFormals(List<Formal> ff) {
- Contract.Requires(ff!=null);
- wr.Write("(");
- string sep = "";
- foreach (Formal f in ff) {
- Contract.Assert(f != null);
- wr.Write(sep);
- sep = ", ";
- PrintFormal(f);
- }
- wr.Write(")");
- }
-
- void PrintFormal(Formal f) {
- Contract.Requires(f != null);
- if (f.IsGhost) {
- wr.Write("ghost ");
- }
- if (f.HasName) {
- wr.Write("{0}: ", f.DisplayName);
- }
- PrintType(f.Type);
- }
-
- void PrintSpec(string kind, List<Expression> ee, int indent) {
- Contract.Requires(kind != null);
- Contract.Requires(ee != null);
- foreach (Expression e in ee) {
- Contract.Assert(e != null);
- Indent(indent);
- wr.Write("{0} ", kind);
- PrintExpression(e);
- wr.WriteLine(";");
- }
- }
-
- void PrintDecreasesSpec(Specification<Expression> decs, int indent) {
- Contract.Requires(decs != null);
- if (decs.Expressions != null && decs.Expressions.Count != 0) {
- Indent(indent);
- wr.Write("decreases");
- if (decs.HasAttributes())
- {
- PrintAttributes(decs.Attributes);
- }
- wr.Write(" ");
- PrintExpressionList(decs.Expressions);
- wr.WriteLine(";");
- }
- }
-
- void PrintFrameSpecLine(string kind, List<FrameExpression/*!*/> ee, int indent, Attributes attrs) {
- Contract.Requires(kind != null);
- Contract.Requires(cce.NonNullElements(ee));
- if (ee != null && ee.Count != 0) {
- Indent(indent);
- wr.Write("{0}", kind);
- if (attrs != null) {
- PrintAttributes(attrs);
- }
- wr.Write(" ");
- PrintFrameExpressionList(ee);
- wr.WriteLine(";");
- }
- }
-
- void PrintSpec(string kind, List<MaybeFreeExpression> ee, int indent) {
- Contract.Requires(kind != null);
- Contract.Requires(ee != null);
- foreach (MaybeFreeExpression e in ee)
- {
- Contract.Assert(e != null);
- Indent(indent);
- wr.Write("{0}{1}", e.IsFree ? "free " : "", kind);
-
- if (e.HasAttributes())
- {
- PrintAttributes(e.Attributes);
- }
-
- wr.Write(" ");
- PrintExpression(e.E);
-
- wr.WriteLine(";");
- }
- }
-
- // ----------------------------- PrintType -----------------------------
-
- public void PrintType(Type ty) {
- Contract.Requires(ty != null);
- wr.Write(ty.ToString());
- }
-
- public void PrintType(string prefix, Type ty) {
- Contract.Requires(prefix != null);
- Contract.Requires(ty != null);
- string s = ty.ToString();
- if (s != "?") {
- wr.Write("{0}{1}", prefix, s);
- }
- }
-
- // ----------------------------- PrintStatement -----------------------------
-
- /// <summary>
- /// Prints from the current position of the current line.
- /// If the statement requires several lines, subsequent lines are indented at "indent".
- /// No newline is printed after the statement.
- /// </summary>
- public void PrintStatement(Statement stmt, int indent) {
- Contract.Requires(stmt != null);
- for (LList<Label> label = stmt.Labels; label != null; label = label.Next) {
- if (label.Data.Name != null) {
- wr.WriteLine("label {0}:", label.Data.Name);
- Indent(indent);
- }
- }
-
- if (stmt is PredicateStmt) {
- Expression expr = ((PredicateStmt)stmt).Expr;
- wr.Write(stmt is AssertStmt ? "assert" : "assume");
- if (stmt.HasAttributes()) {
- PrintAttributes(stmt.Attributes);
- }
- wr.Write(" ");
- PrintExpression(expr);
- wr.Write(";");
-
- } else if (stmt is PrintStmt) {
- PrintStmt s = (PrintStmt)stmt;
- wr.Write("print");
- PrintAttributeArgs(s.Args);
- wr.Write(";");
-
- } else if (stmt is BreakStmt) {
- BreakStmt s = (BreakStmt)stmt;
- if (s.TargetLabel != null) {
- wr.Write("break {0};", s.TargetLabel);
- } else {
- string sep = "";
- for (int i = 0; i < s.BreakCount; i++) {
- wr.Write("{0}break", sep);
- sep = " ";
- }
- wr.Write(";");
- }
-
- } else if (stmt is ProduceStmt) {
- var s = (ProduceStmt) stmt;
- wr.Write(s is YieldStmt ? "yield" : "return");
- if (s.rhss != null) {
- var sep = " ";
- foreach (var rhs in s.rhss) {
- wr.Write(sep);
- PrintRhs(rhs);
- sep = ", ";
- }
- }
- wr.Write(";");
-
- } else if (stmt is AssignStmt) {
- AssignStmt s = (AssignStmt)stmt;
- PrintExpression(s.Lhs);
- wr.Write(" := ");
- PrintRhs(s.Rhs);
- wr.Write(";");
-
- } else if (stmt is VarDecl) {
- VarDecl s = (VarDecl)stmt;
- if (s.IsGhost) {
- wr.Write("ghost ");
- }
- wr.Write("var {0}", s.DisplayName);
- PrintType(": ", s.OptionalType);
- wr.Write(";");
-
- } else if (stmt is CallStmt) {
- CallStmt s = (CallStmt)stmt;
- if (s.Lhs.Count != 0) {
- string sep = "";
- foreach (IdentifierExpr v in s.Lhs) {
- wr.Write(sep);
- PrintExpression(v);
- sep = ", ";
- }
- wr.Write(" := ");
- }
- if (!(s.Receiver is ImplicitThisExpr)) {
- PrintExpr(s.Receiver, 0x70, false, false, -1);
- wr.Write(".");
- }
- wr.Write("{0}(", s.MethodName);
- PrintExpressionList(s.Args);
- wr.Write(");");
-
- } else if (stmt is BlockStmt) {
- wr.WriteLine("{");
- int ind = indent + IndentAmount;
- foreach (Statement s in ((BlockStmt)stmt).Body) {
- Indent(ind);
- PrintStatement(s, ind);
- wr.WriteLine();
- }
- Indent(indent);
- wr.Write("}");
-
- } else if (stmt is IfStmt) {
- IfStmt s = (IfStmt)stmt;
- PrintIfStatement(indent, s, false);
-
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- wr.WriteLine("if {");
- PrintAlternatives(indent, s.Alternatives);
- Indent(indent);
- wr.Write("}");
-
- } else if (stmt is WhileStmt) {
- WhileStmt s = (WhileStmt)stmt;
- PrintWhileStatement(indent, s, false, false);
-
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- wr.WriteLine("while");
- PrintSpec("invariant", s.Invariants, indent + IndentAmount);
- PrintDecreasesSpec(s.Decreases, indent + IndentAmount);
-
- Indent(indent);
- wr.WriteLine("{");
- PrintAlternatives(indent, s.Alternatives);
- Indent(indent);
- wr.Write("}");
-
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- wr.Write("parallel (");
- if (s.BoundVars.Count != 0) {
- PrintQuantifierDomain(s.BoundVars, s.Attributes, s.Range);
- }
- if (s.Ens.Count == 0) {
- wr.Write(") ");
- } else {
- wr.WriteLine(")");
- PrintSpec("ensures", s.Ens, indent + IndentAmount);
- Indent(indent);
- }
- PrintStatement(s.Body, indent);
-
- } else if (stmt is CalcStmt) {
- CalcStmt s = (CalcStmt)stmt;
- wr.Write("calc ");
- if (s.Op != CalcStmt.DefaultOp) {
- wr.Write(BinaryExpr.OpcodeString(s.Op));
- wr.Write(" ");
- }
- wr.WriteLine("{");
- int lineInd = indent + IndentAmount;
- if (s.Lines.Count > 0) {
- Indent(lineInd);
- PrintExpression(s.Lines.First(), lineInd);
- wr.WriteLine(";");
- }
- for (var i = 1; i < s.Lines.Count; i++){
- var e = s.Lines[i];
- var h = s.Hints[i - 1];
- var op = s.CustomOps[i - 1];
- foreach (var st in h.Body) {
- Indent(lineInd);
- PrintStatement(st, lineInd);
- wr.WriteLine();
- }
- Indent(lineInd);
- if (op != null && (BinaryExpr.Opcode)op != s.Op) {
- wr.Write(BinaryExpr.OpcodeString((BinaryExpr.Opcode)op));
- wr.Write(" ");
- }
- PrintExpression(e, lineInd);
- wr.WriteLine(";");
- }
- Indent(indent);
- wr.Write("}");
-
- } else if (stmt is MatchStmt) {
- MatchStmt s = (MatchStmt)stmt;
- wr.Write("match ");
- PrintExpression(s.Source);
- wr.WriteLine(" {");
- int caseInd = indent + IndentAmount;
- foreach (MatchCaseStmt mc in s.Cases) {
- Indent(caseInd);
- wr.Write("case {0}", mc.Id);
- if (mc.Arguments.Count != 0) {
- string sep = "(";
- foreach (BoundVar bv in mc.Arguments) {
- wr.Write("{0}{1}", sep, bv.DisplayName);
- sep = ", ";
- }
- wr.Write(")");
- }
- wr.WriteLine(" =>");
- foreach (Statement bs in mc.Body) {
- Indent(caseInd + IndentAmount);
- PrintStatement(bs, caseInd + IndentAmount);
- wr.WriteLine();
- }
- }
- Indent(indent);
- wr.Write("}");
-
- } else if (stmt is ConcreteUpdateStatement) {
- var s = (ConcreteUpdateStatement)stmt;
- string sep = "";
- foreach (var lhs in s.Lhss) {
- wr.Write(sep);
- PrintExpression(lhs);
- sep = ", ";
- }
- PrintUpdateRHS(s);
- wr.Write(";");
-
- } else if (stmt is VarDeclStmt) {
- var s = (VarDeclStmt)stmt;
- if (s.Lhss[0].IsGhost) {
- wr.Write("ghost ");
- }
- wr.Write("var ");
- string sep = "";
- foreach (var lhs in s.Lhss) {
- wr.Write("{0}{1}", sep, lhs.DisplayName);
- PrintType(": ", lhs.OptionalType);
- sep = ", ";
- }
- if (s.Update != null) {
- PrintUpdateRHS(s.Update);
- }
- wr.Write(";");
-
- } else if (stmt is SkeletonStatement) {
- var s = (SkeletonStatement)stmt;
- if (s.S == null) {
- wr.Write("...;");
- } else if (s.S is AssertStmt) {
- Contract.Assert(s.ConditionOmitted);
- wr.Write("assert ...;");
- } else if (s.S is AssumeStmt) {
- Contract.Assert(s.ConditionOmitted);
- wr.Write("assume ...;");
- } else if (s.S is IfStmt) {
- PrintIfStatement(indent, (IfStmt)s.S, s.ConditionOmitted);
- } else if (s.S is WhileStmt) {
- PrintWhileStatement(indent, (WhileStmt)s.S, s.ConditionOmitted, s.BodyOmitted);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected skeleton statement
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
- }
- }
-
- /// <summary>
- /// Does not print LHS
- /// </summary>
- void PrintUpdateRHS(ConcreteUpdateStatement s) {
- Contract.Requires(s != null);
- if (s is UpdateStmt) {
- var update = (UpdateStmt)s;
- if (update.Lhss.Count != 0) {
- wr.Write(" := ");
- }
- var sep = "";
- foreach (var rhs in update.Rhss) {
- wr.Write(sep);
- PrintRhs(rhs);
- sep = ", ";
- }
- } else if (s is AssignSuchThatStmt) {
- var update = (AssignSuchThatStmt)s;
- wr.Write(" :| ");
- if (update.AssumeToken != null) {
- wr.Write("assume ");
- }
- PrintExpression(update.Expr);
- } else {
- Contract.Assert(s == null); // otherwise, unknown type
- }
- }
-
- void PrintIfStatement(int indent, IfStmt s, bool omitGuard) {
- while (true) {
- if (omitGuard) {
- wr.Write("if ... ");
- } else {
- wr.Write("if (");
- PrintGuard(s.Guard);
- wr.Write(") ");
- }
- PrintStatement(s.Thn, indent);
- if (s.Els == null) {
- break;
- }
- wr.Write(" else ");
- if (s.Els is IfStmt) {
- s = (IfStmt)s.Els;
- } else {
- PrintStatement(s.Els, indent);
- break;
- }
- }
- }
-
- void PrintWhileStatement(int indent, WhileStmt s, bool omitGuard, bool omitBody) {
- if (omitGuard) {
- wr.WriteLine("while ...");
- } else {
- wr.Write("while (");
- PrintGuard(s.Guard);
- wr.WriteLine(")");
- }
-
- PrintSpec("invariant", s.Invariants, indent + IndentAmount);
- PrintDecreasesSpec(s.Decreases, indent + IndentAmount);
- if (s.Mod.Expressions != null) {
- PrintFrameSpecLine("modifies", s.Mod.Expressions, indent + IndentAmount, s.Mod.HasAttributes() ? s.Mod.Attributes : null);
- }
- Indent(indent);
- if (omitBody) {
- wr.WriteLine("...;");
- } else {
- PrintStatement(s.Body, indent);
- }
- }
-
- void PrintAlternatives(int indent, List<GuardedAlternative> alternatives) {
- int caseInd = indent + IndentAmount;
- foreach (var alternative in alternatives) {
- Indent(caseInd);
- wr.Write("case ");
- PrintExpression(alternative.Guard);
- wr.WriteLine(" =>");
- foreach (Statement s in alternative.Body) {
- Indent(caseInd + IndentAmount);
- PrintStatement(s, caseInd + IndentAmount);
- wr.WriteLine();
- }
- }
- }
-
- void PrintRhs(AssignmentRhs rhs) {
- Contract.Requires(rhs != null);
- if (rhs is ExprRhs) {
- PrintExpression(((ExprRhs)rhs).Expr);
- } else if (rhs is HavocRhs) {
- wr.Write("*");
- } else if (rhs is TypeRhs) {
- TypeRhs t = (TypeRhs)rhs;
- wr.Write("new ");
- PrintType(t.EType);
- if (t.ArrayDimensions != null) {
- string s = "[";
- foreach (Expression dim in t.ArrayDimensions) {
- Contract.Assume(dim != null);
- wr.Write(s);
- PrintExpression(dim);
- s = ", ";
- }
- wr.Write("]");
- } else if (t.InitCall != null) {
- wr.Write(".{0}(", t.InitCall.MethodName);
- PrintExpressionList(t.InitCall.Args);
- wr.Write(")");
- }
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected RHS
- }
-
- if (rhs.HasAttributes())
- {
- PrintAttributes(rhs.Attributes);
- }
- }
-
- void PrintGuard(Expression guard) {
- if (guard == null) {
- wr.Write("*");
- } else {
- PrintExpression(guard);
- }
- }
-
- // ----------------------------- PrintExpression -----------------------------
-
- public void PrintExtendedExpr(Expression expr, int indent, bool isRightmost, bool endWithCloseParen) {
- Contract.Requires(expr != null);
- Indent(indent);
- if (expr is ITEExpr) {
- while (true) {
- ITEExpr ite = (ITEExpr)expr;
- wr.Write("if ");
- PrintExpression(ite.Test);
- wr.WriteLine(" then");
- PrintExtendedExpr(ite.Thn, indent + IndentAmount, true, false);
- expr = ite.Els;
- if (expr is ITEExpr) {
- Indent(indent); wr.Write("else ");
- } else {
- Indent(indent); wr.WriteLine("else");
- Indent(indent + IndentAmount);
- PrintExpression(expr);
- wr.WriteLine(endWithCloseParen ? ")" : "");
- return;
- }
- }
- } else if (expr is MatchExpr) {
- MatchExpr me = (MatchExpr)expr;
- wr.Write("match ");
- PrintExpression(me.Source);
- wr.WriteLine();
- int i = 0;
- foreach (MatchCaseExpr mc in me.Cases) {
- bool isLastCase = i == me.Cases.Count - 1;
- Indent(indent);
- wr.Write("case {0}", mc.Id);
- if (mc.Arguments.Count != 0) {
- string sep = "(";
- foreach (BoundVar bv in mc.Arguments) {
- wr.Write("{0}{1}", sep, bv.DisplayName);
- sep = ", ";
- }
- wr.Write(")");
- }
- bool parensNeeded = !isLastCase && mc.Body.WasResolved() && mc.Body.Resolved is MatchExpr;
- if (parensNeeded) {
- wr.WriteLine(" => (");
- } else {
- wr.WriteLine(" =>");
- }
- PrintExtendedExpr(mc.Body, indent + IndentAmount, isLastCase, parensNeeded || (isLastCase && endWithCloseParen));
- i++;
- }
- } else if (expr is ParensExpression) {
- PrintExtendedExpr(((ParensExpression)expr).E, indent, isRightmost, endWithCloseParen);
- } else {
- PrintExpression(expr, indent);
- wr.WriteLine(endWithCloseParen ? ")" : "");
- }
- }
-
- public void PrintExpression(Expression expr) {
- Contract.Requires(expr != null);
- PrintExpr(expr, 0, false, true, -1);
- }
-
- /// <summary>
- /// An indent of -1 means print the entire expression on one line.
- /// </summary>
- public void PrintExpression(Expression expr, int indent) {
- Contract.Requires(expr != null);
- PrintExpr(expr, 0, false, true, indent);
- }
-
- /// <summary>
- /// An indent of -1 means print the entire expression on one line.
- /// </summary>
- void PrintExpr(Expression expr, int contextBindingStrength, bool fragileContext, bool isRightmost, int indent)
- {
- Contract.Requires(-1 <= indent);
- Contract.Requires(expr != null);
-
- if (expr is LiteralExpr) {
- LiteralExpr e = (LiteralExpr)expr;
- if (e.Value == null) {
- wr.Write("null");
- } else if (e.Value is bool) {
- wr.Write((bool)e.Value ? "true" : "false");
- } else {
- wr.Write((BigInteger)e.Value);
- }
-
- } else if (expr is ThisExpr) {
- wr.Write("this");
-
- } else if (expr is IdentifierExpr) {
- wr.Write(((IdentifierExpr)expr).Name);
-
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- wr.Write("#{0}.{1}", dtv.DatatypeName, dtv.MemberName);
- if (dtv.Arguments.Count != 0) {
- wr.Write("(");
- PrintExpressionList(dtv.Arguments);
- wr.Write(")");
- }
-
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- if (e is MultiSetDisplayExpr) wr.Write("multiset");
- wr.Write(e is SetDisplayExpr || e is MultiSetDisplayExpr ? "{" : "[");
- PrintExpressionList(e.Elements);
- wr.Write(e is SetDisplayExpr || e is MultiSetDisplayExpr ? "}" : "]");
-
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- wr.Write("map");
- wr.Write("{");
- PrintExpressionPairList(e.Elements);
- wr.Write("}");
- } else if (expr is ExprDotName) {
- var e = (ExprDotName)expr;
- // determine if parens are needed
- int opBindingStrength = 0x70;
- bool parensNeeded = !(e.Obj is ImplicitThisExpr) &&
- opBindingStrength < contextBindingStrength ||
- (fragileContext && opBindingStrength == contextBindingStrength);
-
- if (parensNeeded) { wr.Write("("); }
- if (!(e.Obj is ImplicitThisExpr)) {
- PrintExpr(e.Obj, opBindingStrength, false, false, -1);
- wr.Write(".");
- }
- wr.Write(e.SuffixName);
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr e = (FieldSelectExpr)expr;
- // determine if parens are needed
- int opBindingStrength = 0x70;
- bool parensNeeded = !(e.Obj is ImplicitThisExpr) &&
- opBindingStrength < contextBindingStrength ||
- (fragileContext && opBindingStrength == contextBindingStrength);
-
- if (parensNeeded) { wr.Write("("); }
- if (!(e.Obj is ImplicitThisExpr)) {
- PrintExpr(e.Obj, opBindingStrength, false, false, -1);
- wr.Write(".");
- }
- wr.Write(e.FieldName);
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- // determine if parens are needed
- int opBindingStrength = 0x70;
- bool parensNeeded = opBindingStrength < contextBindingStrength ||
- (fragileContext && opBindingStrength == contextBindingStrength);
-
- if (parensNeeded) { wr.Write("("); }
- PrintExpr(e.Seq, 0x00, false, false, indent); // BOGUS: fix me
- wr.Write("[");
- if (e.SelectOne) {
- Contract.Assert( e.E0 != null);
- PrintExpression(e.E0);
- } else {
- if (e.E0 != null) {
- PrintExpression(e.E0);
- }
- wr.Write(e.E0 != null && e.E1 != null ? " .. " : "..");
- if (e.E1 != null) {
- PrintExpression(e.E1);
- }
- }
- wr.Write("]");
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
- // determine if parens are needed
- int opBindingStrength = 0x70;
- bool parensNeeded = opBindingStrength < contextBindingStrength ||
- (fragileContext && opBindingStrength == contextBindingStrength);
-
- if (parensNeeded) { wr.Write("("); }
- PrintExpr(e.Array, 0x00, false, false, indent); // BOGUS: fix me
- string prefix = "[";
- foreach (Expression idx in e.Indices) {
- Contract.Assert(idx != null);
- wr.Write(prefix);
- PrintExpression(idx);
- prefix = ", ";
- }
- wr.Write("]");
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- // determine if parens are needed
- int opBindingStrength = 0x70;
- bool parensNeeded = opBindingStrength < contextBindingStrength ||
- (fragileContext && opBindingStrength == contextBindingStrength);
-
- if (parensNeeded) { wr.Write("("); }
- PrintExpr(e.Seq, 00, false, false, indent); // BOGUS: fix me
- wr.Write("[");
- PrintExpression(e.Index);
- wr.Write(" := ");
- PrintExpression(e.Value);
- wr.Write("]");
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- // determine if parens are needed
- int opBindingStrength = 0x70;
- bool parensNeeded = !(e.Receiver is ImplicitThisExpr) &&
- opBindingStrength < contextBindingStrength ||
- (fragileContext && opBindingStrength == contextBindingStrength);
-
- if (parensNeeded) { wr.Write("("); }
- if (!(e.Receiver is ImplicitThisExpr)) {
- PrintExpr(e.Receiver, opBindingStrength, false, false, -1);
- wr.Write(".");
- }
- wr.Write(e.Name);
- if (e.OpenParen == null) {
- Contract.Assert(e.Args.Count == 0);
- } else {
- wr.Write("(");
- PrintExpressionList(e.Args);
- wr.Write(")");
- }
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is OldExpr) {
- wr.Write("old(");
- PrintExpression(((OldExpr)expr).E);
- wr.Write(")");
-
- } else if (expr is MultiSetFormingExpr) {
- wr.Write("multiset(");
- PrintExpression(((MultiSetFormingExpr)expr).E);
- wr.Write(")");
-
- } else if (expr is FreshExpr) {
- wr.Write("fresh(");
- PrintExpression(((FreshExpr)expr).E);
- wr.Write(")");
-
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- if (e.Op == UnaryExpr.Opcode.SeqLength) {
- wr.Write("|");
- PrintExpression(e.E);
- wr.Write("|");
- } else {
- // Prefix operator.
- // determine if parens are needed
- string op;
- int opBindingStrength;
- switch (e.Op) {
- case UnaryExpr.Opcode.SetChoose:
- op = "choose "; opBindingStrength = 0; break;
- case UnaryExpr.Opcode.Not:
- op = "!"; opBindingStrength = 0x60; break;
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected unary opcode
- }
- bool parensNeeded = opBindingStrength < contextBindingStrength ||
- (fragileContext && opBindingStrength == contextBindingStrength);
-
- bool containsNestedNot = e.E is ParensExpression &&
- ((ParensExpression)e.E).E is UnaryExpr &&
- ((UnaryExpr)((ParensExpression)e.E).E).Op == UnaryExpr.Opcode.Not;
-
- if (parensNeeded) { wr.Write("("); }
- wr.Write(op);
- PrintExpr(e.E, opBindingStrength, containsNestedNot, parensNeeded || isRightmost, -1);
- if (parensNeeded) { wr.Write(")"); }
- }
-
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- // determine if parens are needed
- int opBindingStrength;
- bool fragileLeftContext = false; // false means "allow same binding power on left without parens"
- bool fragileRightContext = false; // false means "allow same binding power on right without parens"
- switch (e.Op)
- {
- case BinaryExpr.Opcode.Add:
- opBindingStrength = 0x40; break;
- case BinaryExpr.Opcode.Sub:
- opBindingStrength = 0x40; fragileRightContext = true; break;
- case BinaryExpr.Opcode.Mul:
- opBindingStrength = 0x50; break;
- case BinaryExpr.Opcode.Div:
- case BinaryExpr.Opcode.Mod:
- opBindingStrength = 0x50; fragileRightContext = true; break;
- case BinaryExpr.Opcode.Eq:
- case BinaryExpr.Opcode.Neq:
- case BinaryExpr.Opcode.Gt:
- case BinaryExpr.Opcode.Ge:
- case BinaryExpr.Opcode.Lt:
- case BinaryExpr.Opcode.Le:
- case BinaryExpr.Opcode.Disjoint:
- case BinaryExpr.Opcode.In:
- case BinaryExpr.Opcode.NotIn:
- opBindingStrength = 0x30; fragileLeftContext = fragileRightContext = true; break;
- case BinaryExpr.Opcode.And:
- opBindingStrength = 0x20; break;
- case BinaryExpr.Opcode.Or:
- opBindingStrength = 0x21; break;
- case BinaryExpr.Opcode.Imp:
- opBindingStrength = 0x10; fragileLeftContext = true; break;
- case BinaryExpr.Opcode.Iff:
- opBindingStrength = 0x08; break;
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected binary operator
- }
- int opBS = opBindingStrength & 0xF8;
- int ctxtBS = contextBindingStrength & 0xF8;
- bool parensNeeded = opBS < ctxtBS ||
- (opBS == ctxtBS && (opBindingStrength != contextBindingStrength || fragileContext));
-
- string op = BinaryExpr.OpcodeString(e.Op);
- if (parensNeeded) { wr.Write("("); }
- if (0 <= indent && e.Op == BinaryExpr.Opcode.And) {
- PrintExpr(e.E0, opBindingStrength, fragileLeftContext, false, indent);
- wr.WriteLine(" {0}", op);
- Indent(indent);
- PrintExpr(e.E1, opBindingStrength, fragileRightContext, parensNeeded || isRightmost, indent);
- } else if (0 <= indent && e.Op == BinaryExpr.Opcode.Imp) {
- PrintExpr(e.E0, opBindingStrength, fragileLeftContext, false, indent);
- wr.WriteLine(" {0}", op);
- int ind = indent + IndentAmount;
- Indent(ind);
- PrintExpr(e.E1, opBindingStrength, fragileRightContext, parensNeeded || isRightmost, ind);
- } else {
- PrintExpr(e.E0, opBindingStrength, fragileLeftContext, false, -1);
- wr.Write(" {0} ", op);
- PrintExpr(e.E1, opBindingStrength, fragileRightContext, parensNeeded || isRightmost, -1);
- }
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is ChainingExpression) {
- var e = (ChainingExpression)expr;
- // determine if parens are needed
- int opBindingStrength = 0x30;
- int opBS = opBindingStrength & 0xF8;
- int ctxtBS = contextBindingStrength & 0xF8;
- bool parensNeeded = opBS < ctxtBS ||
- (opBS == ctxtBS && (opBindingStrength != contextBindingStrength || fragileContext));
-
- if (parensNeeded) { wr.Write("("); }
- PrintExpr(e.Operands[0], opBindingStrength, true, false, -1);
- for (int i = 0; i < e.Operators.Count; i++) {
- string op = BinaryExpr.OpcodeString(e.Operators[i]);
- wr.Write(" {0} ", op);
- PrintExpr(e.Operands[i+1], opBindingStrength, true, i == e.Operators.Count - 1 && (parensNeeded || isRightmost), -1);
- }
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- bool parensNeeded = !isRightmost;
- if (parensNeeded) { wr.Write("("); }
- wr.Write("var ");
- string sep = "";
- foreach (var v in e.Vars) {
- wr.Write("{0}{1}", sep, v.DisplayName);
- PrintType(": ", v.Type);
- sep = ", ";
- }
- wr.Write(" := ");
- PrintExpressionList(e.RHSs);
- wr.Write("; ");
- PrintExpression(e.Body);
- if (parensNeeded) { wr.Write(")"); }
-
-
- } else if (expr is QuantifierExpr) {
- QuantifierExpr e = (QuantifierExpr)expr;
- bool parensNeeded = !isRightmost;
- if (parensNeeded) { wr.Write("("); }
- wr.Write(e is ForallExpr ? "forall " : "exists ");
- PrintQuantifierDomain(e.BoundVars, e.Attributes, e.Range);
- wr.Write(" :: ");
- if (0 <= indent) {
- int ind = indent + IndentAmount;
- wr.WriteLine();
- Indent(ind);
- PrintExpression(e.Term, ind);
- } else {
- PrintExpression(e.Term);
- }
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is NamedExpr) {
- var e = (NamedExpr)expr;
- wr.Write("expr {0}: ", e.Name);
- PrintExpression(e.Body);
-
- } else if (expr is SetComprehension) {
- var e = (SetComprehension)expr;
- bool parensNeeded = !isRightmost;
- if (parensNeeded) { wr.Write("("); }
- wr.Write("set ");
- string sep = "";
- foreach (BoundVar bv in e.BoundVars) {
- wr.Write("{0}{1}", sep, bv.DisplayName);
- sep = ", ";
- PrintType(": ", bv.Type);
- }
- PrintAttributes(e.Attributes);
- wr.Write(" | ");
- PrintExpression(e.Range);
- if (!e.TermIsImplicit) {
- wr.Write(" :: ");
- PrintExpression(e.Term);
- }
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is MapComprehension) {
- var e = (MapComprehension)expr;
- bool parensNeeded = !isRightmost;
- if (parensNeeded) { wr.Write("("); }
- wr.Write("map ");
- string sep = "";
- foreach (BoundVar bv in e.BoundVars) {
- wr.Write("{0}{1}", sep, bv.DisplayName);
- sep = ", ";
- PrintType(": ", bv.Type);
- }
- PrintAttributes(e.Attributes);
- wr.Write(" | ");
- PrintExpression(e.Range);
- wr.Write(" :: ");
- PrintExpression(e.Term);
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is WildcardExpr) {
- wr.Write("*");
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- bool parensNeeded = !isRightmost;
- if (parensNeeded) { wr.Write("("); }
- wr.Write("{0} ", e.Kind);
- PrintExpression(e.Guard);
- wr.Write("; ");
- PrintExpression(e.Body);
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is ITEExpr) {
- ITEExpr ite = (ITEExpr)expr;
- bool parensNeeded = !isRightmost;
- if (parensNeeded) { wr.Write("("); }
- wr.Write("if ");
- PrintExpression(ite.Test);
- wr.Write(" then ");
- PrintExpression(ite.Thn);
- wr.Write(" else ");
- PrintExpression(ite.Els);
- if (parensNeeded) { wr.Write(")"); }
-
- } else if (expr is ParensExpression) {
- var e = (ParensExpression)expr;
- // printing of parentheses is done optimally, not according to the parentheses in the given program
- PrintExpr(e.E, contextBindingStrength, fragileContext, isRightmost, indent);
-
- } else if (expr is IdentifierSequence) {
- var e = (IdentifierSequence)expr;
- string sep = "";
- foreach (var id in e.Tokens) {
- wr.Write("{0}{1}", sep, id.val);
- sep = ".";
- }
- if (e.Arguments != null) {
- wr.Write("(");
- PrintExpressionList(e.Arguments);
- wr.Write(")");
- }
-
- } else if (expr is MatchExpr) {
- Contract.Assert(false); throw new cce.UnreachableException(); // MatchExpr is an extended expression and should be printed only using PrintExtendedExpr
- } else if (expr is BoxingCastExpr) {
- // this is not expected for a parsed program, but we may be called for /trace purposes in the translator
- var e = (BoxingCastExpr)expr;
- PrintExpr(e.E, contextBindingStrength, fragileContext, isRightmost, indent);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
-
- private void PrintQuantifierDomain(List<BoundVar> boundVars, Attributes attrs, Expression range) {
- Contract.Requires(boundVars != null);
- string sep = "";
- foreach (BoundVar bv in boundVars) {
- wr.Write("{0}{1}", sep, bv.DisplayName);
- PrintType(": ", bv.Type);
- sep = ", ";
- }
- PrintAttributes(attrs);
- if (range != null) {
- wr.Write(" | ");
- PrintExpression(range);
- }
- }
-
- void PrintExpressionList(List<Expression> exprs) {
- Contract.Requires(exprs != null);
- string sep = "";
- foreach (Expression e in exprs) {
- Contract.Assert(e != null);
- wr.Write(sep);
- sep = ", ";
- PrintExpression(e);
- }
- }
- void PrintExpressionPairList(List<ExpressionPair> exprs) {
- Contract.Requires(exprs != null);
- string sep = "";
- foreach (ExpressionPair p in exprs) {
- Contract.Assert(p != null);
- wr.Write(sep);
- sep = ", ";
- PrintExpression(p.A);
- wr.Write(":=");
- PrintExpression(p.B);
- }
- }
-
- void PrintFrameExpressionList(List<FrameExpression/*!*/>/*!*/ fexprs) {
- Contract.Requires(fexprs != null);
- string sep = "";
- foreach (FrameExpression fe in fexprs) {
- Contract.Assert(fe != null);
- wr.Write(sep);
- sep = ", ";
- PrintExpression(fe.E);
- if (fe.FieldName != null) {
- wr.Write("`{0}", fe.FieldName);
- }
- }
- }
- }
-}
diff --git a/Source/Dafny/RefinementTransformer.cs b/Source/Dafny/RefinementTransformer.cs
deleted file mode 100644
index 03f8faad..00000000
--- a/Source/Dafny/RefinementTransformer.cs
+++ /dev/null
@@ -1,1411 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-// This file contains the transformations that are applied to a module that is
-// constructed as a refinement of another. It is invoked during program resolution,
-// so the transformation is done syntactically. Upon return from the RefinementTransformer,
-// the caller is expected to resolve the resulting module.
-//
-// As for now (and perhaps this is always the right thing to do), attributes do
-// not survive the transformation.
-//-----------------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Numerics;
-using System.Diagnostics.Contracts;
-using IToken = Microsoft.Boogie.IToken;
-
-namespace Microsoft.Dafny
-{
- public class RefinementToken : TokenWrapper
- {
- public readonly ModuleDefinition InheritingModule;
- public RefinementToken(IToken tok, ModuleDefinition m)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(m != null);
- this.InheritingModule = m;
- }
-
- public static bool IsInherited(IToken tok, ModuleDefinition m) {
- while (tok is NestedToken) {
- var n = (NestedToken)tok;
- // check Outer
- var r = n.Outer as RefinementToken;
- if (r == null || r.InheritingModule != m) {
- return false;
- }
- // continue to check Inner
- tok = n.Inner;
- }
- var rtok = tok as RefinementToken;
- return rtok != null && rtok.InheritingModule == m;
- }
- public override string filename {
- get { return WrappedToken.filename + "[" + InheritingModule.Name + "]"; }
- set { throw new NotSupportedException(); }
- }
- }
-
- public class RefinementTransformer : IRewriter
- {
- ResolutionErrorReporter reporter;
- Cloner rawCloner; // This cloner just gives exactly the same thing back.
- RefinementCloner refinementCloner; // This cloner wraps things in a RefinementTransformer
- Program program;
- public RefinementTransformer(ResolutionErrorReporter reporter, Program p) {
- Contract.Requires(reporter != null);
- this.reporter = reporter;
- rawCloner = new Cloner();
- program = p;
- }
-
- private ModuleDefinition moduleUnderConstruction; // non-null for the duration of Construct calls
- private Queue<Action> postTasks = new Queue<Action>(); // empty whenever moduleUnderConstruction==null, these tasks are for the post-resolve phase of module moduleUnderConstruction
- public Queue<Tuple<Method, Method>> translationMethodChecks = new Queue<Tuple<Method, Method>>(); // contains all the methods that need to be checked for structural refinement.
- private Method currentMethod;
-
- public void PreResolve(ModuleDefinition m) {
-
- if (m.RefinementBase == null) return;
-
- if (moduleUnderConstruction != null) {
- postTasks.Clear();
- }
- moduleUnderConstruction = m;
- refinementCloner = new RefinementCloner(moduleUnderConstruction);
- var prev = m.RefinementBase;
-
- // Create a simple name-to-decl dictionary. Ignore any duplicates at this time.
- var declaredNames = new Dictionary<string, int>();
- for (int i = 0; i < m.TopLevelDecls.Count; i++) {
- var d = m.TopLevelDecls[i];
- if (!declaredNames.ContainsKey(d.Name)) {
- declaredNames.Add(d.Name, i);
- }
- }
-
- // Merge the declarations of prev into the declarations of m
- foreach (var d in prev.TopLevelDecls) {
- int index;
- if (!declaredNames.TryGetValue(d.Name, out index)) {
- m.TopLevelDecls.Add(refinementCloner.CloneDeclaration(d, m));
- } else {
- var nw = m.TopLevelDecls[index];
- if (d is ModuleDecl) {
- if (!(nw is ModuleDecl)) {
- reporter.Error(nw, "a module ({0}) must refine another module", nw.Name);
- } else if (!(d is AbstractModuleDecl)) {
- reporter.Error(nw, "a module ({0}) can only refine abstract modules", nw.Name);
- } else {
- ModuleSignature original = ((AbstractModuleDecl)d).OriginalSignature;
- ModuleSignature derived = null;
- if (nw is AliasModuleDecl) {
- derived = ((AliasModuleDecl)nw).Signature;
- } else if (nw is AbstractModuleDecl) {
- derived = ((AbstractModuleDecl)nw).Signature;
- } else {
- reporter.Error(nw, "a module ({0}) can only be refined by alias or abstract modules", d.Name);
- }
- if (derived != null) {
- // check that the new module refines the previous declaration
- if (!CheckIsRefinement(derived, original))
- reporter.Error(nw.tok, "a module ({0}) can only be replaced by a refinement of the original module", d.Name);
- }
- }
- } else if (d is ArbitraryTypeDecl) {
- if (nw is ModuleDecl) {
- reporter.Error(nw, "a module ({0}) must refine another module", nw.Name);
- } else {
- bool dDemandsEqualitySupport = ((ArbitraryTypeDecl)d).MustSupportEquality;
- if (nw is ArbitraryTypeDecl) {
- if (dDemandsEqualitySupport != ((ArbitraryTypeDecl)nw).MustSupportEquality) {
- reporter.Error(nw, "type declaration '{0}' is not allowed to change the requirement of supporting equality", nw.Name);
- }
- } else if (dDemandsEqualitySupport) {
- if (nw is ClassDecl) {
- // fine, as long as "nw" does not take any type parameters
- if (nw.TypeArgs.Count != d.TypeArgs.Count) {
- reporter.Error(nw, "arbitrary type '{0}' is not allowed to be replaced by a class that takes a different number of type parameters", nw.Name);
- }
- } else if (nw is CoDatatypeDecl) {
- reporter.Error(nw, "a type declaration that requires equality support cannot be replaced by a codatatype");
- } else {
- Contract.Assert(nw is IndDatatypeDecl);
- if (nw.TypeArgs.Count != d.TypeArgs.Count) {
- reporter.Error(nw, "arbitrary type '{0}' is not allowed to be replaced by a datatype that takes a different number of type parameters", nw.Name);
- } else {
- // Here, we need to figure out if the new type supports equality. But we won't know about that until resolution has
- // taken place, so we defer it until the PostResolve phase.
- var udt = new UserDefinedType(nw.tok, nw.Name, nw, new List<Type>());
- postTasks.Enqueue(delegate() {
- if (!udt.SupportsEquality) {
- reporter.Error(udt.tok, "datatype '{0}' is used to refine an arbitrary type with equality support, but '{0}' does not support equality", udt.Name);
- }
- });
- }
- }
- } else if (d.TypeArgs.Count != nw.TypeArgs.Count) {
- reporter.Error(nw, "arbitrary type '{0}' is not allowed to be replaced by a type that takes a different number of type parameters", nw.Name);
- }
- }
- } else if (nw is ArbitraryTypeDecl) {
- reporter.Error(nw, "an arbitrary type declaration ({0}) in a refining module cannot replace a more specific type declaration in the refinement base", nw.Name);
- } else if (nw is DatatypeDecl) {
- reporter.Error(nw, "a datatype declaration ({0}) in a refinement module can only replace an arbitrary-type declaration", nw.Name);
- } else if (nw is IteratorDecl) {
- if (d is IteratorDecl) {
- m.TopLevelDecls[index] = MergeIterator((IteratorDecl)nw, (IteratorDecl)d);
- } else {
- reporter.Error(nw, "an iterator declaration ({0}) is a refining module cannot replace a different kind of declaration in the refinement base", nw.Name);
- }
- } else {
- Contract.Assert(nw is ClassDecl);
- if (d is DatatypeDecl) {
- reporter.Error(nw, "a class declaration ({0}) in a refining module cannot replace a different kind of declaration in the refinement base", nw.Name);
- } else {
- m.TopLevelDecls[index] = MergeClass((ClassDecl)nw, (ClassDecl)d);
- }
- }
- }
- }
-
- Contract.Assert(moduleUnderConstruction == m); // this should be as it was set earlier in this method
- }
-
- public bool CheckIsRefinement(ModuleSignature derived, ModuleSignature original) {
- // Check refinement by construction.
- var derivedPointer = derived;
- while (derivedPointer != null) {
- if (derivedPointer == original)
- return true;
- derivedPointer = derivedPointer.Refines;
- }
- // Check structural refinement. Note this involves several checks.
- // First, we need to know if the two modules are signature compatible;
- // this is determined immediately as it is necessary for determining
- // whether resolution will succeed. This involves checking classes, datatypes,
- // type declarations, and nested modules.
- // Second, we need to determine whether the specifications will be compatible
- // (i.e. substitutable), by translating to Boogie.
-
- var errorCount = reporter.ErrorCount;
- foreach (var kv in original.TopLevels) {
- var d = kv.Value;
- TopLevelDecl nw;
- if (derived.TopLevels.TryGetValue(kv.Key, out nw)) {
- if (d is ModuleDecl) {
- if (!(nw is ModuleDecl)) {
- reporter.Error(nw, "a module ({0}) must refine another module", nw.Name);
- } else {
- CheckIsRefinement(((ModuleDecl)nw).Signature, ((ModuleDecl)d).Signature);
- }
- } else if (d is ArbitraryTypeDecl) {
- if (nw is ModuleDecl) {
- reporter.Error(nw, "a module ({0}) must refine another module", nw.Name);
- } else {
- bool dDemandsEqualitySupport = ((ArbitraryTypeDecl)d).MustSupportEquality;
- if (nw is ArbitraryTypeDecl) {
- if (dDemandsEqualitySupport != ((ArbitraryTypeDecl)nw).MustSupportEquality) {
- reporter.Error(nw, "type declaration '{0}' is not allowed to change the requirement of supporting equality", nw.Name);
- }
- } else if (dDemandsEqualitySupport) {
- if (nw is ClassDecl) {
- // fine, as long as "nw" does not take any type parameters
- if (nw.TypeArgs.Count != 0) {
- reporter.Error(nw, "arbitrary type '{0}' is not allowed to be replaced by a class that takes type parameters", nw.Name);
- }
- } else if (nw is CoDatatypeDecl) {
- reporter.Error(nw, "a type declaration that requires equality support cannot be replaced by a codatatype");
- } else {
- Contract.Assert(nw is IndDatatypeDecl);
- if (nw.TypeArgs.Count != 0) {
- reporter.Error(nw, "arbitrary type '{0}' is not allowed to be replaced by a datatype that takes type parameters", nw.Name);
- } else {
- var udt = new UserDefinedType(nw.tok, nw.Name, nw, new List<Type>());
- if (!(udt.SupportsEquality)) {
- reporter.Error(nw.tok, "datatype '{0}' is used to refine an arbitrary type with equality support, but '{0}' does not support equality", nw.Name);
- }
- }
- }
- }
- }
- } else if (d is DatatypeDecl) {
- if (nw is DatatypeDecl) {
- if (d is IndDatatypeDecl && !(nw is IndDatatypeDecl)) {
- reporter.Error(nw, "a datatype ({0}) must be replaced by a datatype, not a codatatype", d.Name);
- } else if (d is CoDatatypeDecl && !(nw is CoDatatypeDecl)) {
- reporter.Error(nw, "a codatatype ({0}) must be replaced by a codatatype, not a datatype", d.Name);
- }
- // check constructors, formals, etc.
- CheckDatatypesAreRefinements((DatatypeDecl)d, (DatatypeDecl)nw);
- } else {
- reporter.Error(nw, "a {0} ({1}) must be refined by a {0}", d is IndDatatypeDecl ? "datatype" : "codatatype", d.Name);
- }
- } else if (d is ClassDecl) {
- if (!(nw is ClassDecl)) {
- reporter.Error(nw, "a class declaration ({0}) must be refined by another class declaration", nw.Name);
- } else {
- CheckClassesAreRefinements((ClassDecl)nw, (ClassDecl)d);
- }
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected toplevel
- }
- } else {
- reporter.Error(d, "declaration {0} must have a matching declaration in the refining module", d.Name);
- }
- }
- return errorCount == reporter.ErrorCount;
- }
-
- private void CheckClassesAreRefinements(ClassDecl nw, ClassDecl d) {
- if (nw.TypeArgs.Count != d.TypeArgs.Count) {
- reporter.Error(nw, "a refining class ({0}) must have the same number of type parameters", nw.Name);
- } else {
- var map = new Dictionary<string, MemberDecl>();
- foreach (var mem in nw.Members) {
- map.Add(mem.Name, mem);
- }
- foreach (var m in d.Members) {
- MemberDecl newMem;
- if (map.TryGetValue(m.Name, out newMem)) {
- if (m.IsStatic != newMem.IsStatic) {
- reporter.Error(newMem, "member {0} must {1}", m.Name, m.IsStatic? "be static" : "not be static");
- }
- if (m is Field) {
- if (newMem is Field) {
- var newField = (Field)newMem;
- if (!ResolvedTypesAreTheSame(newField.Type, ((Field)m).Type))
- reporter.Error(newMem, "field must be refined by a field with the same type (got {0}, expected {1})", newField.Type, ((Field)m).Type);
- if (m.IsGhost || !newField.IsGhost)
- reporter.Error(newField, "a field re-declaration ({0}) must be to ghostify the field", newField.Name, nw.Name);
- } else {
- reporter.Error(newMem, "a field declaration ({1}) must be replaced by a field in the refinement base (not {0})", newMem.Name, nw.Name);
- }
- } else if (m is Method) {
- if (newMem is Method) {
- CheckMethodsAreRefinements((Method)newMem, (Method)m);
- } else {
- reporter.Error(newMem, "method must be refined by a method");
- }
- } else if (m is Function) {
- if (newMem is Function) {
- CheckFunctionsAreRefinements((Function)newMem, (Function)m);
- } else {
- bool isPredicate = m is Predicate;
- bool isCoPredicate = m is CoPredicate;
- string s = isPredicate ? "predicate" : isCoPredicate ? "copredicate" : "function";
- reporter.Error(newMem, "{0} must be refined by a {0}", s);
- }
- }
- } else {
- reporter.Error(nw is DefaultClassDecl ? nw.Module.tok : nw.tok, "refining {0} must have member {1}", nw is DefaultClassDecl ? "module" : "class", m.Name);
- }
- }
- }
- }
- void CheckAgreementResolvedParameters(IToken tok, List<Formal> old, List<Formal> nw, string name, string thing, string parameterKind) {
- Contract.Requires(tok != null);
- Contract.Requires(old != null);
- Contract.Requires(nw != null);
- Contract.Requires(name != null);
- Contract.Requires(thing != null);
- Contract.Requires(parameterKind != null);
- if (old.Count != nw.Count) {
- reporter.Error(tok, "{0} '{1}' is declared with a different number of {2} ({3} instead of {4}) than the corresponding {0} in the module it refines", thing, name, parameterKind, nw.Count, old.Count);
- } else {
- for (int i = 0; i < old.Count; i++) {
- var o = old[i];
- var n = nw[i];
- if (!o.IsGhost && n.IsGhost) {
- reporter.Error(n.tok, "{0} '{1}' of {2} {3} cannot be changed, compared to the corresponding {2} in the module it refines, from non-ghost to ghost", parameterKind, n.Name, thing, name);
- } else if (o.IsGhost && !n.IsGhost) {
- reporter.Error(n.tok, "{0} '{1}' of {2} {3} cannot be changed, compared to the corresponding {2} in the module it refines, from ghost to non-ghost", parameterKind, n.Name, thing, name);
- } else if (!ResolvedTypesAreTheSame(o.Type, n.Type)) {
- reporter.Error(n.tok, "the type of {0} '{1}' is different from the type of the same {0} in the corresponding {2} in the module it refines ('{3}' instead of '{4}')", parameterKind, n.Name, thing, n.Type, o.Type);
- }
- }
- }
- }
- private void CheckMethodsAreRefinements(Method nw, Method m) {
- CheckAgreement_TypeParameters(nw.tok, m.TypeArgs, nw.TypeArgs, m.Name, "method", false);
- CheckAgreementResolvedParameters(nw.tok, m.Ins, nw.Ins, m.Name, "method", "in-parameter");
- CheckAgreementResolvedParameters(nw.tok, m.Outs, nw.Outs, m.Name, "method", "out-parameter");
- program.TranslationTasks.Add(new MethodCheck(nw, m));
- }
- private void CheckFunctionsAreRefinements(Function nw, Function f) {
- if (f is Predicate) {
- if (!(nw is Predicate)) {
- reporter.Error(nw, "a predicate declaration ({0}) can only be refined by a predicate", nw.Name);
- } else {
- CheckAgreement_TypeParameters(nw.tok, f.TypeArgs, nw.TypeArgs, nw.Name, "predicate", false);
- CheckAgreementResolvedParameters(nw.tok, f.Formals, nw.Formals, nw.Name, "predicate", "parameter");
- }
- } else if (f is CoPredicate) {
- reporter.Error(nw, "refinement of co-predicates is not supported");
- } else {
- // f is a plain Function
- if (nw is Predicate || nw is CoPredicate) {
- reporter.Error(nw, "a {0} declaration ({1}) can only be refined by a function or function method", nw.IsGhost ? "function" : "function method", nw.Name);
- } else {
- CheckAgreement_TypeParameters(nw.tok, f.TypeArgs, nw.TypeArgs, nw.Name, "function", false);
- CheckAgreementResolvedParameters(nw.tok, f.Formals, nw.Formals, nw.Name, "function", "parameter");
- if (!ResolvedTypesAreTheSame(nw.ResultType, f.ResultType)) {
- reporter.Error(nw, "the result type of function '{0}' ({1}) differs from the result type of the corresponding function in the module it refines ({2})", nw.Name, nw.ResultType, f.ResultType);
- }
- }
- }
- program.TranslationTasks.Add(new FunctionCheck(nw, f));
- }
-
-
- private void CheckDatatypesAreRefinements(DatatypeDecl dd, DatatypeDecl nn) {
- CheckAgreement_TypeParameters(nn.tok, dd.TypeArgs, nn.TypeArgs, dd.Name, "datatype", false);
- if (dd.Ctors.Count != nn.Ctors.Count) {
- reporter.Error(nn.tok, "a refining datatype must have the same number of constructors");
- } else {
- var map = new Dictionary<string, DatatypeCtor>();
- foreach (var ctor in nn.Ctors) {
- map.Add(ctor.Name, ctor);
- }
- foreach (var ctor in dd.Ctors) {
- DatatypeCtor newCtor;
- if (map.TryGetValue(ctor.Name, out newCtor)) {
- if (newCtor.Formals.Count != ctor.Formals.Count) {
- reporter.Error(newCtor, "the constructor ({0}) must have the same number of formals as in the refined module", newCtor.Name);
- } else {
- for (int i = 0; i < newCtor.Formals.Count; i++) {
- var a = ctor.Formals[i]; var b = newCtor.Formals[i];
- if (a.HasName) {
- if (!b.HasName || a.Name != b.Name)
- reporter.Error(b, "formal argument {0} in constructor {1} does not have the same name as in the refined module (should be {2})", i, ctor.Name, a.Name);
- }
- if (!ResolvedTypesAreTheSame(a.Type, b.Type)) {
- reporter.Error(b, "formal argument {0} in constructor {1} does not have the same type as in the refined module (should be {2}, not {3})", i, ctor.Name, a.Type.ToString(), b.Type.ToString());
- }
- }
- }
- } else {
- reporter.Error(nn, "the constructor {0} must be present in the refining datatype", ctor.Name);
- }
- }
- }
-
- }
- // Check that two resolved types are the same in a similar context (the same type parameters, method, class, etc.)
- // Assumes that prev is in a previous refinement, and next is in some refinement. Note this is not communative.
- public static bool ResolvedTypesAreTheSame(Type prev, Type next) {
- Contract.Requires(prev != null);
- Contract.Requires(next != null);
- if (prev is TypeProxy || next is TypeProxy)
- return false;
-
- if (prev is BoolType) {
- return next is BoolType;
- } else if (prev is IntType) {
- if (next is IntType) {
- return (prev is NatType) == (next is NatType);
- } else return false;
- } else if (prev is ObjectType) {
- return next is ObjectType;
- } else if (prev is SetType) {
- return next is SetType && ResolvedTypesAreTheSame(((SetType)prev).Arg, ((SetType)next).Arg);
- } else if (prev is MultiSetType) {
- return next is MultiSetType && ResolvedTypesAreTheSame(((MultiSetType)prev).Arg, ((MultiSetType)next).Arg);
- } else if (prev is MapType) {
- return next is MapType && ResolvedTypesAreTheSame(((MapType)prev).Domain, ((MapType)next).Domain) && ResolvedTypesAreTheSame(((MapType)prev).Range, ((MapType)next).Range);
- } else if (prev is SeqType) {
- return next is SeqType && ResolvedTypesAreTheSame(((SeqType)prev).Arg, ((SeqType)next).Arg);
- } else if (prev is UserDefinedType) {
- if (!(next is UserDefinedType)) {
- return false;
- }
- UserDefinedType aa = (UserDefinedType)prev;
- UserDefinedType bb = (UserDefinedType)next;
- if (aa.ResolvedClass != null && aa.ResolvedClass.Name == bb.ResolvedClass.Name) {
- // these are both resolved class/datatype types
- Contract.Assert(aa.TypeArgs.Count == bb.TypeArgs.Count);
- for (int i = 0; i < aa.TypeArgs.Count; i++)
- if (!ResolvedTypesAreTheSame(aa.TypeArgs[i], bb.TypeArgs[i]))
- return false;
- return true;
- } else if (aa.ResolvedParam != null && bb.ResolvedParam != null) {
- // these are both resolved type parameters
- Contract.Assert(aa.TypeArgs.Count == 0 && bb.TypeArgs.Count == 0);
- // Note that this is only correct if the two types occur in the same context, ie. both from the same method
- // or class field.
- return aa.ResolvedParam.PositionalIndex == bb.ResolvedParam.PositionalIndex &&
- aa.ResolvedParam.IsToplevelScope == bb.ResolvedParam.IsToplevelScope;
- } else if (aa.ResolvedParam.IsAbstractTypeDeclaration && bb.ResolvedClass != null) {
- return (aa.ResolvedParam.Name == bb.ResolvedClass.Name);
- } else {
- // something is wrong; either aa or bb wasn't properly resolved, or they aren't the same
- return false;
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
- public void PostResolve(ModuleDefinition m) {
- if (m == moduleUnderConstruction) {
- while (this.postTasks.Count != 0) {
- var a = postTasks.Dequeue();
- a();
- }
- } else {
- postTasks.Clear();
- }
- moduleUnderConstruction = null;
- }
- Function CloneFunction(IToken tok, Function f, bool isGhost, List<Expression> moreEnsures, Expression moreBody, Expression replacementBody, bool checkPrevPostconditions, Attributes moreAttributes) {
- Contract.Requires(moreBody == null || f is Predicate);
- Contract.Requires(moreBody == null || replacementBody == null);
-
- var tps = f.TypeArgs.ConvertAll(refinementCloner.CloneTypeParam);
- var formals = f.Formals.ConvertAll(refinementCloner.CloneFormal);
- var req = f.Req.ConvertAll(refinementCloner.CloneExpr);
- var reads = f.Reads.ConvertAll(refinementCloner.CloneFrameExpr);
- var decreases = refinementCloner.CloneSpecExpr(f.Decreases);
-
- List<Expression> ens;
- if (checkPrevPostconditions) // note, if a postcondition includes something that changes in the module, the translator will notice this and still re-check the postcondition
- ens = f.Ens.ConvertAll(rawCloner.CloneExpr);
- else
- ens = f.Ens.ConvertAll(refinementCloner.CloneExpr);
- if (moreEnsures != null) {
- ens.AddRange(moreEnsures);
- }
-
- Expression body;
- Predicate.BodyOriginKind bodyOrigin;
- if (replacementBody != null) {
- body = replacementBody;
- bodyOrigin = Predicate.BodyOriginKind.DelayedDefinition;
- } else if (moreBody != null) {
- if (f.Body == null) {
- body = moreBody;
- bodyOrigin = Predicate.BodyOriginKind.DelayedDefinition;
- } else {
- body = new BinaryExpr(f.tok, BinaryExpr.Opcode.And, refinementCloner.CloneExpr(f.Body), moreBody);
- bodyOrigin = Predicate.BodyOriginKind.Extension;
- }
- } else {
- body = refinementCloner.CloneExpr(f.Body);
- bodyOrigin = Predicate.BodyOriginKind.OriginalOrInherited;
- }
-
- if (f is Predicate) {
- return new Predicate(tok, f.Name, f.IsStatic, isGhost, tps, f.OpenParen, formals,
- req, reads, ens, decreases, body, bodyOrigin, refinementCloner.MergeAttributes(f.Attributes, moreAttributes), false);
- } else if (f is CoPredicate) {
- return new CoPredicate(tok, f.Name, f.IsStatic, tps, f.OpenParen, formals,
- req, reads, ens, body, refinementCloner.MergeAttributes(f.Attributes, moreAttributes), false);
- } else {
- return new Function(tok, f.Name, f.IsStatic, isGhost, tps, f.OpenParen, formals, refinementCloner.CloneType(f.ResultType),
- req, reads, ens, decreases, body, refinementCloner.MergeAttributes(f.Attributes, moreAttributes), false);
- }
- }
-
- Method CloneMethod(Method m, List<MaybeFreeExpression> moreEnsures, Specification<Expression> decreases, BlockStmt newBody, bool checkPreviousPostconditions, Attributes moreAttributes) {
- Contract.Requires(m != null);
- Contract.Requires(decreases != null);
-
- var tps = m.TypeArgs.ConvertAll(refinementCloner.CloneTypeParam);
- var ins = m.Ins.ConvertAll(refinementCloner.CloneFormal);
- var req = m.Req.ConvertAll(refinementCloner.CloneMayBeFreeExpr);
- var mod = refinementCloner.CloneSpecFrameExpr(m.Mod);
-
- List<MaybeFreeExpression> ens;
- if (checkPreviousPostconditions)
- ens = m.Ens.ConvertAll(rawCloner.CloneMayBeFreeExpr);
- else
- ens = m.Ens.ConvertAll(refinementCloner.CloneMayBeFreeExpr);
- if (moreEnsures != null) {
- ens.AddRange(moreEnsures);
- }
-
- var body = newBody ?? refinementCloner.CloneBlockStmt(m.Body);
- if (m is Constructor) {
- return new Constructor(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, tps, ins,
- req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), false);
- } else {
- return new Method(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, m.IsStatic, m.IsGhost, tps, ins, m.Outs.ConvertAll(refinementCloner.CloneFormal),
- req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), false);
- }
- }
-
- // -------------------------------------------------- Merging ---------------------------------------------------------------
-
- IteratorDecl MergeIterator(IteratorDecl nw, IteratorDecl prev) {
- Contract.Requires(nw != null);
- Contract.Requires(prev != null);
-
- if (nw.Requires.Count != 0) {
- reporter.Error(nw.Requires[0].E.tok, "a refining iterator is not allowed to add preconditions");
- }
- if (nw.YieldRequires.Count != 0) {
- reporter.Error(nw.YieldRequires[0].E.tok, "a refining iterator is not allowed to add yield preconditions");
- }
- if (nw.Reads.Expressions.Count != 0) {
- reporter.Error(nw.Reads.Expressions[0].E.tok, "a refining iterator is not allowed to extend the reads clause");
- }
- if (nw.Modifies.Expressions.Count != 0) {
- reporter.Error(nw.Modifies.Expressions[0].E.tok, "a refining iterator is not allowed to extend the modifies clause");
- }
- if (nw.Decreases.Expressions.Count != 0) {
- reporter.Error(nw.Decreases.Expressions[0].tok, "a refining iterator is not allowed to extend the decreases clause");
- }
-
- if (nw.SignatureIsOmitted) {
- Contract.Assert(nw.TypeArgs.Count == 0);
- Contract.Assert(nw.Ins.Count == 0);
- Contract.Assert(nw.Outs.Count == 0);
- } else {
- CheckAgreement_TypeParameters(nw.tok, prev.TypeArgs, nw.TypeArgs, nw.Name, "iterator");
- CheckAgreement_Parameters(nw.tok, prev.Ins, nw.Ins, nw.Name, "iterator", "in-parameter");
- CheckAgreement_Parameters(nw.tok, prev.Outs, nw.Outs, nw.Name, "iterator", "yield-parameter");
- }
-
- BlockStmt newBody;
- if (nw.Body == null) {
- newBody = prev.Body;
- } else if (prev.Body == null) {
- newBody = nw.Body;
- } else {
- newBody = MergeBlockStmt(nw.Body, prev.Body);
- }
-
- var ens = prev.Ensures.ConvertAll(rawCloner.CloneMayBeFreeExpr);
- ens.AddRange(nw.Ensures);
- var yens = prev.YieldEnsures.ConvertAll(rawCloner.CloneMayBeFreeExpr);
- yens.AddRange(nw.YieldEnsures);
-
- return new IteratorDecl(new RefinementToken(nw.tok, moduleUnderConstruction), nw.Name, moduleUnderConstruction,
- nw.SignatureIsOmitted ? prev.TypeArgs.ConvertAll(refinementCloner.CloneTypeParam) : nw.TypeArgs,
- nw.SignatureIsOmitted ? prev.Ins.ConvertAll(refinementCloner.CloneFormal) : nw.Ins,
- nw.SignatureIsOmitted ? prev.Outs.ConvertAll(refinementCloner.CloneFormal) : nw.Outs,
- refinementCloner.CloneSpecFrameExpr(prev.Reads),
- refinementCloner.CloneSpecFrameExpr(prev.Modifies),
- refinementCloner.CloneSpecExpr(prev.Decreases),
- prev.Requires.ConvertAll(refinementCloner.CloneMayBeFreeExpr),
- ens,
- prev.YieldRequires.ConvertAll(refinementCloner.CloneMayBeFreeExpr),
- yens,
- newBody,
- refinementCloner.MergeAttributes(prev.Attributes, nw.Attributes),
- false);
- }
-
- ClassDecl MergeClass(ClassDecl nw, ClassDecl prev) {
- CheckAgreement_TypeParameters(nw.tok, prev.TypeArgs, nw.TypeArgs, nw.Name, "class");
-
- // Create a simple name-to-member dictionary. Ignore any duplicates at this time.
- var declaredNames = new Dictionary<string, int>();
- for (int i = 0; i < nw.Members.Count; i++) {
- var member = nw.Members[i];
- if (!declaredNames.ContainsKey(member.Name)) {
- declaredNames.Add(member.Name, i);
- }
- }
-
- // Merge the declarations of prev into the declarations of m
- foreach (var member in prev.Members) {
- int index;
- if (!declaredNames.TryGetValue(member.Name, out index)) {
- nw.Members.Add(refinementCloner.CloneMember(member));
- } else {
- var nwMember = nw.Members[index];
- if (nwMember is Field) {
- if (member is Field && TypesAreSyntacticallyEqual(((Field)nwMember).Type, ((Field)member).Type)) {
- if (member.IsGhost || !nwMember.IsGhost)
- reporter.Error(nwMember, "a field re-declaration ({0}) must be to ghostify the field", nwMember.Name, nw.Name);
- } else {
- reporter.Error(nwMember, "a field declaration ({0}) in a refining class ({1}) must replace a field in the refinement base", nwMember.Name, nw.Name);
- }
- } else if (nwMember is Function) {
- var f = (Function)nwMember;
- bool isPredicate = f is Predicate;
- bool isCoPredicate = f is CoPredicate;
- string s = isPredicate ? "predicate" : isCoPredicate ? "copredicate" : "function";
- if (!(member is Function) || (isPredicate && !(member is Predicate)) || (isCoPredicate && !(member is CoPredicate))) {
- reporter.Error(nwMember, "a {0} declaration ({1}) can only refine a {0}", s, nwMember.Name);
- } else {
- var prevFunction = (Function)member;
- if (f.Req.Count != 0) {
- reporter.Error(f.Req[0].tok, "a refining {0} is not allowed to add preconditions", s);
- }
- if (f.Reads.Count != 0) {
- reporter.Error(f.Reads[0].E.tok, "a refining {0} is not allowed to extend the reads clause", s);
- }
- if (f.Decreases.Expressions.Count != 0) {
- reporter.Error(f.Decreases.Expressions[0].tok, "decreases clause on refining {0} not supported", s);
- }
-
- if (prevFunction.IsStatic != f.IsStatic) {
- reporter.Error(f, "a function in a refining module cannot be changed from static to non-static or vice versa: {0}", f.Name);
- }
- if (!prevFunction.IsGhost && f.IsGhost) {
- reporter.Error(f, "a function method cannot be changed into a (ghost) function in a refining module: {0}", f.Name);
- } else if (prevFunction.IsGhost && !f.IsGhost && prevFunction.Body != null) {
- reporter.Error(f, "a function can be changed into a function method in a refining module only if the function has not yet been given a body: {0}", f.Name);
- }
- if (f.SignatureIsOmitted) {
- Contract.Assert(f.TypeArgs.Count == 0);
- Contract.Assert(f.Formals.Count == 0);
- } else {
- CheckAgreement_TypeParameters(f.tok, prevFunction.TypeArgs, f.TypeArgs, f.Name, "function");
- CheckAgreement_Parameters(f.tok, prevFunction.Formals, f.Formals, f.Name, "function", "parameter");
- if (!TypesAreSyntacticallyEqual(prevFunction.ResultType, f.ResultType)) {
- reporter.Error(f, "the result type of function '{0}' ({1}) differs from the result type of the corresponding function in the module it refines ({2})", f.Name, f.ResultType, prevFunction.ResultType);
- }
- }
-
- Expression moreBody = null;
- Expression replacementBody = null;
- if (prevFunction.Body == null) {
- replacementBody = f.Body;
- } else if (isPredicate) {
- moreBody = f.Body;
- } else if (f.Body != null) {
- reporter.Error(nwMember, "a refining function is not allowed to extend/change the body");
- }
- nw.Members[index] = CloneFunction(f.tok, prevFunction, f.IsGhost, f.Ens, moreBody, replacementBody, prevFunction.Body == null, f.Attributes);
- }
-
- } else {
- var m = (Method)nwMember;
- if (!(member is Method)) {
- reporter.Error(nwMember, "a method declaration ({0}) can only refine a method", nwMember.Name);
- } else {
- var prevMethod = (Method)member;
- if (m.Req.Count != 0) {
- reporter.Error(m.Req[0].E.tok, "a refining method is not allowed to add preconditions");
- }
- if (m.Mod.Expressions.Count != 0) {
- reporter.Error(m.Mod.Expressions[0].E.tok, "a refining method is not allowed to extend the modifies clause");
- }
- Specification<Expression> decreases;
- if (Contract.Exists(prevMethod.Decreases.Expressions, e => e is WildcardExpr)) {
- decreases = m.Decreases;
- } else {
- if (m.Decreases.Expressions.Count != 0) {
- reporter.Error(m.Decreases.Expressions[0].tok, "decreases clause on refining method not supported, unless the refined method was specified with 'decreases *'");
- }
- decreases = refinementCloner.CloneSpecExpr(prevMethod.Decreases);
- }
- if (prevMethod.IsStatic != m.IsStatic) {
- reporter.Error(m, "a method in a refining module cannot be changed from static to non-static or vice versa: {0}", m.Name);
- }
- if (prevMethod.IsGhost && !m.IsGhost) {
- reporter.Error(m, "a method cannot be changed into a ghost method in a refining module: {0}", m.Name);
- } else if (!prevMethod.IsGhost && m.IsGhost) {
- reporter.Error(m, "a ghost method cannot be changed into a non-ghost method in a refining module: {0}", m.Name);
- }
- if (m.SignatureIsOmitted) {
- Contract.Assert(m.TypeArgs.Count == 0);
- Contract.Assert(m.Ins.Count == 0);
- Contract.Assert(m.Outs.Count == 0);
- } else {
- CheckAgreement_TypeParameters(m.tok, prevMethod.TypeArgs, m.TypeArgs, m.Name, "method");
- CheckAgreement_Parameters(m.tok, prevMethod.Ins, m.Ins, m.Name, "method", "in-parameter");
- CheckAgreement_Parameters(m.tok, prevMethod.Outs, m.Outs, m.Name, "method", "out-parameter");
- }
- currentMethod = m;
- var replacementBody = m.Body;
- if (replacementBody != null) {
- if (prevMethod.Body == null) {
- // cool
- } else {
- replacementBody = MergeBlockStmt(replacementBody, prevMethod.Body);
- }
- }
- nw.Members[index] = CloneMethod(prevMethod, m.Ens, decreases, replacementBody, prevMethod.Body == null, m.Attributes);
- }
- }
- }
- }
-
- return nw;
- }
- void CheckAgreement_TypeParameters(IToken tok, List<TypeParameter> old, List<TypeParameter> nw, string name, string thing, bool checkNames = true) {
- Contract.Requires(tok != null);
- Contract.Requires(old != null);
- Contract.Requires(nw != null);
- Contract.Requires(name != null);
- Contract.Requires(thing != null);
- if (old.Count != nw.Count) {
- reporter.Error(tok, "{0} '{1}' is declared with a different number of type parameters ({2} instead of {3}) than the corresponding {0} in the module it refines", thing, name, nw.Count, old.Count);
- } else {
- for (int i = 0; i < old.Count; i++) {
- var o = old[i];
- var n = nw[i];
- if (o.Name != n.Name && checkNames) { // if checkNames is false, then just treat the parameters positionally.
- reporter.Error(n.tok, "type parameters are not allowed to be renamed from the names given in the {0} in the module being refined (expected '{1}', found '{2}')", thing, o.Name, n.Name);
- } else {
- // This explains what we want to do and why:
- // switch (o.EqualitySupport) {
- // case TypeParameter.EqualitySupportValue.Required:
- // // here, we will insist that the new type-parameter also explicitly requires equality support (because we don't want
- // // to wait for the inference to run on the new module)
- // good = n.EqualitySupport == TypeParameter.EqualitySupportValue.Required;
- // break;
- // case TypeParameter.EqualitySupportValue.InferredRequired:
- // // here, we can allow anything, because even with an Unspecified value, the inference will come up with InferredRequired, like before
- // good = true;
- // break;
- // case TypeParameter.EqualitySupportValue.Unspecified:
- // // inference didn't come up with anything on the previous module, so the only value we'll allow here is Unspecified as well
- // good = n.EqualitySupport == TypeParameter.EqualitySupportValue.Unspecified;
- // break;
- // }
- // Here's how we actually compute it:
- if (o.EqualitySupport != TypeParameter.EqualitySupportValue.InferredRequired && o.EqualitySupport != n.EqualitySupport) {
- reporter.Error(n.tok, "type parameter '{0}' is not allowed to change the requirement of supporting equality", n.Name);
- }
- }
- }
- }
- }
-
- void CheckAgreement_Parameters(IToken tok, List<Formal> old, List<Formal> nw, string name, string thing, string parameterKind) {
- Contract.Requires(tok != null);
- Contract.Requires(old != null);
- Contract.Requires(nw != null);
- Contract.Requires(name != null);
- Contract.Requires(thing != null);
- Contract.Requires(parameterKind != null);
- if (old.Count != nw.Count) {
- reporter.Error(tok, "{0} '{1}' is declared with a different number of {2} ({3} instead of {4}) than the corresponding {0} in the module it refines", thing, name, parameterKind, nw.Count, old.Count);
- } else {
- for (int i = 0; i < old.Count; i++) {
- var o = old[i];
- var n = nw[i];
- if (o.Name != n.Name) {
- reporter.Error(n.tok, "there is a difference in name of {0} {1} ('{2}' versus '{3}') of {4} {5} compared to corresponding {4} in the module it refines", parameterKind, i, n.Name, o.Name, thing, name);
- } else if (!o.IsGhost && n.IsGhost) {
- reporter.Error(n.tok, "{0} '{1}' of {2} {3} cannot be changed, compared to the corresponding {2} in the module it refines, from non-ghost to ghost", parameterKind, n.Name, thing, name);
- } else if (o.IsGhost && !n.IsGhost) {
- reporter.Error(n.tok, "{0} '{1}' of {2} {3} cannot be changed, compared to the corresponding {2} in the module it refines, from ghost to non-ghost", parameterKind, n.Name, thing, name);
- } else if (!TypesAreSyntacticallyEqual(o.Type, n.Type)) {
- reporter.Error(n.tok, "the type of {0} '{1}' is different from the type of the same {0} in the corresponding {2} in the module it refines ('{3}' instead of '{4}')", parameterKind, n.Name, thing, n.Type, o.Type);
- }
- }
- }
- }
-
- bool TypesAreSyntacticallyEqual(Type t, Type u) {
- Contract.Requires(t != null);
- Contract.Requires(u != null);
- return t.ToString() == u.ToString();
- }
-
- BlockStmt MergeBlockStmt(BlockStmt skeleton, BlockStmt oldStmt) {
- Contract.Requires(skeleton != null);
- Contract.Requires(oldStmt != null);
-
- var body = new List<Statement>();
- int i = 0, j = 0;
- while (i < skeleton.Body.Count) {
- var cur = skeleton.Body[i];
- if (j == oldStmt.Body.Count) {
- if (!(cur is SkeletonStatement)) {
- MergeAddStatement(cur, body);
- } else if (((SkeletonStatement)cur).S == null) {
- // the "..." matches the empty statement sequence
- } else {
- reporter.Error(cur.Tok, "skeleton statement does not match old statement");
- }
- i++;
- } else {
- var oldS = oldStmt.Body[j];
- /* See how the two statements match up.
- * cur oldS result
- * ------ ------ ------
- * assert ...; assume E; assert E;
- * assert ...; assert E; assert E;
- * assert E; assert E;
- *
- * assume ...; assume E; assume E;
- *
- * var x := E; var x; var x := E;
- * var x := E; var x := *; var x := E;
- * var x := E1; var x :| P; var x := E1; assert P;
- * var VarProduction; var VarProduction;
- *
- * x := E; x := *; x := E;
- * x := E; x :| P; x := E; assert P;
- *
- * if ... Then else Else if (G) Then' else Else' if (G) Merge(Then,Then') else Merge(Else,Else')
- * if (G) Then else Else if (*) Then' else Else' if (G) Merge(Then,Then') else Merge(Else,Else')
- *
- * while ... LoopSpec ... while (G) LoopSpec' Body while (G) Merge(LoopSpec,LoopSpec') Body
- * while ... LoopSpec Body while (G) LoopSpec' Body' while (G) Merge(LoopSpec,LoopSpec') Merge(Body,Body')
- * while (G) LoopSpec ... while (*) LoopSpec' Body while (G) Merge(LoopSpec,LoopSpec') Body
- * while (G) LoopSpec Body while (*) LoopSpec' Body' while (G) Merge(LoopSpec,LoopSpec') Merge(Body,Body')
- *
- * ... where x = e; S StmtThatDoesNotMatchS; S' StatementThatDoesNotMatchS[e/x]; Merge( ... where x = e; S , S')
- * ... where x = e; S StmtThatMatchesS; S' StmtThatMatchesS; S'
- *
- * Note, LoopSpec must contain only invariant declarations (as the parser ensures for the first three cases).
- * Note, there is an implicit "...;" at the end of every block in a skeleton.
- */
- if (cur is SkeletonStatement) {
- var S = ((SkeletonStatement)cur).S;
- var c = (SkeletonStatement)cur;
- if (S == null) {
- var nxt = i + 1 == skeleton.Body.Count ? null : skeleton.Body[i + 1];
- if (nxt != null && nxt is SkeletonStatement && ((SkeletonStatement)nxt).S == null) {
- // "...; ...;" is the same as just "...;", so skip this one
- } else {
- SubstitutionCloner subber = null;
- if (c.NameReplacements != null) {
- var subExprs = new Dictionary<string, Expression>();
- Contract.Assert(c.NameReplacements.Count == c.ExprReplacements.Count);
- for (int k = 0; k < c.NameReplacements.Count; k++) {
- if (subExprs.ContainsKey(c.NameReplacements[k].val)) {
- reporter.Error(c.NameReplacements[k], "replacement definition must contain at most one definition for a given label");
- } else subExprs.Add(c.NameReplacements[k].val, c.ExprReplacements[k]);
- }
- subber = new SubstitutionCloner(subExprs, rawCloner);
- }
- // skip up until the next thing that matches "nxt"
- while (nxt == null || !PotentialMatch(nxt, oldS)) {
- // loop invariant: oldS == oldStmt.Body[j]
- var s = refinementCloner.CloneStmt(oldS);
- if (subber != null)
- s = subber.CloneStmt(s);
- body.Add(s);
- j++;
- if (j == oldStmt.Body.Count) { break; }
- oldS = oldStmt.Body[j];
- }
- if (subber != null && subber.SubstitutionsMade.Count < subber.Exprs.Count) {
- foreach (var s in subber.SubstitutionsMade)
- subber.Exprs.Remove(s);
- reporter.Error(c.Tok, "could not find labeled expression(s): " + Util.Comma(", ", subber.Exprs.Keys, x => x));
- }
- }
- i++;
-
- } else if (S is AssertStmt) {
- var skel = (AssertStmt)S;
- Contract.Assert(((SkeletonStatement)cur).ConditionOmitted);
- var oldAssume = oldS as PredicateStmt;
- if (oldAssume == null) {
- reporter.Error(cur.Tok, "assert template does not match inherited statement");
- i++;
- } else {
- // Clone the expression, but among the new assert's attributes, indicate
- // that this assertion is supposed to be translated into a check. That is,
- // it is not allowed to be just assumed in the translation, despite the fact
- // that the condition is inherited.
- var e = refinementCloner.CloneExpr(oldAssume.Expr);
- var attrs = refinementCloner.MergeAttributes(oldAssume.Attributes, skel.Attributes);
- body.Add(new AssertStmt(new Translator.ForceCheckToken(skel.Tok), e, new Attributes("prependAssertToken", new List<Attributes.Argument>(), attrs)));
- i++; j++;
- }
-
- } else if (S is AssumeStmt) {
- var skel = (AssumeStmt)S;
- Contract.Assert(((SkeletonStatement)cur).ConditionOmitted);
- var oldAssume = oldS as AssumeStmt;
- if (oldAssume == null) {
- reporter.Error(cur.Tok, "assume template does not match inherited statement");
- i++;
- } else {
- var e = refinementCloner.CloneExpr(oldAssume.Expr);
- var attrs = refinementCloner.MergeAttributes(oldAssume.Attributes, skel.Attributes);
- body.Add(new AssumeStmt(skel.Tok, e, attrs));
- i++; j++;
- }
-
- } else if (S is IfStmt) {
- var skel = (IfStmt)S;
- Contract.Assert(((SkeletonStatement)cur).ConditionOmitted);
- var oldIf = oldS as IfStmt;
- if (oldIf == null) {
- reporter.Error(cur.Tok, "if-statement template does not match inherited statement");
- i++;
- } else {
- var resultingThen = MergeBlockStmt(skel.Thn, oldIf.Thn);
- var resultingElse = MergeElse(skel.Els, oldIf.Els);
- var r = new IfStmt(skel.Tok, refinementCloner.CloneExpr(oldIf.Guard), resultingThen, resultingElse);
- body.Add(r);
- i++; j++;
- }
-
- } else if (S is WhileStmt) {
- var skel = (WhileStmt)S;
- var oldWhile = oldS as WhileStmt;
- if (oldWhile == null) {
- reporter.Error(cur.Tok, "while-statement template does not match inherited statement");
- i++;
- } else {
- Expression guard;
- if (((SkeletonStatement)cur).ConditionOmitted) {
- guard = refinementCloner.CloneExpr(oldWhile.Guard);
- } else {
- if (oldWhile.Guard != null) {
- reporter.Error(skel.Guard.tok, "a skeleton while statement with a guard can only replace a while statement with a non-deterministic guard");
- }
- guard = skel.Guard;
- }
- // Note, if the loop body is omitted in the skeleton, the parser will have set the loop body to an empty block,
- // which has the same merging behavior.
- var r = MergeWhileStmt(skel, oldWhile, guard);
- body.Add(r);
- i++; j++;
- }
-
- } else {
- Contract.Assume(false); // unexpected skeleton statement
- }
-
- } else if (cur is AssertStmt) {
- MergeAddStatement(cur, body);
- i++;
-
- } else if (cur is VarDeclStmt) {
- var cNew = (VarDeclStmt)cur;
- bool doMerge = false;
- Expression addedAssert = null;
- if (oldS is VarDeclStmt) {
- var cOld = (VarDeclStmt)oldS;
- if (VarDeclAgree(cOld.Lhss, cNew.Lhss)) {
- var update = cNew.Update as UpdateStmt;
- if (update != null && update.Rhss.TrueForAll(rhs => !rhs.CanAffectPreviouslyKnownExpressions)) {
- // Note, we allow switching between ghost and non-ghost, since that seems unproblematic.
- if (cOld.Update == null) {
- doMerge = true;
- } else if (cOld.Update is AssignSuchThatStmt) {
- doMerge = true;
- addedAssert = refinementCloner.CloneExpr(((AssignSuchThatStmt)cOld.Update).Expr);
- } else {
- var updateOld = (UpdateStmt)cOld.Update; // if cast fails, there are more ConcreteUpdateStatement subclasses than expected
- doMerge = true;
- foreach (var rhs in updateOld.Rhss) {
- if (!(rhs is HavocRhs))
- doMerge = false;
- }
- }
- }
- }
- }
- if (doMerge) {
- // Go ahead with the merge:
- body.Add(cNew);
- i++; j++;
- if (addedAssert != null) {
- body.Add(new AssertStmt(new Translator.ForceCheckToken(addedAssert.tok), addedAssert, null));
- }
- } else {
- MergeAddStatement(cur, body);
- i++;
- }
-
- } else if (cur is AssignStmt) {
- var cNew = (AssignStmt)cur;
- var cOld = oldS as AssignStmt;
- if (cOld == null && oldS is UpdateStmt) {
- var us = (UpdateStmt)oldS;
- if (us.ResolvedStatements.Count == 1) {
- cOld = us.ResolvedStatements[0] as AssignStmt;
- }
- }
- bool doMerge = false;
- if (cOld != null && cNew.Lhs.Resolved is IdentifierExpr && cOld.Lhs.Resolved is IdentifierExpr) {
- if (((IdentifierExpr)cNew.Lhs.Resolved).Name == ((IdentifierExpr)cOld.Lhs.Resolved).Name) {
- if (!(cNew.Rhs is TypeRhs) && cOld.Rhs is HavocRhs) {
- doMerge = true;
- }
- }
- }
- if (doMerge) {
- // Go ahead with the merge:
- body.Add(cNew);
- i++; j++;
- } else {
- MergeAddStatement(cur, body);
- i++;
- }
-
- } else if (cur is UpdateStmt) {
- var nw = (UpdateStmt)cur;
- List<Statement> stmtGenerated = new List<Statement>();
- bool doMerge = false;
- if (oldS is UpdateStmt) {
- var s = (UpdateStmt)oldS;
- if (LeftHandSidesAgree(s.Lhss, nw.Lhss)) {
- doMerge = true;
- stmtGenerated.Add(nw);
- foreach (var rhs in s.Rhss) {
- if (!(rhs is HavocRhs))
- doMerge = false;
- }
- }
- } else if (oldS is AssignSuchThatStmt) {
- var s = (AssignSuchThatStmt)oldS;
- if (LeftHandSidesAgree(s.Lhss, nw.Lhss)) {
- doMerge = true;
- stmtGenerated.Add(nw);
- var addedAssert = refinementCloner.CloneExpr(s.Expr);
- stmtGenerated.Add(new AssertStmt(new Translator.ForceCheckToken(addedAssert.tok), addedAssert, null));
- }
- }
- if (doMerge) {
- // Go ahead with the merge:
- Contract.Assert(cce.NonNullElements(stmtGenerated));
- body.AddRange(stmtGenerated);
- i++; j++;
- } else {
- MergeAddStatement(cur, body);
- i++;
- }
- } else if (cur is IfStmt) {
- var cNew = (IfStmt)cur;
- var cOld = oldS as IfStmt;
- if (cOld != null && cOld.Guard == null) {
- var r = new IfStmt(cNew.Tok, cNew.Guard, MergeBlockStmt(cNew.Thn, cOld.Thn), MergeElse(cNew.Els, cOld.Els));
- body.Add(r);
- i++; j++;
- } else {
- MergeAddStatement(cur, body);
- i++;
- }
-
- } else if (cur is WhileStmt) {
- var cNew = (WhileStmt)cur;
- var cOld = oldS as WhileStmt;
- if (cOld != null && cOld.Guard == null) {
- var r = MergeWhileStmt(cNew, cOld, cNew.Guard);
- body.Add(r);
- i++; j++;
- } else {
- MergeAddStatement(cur, body);
- i++;
- }
-
- } else if (cur is BlockStmt) {
- var cNew = (BlockStmt)cur;
- var cOld = oldS as BlockStmt;
- if (cOld != null) {
- var r = MergeBlockStmt(cNew, cOld);
- body.Add(r);
- i++; j++;
- } else {
- MergeAddStatement(cur, body);
- i++;
- }
- } else {
- MergeAddStatement(cur, body);
- i++;
- }
- }
- }
- // implement the implicit "...;" at the end of each block statement skeleton
- for (; j < oldStmt.Body.Count; j++) {
- body.Add(refinementCloner.CloneStmt(oldStmt.Body[j]));
- }
- return new BlockStmt(skeleton.Tok, body);
- }
-
- private bool LeftHandSidesAgree(List<Expression> old, List<Expression> nw) {
- if (old.Count != nw.Count)
- return false;
- for (int i = 0; i < old.Count; i++) {
- var a = old[i].Resolved as IdentifierExpr;
- var b = nw[i] as IdentifierSequence;
- if (a != null && b != null)
- if (b.Tokens.Count == 1 && b.Arguments == null)
- if (a.Name == b.Tokens[0].val)
- continue;
- return false;
- }
- return true;
- }
- private bool VarDeclAgree(List<VarDecl> old, List<VarDecl> nw) {
- if (old.Count != nw.Count)
- return false;
- for (int i = 0; i < old.Count; i++) {
- if (old[i].Name != nw[i].Name)
- return false;
- }
- return true;
- }
-
- bool PotentialMatch(Statement nxt, Statement other) {
- Contract.Requires(nxt != null);
- Contract.Requires(!(nxt is SkeletonStatement) || ((SkeletonStatement)nxt).S != null); // nxt is not "...;"
- Contract.Requires(other != null);
-
- if (nxt.Labels != null) {
- for (var olbl = other.Labels; olbl != null; olbl = olbl.Next) {
- var odata = olbl.Data;
- for (var l = nxt.Labels; l != null; l = l.Next) {
- if (odata.Name == l.Data.Name) {
- return true;
- }
- }
- }
- return false; // labels of 'nxt' don't match any label of 'other'
- } else if (nxt is SkeletonStatement) {
- var S = ((SkeletonStatement)nxt).S;
- if (S is AssertStmt) {
- return other is PredicateStmt;
- } else if (S is AssumeStmt) {
- return other is AssumeStmt;
- } else if (S is IfStmt) {
- return other is IfStmt;
- } else if (S is WhileStmt) {
- return other is WhileStmt;
- } else {
- Contract.Assume(false); // unexpected skeleton
- }
-
- } else if (nxt is IfStmt) {
- var oth = other as IfStmt;
- return oth != null && oth.Guard == null;
- } else if (nxt is WhileStmt) {
- var oth = other as WhileStmt;
- return oth != null && oth.Guard == null;
- } else if (nxt is VarDeclStmt) {
- var oth = other as VarDeclStmt;
- return oth != null && VarDeclAgree(((VarDeclStmt)nxt).Lhss, oth.Lhss);
- } else if (nxt is BlockStmt) {
- var b = (BlockStmt)nxt;
- if (b.Labels != null) {
- var oth = other as BlockStmt;
- if (oth != null && oth.Labels != null) {
- return b.Labels.Data.Name == oth.Labels.Data.Name; // both have the same label
- }
- } else if (other is BlockStmt && ((BlockStmt)other).Labels == null) {
- return true; // both are unlabeled
- }
- } else if (nxt is UpdateStmt) {
- var up = (UpdateStmt)nxt;
- if (other is AssignSuchThatStmt) {
- var oth = other as AssignSuchThatStmt;
- return oth != null && LeftHandSidesAgree(oth.Lhss, up.Lhss);
- }
- }
-
- // not a potential match
- return false;
- }
-
- WhileStmt MergeWhileStmt(WhileStmt cNew, WhileStmt cOld, Expression guard) {
- Contract.Requires(cNew != null);
- Contract.Requires(cOld != null);
-
- // Note, the parser produces errors if there are any decreases or modifies clauses (and it creates
- // the Specification structures with a null list).
- Contract.Assume(cNew.Mod.Expressions == null);
-
- // If the previous loop was not specified with "decreases *", then the new loop is not allowed to provide any "decreases" clause.
- // Any "decreases *" clause is not inherited, so if the previous loop was specified with "decreases *", then the new loop needs
- // to either redeclare "decreases *", provided a termination-checking "decreases" clause, or give no "decreases" clause and thus
- // get a default "decreases" loop.
- Specification<Expression> decr;
- if (Contract.Exists(cOld.Decreases.Expressions, e => e is WildcardExpr)) {
- decr = cNew.Decreases; // take the new decreases clauses, whatever they may be (including nothing at all)
- } else {
- if (cNew.Decreases.Expressions.Count != 0) {
- reporter.Error(cNew.Decreases.Expressions[0].tok, "a refining loop can provide a decreases clause only if the loop being refined was declared with 'decreases *'");
- }
- decr = refinementCloner.CloneSpecExpr(cOld.Decreases);
- }
-
- var invs = cOld.Invariants.ConvertAll(refinementCloner.CloneMayBeFreeExpr);
- invs.AddRange(cNew.Invariants);
- var r = new RefinedWhileStmt(cNew.Tok, guard, invs, decr, refinementCloner.CloneSpecFrameExpr(cOld.Mod), MergeBlockStmt(cNew.Body, cOld.Body));
- return r;
- }
-
- Statement MergeElse(Statement skeleton, Statement oldStmt) {
- Contract.Requires(skeleton == null || skeleton is BlockStmt || skeleton is IfStmt || skeleton is SkeletonStatement);
- Contract.Requires(oldStmt == null || oldStmt is BlockStmt || oldStmt is IfStmt || oldStmt is SkeletonStatement);
-
- if (skeleton == null) {
- return refinementCloner.CloneStmt(oldStmt);
- } else if (skeleton is IfStmt || skeleton is SkeletonStatement) {
- // wrap a block statement around the if statement
- skeleton = new BlockStmt(skeleton.Tok, new List<Statement>() { skeleton });
- }
-
- if (oldStmt == null) {
- // make it into an empty block statement
- oldStmt = new BlockStmt(skeleton.Tok, new List<Statement>());
- } else if (oldStmt is IfStmt || oldStmt is SkeletonStatement) {
- // wrap a block statement around the if statement
- oldStmt = new BlockStmt(oldStmt.Tok, new List<Statement>() { oldStmt });
- }
-
- Contract.Assert(skeleton is BlockStmt && oldStmt is BlockStmt);
- return MergeBlockStmt((BlockStmt)skeleton, (BlockStmt)oldStmt);
- }
-
- /// <summary>
- /// Add "s" to "stmtList", but complain if "s" contains further occurrences of "...", if "s" assigns to a
- /// variable that was not declared in the refining module, or if "s" has some control flow that jumps to a
- /// place outside "s".
- /// </summary>
- void MergeAddStatement(Statement s, List<Statement> stmtList) {
- Contract.Requires(s != null);
- Contract.Requires(stmtList != null);
- var prevErrorCount = reporter.ErrorCount;
- CheckIsOkayNewStatement(s, new Stack<string>(), 0);
- if (reporter.ErrorCount == prevErrorCount) {
- stmtList.Add(s);
- }
- }
-
- /// <summary>
- /// See comment on MergeAddStatement.
- /// </summary>
- void CheckIsOkayNewStatement(Statement s, Stack<string> labels, int loopLevels) {
- Contract.Requires(s != null);
- Contract.Requires(labels != null);
- Contract.Requires(0 <= loopLevels);
-
- for (LList<Label> n = s.Labels; n != null; n = n.Next) {
- labels.Push(n.Data.Name);
- }
- if (s is SkeletonStatement) {
- reporter.Error(s, "skeleton statement may not be used here; it does not have a matching statement in what is being replaced");
- } else if (s is ProduceStmt) {
- reporter.Error(s, (s is YieldStmt ? "yield" : "return") + " statements are not allowed in skeletons");
- } else if (s is BreakStmt) {
- var b = (BreakStmt)s;
- if (b.TargetLabel != null ? !labels.Contains(b.TargetLabel) : loopLevels < b.BreakCount) {
- reporter.Error(s, "break statement in skeleton is not allowed to break outside the skeleton fragment");
- }
- } else if (s is AssignStmt) {
- // TODO: To be a refinement automatically (that is, without any further verification), only variables and fields defined
- // in this module are allowed. This needs to be checked. If the LHS refers to an l-value that was not declared within
- // this module, then either an error should be reported or the Translator needs to know to translate new proof obligations.
- var a = (AssignStmt)s;
- reporter.Error(a.Tok, "cannot have assignment statement");
- } else if (s is ConcreteUpdateStatement) {
- postTasks.Enqueue(() =>
- {
- CheckIsOkayUpdateStmt((ConcreteUpdateStatement)s, moduleUnderConstruction, reporter);
- });
- } else if (s is CallStmt) {
- reporter.Error(s.Tok, "cannot have call statement");
- } else if (s is ParallelStmt) {
- if (((ParallelStmt)s).Kind == ParallelStmt.ParBodyKind.Assign) // allow Proof and Call (as neither touch any existing state)
- reporter.Error(s.Tok, "cannot have parallel statement");
- } else {
- if (s is WhileStmt || s is AlternativeLoopStmt) {
- loopLevels++;
- }
- foreach (var ss in s.SubStatements) {
- CheckIsOkayNewStatement(ss, labels, loopLevels);
- }
- }
-
- for (LList<Label> n = s.Labels; n != null; n = n.Next) {
- labels.Pop();
- }
- }
-
- // Checks that statement stmt, defined in the constructed module m, is a refinement of skip in the parent module
- private bool CheckIsOkayUpdateStmt(ConcreteUpdateStatement stmt, ModuleDefinition m, ResolutionErrorReporter reporter) {
- foreach (var lhs in stmt.Lhss) {
- var l = lhs.Resolved;
- if (l is IdentifierExpr) {
- var ident = (IdentifierExpr)l;
- Contract.Assert(ident.Var is VarDecl || ident.Var is Formal); // LHS identifier expressions must be locals or out parameters (ie. formals)
- if ((ident.Var is VarDecl && RefinementToken.IsInherited(((VarDecl)ident.Var).Tok, m)) || ident.Var is Formal) {
- // for some reason, formals are not considered to be inherited.
- reporter.Error(l.tok, "cannot assign to variable defined previously");
- return false;
- }
- } else if (l is FieldSelectExpr) {
- if (RefinementToken.IsInherited(((FieldSelectExpr)l).Field.tok, m)) {
- return false;
- }
- } else {
- return false;
- }
- }
- if (stmt is UpdateStmt) {
- var s = (UpdateStmt)stmt;
- foreach (var rhs in s.Rhss) {
- if (s.Rhss[0].CanAffectPreviouslyKnownExpressions) {
- return false;
- }
- }
- }
- return true;
- }
- // ---------------------- additional methods -----------------------------------------------------------------------------
-
- public static bool ContainsChange(Expression expr, ModuleDefinition m) {
- Contract.Requires(expr != null);
- Contract.Requires(m != null);
-
- if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- if (e.Function.EnclosingClass.Module == m) {
- var p = e.Function as Predicate;
- if (p != null && p.BodyOrigin == Predicate.BodyOriginKind.Extension) {
- return true;
- }
- }
- }
-
- foreach (var ee in expr.SubExpressions) {
- if (ContainsChange(ee, m)) {
- return true;
- }
- }
- return false;
- }
- }
-
- class RefinementCloner : Cloner {
- ModuleDefinition moduleUnderConstruction;
- public RefinementCloner(ModuleDefinition m) {
- moduleUnderConstruction = m;
- }
- public override IToken Tok(IToken tok) {
- return new RefinementToken(tok, moduleUnderConstruction);
- }
- public virtual Attributes MergeAttributes(Attributes prevAttrs, Attributes moreAttrs) {
- if (moreAttrs == null) {
- return CloneAttributes(prevAttrs);
- } else {
- return new Attributes(moreAttrs.Name, moreAttrs.Args.ConvertAll(CloneAttrArg), MergeAttributes(prevAttrs, moreAttrs.Prev));
- }
- }
- }
- class SubstitutionCloner : Cloner {
- public Dictionary<string, Expression> Exprs;
- public SortedSet<string> SubstitutionsMade;
- Cloner c;
- public SubstitutionCloner(Dictionary<string, Expression> subs, Cloner c) {
- Exprs = subs;
- SubstitutionsMade = new SortedSet<string>();
- this.c = c;
- }
- public override Expression CloneExpr(Expression expr) {
- if (expr is NamedExpr) {
- NamedExpr n = (NamedExpr)expr;
- Expression E;
- if (Exprs.TryGetValue(n.Name, out E)) {
- SubstitutionsMade.Add(n.Name);
- return new NamedExpr(n.tok, n.Name, E, c.CloneExpr(n.Body), E.tok);
- }
- }
- return base.CloneExpr(expr); // in all other cases, just do what the base class would.
- // note that when we get a named expression that is not in
- // our substitution list, then we call the base class, which
- // recurses on the body of the named expression.
- }
- }
-} \ No newline at end of file
diff --git a/Source/Dafny/Resolver.cs b/Source/Dafny/Resolver.cs
deleted file mode 100644
index a876864e..00000000
--- a/Source/Dafny/Resolver.cs
+++ /dev/null
@@ -1,6706 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using System.Diagnostics.Contracts;
-using Microsoft.Boogie;
-
-namespace Microsoft.Dafny
-{
- public class ResolutionErrorReporter
- {
- public int ErrorCount = 0;
-
- /// <summary>
- /// This method is virtual, because it is overridden in the VSX plug-in for Dafny.
- /// </summary>
- public virtual void Error(IToken tok, string msg, params object[] args) {
- Contract.Requires(tok != null);
- Contract.Requires(msg != null);
- ConsoleColor col = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("{0}({1},{2}): Error: {3}",
- tok.filename, tok.line, tok.col - 1,
- string.Format(msg, args));
- Console.ForegroundColor = col;
- ErrorCount++;
- }
- public void Error(Declaration d, string msg, params object[] args) {
- Contract.Requires(d != null);
- Contract.Requires(msg != null);
- Error(d.tok, msg, args);
- }
- public void Error(Statement s, string msg, params object[] args) {
- Contract.Requires(s != null);
- Contract.Requires(msg != null);
- Error(s.Tok, msg, args);
- }
- public void Error(NonglobalVariable v, string msg, params object[] args) {
- Contract.Requires(v != null);
- Contract.Requires(msg != null);
- Error(v.tok, msg, args);
- }
- public void Error(Expression e, string msg, params object[] args) {
- Contract.Requires(e != null);
- Contract.Requires(msg != null);
- Error(e.tok, msg, args);
- }
- public void Warning(IToken tok, string msg, params object[] args) {
- Contract.Requires(tok != null);
- Contract.Requires(msg != null);
- ConsoleColor col = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine("{0}({1},{2}): Warning: {3}",
- tok.filename, tok.line, tok.col - 1,
- string.Format(msg, args));
- Console.ForegroundColor = col;
- }
- }
-
- public class Resolver : ResolutionErrorReporter
- {
- readonly BuiltIns builtIns;
-
- //Dictionary<string/*!*/,TopLevelDecl/*!*/>/*!*/ classes; // can map to AmbiguousTopLevelDecl
- //Dictionary<string, ModuleDecl> importedNames; // the imported modules, as a map.
- ModuleSignature moduleInfo = null;
-
- class AmbiguousTopLevelDecl : TopLevelDecl // only used with "classes"
- {
- readonly TopLevelDecl A;
- readonly TopLevelDecl B;
- public AmbiguousTopLevelDecl(ModuleDefinition m, TopLevelDecl a, TopLevelDecl b)
- : base(a.tok, a.Name + "/" + b.Name, m, new List<TypeParameter>(), null) {
- A = a;
- B = b;
- }
- public string ModuleNames() {
- string nm;
- if (A is AmbiguousTopLevelDecl) {
- nm = ((AmbiguousTopLevelDecl)A).ModuleNames();
- } else {
- nm = A.Module.Name;
- }
- if (B is AmbiguousTopLevelDecl) {
- nm += ", " + ((AmbiguousTopLevelDecl)B).ModuleNames();
- } else {
- nm += ", " + B.Module.Name;
- }
- return nm;
- }
- }
-
- class AmbiguousMemberDecl : MemberDecl // only used with "classes"
- {
- readonly MemberDecl A;
- readonly MemberDecl B;
- public AmbiguousMemberDecl(ModuleDefinition m, MemberDecl a, MemberDecl b)
- : base(a.tok, a.Name + "/" + b.Name, a.IsStatic, a.IsGhost, null) {
- A = a;
- B = b;
- }
- public string ModuleNames() {
- string nm;
- if (A is AmbiguousMemberDecl) {
- nm = ((AmbiguousMemberDecl)A).ModuleNames();
- } else {
- nm = A.EnclosingClass.Module.Name;
- }
- if (B is AmbiguousMemberDecl) {
- nm += ", " + ((AmbiguousMemberDecl)B).ModuleNames();
- } else {
- nm += ", " + B.EnclosingClass.Module.Name;
- }
- return nm;
- }
- }
- //Dictionary<string/*!*/, Tuple<DatatypeCtor, bool>> allDatatypeCtors;
-
- readonly Dictionary<ClassDecl/*!*/, Dictionary<string/*!*/, MemberDecl/*!*/>/*!*/>/*!*/ classMembers = new Dictionary<ClassDecl/*!*/, Dictionary<string/*!*/, MemberDecl/*!*/>/*!*/>();
- readonly Dictionary<DatatypeDecl/*!*/, Dictionary<string/*!*/, MemberDecl/*!*/>/*!*/>/*!*/ datatypeMembers = new Dictionary<DatatypeDecl/*!*/, Dictionary<string/*!*/, MemberDecl/*!*/>/*!*/>();
- readonly Dictionary<DatatypeDecl/*!*/, Dictionary<string/*!*/, DatatypeCtor/*!*/>/*!*/>/*!*/ datatypeCtors = new Dictionary<DatatypeDecl/*!*/, Dictionary<string/*!*/, DatatypeCtor/*!*/>/*!*/>();
- readonly Graph<ModuleDecl/*!*/>/*!*/ dependencies = new Graph<ModuleDecl/*!*/>();
- private ModuleSignature systemNameInfo = null;
- private bool useCompileSignatures = false;
-
- public Resolver(Program prog) {
- Contract.Requires(prog != null);
- builtIns = prog.BuiltIns;
- }
-
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(builtIns != null);
- Contract.Invariant(cce.NonNullElements(dependencies));
- Contract.Invariant(cce.NonNullDictionaryAndValues(classMembers) && Contract.ForAll(classMembers.Values, v => cce.NonNullDictionaryAndValues(v)));
- Contract.Invariant(cce.NonNullDictionaryAndValues(datatypeCtors) && Contract.ForAll(datatypeCtors.Values, v => cce.NonNullDictionaryAndValues(v)));
- }
-
- public void ResolveProgram(Program prog) {
- Contract.Requires(prog != null);
- var bindings = new ModuleBindings(null);
- var b = BindModuleNames(prog.DefaultModuleDef, bindings);
- bindings.BindName("_module", prog.DefaultModule, b);
- if (ErrorCount > 0) { return; } // if there were errors, then the implict ModuleBindings data structure invariant
- // is violated, so Processing dependencies will not succeed.
- ProcessDependencies(prog.DefaultModule, b, dependencies);
- // check for cycles in the import graph
- List<ModuleDecl> cycle = dependencies.TryFindCycle();
- if (cycle != null) {
- var cy = Util.Comma(" -> ", cycle, m => m.Name);
- Error(cycle[0], "module definition contains a cycle (note: parent modules implicitly depend on submodules): {0}", cy);
- }
- if (ErrorCount > 0) { return; } // give up on trying to resolve anything else
-
- // fill in module heights
- List<ModuleDecl> sortedDecls = dependencies.TopologicallySortedComponents();
- int h = 0;
- foreach (ModuleDecl m in sortedDecls) {
- m.Height = h;
- if (m is LiteralModuleDecl) {
- var mdef = ((LiteralModuleDecl)m).ModuleDef;
- mdef.Height = h;
- prog.Modules.Add(mdef);
- }
- h++;
- }
-
- var refinementTransformer = new RefinementTransformer(this, prog);
-
- IRewriter rewriter = new AutoContractsRewriter();
- systemNameInfo = RegisterTopLevelDecls(prog.BuiltIns.SystemModule, false);
- foreach (var decl in sortedDecls) {
- if (decl is LiteralModuleDecl) {
- // The declaration is a literal module, so it has members and such that we need
- // to resolve. First we do refinement transformation. Then we construct the signature
- // of the module. This is the public, externally visible signature. Then we add in
- // everything that the system defines, as well as any "import" (i.e. "opened" modules)
- // directives (currently not supported, but this is where we would do it.) This signature,
- // which is only used while resolving the members of the module is stored in the (basically)
- // global variable moduleInfo. Then the signatures of the module members are resolved, followed
- // by the bodies.
- var literalDecl = (LiteralModuleDecl)decl;
- var m = (literalDecl).ModuleDef;
-
- var errorCount = ErrorCount;
- rewriter.PreResolve(m);
- ModuleSignature refinedSig = null;
- if (m.RefinementBaseRoot != null) {
- if (ResolvePath(m.RefinementBaseRoot, m.RefinementBaseName, out refinedSig)) {
- if (refinedSig.ModuleDef != null) {
- m.RefinementBase = refinedSig.ModuleDef;
- refinementTransformer.PreResolve(m);
- } else {
- Error(m.RefinementBaseName[0], "module ({0}) named as refinement base is not a literal module or simple reference to a literal module", Util.Comma(".", m.RefinementBaseName, x => x.val));
- }
- } else {
- Error(m.RefinementBaseName[0], "module ({0}) named as refinement base does not exist", Util.Comma(".", m.RefinementBaseName, x => x.val));
- }
- }
- literalDecl.Signature = RegisterTopLevelDecls(m, true);
- literalDecl.Signature.Refines = refinedSig;
- var sig = literalDecl.Signature;
- // set up environment
- var preResolveErrorCount = ErrorCount;
- useCompileSignatures = false;
- ResolveModuleDefinition(m, sig);
- if (ErrorCount == preResolveErrorCount) {
- refinementTransformer.PostResolve(m);
- // give rewriter a chance to do processing
- rewriter.PostResolve(m);
- }
- if (ErrorCount == errorCount && !m.IsGhost) {
- // compilation should only proceed if everything is good, including the signature (which preResolveErrorCount does not include);
- var nw = (new Cloner()).CloneModuleDefinition(m, m.CompileName + "_Compile");
- var compileSig = RegisterTopLevelDecls(nw, true);
- compileSig.Refines = refinedSig;
- sig.CompileSignature = compileSig;
- useCompileSignatures = true;
- ResolveModuleDefinition(nw, compileSig);
- prog.CompileModules.Add(nw);
- }
- } else if (decl is AliasModuleDecl) {
- var alias = (AliasModuleDecl)decl;
- // resolve the path
- ModuleSignature p;
- if (ResolvePath(alias.Root, alias.Path, out p)) {
- alias.Signature = p;
- } else {
- alias.Signature = new ModuleSignature(); // there was an error, give it a valid but empty signature
- }
- } else if (decl is AbstractModuleDecl) {
- var abs = (AbstractModuleDecl)decl;
- ModuleSignature p;
- if (ResolvePath(abs.Root, abs.Path, out p)) {
- abs.Signature = MakeAbstractSignature(p, abs.FullCompileName, abs.Height, prog.Modules);
- abs.OriginalSignature = p;
- ModuleSignature compileSig;
- if (abs.CompilePath != null) {
- if (ResolvePath(abs.CompileRoot, abs.CompilePath, out compileSig)) {
- if (refinementTransformer.CheckIsRefinement(compileSig, p)) {
- abs.Signature.CompileSignature = compileSig;
- } else {
- Error(abs.CompilePath[0],
- "module " + Util.Comma(".", abs.CompilePath, x => x.val) + " must be a refinement of " + Util.Comma(".", abs.Path, x => x.val));
- }
- abs.Signature.IsGhost = compileSig.IsGhost;
- // always keep the ghost information, to supress a spurious error message when the compile module isn't actually a refinement
- }
- }
- } else {
- abs.Signature = new ModuleSignature(); // there was an error, give it a valid but empty signature
- }
- } else { Contract.Assert(false); }
- Contract.Assert(decl.Signature != null);
- }
- // compute IsRecursive bit for mutually recursive functions
- foreach (ModuleDefinition m in prog.Modules) {
- foreach (var fn in ModuleDefinition.AllFunctions(m.TopLevelDecls)) {
- if (!fn.IsRecursive) { // note, self-recursion has already been determined
- int n = m.CallGraph.GetSCCSize(fn);
- if (2 <= n) {
- // the function is mutually recursive (note, the SCC does not determine self recursion)
- fn.IsRecursive = true;
- }
- }
- }
- }
- }
-
- private void ResolveModuleDefinition(ModuleDefinition m, ModuleSignature sig) {
- moduleInfo = MergeSignature(sig, systemNameInfo);
- // resolve
- var datatypeDependencies = new Graph<IndDatatypeDecl>();
- int prevErrorCount = ErrorCount;
- ResolveTopLevelDecls_Signatures(m, m.TopLevelDecls, datatypeDependencies);
- if (ErrorCount == prevErrorCount) {
- ResolveTopLevelDecls_Meat(m.TopLevelDecls, datatypeDependencies);
- }
- }
-
-
- public class ModuleBindings
- {
- private ModuleBindings parent;
- private Dictionary<string, ModuleDecl> modules;
- private Dictionary<string, ModuleBindings> bindings;
-
- public ModuleBindings(ModuleBindings p) {
- parent = p;
- modules = new Dictionary<string, ModuleDecl>();
- bindings = new Dictionary<string, ModuleBindings>();
- }
- public bool BindName(string name, ModuleDecl subModule, ModuleBindings b) {
- if (modules.ContainsKey(name)) {
- return false;
- } else {
- modules.Add(name, subModule);
- bindings.Add(name, b);
- return true;
- }
- }
- public bool TryLookup(IToken name, out ModuleDecl m) {
- Contract.Requires(name != null);
- if (modules.TryGetValue(name.val, out m)) {
- return true;
- } else if (parent != null) {
- return parent.TryLookup(name, out m);
- } else return false;
- }
- public bool TryLookupIgnore(IToken name, out ModuleDecl m, ModuleDecl ignore) {
- Contract.Requires(name != null);
- if (modules.TryGetValue(name.val, out m) && m != ignore) {
- return true;
- } else if (parent != null) {
- return parent.TryLookup(name, out m);
- } else return false;
- }
- public IEnumerable<ModuleDecl> ModuleList {
- get { return modules.Values; }
- }
- public ModuleBindings SubBindings(string name) {
- ModuleBindings v = null;
- bindings.TryGetValue(name, out v);
- return v;
- }
- }
- private ModuleBindings BindModuleNames(ModuleDefinition moduleDecl, ModuleBindings parentBindings) {
- var bindings = new ModuleBindings(parentBindings);
-
- foreach (var tld in moduleDecl.TopLevelDecls) {
- if (tld is LiteralModuleDecl) {
- var subdecl = (LiteralModuleDecl)tld;
- var subBindings = BindModuleNames(subdecl.ModuleDef, bindings);
- if (!bindings.BindName(subdecl.Name, subdecl, subBindings)) {
- Error(subdecl.tok, "Duplicate module name: {0}", subdecl.Name);
- }
- } else if (tld is AbstractModuleDecl) {
- var subdecl = (AbstractModuleDecl)tld;
- if (!bindings.BindName(subdecl.Name, subdecl, null)) {
- Error(subdecl.tok, "Duplicate module name: {0}", subdecl.Name);
- }
- } else if (tld is AliasModuleDecl) {
- var subdecl = (AliasModuleDecl)tld;
- if (!bindings.BindName(subdecl.Name, subdecl, null)) {
- Error(subdecl.tok, "Duplicate module name: {0}", subdecl.Name);
- }
- }
- }
- return bindings;
- }
-
- private void ProcessDependenciesDefinition(ModuleDecl decl, ModuleDefinition m, ModuleBindings bindings, Graph<ModuleDecl> dependencies) {
- if (m.RefinementBaseName != null) {
- ModuleDecl other;
- if (!bindings.TryLookup(m.RefinementBaseName[0], out other)) {
- Error(m, "module {0} named as refinement base does not exist", m.RefinementBaseName[0].val);
- } else if (other is LiteralModuleDecl && ((LiteralModuleDecl)other).ModuleDef == m) {
- Error(m, "module cannot refine itself: {0}", m.RefinementBaseName[0].val);
- } else {
- Contract.Assert(other != null); // follows from postcondition of TryGetValue
- dependencies.AddEdge(decl, other);
- m.RefinementBaseRoot = other;
- }
- }
- foreach (var toplevel in m.TopLevelDecls) {
- if (toplevel is ModuleDecl) {
- var d = (ModuleDecl)toplevel;
- dependencies.AddEdge(decl, d);
- var subbindings = bindings.SubBindings(d.Name);
- ProcessDependencies(d, subbindings ?? bindings, dependencies);
- }
- }
- }
- private void ProcessDependencies(ModuleDecl moduleDecl, ModuleBindings bindings, Graph<ModuleDecl> dependencies) {
- dependencies.AddVertex(moduleDecl);
- if (moduleDecl is LiteralModuleDecl) {
- ProcessDependenciesDefinition(moduleDecl, ((LiteralModuleDecl)moduleDecl).ModuleDef, bindings, dependencies);
- } else if (moduleDecl is AliasModuleDecl) {
- var alias = moduleDecl as AliasModuleDecl;
- ModuleDecl root;
- if (!bindings.TryLookupIgnore(alias.Path[0], out root, alias))
- Error(alias.tok, ModuleNotFoundErrorMessage(0, alias.Path));
- else {
- dependencies.AddEdge(moduleDecl, root);
- alias.Root = root;
- }
- } else if (moduleDecl is AbstractModuleDecl) {
- var abs = moduleDecl as AbstractModuleDecl;
- ModuleDecl root;
- if (!bindings.TryLookup(abs.Path[0], out root))
- Error(abs.tok, ModuleNotFoundErrorMessage(0, abs.Path));
- else {
- dependencies.AddEdge(moduleDecl, root);
- abs.Root = root;
- }
- if (abs.CompilePath != null) {
- if (!bindings.TryLookup(abs.CompilePath[0], out root))
- Error(abs.tok, ModuleNotFoundErrorMessage(0, abs.CompilePath));
- else {
- dependencies.AddEdge(moduleDecl, root);
- abs.CompileRoot = root;
- }
- }
- }
- }
-
- private string ModuleNotFoundErrorMessage(int i, List<IToken> path) {
- return "module " + path[i].val + " does not exist" +
- (1 < path.Count ? " (position " + i.ToString() + " in path " + Util.Comma(".", path, x => x.val) + ")" : "");
- }
-
- public static ModuleSignature MergeSignature(ModuleSignature m, ModuleSignature system) {
- var info = new ModuleSignature();
- // add the system-declared information, among which we know there are no duplicates
- foreach (var kv in system.TopLevels) {
- info.TopLevels.Add(kv.Key, kv.Value);
- }
- foreach (var kv in system.Ctors) {
- info.Ctors.Add(kv.Key, kv.Value);
- }
- // add for the module itself
- foreach (var kv in m.TopLevels) {
- info.TopLevels[kv.Key] = kv.Value;
- }
- foreach (var kv in m.Ctors) {
- info.Ctors[kv.Key] = kv.Value;
- }
- foreach (var kv in m.StaticMembers) {
- info.StaticMembers[kv.Key] = kv.Value;
- }
- info.IsGhost = m.IsGhost;
- return info;
- }
- ModuleSignature RegisterTopLevelDecls(ModuleDefinition moduleDef, bool useImports) {
- Contract.Requires(moduleDef != null);
- var sig = new ModuleSignature();
- sig.ModuleDef = moduleDef;
- sig.IsGhost = moduleDef.IsGhost;
- List<TopLevelDecl> declarations = moduleDef.TopLevelDecls;
-
- if (useImports) {
- // First go through and add anything from the opened imports
- foreach (var im in declarations) {
- if (im is ModuleDecl && ((ModuleDecl)im).Opened) {
- var s = ((ModuleDecl)im).Signature;
- // classes:
- foreach (var kv in s.TopLevels) {
- TopLevelDecl d;
- if (sig.TopLevels.TryGetValue(kv.Key, out d)) {
- sig.TopLevels[kv.Key] = new AmbiguousTopLevelDecl(moduleDef, d, kv.Value);
- } else {
- sig.TopLevels.Add(kv.Key, kv.Value);
- }
- }
- // constructors:
- foreach (var kv in s.Ctors) {
- Tuple<DatatypeCtor, bool> pair;
- if (sig.Ctors.TryGetValue(kv.Key, out pair)) {
- // mark it as a duplicate
- sig.Ctors[kv.Key] = new Tuple<DatatypeCtor, bool>(pair.Item1, true);
- } else {
- // add new
- sig.Ctors.Add(kv.Key, kv.Value);
- }
- }
- // static members:
- foreach (var kv in s.StaticMembers) {
- MemberDecl md;
- if (sig.StaticMembers.TryGetValue(kv.Key, out md)) {
- sig.StaticMembers[kv.Key] = new AmbiguousMemberDecl(moduleDef, md, kv.Value);
- } else {
- // add new
- sig.StaticMembers.Add(kv.Key, kv.Value);
- }
- }
- }
- }
- }
- // This is solely used to detect duplicates amongst the various e
- Dictionary<string, TopLevelDecl> toplevels = new Dictionary<string, TopLevelDecl>();
- // Now add the things present
- foreach (TopLevelDecl d in declarations) {
- Contract.Assert(d != null);
- // register the class/datatype/module name
- if (toplevels.ContainsKey(d.Name)) {
- Error(d, "Duplicate name of top-level declaration: {0}", d.Name);
- } else {
- toplevels[d.Name] = d;
- sig.TopLevels[d.Name] = d;
- }
- if (d is ModuleDecl) {
- // nothing to do
- } else if (d is ArbitraryTypeDecl) {
- // nothing more to register
-
- } else if (d is IteratorDecl) {
- var iter = (IteratorDecl)d;
-
- // register the names of the implicit members
- var members = new Dictionary<string, MemberDecl>();
- classMembers.Add(iter, members);
-
- // First, register the iterator's in- and out-parameters as readonly fields
- foreach (var p in iter.Ins) {
- if (members.ContainsKey(p.Name)) {
- Error(p, "Name of in-parameter is used by another member of the iterator: {0}", p.Name);
- } else {
- var field = new SpecialField(p.tok, p.Name, p.CompileName, "", "", p.IsGhost, false, false, p.Type, null);
- field.EnclosingClass = iter; // resolve here
- members.Add(p.Name, field);
- iter.Members.Add(field);
- }
- }
- foreach (var p in iter.Outs) {
- if (members.ContainsKey(p.Name)) {
- Error(p, "Name of yield-parameter is used by another member of the iterator: {0}", p.Name);
- } else {
- var field = new SpecialField(p.tok, p.Name, p.CompileName, "", "", p.IsGhost, true, true, p.Type, null);
- field.EnclosingClass = iter; // resolve here
- iter.OutsFields.Add(field);
- members.Add(p.Name, field);
- iter.Members.Add(field);
- }
- }
- foreach (var p in iter.Outs) {
- var nm = p.Name + "s";
- if (members.ContainsKey(nm)) {
- Error(p.tok, "Name of implicit yield-history variable '{0}' is already used by another member of the iterator", p.Name);
- } else {
- var tp = new SeqType(p.Type.IsSubrangeType ? new IntType() : p.Type);
- var field = new SpecialField(p.tok, nm, nm, "", "", true, true, false, tp, null);
- field.EnclosingClass = iter; // resolve here
- iter.OutsHistoryFields.Add(field); // for now, just record this field (until all parameters have been added as members)
- }
- }
- // now that already-used 'ys' names have been checked for, add these yield-history variables
- iter.OutsHistoryFields.ForEach(f => {
- members.Add(f.Name, f);
- iter.Members.Add(f);
- });
- // add the additional special variables as fields
- iter.Member_Reads = new SpecialField(iter.tok, "_reads", "_reads", "", "", true, false, false, new SetType(new ObjectType()), null);
- iter.Member_Modifies = new SpecialField(iter.tok, "_modifies", "_modifies", "", "", true, false, false, new SetType(new ObjectType()), null);
- iter.Member_New = new SpecialField(iter.tok, "_new", "_new", "", "", true, true, true, new SetType(new ObjectType()), null);
- foreach (var field in new List<Field>() { iter.Member_Reads, iter.Member_Modifies, iter.Member_New }) {
- field.EnclosingClass = iter; // resolve here
- members.Add(field.Name, field);
- iter.Members.Add(field);
- }
- // finally, add special variables to hold the components of the (explicit or implicit) decreases clause
- bool inferredDecreases;
- var decr = Translator.MethodDecreasesWithDefault(iter, out inferredDecreases);
- if (inferredDecreases) {
- iter.InferredDecreases = true;
- Contract.Assert(iter.Decreases.Expressions.Count == 0);
- iter.Decreases.Expressions.AddRange(decr);
- }
- // create the fields; unfortunately, we don't know their types yet, so we'll just insert type proxies for now
- var i = 0;
- foreach (var p in iter.Decreases.Expressions) {
- var nm = "_decreases" + i;
- var field = new SpecialField(p.tok, nm, nm, "", "", true, false, false, new InferredTypeProxy(), null);
- field.EnclosingClass = iter; // resolve here
- iter.DecreasesFields.Add(field);
- members.Add(field.Name, field);
- iter.Members.Add(field);
- i++;
- }
-
- // Note, the typeArgs parameter to the following Method/Predicate constructors is passed in as the empty list. What that is
- // saying is that the Method/Predicate does not take any type parameters over and beyond what the enclosing type (namely, the
- // iterator type) does.
- // --- here comes the constructor
- var init = new Constructor(iter.tok, iter.Name, new List<TypeParameter>(), iter.Ins,
- new List<MaybeFreeExpression>(),
- new Specification<FrameExpression>(new List<FrameExpression>(), null),
- new List<MaybeFreeExpression>(),
- new Specification<Expression>(new List<Expression>(), null),
- null, null, false);
- // --- here comes predicate Valid()
- var valid = new Predicate(iter.tok, "Valid", false, true, new List<TypeParameter>(), iter.tok,
- new List<Formal>(),
- new List<Expression>(),
- new List<FrameExpression>(),
- new List<Expression>(),
- new Specification<Expression>(new List<Expression>(), null),
- null, Predicate.BodyOriginKind.OriginalOrInherited, null, false);
- // --- here comes method MoveNext
- var moveNext = new Method(iter.tok, "MoveNext", false, false, new List<TypeParameter>(),
- new List<Formal>(), new List<Formal>() { new Formal(iter.tok, "more", Type.Bool, false, false) },
- new List<MaybeFreeExpression>(),
- new Specification<FrameExpression>(new List<FrameExpression>(), null),
- new List<MaybeFreeExpression>(),
- new Specification<Expression>(new List<Expression>(), null),
- null, null, false);
- // add these implicit members to the class
- init.EnclosingClass = iter;
- valid.EnclosingClass = iter;
- moveNext.EnclosingClass = iter;
- iter.HasConstructor = true;
- iter.Member_Init = init;
- iter.Member_Valid = valid;
- iter.Member_MoveNext = moveNext;
- MemberDecl member;
- if (members.TryGetValue(init.Name, out member)) {
- Error(member.tok, "member name '{0}' is already predefined for this iterator", init.Name);
- } else {
- members.Add(init.Name, init);
- iter.Members.Add(init);
- }
- // If the name of the iterator is "Valid" or "MoveNext", one of the following will produce an error message. That
- // error message may not be as clear as it could be, but the situation also seems unlikely to ever occur in practice.
- if (members.TryGetValue("Valid", out member)) {
- Error(member.tok, "member name 'Valid' is already predefined for iterators");
- } else {
- members.Add(valid.Name, valid);
- iter.Members.Add(valid);
- }
- if (members.TryGetValue("MoveNext", out member)) {
- Error(member.tok, "member name 'MoveNext' is already predefined for iterators");
- } else {
- members.Add(moveNext.Name, moveNext);
- iter.Members.Add(moveNext);
- }
-
- } else if (d is ClassDecl) {
- ClassDecl cl = (ClassDecl)d;
-
- // register the names of the class members
- var members = new Dictionary<string, MemberDecl>();
- classMembers.Add(cl, members);
-
- bool hasConstructor = false;
- foreach (MemberDecl m in cl.Members) {
- if (members.ContainsKey(m.Name)) {
- Error(m, "Duplicate member name: {0}", m.Name);
- } else {
- members.Add(m.Name, m);
- }
- if (m is Constructor) {
- hasConstructor = true;
- }
- }
- cl.HasConstructor = hasConstructor;
- if (cl.IsDefaultClass) {
- foreach (MemberDecl m in cl.Members) {
- if (m.IsStatic && (m is Function || m is Method)) {
- sig.StaticMembers[m.Name] = m;
- }
- }
- }
-
- } else {
- DatatypeDecl dt = (DatatypeDecl)d;
-
- // register the names of the constructors
- var ctors = new Dictionary<string, DatatypeCtor>();
- datatypeCtors.Add(dt, ctors);
- // ... and of the other members
- var members = new Dictionary<string, MemberDecl>();
- datatypeMembers.Add(dt, members);
-
- foreach (DatatypeCtor ctor in dt.Ctors) {
- if (ctor.Name.EndsWith("?")) {
- Error(ctor, "a datatype constructor name is not allowed to end with '?'");
- } else if (ctors.ContainsKey(ctor.Name)) {
- Error(ctor, "Duplicate datatype constructor name: {0}", ctor.Name);
- } else {
- ctors.Add(ctor.Name, ctor);
-
- // create and add the query "method" (field, really)
- string queryName = ctor.Name + "?";
- var query = new SpecialField(ctor.tok, queryName, "is_" + ctor.CompileName, "", "", false, false, false, Type.Bool, null);
- query.EnclosingClass = dt; // resolve here
- members.Add(queryName, query);
- ctor.QueryField = query;
-
- // also register the constructor name globally
- Tuple<DatatypeCtor, bool> pair;
- if (sig.Ctors.TryGetValue(ctor.Name, out pair)) {
- // mark it as a duplicate
- sig.Ctors[ctor.Name] = new Tuple<DatatypeCtor, bool>(pair.Item1, true);
- } else {
- // add new
- sig.Ctors.Add(ctor.Name, new Tuple<DatatypeCtor, bool>(ctor, false));
- }
- }
- }
- // add deconstructors now (that is, after the query methods have been added)
- foreach (DatatypeCtor ctor in dt.Ctors) {
- foreach (var formal in ctor.Formals) {
- SpecialField dtor = null;
- if (formal.HasName) {
- if (members.ContainsKey(formal.Name)) {
- Error(ctor, "Name of deconstructor is used by another member of the datatype: {0}", formal.Name);
- } else {
- dtor = new DatatypeDestructor(formal.tok, ctor, formal, formal.Name, "dtor_" + formal.Name, "", "", formal.IsGhost, formal.Type, null);
- dtor.EnclosingClass = dt; // resolve here
- members.Add(formal.Name, dtor);
- }
- }
- ctor.Destructors.Add(dtor);
- }
- }
- }
- }
- return sig;
- }
-
- private ModuleSignature MakeAbstractSignature(ModuleSignature p, string Name, int Height, List<ModuleDefinition> mods) {
- var mod = new ModuleDefinition(Token.NoToken, Name + ".Abs", true, true, null, null, false);
- mod.Height = Height;
- foreach (var kv in p.TopLevels) {
- mod.TopLevelDecls.Add(CloneDeclaration(kv.Value, mod, mods, Name));
- }
- var sig = RegisterTopLevelDecls(mod, false);
- sig.Refines = p.Refines;
- sig.CompileSignature = p;
- sig.IsGhost = p.IsGhost;
- mods.Add(mod);
- ResolveModuleDefinition(mod, sig);
- return sig;
- }
- TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition m, List<ModuleDefinition> mods, string Name) {
- Contract.Requires(d != null);
- Contract.Requires(m != null);
-
- if (d is ArbitraryTypeDecl) {
- var dd = (ArbitraryTypeDecl)d;
- return new ArbitraryTypeDecl(dd.tok, dd.Name, m, dd.EqualitySupport, null);
- } else if (d is IndDatatypeDecl) {
- var dd = (IndDatatypeDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var ctors = dd.Ctors.ConvertAll(CloneCtor);
- var dt = new IndDatatypeDecl(dd.tok, dd.Name, m, tps, ctors, null);
- return dt;
- } else if (d is CoDatatypeDecl) {
- var dd = (CoDatatypeDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var ctors = dd.Ctors.ConvertAll(CloneCtor);
- var dt = new CoDatatypeDecl(dd.tok, dd.Name, m, tps, ctors, null);
- return dt;
- } else if (d is ClassDecl) {
- var dd = (ClassDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var mm = dd.Members.ConvertAll(CloneMember);
- if (dd is DefaultClassDecl) {
- return new DefaultClassDecl(m, mm);
- } else return new ClassDecl(dd.tok, dd.Name, m, tps, mm, null);
- } else if (d is ModuleDecl) {
- if (d is LiteralModuleDecl) {
- return new LiteralModuleDecl(((LiteralModuleDecl)d).ModuleDef, m);
- } else if (d is AliasModuleDecl) {
- var a = (AliasModuleDecl)d;
- var alias = new AliasModuleDecl(a.Path, a.tok, m, a.Opened);
- alias.ModuleReference = a.ModuleReference;
- alias.Signature = a.Signature;
- return alias;
- } else if (d is AbstractModuleDecl) {
- var abs = (AbstractModuleDecl)d;
- var sig = MakeAbstractSignature(abs.OriginalSignature, Name + "." + abs.Name, abs.Height, mods);
- var a = new AbstractModuleDecl(abs.Path, abs.tok, m, abs.CompilePath, abs.Opened);
- a.Signature = sig;
- a.OriginalSignature = abs.OriginalSignature;
- return a;
- } else {
- Contract.Assert(false); // unexpected declaration
- return null; // to please compiler
- }
- } else {
- Contract.Assert(false); // unexpected declaration
- return null; // to please compiler
- }
- }
- MemberDecl CloneMember(MemberDecl member) {
- if (member is Field) {
- Contract.Assert(!(member is SpecialField)); // we don't expect a SpecialField to be cloned (or do we?)
- var f = (Field)member;
- return new Field(f.tok, f.Name, f.IsGhost, f.IsMutable, f.IsUserMutable, CloneType(f.Type), null);
- } else if (member is Function) {
- var f = (Function)member;
- return CloneFunction(f.tok, f, f.IsGhost);
- } else {
- var m = (Method)member;
- return CloneMethod(m);
- }
- }
- TypeParameter CloneTypeParam(TypeParameter tp) {
- return new TypeParameter(tp.tok, tp.Name);
- }
-
- DatatypeCtor CloneCtor(DatatypeCtor ct) {
- return new DatatypeCtor(ct.tok, ct.Name, ct.Formals.ConvertAll(CloneFormal), null);
- }
- Formal CloneFormal(Formal formal) {
- return new Formal(formal.tok, formal.Name, CloneType(formal.Type), formal.InParam, formal.IsGhost);
- }
- Type CloneType(Type t) {
- if (t is BasicType) {
- return t;
- } else if (t is SetType) {
- var tt = (SetType)t;
- return new SetType(CloneType(tt.Arg));
- } else if (t is SeqType) {
- var tt = (SeqType)t;
- return new SeqType(CloneType(tt.Arg));
- } else if (t is MultiSetType) {
- var tt = (MultiSetType)t;
- return new MultiSetType(CloneType(tt.Arg));
- } else if (t is MapType) {
- var tt = (MapType)t;
- return new MapType(CloneType(tt.Domain), CloneType(tt.Range));
- } else if (t is UserDefinedType) {
- var tt = (UserDefinedType)t;
- return new UserDefinedType(tt.tok, tt.Name, tt.TypeArgs.ConvertAll(CloneType), tt.Path.ConvertAll(x => x));
- } else if (t is InferredTypeProxy) {
- return new InferredTypeProxy();
- } else {
- Contract.Assert(false); // unexpected type (e.g., no other type proxies are expected at this time)
- return null; // to please compiler
- }
- }
- Function CloneFunction(IToken tok, Function f, bool isGhost) {
-
- var tps = f.TypeArgs.ConvertAll(CloneTypeParam);
- var formals = f.Formals.ConvertAll(CloneFormal);
- var req = f.Req.ConvertAll(CloneExpr);
- var reads = f.Reads.ConvertAll(CloneFrameExpr);
- var decreases = CloneSpecExpr(f.Decreases);
-
- var ens = f.Ens.ConvertAll(CloneExpr);
-
- Expression body = CloneExpr(f.Body);
-
- if (f is Predicate) {
- return new Predicate(tok, f.Name, f.IsStatic, isGhost, tps, f.OpenParen, formals,
- req, reads, ens, decreases, body, Predicate.BodyOriginKind.OriginalOrInherited, null, false);
- } else if (f is CoPredicate) {
- return new CoPredicate(tok, f.Name, f.IsStatic, tps, f.OpenParen, formals,
- req, reads, ens, body, null, false);
- } else {
- return new Function(tok, f.Name, f.IsStatic, isGhost, tps, f.OpenParen, formals, CloneType(f.ResultType),
- req, reads, ens, decreases, body, null, false);
- }
- }
- Method CloneMethod(Method m) {
- Contract.Requires(m != null);
-
- var tps = m.TypeArgs.ConvertAll(CloneTypeParam);
- var ins = m.Ins.ConvertAll(CloneFormal);
- var req = m.Req.ConvertAll(CloneMayBeFreeExpr);
- var mod = CloneSpecFrameExpr(m.Mod);
- var decreases = CloneSpecExpr(m.Decreases);
-
- var ens = m.Ens.ConvertAll(CloneMayBeFreeExpr);
-
- if (m is Constructor) {
- return new Constructor(m.tok, m.Name, tps, ins,
- req, mod, ens, decreases, null, null, false);
- } else {
- return new Method(m.tok, m.Name, m.IsStatic, m.IsGhost, tps, ins, m.Outs.ConvertAll(CloneFormal),
- req, mod, ens, decreases, null, null, false);
- }
- }
- Specification<Expression> CloneSpecExpr(Specification<Expression> spec) {
- var ee = spec.Expressions == null ? null : spec.Expressions.ConvertAll(CloneExpr);
- return new Specification<Expression>(ee, null);
- }
- Specification<FrameExpression> CloneSpecFrameExpr(Specification<FrameExpression> frame) {
- var ee = frame.Expressions == null ? null : frame.Expressions.ConvertAll(CloneFrameExpr);
- return new Specification<FrameExpression>(ee, null);
- }
- FrameExpression CloneFrameExpr(FrameExpression frame) {
- return new FrameExpression(frame.tok, CloneExpr(frame.E), frame.FieldName);
- }
- MaybeFreeExpression CloneMayBeFreeExpr(MaybeFreeExpression expr) {
- return new MaybeFreeExpression(CloneExpr(expr.E), expr.IsFree);
- }
- BoundVar CloneBoundVar(BoundVar bv) {
- return new BoundVar(bv.tok, bv.Name, CloneType(bv.Type));
- }
- Expression CloneExpr(Expression expr) {
- if (expr == null) {
- return null;
- } else if (expr is LiteralExpr) {
- var e = (LiteralExpr)expr;
- if (e.Value == null) {
- return new LiteralExpr(e.tok);
- } else if (e.Value is bool) {
- return new LiteralExpr(e.tok, (bool)e.Value);
- } else {
- return new LiteralExpr(e.tok, (BigInteger)e.Value);
- }
-
- } else if (expr is ThisExpr) {
- if (expr is ImplicitThisExpr) {
- return new ImplicitThisExpr(expr.tok);
- } else {
- return new ThisExpr(expr.tok);
- }
-
- } else if (expr is IdentifierExpr) {
- var e = (IdentifierExpr)expr;
- return new IdentifierExpr(e.tok, e.Name);
-
- } else if (expr is DatatypeValue) {
- var e = (DatatypeValue)expr;
- return new DatatypeValue(e.tok, e.DatatypeName, e.MemberName, e.Arguments.ConvertAll(CloneExpr));
-
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- if (expr is SetDisplayExpr) {
- return new SetDisplayExpr(e.tok, e.Elements.ConvertAll(CloneExpr));
- } else if (expr is MultiSetDisplayExpr) {
- return new MultiSetDisplayExpr(e.tok, e.Elements.ConvertAll(CloneExpr));
- } else {
- Contract.Assert(expr is SeqDisplayExpr);
- return new SeqDisplayExpr(e.tok, e.Elements.ConvertAll(CloneExpr));
- }
-
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- List<ExpressionPair> pp = new List<ExpressionPair>();
- foreach (ExpressionPair p in e.Elements) {
- pp.Add(new ExpressionPair(CloneExpr(p.A), CloneExpr(p.B)));
- }
- return new MapDisplayExpr(expr.tok, pp);
- } else if (expr is ExprDotName) {
- var e = (ExprDotName)expr;
- return new ExprDotName(e.tok, CloneExpr(e.Obj), e.SuffixName);
-
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- return new FieldSelectExpr(e.tok, CloneExpr(e.Obj), e.FieldName);
-
- } else if (expr is SeqSelectExpr) {
- var e = (SeqSelectExpr)expr;
- return new SeqSelectExpr(e.tok, e.SelectOne, CloneExpr(e.Seq), CloneExpr(e.E0), CloneExpr(e.E1));
-
- } else if (expr is MultiSelectExpr) {
- var e = (MultiSelectExpr)expr;
- return new MultiSelectExpr(e.tok, CloneExpr(e.Array), e.Indices.ConvertAll(CloneExpr));
-
- } else if (expr is SeqUpdateExpr) {
- var e = (SeqUpdateExpr)expr;
- return new SeqUpdateExpr(e.tok, CloneExpr(e.Seq), CloneExpr(e.Index), CloneExpr(e.Value));
-
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- return new FunctionCallExpr(e.tok, e.Name, CloneExpr(e.Receiver), e.OpenParen == null ? null : (e.OpenParen), e.Args.ConvertAll(CloneExpr));
-
- } else if (expr is OldExpr) {
- var e = (OldExpr)expr;
- return new OldExpr(e.tok, CloneExpr(e.E));
-
- } else if (expr is MultiSetFormingExpr) {
- var e = (MultiSetFormingExpr)expr;
- return new MultiSetFormingExpr(e.tok, CloneExpr(e.E));
-
- } else if (expr is FreshExpr) {
- var e = (FreshExpr)expr;
- return new FreshExpr(e.tok, CloneExpr(e.E));
-
- } else if (expr is UnaryExpr) {
- var e = (UnaryExpr)expr;
- return new UnaryExpr(e.tok, e.Op, CloneExpr(e.E));
-
- } else if (expr is BinaryExpr) {
- var e = (BinaryExpr)expr;
- return new BinaryExpr(e.tok, e.Op, CloneExpr(e.E0), CloneExpr(e.E1));
-
- } else if (expr is ChainingExpression) {
- var e = (ChainingExpression)expr;
- return CloneExpr(e.E); // just clone the desugaring, since it's already available
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- return new LetExpr(e.tok, e.Vars.ConvertAll(CloneBoundVar), e.RHSs.ConvertAll(CloneExpr), CloneExpr(e.Body));
-
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- var tk = e.tok;
- var bvs = e.BoundVars.ConvertAll(CloneBoundVar);
- var range = CloneExpr(e.Range);
- var term = CloneExpr(e.Term);
- if (e is ForallExpr) {
- return new ForallExpr(tk, bvs, range, term, null);
- } else if (e is ExistsExpr) {
- return new ExistsExpr(tk, bvs, range, term, null);
- } else if (e is MapComprehension) {
- return new MapComprehension(tk, bvs, range, term);
- } else {
- Contract.Assert(e is SetComprehension);
- return new SetComprehension(tk, bvs, range, term);
- }
-
- } else if (expr is WildcardExpr) {
- return new WildcardExpr(expr.tok);
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- if (e is AssertExpr) {
- return new AssertExpr(e.tok, CloneExpr(e.Guard), CloneExpr(e.Body));
- } else {
- Contract.Assert(e is AssumeExpr);
- return new AssumeExpr(e.tok, CloneExpr(e.Guard), CloneExpr(e.Body));
- }
-
- } else if (expr is ITEExpr) {
- var e = (ITEExpr)expr;
- return new ITEExpr(e.tok, CloneExpr(e.Test), CloneExpr(e.Thn), CloneExpr(e.Els));
-
- } else if (expr is ParensExpression) {
- var e = (ParensExpression)expr;
- return CloneExpr(e.E); // skip the parentheses in the clone
-
- } else if (expr is IdentifierSequence) {
- var e = (IdentifierSequence)expr;
- var aa = e.Arguments == null ? null : e.Arguments.ConvertAll(CloneExpr);
- return new IdentifierSequence(e.Tokens.ConvertAll(tk => (tk)), e.OpenParen == null ? null : (e.OpenParen), aa);
-
- } else if (expr is MatchExpr) {
- var e = (MatchExpr)expr;
- return new MatchExpr(e.tok, CloneExpr(e.Source),
- e.Cases.ConvertAll(c => new MatchCaseExpr(c.tok, c.Id, c.Arguments.ConvertAll(CloneBoundVar), CloneExpr(c.Body))));
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
-
- private bool ResolvePath(ModuleDecl root, List<IToken> Path, out ModuleSignature p) {
- p = root.Signature;
- int i = 1;
- while (i < Path.Count) {
- ModuleSignature pp;
- if (p.FindSubmodule(Path[i].val, out pp)) {
- p = pp;
- i++;
- } else {
- Error(Path[i], ModuleNotFoundErrorMessage(i, Path));
- break;
- }
- }
- return i == Path.Count;
- }
- public void ResolveTopLevelDecls_Signatures(ModuleDefinition def, List<TopLevelDecl/*!*/>/*!*/ declarations, Graph<IndDatatypeDecl/*!*/>/*!*/ datatypeDependencies) {
- Contract.Requires(declarations != null);
- Contract.Requires(datatypeDependencies != null); // more expensive check: Contract.Requires(cce.NonNullElements(datatypeDependencies));
- foreach (TopLevelDecl d in declarations) {
- Contract.Assert(d != null);
- allTypeParameters.PushMarker();
- ResolveTypeParameters(d.TypeArgs, true, d);
- if (d is ArbitraryTypeDecl) {
- // nothing to do
- } else if (d is IteratorDecl) {
- ResolveIteratorSignature((IteratorDecl)d);
- } else if (d is ClassDecl) {
- ResolveClassMemberTypes((ClassDecl)d);
- } else if (d is ModuleDecl) {
- var decl = (ModuleDecl)d;
- if (!def.IsGhost) {
- if (decl.Signature.IsGhost)
- {
- if (!(def.IsDefaultModule)) // _module is allowed to contain ghost modules, but not be ghost itself. Note this presents a challenge to
- // trusted verification, as toplevels can't be trusted if they invoke ghost module members.
- Error(d.tok, "ghost modules can only be imported into other ghost modules, not physical ones.");
- } else {
- // physical modules are allowed everywhere
- }
- } else {
- // everything is allowed in a ghost module
- }
- } else {
- ResolveCtorTypes((DatatypeDecl)d, datatypeDependencies);
- }
- allTypeParameters.PopMarker();
- }
- }
-
- public void ResolveTopLevelDecls_Meat(List<TopLevelDecl/*!*/>/*!*/ declarations, Graph<IndDatatypeDecl/*!*/>/*!*/ datatypeDependencies) {
- Contract.Requires(declarations != null);
- Contract.Requires(cce.NonNullElements(datatypeDependencies));
-
- int prevErrorCount = ErrorCount;
-
- // Resolve the meat of classes, and the type parameters of all top-level type declarations
- foreach (TopLevelDecl d in declarations) {
- Contract.Assert(d != null);
- allTypeParameters.PushMarker();
- ResolveTypeParameters(d.TypeArgs, false, d);
- if (d is IteratorDecl) {
- var iter = (IteratorDecl)d;
- allTypeParameters.PushMarker();
- ResolveTypeParameters(iter.TypeArgs, false, iter);
- ResolveIterator(iter);
- allTypeParameters.PopMarker();
- ResolveClassMemberBodies(iter); // resolve the automatically generated members
-
- } else if (d is ClassDecl) {
- var cl = (ClassDecl)d;
- ResolveAttributes(cl.Attributes, false);
- ResolveClassMemberBodies(cl);
- }
- allTypeParameters.PopMarker();
- }
-
- if (ErrorCount == prevErrorCount) {
- foreach (TopLevelDecl d in declarations) {
- if (d is ClassDecl) {
- foreach (var member in ((ClassDecl)d).Members) {
- if (member is Method) {
- var m = (Method)member;
- if (m.Body != null) {
- CheckTypeInference(m.Body);
- bool tail = true;
- bool hasTailRecursionPreference = Attributes.ContainsBool(m.Attributes, "tailrecursion", ref tail);
- if (hasTailRecursionPreference && !tail) {
- // the user specifically requested no tail recursion, so do nothing else
- } else if (hasTailRecursionPreference && tail && m.IsGhost) {
- Error(m.tok, "tail recursion can be specified only for methods that will be compiled, not for ghost methods");
- } else {
- var module = m.EnclosingClass.Module;
- var sccSize = module.CallGraph.GetSCCSize(m);
- if (hasTailRecursionPreference && 2 <= sccSize) {
- Error(m.tok, "sorry, tail-call optimizations are not supported for mutually recursive methods");
- } else if (hasTailRecursionPreference || sccSize == 1) {
- CallStmt tailCall = null;
- var status = CheckTailRecursive(m.Body.Body, m, ref tailCall, hasTailRecursionPreference);
- if (status != TailRecursionStatus.NotTailRecursive) {
- m.IsTailRecursive = true;
- }
- }
- }
- }
- if (!m.IsTailRecursive && m.Body != null && Contract.Exists(m.Decreases.Expressions, e => e is WildcardExpr)) {
- Error(m.Decreases.Expressions[0].tok, "'decreases *' is allowed only on tail-recursive methods");
- }
- } else if (member is Function) {
- var f = (Function)member;
- if (f.Body != null) {
- CheckTypeInference(f.Body);
- bool tail = true;
- if (Attributes.ContainsBool(f.Attributes, "tailrecursion", ref tail) && tail) {
- Error(f.tok, "sorry, tail-call functions are not supported");
- }
- }
- }
- }
- }
- }
- }
-
- // Perform the stratosphere check on inductive datatypes, and compute to what extent the inductive datatypes require equality support
- foreach (var dtd in datatypeDependencies.TopologicallySortedComponents()) {
- if (datatypeDependencies.GetSCCRepresentative(dtd) == dtd) {
- // do the following check once per SCC, so call it on each SCC representative
- SccStratosphereCheck(dtd, datatypeDependencies);
- DetermineEqualitySupport(dtd, datatypeDependencies);
- }
- }
-
- if (ErrorCount == prevErrorCount) { // because CheckCoCalls requires the given expression to have been successfully resolved
- // Perform the guardedness check on co-datatypes
- foreach (var fn in ModuleDefinition.AllFunctions(declarations)) {
- var module = fn.EnclosingClass.Module;
- if (fn.Body != null && module.CallGraph.GetSCCRepresentative(fn) == fn) {
- bool dealsWithCodatatypes = false;
- foreach (var m in module.CallGraph.GetSCC(fn)) {
- var f = (Function)m;
- if (f.ResultType.InvolvesCoDatatype) {
- dealsWithCodatatypes = true;
- break;
- }
- }
- foreach (var m in module.CallGraph.GetSCC(fn)) {
- var f = (Function)m;
- var checker = new CoCallResolution(f, dealsWithCodatatypes);
- checker.CheckCoCalls(f.Body);
- }
- }
- }
- // Inferred required equality support for datatypes and for Function and Method signatures
- // First, do datatypes until a fixpoint is reached
- bool inferredSomething;
- do {
- inferredSomething = false;
- foreach (var d in declarations) {
- if (d is DatatypeDecl) {
- var dt = (DatatypeDecl)d;
- foreach (var tp in dt.TypeArgs) {
- if (tp.EqualitySupport == TypeParameter.EqualitySupportValue.Unspecified) {
- // here's our chance to infer the need for equality support
- foreach (var ctor in dt.Ctors) {
- foreach (var arg in ctor.Formals) {
- if (InferRequiredEqualitySupport(tp, arg.Type)) {
- tp.EqualitySupport = TypeParameter.EqualitySupportValue.InferredRequired;
- inferredSomething = true;
- goto DONE_DT; // break out of the doubly-nested loop
- }
- }
- }
- DONE_DT: ;
- }
- }
- }
- }
- } while (inferredSomething);
- // Now do it for Function and Method signatures
- foreach (var d in declarations) {
- if (d is IteratorDecl) {
- var iter = (IteratorDecl)d;
- foreach (var tp in iter.TypeArgs) {
- if (tp.EqualitySupport == TypeParameter.EqualitySupportValue.Unspecified) {
- // here's our chance to infer the need for equality support
- foreach (var p in iter.Ins) {
- if (InferRequiredEqualitySupport(tp, p.Type)) {
- tp.EqualitySupport = TypeParameter.EqualitySupportValue.InferredRequired;
- goto DONE;
- }
- }
- foreach (var p in iter.Outs) {
- if (InferRequiredEqualitySupport(tp, p.Type)) {
- tp.EqualitySupport = TypeParameter.EqualitySupportValue.InferredRequired;
- goto DONE;
- }
- }
- DONE: ;
- }
- }
- } else if (d is ClassDecl) {
- var cl = (ClassDecl)d;
- foreach (var member in cl.Members) {
- if (!member.IsGhost) {
- if (member is Function) {
- var f = (Function)member;
- foreach (var tp in f.TypeArgs) {
- if (tp.EqualitySupport == TypeParameter.EqualitySupportValue.Unspecified) {
- // here's our chance to infer the need for equality support
- if (InferRequiredEqualitySupport(tp, f.ResultType)) {
- tp.EqualitySupport = TypeParameter.EqualitySupportValue.InferredRequired;
- } else {
- foreach (var p in f.Formals) {
- if (InferRequiredEqualitySupport(tp, p.Type)) {
- tp.EqualitySupport = TypeParameter.EqualitySupportValue.InferredRequired;
- break;
- }
- }
- }
- }
- }
- } else if (member is Method) {
- var m = (Method)member;
- foreach (var tp in m.TypeArgs) {
- if (tp.EqualitySupport == TypeParameter.EqualitySupportValue.Unspecified) {
- // here's our chance to infer the need for equality support
- foreach (var p in m.Ins) {
- if (InferRequiredEqualitySupport(tp, p.Type)) {
- tp.EqualitySupport = TypeParameter.EqualitySupportValue.InferredRequired;
- goto DONE;
- }
- }
- foreach (var p in m.Outs) {
- if (InferRequiredEqualitySupport(tp, p.Type)) {
- tp.EqualitySupport = TypeParameter.EqualitySupportValue.InferredRequired;
- goto DONE;
- }
- }
- DONE: ;
- }
- }
- }
- }
- }
- }
- }
- // Check that all == and != operators in non-ghost contexts are applied to equality-supporting types.
- // Note that this check can only be done after determining which expressions are ghosts.
- foreach (var d in declarations) {
- if (d is IteratorDecl) {
- var iter = (IteratorDecl)d;
- foreach (var p in iter.Ins) {
- if (!p.IsGhost) {
- CheckEqualityTypes_Type(p.tok, p.Type);
- }
- }
- foreach (var p in iter.Outs) {
- if (!p.IsGhost) {
- CheckEqualityTypes_Type(p.tok, p.Type);
- }
- }
- if (iter.Body != null) {
- CheckEqualityTypes_Stmt(iter.Body);
- }
- } else if (d is ClassDecl) {
- var cl = (ClassDecl)d;
- foreach (var member in cl.Members) {
- if (!member.IsGhost) {
- if (member is Field) {
- var f = (Field)member;
- CheckEqualityTypes_Type(f.tok, f.Type);
- } else if (member is Function) {
- var f = (Function)member;
- foreach (var p in f.Formals) {
- if (!p.IsGhost) {
- CheckEqualityTypes_Type(p.tok, p.Type);
- }
- }
- CheckEqualityTypes_Type(f.tok, f.ResultType);
- if (f.Body != null) {
- CheckEqualityTypes(f.Body);
- }
- } else if (member is Method) {
- var m = (Method)member;
- foreach (var p in m.Ins) {
- if (!p.IsGhost) {
- CheckEqualityTypes_Type(p.tok, p.Type);
- }
- }
- foreach (var p in m.Outs) {
- if (!p.IsGhost) {
- CheckEqualityTypes_Type(p.tok, p.Type);
- }
- }
- if (m.Body != null) {
- CheckEqualityTypes_Stmt(m.Body);
- }
- }
- }
- }
- } else if (d is DatatypeDecl) {
- var dt = (DatatypeDecl)d;
- foreach (var ctor in dt.Ctors) {
- foreach (var p in ctor.Formals) {
- if (!p.IsGhost) {
- CheckEqualityTypes_Type(p.tok, p.Type);
- }
- }
- }
- }
- }
- // Check that copredicates are not recursive with non-copredicate functions.
- foreach (var fn in ModuleDefinition.AllFunctions(declarations)) {
- if (fn.Body != null && (fn is CoPredicate || fn.IsRecursive)) {
- CoPredicateChecks(fn.Body, fn, CallingPosition.Positive);
- }
- }
- }
- }
-
- enum TailRecursionStatus
- {
- NotTailRecursive, // contains code that makes the enclosing method body not tail recursive (in way that is supported)
- CanBeFollowedByAnything, // the code just analyzed does not do any recursive calls
- TailCallSpent, // the method body is tail recursive, provided that all code that follows it in the method body is ghost
- }
-
- /// <summary>
- /// Checks if "stmts" can be considered tail recursive, and (provided "reportsError" is true) reports an error if not.
- /// Note, the current implementation is rather conservative in its analysis; upon need, the
- /// algorithm could be improved.
- /// In the current implementation, "enclosingMethod" is not allowed to be a mutually recursive method.
- ///
- /// The incoming value of "tailCall" is not used, but it's nevertheless a 'ref' parameter to allow the
- /// body to return the incoming value or to omit assignments to it.
- /// If the return value is CanBeFollowedByAnything, "tailCall" is unchanged.
- /// If the return value is TailCallSpent, "tailCall" shows one of the calls where the tail call was spent. (Note,
- /// there could be several if the statements have branches.)
- /// If the return value is NoTailRecursive, "tailCall" could be anything. In this case, an error
- /// message has been reported (provided "reportsErrors" is true).
- /// </summary>
- TailRecursionStatus CheckTailRecursive(List<Statement> stmts, Method enclosingMethod, ref CallStmt tailCall, bool reportErrors) {
- Contract.Requires(stmts != null);
- var status = TailRecursionStatus.CanBeFollowedByAnything;
- foreach (var s in stmts) {
- if (!s.IsGhost) {
- if (s is ReturnStmt && ((ReturnStmt)s).hiddenUpdate == null) {
- return status;
- }
- if (status == TailRecursionStatus.TailCallSpent) {
- // a tail call cannot be followed by non-ghost code
- if (reportErrors) {
- Error(tailCall.Tok, "this recursive call is not recognized as being tail recursive, because it is followed by non-ghost code");
- }
- return TailRecursionStatus.NotTailRecursive;
- }
- status = CheckTailRecursive(s, enclosingMethod, ref tailCall, reportErrors);
- if (status == TailRecursionStatus.NotTailRecursive) {
- return status;
- }
- }
- }
- return status;
- }
-
- /// <summary>
- /// See CheckTailRecursive(List Statement, ...), including its description of "tailCall".
- /// In the current implementation, "enclosingMethod" is not allowed to be a mutually recursive method.
- /// </summary>
- TailRecursionStatus CheckTailRecursive(Statement stmt, Method enclosingMethod, ref CallStmt tailCall, bool reportErrors) {
- Contract.Requires(stmt != null && !stmt.IsGhost);
- if (stmt is PrintStmt) {
- } else if (stmt is BreakStmt) {
- } else if (stmt is ReturnStmt) {
- var s = (ReturnStmt)stmt;
- if (s.hiddenUpdate != null) {
- return CheckTailRecursive(s.hiddenUpdate, enclosingMethod, ref tailCall, reportErrors);
- }
- } else if (stmt is AssignStmt) {
- } else if (stmt is VarDecl) {
- } else if (stmt is CallStmt) {
- var s = (CallStmt)stmt;
- if (s.Method == enclosingMethod) {
- // It's a recursive call. It can be considered a tail call only if the LHS of the call are the
- // formal out-parameters of the method
- for (int i = 0; i < s.Lhs.Count; i++) {
- var formal = enclosingMethod.Outs[i];
- if (!formal.IsGhost) {
- var lhs = s.Lhs[i] as IdentifierExpr;
- if (lhs != null && lhs.Var == formal) {
- // all is good
- } else {
- if (reportErrors) {
- Error(s.Tok, "the recursive call to '{0}' is not tail recursive because the actual out-parameter {1} is not the formal out-parameter '{2}'", s.Method.Name, i, formal.Name);
- }
- return TailRecursionStatus.NotTailRecursive;
- }
- }
- }
- tailCall = s;
- return TailRecursionStatus.TailCallSpent;
- }
- } else if (stmt is BlockStmt) {
- var s = (BlockStmt)stmt;
- return CheckTailRecursive(s.Body, enclosingMethod, ref tailCall, reportErrors);
- } else if (stmt is IfStmt) {
- var s = (IfStmt)stmt;
- var stThen = CheckTailRecursive(s.Thn, enclosingMethod, ref tailCall, reportErrors);
- if (stThen == TailRecursionStatus.NotTailRecursive) {
- return stThen;
- }
- var stElse = s.Els == null ? TailRecursionStatus.CanBeFollowedByAnything : CheckTailRecursive(s.Els, enclosingMethod, ref tailCall, reportErrors);
- if (stElse == TailRecursionStatus.NotTailRecursive) {
- return stElse;
- } else if (stThen == TailRecursionStatus.TailCallSpent || stElse == TailRecursionStatus.TailCallSpent) {
- return TailRecursionStatus.TailCallSpent;
- }
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- var status = TailRecursionStatus.CanBeFollowedByAnything;
- foreach (var alt in s.Alternatives) {
- var st = CheckTailRecursive(alt.Body, enclosingMethod, ref tailCall, reportErrors);
- if (st == TailRecursionStatus.NotTailRecursive) {
- return st;
- } else if (st == TailRecursionStatus.TailCallSpent) {
- status = st;
- }
- }
- return status;
- } else if (stmt is WhileStmt) {
- var s = (WhileStmt)stmt;
- var status = CheckTailRecursive(s.Body, enclosingMethod, ref tailCall, reportErrors);
- if (status != TailRecursionStatus.CanBeFollowedByAnything) {
- if (status == TailRecursionStatus.NotTailRecursive) {
- // an error has already been reported
- } else if (reportErrors) {
- Error(tailCall.Tok, "a recursive call inside a loop is not recognized as being a tail call");
- }
- return TailRecursionStatus.NotTailRecursive;
- }
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- foreach (var alt in s.Alternatives) {
- var status = CheckTailRecursive(alt.Body, enclosingMethod, ref tailCall, reportErrors);
- if (status != TailRecursionStatus.CanBeFollowedByAnything) {
- if (status == TailRecursionStatus.NotTailRecursive) {
- // an error has already been reported
- } else if (reportErrors) {
- Error(tailCall.Tok, "a recursive call inside a loop is not recognized as being a tail call");
- }
- return TailRecursionStatus.NotTailRecursive;
- }
- }
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- var status = CheckTailRecursive(s.Body, enclosingMethod, ref tailCall, reportErrors);
- if (status != TailRecursionStatus.CanBeFollowedByAnything) {
- if (status == TailRecursionStatus.NotTailRecursive) {
- // an error has already been reported
- } else if (reportErrors) {
- Error(tailCall.Tok, "a recursive call inside a parallel statement is not a tail call");
- }
- return TailRecursionStatus.NotTailRecursive;
- }
- } else if (stmt is MatchStmt) {
- var s = (MatchStmt)stmt;
- var status = TailRecursionStatus.CanBeFollowedByAnything;
- foreach (var kase in s.Cases) {
- var st = CheckTailRecursive(kase.Body, enclosingMethod, ref tailCall, reportErrors);
- if (st == TailRecursionStatus.NotTailRecursive) {
- return st;
- } else if (st == TailRecursionStatus.TailCallSpent) {
- status = st;
- }
- }
- return status;
- } else if (stmt is AssignSuchThatStmt) {
- } else if (stmt is ConcreteSyntaxStatement) {
- var s = (ConcreteSyntaxStatement)stmt;
- return CheckTailRecursive(s.ResolvedStatements, enclosingMethod, ref tailCall, reportErrors);
- } else {
- Contract.Assert(false); // unexpected statement type
- }
- return TailRecursionStatus.CanBeFollowedByAnything;
- }
-
- enum CallingPosition { Positive, Negative, Neither }
-
- static CallingPosition Invert(CallingPosition cp) {
- switch (cp) {
- case CallingPosition.Positive: return CallingPosition.Negative;
- case CallingPosition.Negative: return CallingPosition.Positive;
- default: return CallingPosition.Neither;
- }
- }
-
- void CoPredicateChecks(Expression expr, Function context, CallingPosition cp) {
- Contract.Requires(expr != null);
- Contract.Requires(context != null);
- if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- CoPredicateChecks(e.Resolved, context, cp);
- return;
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- var moduleCaller = context.EnclosingClass.Module;
- var moduleCallee = e.Function.EnclosingClass.Module;
- if (moduleCaller == moduleCallee && moduleCaller.CallGraph.GetSCCRepresentative(context) == moduleCaller.CallGraph.GetSCCRepresentative(e.Function)) {
- // we're looking at a recursive call
- if (context is CoPredicate) {
- if (!(e.Function is CoPredicate)) {
- Error(e, "a recursive call from a copredicate can go only to other copredicates");
- } else if (cp != CallingPosition.Positive) {
- Error(e, "a recursive copredicate call can only be done in positive positions");
- }
- } else if (e.Function is CoPredicate) {
- Error(e, "a recursive call from a non-copredicate can go only to other non-copredicates");
- }
- }
- // fall through to do the subexpressions
- } else if (expr is UnaryExpr) {
- var e = (UnaryExpr)expr;
- if (e.Op == UnaryExpr.Opcode.Not) {
- CoPredicateChecks(e.E, context, Invert(cp));
- return;
- }
- } else if (expr is BinaryExpr) {
- var e = (BinaryExpr)expr;
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.And:
- case BinaryExpr.ResolvedOpcode.Or:
- CoPredicateChecks(e.E0, context, cp);
- CoPredicateChecks(e.E1, context, cp);
- return;
- case BinaryExpr.ResolvedOpcode.Imp:
- CoPredicateChecks(e.E0, context, Invert(cp));
- CoPredicateChecks(e.E1, context, cp);
- return;
- default:
- break;
- }
- } else if (expr is MatchExpr) {
- var e = (MatchExpr)expr;
- CoPredicateChecks(e.Source, context, CallingPosition.Neither);
- e.Cases.Iter(kase => CoPredicateChecks(kase.Body, context, cp));
- return;
- } else if (expr is ITEExpr) {
- var e = (ITEExpr)expr;
- CoPredicateChecks(e.Test, context, CallingPosition.Neither);
- CoPredicateChecks(e.Thn, context, cp);
- CoPredicateChecks(e.Els, context, cp);
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- CoPredicateChecks(e.Body, context, cp);
- return;
- } else if (expr is QuantifierExpr) {
- var e = (QuantifierExpr)expr;
- if (e.Range != null) {
- CoPredicateChecks(e.Range, context, e is ExistsExpr ? Invert(cp) : cp);
- }
- CoPredicateChecks(e.Term, context, cp);
- return;
- }
- expr.SubExpressions.Iter(ee => CoPredicateChecks(ee, context, CallingPosition.Neither));
- }
-
- void CheckEqualityTypes_Stmt(Statement stmt) {
- Contract.Requires(stmt != null);
- if (stmt.IsGhost) {
- return;
- } else if (stmt is PrintStmt) {
- var s = (PrintStmt)stmt;
- foreach (var arg in s.Args) {
- if (arg.E != null) {
- CheckEqualityTypes(arg.E);
- }
- }
- } else if (stmt is BreakStmt) {
- } else if (stmt is ProduceStmt) {
- var s = (ProduceStmt)stmt;
- if (s.rhss != null) {
- s.rhss.Iter(CheckEqualityTypes_Rhs);
- }
- } else if (stmt is AssignStmt) {
- AssignStmt s = (AssignStmt)stmt;
- CheckEqualityTypes(s.Lhs);
- CheckEqualityTypes_Rhs(s.Rhs);
- } else if (stmt is VarDecl) {
- var s = (VarDecl)stmt;
- s.SubStatements.Iter(CheckEqualityTypes_Stmt);
- } else if (stmt is CallStmt) {
- var s = (CallStmt)stmt;
- CheckEqualityTypes(s.Receiver);
- s.Args.Iter(CheckEqualityTypes);
- s.Lhs.Iter(CheckEqualityTypes);
-
- Contract.Assert(s.Method.TypeArgs.Count <= s.TypeArgumentSubstitutions.Count);
- var i = 0;
- foreach (var formalTypeArg in s.Method.TypeArgs) {
- var actualTypeArg = s.TypeArgumentSubstitutions[formalTypeArg];
- if (formalTypeArg.MustSupportEquality && !actualTypeArg.SupportsEquality) {
- Error(s.Tok, "type parameter {0} ({1}) passed to method {2} must support equality (got {3}){4}", i, formalTypeArg.Name, s.Method.Name, actualTypeArg, TypeEqualityErrorMessageHint(actualTypeArg));
- }
- i++;
- }
- } else if (stmt is BlockStmt) {
- var s = (BlockStmt)stmt;
- s.Body.Iter(CheckEqualityTypes_Stmt);
- } else if (stmt is IfStmt) {
- var s = (IfStmt)stmt;
- if (s.Guard != null) {
- CheckEqualityTypes(s.Guard);
- }
- s.SubStatements.Iter(CheckEqualityTypes_Stmt);
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- foreach (var alt in s.Alternatives) {
- CheckEqualityTypes(alt.Guard);
- alt.Body.Iter(CheckEqualityTypes_Stmt);
- }
- } else if (stmt is WhileStmt) {
- var s = (WhileStmt)stmt;
- if (s.Guard != null) {
- CheckEqualityTypes(s.Guard);
- }
- CheckEqualityTypes_Stmt(s.Body);
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- foreach (var alt in s.Alternatives) {
- CheckEqualityTypes(alt.Guard);
- alt.Body.Iter(CheckEqualityTypes_Stmt);
- }
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- CheckEqualityTypes(s.Range);
- CheckEqualityTypes_Stmt(s.Body);
- } else if (stmt is MatchStmt) {
- var s = (MatchStmt)stmt;
- CheckEqualityTypes(s.Source);
- foreach (MatchCaseStmt mc in s.Cases) {
- mc.Body.Iter(CheckEqualityTypes_Stmt);
- }
- } else if (stmt is ConcreteSyntaxStatement) {
- var s = (ConcreteSyntaxStatement)stmt;
- s.ResolvedStatements.Iter(CheckEqualityTypes_Stmt);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
- }
- }
-
- void CheckEqualityTypes_Rhs(AssignmentRhs rhs) {
- Contract.Requires(rhs != null);
- rhs.SubExpressions.Iter(CheckEqualityTypes);
- rhs.SubStatements.Iter(CheckEqualityTypes_Stmt);
- }
-
- void CheckEqualityTypes(Expression expr) {
- Contract.Requires(expr != null);
- if (expr is BinaryExpr) {
- var e = (BinaryExpr)expr;
- var t0 = e.E0.Type.Normalize();
- var t1 = e.E1.Type.Normalize();
- switch (e.Op) {
- case BinaryExpr.Opcode.Eq:
- case BinaryExpr.Opcode.Neq:
- // First, check a special case: a datatype value (like Nil) that takes no parameters
- var e0 = e.E0.Resolved as DatatypeValue;
- var e1 = e.E1.Resolved as DatatypeValue;
- if (e0 != null && e0.Arguments.Count == 0) {
- // that's cool
- } else if (e1 != null && e1.Arguments.Count == 0) {
- // oh yeah!
- } else if (!t0.SupportsEquality) {
- Error(e.E0, "{0} can only be applied to expressions of types that support equality (got {1}){2}", BinaryExpr.OpcodeString(e.Op), t0, TypeEqualityErrorMessageHint(t0));
- } else if (!t1.SupportsEquality) {
- Error(e.E1, "{0} can only be applied to expressions of types that support equality (got {1}){2}", BinaryExpr.OpcodeString(e.Op), t1, TypeEqualityErrorMessageHint(t1));
- }
- break;
- default:
- switch (e.ResolvedOp) {
- // Note, all operations on sets, multisets, and maps are guaranteed to work because of restrictions placed on how
- // these types are instantiated. (Except: This guarantee does not apply to equality on maps, because the Range type
- // of maps is not restricted, only the Domain type. However, the equality operator is checked above.)
- case BinaryExpr.ResolvedOpcode.InSeq:
- case BinaryExpr.ResolvedOpcode.NotInSeq:
- case BinaryExpr.ResolvedOpcode.Prefix:
- case BinaryExpr.ResolvedOpcode.ProperPrefix:
- if (!t1.SupportsEquality) {
- Error(e.E1, "{0} can only be applied to expressions of sequence types that support equality (got {1}){2}", BinaryExpr.OpcodeString(e.Op), t1, TypeEqualityErrorMessageHint(t1));
- } else if (!t0.SupportsEquality) {
- if (e.ResolvedOp == BinaryExpr.ResolvedOpcode.InSet || e.ResolvedOp == BinaryExpr.ResolvedOpcode.NotInSeq) {
- Error(e.E0, "{0} can only be applied to expressions of types that support equality (got {1}){2}", BinaryExpr.OpcodeString(e.Op), t0, TypeEqualityErrorMessageHint(t0));
- } else {
- Error(e.E0, "{0} can only be applied to expressions of sequence types that support equality (got {1}){2}", BinaryExpr.OpcodeString(e.Op), t0, TypeEqualityErrorMessageHint(t0));
- }
- }
- break;
- default:
- break;
- }
- break;
- }
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- foreach (var bv in e.BoundVars) {
- CheckEqualityTypes_Type(bv.tok, bv.Type);
- }
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- foreach (var bv in e.Vars) {
- CheckEqualityTypes_Type(bv.tok, bv.Type);
- }
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- Contract.Assert(e.Function.TypeArgs.Count <= e.TypeArgumentSubstitutions.Count);
- var i = 0;
- foreach (var formalTypeArg in e.Function.TypeArgs) {
- var actualTypeArg = e.TypeArgumentSubstitutions[formalTypeArg];
- if (formalTypeArg.MustSupportEquality && !actualTypeArg.SupportsEquality) {
- Error(e.tok, "type parameter {0} ({1}) passed to function {2} must support equality (got {3}){4}", i, formalTypeArg.Name, e.Function.Name, actualTypeArg, TypeEqualityErrorMessageHint(actualTypeArg));
- }
- i++;
- }
- }
-
- foreach (var ee in expr.SubExpressions) {
- CheckEqualityTypes(ee);
- }
- }
-
- void CheckEqualityTypes_Type(IToken tok, Type type) {
- Contract.Requires(tok != null);
- Contract.Requires(type != null);
- type = type.Normalize();
- if (type is BasicType) {
- // fine
- } else if (type is SetType) {
- var argType = ((SetType)type).Arg;
- if (!argType.SupportsEquality) {
- Error(tok, "set argument type must support equality (got {0}){1}", argType, TypeEqualityErrorMessageHint(argType));
- }
- CheckEqualityTypes_Type(tok, argType);
-
- } else if (type is MultiSetType) {
- var argType = ((MultiSetType)type).Arg;
- if (!argType.SupportsEquality) {
- Error(tok, "multiset argument type must support equality (got {0}){1}", argType, TypeEqualityErrorMessageHint(argType));
- }
- CheckEqualityTypes_Type(tok, argType);
-
- } else if (type is MapType) {
- var mt = (MapType)type;
- if (!mt.Domain.SupportsEquality) {
- Error(tok, "map domain type must support equality (got {0}){1}", mt.Domain, TypeEqualityErrorMessageHint(mt.Domain));
- }
- CheckEqualityTypes_Type(tok, mt.Domain);
- CheckEqualityTypes_Type(tok, mt.Range);
-
- } else if (type is SeqType) {
- Type argType = ((SeqType)type).Arg;
- CheckEqualityTypes_Type(tok, argType);
-
- } else if (type is UserDefinedType) {
- var udt = (UserDefinedType)type;
- if (udt.ResolvedClass != null) {
- Contract.Assert(udt.ResolvedClass.TypeArgs.Count == udt.TypeArgs.Count);
- var i = 0;
- foreach (var argType in udt.TypeArgs) {
- var formalTypeArg = udt.ResolvedClass.TypeArgs[i];
- if (formalTypeArg.MustSupportEquality && !argType.SupportsEquality) {
- Error(tok, "type parameter {0} ({1}) passed to type {2} must support equality (got {3}){4}", i, formalTypeArg.Name, udt.ResolvedClass.Name, argType, TypeEqualityErrorMessageHint(argType));
- }
- CheckEqualityTypes_Type(tok, argType);
- i++;
- }
- } else {
- Contract.Assert(udt.TypeArgs.Count == 0); // TypeParameters have no type arguments
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- bool CheckTypeInference(Expression e) {
- if (e == null) return false;
- foreach (Expression se in e.SubExpressions) {
- if (CheckTypeInference(se))
- return true;
- }
- if (e.Type is TypeProxy && !(e.Type is InferredTypeProxy || e.Type is ParamTypeProxy || e.Type is ObjectTypeProxy)) {
- Error(e.tok, "the type of this expression is underspecified, but it cannot be an arbitrary type.");
- return true;
- }
- return false;
- }
- void CheckTypeInference(Statement stmt) {
- Contract.Requires(stmt != null);
- if (stmt is PrintStmt) {
- var s = (PrintStmt)stmt;
- s.Args.Iter(arg => CheckTypeInference(arg.E));
- } else if (stmt is BreakStmt) {
- } else if (stmt is ProduceStmt) {
- var s = (ProduceStmt)stmt;
- if (s.rhss != null) {
- s.rhss.Iter(rhs => rhs.SubExpressions.Iter(e => CheckTypeInference(e)));
- }
- } else if (stmt is AssignStmt) {
- AssignStmt s = (AssignStmt)stmt;
- CheckTypeInference(s.Lhs);
- s.Rhs.SubExpressions.Iter(e => { CheckTypeInference(e); });
- } else if (stmt is VarDecl) {
- var s = (VarDecl)stmt;
- s.SubStatements.Iter(CheckTypeInference);
- if (s.Type is TypeProxy && !(s.Type is InferredTypeProxy || s.Type is ParamTypeProxy || s.Type is ObjectTypeProxy)) {
- Error(s.Tok, "the type of this expression is underspecified, but it cannot be an arbitrary type.");
- }
- } else if (stmt is CallStmt) {
- var s = (CallStmt)stmt;
- CheckTypeInference(s.Receiver);
- s.Args.Iter(e => CheckTypeInference(e));
- s.Lhs.Iter(e => CheckTypeInference(e));
- } else if (stmt is BlockStmt) {
- var s = (BlockStmt)stmt;
- s.Body.Iter(CheckTypeInference);
- } else if (stmt is IfStmt) {
- var s = (IfStmt)stmt;
- if (s.Guard != null) {
- CheckTypeInference(s.Guard);
- }
- s.SubStatements.Iter(CheckTypeInference);
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- foreach (var alt in s.Alternatives) {
- CheckTypeInference(alt.Guard);
- alt.Body.Iter(CheckTypeInference);
- }
- } else if (stmt is WhileStmt) {
- var s = (WhileStmt)stmt;
- if (s.Guard != null) {
- CheckTypeInference(s.Guard);
- }
- CheckTypeInference(s.Body);
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- foreach (var alt in s.Alternatives) {
- CheckTypeInference(alt.Guard);
- alt.Body.Iter(CheckTypeInference);
- }
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- CheckTypeInference(s.Range);
- CheckTypeInference(s.Body);
- } else if (stmt is CalcStmt) {
- // NadiaToDo: is this correct?
- var s = (CalcStmt)stmt;
- s.SubExpressions.Iter(e => CheckTypeInference(e));
- s.SubStatements.Iter(CheckTypeInference);
- } else if (stmt is MatchStmt) {
- var s = (MatchStmt)stmt;
- CheckTypeInference(s.Source);
- foreach (MatchCaseStmt mc in s.Cases) {
- mc.Body.Iter(CheckTypeInference);
- }
- } else if (stmt is ConcreteSyntaxStatement) {
- var s = (ConcreteSyntaxStatement)stmt;
- s.ResolvedStatements.Iter(CheckTypeInference);
- } else if (stmt is PredicateStmt) {
- CheckTypeInference(((PredicateStmt)stmt).Expr);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
- }
- }
-
- string TypeEqualityErrorMessageHint(Type argType) {
- Contract.Requires(argType != null);
- var tp = argType.AsTypeParameter;
- if (tp != null) {
- return string.Format(" (perhaps try declaring type parameter '{0}' on line {1} as '{0}(==)', which says it can only be instantiated with a type that supports equality)", tp.Name, tp.tok.line);
- }
- return "";
- }
-
- bool InferRequiredEqualitySupport(TypeParameter tp, Type type) {
- Contract.Requires(tp != null);
- Contract.Requires(type != null);
-
- type = type.Normalize();
- if (type is BasicType) {
- } else if (type is SetType) {
- var st = (SetType)type;
- return st.Arg.AsTypeParameter == tp || InferRequiredEqualitySupport(tp, st.Arg);
- } else if (type is MultiSetType) {
- var ms = (MultiSetType)type;
- return ms.Arg.AsTypeParameter == tp || InferRequiredEqualitySupport(tp, ms.Arg);
- } else if (type is MapType) {
- var mt = (MapType)type;
- return mt.Domain.AsTypeParameter == tp || InferRequiredEqualitySupport(tp, mt.Domain) || InferRequiredEqualitySupport(tp, mt.Range);
- } else if (type is SeqType) {
- var sq = (SeqType)type;
- return InferRequiredEqualitySupport(tp, sq.Arg);
- } else if (type is UserDefinedType) {
- var udt = (UserDefinedType)type;
- if (udt.ResolvedClass != null) {
- var i = 0;
- foreach (var argType in udt.TypeArgs) {
- var formalTypeArg = udt.ResolvedClass.TypeArgs[i];
- if ((formalTypeArg.MustSupportEquality && argType.AsTypeParameter == tp) || InferRequiredEqualitySupport(tp, argType)) {
- return true;
- }
- i++;
- }
- } else {
- Contract.Assert(udt.TypeArgs.Count == 0); // TypeParameters have no type arguments
- }
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- return false;
- }
-
- ClassDecl currentClass;
- Function currentFunction;
- readonly Scope<TypeParameter>/*!*/ allTypeParameters = new Scope<TypeParameter>();
- readonly Scope<IVariable>/*!*/ scope = new Scope<IVariable>();
- Scope<Statement>/*!*/ labeledStatements = new Scope<Statement>();
- List<Statement> loopStack = new List<Statement>(); // the enclosing loops (from which it is possible to break out)
- readonly Dictionary<Statement, bool> inSpecOnlyContext = new Dictionary<Statement, bool>(); // invariant: domain contain union of the domains of "labeledStatements" and "loopStack"
-
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveClassMemberTypes(ClassDecl/*!*/ cl) {
- Contract.Requires(cl != null);
- Contract.Requires(currentClass == null);
- Contract.Ensures(currentClass == null);
-
- currentClass = cl;
- foreach (MemberDecl member in cl.Members) {
- member.EnclosingClass = cl;
- if (member is Field) {
- ResolveType(member.tok, ((Field)member).Type, null, false);
-
- } else if (member is Function) {
- Function f = (Function)member;
- allTypeParameters.PushMarker();
- ResolveTypeParameters(f.TypeArgs, true, f);
- ResolveFunctionSignature(f);
- allTypeParameters.PopMarker();
-
- } else if (member is Method) {
- Method m = (Method)member;
- allTypeParameters.PushMarker();
- ResolveTypeParameters(m.TypeArgs, true, m);
- ResolveMethodSignature(m);
- allTypeParameters.PopMarker();
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member type
- }
- }
- currentClass = null;
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed, and that all types in class members have been resolved
- /// </summary>
- void ResolveClassMemberBodies(ClassDecl cl) {
- Contract.Requires(cl != null);
- Contract.Requires(currentClass == null);
- Contract.Ensures(currentClass == null);
-
- currentClass = cl;
- foreach (MemberDecl member in cl.Members) {
- if (member is Field) {
- ResolveAttributes(member.Attributes, false);
- // nothing more to do
-
- } else if (member is Function) {
- Function f = (Function)member;
- allTypeParameters.PushMarker();
- ResolveTypeParameters(f.TypeArgs, false, f);
- ResolveFunction(f);
- allTypeParameters.PopMarker();
-
- } else if (member is Method) {
- Method m = (Method)member;
- allTypeParameters.PushMarker();
- ResolveTypeParameters(m.TypeArgs, false, m);
- ResolveMethod(m);
- allTypeParameters.PopMarker();
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member type
- }
- }
- currentClass = null;
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveCtorTypes(DatatypeDecl/*!*/ dt, Graph<IndDatatypeDecl/*!*/>/*!*/ dependencies) {
- Contract.Requires(dt != null);
- Contract.Requires(dependencies != null); // more expensive check: Contract.Requires(cce.NonNullElements(dependencies));
- foreach (DatatypeCtor ctor in dt.Ctors) {
-
- ctor.EnclosingDatatype = dt;
-
- allTypeParameters.PushMarker();
- ResolveCtorSignature(ctor, dt.TypeArgs);
- allTypeParameters.PopMarker();
-
- if (dt is IndDatatypeDecl) {
- var idt = (IndDatatypeDecl)dt;
- dependencies.AddVertex(idt);
- foreach (Formal p in ctor.Formals) {
- AddDatatypeDependencyEdge(idt, p.Type, dependencies);
- }
- }
- }
- }
-
- void AddDatatypeDependencyEdge(IndDatatypeDecl/*!*/ dt, Type/*!*/ tp, Graph<IndDatatypeDecl/*!*/>/*!*/ dependencies) {
- Contract.Requires(dt != null);
- Contract.Requires(tp != null);
- Contract.Requires(dependencies != null); // more expensive check: Contract.Requires(cce.NonNullElements(dependencies));
-
- var dependee = tp.AsIndDatatype;
- if (dependee != null && dt.Module == dependee.Module) {
- dependencies.AddEdge((IndDatatypeDecl)dt, dependee);
- foreach (var ta in ((UserDefinedType)tp).TypeArgs) {
- AddDatatypeDependencyEdge(dt, ta, dependencies);
- }
- }
- }
-
- /// <summary>
- /// Check that the SCC of 'startingPoint' can be carved up into stratospheres in such a way that each
- /// datatype has some value that can be constructed from datatypes in lower stratospheres only.
- /// The algorithm used here is quadratic in the number of datatypes in the SCC. Since that number is
- /// deemed to be rather small, this seems okay.
- ///
- /// As a side effect of this checking, the DefaultCtor field is filled in (for every inductive datatype
- /// that passes the check). It may be that several constructors could be used as the default, but
- /// only the first one encountered as recorded. This particular choice is slightly more than an
- /// implementation detail, because it affects how certain cycles among inductive datatypes (having
- /// to do with the types used to instantiate type parameters of datatypes) are used.
- ///
- /// The role of the SCC here is simply to speed up this method. It would still be correct if the
- /// equivalence classes in the given SCC were unions of actual SCC's. In particular, this method
- /// would still work if "dependencies" consisted of one large SCC containing all the inductive
- /// datatypes in the module.
- /// </summary>
- void SccStratosphereCheck(IndDatatypeDecl startingPoint, Graph<IndDatatypeDecl/*!*/>/*!*/ dependencies) {
- Contract.Requires(startingPoint != null);
- Contract.Requires(dependencies != null); // more expensive check: Contract.Requires(cce.NonNullElements(dependencies));
-
- var scc = dependencies.GetSCC(startingPoint);
- int totalCleared = 0;
- while (true) {
- int clearedThisRound = 0;
- foreach (var dt in scc) {
- if (dt.DefaultCtor != null) {
- // previously cleared
- } else if (ComputeDefaultCtor(dt)) {
- Contract.Assert(dt.DefaultCtor != null); // should have been set by the successful call to StratosphereCheck)
- clearedThisRound++;
- totalCleared++;
- }
- }
- if (totalCleared == scc.Count) {
- // all is good
- return;
- } else if (clearedThisRound != 0) {
- // some progress was made, so let's keep going
- } else {
- // whatever is in scc-cleared now failed to pass the test
- foreach (var dt in scc) {
- if (dt.DefaultCtor == null) {
- Error(dt, "because of cyclic dependencies among constructor argument types, no instances of datatype '{0}' can be constructed", dt.Name);
- }
- }
- return;
- }
- }
- }
-
- /// <summary>
- /// Check that the datatype has some constructor all whose argument types can be constructed.
- /// Returns 'true' and sets dt.DefaultCtor if that is the case.
- /// </summary>
- bool ComputeDefaultCtor(IndDatatypeDecl dt) {
- Contract.Requires(dt != null);
- Contract.Requires(dt.DefaultCtor == null); // the intention is that this method be called only when DefaultCtor hasn't already been set
- Contract.Ensures(!Contract.Result<bool>() || dt.DefaultCtor != null);
-
- // Stated differently, check that there is some constuctor where no argument type goes to the same stratum.
- foreach (DatatypeCtor ctor in dt.Ctors) {
- var typeParametersUsed = new List<TypeParameter>();
- foreach (Formal p in ctor.Formals) {
- if (!CheckCanBeConstructed(p.Type, typeParametersUsed)) {
- // the argument type (has a component which) is not yet known to be constructable
- goto NEXT_OUTER_ITERATION;
- }
- }
- // this constructor satisfies the requirements, so the datatype is allowed
- dt.DefaultCtor = ctor;
- dt.TypeParametersUsedInConstructionByDefaultCtor = new bool[dt.TypeArgs.Count];
- for (int i = 0; i < dt.TypeArgs.Count; i++) {
- dt.TypeParametersUsedInConstructionByDefaultCtor[i] = typeParametersUsed.Contains(dt.TypeArgs[i]);
- }
- return true;
- NEXT_OUTER_ITERATION: { }
- }
- // no constructor satisfied the requirements, so this is an illegal datatype declaration
- return false;
- }
-
- bool CheckCanBeConstructed(Type tp, List<TypeParameter> typeParametersUsed) {
- var dependee = tp.AsIndDatatype;
- if (dependee == null) {
- // the type is not an inductive datatype, which means it is always possible to construct it
- if (tp.IsTypeParameter) {
- typeParametersUsed.Add(((UserDefinedType)tp).ResolvedParam);
- }
- return true;
- } else if (dependee.DefaultCtor == null) {
- // the type is an inductive datatype that we don't yet know how to construct
- return false;
- }
- // also check the type arguments of the inductive datatype
- Contract.Assert(((UserDefinedType)tp).TypeArgs.Count == dependee.TypeParametersUsedInConstructionByDefaultCtor.Length);
- var i = 0;
- foreach (var ta in ((UserDefinedType)tp).TypeArgs) { // note, "tp" is known to be a UserDefinedType, because that follows from tp being an inductive datatype
- if (dependee.TypeParametersUsedInConstructionByDefaultCtor[i] && !CheckCanBeConstructed(ta, typeParametersUsed)) {
- return false;
- }
- i++;
- }
- return true;
- }
-
- void DetermineEqualitySupport(IndDatatypeDecl startingPoint, Graph<IndDatatypeDecl/*!*/>/*!*/ dependencies) {
- Contract.Requires(startingPoint != null);
- Contract.Requires(dependencies != null); // more expensive check: Contract.Requires(cce.NonNullElements(dependencies));
-
- var scc = dependencies.GetSCC(startingPoint);
- // First, the simple case: If any parameter of any inductive datatype in the SCC is of a codatatype type, then
- // the whole SCC is incapable of providing the equality operation.
- foreach (var dt in scc) {
- Contract.Assume(dt.EqualitySupport == IndDatatypeDecl.ES.NotYetComputed);
- foreach (var ctor in dt.Ctors) {
- foreach (var arg in ctor.Formals) {
- var anotherIndDt = arg.Type.AsIndDatatype;
- if ((anotherIndDt != null && anotherIndDt.EqualitySupport == IndDatatypeDecl.ES.Never) || arg.Type.IsCoDatatype) {
- // arg.Type is known never to support equality
- // So, go around the entire SCC and record what we learnt
- foreach (var ddtt in scc) {
- ddtt.EqualitySupport = IndDatatypeDecl.ES.Never;
- }
- return; // we are done
- }
- }
- }
- }
-
- // Now for the more involved case: we need to determine which type parameters determine equality support for each datatype in the SCC
- // We start by seeing where each datatype's type parameters are used in a place known to determine equality support.
- bool thingsChanged = false;
- foreach (var dt in scc) {
- if (dt.TypeArgs.Count == 0) {
- // if the datatype has no type parameters, we certainly won't find any type parameters being used in the arguments types to the constructors
- continue;
- }
- foreach (var ctor in dt.Ctors) {
- foreach (var arg in ctor.Formals) {
- var typeArg = arg.Type.AsTypeParameter;
- if (typeArg != null) {
- typeArg.NecessaryForEqualitySupportOfSurroundingInductiveDatatype = true;
- thingsChanged = true;
- } else {
- var otherDt = arg.Type.AsIndDatatype;
- if (otherDt != null && otherDt.EqualitySupport == IndDatatypeDecl.ES.ConsultTypeArguments) { // datatype is in a different SCC
- var otherUdt = (UserDefinedType)arg.Type.Normalize();
- var i = 0;
- foreach (var otherTp in otherDt.TypeArgs) {
- if (otherTp.NecessaryForEqualitySupportOfSurroundingInductiveDatatype) {
- var tp = otherUdt.TypeArgs[i].AsTypeParameter;
- if (tp != null) {
- tp.NecessaryForEqualitySupportOfSurroundingInductiveDatatype = true;
- thingsChanged = true;
- }
- }
- }
- }
- }
- }
- }
- }
- // Then we propagate this information up through the SCC
- while (thingsChanged) {
- thingsChanged = false;
- foreach (var dt in scc) {
- if (dt.TypeArgs.Count == 0) {
- // if the datatype has no type parameters, we certainly won't find any type parameters being used in the arguments types to the constructors
- continue;
- }
- foreach (var ctor in dt.Ctors) {
- foreach (var arg in ctor.Formals) {
- var otherDt = arg.Type.AsIndDatatype;
- if (otherDt != null && otherDt.EqualitySupport == IndDatatypeDecl.ES.NotYetComputed) { // otherDt lives in the same SCC
- var otherUdt = (UserDefinedType)arg.Type.Normalize();
- var i = 0;
- foreach (var otherTp in otherDt.TypeArgs) {
- if (otherTp.NecessaryForEqualitySupportOfSurroundingInductiveDatatype) {
- var tp = otherUdt.TypeArgs[i].AsTypeParameter;
- if (tp != null && !tp.NecessaryForEqualitySupportOfSurroundingInductiveDatatype) {
- tp.NecessaryForEqualitySupportOfSurroundingInductiveDatatype = true;
- thingsChanged = true;
- }
- }
- i++;
- }
- }
- }
- }
- }
- }
- // Now that we have computed the .NecessaryForEqualitySupportOfSurroundingInductiveDatatype values, mark the datatypes as ones
- // where equality support should be checked by looking at the type arguments.
- foreach (var dt in scc) {
- dt.EqualitySupport = IndDatatypeDecl.ES.ConsultTypeArguments;
- }
- }
-
- void ResolveAttributes(Attributes attrs, bool twoState) {
- // order does not matter much for resolution, so resolve them in reverse order
- for (; attrs != null; attrs = attrs.Prev) {
- if (attrs.Args != null) {
- ResolveAttributeArgs(attrs.Args, twoState, true);
- }
- }
- }
-
- void ResolveAttributeArgs(List<Attributes.Argument/*!*/>/*!*/ args, bool twoState, bool allowGhosts) {
- Contract.Requires(args != null);
- foreach (Attributes.Argument aa in args) {
- Contract.Assert(aa != null);
- if (aa.E != null) {
- ResolveExpression(aa.E, twoState);
- if (!allowGhosts) {
- CheckIsNonGhost(aa.E);
- }
- }
- }
- }
-
- void ResolveTypeParameters(List<TypeParameter/*!*/>/*!*/ tparams, bool emitErrors, TypeParameter.ParentType/*!*/ parent) {
- Contract.Requires(tparams != null);
- Contract.Requires(parent != null);
- // push non-duplicated type parameter names
- int index = 0;
- foreach (TypeParameter tp in tparams) {
- Contract.Assert(tp != null);
- if (emitErrors) {
- // we're seeing this TypeParameter for the first time
- tp.Parent = parent;
- tp.PositionalIndex = index;
- }
- if (!allTypeParameters.Push(tp.Name, tp) && emitErrors) {
- Error(tp, "Duplicate type-parameter name: {0}", tp.Name);
- }
- }
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveFunctionSignature(Function f) {
- Contract.Requires(f != null);
- scope.PushMarker();
- if (f.SignatureIsOmitted) {
- Error(f, "function signature can be omitted only in refining functions");
- }
- var defaultTypeArguments = f.TypeArgs.Count == 0 ? f.TypeArgs : null;
- foreach (Formal p in f.Formals) {
- if (!scope.Push(p.Name, p)) {
- Error(p, "Duplicate parameter name: {0}", p.Name);
- }
- ResolveType(p.tok, p.Type, defaultTypeArguments, true);
- }
- ResolveType(f.tok, f.ResultType, defaultTypeArguments, true);
- scope.PopMarker();
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveFunction(Function f) {
- Contract.Requires(f != null);
- Contract.Requires(currentFunction == null);
- Contract.Ensures(currentFunction == null);
- scope.PushMarker();
- currentFunction = f;
- if (f.IsStatic) {
- scope.AllowInstance = false;
- }
- foreach (Formal p in f.Formals) {
- scope.Push(p.Name, p);
- }
- ResolveAttributes(f.Attributes, false);
- foreach (Expression r in f.Req) {
- ResolveExpression(r, false);
- Contract.Assert(r.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(r.Type, Type.Bool)) {
- Error(r, "Precondition must be a boolean (got {0})", r.Type);
- }
- }
- foreach (FrameExpression fr in f.Reads) {
- ResolveFrameExpression(fr, "reads");
- }
- foreach (Expression r in f.Ens) {
- ResolveExpression(r, false); // since this is a function, the postcondition is still a one-state predicate
- Contract.Assert(r.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(r.Type, Type.Bool)) {
- Error(r, "Postcondition must be a boolean (got {0})", r.Type);
- }
- }
- foreach (Expression r in f.Decreases.Expressions) {
- ResolveExpression(r, false);
- // any type is fine
- }
- if (f.Body != null) {
- var prevErrorCount = ErrorCount;
- List<IVariable> matchVarContext = new List<IVariable>(f.Formals);
- ResolveExpression(f.Body, false, matchVarContext);
- if (!f.IsGhost) {
- CheckIsNonGhost(f.Body);
- }
- Contract.Assert(f.Body.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(f.Body.Type, f.ResultType)) {
- Error(f, "Function body type mismatch (expected {0}, got {1})", f.ResultType, f.Body.Type);
- }
- }
- currentFunction = null;
- scope.PopMarker();
- }
-
- void ResolveFrameExpression(FrameExpression fe, string kind) {
- Contract.Requires(fe != null);
- Contract.Requires(kind != null);
- ResolveExpression(fe.E, false);
- Type t = fe.E.Type;
- Contract.Assert(t != null); // follows from postcondition of ResolveExpression
- if (t is CollectionType) {
- t = ((CollectionType)t).Arg;
- }
- if (t is ObjectType) {
- // fine, as long as there's no field name
- if (fe.FieldName != null) {
- Error(fe.E, "type '{0}' does not contain a field named '{1}'", t, fe.FieldName);
- }
- } else if (UserDefinedType.DenotesClass(t) != null) {
- // fine type
- if (fe.FieldName != null) {
- NonProxyType nptype;
- MemberDecl member = ResolveMember(fe.E.tok, t, fe.FieldName, out nptype);
- UserDefinedType ctype = (UserDefinedType)nptype; // correctness of cast follows from the DenotesClass test above
- if (member == null) {
- // error has already been reported by ResolveMember
- } else if (!(member is Field)) {
- Error(fe.E, "member {0} in type {1} does not refer to a field", fe.FieldName, cce.NonNull(ctype).Name);
- } else {
- Contract.Assert(ctype != null && ctype.ResolvedClass != null); // follows from postcondition of ResolveMember
- fe.Field = (Field)member;
- }
- }
- } else {
- Error(fe.E, "a {0}-clause expression must denote an object or a collection of objects (instead got {1})", kind, fe.E.Type);
- }
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveMethodSignature(Method m) {
- Contract.Requires(m != null);
- scope.PushMarker();
- if (m.SignatureIsOmitted) {
- Error(m, "method signature can be omitted only in refining methods");
- }
- var defaultTypeArguments = m.TypeArgs.Count == 0 ? m.TypeArgs : null;
- // resolve in-parameters
- foreach (Formal p in m.Ins) {
- if (!scope.Push(p.Name, p)) {
- Error(p, "Duplicate parameter name: {0}", p.Name);
- }
- ResolveType(p.tok, p.Type, defaultTypeArguments, true);
- }
- // resolve out-parameters
- foreach (Formal p in m.Outs) {
- if (!scope.Push(p.Name, p)) {
- Error(p, "Duplicate parameter name: {0}", p.Name);
- }
- ResolveType(p.tok, p.Type, defaultTypeArguments, true);
- }
- scope.PopMarker();
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveMethod(Method m) {
- Contract.Requires(m != null);
-
- // Add in-parameters to the scope, but don't care about any duplication errors, since they have already been reported
- scope.PushMarker();
- if (m.IsStatic) {
- scope.AllowInstance = false;
- }
- foreach (Formal p in m.Ins) {
- scope.Push(p.Name, p);
- }
-
- // Start resolving specification...
- foreach (MaybeFreeExpression e in m.Req) {
- ResolveExpression(e.E, false);
- Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E.Type, Type.Bool)) {
- Error(e.E, "Precondition must be a boolean (got {0})", e.E.Type);
- }
- }
-
- foreach (FrameExpression fe in m.Mod.Expressions) {
- ResolveFrameExpression(fe, "modifies");
- }
-
- foreach (Expression e in m.Decreases.Expressions) {
- ResolveExpression(e, false);
- // any type is fine
- if (m.IsGhost && e is WildcardExpr) {
- Error(e, "'decreases *' is not allowed on ghost methods");
- }
- }
-
- // Add out-parameters to a new scope that will also include the outermost-level locals of the body
- // Don't care about any duplication errors among the out-parameters, since they have already been reported
- scope.PushMarker();
- foreach (Formal p in m.Outs) {
- scope.Push(p.Name, p);
- }
-
- // attributes are allowed to mention both in- and out-parameters
- ResolveAttributes(m.Attributes, false);
-
- // ... continue resolving specification
- foreach (MaybeFreeExpression e in m.Ens) {
- ResolveExpression(e.E, true);
- Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E.Type, Type.Bool)) {
- Error(e.E, "Postcondition must be a boolean (got {0})", e.E.Type);
- }
- }
-
- // Resolve body
- if (m.Body != null) {
- ResolveBlockStatement(m.Body, m.IsGhost, m);
- }
-
- scope.PopMarker(); // for the out-parameters and outermost-level locals
- scope.PopMarker(); // for the in-parameters
- }
-
- void ResolveCtorSignature(DatatypeCtor ctor, List<TypeParameter> dtTypeArguments) {
- Contract.Requires(ctor != null);
- Contract.Requires(dtTypeArguments != null);
- foreach (Formal p in ctor.Formals) {
- ResolveType(p.tok, p.Type, dtTypeArguments, false);
- }
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveIteratorSignature(IteratorDecl iter) {
- Contract.Requires(iter != null);
- scope.PushMarker();
- if (iter.SignatureIsOmitted) {
- Error(iter, "iterator signature can be omitted only in refining methods");
- }
- var defaultTypeArguments = iter.TypeArgs.Count == 0 ? iter.TypeArgs : null;
- // resolve the types of the parameters
- foreach (var p in iter.Ins.Concat(iter.Outs)) {
- ResolveType(p.tok, p.Type, defaultTypeArguments, true);
- }
- // resolve the types of the added fields (in case some of these types would cause the addition of default type arguments)
- foreach (var p in iter.OutsHistoryFields) {
- ResolveType(p.tok, p.Type, defaultTypeArguments, true);
- }
- scope.PopMarker();
- }
-
- /// <summary>
- /// Assumes type parameters have already been pushed
- /// </summary>
- void ResolveIterator(IteratorDecl iter) {
- Contract.Requires(iter != null);
- Contract.Requires(currentClass == null);
- Contract.Ensures(currentClass == null);
-
- var initialErrorCount = ErrorCount;
-
- // Add in-parameters to the scope, but don't care about any duplication errors, since they have already been reported
- scope.PushMarker();
- scope.AllowInstance = false; // disallow 'this' from use, which means that the special fields and methods added are not accessible in the syntactically given spec
- iter.Ins.ForEach(p => scope.Push(p.Name, p));
-
- // Start resolving specification...
- // we start with the decreases clause, because the _decreases<n> fields were only given type proxies before; we'll know
- // the types only after resolving the decreases clause (and it may be that some of resolution has already seen uses of
- // these fields; so, with no further ado, here we go
- Contract.Assert(iter.Decreases.Expressions.Count == iter.DecreasesFields.Count);
- for (int i = 0; i < iter.Decreases.Expressions.Count; i++) {
- var e = iter.Decreases.Expressions[i];
- ResolveExpression(e, false);
- // any type is fine, but associate this type with the corresponding _decreases<n> field
- var d = iter.DecreasesFields[i];
- if (!UnifyTypes(d.Type, e.Type)) {
- // bummer, there was a use--and a bad use--of the field before, so this won't be the best of error messages
- Error(e, "type of field {0} is {1}, but has been constrained elsewhere to be of type {2}", d.Name, e.Type, d.Type);
- }
- }
- foreach (FrameExpression fe in iter.Reads.Expressions) {
- ResolveFrameExpression(fe, "reads");
- }
- foreach (FrameExpression fe in iter.Modifies.Expressions) {
- ResolveFrameExpression(fe, "modifies");
- }
- foreach (MaybeFreeExpression e in iter.Requires) {
- ResolveExpression(e.E, false);
- Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E.Type, Type.Bool)) {
- Error(e.E, "Precondition must be a boolean (got {0})", e.E.Type);
- }
- }
-
- scope.PopMarker(); // for the in-parameters
-
- // We resolve the rest of the specification in an instance context. So mentions of the in- or yield-parameters
- // get resolved as field dereferences (with an implicit "this")
- scope.PushMarker();
- currentClass = iter;
- Contract.Assert(scope.AllowInstance);
-
- foreach (MaybeFreeExpression e in iter.YieldRequires) {
- ResolveExpression(e.E, false);
- Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E.Type, Type.Bool)) {
- Error(e.E, "Yield precondition must be a boolean (got {0})", e.E.Type);
- }
- }
- foreach (MaybeFreeExpression e in iter.YieldEnsures) {
- ResolveExpression(e.E, true);
- Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E.Type, Type.Bool)) {
- Error(e.E, "Yield postcondition must be a boolean (got {0})", e.E.Type);
- }
- }
- foreach (MaybeFreeExpression e in iter.Ensures) {
- ResolveExpression(e.E, true);
- Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E.Type, Type.Bool)) {
- Error(e.E, "Postcondition must be a boolean (got {0})", e.E.Type);
- }
- }
-
- ResolveAttributes(iter.Attributes, false);
-
- var postSpecErrorCount = ErrorCount;
-
- // Resolve body
- if (iter.Body != null) {
- ResolveBlockStatement(iter.Body, false, iter);
- }
-
- currentClass = null;
- scope.PopMarker(); // pop off the AllowInstance setting
-
- if (postSpecErrorCount == initialErrorCount) {
- CreateIteratorMethodSpecs(iter);
- }
- }
-
- /// <summary>
- /// Assumes the specification of the iterator itself has been successfully resolved.
- /// </summary>
- void CreateIteratorMethodSpecs(IteratorDecl iter) {
- Contract.Requires(iter != null);
-
- // ---------- here comes the constructor ----------
- // same requires clause as the iterator itself
- iter.Member_Init.Req.AddRange(iter.Requires);
- // modifies this;
- iter.Member_Init.Mod.Expressions.Add(new FrameExpression(iter.tok, new ThisExpr(iter.tok), null));
- var ens = iter.Member_Init.Ens;
- foreach (var p in iter.Ins) {
- // ensures this.x == x;
- ens.Add(new MaybeFreeExpression(new BinaryExpr(p.tok, BinaryExpr.Opcode.Eq,
- new FieldSelectExpr(p.tok, new ThisExpr(p.tok), p.Name), new IdentifierExpr(p.tok, p.Name))));
- }
- foreach (var p in iter.OutsHistoryFields) {
- // ensures this.ys == [];
- ens.Add(new MaybeFreeExpression(new BinaryExpr(p.tok, BinaryExpr.Opcode.Eq,
- new FieldSelectExpr(p.tok, new ThisExpr(p.tok), p.Name), new SeqDisplayExpr(p.tok, new List<Expression>()))));
- }
- // ensures this.Valid();
- ens.Add(new MaybeFreeExpression(new FunctionCallExpr(iter.tok, "Valid", new ThisExpr(iter.tok), iter.tok, new List<Expression>())));
- // ensures this._reads == old(ReadsClause);
- var modSetSingletons = new List<Expression>();
- Expression frameSet = new SetDisplayExpr(iter.tok, modSetSingletons);
- foreach (var fr in iter.Reads.Expressions) {
- if (fr.FieldName != null) {
- Error(fr.tok, "sorry, a reads clause for an iterator is not allowed to designate specific fields");
- } else if (fr.E.Type.IsRefType) {
- modSetSingletons.Add(fr.E);
- } else {
- frameSet = new BinaryExpr(fr.tok, BinaryExpr.Opcode.Add, frameSet, fr.E);
- }
- }
- ens.Add(new MaybeFreeExpression(new BinaryExpr(iter.tok, BinaryExpr.Opcode.Eq,
- new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_reads"),
- new OldExpr(iter.tok, frameSet))));
- // ensures this._modifies == old(ModifiesClause);
- modSetSingletons = new List<Expression>();
- frameSet = new SetDisplayExpr(iter.tok, modSetSingletons);
- foreach (var fr in iter.Modifies.Expressions) {
- if (fr.FieldName != null) {
- Error(fr.tok, "sorry, a modifies clause for an iterator is not allowed to designate specific fields");
- } else if (fr.E.Type.IsRefType) {
- modSetSingletons.Add(fr.E);
- } else {
- frameSet = new BinaryExpr(fr.tok, BinaryExpr.Opcode.Add, frameSet, fr.E);
- }
- }
- ens.Add(new MaybeFreeExpression(new BinaryExpr(iter.tok, BinaryExpr.Opcode.Eq,
- new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_modifies"),
- new OldExpr(iter.tok, frameSet))));
- // ensures this._new == {};
- ens.Add(new MaybeFreeExpression(new BinaryExpr(iter.tok, BinaryExpr.Opcode.Eq,
- new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_new"),
- new SetDisplayExpr(iter.tok, new List<Expression>()))));
- // ensures this._decreases0 == old(DecreasesClause[0]) && ...;
- Contract.Assert(iter.Decreases.Expressions.Count == iter.DecreasesFields.Count);
- for (int i = 0; i < iter.Decreases.Expressions.Count; i++) {
- var p = iter.Decreases.Expressions[i];
- ens.Add(new MaybeFreeExpression(new BinaryExpr(iter.tok, BinaryExpr.Opcode.Eq,
- new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), iter.DecreasesFields[i].Name),
- new OldExpr(iter.tok, p))));
- }
-
- // ---------- here comes predicate Valid() ----------
- var reads = iter.Member_Valid.Reads;
- reads.Add(new FrameExpression(iter.tok, new ThisExpr(iter.tok), null)); // reads this;
- reads.Add(new FrameExpression(iter.tok, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_reads"), null)); // reads this._reads;
- reads.Add(new FrameExpression(iter.tok, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_new"), null)); // reads this._new;
-
- // ---------- here comes method MoveNext() ----------
- // requires this.Valid();
- var req = iter.Member_MoveNext.Req;
- req.Add(new MaybeFreeExpression(new FunctionCallExpr(iter.tok, "Valid", new ThisExpr(iter.tok), iter.tok, new List<Expression>())));
- // requires YieldRequires;
- req.AddRange(iter.YieldRequires);
- // modifies this, this._modifies, this._new;
- var mod = iter.Member_MoveNext.Mod.Expressions;
- mod.Add(new FrameExpression(iter.tok, new ThisExpr(iter.tok), null));
- mod.Add(new FrameExpression(iter.tok, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_modifies"), null));
- mod.Add(new FrameExpression(iter.tok, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_new"), null));
- // ensures fresh(_new - old(_new));
- ens = iter.Member_MoveNext.Ens;
- ens.Add(new MaybeFreeExpression(new FreshExpr(iter.tok,
- new BinaryExpr(iter.tok, BinaryExpr.Opcode.Sub,
- new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_new"),
- new OldExpr(iter.tok, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), "_new"))))));
- // ensures more ==> this.Valid();
- ens.Add(new MaybeFreeExpression(new BinaryExpr(iter.tok, BinaryExpr.Opcode.Imp,
- new IdentifierExpr(iter.tok, "more"),
- new FunctionCallExpr(iter.tok, "Valid", new ThisExpr(iter.tok), iter.tok, new List<Expression>()))));
- // ensures this.ys == if more then old(this.ys) + [this.y] else old(this.ys);
- Contract.Assert(iter.OutsFields.Count == iter.OutsHistoryFields.Count);
- for (int i = 0; i < iter.OutsFields.Count; i++) {
- var y = iter.OutsFields[i];
- var ys = iter.OutsHistoryFields[i];
- var ite = new ITEExpr(iter.tok, new IdentifierExpr(iter.tok, "more"),
- new BinaryExpr(iter.tok, BinaryExpr.Opcode.Add,
- new OldExpr(iter.tok, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), ys.Name)),
- new SeqDisplayExpr(iter.tok, new List<Expression>() { new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), y.Name) })),
- new OldExpr(iter.tok, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), ys.Name)));
- var eq = new BinaryExpr(iter.tok, BinaryExpr.Opcode.Eq, new FieldSelectExpr(iter.tok, new ThisExpr(iter.tok), ys.Name), ite);
- ens.Add(new MaybeFreeExpression(eq));
- }
- // ensures more ==> YieldEnsures;
- foreach (var ye in iter.YieldEnsures) {
- ens.Add(new MaybeFreeExpression(
- new BinaryExpr(iter.tok, BinaryExpr.Opcode.Imp, new IdentifierExpr(iter.tok, "more"), ye.E),
- ye.IsFree));
- }
- // ensures !more ==> Ensures;
- foreach (var e in iter.Ensures) {
- ens.Add(new MaybeFreeExpression(new BinaryExpr(iter.tok, BinaryExpr.Opcode.Imp,
- new UnaryExpr(iter.tok, UnaryExpr.Opcode.Not, new IdentifierExpr(iter.tok, "more")),
- e.E),
- e.IsFree));
- }
- // decreases this._decreases0, this._decreases1, ...;
- Contract.Assert(iter.Decreases.Expressions.Count == iter.DecreasesFields.Count);
- for (int i = 0; i < iter.Decreases.Expressions.Count; i++) {
- var p = iter.Decreases.Expressions[i];
- iter.Member_MoveNext.Decreases.Expressions.Add(new FieldSelectExpr(p.tok, new ThisExpr(p.tok), iter.DecreasesFields[i].Name));
- }
- iter.Member_MoveNext.Decreases.Attributes = iter.Decreases.Attributes;
- }
-
- /// <summary>
- /// If ResolveType encounters a type "T" that takes type arguments but wasn't given any, then:
- /// * If "defaultTypeArguments" is non-null and "defaultTypeArgument.Count" equals the number
- /// of type arguments that "T" expects, then use these default type arguments as "T"'s arguments.
- /// * If "allowAutoTypeArguments" is true, then infer "T"'s arguments.
- /// * If "defaultTypeArguments" is non-null AND "allowAutoTypeArguments" is true, then enough
- /// type parameters will be added to "defaultTypeArguments" to have at least as many type
- /// parameters as "T" expects, and then a prefix of the "defaultTypeArguments" will be supplied
- /// as arguments to "T".
- /// </summary>
- public void ResolveType(IToken tok, Type type, List<TypeParameter> defaultTypeArguments, bool allowAutoTypeArguments) {
- Contract.Requires(tok != null);
- Contract.Requires(type != null);
- if (type is BasicType) {
- // nothing to resolve
- } else if (type is MapType) {
- MapType mt = (MapType)type;
- ResolveType(tok, mt.Domain, defaultTypeArguments, allowAutoTypeArguments);
- ResolveType(tok, mt.Range, defaultTypeArguments, allowAutoTypeArguments);
- if (mt.Domain.IsSubrangeType || mt.Range.IsSubrangeType) {
- Error(tok, "sorry, cannot instantiate collection type with a subrange type");
- }
- } else if (type is CollectionType) {
- var t = (CollectionType)type;
- var argType = t.Arg;
- ResolveType(tok, argType, defaultTypeArguments, allowAutoTypeArguments);
- if (argType.IsSubrangeType) {
- Error(tok, "sorry, cannot instantiate collection type with a subrange type");
- }
- } else if (type is UserDefinedType) {
- UserDefinedType t = (UserDefinedType)type;
- foreach (Type tt in t.TypeArgs) {
- ResolveType(t.tok, tt, defaultTypeArguments, allowAutoTypeArguments);
- if (tt.IsSubrangeType) {
- Error(t.tok, "sorry, cannot instantiate type parameter with a subrange type");
- }
- }
- TypeParameter tp = t.Path.Count == 0 ? allTypeParameters.Find(t.Name) : null;
- if (tp != null) {
- if (t.TypeArgs.Count == 0) {
- t.ResolvedParam = tp;
- } else {
- Error(t.tok, "Type parameter expects no type arguments: {0}", t.Name);
- }
- } else if (t.ResolvedClass == null) { // this test is because 'array' is already resolved; TODO: an alternative would be to pre-populate 'classes' with built-in references types like 'array' (and perhaps in the future 'string')
- TopLevelDecl d = null;
-
- int j = 0;
- var sig = moduleInfo;
- while (j < t.Path.Count) {
- if (sig.FindSubmodule(t.Path[j].val, out sig)) {
- j++;
- sig = GetSignature(sig);
- } else {
- Error(t.Path[j], ModuleNotFoundErrorMessage(j, t.Path));
- break;
- }
- }
- if (j == t.Path.Count) {
- if (!sig.TopLevels.TryGetValue(t.Name, out d)) {
- if (j == 0)
- Error(t.tok, "Undeclared top-level type or type parameter: {0} (did you forget to qualify a name?)", t.Name);
- else
- Error(t.tok, "Undeclared type {0} in module {1}", t.Name, t.Path[t.Path.Count - 1].val);
- }
- } else {
- // error has already been reported
- }
-
- if (d == null) {
- // error has been reported above
- } else if (d is AmbiguousTopLevelDecl) {
- Error(t.tok, "The name {0} ambiguously refers to a type in one of the modules {1} (try qualifying the type name with the module name)", t.Name, ((AmbiguousTopLevelDecl)d).ModuleNames());
- } else if (d is ArbitraryTypeDecl) {
- t.ResolvedParam = ((ArbitraryTypeDecl)d).TheType; // resolve like a type parameter
- } else {
- // d is a class or datatype, and it may have type parameters
- t.ResolvedClass = d;
- if (d.TypeArgs.Count != t.TypeArgs.Count && t.TypeArgs.Count == 0) {
- if (allowAutoTypeArguments && defaultTypeArguments == null) {
- // add type arguments that will be inferred
- for (int i = 0; i < d.TypeArgs.Count; i++) {
- t.TypeArgs.Add(new InferredTypeProxy());
- }
- } else if (defaultTypeArguments != null) {
- // add specific type arguments, drawn from defaultTypeArguments (which may have to be extended)
- if (allowAutoTypeArguments) {
- // add to defaultTypeArguments the necessary number of arguments
- for (int i = defaultTypeArguments.Count; i < d.TypeArgs.Count; i++) {
- defaultTypeArguments.Add(new TypeParameter(t.tok, "_T" + i));
- }
- }
- if (allowAutoTypeArguments || d.TypeArgs.Count == defaultTypeArguments.Count) {
- Contract.Assert(d.TypeArgs.Count <= defaultTypeArguments.Count);
- // automatically supply a prefix of the arguments from defaultTypeArguments
- for (int i = 0; i < d.TypeArgs.Count; i++) {
- var typeArg = new UserDefinedType(t.tok, defaultTypeArguments[i].Name, new List<Type>(), null);
- typeArg.ResolvedParam = defaultTypeArguments[i]; // resolve "typeArg" here
- t.TypeArgs.Add(typeArg);
- }
- }
- }
- }
- // defaults and auto have been applied; check if we now have the right number of arguments
- if (d.TypeArgs.Count != t.TypeArgs.Count) {
- Error(t.tok, "Wrong number of type arguments ({0} instead of {1}) passed to class/datatype: {2}", t.TypeArgs.Count, d.TypeArgs.Count, t.Name);
- }
- }
- }
-
- } else if (type is TypeProxy) {
- TypeProxy t = (TypeProxy)type;
- if (t.T != null) {
- ResolveType(tok, t.T, defaultTypeArguments, allowAutoTypeArguments);
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- public bool UnifyTypes(Type a, Type b) {
- Contract.Requires(a != null);
- Contract.Requires(b != null);
- while (a is TypeProxy) {
- TypeProxy proxy = (TypeProxy)a;
- if (proxy.T == null) {
- // merge a and b; to avoid cycles, first get to the bottom of b
- while (b is TypeProxy && ((TypeProxy)b).T != null) {
- b = ((TypeProxy)b).T;
- }
- return AssignProxy(proxy, b);
- } else {
- a = proxy.T;
- }
- }
-
- while (b is TypeProxy) {
- TypeProxy proxy = (TypeProxy)b;
- if (proxy.T == null) {
- // merge a and b (we have already got to the bottom of a)
- return AssignProxy(proxy, a);
- } else {
- b = proxy.T;
- }
- }
-
-#if !NO_CHEAP_OBJECT_WORKAROUND
- if (a is ObjectType || b is ObjectType) { // TODO: remove this temporary hack
- var other = a is ObjectType ? b : a;
- if (other is BoolType || other is IntType || other is SetType || other is SeqType || other.IsDatatype) {
- return false;
- }
- // allow anything else with object; this is BOGUS
- return true;
- }
-#endif
- // Now, a and b are non-proxies and stand for the same things as the original a and b, respectively.
-
- if (a is BoolType) {
- return b is BoolType;
- } else if (a is IntType) {
- return b is IntType;
- } else if (a is ObjectType) {
- return b is ObjectType;
- } else if (a is SetType) {
- return b is SetType && UnifyTypes(((SetType)a).Arg, ((SetType)b).Arg);
- } else if (a is MultiSetType) {
- return b is MultiSetType && UnifyTypes(((MultiSetType)a).Arg, ((MultiSetType)b).Arg);
- } else if (a is MapType) {
- return b is MapType && UnifyTypes(((MapType)a).Domain, ((MapType)b).Domain) && UnifyTypes(((MapType)a).Range, ((MapType)b).Range);
- } else if (a is SeqType) {
- return b is SeqType && UnifyTypes(((SeqType)a).Arg, ((SeqType)b).Arg);
- } else if (a is UserDefinedType) {
- if (!(b is UserDefinedType)) {
- return false;
- }
- UserDefinedType aa = (UserDefinedType)a;
- UserDefinedType bb = (UserDefinedType)b;
- if (aa.ResolvedClass != null && aa.ResolvedClass == bb.ResolvedClass) {
- // these are both resolved class/datatype types
- Contract.Assert(aa.TypeArgs.Count == bb.TypeArgs.Count);
- bool successSoFar = true;
- for (int i = 0; i < aa.TypeArgs.Count; i++) {
- if (!UnifyTypes(aa.TypeArgs[i], bb.TypeArgs[i])) {
- successSoFar = false;
- }
- }
- return successSoFar;
- } else if (aa.ResolvedParam != null && aa.ResolvedParam == bb.ResolvedParam) {
- // these are both resolved type parameters
- Contract.Assert(aa.TypeArgs.Count == 0 && bb.TypeArgs.Count == 0);
- return true;
- } else {
- // something is wrong; either aa or bb wasn't properly resolved, or they don't unify
- return false;
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- bool AssignProxy(TypeProxy proxy, Type t) {
- Contract.Requires(proxy != null);
- Contract.Requires(t != null);
- Contract.Requires(proxy.T == null);
- Contract.Requires(!(t is TypeProxy) || ((TypeProxy)t).T == null);
- //modifies proxy.T, ((TypeProxy)t).T; // might also change t.T if t is a proxy
- Contract.Ensures(Contract.Result<bool>() == (proxy == t || proxy.T != null || (t is TypeProxy && ((TypeProxy)t).T != null)));
- if (proxy == t) {
- // they are already in the same equivalence class
- return true;
-
- } else if (proxy is UnrestrictedTypeProxy) {
- // it's fine to redirect proxy to t (done below)
-
- } else if (t is UnrestrictedTypeProxy) {
- // merge proxy and t by redirecting t to proxy, rather than the other way around
- ((TypeProxy)t).T = proxy;
- return true;
-
- } else if (t is RestrictedTypeProxy) {
- // Both proxy and t are restricted type proxies. To simplify unification, order proxy and t
- // according to their types.
- RestrictedTypeProxy r0 = (RestrictedTypeProxy)proxy;
- RestrictedTypeProxy r1 = (RestrictedTypeProxy)t;
- if (r0.OrderID <= r1.OrderID) {
- return AssignRestrictedProxies(r0, r1);
- } else {
- return AssignRestrictedProxies(r1, r0);
- }
-
- // In the remaining cases, proxy is a restricted proxy and t is a non-proxy
- } else if (proxy is DatatypeProxy) {
- if (t.IsIndDatatype) {
- // all is fine, proxy can be redirected to t
- } else {
- return false;
- }
-
- } else if (proxy is ObjectTypeProxy) {
- if (t is ObjectType || UserDefinedType.DenotesClass(t) != null) {
- // all is fine, proxy can be redirected to t
- } else {
- return false;
- }
-
- } else if (proxy is CollectionTypeProxy) {
- CollectionTypeProxy collProxy = (CollectionTypeProxy)proxy;
- if (t is CollectionType) {
- if (!UnifyTypes(collProxy.Arg, ((CollectionType)t).Arg)) {
- return false;
- }
- } else {
- return false;
- }
-
- } else if (proxy is OperationTypeProxy) {
- OperationTypeProxy opProxy = (OperationTypeProxy)proxy;
- if (t is IntType || t is SetType || t is MultiSetType || (opProxy.AllowSeq && t is SeqType)) {
- // this is the expected case
- } else {
- return false;
- }
-
- } else if (proxy is IndexableTypeProxy) {
- IndexableTypeProxy iProxy = (IndexableTypeProxy)proxy;
- if (t is SeqType) {
- if (!UnifyTypes(iProxy.Arg, ((SeqType)t).Arg)) {
- return false;
- }
- if (!UnifyTypes(iProxy.Domain, Type.Int)) {
- return false;
- }
- } else if (t.IsArrayType && (t.AsArrayType).Dims == 1) {
- Type elType = UserDefinedType.ArrayElementType(t);
- if (!UnifyTypes(iProxy.Arg, elType)) {
- return false;
- }
- if (!UnifyTypes(iProxy.Domain, Type.Int)) {
- return false;
- }
- } else if (t is MapType) {
- if (!UnifyTypes(iProxy.Arg, ((MapType)t).Range)) {
- return false;
- }
- if (!UnifyTypes(iProxy.Domain, ((MapType)t).Domain)) {
- return false;
- }
- } else {
- return false;
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected proxy type
- }
-
- // do the merge, but never infer a subrange type
- if (t is NatType) {
- proxy.T = Type.Int;
- } else {
- proxy.T = t;
- }
- return true;
- }
-
- bool AssignRestrictedProxies(RestrictedTypeProxy a, RestrictedTypeProxy b) {
- Contract.Requires(a != null);
- Contract.Requires(b != null);
- Contract.Requires(a != b);
- Contract.Requires(a.T == null && b.T == null);
- Contract.Requires(a.OrderID <= b.OrderID);
- //modifies a.T, b.T;
- Contract.Ensures(!Contract.Result<bool>() || a.T != null || b.T != null);
-
- if (a is DatatypeProxy) {
- if (b is DatatypeProxy) {
- // all is fine
- a.T = b;
- return true;
- } else {
- return false;
- }
- } else if (a is ObjectTypeProxy) {
- if (b is ObjectTypeProxy) {
- // all is fine
- a.T = b;
- return true;
- } else if (b is IndexableTypeProxy) {
- // the intersection of ObjectTypeProxy and IndexableTypeProxy is an array type
- a.T = builtIns.ArrayType(1, ((IndexableTypeProxy)b).Arg);
- b.T = a.T;
- return true;
- } else {
- return false;
- }
-
- } else if (a is CollectionTypeProxy) {
- if (b is CollectionTypeProxy) {
- a.T = b;
- return UnifyTypes(((CollectionTypeProxy)a).Arg, ((CollectionTypeProxy)b).Arg);
- } else if (b is OperationTypeProxy) {
- if (((OperationTypeProxy)b).AllowSeq) {
- b.T = a; // a is a stronger constraint than b
- } else {
- // a says set<T>,seq<T> and b says int,set; the intersection is set<T>
- a.T = new SetType(((CollectionTypeProxy)a).Arg);
- b.T = a.T;
- }
- return true;
- } else if (b is IndexableTypeProxy) {
- CollectionTypeProxy pa = (CollectionTypeProxy)a;
- IndexableTypeProxy pb = (IndexableTypeProxy)b;
- // a and b could be a map or a sequence
- return true;
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected restricted-proxy type
- }
-
- } else if (a is OperationTypeProxy) {
- OperationTypeProxy pa = (OperationTypeProxy)a;
- if (b is OperationTypeProxy) {
- if (!pa.AllowSeq || ((OperationTypeProxy)b).AllowSeq) {
- b.T = a;
- } else {
- a.T = b; // b has the stronger requirement
- }
- return true;
- } else {
- IndexableTypeProxy pb = (IndexableTypeProxy)b; // cast justification: lse we have unexpected restricted-proxy type
- if (pa.AllowSeq) {
- // strengthen a and b to a sequence type
- b.T = new SeqType(pb.Arg);
- a.T = b.T;
- return true;
- } else {
- return false;
- }
- }
-
- } else if (a is IndexableTypeProxy) {
- Contract.Assert(b is IndexableTypeProxy); // else we have unexpected restricted-proxy type
- a.T = b;
- return UnifyTypes(((IndexableTypeProxy)a).Arg, ((IndexableTypeProxy)b).Arg);
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected restricted-proxy type
- }
- }
-
- /// <summary>
- /// "specContextOnly" means that the statement must be erasable, that is, it should be okay to omit it
- /// at run time. That means it must not have any side effects on non-ghost variables, for example.
- /// </summary>
- public void ResolveStatement(Statement stmt, bool specContextOnly, ICodeContext codeContext) {
- Contract.Requires(stmt != null);
- Contract.Requires(codeContext != null);
- if (stmt is PredicateStmt) {
- PredicateStmt s = (PredicateStmt)stmt;
- ResolveAttributes(s.Attributes, false);
- s.IsGhost = true;
- ResolveExpression(s.Expr, true);
- Contract.Assert(s.Expr.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(s.Expr.Type, Type.Bool)) {
- Error(s.Expr, "condition is expected to be of type {0}, but is {1}", Type.Bool, s.Expr.Type);
- }
-
- } else if (stmt is PrintStmt) {
- PrintStmt s = (PrintStmt)stmt;
- ResolveAttributeArgs(s.Args, false, false);
- if (specContextOnly) {
- Error(stmt, "print statement is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
- }
-
- } else if (stmt is BreakStmt) {
- var s = (BreakStmt)stmt;
- if (s.TargetLabel != null) {
- Statement target = labeledStatements.Find(s.TargetLabel);
- if (target == null) {
- Error(s, "break label is undefined or not in scope: {0}", s.TargetLabel);
- } else {
- s.TargetStmt = target;
- bool targetIsLoop = target is WhileStmt || target is AlternativeLoopStmt;
- if (specContextOnly && !s.TargetStmt.IsGhost && !inSpecOnlyContext[s.TargetStmt]) {
- Error(stmt, "ghost-context break statement is not allowed to break out of non-ghost " + (targetIsLoop ? "loop" : "structure"));
- }
- }
- } else {
- if (loopStack.Count < s.BreakCount) {
- Error(s, "trying to break out of more loop levels than there are enclosing loops");
- } else {
- Statement target = loopStack[loopStack.Count - s.BreakCount];
- if (target.Labels == null) {
- // make sure there is a label, because the compiler and translator will want to see a unique ID
- target.Labels = new LList<Label>(new Label(target.Tok, null), null);
- }
- s.TargetStmt = target;
- if (specContextOnly && !target.IsGhost && !inSpecOnlyContext[target]) {
- Error(stmt, "ghost-context break statement is not allowed to break out of non-ghost loop");
- }
- }
- }
-
- } else if (stmt is ProduceStmt) {
- var kind = stmt is YieldStmt ? "yield" : "return";
- if (stmt is YieldStmt && !(codeContext is IteratorDecl)) {
- Error(stmt, "yield statement is allowed only in iterators");
- } else if (stmt is ReturnStmt && !(codeContext is Method)) {
- Error(stmt, "return statement is allowed only in method");
- } else if (specContextOnly && !codeContext.IsGhost) {
- Error(stmt, "{0} statement is not allowed in this context (because it is guarded by a specification-only expression)", kind);
- }
- var s = (ProduceStmt)stmt;
- if (s.rhss != null) {
- if (codeContext.Outs.Count != s.rhss.Count)
- Error(s, "number of {2} parameters does not match declaration (found {0}, expected {1})", s.rhss.Count, codeContext.Outs.Count, kind);
- else {
- Contract.Assert(s.rhss.Count > 0);
- // Create a hidden update statement using the out-parameter formals, resolve the RHS, and check that the RHS is good.
- List<Expression> formals = new List<Expression>();
- int i = 0;
- foreach (Formal f in codeContext.Outs) {
- IdentifierExpr ident = new IdentifierExpr(f.tok, f.Name);
- ident.Var = f;
- ident.Type = ident.Var.Type;
- Contract.Assert(f.Type != null);
- formals.Add(ident);
- // link the receiver parameter properly:
- if (s.rhss[i] is TypeRhs) {
- var r = (TypeRhs)s.rhss[i];
- if (r.InitCall != null) {
- r.InitCall.Receiver = ident;
- }
- }
- i++;
- }
- s.hiddenUpdate = new UpdateStmt(s.Tok, formals, s.rhss, true);
- // resolving the update statement will check for return/yield statement specifics.
- ResolveStatement(s.hiddenUpdate, specContextOnly, codeContext);
- }
- } else {// this is a regular return/yield statement.
- s.hiddenUpdate = null;
- }
- } else if (stmt is ConcreteUpdateStatement) {
- ResolveUpdateStmt((ConcreteUpdateStatement)stmt, specContextOnly, codeContext);
- } else if (stmt is VarDeclStmt) {
- var s = (VarDeclStmt)stmt;
- foreach (var vd in s.Lhss) {
- ResolveStatement(vd, specContextOnly, codeContext);
- s.ResolvedStatements.Add(vd);
- }
- if (s.Update != null) {
- ResolveStatement(s.Update, specContextOnly, codeContext);
- s.ResolvedStatements.Add(s.Update);
- }
-
- } else if (stmt is AssignStmt) {
- AssignStmt s = (AssignStmt)stmt;
- int prevErrorCount = ErrorCount;
- if (s.Lhs is SeqSelectExpr) {
- ResolveSeqSelectExpr((SeqSelectExpr)s.Lhs, true, false); // allow ghosts for now, tighted up below
- } else {
- ResolveExpression(s.Lhs, true); // allow ghosts for now, tighted up below
- }
- bool lhsResolvedSuccessfully = ErrorCount == prevErrorCount;
- Contract.Assert(s.Lhs.Type != null); // follows from postcondition of ResolveExpression
- // check that LHS denotes a mutable variable or a field
- bool lvalueIsGhost = false;
- var lhs = s.Lhs.Resolved;
- if (lhs is IdentifierExpr) {
- IVariable var = ((IdentifierExpr)lhs).Var;
- if (var == null) {
- // the LHS didn't resolve correctly; some error would already have been reported
- } else {
- lvalueIsGhost = var.IsGhost || codeContext.IsGhost;
- if (!var.IsMutable) {
- Error(stmt, "LHS of assignment must denote a mutable variable or field");
- }
- if (!lvalueIsGhost && specContextOnly) {
- Error(stmt, "Assignment to non-ghost variable is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
- }
- }
- } else if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- if (fse.Field != null) { // otherwise, an error was reported above
- lvalueIsGhost = fse.Field.IsGhost;
- if (!lvalueIsGhost) {
- if (specContextOnly) {
- Error(stmt, "Assignment to non-ghost field is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
- } else {
- // It is now that we wish we would have resolved s.Lhs to not allow ghosts. Too late, so we do
- // the next best thing.
- if (lhsResolvedSuccessfully && UsesSpecFeatures(fse.Obj)) {
- Error(stmt, "Assignment to non-ghost field is not allowed to use specification-only expressions in the receiver");
- }
- }
- }
- if (!fse.Field.IsUserMutable) {
- Error(stmt, "LHS of assignment does not denote a mutable field");
- }
- }
- } else if (lhs is SeqSelectExpr) {
- var slhs = (SeqSelectExpr)lhs;
- // LHS is fine, provided the "sequence" is really an array
- if (lhsResolvedSuccessfully) {
- Contract.Assert(slhs.Seq.Type != null);
- if (!UnifyTypes(slhs.Seq.Type, builtIns.ArrayType(1, new InferredTypeProxy()))) {
- Error(slhs.Seq, "LHS of array assignment must denote an array element (found {0})", slhs.Seq.Type);
- }
- if (specContextOnly) {
- Error(stmt, "Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
- }
- if (!slhs.SelectOne) {
- Error(stmt, "cannot assign to a range of array elements (try the 'parallel' statement)");
- }
- }
-
- } else if (lhs is MultiSelectExpr) {
- if (specContextOnly) {
- Error(stmt, "Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
- }
-
- } else {
- Error(stmt, "LHS of assignment must denote a mutable variable or field");
- }
-
- s.IsGhost = lvalueIsGhost;
- Type lhsType = s.Lhs.Type;
- if (lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne) {
- Error(stmt, "cannot assign to a range of array elements (try the 'parallel' statement)");
- //lhsType = UserDefinedType.ArrayElementType(lhsType);
- } else {
- if (s.Rhs is ExprRhs) {
- ExprRhs rr = (ExprRhs)s.Rhs;
- ResolveExpression(rr.Expr, true);
- if (!lvalueIsGhost) {
- CheckIsNonGhost(rr.Expr);
- }
- Contract.Assert(rr.Expr.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(lhsType, rr.Expr.Type)) {
- Error(stmt, "RHS (of type {0}) not assignable to LHS (of type {1})", rr.Expr.Type, lhsType);
- }
- } else if (s.Rhs is TypeRhs) {
- TypeRhs rr = (TypeRhs)s.Rhs;
- Type t = ResolveTypeRhs(rr, stmt, lvalueIsGhost, codeContext);
- if (!lvalueIsGhost) {
- if (rr.ArrayDimensions != null) {
- foreach (var dim in rr.ArrayDimensions) {
- CheckIsNonGhost(dim);
- }
- }
- if (rr.InitCall != null) {
- foreach (var arg in rr.InitCall.Args) {
- CheckIsNonGhost(arg);
- }
- }
- }
- if (!UnifyTypes(lhsType, t)) {
- Error(stmt, "type {0} is not assignable to LHS (of type {1})", t, lhsType);
- }
- } else if (s.Rhs is HavocRhs) {
- // nothing else to do
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected RHS
- }
- }
- } else if (stmt is VarDecl) {
- VarDecl s = (VarDecl)stmt;
- if (s.OptionalType != null) {
- ResolveType(stmt.Tok, s.OptionalType, null, true);
- s.type = s.OptionalType;
- }
- // now that the declaration has been processed, add the name to the scope
- if (!scope.Push(s.Name, s)) {
- Error(s, "Duplicate local-variable name: {0}", s.Name);
- }
- if (specContextOnly) {
- // a local variable in a specification-only context might as well be ghost
- s.IsGhost = true;
- }
-
- } else if (stmt is CallStmt) {
- CallStmt s = (CallStmt)stmt;
- ResolveCallStmt(s, specContextOnly, codeContext, null);
-
- } else if (stmt is BlockStmt) {
- scope.PushMarker();
- ResolveBlockStatement((BlockStmt)stmt, specContextOnly, codeContext);
- scope.PopMarker();
-
- } else if (stmt is IfStmt) {
- IfStmt s = (IfStmt)stmt;
- bool branchesAreSpecOnly = specContextOnly;
- if (s.Guard != null) {
- int prevErrorCount = ErrorCount;
- ResolveExpression(s.Guard, true);
- Contract.Assert(s.Guard.Type != null); // follows from postcondition of ResolveExpression
- bool successfullyResolved = ErrorCount == prevErrorCount;
- if (!UnifyTypes(s.Guard.Type, Type.Bool)) {
- Error(s.Guard, "condition is expected to be of type {0}, but is {1}", Type.Bool, s.Guard.Type);
- }
- if (!specContextOnly && successfullyResolved) {
- branchesAreSpecOnly = UsesSpecFeatures(s.Guard);
- }
- }
- s.IsGhost = branchesAreSpecOnly;
- ResolveStatement(s.Thn, branchesAreSpecOnly, codeContext);
- if (s.Els != null) {
- ResolveStatement(s.Els, branchesAreSpecOnly, codeContext);
- }
-
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- s.IsGhost = ResolveAlternatives(s.Alternatives, specContextOnly, null, codeContext);
-
- } else if (stmt is WhileStmt) {
- WhileStmt s = (WhileStmt)stmt;
- bool bodyMustBeSpecOnly = specContextOnly;
- if (s.Guard != null) {
- int prevErrorCount = ErrorCount;
- ResolveExpression(s.Guard, true);
- Contract.Assert(s.Guard.Type != null); // follows from postcondition of ResolveExpression
- bool successfullyResolved = ErrorCount == prevErrorCount;
- if (!UnifyTypes(s.Guard.Type, Type.Bool)) {
- Error(s.Guard, "condition is expected to be of type {0}, but is {1}", Type.Bool, s.Guard.Type);
- }
- if (!specContextOnly && successfullyResolved) {
- bodyMustBeSpecOnly = UsesSpecFeatures(s.Guard);
- }
- }
-
- foreach (MaybeFreeExpression inv in s.Invariants) {
- ResolveExpression(inv.E, true);
- Contract.Assert(inv.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(inv.E.Type, Type.Bool)) {
- Error(inv.E, "invariant is expected to be of type {0}, but is {1}", Type.Bool, inv.E.Type);
- }
- }
-
- foreach (Expression e in s.Decreases.Expressions) {
- ResolveExpression(e, true);
- if (bodyMustBeSpecOnly && e is WildcardExpr) {
- Error(e, "'decreases *' is not allowed on ghost loops");
- }
- // any type is fine
- }
-
- if (s.Mod.Expressions != null) {
- foreach (FrameExpression fe in s.Mod.Expressions) {
- ResolveFrameExpression(fe, "modifies");
- }
- }
- s.IsGhost = bodyMustBeSpecOnly;
- loopStack.Add(s); // push
- if (s.Labels == null) { // otherwise, "s" is already in "inSpecOnlyContext" map
- inSpecOnlyContext.Add(s, specContextOnly);
- }
-
- ResolveStatement(s.Body, bodyMustBeSpecOnly, codeContext);
- loopStack.RemoveAt(loopStack.Count - 1); // pop
-
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- s.IsGhost = ResolveAlternatives(s.Alternatives, specContextOnly, s, codeContext);
- foreach (MaybeFreeExpression inv in s.Invariants) {
- ResolveExpression(inv.E, true);
- Contract.Assert(inv.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(inv.E.Type, Type.Bool)) {
- Error(inv.E, "invariant is expected to be of type {0}, but is {1}", Type.Bool, inv.E.Type);
- }
- }
-
- foreach (Expression e in s.Decreases.Expressions) {
- ResolveExpression(e, true);
- if (s.IsGhost && e is WildcardExpr) {
- Error(e, "'decreases *' is not allowed on ghost loops");
- }
- // any type is fine
- }
-
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
-
- int prevErrorCount = ErrorCount;
- scope.PushMarker();
- foreach (BoundVar v in s.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
- ResolveType(v.tok, v.Type, null, true);
- }
- ResolveExpression(s.Range, true);
- Contract.Assert(s.Range.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(s.Range.Type, Type.Bool)) {
- Error(stmt, "range restriction in parallel statement must be of type bool (instead got {0})", s.Range.Type);
- }
- foreach (var ens in s.Ens) {
- ResolveExpression(ens.E, true);
- Contract.Assert(ens.E.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(ens.E.Type, Type.Bool)) {
- Error(ens.E, "ensures condition is expected to be of type {0}, but is {1}", Type.Bool, ens.E.Type);
- }
- }
- // Since the range and postconditions are more likely to infer the types of the bound variables, resolve them
- // first (above) and only then resolve the attributes (below).
- ResolveAttributes(s.Attributes, true);
-
- bool bodyMustBeSpecOnly = specContextOnly || (prevErrorCount == ErrorCount && UsesSpecFeatures(s.Range));
- if (!bodyMustBeSpecOnly && prevErrorCount == ErrorCount) {
- var missingBounds = new List<BoundVar>();
- s.Bounds = DiscoverBounds(s.Tok, s.BoundVars, s.Range, true, false, missingBounds);
- if (missingBounds.Count != 0) {
- bodyMustBeSpecOnly = true;
- }
- }
- s.IsGhost = bodyMustBeSpecOnly;
-
- // clear the labels for the duration of checking the body, because break statements are not allowed to leave a parallel statement
- var prevLblStmts = labeledStatements;
- var prevLoopStack = loopStack;
- labeledStatements = new Scope<Statement>();
- loopStack = new List<Statement>();
- ResolveStatement(s.Body, bodyMustBeSpecOnly, codeContext);
- labeledStatements = prevLblStmts;
- loopStack = prevLoopStack;
- scope.PopMarker();
-
- if (prevErrorCount == ErrorCount) {
- // determine the Kind and run some additional checks on the body
- if (s.Ens.Count != 0) {
- // The only supported kind with ensures clauses is Proof.
- s.Kind = ParallelStmt.ParBodyKind.Proof;
- } else {
- // There are two special cases:
- // * Assign, which is the only kind of the parallel statement that allows a heap update.
- // * Call, which is a single call statement with no side effects or output parameters.
- // The effect of Assign and the postcondition of Call will be seen outside the parallel
- // statement.
- Statement s0 = s.S0;
- if (s0 is AssignStmt) {
- s.Kind = ParallelStmt.ParBodyKind.Assign;
- } else if (s0 is CallStmt) {
- s.Kind = ParallelStmt.ParBodyKind.Call;
- } else {
- s.Kind = ParallelStmt.ParBodyKind.Proof;
- if (s.Body is BlockStmt && ((BlockStmt)s.Body).Body.Count == 0) {
- // an empty statement, so don't produce any warning
- } else {
- Warning(s.Tok, "the conclusion of the body of this parallel statement will not be known outside the parallel statement; consider using an 'ensures' clause");
- }
- }
- }
- CheckParallelBodyRestrictions(s.Body, s.Kind);
- }
-
- } else if (stmt is CalcStmt) {
- var prevErrorCount = ErrorCount;
- CalcStmt s = (CalcStmt)stmt;
- s.IsGhost = true;
- if (s.Lines.Count > 0) {
- var resOp = s.Op;
- var e0 = s.Lines.First();
- ResolveExpression(e0, true);
- Contract.Assert(e0.Type != null); // follows from postcondition of ResolveExpression
- for (int i = 1; i < s.Lines.Count; i++) {
- var e1 = s.Lines[i];
- ResolveExpression(e1, true);
- Contract.Assert(e1.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e0.Type, e1.Type)) {
- Error(e1, "all lines in a calculation must have the same type (got {0} after {1})", e1.Type, e0.Type);
- } else {
- BinaryExpr step;
- var op = s.CustomOps[i - 1];
- if (op == null) {
- step = new BinaryExpr(e0.tok, s.Op, e0, e1); // Use calc-wide operator
- } else {
- step = new BinaryExpr(e0.tok, (BinaryExpr.Opcode)op, e0, e1); // Use custom line operator
- Contract.Assert(CalcStmt.ResultOp(resOp, (BinaryExpr.Opcode)op) != null); // This was checked during parsing
- resOp = (BinaryExpr.Opcode)CalcStmt.ResultOp(resOp, (BinaryExpr.Opcode)op);
- }
- ResolveExpression(step, true);
- s.Steps.Add(step);
- }
- e0 = e1;
- }
- foreach (var h in s.Hints) {
- ResolveStatement(h, true, codeContext);
- }
- if (prevErrorCount == ErrorCount && s.Steps.Count > 0) {
- // do not build Result if there were errors, as it might be ill-typed and produce unnecessary resolution errors
- s.Result = new BinaryExpr(s.Tok, resOp, s.Lines.First(), s.Lines.Last());
- ResolveExpression(s.Result, true);
- }
- }
- Contract.Assert(prevErrorCount != ErrorCount || s.Steps.Count == s.Hints.Count);
- Contract.Assert(prevErrorCount != ErrorCount || s.Steps.Count == 0 || s.Result != null);
-
- } else if (stmt is MatchStmt) {
- MatchStmt s = (MatchStmt)stmt;
- bool bodyIsSpecOnly = specContextOnly;
- int prevErrorCount = ErrorCount;
- ResolveExpression(s.Source, true);
- Contract.Assert(s.Source.Type != null); // follows from postcondition of ResolveExpression
- bool successfullyResolved = ErrorCount == prevErrorCount;
- if (!specContextOnly && successfullyResolved) {
- bodyIsSpecOnly = UsesSpecFeatures(s.Source);
- }
- UserDefinedType sourceType = null;
- DatatypeDecl dtd = null;
- Dictionary<TypeParameter, Type> subst = new Dictionary<TypeParameter, Type>();
- if (s.Source.Type.IsDatatype) {
- sourceType = (UserDefinedType)s.Source.Type;
- dtd = cce.NonNull((DatatypeDecl)sourceType.ResolvedClass);
- }
- Dictionary<string, DatatypeCtor> ctors;
- if (dtd == null) {
- Error(s.Source, "the type of the match source expression must be a datatype (instead found {0})", s.Source.Type);
- ctors = null;
- } else {
- Contract.Assert(sourceType != null); // dtd and sourceType are set together above
- ctors = datatypeCtors[dtd];
- Contract.Assert(ctors != null); // dtd should have been inserted into datatypeCtors during a previous resolution stage
-
- // build the type-parameter substitution map for this use of the datatype
- for (int i = 0; i < dtd.TypeArgs.Count; i++) {
- subst.Add(dtd.TypeArgs[i], sourceType.TypeArgs[i]);
- }
- }
- s.IsGhost = bodyIsSpecOnly;
-
- Dictionary<string, object> memberNamesUsed = new Dictionary<string, object>(); // this is really a set
- foreach (MatchCaseStmt mc in s.Cases) {
- DatatypeCtor ctor = null;
- if (ctors != null) {
- Contract.Assert(dtd != null);
- if (!ctors.TryGetValue(mc.Id, out ctor)) {
- Error(mc.tok, "member {0} does not exist in datatype {1}", mc.Id, dtd.Name);
- } else {
- Contract.Assert(ctor != null); // follows from postcondition of TryGetValue
- mc.Ctor = ctor;
- if (ctor.Formals.Count != mc.Arguments.Count) {
- Error(mc.tok, "member {0} has wrong number of formals (found {1}, expected {2})", mc.Id, mc.Arguments.Count, ctor.Formals.Count);
- }
- if (memberNamesUsed.ContainsKey(mc.Id)) {
- Error(mc.tok, "member {0} appears in more than one case", mc.Id);
- } else {
- memberNamesUsed.Add(mc.Id, null); // add mc.Id to the set of names used
- }
- }
- }
- scope.PushMarker();
- int i = 0;
- foreach (BoundVar v in mc.Arguments) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate parameter name: {0}", v.Name);
- }
- ResolveType(v.tok, v.Type, null, true);
- if (ctor != null && i < ctor.Formals.Count) {
- Formal formal = ctor.Formals[i];
- Type st = SubstType(formal.Type, subst);
- if (!UnifyTypes(v.Type, st)) {
- Error(stmt, "the declared type of the formal ({0}) does not agree with the corresponding type in the constructor's signature ({1})", v.Type, st);
- }
- v.IsGhost = formal.IsGhost;
- }
- i++;
- }
- foreach (Statement ss in mc.Body) {
- ResolveStatement(ss, bodyIsSpecOnly, codeContext);
- }
- scope.PopMarker();
- }
- if (dtd != null && memberNamesUsed.Count != dtd.Ctors.Count) {
- // We could complain about the syntactic omission of constructors:
- // Error(stmt, "match statement does not cover all constructors");
- // but instead we let the verifier do a semantic check.
- // So, for now, record the missing constructors:
- foreach (var ctr in dtd.Ctors) {
- if (!memberNamesUsed.ContainsKey(ctr.Name)) {
- s.MissingCases.Add(ctr);
- }
- }
- Contract.Assert(memberNamesUsed.Count + s.MissingCases.Count == dtd.Ctors.Count);
- }
-
-
- } else if (stmt is SkeletonStatement) {
- var s = (SkeletonStatement)stmt;
- Error(s.Tok, "skeleton statements are allowed only in refining methods");
- // nevertheless, resolve the underlying statement; hey, why not
- if (s.S != null) {
- ResolveStatement(s.S, specContextOnly, codeContext);
- }
- } else {
- Contract.Assert(false); throw new cce.UnreachableException();
- }
- }
- private void ResolveUpdateStmt(ConcreteUpdateStatement s, bool specContextOnly, ICodeContext codeContext) {
- Contract.Requires(codeContext != null);
-
- int prevErrorCount = ErrorCount;
- // First, resolve all LHS's and expression-looking RHS's.
- SeqSelectExpr arrayRangeLhs = null;
- var update = s as UpdateStmt;
-
- foreach (var lhs in s.Lhss) {
- var ec = ErrorCount;
- if (lhs is SeqSelectExpr) {
- var sse = (SeqSelectExpr)lhs;
- ResolveSeqSelectExpr(sse, true, true);
- if (arrayRangeLhs == null && !sse.SelectOne) {
- arrayRangeLhs = sse;
- }
- } else {
- ResolveExpression(lhs, true);
- }
- if (update == null && ec == ErrorCount && specContextOnly && !AssignStmt.LhsIsToGhost(lhs)) {
- Error(lhs, "cannot assign to non-ghost variable in a ghost context");
- }
- }
- IToken firstEffectfulRhs = null;
- CallRhs callRhs = null;
- // Resolve RHSs
- if (update == null) {
- var suchThat = (AssignSuchThatStmt)s; // this is the other possible subclass
- ResolveExpression(suchThat.Expr, true);
- if (suchThat.AssumeToken == null) {
- // to ease in the verification, only allow local variables as LHSs
- var lhsNames = new Dictionary<string, object>();
- foreach (var lhs in s.Lhss) {
- if (!(lhs.Resolved is IdentifierExpr)) {
- Error(lhs, "the assign-such-that statement currently only supports local-variable LHSs");
- } else {
- var ie = (IdentifierExpr)lhs.Resolved;
- if (lhsNames.ContainsKey(ie.Name)) {
- // disallow same LHS.
- Error(s, "duplicate variable in left-hand side of assign-such-that statement: {0}", ie.Name);
- } else {
- lhsNames.Add(ie.Name, null);
- }
- }
- }
- }
- } else {
- foreach (var rhs in update.Rhss) {
- bool isEffectful;
- if (rhs is TypeRhs) {
- var tr = (TypeRhs)rhs;
- ResolveTypeRhs(tr, s, specContextOnly, codeContext);
- isEffectful = tr.InitCall != null;
- } else if (rhs is HavocRhs) {
- isEffectful = false;
- } else {
- var er = (ExprRhs)rhs;
- if (er.Expr is IdentifierSequence) {
- var cRhs = ResolveIdentifierSequence((IdentifierSequence)er.Expr, true, true);
- isEffectful = cRhs != null;
- callRhs = callRhs ?? cRhs;
- } else if (er.Expr is FunctionCallExpr) {
- var cRhs = ResolveFunctionCallExpr((FunctionCallExpr)er.Expr, true, true);
- isEffectful = cRhs != null;
- callRhs = callRhs ?? cRhs;
- } else {
- ResolveExpression(er.Expr, true);
- isEffectful = false;
- }
- }
- if (isEffectful && firstEffectfulRhs == null) {
- firstEffectfulRhs = rhs.Tok;
- }
- }
- }
- // check for duplicate identifiers on the left (full duplication checking for references and the like is done during verification)
- var lhsNameSet = new Dictionary<string, object>();
- foreach (var lhs in s.Lhss) {
- var ie = lhs.Resolved as IdentifierExpr;
- if (ie != null) {
- if (lhsNameSet.ContainsKey(ie.Name)) {
- if (callRhs != null)
- // only allow same LHS in a multiassignment, not a call statement
- Error(s, "duplicate variable in left-hand side of call statement: {0}", ie.Name);
- } else {
- lhsNameSet.Add(ie.Name, null);
- }
- }
- }
- if (update != null) {
- // figure out what kind of UpdateStmt this is
- if (firstEffectfulRhs == null) {
- if (s.Lhss.Count == 0) {
- Contract.Assert(update.Rhss.Count == 1); // guaranteed by the parser
- Error(s, "expected method call, found expression");
- } else if (s.Lhss.Count != update.Rhss.Count) {
- Error(s, "the number of left-hand sides ({0}) and right-hand sides ({1}) must match for a multi-assignment", s.Lhss.Count, update.Rhss.Count);
- } else if (arrayRangeLhs != null && s.Lhss.Count != 1) {
- Error(arrayRangeLhs, "array-range may not be used as LHS of multi-assignment; use separate assignment statements for each array-range assignment");
- } else if (ErrorCount == prevErrorCount) {
- // add the statements here in a sequence, but don't use that sequence later for translation (instead, should translated properly as multi-assignment)
- for (int i = 0; i < s.Lhss.Count; i++) {
- var a = new AssignStmt(s.Tok, s.Lhss[i].Resolved, update.Rhss[i]);
- s.ResolvedStatements.Add(a);
- }
- }
-
- } else if (update.CanMutateKnownState) {
- if (1 < update.Rhss.Count) {
- Error(firstEffectfulRhs, "cannot have effectful parameter in multi-return statement.");
- } else { // it might be ok, if it is a TypeRhs
- Contract.Assert(update.Rhss.Count == 1);
- if (callRhs != null) {
- Error(callRhs.Tok, "cannot have method call in return statement.");
- } else {
- // we have a TypeRhs
- Contract.Assert(update.Rhss[0] is TypeRhs);
- var tr = (TypeRhs)update.Rhss[0];
- Contract.Assert(tr.InitCall != null); // there were effects, so this must have been a call.
- if (tr.CanAffectPreviouslyKnownExpressions) {
- Error(tr.Tok, "can only have initialization methods which modify at most 'this'.");
- }
- var a = new AssignStmt(s.Tok, s.Lhss[0].Resolved, tr);
- s.ResolvedStatements.Add(a);
- }
- }
-
- } else {
- // if there was an effectful RHS, that must be the only RHS
- if (update.Rhss.Count != 1) {
- Error(firstEffectfulRhs, "an update statement is allowed an effectful RHS only if there is just one RHS");
- } else if (arrayRangeLhs != null) {
- Error(arrayRangeLhs, "Assignment to range of array elements must have a simple expression RHS; try using a temporary local variable");
- } else if (callRhs == null) {
- // must be a single TypeRhs
- if (s.Lhss.Count != 1) {
- Contract.Assert(2 <= s.Lhss.Count); // the parser allows 0 Lhss only if the whole statement looks like an expression (not a TypeRhs)
- Error(s.Lhss[1].tok, "the number of left-hand sides ({0}) and right-hand sides ({1}) must match for a multi-assignment", s.Lhss.Count, update.Rhss.Count);
- } else if (ErrorCount == prevErrorCount) {
- var a = new AssignStmt(s.Tok, s.Lhss[0].Resolved, update.Rhss[0]);
- s.ResolvedStatements.Add(a);
- }
- } else {
- // a call statement
- if (ErrorCount == prevErrorCount) {
- var resolvedLhss = new List<Expression>();
- foreach (var ll in s.Lhss) {
- resolvedLhss.Add(ll.Resolved);
- }
- var a = new CallStmt(callRhs.Tok, resolvedLhss, callRhs.Receiver, callRhs.MethodName, callRhs.Args);
- s.ResolvedStatements.Add(a);
- }
- }
- }
- }
-
- foreach (var a in s.ResolvedStatements) {
- ResolveStatement(a, specContextOnly, codeContext);
- }
- s.IsGhost = s.ResolvedStatements.TrueForAll(ss => ss.IsGhost);
- }
-
- bool ResolveAlternatives(List<GuardedAlternative> alternatives, bool specContextOnly, AlternativeLoopStmt loopToCatchBreaks, ICodeContext codeContext) {
- Contract.Requires(alternatives != null);
- Contract.Requires(codeContext != null);
-
- bool isGhost = specContextOnly;
- // first, resolve the guards, which tells us whether or not the entire statement is a ghost statement
- foreach (var alternative in alternatives) {
- int prevErrorCount = ErrorCount;
- ResolveExpression(alternative.Guard, true);
- Contract.Assert(alternative.Guard.Type != null); // follows from postcondition of ResolveExpression
- bool successfullyResolved = ErrorCount == prevErrorCount;
- if (!UnifyTypes(alternative.Guard.Type, Type.Bool)) {
- Error(alternative.Guard, "condition is expected to be of type {0}, but is {1}", Type.Bool, alternative.Guard.Type);
- }
- if (!specContextOnly && successfullyResolved) {
- isGhost = isGhost || UsesSpecFeatures(alternative.Guard);
- }
- }
-
- if (loopToCatchBreaks != null) {
- loopStack.Add(loopToCatchBreaks); // push
- if (loopToCatchBreaks.Labels == null) { // otherwise, "loopToCatchBreak" is already in "inSpecOnlyContext" map
- inSpecOnlyContext.Add(loopToCatchBreaks, specContextOnly);
- }
- }
- foreach (var alternative in alternatives) {
- scope.PushMarker();
- foreach (Statement ss in alternative.Body) {
- ResolveStatement(ss, isGhost, codeContext);
- }
- scope.PopMarker();
- }
- if (loopToCatchBreaks != null) {
- loopStack.RemoveAt(loopStack.Count - 1); // pop
- }
-
- return isGhost;
- }
-
- /// <summary>
- /// Resolves the given call statement.
- /// Assumes all LHSs have already been resolved (and checked for mutability).
- /// </summary>
- void ResolveCallStmt(CallStmt s, bool specContextOnly, ICodeContext codeContext, Type receiverType) {
- Contract.Requires(s != null);
- Contract.Requires(codeContext != null);
- bool isInitCall = receiverType != null;
-
- // resolve receiver
- ResolveReceiver(s.Receiver, true);
- Contract.Assert(s.Receiver.Type != null); // follows from postcondition of ResolveExpression
- if (receiverType == null) {
- receiverType = s.Receiver.Type;
- }
- // resolve the method name
- NonProxyType nptype;
- MemberDecl member = ResolveMember(s.Tok, receiverType, s.MethodName, out nptype);
- Method callee = null;
- if (member == null) {
- // error has already been reported by ResolveMember
- } else if (member is Method) {
- s.Method = (Method)member;
- callee = s.Method;
- if (!isInitCall && callee is Constructor) {
- Error(s, "a constructor is only allowed to be called when an object is being allocated");
- }
- s.IsGhost = callee.IsGhost;
- if (specContextOnly && !callee.IsGhost) {
- Error(s, "only ghost methods can be called from this context");
- }
- } else {
- Error(s, "member {0} in type {1} does not refer to a method", s.MethodName, nptype);
- }
-
- // resolve left-hand sides
- foreach (var lhs in s.Lhs) {
- Contract.Assume(lhs.Type != null); // a sanity check that LHSs have already been resolved
- }
- // resolve arguments
- if (!s.IsGhost && s.Receiver.WasResolved()) {
- CheckIsNonGhost(s.Receiver);
- }
- int j = 0;
- foreach (Expression e in s.Args) {
- bool allowGhost = s.IsGhost || callee == null || callee.Ins.Count <= j || callee.Ins[j].IsGhost;
- ResolveExpression(e, true);
- if (!allowGhost) {
- CheckIsNonGhost(e);
- }
- j++;
- }
-
- if (callee == null) {
- // error has been reported above
- } else if (callee.Ins.Count != s.Args.Count) {
- Error(s, "wrong number of method arguments (got {0}, expected {1})", s.Args.Count, callee.Ins.Count);
- } else if (callee.Outs.Count != s.Lhs.Count) {
- if (isInitCall) {
- Error(s, "a method called as an initialization method must not have any result arguments");
- } else {
- Error(s, "wrong number of method result arguments (got {0}, expected {1})", s.Lhs.Count, callee.Outs.Count);
- }
- } else {
- Contract.Assert(nptype != null); // follows from postcondition of ResolveMember above
- if (isInitCall) {
- if (callee.IsStatic) {
- Error(s.Tok, "a method called as an initialization method must not be 'static'");
- }
- } else if (!callee.IsStatic) {
- if (!scope.AllowInstance && s.Receiver is ThisExpr) {
- // The call really needs an instance, but that instance is given as 'this', which is not
- // available in this context. For more details, see comment in the resolution of a
- // FunctionCallExpr.
- Error(s.Receiver, "'this' is not allowed in a 'static' context");
- } else if (s.Receiver is StaticReceiverExpr) {
- Error(s.Receiver, "call to instance method requires an instance");
- }
- }
-#if !NO_WORK_TO_BE_DONE
- UserDefinedType ctype = (UserDefinedType)nptype; // TODO: get rid of this statement, make this code handle any non-proxy type
-#endif
- // build the type substitution map
- s.TypeArgumentSubstitutions = new Dictionary<TypeParameter, Type>();
- for (int i = 0; i < ctype.TypeArgs.Count; i++) {
- s.TypeArgumentSubstitutions.Add(cce.NonNull(ctype.ResolvedClass).TypeArgs[i], ctype.TypeArgs[i]);
- }
- foreach (TypeParameter p in callee.TypeArgs) {
- s.TypeArgumentSubstitutions.Add(p, new ParamTypeProxy(p));
- }
- // type check the arguments
- for (int i = 0; i < callee.Ins.Count; i++) {
- Type st = SubstType(callee.Ins[i].Type, s.TypeArgumentSubstitutions);
- if (!UnifyTypes(cce.NonNull(s.Args[i].Type), st)) {
- Error(s, "incorrect type of method in-parameter {0} (expected {1}, got {2})", i, st, s.Args[i].Type);
- }
- }
- for (int i = 0; i < callee.Outs.Count; i++) {
- Type st = SubstType(callee.Outs[i].Type, s.TypeArgumentSubstitutions);
- var lhs = s.Lhs[i];
- if (!UnifyTypes(cce.NonNull(lhs.Type), st)) {
- Error(s, "incorrect type of method out-parameter {0} (expected {1}, got {2})", i, st, lhs.Type);
- } else {
- var resolvedLhs = lhs.Resolved;
- if (!specContextOnly && (s.IsGhost || callee.Outs[i].IsGhost)) {
- // LHS must denote a ghost
- if (resolvedLhs is IdentifierExpr) {
- var ll = (IdentifierExpr)resolvedLhs;
- if (!ll.Var.IsGhost) {
- if (ll is AutoGhostIdentifierExpr && ll.Var is VarDecl) {
- // the variable was actually declared in this statement, so auto-declare it as ghost
- ((VarDecl)ll.Var).MakeGhost();
- } else {
- Error(s, "actual out-parameter {0} is required to be a ghost variable", i);
- }
- }
- } else if (resolvedLhs is FieldSelectExpr) {
- var ll = (FieldSelectExpr)resolvedLhs;
- if (!ll.Field.IsGhost) {
- Error(s, "actual out-parameter {0} is required to be a ghost field", i);
- }
- } else {
- // this is an array update, and arrays are always non-ghost
- Error(s, "actual out-parameter {0} is required to be a ghost variable", i);
- }
- }
- // LHS must denote a mutable field.
- if (resolvedLhs is IdentifierExpr) {
- var ll = (IdentifierExpr)resolvedLhs;
- if (!ll.Var.IsMutable) {
- Error(resolvedLhs, "LHS of assignment must denote a mutable variable");
- }
- } else if (resolvedLhs is FieldSelectExpr) {
- var ll = (FieldSelectExpr)resolvedLhs;
- if (!ll.Field.IsUserMutable) {
- Error(resolvedLhs, "LHS of assignment must denote a mutable field");
- }
- }
- }
- }
-
- // Resolution termination check
- ModuleDefinition callerModule = codeContext.EnclosingModule;
- ModuleDefinition calleeModule = ((ICodeContext)callee).EnclosingModule;
- if (callerModule == calleeModule) {
- // intra-module call; this is allowed; add edge in module's call graph
- var caller = codeContext is Method ? (Method)codeContext : ((IteratorDecl)codeContext).Member_MoveNext;
- callerModule.CallGraph.AddEdge(caller, callee);
- } else {
- //Contract.Assert(dependencies.Reaches(callerModule, calleeModule));
- //
- }
- }
- }
-
- void ResolveBlockStatement(BlockStmt blockStmt, bool specContextOnly, ICodeContext codeContext) {
- Contract.Requires(blockStmt != null);
- Contract.Requires(codeContext != null);
-
- foreach (Statement ss in blockStmt.Body) {
- labeledStatements.PushMarker();
- // push labels
- for (var l = ss.Labels; l != null; l = l.Next) {
- var lnode = l.Data;
- Contract.Assert(lnode.Name != null); // LabelNode's with .Label==null are added only during resolution of the break statements with 'stmt' as their target, which hasn't happened yet
- var prev = labeledStatements.Find(lnode.Name);
- if (prev == ss) {
- Error(lnode.Tok, "duplicate label");
- } else if (prev != null) {
- Error(lnode.Tok, "label shadows an enclosing label");
- } else {
- bool b = labeledStatements.Push(lnode.Name, ss);
- Contract.Assert(b); // since we just checked for duplicates, we expect the Push to succeed
- if (l == ss.Labels) { // add it only once
- inSpecOnlyContext.Add(ss, specContextOnly);
- }
- }
- }
- ResolveStatement(ss, specContextOnly, codeContext);
- labeledStatements.PopMarker();
- }
- }
-
- /// <summary>
- /// This method performs some additional checks on the body "stmt" of a parallel statement of kind "kind".
- /// </summary>
- public void CheckParallelBodyRestrictions(Statement stmt, ParallelStmt.ParBodyKind kind) {
- Contract.Requires(stmt != null);
- if (stmt is PredicateStmt) {
- // cool
- } else if (stmt is PrintStmt) {
- Error(stmt, "print statement is not allowed inside a parallel statement");
- } else if (stmt is BreakStmt) {
- // this case is checked already in the first pass through the parallel body, by doing so from an empty set of labeled statements and resetting the loop-stack
- } else if (stmt is ReturnStmt) {
- Error(stmt, "return statement is not allowed inside a parallel statement");
- } else if (stmt is YieldStmt) {
- Error(stmt, "yield statement is not allowed inside a parallel statement");
- } else if (stmt is AssignSuchThatStmt) {
- var s = (AssignSuchThatStmt)stmt;
- foreach (var lhs in s.Lhss) {
- CheckParallelBodyLhs(s.Tok, lhs.Resolved, kind);
- }
- } else if (stmt is ConcreteSyntaxStatement) {
- var s = (ConcreteSyntaxStatement)stmt;
- foreach (var ss in s.ResolvedStatements) {
- CheckParallelBodyRestrictions(ss, kind);
- }
- } else if (stmt is AssignStmt) {
- var s = (AssignStmt)stmt;
- CheckParallelBodyLhs(s.Tok, s.Lhs.Resolved, kind);
- var rhs = s.Rhs; // ExprRhs and HavocRhs are fine, but TypeRhs is not
- if (rhs is TypeRhs) {
- if (kind == ParallelStmt.ParBodyKind.Assign) {
- Error(rhs.Tok, "new allocation not supported in parallel statements");
- } else {
- var t = (TypeRhs)rhs;
- if (t.InitCall != null) {
- CheckParallelBodyRestrictions(t.InitCall, kind);
- }
- }
- } else if (rhs is ExprRhs) {
- var r = ((ExprRhs)rhs).Expr.Resolved;
- if (kind == ParallelStmt.ParBodyKind.Assign && r is UnaryExpr && ((UnaryExpr)r).Op == UnaryExpr.Opcode.SetChoose) {
- Error(r, "set choose operator not supported inside the enclosing parallel statement");
- }
- }
- } else if (stmt is VarDecl) {
- // cool
- } else if (stmt is CallStmt) {
- var s = (CallStmt)stmt;
- foreach (var lhs in s.Lhs) {
- var idExpr = lhs as IdentifierExpr;
- if (idExpr != null) {
- if (scope.ContainsDecl(idExpr.Var)) {
- Error(stmt, "body of parallel statement is attempting to update a variable declared outside the parallel statement");
- }
- } else {
- Error(stmt, "the body of the enclosing parallel statement is not allowed to update heap locations");
- }
- }
- if (!s.Method.IsGhost) {
- // The reason for this restriction is that the compiler is going to omit the parallel statement altogether--it has
- // no effect. However, print effects are not documented, so to make sure that the compiler does not omit a call to
- // a method that prints something, all calls to non-ghost methods are disallowed. (Note, if this restriction
- // is somehow lifted in the future, then it is still necessary to enforce s.Method.Mod.Expressions.Count != 0 for
- // calls to non-ghost methods.)
- Error(s, "the body of the enclosing parallel statement is not allowed to call non-ghost methods");
- }
-
- } else if (stmt is BlockStmt) {
- var s = (BlockStmt)stmt;
- scope.PushMarker();
- foreach (var ss in s.Body) {
- CheckParallelBodyRestrictions(ss, kind);
- }
- scope.PopMarker();
-
- } else if (stmt is IfStmt) {
- var s = (IfStmt)stmt;
- CheckParallelBodyRestrictions(s.Thn, kind);
- if (s.Els != null) {
- CheckParallelBodyRestrictions(s.Els, kind);
- }
-
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- foreach (var alt in s.Alternatives) {
- foreach (var ss in alt.Body) {
- CheckParallelBodyRestrictions(ss, kind);
- }
- }
-
- } else if (stmt is WhileStmt) {
- WhileStmt s = (WhileStmt)stmt;
- CheckParallelBodyRestrictions(s.Body, kind);
-
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- foreach (var alt in s.Alternatives) {
- foreach (var ss in alt.Body) {
- CheckParallelBodyRestrictions(ss, kind);
- }
- }
-
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- switch (s.Kind) {
- case ParallelStmt.ParBodyKind.Assign:
- Error(stmt, "a parallel statement with heap updates is not allowed inside the body of another parallel statement");
- break;
- case ParallelStmt.ParBodyKind.Call:
- case ParallelStmt.ParBodyKind.Proof:
- // these are fine, since they don't update any non-local state
- break;
- default:
- Contract.Assert(false); // unexpected kind
- break;
- }
-
- } else if (stmt is CalcStmt) {
- // cool
- // NadiaTodo: ...I assume because it's always ghost
-
- } else if (stmt is MatchStmt) {
- var s = (MatchStmt)stmt;
- foreach (var kase in s.Cases) {
- foreach (var ss in kase.Body) {
- CheckParallelBodyRestrictions(ss, kind);
- }
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException();
- }
- }
-
- void CheckParallelBodyLhs(IToken tok, Expression lhs, ParallelStmt.ParBodyKind kind) {
- var idExpr = lhs as IdentifierExpr;
- if (idExpr != null) {
- if (scope.ContainsDecl(idExpr.Var)) {
- Error(tok, "body of parallel statement is attempting to update a variable declared outside the parallel statement");
- }
- } else if (kind != ParallelStmt.ParBodyKind.Assign) {
- Error(tok, "the body of the enclosing parallel statement is not allowed to update heap locations");
- }
- }
-
- Type ResolveTypeRhs(TypeRhs rr, Statement stmt, bool specContextOnly, ICodeContext codeContext) {
- Contract.Requires(rr != null);
- Contract.Requires(stmt != null);
- Contract.Requires(codeContext != null);
- Contract.Ensures(Contract.Result<Type>() != null);
-
- if (rr.Type == null) {
- ResolveType(stmt.Tok, rr.EType, null, true);
- if (rr.ArrayDimensions == null) {
- if (!rr.EType.IsRefType) {
- Error(stmt, "new can be applied only to reference types (got {0})", rr.EType);
- } else {
- bool callsConstructor = false;
- if (rr.InitCall != null) {
- ResolveCallStmt(rr.InitCall, specContextOnly, codeContext, rr.EType);
- if (rr.InitCall.Method is Constructor) {
- callsConstructor = true;
- }
- }
- if (!callsConstructor && rr.EType is UserDefinedType) {
- var udt = (UserDefinedType)rr.EType;
- var cl = (ClassDecl)udt.ResolvedClass; // cast is guaranteed by the call to rr.EType.IsRefType above, together with the "rr.EType is UserDefinedType" test
- if (cl.HasConstructor) {
- Error(stmt, "when allocating an object of type '{0}', one of its constructor methods must be called", cl.Name);
- }
- }
- }
- rr.Type = rr.EType;
- } else {
- int i = 0;
- if (rr.EType.IsSubrangeType) {
- Error(stmt, "sorry, cannot instantiate 'array' type with a subrange type");
- }
- foreach (Expression dim in rr.ArrayDimensions) {
- Contract.Assert(dim != null);
- ResolveExpression(dim, true);
- if (!UnifyTypes(dim.Type, Type.Int)) {
- Error(stmt, "new must use an integer expression for the array size (got {0} for index {1})", dim.Type, i);
- }
- i++;
- }
- rr.Type = builtIns.ArrayType(rr.ArrayDimensions.Count, rr.EType);
- }
- }
- return rr.Type;
- }
-
- MemberDecl ResolveMember(IToken tok, Type receiverType, string memberName, out NonProxyType nptype) {
- Contract.Requires(tok != null);
- Contract.Requires(receiverType != null);
- Contract.Requires(memberName != null);
- Contract.Ensures(Contract.Result<MemberDecl>() == null || Contract.ValueAtReturn(out nptype) != null);
-
- nptype = null; // prepare for the worst
- receiverType = receiverType.Normalize();
- if (receiverType is TypeProxy) {
- Error(tok, "type of the receiver is not fully determined at this program point", receiverType);
- return null;
- }
- Contract.Assert(receiverType is NonProxyType); // there are only two kinds of types: proxies and non-proxies
-
- UserDefinedType ctype = UserDefinedType.DenotesClass(receiverType);
- if (ctype != null) {
- var cd = (ClassDecl)ctype.ResolvedClass; // correctness of cast follows from postcondition of DenotesClass
- Contract.Assert(ctype.TypeArgs.Count == cd.TypeArgs.Count); // follows from the fact that ctype was resolved
- MemberDecl member;
- if (!classMembers[cd].TryGetValue(memberName, out member)) {
- Error(tok, "member {0} does not exist in {2} {1}", memberName, ctype.Name, cd is IteratorDecl ? "iterator" : "class");
- return null;
- } else {
- nptype = ctype;
- return member;
- }
- }
-
- DatatypeDecl dtd = receiverType.AsDatatype;
- if (dtd != null) {
- MemberDecl member;
- if (!datatypeMembers[dtd].TryGetValue(memberName, out member)) {
- Error(tok, "member {0} does not exist in datatype {1}", memberName, dtd.Name);
- return null;
- } else {
- nptype = (UserDefinedType)receiverType;
- return member;
- }
- }
-
- Error(tok, "type {0} does not have a member {1}", receiverType, memberName);
- return null;
- }
-
- public static Type SubstType(Type type, Dictionary<TypeParameter/*!*/, Type/*!*/>/*!*/ subst) {
- Contract.Requires(type != null);
- Contract.Requires(cce.NonNullDictionaryAndValues(subst));
- Contract.Ensures(Contract.Result<Type>() != null);
-
- if (type is BasicType) {
- return type;
- } else if (type is MapType) {
- MapType t = (MapType)type;
- return new MapType(SubstType(t.Domain, subst), SubstType(t.Range, subst));
- } else if (type is CollectionType) {
- CollectionType t = (CollectionType)type;
- Type arg = SubstType(t.Arg, subst);
- if (arg == t.Arg) {
- return type;
- } else if (type is SetType) {
- return new SetType(arg);
- } else if (type is MultiSetType) {
- return new MultiSetType(arg);
- } else if (type is SeqType) {
- return new SeqType(arg);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected collection type
- }
- } else if (type is UserDefinedType) {
- UserDefinedType t = (UserDefinedType)type;
- if (t.ResolvedParam != null) {
- Contract.Assert(t.TypeArgs.Count == 0);
- Type s;
- if (subst.TryGetValue(t.ResolvedParam, out s)) {
- return cce.NonNull(s);
- } else {
- return type;
- }
- } else if (t.ResolvedClass != null) {
- List<Type> newArgs = null; // allocate it lazily
- for (int i = 0; i < t.TypeArgs.Count; i++) {
- Type p = t.TypeArgs[i];
- Type s = SubstType(p, subst);
- if (s != p && newArgs == null) {
- // lazily construct newArgs
- newArgs = new List<Type>();
- for (int j = 0; j < i; j++) {
- newArgs.Add(t.TypeArgs[j]);
- }
- }
- if (newArgs != null) {
- newArgs.Add(s);
- }
- }
- if (newArgs == null) {
- // there were no substitutions
- return type;
- } else {
- return new UserDefinedType(t.tok, t.Name, t.ResolvedClass, newArgs);
- }
- } else {
- // there's neither a resolved param nor a resolved class, which means the UserDefinedType wasn't
- // properly resolved; just return it
- return type;
- }
- } else if (type is TypeProxy) {
- TypeProxy t = (TypeProxy)type;
- if (t.T == null) {
- return type;
- } else {
- // bypass the proxy
- return SubstType(t.T, subst);
- }
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- public static UserDefinedType GetThisType(IToken tok, ClassDecl cl) {
- Contract.Requires(tok != null);
- Contract.Requires(cl != null);
- Contract.Ensures(Contract.Result<UserDefinedType>() != null);
-
- List<Type> args = new List<Type>();
- foreach (TypeParameter tp in cl.TypeArgs) {
- args.Add(new UserDefinedType(tok, tp.Name, tp));
- }
- return new UserDefinedType(tok, cl.Name, cl, args);
- }
-
- /// <summary>
- /// Requires "member" to be declared in a class.
- /// </summary>
- public static UserDefinedType GetReceiverType(IToken tok, MemberDecl member) {
- Contract.Requires(tok != null);
- Contract.Requires(member != null);
- Contract.Ensures(Contract.Result<UserDefinedType>() != null);
-
- return GetThisType(tok, (ClassDecl)member.EnclosingClass);
- }
-
- /// <summary>
- /// "twoState" implies that "old" and "fresh" expressions are allowed.
- /// </summary>
- void ResolveExpression(Expression expr, bool twoState) {
- ResolveExpression(expr, twoState, null);
- }
-
- /// <summary>
- /// "matchVarContext" says which variables are allowed to be used as the source expression in a "match" expression;
- /// if null, no "match" expression will be allowed.
- /// </summary>
- void ResolveExpression(Expression expr, bool twoState, List<IVariable> matchVarContext) {
- Contract.Requires(expr != null);
- Contract.Ensures(expr.Type != null);
- if (expr.Type != null) {
- // expression has already been resovled
- return;
- }
-
- // The following cases will resolve the subexpressions and will attempt to assign a type of expr. However, if errors occur
- // and it cannot be determined what the type of expr is, then it is fine to leave expr.Type as null. In that case, the end
- // of this method will assign proxy type to the expression, which reduces the number of error messages that are produced
- // while type checking the rest of the program.
-
- if (expr is ParensExpression) {
- var e = (ParensExpression)expr;
- ResolveExpression(e.E, twoState, matchVarContext); // allow "match" expressions inside e.E if the parenthetic expression had been allowed to be a "match" expression
- e.ResolvedExpression = e.E;
- e.Type = e.E.Type;
-
- } else if (expr is ChainingExpression) {
- var e = (ChainingExpression)expr;
- ResolveExpression(e.E, twoState);
- e.ResolvedExpression = e.E;
- e.Type = e.E.Type;
-
- } else if (expr is IdentifierSequence) {
- var e = (IdentifierSequence)expr;
- ResolveIdentifierSequence(e, twoState, false);
-
- } else if (expr is LiteralExpr) {
- LiteralExpr e = (LiteralExpr)expr;
- if (e.Value == null) {
- e.Type = new ObjectTypeProxy();
- } else if (e.Value is BigInteger) {
- e.Type = Type.Int;
- } else if (e.Value is bool) {
- e.Type = Type.Bool;
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected literal type
- }
-
- } else if (expr is ThisExpr) {
- if (!scope.AllowInstance) {
- Error(expr, "'this' is not allowed in a 'static' context");
- }
- if (currentClass != null) {
- expr.Type = GetThisType(expr.tok, currentClass); // do this regardless of scope.AllowInstance, for better error reporting
- }
-
- } else if (expr is IdentifierExpr) {
- IdentifierExpr e = (IdentifierExpr)expr;
- e.Var = scope.Find(e.Name);
- if (e.Var == null) {
- Error(expr, "Identifier does not denote a local variable, parameter, or bound variable: {0}", e.Name);
- } else {
- expr.Type = e.Var.Type;
- }
-
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- TopLevelDecl d;
- if (!moduleInfo.TopLevels.TryGetValue(dtv.DatatypeName, out d)) {
- Error(expr.tok, "Undeclared datatype: {0}", dtv.DatatypeName);
- } else if (d is AmbiguousTopLevelDecl) {
- Error(expr.tok, "The name {0} ambiguously refers to a type in one of the modules {1}", dtv.DatatypeName, ((AmbiguousTopLevelDecl)d).ModuleNames());
- } else if (!(d is DatatypeDecl)) {
- Error(expr.tok, "Expected datatype: {0}", dtv.DatatypeName);
- } else {
- ResolveDatatypeValue(twoState, dtv, (DatatypeDecl)d);
- }
-
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- Type elementType = new InferredTypeProxy();
- foreach (Expression ee in e.Elements) {
- ResolveExpression(ee, twoState);
- Contract.Assert(ee.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(elementType, ee.Type)) {
- Error(ee, "All elements of display must be of the same type (got {0}, but type of previous elements is {1})", ee.Type, elementType);
- }
- }
- if (expr is SetDisplayExpr) {
- expr.Type = new SetType(elementType);
- } else if (expr is MultiSetDisplayExpr) {
- expr.Type = new MultiSetType(elementType);
- } else {
- expr.Type = new SeqType(elementType);
- }
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- Type domainType = new InferredTypeProxy();
- Type rangeType = new InferredTypeProxy();
- foreach (ExpressionPair p in e.Elements) {
- ResolveExpression(p.A, twoState);
- Contract.Assert(p.A.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(domainType, p.A.Type)) {
- Error(p.A, "All elements of display must be of the same type (got {0}, but type of previous elements is {1})", p.A.Type, domainType);
- }
- ResolveExpression(p.B, twoState);
- Contract.Assert(p.B.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(rangeType, p.B.Type)) {
- Error(p.B, "All elements of display must be of the same type (got {0}, but type of previous elements is {1})", p.B.Type, rangeType);
- }
- }
- expr.Type = new MapType(domainType, rangeType);
- } else if (expr is ExprDotName) {
- var e = (ExprDotName)expr;
- // The following call to ResolveExpression is just preliminary. If it succeeds, it is redone below on the resolved expression. Thus,
- // it's okay to be more lenient here and use coLevel (instead of trying to use CoLevel_Dec(coLevel), which is needed when .Name denotes a
- // destructor for a co-datatype).
- ResolveExpression(e.Obj, twoState);
- Contract.Assert(e.Obj.Type != null); // follows from postcondition of ResolveExpression
- Expression resolved = ResolvePredicateOrField(expr.tok, e.Obj, e.SuffixName);
- if (resolved == null) {
- // error has already been reported by ResolvePredicateOrField
- } else {
- // the following will cause e.Obj to be resolved again, but that's still correct
- e.ResolvedExpression = resolved;
- ResolveExpression(e.ResolvedExpression, twoState);
- e.Type = e.ResolvedExpression.Type;
- }
-
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- ResolveExpression(e.Obj, twoState);
- Contract.Assert(e.Obj.Type != null); // follows from postcondition of ResolveExpression
- NonProxyType nptype;
- MemberDecl member = ResolveMember(expr.tok, e.Obj.Type, e.FieldName, out nptype);
-#if !NO_WORK_TO_BE_DONE
- UserDefinedType ctype = (UserDefinedType)nptype;
-#endif
- if (member == null) {
- // error has already been reported by ResolveMember
- } else if (!(member is Field)) {
- Error(expr, "member {0} in type {1} does not refer to a field", e.FieldName, cce.NonNull(ctype).Name);
- } else {
- Contract.Assert(ctype != null && ctype.ResolvedClass != null); // follows from postcondition of ResolveMember
- e.Field = (Field)member;
- if (e.Obj is StaticReceiverExpr) {
- Error(expr, "a field must be selected via an object, not just a class name");
- }
- // build the type substitution map
- Dictionary<TypeParameter, Type> subst = new Dictionary<TypeParameter, Type>();
- for (int i = 0; i < ctype.TypeArgs.Count; i++) {
- subst.Add(ctype.ResolvedClass.TypeArgs[i], ctype.TypeArgs[i]);
- }
- e.Type = SubstType(e.Field.Type, subst);
- }
-
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- ResolveSeqSelectExpr(e, twoState, true);
-
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
-
- ResolveExpression(e.Array, twoState);
- Contract.Assert(e.Array.Type != null); // follows from postcondition of ResolveExpression
- Type elementType = new InferredTypeProxy();
- if (!UnifyTypes(e.Array.Type, builtIns.ArrayType(e.Indices.Count, elementType))) {
- Error(e.Array, "array selection requires an array{0} (got {1})", e.Indices.Count, e.Array.Type);
- }
- int i = 0;
- foreach (Expression idx in e.Indices) {
- Contract.Assert(idx != null);
- ResolveExpression(idx, twoState);
- Contract.Assert(idx.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(idx.Type, Type.Int)) {
- Error(idx, "array selection requires integer indices (got {0} for index {1})", idx.Type, i);
- }
- i++;
- }
- e.Type = elementType;
-
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- ResolveExpression(e.Seq, twoState);
- Contract.Assert(e.Seq.Type != null); // follows from postcondition of ResolveExpression
- Type elementType = new InferredTypeProxy();
- Type domainType = new InferredTypeProxy();
- Type rangeType = new InferredTypeProxy();
- if (UnifyTypes(e.Seq.Type, new SeqType(elementType))) {
- ResolveExpression(e.Index, twoState);
- Contract.Assert(e.Index.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Index.Type, Type.Int)) {
- Error(e.Index, "sequence update requires integer index (got {0})", e.Index.Type);
- }
- ResolveExpression(e.Value, twoState);
- Contract.Assert(e.Value.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Value.Type, elementType)) {
- Error(e.Value, "sequence update requires the value to have the element type of the sequence (got {0})", e.Value.Type);
- }
- expr.Type = e.Seq.Type;
- } else if (UnifyTypes(e.Seq.Type, new MapType(domainType, rangeType))) {
- ResolveExpression(e.Index, twoState);
- if (!UnifyTypes(e.Index.Type, domainType)) {
- Error(e.Index, "map update requires domain element to be of type {0} (got {1})", domainType, e.Index.Type);
- }
- ResolveExpression(e.Value, twoState);
- if (!UnifyTypes(e.Value.Type, rangeType)) {
- Error(e.Value, "map update requires the value to have the range type {0} (got {1})", rangeType, e.Value.Type);
- }
- expr.Type = e.Seq.Type;
- } else {
- Error(expr, "update requires a sequence or map (got {0})", e.Seq.Type);
- }
-
-
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- ResolveFunctionCallExpr(e, twoState, false);
-
- } else if (expr is OldExpr) {
- OldExpr e = (OldExpr)expr;
- if (!twoState) {
- Error(expr, "old expressions are not allowed in this context");
- }
- ResolveExpression(e.E, twoState, null);
- expr.Type = e.E.Type;
-
- } else if (expr is MultiSetFormingExpr) {
- MultiSetFormingExpr e = (MultiSetFormingExpr)expr;
- ResolveExpression(e.E, twoState);
- if (!UnifyTypes(e.E.Type, new SetType(new InferredTypeProxy())) && !UnifyTypes(e.E.Type, new SeqType(new InferredTypeProxy()))) {
- Error(e.tok, "can only form a multiset from a seq or set.");
- }
- expr.Type = new MultiSetType(((CollectionType)e.E.Type).Arg);
- } else if (expr is FreshExpr) {
- FreshExpr e = (FreshExpr)expr;
- if (!twoState) {
- Error(expr, "fresh expressions are not allowed in this context");
- }
- ResolveExpression(e.E, twoState);
- // the type of e.E must be either an object or a collection of objects
- Type t = e.E.Type;
- Contract.Assert(t != null); // follows from postcondition of ResolveExpression
- if (t is CollectionType) {
- t = ((CollectionType)t).Arg;
- }
- if (t is ObjectType) {
- // fine
- } else if (UserDefinedType.DenotesClass(t) != null) {
- // fine
- } else if (t.IsDatatype) {
- // fine, treat this as the datatype itself.
- } else {
- Error(expr, "the argument of a fresh expression must denote an object or a collection of objects (instead got {0})", e.E.Type);
- }
- expr.Type = Type.Bool;
-
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- ResolveExpression(e.E, twoState);
- Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
- switch (e.Op) {
- case UnaryExpr.Opcode.Not:
- if (!UnifyTypes(e.E.Type, Type.Bool)) {
- Error(expr, "logical negation expects a boolean argument (instead got {0})", e.E.Type);
- }
- expr.Type = Type.Bool;
- break;
- case UnaryExpr.Opcode.SetChoose:
- var elType = new InferredTypeProxy();
- if (!UnifyTypes(e.E.Type, new SetType(elType))) {
- Error(expr, "choose operator expects a set argument (instead got {0})", e.E.Type);
- }
- expr.Type = elType;
- break;
- case UnaryExpr.Opcode.SeqLength:
- if (!UnifyTypes(e.E.Type, new SeqType(new InferredTypeProxy()))) {
- Error(expr, "length operator expects a sequence argument (instead got {0})", e.E.Type);
- }
- expr.Type = Type.Int;
- break;
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected unary operator
- }
-
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- ResolveExpression(e.E0, twoState);
- Contract.Assert(e.E0.Type != null); // follows from postcondition of ResolveExpression
- ResolveExpression(e.E1, twoState);
- Contract.Assert(e.E1.Type != null); // follows from postcondition of ResolveExpression
- switch (e.Op) {
- case BinaryExpr.Opcode.Iff:
- case BinaryExpr.Opcode.Imp:
- case BinaryExpr.Opcode.And:
- case BinaryExpr.Opcode.Or:
- if (!UnifyTypes(e.E0.Type, Type.Bool)) {
- Error(expr, "first argument to {0} must be of type bool (instead got {1})", BinaryExpr.OpcodeString(e.Op), e.E0.Type);
- }
- if (!UnifyTypes(e.E1.Type, Type.Bool)) {
- Error(expr, "second argument to {0} must be of type bool (instead got {1})", BinaryExpr.OpcodeString(e.Op), e.E1.Type);
- }
- expr.Type = Type.Bool;
- break;
-
- case BinaryExpr.Opcode.Eq:
- case BinaryExpr.Opcode.Neq:
- if (!ComparableTypes(e.E0.Type, e.E1.Type)) {
- if (!UnifyTypes(e.E0.Type, e.E1.Type)) {
- Error(expr, "arguments must have the same type (got {0} and {1})", e.E0.Type, e.E1.Type);
- }
- }
- expr.Type = Type.Bool;
- break;
-
- case BinaryExpr.Opcode.Disjoint:
- // TODO: the error messages are backwards from what (ideally) they should be. this is necessary because UnifyTypes can't backtrack.
- if (!UnifyTypes(e.E0.Type, e.E1.Type)) {
- Error(expr, "arguments must have the same type (got {0} and {1})", e.E0.Type, e.E1.Type);
- }
- if (!UnifyTypes(e.E0.Type, new SetType(new InferredTypeProxy())) &&
- !UnifyTypes(e.E0.Type, new MultiSetType(new InferredTypeProxy())) &&
- !UnifyTypes(e.E0.Type, new MapType(new InferredTypeProxy(), new InferredTypeProxy()))) {
- Error(expr, "arguments must be of a [multi]set or map type (got {0})", e.E0.Type);
- }
- expr.Type = Type.Bool;
- break;
-
- case BinaryExpr.Opcode.Lt:
- case BinaryExpr.Opcode.Le:
- case BinaryExpr.Opcode.Add: {
- if (e.Op == BinaryExpr.Opcode.Lt && e.E0.Type.IsIndDatatype) {
- if (!UnifyTypes(e.E1.Type, new DatatypeProxy())) {
- Error(expr, "arguments to rank comparison must be datatypes (instead of {0})", e.E1.Type);
- }
- expr.Type = Type.Bool;
- } else if (e.Op == BinaryExpr.Opcode.Lt && e.E1.Type.IsIndDatatype) {
- if (!UnifyTypes(e.E0.Type, new DatatypeProxy())) {
- Error(expr, "arguments to rank comparison must be datatypes (instead of {0})", e.E0.Type);
- }
- expr.Type = Type.Bool;
- } else {
- bool err = false;
- if (!UnifyTypes(e.E0.Type, new OperationTypeProxy(true))) {
- Error(expr, "arguments to {0} must be int or a collection type (instead got {1})", BinaryExpr.OpcodeString(e.Op), e.E0.Type);
- err = true;
- }
- if (!UnifyTypes(e.E1.Type, e.E0.Type)) {
- Error(expr, "arguments to {0} must have the same type (got {1} and {2})", BinaryExpr.OpcodeString(e.Op), e.E0.Type, e.E1.Type);
- err = true;
- }
- if (e.Op != BinaryExpr.Opcode.Add) {
- expr.Type = Type.Bool;
- } else if (!err) {
- expr.Type = e.E0.Type;
- }
- }
- }
- break;
-
- case BinaryExpr.Opcode.Sub:
- case BinaryExpr.Opcode.Mul:
- case BinaryExpr.Opcode.Gt:
- case BinaryExpr.Opcode.Ge: {
- if (e.Op == BinaryExpr.Opcode.Gt && e.E0.Type.IsIndDatatype) {
- if (!UnifyTypes(e.E1.Type, new DatatypeProxy())) {
- Error(expr, "arguments to rank comparison must be datatypes (instead of {0})", e.E1.Type);
- }
- expr.Type = Type.Bool;
- } else {
- bool err = false;
- if (!UnifyTypes(e.E0.Type, new OperationTypeProxy(false))) {
- Error(expr, "arguments to {0} must be int or a set (instead got {1})", BinaryExpr.OpcodeString(e.Op), e.E0.Type);
- err = true;
- }
- if (!UnifyTypes(e.E1.Type, e.E0.Type)) {
- Error(expr, "arguments to {0} must have the same type (got {1} and {2})", BinaryExpr.OpcodeString(e.Op), e.E0.Type, e.E1.Type);
- err = true;
- }
- if (e.Op == BinaryExpr.Opcode.Gt || e.Op == BinaryExpr.Opcode.Ge) {
- expr.Type = Type.Bool;
- } else if (!err) {
- expr.Type = e.E0.Type;
- }
- }
- }
- break;
-
- case BinaryExpr.Opcode.In:
- case BinaryExpr.Opcode.NotIn:
- if (!UnifyTypes(e.E1.Type, new CollectionTypeProxy(e.E0.Type))) {
- Error(expr, "second argument to \"{0}\" must be a set or sequence with elements of type {1}, or a map with domain {1} (instead got {2})", BinaryExpr.OpcodeString(e.Op), e.E0.Type, e.E1.Type);
- }
- expr.Type = Type.Bool;
- break;
-
- case BinaryExpr.Opcode.Div:
- case BinaryExpr.Opcode.Mod:
- if (!UnifyTypes(e.E0.Type, Type.Int)) {
- Error(expr, "first argument to {0} must be of type int (instead got {1})", BinaryExpr.OpcodeString(e.Op), e.E0.Type);
- }
- if (!UnifyTypes(e.E1.Type, Type.Int)) {
- Error(expr, "second argument to {0} must be of type int (instead got {1})", BinaryExpr.OpcodeString(e.Op), e.E1.Type);
- }
- expr.Type = Type.Int;
- break;
-
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected operator
- }
- e.ResolvedOp = ResolveOp(e.Op, e.E1.Type);
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- foreach (var rhs in e.RHSs) {
- ResolveExpression(rhs, twoState);
- }
- scope.PushMarker();
- if (e.Vars.Count != e.RHSs.Count) {
- Error(expr, "let expression must have same number of bound variables (found {0}) as RHSs (found {1})", e.Vars.Count, e.RHSs.Count);
- }
- int i = 0;
- foreach (var v in e.Vars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate let-variable name: {0}", v.Name);
- }
- ResolveType(v.tok, v.Type, null, true);
- if (i < e.RHSs.Count && !UnifyTypes(v.Type, e.RHSs[i].Type)) {
- Error(e.RHSs[i].tok, "type of RHS ({0}) does not match type of bound variable ({1})", e.RHSs[i].Type, v.Type);
- }
- i++;
- }
- ResolveExpression(e.Body, twoState);
- scope.PopMarker();
- expr.Type = e.Body.Type;
-
- } else if (expr is NamedExpr) {
- var e = (NamedExpr)expr;
- ResolveExpression(e.Body, twoState);
- if (e.Contract != null) ResolveExpression(e.Contract, twoState);
- e.Type = e.Body.Type;
- } else if (expr is QuantifierExpr) {
- QuantifierExpr e = (QuantifierExpr)expr;
- int prevErrorCount = ErrorCount;
- scope.PushMarker();
- foreach (BoundVar v in e.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
- ResolveType(v.tok, v.Type, null, true);
- }
- if (e.Range != null) {
- ResolveExpression(e.Range, twoState);
- Contract.Assert(e.Range.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Range.Type, Type.Bool)) {
- Error(expr, "range of quantifier must be of type bool (instead got {0})", e.Range.Type);
- }
- }
- ResolveExpression(e.Term, twoState);
- Contract.Assert(e.Term.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Term.Type, Type.Bool)) {
- Error(expr, "body of quantifier must be of type bool (instead got {0})", e.Term.Type);
- }
- // Since the body is more likely to infer the types of the bound variables, resolve it
- // first (above) and only then resolve the attributes (below).
- ResolveAttributes(e.Attributes, twoState);
- scope.PopMarker();
- expr.Type = Type.Bool;
-
- if (prevErrorCount == ErrorCount) {
- var missingBounds = new List<BoundVar>();
- e.Bounds = DiscoverBounds(e.tok, e.BoundVars, e.LogicalBody(), e is ExistsExpr, false, missingBounds);
- if (missingBounds.Count != 0) {
- // Report errors here about quantifications that depend on the allocation state.
- var mb = missingBounds;
- if (currentFunction != null) {
- mb = new List<BoundVar>(); // (who cares if we allocate another array; this happens only in the case of a resolution error anyhow)
- foreach (var bv in missingBounds) {
- if (bv.Type.IsRefType) {
- Error(expr, "a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of '{0}'", bv.Name);
- } else {
- mb.Add(bv);
- }
- }
- }
- if (mb.Count != 0) {
- e.MissingBounds = mb;
- }
- }
- }
-
- } else if (expr is SetComprehension) {
- var e = (SetComprehension)expr;
- int prevErrorCount = ErrorCount;
- scope.PushMarker();
- foreach (BoundVar v in e.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
- ResolveType(v.tok, v.Type, null, true);
- }
- ResolveExpression(e.Range, twoState);
- Contract.Assert(e.Range.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Range.Type, Type.Bool)) {
- Error(expr, "range of comprehension must be of type bool (instead got {0})", e.Range.Type);
- }
- ResolveExpression(e.Term, twoState);
- Contract.Assert(e.Term.Type != null); // follows from postcondition of ResolveExpression
-
- ResolveAttributes(e.Attributes, twoState);
- scope.PopMarker();
- expr.Type = new SetType(e.Term.Type);
-
- if (prevErrorCount == ErrorCount) {
- var missingBounds = new List<BoundVar>();
- e.Bounds = DiscoverBounds(e.tok, e.BoundVars, e.Range, true, false, missingBounds);
- if (missingBounds.Count != 0) {
- e.MissingBounds = missingBounds;
- foreach (var bv in e.MissingBounds) {
- Error(expr, "a set comprehension must produce a finite set, but Dafny's heuristics can't figure out how to produce a bounded set of values for '{0}'", bv.Name);
- }
- }
- }
-
- } else if (expr is MapComprehension) {
- var e = (MapComprehension)expr;
- int prevErrorCount = ErrorCount;
- scope.PushMarker();
- if (e.BoundVars.Count != 1) {
- Error(e.tok, "a map comprehension must have exactly one bound variable.");
- }
- foreach (BoundVar v in e.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
- ResolveType(v.tok, v.Type, null, true);
- }
- ResolveExpression(e.Range, twoState);
- Contract.Assert(e.Range.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Range.Type, Type.Bool)) {
- Error(expr, "range of comprehension must be of type bool (instead got {0})", e.Range.Type);
- }
- ResolveExpression(e.Term, twoState);
- Contract.Assert(e.Term.Type != null); // follows from postcondition of ResolveExpression
-
- ResolveAttributes(e.Attributes, twoState);
- scope.PopMarker();
- expr.Type = new MapType(e.BoundVars[0].Type, e.Term.Type);
-
- if (prevErrorCount == ErrorCount) {
- var missingBounds = new List<BoundVar>();
- e.Bounds = DiscoverBounds(e.tok, e.BoundVars, e.Range, true, false, missingBounds);
- if (missingBounds.Count != 0) {
- e.MissingBounds = missingBounds;
- foreach (var bv in e.MissingBounds) {
- Error(expr, "a map comprehension must produce a finite domain, but Dafny's heuristics can't figure out how to produce a bounded set of values for '{0}'", bv.Name);
- }
- }
- }
-
- } else if (expr is WildcardExpr) {
- expr.Type = new SetType(new ObjectType());
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- ResolveExpression(e.Guard, twoState);
- Contract.Assert(e.Guard.Type != null); // follows from postcondition of ResolveExpression
- ResolveExpression(e.Body, twoState);
- Contract.Assert(e.Body.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Guard.Type, Type.Bool)) {
- Error(expr, "guard condition in {0} expression must be a boolean (instead got {1})", e.Kind, e.Guard.Type);
- }
- expr.Type = e.Body.Type;
-
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- ResolveExpression(e.Test, twoState);
- Contract.Assert(e.Test.Type != null); // follows from postcondition of ResolveExpression
- ResolveExpression(e.Thn, twoState);
- Contract.Assert(e.Thn.Type != null); // follows from postcondition of ResolveExpression
- ResolveExpression(e.Els, twoState);
- Contract.Assert(e.Els.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.Test.Type, Type.Bool)) {
- Error(expr, "guard condition in if-then-else expression must be a boolean (instead got {0})", e.Test.Type);
- }
- if (UnifyTypes(e.Thn.Type, e.Els.Type)) {
- expr.Type = e.Thn.Type;
- } else {
- Error(expr, "the two branches of an if-then-else expression must have the same type (got {0} and {1})", e.Thn.Type, e.Els.Type);
- }
-
- } else if (expr is MatchExpr) {
- MatchExpr me = (MatchExpr)expr;
- Contract.Assert(!twoState); // currently, match expressions are allowed only at the outermost level of function bodies
- if (matchVarContext == null) {
- Error(me, "'match' expressions are not supported in this context");
- matchVarContext = new List<IVariable>();
- }
- ResolveExpression(me.Source, twoState);
- Contract.Assert(me.Source.Type != null); // follows from postcondition of ResolveExpression
- UserDefinedType sourceType = null;
- DatatypeDecl dtd = null;
- Dictionary<TypeParameter, Type> subst = new Dictionary<TypeParameter, Type>();
- if (me.Source.Type.IsDatatype) {
- sourceType = (UserDefinedType)me.Source.Type;
- dtd = cce.NonNull((DatatypeDecl)sourceType.ResolvedClass);
- }
- Dictionary<string, DatatypeCtor> ctors;
- IVariable goodMatchVariable = null;
- if (dtd == null) {
- Error(me.Source, "the type of the match source expression must be a datatype (instead found {0})", me.Source.Type);
- ctors = null;
- } else {
- Contract.Assert(sourceType != null); // dtd and sourceType are set together above
- ctors = datatypeCtors[dtd];
- Contract.Assert(ctors != null); // dtd should have been inserted into datatypeCtors during a previous resolution stage
-
- IdentifierExpr ie = me.Source.Resolved as IdentifierExpr;
- if (ie == null || !(ie.Var is Formal || ie.Var is BoundVar)) {
- Error(me.Source.tok, "match source expression must be a formal parameter of the enclosing function or an enclosing match expression");
- } else if (!matchVarContext.Contains(ie.Var)) {
- Error(me.Source.tok, "match source expression '{0}' has already been used as a match source expression in this context", ie.Var.Name);
- } else {
- goodMatchVariable = ie.Var;
- }
-
- // build the type-parameter substitution map for this use of the datatype
- for (int i = 0; i < dtd.TypeArgs.Count; i++) {
- subst.Add(dtd.TypeArgs[i], sourceType.TypeArgs[i]);
- }
- }
-
- Dictionary<string, object> memberNamesUsed = new Dictionary<string, object>(); // this is really a set
- expr.Type = new InferredTypeProxy();
- foreach (MatchCaseExpr mc in me.Cases) {
- DatatypeCtor ctor = null;
- if (ctors != null) {
- Contract.Assert(dtd != null);
- if (!ctors.TryGetValue(mc.Id, out ctor)) {
- Error(mc.tok, "member {0} does not exist in datatype {1}", mc.Id, dtd.Name);
- } else {
- Contract.Assert(ctor != null); // follows from postcondition of TryGetValue
- mc.Ctor = ctor;
- if (ctor.Formals.Count != mc.Arguments.Count) {
- Error(mc.tok, "member {0} has wrong number of formals (found {1}, expected {2})", mc.Id, mc.Arguments.Count, ctor.Formals.Count);
- }
- if (memberNamesUsed.ContainsKey(mc.Id)) {
- Error(mc.tok, "member {0} appears in more than one case", mc.Id);
- } else {
- memberNamesUsed.Add(mc.Id, null); // add mc.Id to the set of names used
- }
- }
- }
- scope.PushMarker();
- int i = 0;
- foreach (BoundVar v in mc.Arguments) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate parameter name: {0}", v.Name);
- }
- ResolveType(v.tok, v.Type, null, true);
- if (ctor != null && i < ctor.Formals.Count) {
- Formal formal = ctor.Formals[i];
- Type st = SubstType(formal.Type, subst);
- if (!UnifyTypes(v.Type, st)) {
- Error(expr, "the declared type of the formal ({0}) does not agree with the corresponding type in the constructor's signature ({1})", v.Type, st);
- }
- v.IsGhost = formal.IsGhost;
- }
- i++;
- }
- List<IVariable> innerMatchVarContext = new List<IVariable>(matchVarContext);
- if (goodMatchVariable != null) {
- innerMatchVarContext.Remove(goodMatchVariable); // this variable is no longer available for matching
- }
- innerMatchVarContext.AddRange(mc.Arguments);
- ResolveExpression(mc.Body, twoState, innerMatchVarContext);
- Contract.Assert(mc.Body.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(expr.Type, mc.Body.Type)) {
- Error(mc.Body.tok, "type of case bodies do not agree (found {0}, previous types {1})", mc.Body.Type, expr.Type);
- }
- scope.PopMarker();
- }
- if (dtd != null && memberNamesUsed.Count != dtd.Ctors.Count) {
- // We could complain about the syntactic omission of constructors:
- // Error(expr, "match expression does not cover all constructors");
- // but instead we let the verifier do a semantic check.
- // So, for now, record the missing constructors:
- foreach (var ctr in dtd.Ctors) {
- if (!memberNamesUsed.ContainsKey(ctr.Name)) {
- me.MissingCases.Add(ctr);
- }
- }
- Contract.Assert(memberNamesUsed.Count + me.MissingCases.Count == dtd.Ctors.Count);
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
-
- if (expr.Type == null) {
- // some resolution error occurred
- expr.Type = Type.Flexible;
- }
- }
-
- private void ResolveDatatypeValue(bool twoState, DatatypeValue dtv, DatatypeDecl dt) {
- // this resolution is a little special, in that the syntax shows only the base name, not its instantiation (which is inferred)
- List<Type> gt = new List<Type>(dt.TypeArgs.Count);
- Dictionary<TypeParameter, Type> subst = new Dictionary<TypeParameter, Type>();
- for (int i = 0; i < dt.TypeArgs.Count; i++) {
- Type t = new InferredTypeProxy();
- gt.Add(t);
- dtv.InferredTypeArgs.Add(t);
- subst.Add(dt.TypeArgs[i], t);
- }
- // Construct a resolved type directly, as we know the declaration is dt.
- dtv.Type = new UserDefinedType(dtv.tok, dtv.DatatypeName, dt, gt);
-
- DatatypeCtor ctor;
- if (!datatypeCtors[dt].TryGetValue(dtv.MemberName, out ctor)) {
- Error(dtv.tok, "undeclared constructor {0} in datatype {1}", dtv.MemberName, dtv.DatatypeName);
- } else {
- Contract.Assert(ctor != null); // follows from postcondition of TryGetValue
- dtv.Ctor = ctor;
- if (ctor.Formals.Count != dtv.Arguments.Count) {
- Error(dtv.tok, "wrong number of arguments to datatype constructor {0} (found {1}, expected {2})", dtv.DatatypeName, dtv.Arguments.Count, ctor.Formals.Count);
- }
- }
- int j = 0;
- foreach (Expression arg in dtv.Arguments) {
- Formal formal = ctor != null && j < ctor.Formals.Count ? ctor.Formals[j] : null;
- ResolveExpression(arg, twoState, null);
- Contract.Assert(arg.Type != null); // follows from postcondition of ResolveExpression
- if (formal != null) {
- Type st = SubstType(formal.Type, subst);
- if (!UnifyTypes(arg.Type, st)) {
- Error(arg.tok, "incorrect type of datatype constructor argument (found {0}, expected {1})", arg.Type, st);
- }
- }
- j++;
- }
- }
-
- private bool ComparableTypes(Type A, Type B) {
- if (A.IsArrayType && B.IsArrayType) {
- Type a = UserDefinedType.ArrayElementType(A);
- Type b = UserDefinedType.ArrayElementType(B);
- return CouldPossiblyBeSameType(a, b);
- } else
- if (A is UserDefinedType && B is UserDefinedType) {
- UserDefinedType a = (UserDefinedType)A;
- UserDefinedType b = (UserDefinedType)B;
- if (a.ResolvedClass != null && b.ResolvedClass != null && a.ResolvedClass.Name == b.ResolvedClass.Name) {
- if (a.TypeArgs.Count != b.TypeArgs.Count) {
- return false; // this probably doesn't happen if the classes are the same.
- }
- for (int i = 0; i < a.TypeArgs.Count; i++) {
- if (!CouldPossiblyBeSameType(a.TypeArgs[i], b.TypeArgs[i]))
- return false;
- }
- // all parameters could be the same
- return true;
- }
- // either we don't know what class it is yet, or the classes mismatch
- return false;
- }
- return false;
- }
- private bool CouldPossiblyBeSameType(Type A, Type B) {
- if (A.IsTypeParameter || B.IsTypeParameter) {
- return true;
- }
- if (A.IsArrayType && B.IsArrayType) {
- Type a = UserDefinedType.ArrayElementType(A);
- Type b = UserDefinedType.ArrayElementType(B);
- return CouldPossiblyBeSameType(a, b);
- }
- if (A is UserDefinedType && B is UserDefinedType) {
- UserDefinedType a = (UserDefinedType)A;
- UserDefinedType b = (UserDefinedType)B;
- if (a.ResolvedClass != null && b.ResolvedClass != null && a.ResolvedClass == b.ResolvedClass) {
- if (a.TypeArgs.Count != b.TypeArgs.Count) {
- return false; // this probably doesn't happen if the classes are the same.
- }
- for (int i = 0; i < a.TypeArgs.Count; i++) {
- if (!CouldPossiblyBeSameType(a.TypeArgs[i], b.TypeArgs[i]))
- return false;
- }
- // all parameters could be the same
- return true;
- }
- // either we don't know what class it is yet, or the classes mismatch
- return false;
- }
- return false;
- }
-
- /// <summary>
- /// Generate an error for every non-ghost feature used in "expr".
- /// Requires "expr" to have been successfully resolved.
- /// </summary>
- void CheckIsNonGhost(Expression expr) {
- Contract.Requires(expr != null);
- Contract.Requires(expr.WasResolved()); // this check approximates the requirement that "expr" be resolved
-
- if (expr is IdentifierExpr) {
- var e = (IdentifierExpr)expr;
- if (e.Var != null && e.Var.IsGhost) {
- Error(expr, "ghost variables are allowed only in specification contexts");
- return;
- }
-
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- if (e.Field != null && e.Field.IsGhost) {
- Error(expr, "ghost fields are allowed only in specification contexts");
- return;
- }
-
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- if (e.Function != null) {
- if (e.Function.IsGhost) {
- Error(expr, "function calls are allowed only in specification contexts (consider declaring the function a 'function method')");
- return;
- }
- // function is okay, so check all NON-ghost arguments
- CheckIsNonGhost(e.Receiver);
- for (int i = 0; i < e.Function.Formals.Count; i++) {
- if (!e.Function.Formals[i].IsGhost) {
- CheckIsNonGhost(e.Args[i]);
- }
- }
- }
- return;
-
- } else if (expr is DatatypeValue) {
- var e = (DatatypeValue)expr;
- // check all NON-ghost arguments
- // note that if resolution is successful, then |e.Arguments| == |e.Ctor.Formals|
- for (int i = 0; i < e.Arguments.Count; i++) {
- if (!e.Ctor.Formals[i].IsGhost) {
- CheckIsNonGhost(e.Arguments[i]);
- }
- }
- return;
-
- } else if (expr is OldExpr) {
- Error(expr, "old expressions are allowed only in specification and ghost contexts");
- return;
-
- } else if (expr is FreshExpr) {
- Error(expr, "fresh expressions are allowed only in specification and ghost contexts");
- return;
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- // ignore the guard
- CheckIsNonGhost(e.Body);
- return;
-
- } else if (expr is BinaryExpr) {
- var e = (BinaryExpr)expr;
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.RankGt:
- case BinaryExpr.ResolvedOpcode.RankLt:
- Error(expr, "rank comparisons are allowed only in specification and ghost contexts");
- return;
- default:
- break;
- }
-
- } else if (expr is QuantifierExpr) {
- var e = (QuantifierExpr)expr;
- if (e.MissingBounds != null) {
- foreach (var bv in e.MissingBounds) {
- Error(expr, "quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for '{0}'", bv.Name);
- }
- return;
- }
- } else if (expr is NamedExpr) {
- if (!moduleInfo.IsGhost)
- CheckIsNonGhost(((NamedExpr)expr).Body);
- return;
- }
-
- foreach (var ee in expr.SubExpressions) {
- CheckIsNonGhost(ee);
- }
- }
-
- /// <summary>
- /// If "!allowMethodCall" or if what is being called does not refer to a method, resolves "e" and returns "null".
- /// Otherwise (that is, if "allowMethodCall" and what is being called refers to a method), resolves the receiver
- /// of "e" but NOT the arguments, and returns a CallRhs corresponding to the call.
- /// </summary>
- CallRhs ResolveFunctionCallExpr(FunctionCallExpr e, bool twoState, bool allowMethodCall) {
- ResolveReceiver(e.Receiver, twoState);
- Contract.Assert(e.Receiver.Type != null); // follows from postcondition of ResolveExpression
- NonProxyType nptype;
- MemberDecl member = ResolveMember(e.tok, e.Receiver.Type, e.Name, out nptype);
-#if !NO_WORK_TO_BE_DONE
- UserDefinedType ctype = (UserDefinedType)nptype;
-#endif
- if (member == null) {
- // error has already been reported by ResolveMember
- } else if (member is Method) {
- if (allowMethodCall) {
- // it's a method
- return new CallRhs(e.tok, e.Receiver, e.Name, e.Args);
- } else {
- Error(e, "member {0} in type {1} refers to a method, but only functions can be used in this context", e.Name, cce.NonNull(ctype).Name);
- }
- } else if (!(member is Function)) {
- Error(e, "member {0} in type {1} does not refer to a function", e.Name, cce.NonNull(ctype).Name);
- } else {
- Function function = (Function)member;
- e.Function = function;
- if (function is CoPredicate) {
- ((CoPredicate)function).Uses.Add(e);
- }
- if (e.Receiver is StaticReceiverExpr && !function.IsStatic) {
- Error(e, "an instance function must be selected via an object, not just a class name");
- }
- if (function.Formals.Count != e.Args.Count) {
- Error(e, "wrong number of function arguments (got {0}, expected {1})", e.Args.Count, function.Formals.Count);
- } else {
- Contract.Assert(ctype != null); // follows from postcondition of ResolveMember
- if (!function.IsStatic) {
- if (!scope.AllowInstance && e.Receiver is ThisExpr) {
- // The call really needs an instance, but that instance is given as 'this', which is not
- // available in this context. In most cases, occurrences of 'this' inside e.Receiver would
- // have been caught in the recursive call to resolve e.Receiver, but not the specific case
- // of e.Receiver being 'this' (explicitly or implicitly), for that case needs to be allowed
- // in the event that a static function calls another static function (and note that we need the
- // type of the receiver in order to find the method, so we could not have made this check
- // earlier).
- Error(e.Receiver, "'this' is not allowed in a 'static' context");
- } else if (e.Receiver is StaticReceiverExpr) {
- Error(e.Receiver, "call to instance function requires an instance");
- }
- }
- // build the type substitution map
- e.TypeArgumentSubstitutions = new Dictionary<TypeParameter, Type>();
- for (int i = 0; i < ctype.TypeArgs.Count; i++) {
- e.TypeArgumentSubstitutions.Add(cce.NonNull(ctype.ResolvedClass).TypeArgs[i], ctype.TypeArgs[i]);
- }
- foreach (TypeParameter p in function.TypeArgs) {
- e.TypeArgumentSubstitutions.Add(p, new ParamTypeProxy(p));
- }
- // type check the arguments
- for (int i = 0; i < function.Formals.Count; i++) {
- Expression farg = e.Args[i];
- ResolveExpression(farg, twoState);
- Contract.Assert(farg.Type != null); // follows from postcondition of ResolveExpression
- Type s = SubstType(function.Formals[i].Type, e.TypeArgumentSubstitutions);
- if (!UnifyTypes(farg.Type, s)) {
- Error(e, "incorrect type of function argument {0} (expected {1}, got {2})", i, s, farg.Type);
- }
- }
- e.Type = SubstType(function.ResultType, e.TypeArgumentSubstitutions);
- }
-
- // Resolution termination check
- if (currentFunction != null && currentFunction.EnclosingClass != null && function.EnclosingClass != null) {
- ModuleDefinition callerModule = currentFunction.EnclosingClass.Module;
- ModuleDefinition calleeModule = function.EnclosingClass.Module;
- if (callerModule == calleeModule) {
- // intra-module call; this is allowed; add edge in module's call graph
- callerModule.CallGraph.AddEdge(currentFunction, function);
- if (currentFunction == function) {
- currentFunction.IsRecursive = true; // self recursion (mutual recursion is determined elsewhere)
- }
- } else {
- //Contract.Assert(dependencies.Reaches(callerModule, calleeModule));
- }
- }
- }
- return null;
- }
-
- /// <summary>
- /// If "!allowMethodCall", or if "e" does not designate a method call, resolves "e" and returns "null".
- /// Otherwise, resolves all sub-parts of "e" and returns a (resolved) CallRhs expression representing the call.
- /// </summary>
- CallRhs ResolveIdentifierSequence(IdentifierSequence e, bool twoState, bool allowMethodCall) {
- // Look up "id" as follows:
- // - local variable, parameter, or bound variable (if this clashes with something of interest, one can always rename the local variable locally)
- // - unamibugous type/module name (class, datatype, sub-module (including submodules of imports) or arbitrary-type)
- // (if two imported types have the same name, an error message is produced here)
- // - unambiguous constructor name of a datatype (if two constructors have the same name, an error message is produced here)
- // - field, function or method name (with implicit receiver) (if the field is occluded by anything above, one can use an explicit "this.")
- // - iterator
- // - static function or method in the enclosing module, or its imports.
-
- Expression r = null; // resolved version of e
- CallRhs call = null;
-
- TopLevelDecl decl;
- Tuple<DatatypeCtor, bool> pair;
- Dictionary<string, MemberDecl> members;
- MemberDecl member;
- var id = e.Tokens[0];
- if (scope.Find(id.val) != null) {
- // ----- root is a local variable, parameter, or bound variable
- r = new IdentifierExpr(id, id.val);
- ResolveExpression(r, twoState);
- r = ResolveSuffix(r, e, 1, twoState, allowMethodCall, out call);
-
- } else if (moduleInfo.TopLevels.TryGetValue(id.val, out decl)) {
- if (decl is AmbiguousTopLevelDecl) {
- Error(id, "The name {0} ambiguously refers to a type in one of the modules {1}", id.val, ((AmbiguousTopLevelDecl)decl).ModuleNames());
- } else if (e.Tokens.Count == 1 && e.Arguments == null) {
- Error(id, "name of type ('{0}') is used as a variable", id.val);
- } else if (e.Tokens.Count == 1 && e.Arguments != null) {
- Error(id, "name of type ('{0}') is used as a function", id.val);
- // resolve the arguments nonetheless
- foreach (var arg in e.Arguments) {
- ResolveExpression(arg, twoState);
- }
- } else if (decl is ClassDecl) {
- // ----- root is a class
- var cd = (ClassDecl)decl;
- r = ResolveSuffix(new StaticReceiverExpr(id, cd), e, 1, twoState, allowMethodCall, out call);
-
- } else if (decl is ModuleDecl) {
- // ----- root is a submodule
- if (!(1 < e.Tokens.Count)) {
- Error(e.tok, "module {0} cannot be used here", ((ModuleDecl)decl).Name);
- }
- call = ResolveIdentifierSequenceModuleScope(e, 1, ((ModuleDecl)decl).Signature, twoState, allowMethodCall);
- } else {
- // ----- root is a datatype
- var dt = (DatatypeDecl)decl; // otherwise, unexpected TopLevelDecl
- var args = (e.Tokens.Count == 2 ? e.Arguments : null) ?? new List<Expression>();
- r = new DatatypeValue(id, id.val, e.Tokens[1].val, args);
- ResolveExpression(r, twoState);
- if (e.Tokens.Count != 2) {
- r = ResolveSuffix(r, e, 2, twoState, allowMethodCall, out call);
- }
- }
-
- } else if (moduleInfo.Ctors.TryGetValue(id.val, out pair)) {
- // ----- root is a datatype constructor
- if (pair.Item2) {
- // there is more than one constructor with this name
- Error(id, "the name '{0}' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, '{1}.{0}')", id.val, pair.Item1.EnclosingDatatype.Name);
- } else {
- var args = (e.Tokens.Count == 1 ? e.Arguments : null) ?? new List<Expression>();
- r = new DatatypeValue(id, pair.Item1.EnclosingDatatype.Name, id.val, args);
- ResolveExpression(r, twoState);
- if (e.Tokens.Count != 1) {
- r = ResolveSuffix(r, e, 1, twoState, allowMethodCall, out call);
- }
- }
-
- } else if ((currentClass != null && classMembers.TryGetValue(currentClass, out members) && members.TryGetValue(id.val, out member))
- || moduleInfo.StaticMembers.TryGetValue(id.val, out member)) // try static members of the current module too.
- {
- // ----- field, function, or method
- if (member is AmbiguousMemberDecl) {
- Contract.Assert(member.IsStatic); // currently, static members of _default are the only thing which can be ambiguous.
- Error(id, "The name {0} ambiguously refers to a static member in one of the modules {1}", id.val, ((AmbiguousMemberDecl)member).ModuleNames());
- } else {
- Expression receiver;
- if (member.IsStatic) {
- receiver = new StaticReceiverExpr(id, (ClassDecl)member.EnclosingClass);
- } else {
- if (!scope.AllowInstance) {
- Error(id, "'this' is not allowed in a 'static' context");
- // nevertheless, set "receiver" to a value so we can continue resolution
- }
- receiver = new ImplicitThisExpr(id);
- receiver.Type = GetThisType(id, (ClassDecl)member.EnclosingClass); // resolve here
- }
- r = ResolveSuffix(receiver, e, 0, twoState, allowMethodCall, out call);
- }
-
- } else {
- Error(id, "unresolved identifier: {0}", id.val);
- // resolve arguments, if any
- if (e.Arguments != null) {
- foreach (var arg in e.Arguments) {
- ResolveExpression(arg, twoState);
- }
- }
- }
-
- if (r != null) {
- e.ResolvedExpression = r;
- e.Type = r.Type;
- }
- return call;
- }
-
- CallRhs ResolveIdentifierSequenceModuleScope(IdentifierSequence e, int p, ModuleSignature sig, bool twoState, bool allowMethodCall) {
- // Look up "id" as follows:
- // - unamibugous type/module name (class, datatype, sub-module (including submodules of imports) or arbitrary-type)
- // (if two imported types have the same name, an error message is produced here)
- // - static function or method of sig.
- // This is used to look up names that appear after a dot in a sequence identifier. For example, in X.M.*, M should be looked up in X, but
- // should not consult the local scope. This distingushes this from the above, in that local scope, imported modules, etc. are ignored.
- Contract.Requires(p < e.Tokens.Count);
- Expression r = null; // resolved version of e
- CallRhs call = null;
-
- TopLevelDecl decl;
- MemberDecl member;
- Tuple<DatatypeCtor, bool> pair;
- var id = e.Tokens[p];
- sig = GetSignature(sig);
- if (sig.TopLevels.TryGetValue(id.val, out decl)) {
- if (decl is AmbiguousTopLevelDecl) {
- Error(id, "The name {0} ambiguously refers to a something in one of the modules {1}", id.val, ((AmbiguousTopLevelDecl)decl).ModuleNames());
- } else if (decl is ClassDecl) {
- // ----- root is a class
- var cd = (ClassDecl)decl;
- r = ResolveSuffix(new StaticReceiverExpr(id, cd), e, p + 1, twoState, allowMethodCall, out call);
-
- } else if (decl is ModuleDecl) {
- // ----- root is a submodule
- if (!(p + 1 < e.Tokens.Count)) {
- Error(e.tok, "module {0} cannot be used here", ((ModuleDecl)decl).Name);
- }
- call = ResolveIdentifierSequenceModuleScope(e, p + 1, ((ModuleDecl)decl).Signature, twoState, allowMethodCall);
- } else {
- // ----- root is a datatype
- var dt = (DatatypeDecl)decl; // otherwise, unexpected TopLevelDecl
- var args = (e.Tokens.Count == p + 2 ? e.Arguments : null) ?? new List<Expression>();
- r = new DatatypeValue(id, id.val, e.Tokens[p + 1].val, args);
- ResolveDatatypeValue(twoState, (DatatypeValue)r, dt);
- if (e.Tokens.Count != p + 2) {
- r = ResolveSuffix(r, e, p + 2, twoState, allowMethodCall, out call);
- }
- }
- } else if (sig.Ctors.TryGetValue(id.val, out pair)) {
- // ----- root is a datatype constructor
- if (pair.Item2) {
- // there is more than one constructor with this name
- Error(id, "the name '{0}' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, '{1}.{0}')", id.val, pair.Item1.EnclosingDatatype.Name);
- } else {
- var dt = pair.Item1.EnclosingDatatype;
- var args = (e.Tokens.Count == p + 1 ? e.Arguments : null) ?? new List<Expression>();
- r = new DatatypeValue(id, dt.Name, id.val, args);
- ResolveDatatypeValue(twoState, (DatatypeValue)r, dt);
- if (e.Tokens.Count != p + 1) {
- r = ResolveSuffix(r, e, p + 1, twoState, allowMethodCall, out call);
- }
- }
- } else if (sig.StaticMembers.TryGetValue(id.val, out member)) // try static members of the current module too.
- {
- // ----- function, or method
- Expression receiver;
- Contract.Assert(member.IsStatic);
- receiver = new StaticReceiverExpr(id, (ClassDecl)member.EnclosingClass);
- r = ResolveSuffix(receiver, e, p, twoState, allowMethodCall, out call);
-
- } else {
- Error(id, "unresolved identifier: {0}", id.val);
- // resolve arguments, if any
- if (e.Arguments != null) {
- foreach (var arg in e.Arguments) {
- ResolveExpression(arg, twoState);
- }
- }
- }
-
- if (r != null) {
- e.ResolvedExpression = r;
- e.Type = r.Type;
- }
- return call;
- }
-
- private ModuleSignature GetSignature(ModuleSignature sig) {
- if (useCompileSignatures) {
- while (sig.CompileSignature != null)
- sig = sig.CompileSignature;
- }
- return sig;
- }
- /// <summary>
- /// Given resolved expression "r" and unresolved expressions e.Tokens[p..] and e.Arguments.
- /// Returns a resolved version of the expression:
- /// r . e.Tokens[p] . e.Tokens[p+1] ... . e.Tokens[e.Tokens.Count-1] ( e.Arguments )
- /// Except, if "allowMethodCall" is "true" and the would-be-returned value designates a method
- /// call, instead returns null and returns "call" as a non-null value.
- /// </summary>
- Expression ResolveSuffix(Expression r, IdentifierSequence e, int p, bool twoState, bool allowMethodCall, out CallRhs call) {
- Contract.Requires(r != null);
- Contract.Requires(e != null);
- Contract.Requires(0 <= p && p <= e.Tokens.Count);
- Contract.Ensures((Contract.Result<Expression>() != null && Contract.ValueAtReturn(out call) == null) ||
- (allowMethodCall && Contract.Result<Expression>() == null && Contract.ValueAtReturn(out call) != null));
-
- call = null;
- int nonCallArguments = e.Arguments == null ? e.Tokens.Count : e.Tokens.Count - 1;
- for (; p < nonCallArguments; p++) {
- var resolved = ResolvePredicateOrField(e.Tokens[p], r, e.Tokens[p].val);
- if (resolved != null) {
- r = resolved;
- ResolveExpression(r, twoState, null);
- }
- }
-
- if (p < e.Tokens.Count) {
- Contract.Assert(e.Arguments != null);
-
-
- bool itIsAMethod = false;
- if (allowMethodCall) {
- var udt = r.Type.Normalize() as UserDefinedType;
- if (udt != null && udt.ResolvedClass != null) {
- Dictionary<string, MemberDecl> members;
- if (udt.ResolvedClass is ClassDecl) {
- classMembers.TryGetValue((ClassDecl)udt.ResolvedClass, out members);
- } else {
- members = null;
- }
- MemberDecl member;
- if (members != null && members.TryGetValue(e.Tokens[p].val, out member) && member is Method) {
- itIsAMethod = true;
- }
- }
- }
- if (itIsAMethod) {
- // method
- call = new CallRhs(e.Tokens[p], r, e.Tokens[p].val, e.Arguments);
- r = null;
- } else {
- r = new FunctionCallExpr(e.Tokens[p], e.Tokens[p].val, r, e.OpenParen, e.Arguments);
- ResolveExpression(r, twoState, null);
- }
- } else if (e.Arguments != null) {
- Contract.Assert(p == e.Tokens.Count);
- Error(e.OpenParen, "non-function expression is called with parameters");
- // resolve the arguments nonetheless
- foreach (var arg in e.Arguments) {
- ResolveExpression(arg, twoState);
- }
- }
- return r;
- }
-
- /// <summary>
- /// Resolves "obj . suffixName" to either a parameter-less predicate invocation or a field selection.
- /// Expects "obj" already to have been resolved.
- /// On success, returns the result of the resolution--as an un-resolved expression.
- /// On failure, returns null (in which case an error has been reported to the user).
- /// </summary>
- Expression/*?*/ ResolvePredicateOrField(IToken tok, Expression obj, string suffixName) {
- Contract.Requires(tok != null);
- Contract.Requires(obj != null);
- Contract.Requires(obj.Type != null); // obj is expected already to have been resolved
- Contract.Requires(suffixName != null);
-
- NonProxyType nptype;
- MemberDecl member = ResolveMember(tok, obj.Type, suffixName, out nptype);
- if (member == null) {
- // error has already been reported by ResolveMember
- return null;
- } else if (member is Predicate && ((Predicate)member).Formals.Count == 0) {
- // parameter-less predicates are allowed to be used without parentheses
- return new FunctionCallExpr(tok, suffixName, obj, null, new List<Expression>());
- } else {
- // assume it's a field and let the resolution of the FieldSelectExpr check any further problems
- return new FieldSelectExpr(tok, obj, suffixName);
- }
- }
-
- /// <summary>
- /// Tries to find a bounded pool for each of the bound variables "bvars" of "expr". If this process
- /// fails, then "null" is returned and the bound variables for which the process fails are added to "missingBounds".
- /// If "returnAllBounds" is false, then:
- /// -- at most one BoundedPool per variable is returned
- /// -- every IntBoundedPool returned has both a lower and an upper bound
- /// -- no SuperSetBoundedPool is returned
- /// If "returnAllBounds" is true, then:
- /// -- a variable may give rise to several BoundedPool's
- /// -- IntBoundedPool bounds may have just one component
- /// -- a non-null return value means that some bound were found for each variable (but, for example, perhaps one
- /// variable only has lower bounds, no upper bounds)
- /// Requires "expr" to be successfully resolved.
- /// </summary>
- public static List<ComprehensionExpr.BoundedPool> DiscoverBounds(IToken tok, List<BoundVar> bvars, Expression expr, bool polarity, bool returnAllBounds, List<BoundVar> missingBounds) {
- Contract.Requires(tok != null);
- Contract.Requires(bvars != null);
- Contract.Requires(missingBounds != null);
- Contract.Requires(expr != null);
- Contract.Requires(expr.Type != null); // a sanity check (but not a complete proof) that "expr" has been resolved
- Contract.Ensures(
- (returnAllBounds && Contract.OldValue(missingBounds.Count) <= missingBounds.Count) ||
- (!returnAllBounds &&
- Contract.Result<List<ComprehensionExpr.BoundedPool>>() != null &&
- Contract.Result<List<ComprehensionExpr.BoundedPool>>().Count == bvars.Count &&
- Contract.OldValue(missingBounds.Count) == missingBounds.Count) ||
- (!returnAllBounds &&
- Contract.Result<List<ComprehensionExpr.BoundedPool>>() == null &&
- Contract.OldValue(missingBounds.Count) < missingBounds.Count));
-
- var bounds = new List<ComprehensionExpr.BoundedPool>();
- bool foundError = false;
- for (int j = 0; j < bvars.Count; j++) {
- var bv = bvars[j];
- if (bv.Type is BoolType) {
- // easy
- bounds.Add(new ComprehensionExpr.BoolBoundedPool());
- } else if (bv.Type.IsIndDatatype && (bv.Type.AsIndDatatype).HasFinitePossibleValues) {
- bounds.Add(new ComprehensionExpr.DatatypeBoundedPool(bv.Type.AsIndDatatype));
- } else {
- // Go through the conjuncts of the range expression to look for bounds.
- Expression lowerBound = bv.Type is NatType ? new LiteralExpr(bv.tok, new BigInteger(0)) : null;
- Expression upperBound = null;
- bool foundBoundsForBv = false;
- if (returnAllBounds && lowerBound != null) {
- bounds.Add(new ComprehensionExpr.IntBoundedPool(lowerBound, upperBound));
- lowerBound = null;
- foundBoundsForBv = true;
- }
- foreach (var conjunct in NormalizedConjuncts(expr, polarity)) {
- var c = conjunct as BinaryExpr;
- if (c == null) {
- goto CHECK_NEXT_CONJUNCT;
- }
- var e0 = c.E0;
- var e1 = c.E1;
- int whereIsBv = SanitizeForBoundDiscovery(bvars, j, c.ResolvedOp, ref e0, ref e1);
- if (whereIsBv < 0) {
- goto CHECK_NEXT_CONJUNCT;
- }
- switch (c.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.InSet:
- if (whereIsBv == 0) {
- bounds.Add(new ComprehensionExpr.SetBoundedPool(e1));
- foundBoundsForBv = true;
- if (!returnAllBounds) goto CHECK_NEXT_BOUND_VARIABLE;
- }
- break;
- case BinaryExpr.ResolvedOpcode.Subset:
- if (returnAllBounds && whereIsBv == 1) {
- bounds.Add(new ComprehensionExpr.SuperSetBoundedPool(e0));
- foundBoundsForBv = true;
- }
- break;
- case BinaryExpr.ResolvedOpcode.InMultiSet:
- if (whereIsBv == 0) {
- bounds.Add(new ComprehensionExpr.SetBoundedPool(e1));
- foundBoundsForBv = true;
- if (!returnAllBounds) goto CHECK_NEXT_BOUND_VARIABLE;
- }
- break;
- case BinaryExpr.ResolvedOpcode.InSeq:
- if (whereIsBv == 0) {
- bounds.Add(new ComprehensionExpr.SeqBoundedPool(e1));
- foundBoundsForBv = true;
- if (!returnAllBounds) goto CHECK_NEXT_BOUND_VARIABLE;
- }
- break;
- case BinaryExpr.ResolvedOpcode.InMap:
- if (whereIsBv == 0) {
- bounds.Add(new ComprehensionExpr.SetBoundedPool(e1));
- foundBoundsForBv = true;
- if (!returnAllBounds) goto CHECK_NEXT_BOUND_VARIABLE;
- }
- break;
- case BinaryExpr.ResolvedOpcode.EqCommon:
- if (bv.Type is IntType) {
- var otherOperand = whereIsBv == 0 ? e1 : e0;
- bounds.Add(new ComprehensionExpr.IntBoundedPool(otherOperand, Plus(otherOperand, 1)));
- foundBoundsForBv = true;
- if (!returnAllBounds) goto CHECK_NEXT_BOUND_VARIABLE;
- } else if (returnAllBounds && bv.Type is SetType) {
- var otherOperand = whereIsBv == 0 ? e1 : e0;
- bounds.Add(new ComprehensionExpr.SuperSetBoundedPool(otherOperand));
- foundBoundsForBv = true;
- }
- break;
- case BinaryExpr.ResolvedOpcode.Gt:
- case BinaryExpr.ResolvedOpcode.Ge:
- Contract.Assert(false); throw new cce.UnreachableException(); // promised by postconditions of NormalizedConjunct
- case BinaryExpr.ResolvedOpcode.Lt:
- if (whereIsBv == 0 && upperBound == null) {
- upperBound = e1; // bv < E
- } else if (whereIsBv == 1 && lowerBound == null) {
- lowerBound = Plus(e0, 1); // E < bv
- }
- break;
- case BinaryExpr.ResolvedOpcode.Le:
- if (whereIsBv == 0 && upperBound == null) {
- upperBound = Plus(e1, 1); // bv <= E
- } else if (whereIsBv == 1 && lowerBound == null) {
- lowerBound = e0; // E <= bv
- }
- break;
- default:
- break;
- }
- if ((lowerBound != null && upperBound != null) ||
- (returnAllBounds && (lowerBound != null || upperBound != null))) {
- // we have found two halves (or, in the case of returnAllBounds, we have found some bound)
- bounds.Add(new ComprehensionExpr.IntBoundedPool(lowerBound, upperBound));
- lowerBound = null;
- upperBound = null;
- foundBoundsForBv = true;
- if (!returnAllBounds) goto CHECK_NEXT_BOUND_VARIABLE;
- }
- CHECK_NEXT_CONJUNCT: ;
- }
- if (!foundBoundsForBv) {
- // we have checked every conjunct in the range expression and still have not discovered good bounds
- missingBounds.Add(bv); // record failing bound variable
- foundError = true;
- }
- }
- CHECK_NEXT_BOUND_VARIABLE: ; // should goto here only if the bound for the current variable has been discovered (otherwise, return with null from this method)
- }
- return foundError ? null : bounds;
- }
-
- /// <summary>
- /// If the return value is negative, the resulting "e0" and "e1" should not be used.
- /// Otherwise, the following is true on return:
- /// The new "e0 op e1" is equivalent to the old "e0 op e1".
- /// One of "e0" and "e1" is the identifier "boundVars[bvi]"; the return value is either 0 or 1, and indicates which.
- /// The other of "e0" and "e1" is an expression whose free variables are not among "boundVars[bvi..]".
- /// Ensures that the resulting "e0" and "e1" are not ConcreteSyntaxExpression's.
- /// </summary>
- static int SanitizeForBoundDiscovery(List<BoundVar> boundVars, int bvi, BinaryExpr.ResolvedOpcode op, ref Expression e0, ref Expression e1) {
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Requires(boundVars != null);
- Contract.Requires(0 <= bvi && bvi < boundVars.Count);
- Contract.Ensures(Contract.Result<int>() < 2);
- Contract.Ensures(!(Contract.ValueAtReturn(out e0) is ConcreteSyntaxExpression));
- Contract.Ensures(!(Contract.ValueAtReturn(out e1) is ConcreteSyntaxExpression));
-
- var bv = boundVars[bvi];
- e0 = e0.Resolved;
- e1 = e1.Resolved;
-
- // make an initial assessment of where bv is; to continue, we need bv to appear in exactly one operand
- var fv0 = FreeVariables(e0);
- var fv1 = FreeVariables(e1);
- Expression thisSide;
- Expression thatSide;
- int whereIsBv;
- if (fv0.Contains(bv)) {
- if (fv1.Contains(bv)) {
- return -1;
- }
- whereIsBv = 0;
- thisSide = e0; thatSide = e1;
- } else if (fv1.Contains(bv)) {
- whereIsBv = 1;
- thisSide = e1; thatSide = e0;
- } else {
- return -1;
- }
-
- // Next, clean up the side where bv is by adjusting both sides of the expression
- switch (op) {
- case BinaryExpr.ResolvedOpcode.EqCommon:
- case BinaryExpr.ResolvedOpcode.NeqCommon:
- case BinaryExpr.ResolvedOpcode.Gt:
- case BinaryExpr.ResolvedOpcode.Ge:
- case BinaryExpr.ResolvedOpcode.Le:
- case BinaryExpr.ResolvedOpcode.Lt:
- // Repeatedly move additive or subtractive terms from thisSide to thatSide
- while (true) {
- var bin = thisSide as BinaryExpr;
- if (bin == null) {
- break; // done simplifying
-
- } else if (bin.ResolvedOp == BinaryExpr.ResolvedOpcode.Add) {
- // Change "A+B op C" into either "A op C-B" or "B op C-A", depending on where we find bv among A and B.
- if (!FreeVariables(bin.E1).Contains(bv)) {
- thisSide = bin.E0.Resolved;
- thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Sub, thatSide, bin.E1);
- } else {
- thisSide = bin.E1.Resolved;
- thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Sub, thatSide, bin.E0);
- }
- ((BinaryExpr)thatSide).ResolvedOp = BinaryExpr.ResolvedOpcode.Sub;
- thatSide.Type = bin.Type;
-
- } else if (bin.ResolvedOp == BinaryExpr.ResolvedOpcode.Sub) {
- // Change "A-B op C" in a similar way.
- if (!FreeVariables(bin.E1).Contains(bv)) {
- // change to "A op C+B"
- thisSide = bin.E0.Resolved;
- thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Add, thatSide, bin.E1);
- ((BinaryExpr)thatSide).ResolvedOp = BinaryExpr.ResolvedOpcode.Add;
- } else {
- // In principle, change to "-B op C-A" and then to "B dualOp A-C". But since we don't want
- // to change "op", we instead end with "A-C op B" and switch the mapping of thisSide/thatSide
- // to e0/e1 (by inverting "whereIsBv").
- thisSide = bin.E1.Resolved;
- thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Sub, bin.E0, thatSide);
- ((BinaryExpr)thatSide).ResolvedOp = BinaryExpr.ResolvedOpcode.Sub;
- whereIsBv = 1 - whereIsBv;
- }
- thatSide.Type = bin.Type;
-
- } else {
- break; // done simplifying
- }
- }
- break;
-
- default:
- break;
- }
-
- // Now, see if the interesting side is simply bv itself
- if (thisSide is IdentifierExpr && ((IdentifierExpr)thisSide).Var == bv) {
- // we're cool
- } else {
- // no, the situation is more complicated than we care to understand
- return -1;
- }
-
- // Finally, check that the other side does not contain "bv" or any of the bound variables
- // listed after "bv" in the quantifier.
- var fv = FreeVariables(thatSide);
- for (int i = bvi; i < boundVars.Count; i++) {
- if (fv.Contains(boundVars[i])) {
- return -1;
- }
- }
-
- // As we return, also return the adjusted sides
- if (whereIsBv == 0) {
- e0 = thisSide; e1 = thatSide;
- } else {
- e0 = thatSide; e1 = thisSide;
- }
- return whereIsBv;
- }
-
- /// <summary>
- /// Returns all conjuncts of "expr" in "polarity" positions. That is, if "polarity" is "true", then
- /// returns the conjuncts of "expr" in positive positions; else, returns the conjuncts of "expr" in
- /// negative positions. The method considers a canonical-like form of the expression that pushes
- /// negations inwards far enough that one can determine what the result is going to be (so, almost
- /// a negation normal form).
- /// As a convenience, arithmetic inequalities are rewritten so that the negation of an arithmetic
- /// inequality is never returned and the comparisons > and >= are never returned; the negation of
- /// a common equality or disequality is rewritten analogously.
- /// Requires "expr" to be successfully resolved.
- /// Ensures that what is returned is not a ConcreteSyntaxExpression.
- /// </summary>
- static IEnumerable<Expression> NormalizedConjuncts(Expression expr, bool polarity) {
- // We consider 5 cases. To describe them, define P(e)=Conjuncts(e,true) and N(e)=Conjuncts(e,false).
- // * X ==> Y is treated as a shorthand for !X || Y, and so is described by the remaining cases
- // * X && Y P(_) = P(X),P(Y) and N(_) = !(X && Y)
- // * X || Y P(_) = (X || Y) and N(_) = N(X),N(Y)
- // * !X P(_) = N(X) and N(_) = P(X)
- // * else P(_) = else and N(_) = !else
- // So for ==>, we have:
- // * X ==> Y P(_) = P(!X || Y) = (!X || Y) = (X ==> Y)
- // N(_) = N(!X || Y) = N(!X),N(Y) = P(X),N(Y)
- expr = expr.Resolved;
-
- // Binary expressions
- var b = expr as BinaryExpr;
- if (b != null) {
- bool breakDownFurther = false;
- bool p0 = polarity;
- if (b.ResolvedOp == BinaryExpr.ResolvedOpcode.And) {
- breakDownFurther = polarity;
- } else if (b.ResolvedOp == BinaryExpr.ResolvedOpcode.Or) {
- breakDownFurther = !polarity;
- } else if (b.ResolvedOp == BinaryExpr.ResolvedOpcode.Imp) {
- breakDownFurther = !polarity;
- p0 = !p0;
- }
- if (breakDownFurther) {
- foreach (var c in NormalizedConjuncts(b.E0, p0)) {
- yield return c;
- }
- foreach (var c in NormalizedConjuncts(b.E1, polarity)) {
- yield return c;
- }
- yield break;
- }
- }
-
- // Unary expression
- var u = expr as UnaryExpr;
- if (u != null && u.Op == UnaryExpr.Opcode.Not) {
- foreach (var c in NormalizedConjuncts(u.E, !polarity)) {
- yield return c;
- }
- yield break;
- }
-
- // no other case applied, so return the expression or its negation, but first clean it up a little
- b = expr as BinaryExpr;
- if (b != null) {
- BinaryExpr.Opcode newOp;
- BinaryExpr.ResolvedOpcode newROp;
- bool swapOperands;
- switch (b.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.Gt: // A > B yield polarity ? (B < A) : (A <= B);
- newOp = polarity ? BinaryExpr.Opcode.Lt : BinaryExpr.Opcode.Le;
- newROp = polarity ? BinaryExpr.ResolvedOpcode.Lt : BinaryExpr.ResolvedOpcode.Le;
- swapOperands = polarity;
- break;
- case BinaryExpr.ResolvedOpcode.Ge: // A >= B yield polarity ? (B <= A) : (A < B);
- newOp = polarity ? BinaryExpr.Opcode.Le : BinaryExpr.Opcode.Lt;
- newROp = polarity ? BinaryExpr.ResolvedOpcode.Le : BinaryExpr.ResolvedOpcode.Lt;
- swapOperands = polarity;
- break;
- case BinaryExpr.ResolvedOpcode.Le: // A <= B yield polarity ? (A <= B) : (B < A);
- newOp = polarity ? BinaryExpr.Opcode.Le : BinaryExpr.Opcode.Lt;
- newROp = polarity ? BinaryExpr.ResolvedOpcode.Le : BinaryExpr.ResolvedOpcode.Lt;
- swapOperands = !polarity;
- break;
- case BinaryExpr.ResolvedOpcode.Lt: // A < B yield polarity ? (A < B) : (B <= A);
- newOp = polarity ? BinaryExpr.Opcode.Lt : BinaryExpr.Opcode.Le;
- newROp = polarity ? BinaryExpr.ResolvedOpcode.Lt : BinaryExpr.ResolvedOpcode.Le;
- swapOperands = !polarity;
- break;
- case BinaryExpr.ResolvedOpcode.EqCommon: // A == B yield polarity ? (A == B) : (A != B);
- newOp = polarity ? BinaryExpr.Opcode.Eq : BinaryExpr.Opcode.Neq;
- newROp = polarity ? BinaryExpr.ResolvedOpcode.EqCommon : BinaryExpr.ResolvedOpcode.NeqCommon;
- swapOperands = false;
- break;
- case BinaryExpr.ResolvedOpcode.NeqCommon: // A != B yield polarity ? (A != B) : (A == B);
- newOp = polarity ? BinaryExpr.Opcode.Neq : BinaryExpr.Opcode.Eq;
- newROp = polarity ? BinaryExpr.ResolvedOpcode.NeqCommon : BinaryExpr.ResolvedOpcode.EqCommon;
- swapOperands = false;
- break;
- default:
- goto JUST_RETURN_IT;
- }
- if (newROp != b.ResolvedOp || swapOperands) {
- b = new BinaryExpr(b.tok, newOp, swapOperands ? b.E1 : b.E0, swapOperands ? b.E0 : b.E1);
- b.ResolvedOp = newROp;
- b.Type = Type.Bool;
- yield return b;
- yield break;
- }
- }
- JUST_RETURN_IT: ;
- if (polarity) {
- yield return expr;
- } else {
- expr = new UnaryExpr(expr.tok, UnaryExpr.Opcode.Not, expr);
- expr.Type = Type.Bool;
- yield return expr;
- }
- }
-
- public static Expression Plus(Expression e, int n) {
- Contract.Requires(0 <= n);
-
- var nn = new LiteralExpr(e.tok, n);
- nn.Type = Type.Int;
- var p = new BinaryExpr(e.tok, BinaryExpr.Opcode.Add, e, nn);
- p.ResolvedOp = BinaryExpr.ResolvedOpcode.Add;
- p.Type = Type.Int;
- return p;
- }
-
- public static Expression Minus(Expression e, int n) {
- Contract.Requires(0 <= n);
-
- var nn = new LiteralExpr(e.tok, n);
- nn.Type = Type.Int;
- var p = new BinaryExpr(e.tok, BinaryExpr.Opcode.Sub, e, nn);
- p.ResolvedOp = BinaryExpr.ResolvedOpcode.Sub;
- p.Type = Type.Int;
- return p;
- }
-
- /// <summary>
- /// Returns the set of free variables in "expr".
- /// Requires "expr" to be successfully resolved.
- /// Ensures that the set returned has no aliases.
- /// </summary>
- static ISet<IVariable> FreeVariables(Expression expr) {
- Contract.Requires(expr != null);
- Contract.Ensures(expr.Type != null);
-
- if (expr is IdentifierExpr) {
- var e = (IdentifierExpr)expr;
- return new HashSet<IVariable>() { e.Var };
-
- } else if (expr is QuantifierExpr) {
- var e = (QuantifierExpr)expr;
- var s = FreeVariables(e.LogicalBody());
- foreach (var bv in e.BoundVars) {
- s.Remove(bv);
- }
- return s;
-
- } else if (expr is MatchExpr) {
- var e = (MatchExpr)expr;
- var s = FreeVariables(e.Source);
- foreach (MatchCaseExpr mc in e.Cases) {
- var t = FreeVariables(mc.Body);
- foreach (var bv in mc.Arguments) {
- t.Remove(bv);
- }
- s.UnionWith(t);
- }
- return s;
-
- } else {
- ISet<IVariable> s = null;
- foreach (var e in expr.SubExpressions) {
- var t = FreeVariables(e);
- if (s == null) {
- s = t;
- } else {
- s.UnionWith(t);
- }
- }
- return s == null ? new HashSet<IVariable>() : s;
- }
- }
-
- void ResolveReceiver(Expression expr, bool twoState) {
- Contract.Requires(expr != null);
- Contract.Ensures(expr.Type != null);
-
- if (expr is ThisExpr && !expr.WasResolved()) {
- // Allow 'this' here, regardless of scope.AllowInstance. The caller is responsible for
- // making sure 'this' does not really get used when it's not available.
- Contract.Assume(currentClass != null); // this is really a precondition, in this case
- expr.Type = GetThisType(expr.tok, currentClass);
- } else {
- ResolveExpression(expr, twoState);
- }
- }
-
- void ResolveSeqSelectExpr(SeqSelectExpr e, bool twoState, bool allowNonUnitArraySelection) {
- Contract.Requires(e != null);
- if (e.Type != null) {
- // already resolved
- return;
- }
-
- bool seqErr = false;
- ResolveExpression(e.Seq, twoState);
- Contract.Assert(e.Seq.Type != null); // follows from postcondition of ResolveExpression
- Type elementType = new InferredTypeProxy();
- Type domainType = new InferredTypeProxy();
-
- IndexableTypeProxy expectedType = new IndexableTypeProxy(elementType, domainType);
- if (!UnifyTypes(e.Seq.Type, expectedType)) {
- Error(e, "sequence/array/map selection requires a sequence, array or map (got {0})", e.Seq.Type);
- seqErr = true;
- }
- if (!e.SelectOne) // require sequence or array
- {
- if (!allowNonUnitArraySelection) {
- // require seq
- if (!UnifyTypes(expectedType, new SeqType(new InferredTypeProxy()))) {
- Error(e, "selection requires a sequence (got {0})", e.Seq.Type);
- }
- } else {
- if (UnifyTypes(expectedType, new MapType(new InferredTypeProxy(), new InferredTypeProxy()))) {
- Error(e, "cannot multiselect a map (got {0} as map type)", e.Seq.Type);
- }
- }
- }
- if (e.E0 != null) {
- ResolveExpression(e.E0, twoState);
- Contract.Assert(e.E0.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E0.Type, domainType)) {
- Error(e.E0, "sequence/array/map selection requires {1} indices (got {0})", e.E0.Type, domainType);
- }
- }
- if (e.E1 != null) {
- ResolveExpression(e.E1, twoState);
- Contract.Assert(e.E1.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(e.E1.Type, domainType)) {
- Error(e.E1, "sequence/array/map selection requires {1} indices (got {0})", e.E1.Type, domainType);
- }
- }
- if (!seqErr) {
- if (e.SelectOne) {
- e.Type = elementType;
- } else {
- e.Type = new SeqType(elementType);
- }
- }
- }
-
- /// <summary>
- /// Note: this method is allowed to be called even if "type" does not make sense for "op", as might be the case if
- /// resolution of the binary expression failed. If so, an arbitrary resolved opcode is returned.
- /// </summary>
- BinaryExpr.ResolvedOpcode ResolveOp(BinaryExpr.Opcode op, Type operandType) {
- Contract.Requires(operandType != null);
- switch (op) {
- case BinaryExpr.Opcode.Iff: return BinaryExpr.ResolvedOpcode.Iff;
- case BinaryExpr.Opcode.Imp: return BinaryExpr.ResolvedOpcode.Imp;
- case BinaryExpr.Opcode.And: return BinaryExpr.ResolvedOpcode.And;
- case BinaryExpr.Opcode.Or: return BinaryExpr.ResolvedOpcode.Or;
- case BinaryExpr.Opcode.Eq:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.SetEq;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSetEq;
- } else if (operandType is SeqType) {
- return BinaryExpr.ResolvedOpcode.SeqEq;
- } else if (operandType is MapType) {
- return BinaryExpr.ResolvedOpcode.MapEq;
- } else {
- return BinaryExpr.ResolvedOpcode.EqCommon;
- }
- case BinaryExpr.Opcode.Neq:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.SetNeq;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSetNeq;
- } else if (operandType is SeqType) {
- return BinaryExpr.ResolvedOpcode.SeqNeq;
- } else if (operandType is MapType) {
- return BinaryExpr.ResolvedOpcode.MapNeq;
- } else {
- return BinaryExpr.ResolvedOpcode.NeqCommon;
- }
- case BinaryExpr.Opcode.Disjoint:
- if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSetDisjoint;
- } else if (operandType is MapType) {
- return BinaryExpr.ResolvedOpcode.MapDisjoint;
- } else {
- return BinaryExpr.ResolvedOpcode.Disjoint;
- }
- case BinaryExpr.Opcode.Lt:
- if (operandType.IsIndDatatype || operandType is DatatypeProxy) {
- return BinaryExpr.ResolvedOpcode.RankLt;
- } else if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.ProperSubset;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.ProperMultiSubset;
- } else if (operandType is SeqType) {
- return BinaryExpr.ResolvedOpcode.ProperPrefix;
- } else {
- return BinaryExpr.ResolvedOpcode.Lt;
- }
- case BinaryExpr.Opcode.Le:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.Subset;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSubset;
- } else if (operandType is SeqType) {
- return BinaryExpr.ResolvedOpcode.Prefix;
- } else {
- return BinaryExpr.ResolvedOpcode.Le;
- }
- case BinaryExpr.Opcode.Add:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.Union;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSetUnion;
- } else if (operandType is MapType) {
- return BinaryExpr.ResolvedOpcode.MapUnion;
- } else if (operandType is SeqType) {
- return BinaryExpr.ResolvedOpcode.Concat;
- } else {
- return BinaryExpr.ResolvedOpcode.Add;
- }
- case BinaryExpr.Opcode.Sub:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.SetDifference;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSetDifference;
- } else {
- return BinaryExpr.ResolvedOpcode.Sub;
- }
- case BinaryExpr.Opcode.Mul:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.Intersection;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSetIntersection;
- } else {
- return BinaryExpr.ResolvedOpcode.Mul;
- }
- case BinaryExpr.Opcode.Gt:
- if (operandType.IsDatatype) {
- return BinaryExpr.ResolvedOpcode.RankGt;
- } else if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.ProperSuperset;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.ProperMultiSuperset;
- } else {
- return BinaryExpr.ResolvedOpcode.Gt;
- }
- case BinaryExpr.Opcode.Ge:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.Superset;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.MultiSuperset;
- } else {
- return BinaryExpr.ResolvedOpcode.Ge;
- }
- case BinaryExpr.Opcode.In:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.InSet;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.InMultiSet;
- } else if (operandType is MapType) {
- return BinaryExpr.ResolvedOpcode.InMap;
- } else {
- return BinaryExpr.ResolvedOpcode.InSeq;
- }
- case BinaryExpr.Opcode.NotIn:
- if (operandType is SetType) {
- return BinaryExpr.ResolvedOpcode.NotInSet;
- } else if (operandType is MultiSetType) {
- return BinaryExpr.ResolvedOpcode.NotInMultiSet;
- } else if (operandType is MapType) {
- return BinaryExpr.ResolvedOpcode.NotInMap;
- } else {
- return BinaryExpr.ResolvedOpcode.NotInSeq;
- }
- case BinaryExpr.Opcode.Div: return BinaryExpr.ResolvedOpcode.Div;
- case BinaryExpr.Opcode.Mod: return BinaryExpr.ResolvedOpcode.Mod;
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected operator
- }
- }
-
- /// <summary>
- /// Returns whether or not 'expr' has any subexpression that uses some feature (like a ghost or quantifier)
- /// that is allowed only in specification contexts.
- /// Requires 'expr' to be a successfully resolved expression.
- /// </summary>
- bool UsesSpecFeatures(Expression expr) {
- Contract.Requires(expr != null);
- Contract.Requires(expr.WasResolved()); // this check approximates the requirement that "expr" be resolved
-
- if (expr is LiteralExpr) {
- return false;
- } else if (expr is ThisExpr) {
- return false;
- } else if (expr is IdentifierExpr) {
- IdentifierExpr e = (IdentifierExpr)expr;
- return cce.NonNull(e.Var).IsGhost;
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- return dtv.Arguments.Exists(arg => UsesSpecFeatures(arg));
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- return e.Elements.Exists(ee => UsesSpecFeatures(ee));
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- return e.Elements.Exists(p => UsesSpecFeatures(p.A) || UsesSpecFeatures(p.B));
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr e = (FieldSelectExpr)expr;
- return cce.NonNull(e.Field).IsGhost || UsesSpecFeatures(e.Obj);
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- return UsesSpecFeatures(e.Seq) ||
- (e.E0 != null && UsesSpecFeatures(e.E0)) ||
- (e.E1 != null && UsesSpecFeatures(e.E1));
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
- return UsesSpecFeatures(e.Array) || e.Indices.Exists(ee => UsesSpecFeatures(ee));
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- return UsesSpecFeatures(e.Seq) ||
- (e.Index != null && UsesSpecFeatures(e.Index)) ||
- (e.Value != null && UsesSpecFeatures(e.Value));
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- if (cce.NonNull(e.Function).IsGhost) {
- return true;
- }
- return e.Args.Exists(arg => UsesSpecFeatures(arg));
- } else if (expr is OldExpr) {
- OldExpr e = (OldExpr)expr;
- return UsesSpecFeatures(e.E);
- } else if (expr is FreshExpr) {
- return true;
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- return UsesSpecFeatures(e.E);
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- if (e.ResolvedOp == BinaryExpr.ResolvedOpcode.RankLt || e.ResolvedOp == BinaryExpr.ResolvedOpcode.RankGt) {
- return true;
- }
- return UsesSpecFeatures(e.E0) || UsesSpecFeatures(e.E1);
- } else if (expr is NamedExpr) {
- return moduleInfo.IsGhost ? false : UsesSpecFeatures(((NamedExpr)expr).Body);
- } else if (expr is ComprehensionExpr) {
- if (expr is QuantifierExpr && ((QuantifierExpr)expr).Bounds == null) {
- return true; // the quantifier cannot be compiled if the resolver found no bounds
- }
- return Contract.Exists(expr.SubExpressions, se => UsesSpecFeatures(se));
- } else if (expr is SetComprehension) {
- var e = (SetComprehension)expr;
- return (e.Range != null && UsesSpecFeatures(e.Range)) || (e.Term != null && UsesSpecFeatures(e.Term));
- } else if (expr is MapComprehension) {
- var e = (MapComprehension)expr;
- return (UsesSpecFeatures(e.Range)) || (UsesSpecFeatures(e.Term));
- } else if (expr is WildcardExpr) {
- return false;
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- return UsesSpecFeatures(e.Body);
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- return UsesSpecFeatures(e.Test) || UsesSpecFeatures(e.Thn) || UsesSpecFeatures(e.Els);
- } else if (expr is MatchExpr) {
- MatchExpr me = (MatchExpr)expr;
- if (UsesSpecFeatures(me.Source)) {
- return true;
- }
- return me.Cases.Exists(mc => UsesSpecFeatures(mc.Body));
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return e.ResolvedExpression != null && UsesSpecFeatures(e.ResolvedExpression);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
- }
-
- class CoCallResolution
- {
- readonly ModuleDefinition currentModule;
- readonly Function currentFunction;
- readonly bool dealsWithCodatatypes;
-
- public CoCallResolution(Function currentFunction, bool dealsWithCodatatypes) {
- Contract.Requires(currentFunction != null);
- this.currentModule = currentFunction.EnclosingClass.Module;
- this.currentFunction = currentFunction;
- this.dealsWithCodatatypes = dealsWithCodatatypes;
- }
-
- /// <summary>
- /// Determines which calls in "expr" can be considered to be co-calls, which co-constructor
- /// invocations host such co-calls, and which destructor operations are not allowed.
- /// Assumes "expr" to have been successfully resolved.
- /// </summary>
- public void CheckCoCalls(Expression expr) {
- Contract.Requires(expr != null);
- var candidates = CheckCoCalls(expr, true, null);
- ProcessCoCallInfo(candidates);
- }
-
- struct CoCallInfo
- {
- public int GuardCount;
- public FunctionCallExpr CandidateCall;
- public DatatypeValue EnclosingCoConstructor;
- public CoCallInfo(int guardCount, FunctionCallExpr candidateCall, DatatypeValue enclosingCoConstructor) {
- Contract.Requires(0 <= guardCount);
- Contract.Requires(candidateCall != null);
-
- GuardCount = guardCount;
- CandidateCall = candidateCall;
- EnclosingCoConstructor = enclosingCoConstructor;
- }
-
- public void AdjustGuardCount(int p) {
- GuardCount += p;
- }
- }
-
- /// <summary>
- /// Recursively goes through the entire "expr". Every call within the same recursive cluster is a potential
- /// co-call. All such calls will get their .CoCall field filled in, indicating whether or not the call
- /// is a co-call. If the situation deals with co-datatypes, then one of the NoBecause... values is chosen (rather
- /// than just No), so that any error message that may later be produced when trying to prove termination of the
- /// recursive call can include a note pointing out that the call was not selected to be a co-call.
- /// "allowCallsWithinRecursiveCluster" is passed in as "false" if the enclosing context has no easy way of
- /// controlling the uses of "expr" (for example, if the enclosing context passes "expr" to a function or binds
- /// "expr" to a variable).
- /// </summary>
- List<CoCallInfo> CheckCoCalls(Expression expr, bool allowCallsWithinRecursiveCluster, DatatypeValue coContext) {
- Contract.Requires(expr != null);
- Contract.Ensures(allowCallsWithinRecursiveCluster || Contract.Result<List<CoCallInfo>>().Count == 0);
-
- var candidates = new List<CoCallInfo>();
- expr = expr.Resolved;
- if (expr is DatatypeValue) {
- var e = (DatatypeValue)expr;
- if (e.Ctor.EnclosingDatatype is CoDatatypeDecl) {
- foreach (var arg in e.Arguments) {
- foreach (var c in CheckCoCalls(arg, allowCallsWithinRecursiveCluster, e)) {
- c.AdjustGuardCount(1);
- candidates.Add(c);
- }
- }
- return candidates;
- }
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- if (e.Field.EnclosingClass is CoDatatypeDecl) {
- foreach (var c in CheckCoCalls(e.Obj, allowCallsWithinRecursiveCluster, null)) {
- if (c.GuardCount <= 1) {
- // This call was not guarded (c.GuardedCount == 0) or the guard for this candidate co-call is
- // being removed (c.GuardedCount == 1), so this call is not allowed as a co-call.
- // (So, don't include "res" among "results".)
- c.CandidateCall.CoCall = FunctionCallExpr.CoCallResolution.NoBecauseIsNotGuarded;
- } else {
- c.AdjustGuardCount(-1);
- candidates.Add(c);
- }
- }
- return candidates;
- }
- } else if (expr is MatchExpr) {
- var e = (MatchExpr)expr;
- var r = CheckCoCalls(e.Source, false, null);
- Contract.Assert(r.Count == 0); // follows from postcondition of CheckCoCalls
- foreach (var kase in e.Cases) {
- r = CheckCoCalls(kase.Body, allowCallsWithinRecursiveCluster, null);
- candidates.AddRange(r);
- }
- return candidates;
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- // First, consider the arguments of the call, making sure that they do not include calls within the recursive cluster.
- // (Note, if functions could have a "destruction level" declaration that promised to only destruct its arguments by
- // so much, then some recursive calls within the cluster could be allowed.)
- foreach (var arg in e.Args) {
- var r = CheckCoCalls(arg, false, null);
- Contract.Assert(r.Count == 0); // follows from postcondition of CheckCoCalls
- }
- // Second, investigate the possibility that this call itself may be a candidate co-call
- if (currentModule.CallGraph.GetSCCRepresentative(currentFunction) == currentModule.CallGraph.GetSCCRepresentative(e.Function)) {
- // This call goes to another function in the same recursive cluster
- if (e.Function.Reads.Count != 0) {
- // this call is disqualified from being a co-call, because of side effects
- if (!dealsWithCodatatypes) {
- e.CoCall = FunctionCallExpr.CoCallResolution.No;
- } else if (coContext != null) {
- e.CoCall = FunctionCallExpr.CoCallResolution.NoBecauseFunctionHasSideEffects;
- } else {
- e.CoCall = FunctionCallExpr.CoCallResolution.NoBecauseIsNotGuarded;
- }
- } else if (!allowCallsWithinRecursiveCluster) {
- if (!dealsWithCodatatypes) {
- e.CoCall = FunctionCallExpr.CoCallResolution.No;
- } else {
- e.CoCall = FunctionCallExpr.CoCallResolution.NoBecauseRecursiveCallsAreNotAllowedInThisContext;
- }
- } else {
- // e.CoCall is not filled in here, but will be filled in when the list of candidates are processed
- candidates.Add(new CoCallInfo(0, e, coContext));
- }
- }
- return candidates;
- } else if (expr is OldExpr) {
- var e = (OldExpr)expr;
- // here, "coContext" is passed along (the use of "old" says this must be ghost code, so the compiler does not need to handle this case)
- return CheckCoCalls(e.E, allowCallsWithinRecursiveCluster, coContext);
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- foreach (var rhs in e.RHSs) {
- var r = CheckCoCalls(rhs, false, null);
- Contract.Assert(r.Count == 0); // follows from postcondition of CheckCoCalls
- }
- return CheckCoCalls(e.Body, allowCallsWithinRecursiveCluster, null);
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- foreach (var ee in e.SubExpressions) {
- var r = CheckCoCalls(ee, false, null);
- Contract.Assert(r.Count == 0); // follows from postcondition of CheckCoCalls
- }
- return candidates;
- }
-
- // Default handling:
- foreach (var ee in expr.SubExpressions) {
- var r = CheckCoCalls(ee, allowCallsWithinRecursiveCluster, null);
- candidates.AddRange(r);
- }
- if (expr.Type is BasicType) {
- // nothing can escape this expression, so process the results now
- ProcessCoCallInfo(candidates);
- candidates.Clear();
- }
- return candidates;
- }
-
- /// <summary>
- /// This method is to be called when it has been determined that all candidate
- /// co-calls in "info" are indeed allowed as co-calls.
- /// </summary>
- void ProcessCoCallInfo(List<CoCallInfo> coCandidates) {
- foreach (var c in coCandidates) {
- if (c.GuardCount != 0) {
- c.CandidateCall.CoCall = FunctionCallExpr.CoCallResolution.Yes;
- c.EnclosingCoConstructor.IsCoCall = true;
- } else if (dealsWithCodatatypes) {
- c.CandidateCall.CoCall = FunctionCallExpr.CoCallResolution.NoBecauseIsNotGuarded;
- } else {
- c.CandidateCall.CoCall = FunctionCallExpr.CoCallResolution.No;
- }
- }
- }
- }
-
- class Scope<Thing> where Thing : class
- {
- [Rep]
- readonly List<string> names = new List<string>(); // a null means a marker
- [Rep]
- readonly List<Thing> things = new List<Thing>();
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(names != null);
- Contract.Invariant(things != null);
- Contract.Invariant(names.Count == things.Count);
- Contract.Invariant(-1 <= scopeSizeWhereInstancesWereDisallowed && scopeSizeWhereInstancesWereDisallowed <= names.Count);
- }
-
- int scopeSizeWhereInstancesWereDisallowed = -1;
-
- public bool AllowInstance {
- get { return scopeSizeWhereInstancesWereDisallowed == -1; }
- set {
- Contract.Requires(AllowInstance && !value); // only allowed to change from true to false (that's all that's currently needed in Dafny); Pop is what can make the change in the other direction
- scopeSizeWhereInstancesWereDisallowed = names.Count;
- }
- }
-
- public void PushMarker() {
- names.Add(null);
- things.Add(null);
- }
-
- public void PopMarker() {
- int n = names.Count;
- while (true) {
- n--;
- if (names[n] == null) {
- break;
- }
- }
- names.RemoveRange(n, names.Count - n);
- things.RemoveRange(n, things.Count - n);
- if (names.Count < scopeSizeWhereInstancesWereDisallowed) {
- scopeSizeWhereInstancesWereDisallowed = -1;
- }
- }
-
- // Pushes name-->thing association and returns "true", if name has not already been pushed since the last marker.
- // If name already has been pushed since the last marker, does nothing and returns "false".
- public bool Push(string name, Thing thing) {
- Contract.Requires(name != null);
- Contract.Requires(thing != null);
- if (Find(name, true) != null) {
- return false;
- } else {
- names.Add(name);
- things.Add(thing);
- return true;
- }
- }
-
- Thing Find(string name, bool topScopeOnly) {
- Contract.Requires(name != null);
- for (int n = names.Count; 0 <= --n; ) {
- if (names[n] == null) {
- if (topScopeOnly) {
- return null; // no present
- }
- } else if (names[n] == name) {
- Thing t = things[n];
- Contract.Assert(t != null);
- return t;
- }
- }
- return null; // not present
- }
-
- public Thing Find(string name) {
- Contract.Requires(name != null);
- return Find(name, false);
- }
-
- public bool ContainsDecl(Thing t) {
- return things.Exists(thing => thing == t);
- }
- }
-}
diff --git a/Source/Dafny/Rewriter.cs b/Source/Dafny/Rewriter.cs
deleted file mode 100644
index c95be2f4..00000000
--- a/Source/Dafny/Rewriter.cs
+++ /dev/null
@@ -1,342 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-
-namespace Microsoft.Dafny
-{
- [ContractClass(typeof(IRewriterContracts))]
- public interface IRewriter
- {
- void PreResolve(ModuleDefinition m);
- void PostResolve(ModuleDefinition m);
- }
- [ContractClassFor(typeof(IRewriter))]
- abstract class IRewriterContracts : IRewriter
- {
- public void PreResolve(ModuleDefinition m) {
- Contract.Requires(m != null);
- }
- public void PostResolve(ModuleDefinition m) {
- Contract.Requires(m != null);
- }
- }
-
- public class AutoGeneratedToken : TokenWrapper
- {
- public AutoGeneratedToken(Boogie.IToken wrappedToken)
- : base(wrappedToken)
- {
- Contract.Requires(wrappedToken != null);
- }
- }
-
- /// <summary>
- /// AutoContracts is an experimental feature that will fill much of the dynamic-frames boilerplate
- /// into a class. From the user's perspective, what needs to be done is simply:
- /// - mark the class with {:autocontracts}
- /// - declare a function (or predicate) called Valid()
- ///
- /// AutoContracts will then:
- ///
- /// Declare:
- /// ghost var Repr: set(object);
- ///
- /// For function/predicate Valid(), insert:
- /// reads this, Repr;
- /// Into body of Valid(), insert (at the beginning of the body):
- /// this in Repr && null !in Repr
- /// and also insert, for every array-valued field A declared in the class:
- /// (A != null ==> A in Repr) &&
- /// and for every field F of a class type T where T has a field called Repr, also insert:
- /// (F != null ==> F in Repr && F.Repr SUBSET Repr && this !in Repr)
- /// Except, if A or F is declared with {:autocontracts false}, then the implication will not
- /// be added.
- ///
- /// For every constructor, add:
- /// modifies this;
- /// ensures Valid() && fresh(Repr - {this});
- /// At the end of the body of the constructor, add:
- /// Repr := {this};
- /// if (A != null) { Repr := Repr + {A}; }
- /// if (F != null) { Repr := Repr + {F} + F.Repr; }
- ///
- /// For every method, add:
- /// requires Valid();
- /// modifies Repr;
- /// ensures Valid() && fresh(Repr - old(Repr));
- /// At the end of the body of the method, add:
- /// if (A != null) { Repr := Repr + {A}; }
- /// if (F != null) { Repr := Repr + {F} + F.Repr; }
- /// </summary>
- public class AutoContractsRewriter : IRewriter
- {
- public void PreResolve(ModuleDefinition m) {
- foreach (var d in m.TopLevelDecls) {
- bool sayYes = true;
- if (d is ClassDecl && Attributes.ContainsBool(d.Attributes, "autocontracts", ref sayYes) && sayYes) {
- ProcessClassPreResolve((ClassDecl)d);
- }
- }
- }
-
- void ProcessClassPreResolve(ClassDecl cl) {
- // Add: ghost var Repr: set<object>;
- // ...unless a field with that name is already present
- if (!cl.Members.Exists(member => member is Field && member.Name == "Repr")) {
- Type ty = new SetType(new ObjectType());
- cl.Members.Add(new Field(new AutoGeneratedToken(cl.tok), "Repr", true, ty, null));
- }
-
- foreach (var member in cl.Members) {
- bool sayYes = true;
- if (Attributes.ContainsBool(member.Attributes, "autocontracts", ref sayYes) && !sayYes) {
- continue;
- }
- Boogie.IToken tok = new AutoGeneratedToken(member.tok);
- if (member is Function && member.Name == "Valid" && !member.IsStatic) {
- var valid = (Function)member;
- // reads this;
- valid.Reads.Add(new FrameExpression(tok, new ThisExpr(tok), null));
- // reads Repr;
- valid.Reads.Add(new FrameExpression(tok, new FieldSelectExpr(tok, new ImplicitThisExpr(tok), "Repr"), null));
- } else if (member is Constructor) {
- var ctor = (Constructor)member;
- // modifies this;
- ctor.Mod.Expressions.Add(new FrameExpression(tok, new ImplicitThisExpr(tok), null));
- // ensures Valid();
- ctor.Ens.Insert(0, new MaybeFreeExpression(new FunctionCallExpr(tok, "Valid", new ImplicitThisExpr(tok), tok, new List<Expression>())));
- // ensures fresh(Repr - {this});
- var freshness = new FreshExpr(tok, new BinaryExpr(tok, BinaryExpr.Opcode.Sub,
- new FieldSelectExpr(tok, new ImplicitThisExpr(tok), "Repr"),
- new SetDisplayExpr(tok, new List<Expression>() { new ThisExpr(tok) })));
- ctor.Ens.Insert(1, new MaybeFreeExpression(freshness));
- } else if (member is Method && !member.IsStatic) {
- var m = (Method)member;
- // requires Valid();
- m.Req.Insert(0, new MaybeFreeExpression(new FunctionCallExpr(tok, "Valid", new ImplicitThisExpr(tok), tok, new List<Expression>())));
- // If this is a mutating method, we should also add a modifies clause and a postcondition, but we don't do that if it's
- // a simple query method. However, we won't know if it's a simple query method until after resolution, so we'll add the
- // rest of the spec then.
- }
- }
- }
-
- public void PostResolve(ModuleDefinition m) {
- foreach (var d in m.TopLevelDecls) {
- bool sayYes = true;
- if (d is ClassDecl && Attributes.ContainsBool(d.Attributes, "autocontracts", ref sayYes) && sayYes) {
- ProcessClassPostResolve((ClassDecl)d);
- }
- }
- }
-
- void ProcessClassPostResolve(ClassDecl cl) {
- // Find all fields of a reference type, and make a note of whether or not the reference type has a Repr field.
- // Also, find the Repr field and the function Valid in class "cl"
- Field ReprField = null;
- Function Valid = null;
- var subobjects = new List<Tuple<Field, Field>>();
- foreach (var member in cl.Members) {
- var field = member as Field;
- if (field != null) {
- bool sayYes = true;
- if (field.Name == "Repr") {
- ReprField = field;
- } else if (Attributes.ContainsBool(field.Attributes, "autocontracts", ref sayYes) && !sayYes) {
- // ignore this field
- } else if (field.Type is ObjectType) {
- subobjects.Add(new Tuple<Field, Field>(field, null));
- } else if (field.Type.IsRefType) {
- var rcl = (ClassDecl)((UserDefinedType)field.Type).ResolvedClass;
- Field rRepr = null;
- foreach (var memb in rcl.Members) {
- var f = memb as Field;
- if (f != null && f.Name == "Repr") {
- rRepr = f;
- break;
- }
- }
- subobjects.Add(new Tuple<Field, Field>(field, rRepr));
- }
- } else if (member is Function && member.Name == "Valid" && !member.IsStatic) {
- var fn = (Function)member;
- if (fn.Formals.Count == 0 && fn.ResultType is BoolType) {
- Valid = fn;
- }
- }
- }
- Contract.Assert(ReprField != null); // we expect there to be a "Repr" field, since we added one in PreResolve
-
- Boogie.IToken clTok = new AutoGeneratedToken(cl.tok);
- Type ty = new UserDefinedType(clTok, cl.Name, cl, new List<Type>());
- var self = new ThisExpr(clTok);
- self.Type = ty;
- var implicitSelf = new ImplicitThisExpr(clTok);
- implicitSelf.Type = ty;
- var Repr = new FieldSelectExpr(clTok, implicitSelf, "Repr");
- Repr.Field = ReprField;
- Repr.Type = ReprField.Type;
- var cNull = new LiteralExpr(clTok);
- cNull.Type = new ObjectType();
-
- foreach (var member in cl.Members) {
- bool sayYes = true;
- if (Attributes.ContainsBool(member.Attributes, "autocontracts", ref sayYes) && !sayYes) {
- continue;
- }
- Boogie.IToken tok = new AutoGeneratedToken(member.tok);
- if (member is Function && member.Name == "Valid" && !member.IsStatic) {
- var valid = (Function)member;
- if (valid.IsGhost && valid.ResultType is BoolType) {
- var c0 = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.InSet, self, Repr); // this in Repr
- var c1 = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.NotInSet, cNull, Repr); // null !in Repr
- var c = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.And, c0, c1);
-
- foreach (var ff in subobjects) {
- var F = new FieldSelectExpr(tok, implicitSelf, ff.Item1.Name);
- F.Field = ff.Item1;
- F.Type = ff.Item1.Type;
-
- c0 = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.NeqCommon, F, cNull);
- c1 = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.InSet, F, Repr);
- if (ff.Item2 == null) {
- // F != null ==> F in Repr (so, nothing else to do)
- } else {
- // F != null ==> F in Repr && F.Repr <= Repr && this !in F.Repr
- var FRepr = new FieldSelectExpr(tok, F, ff.Item2.Name);
- FRepr.Field = ff.Item2;
- FRepr.Type = ff.Item2.Type;
- var c2 = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.Subset, FRepr, Repr);
- var c3 = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.NotInSet, self, FRepr);
- c1 = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.And, c1, BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.And, c2, c3));
- }
- c = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.And, c, BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.Imp, c0, c1));
- }
-
- if (valid.Body == null) {
- valid.Body = c;
- } else {
- valid.Body = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.And, c, valid.Body);
- }
- }
-
- } else if (member is Constructor) {
- var ctor = (Constructor)member;
- if (ctor.Body == null) {
- ctor.Body = new BlockStmt(tok, new List<Statement>());
- }
- // TODO: these assignments should be included on every return path
- var bodyStatements = ((BlockStmt)ctor.Body).Body;
- // Repr := {this};
- var e = new SetDisplayExpr(tok, new List<Expression>() { self });
- e.Type = new SetType(new ObjectType());
- Statement s = new AssignStmt(tok, Repr, new ExprRhs(e));
- s.IsGhost = true;
- bodyStatements.Add(s);
-
- AddSubobjectReprs(tok, subobjects, bodyStatements, self, implicitSelf, cNull, Repr);
-
- } else if (member is Method && !member.IsStatic) {
- var m = (Method)member;
- if (Valid != null && !IsSimpleQueryMethod(m)) {
- // modifies Repr;
- m.Mod.Expressions.Add(new FrameExpression(Repr.tok, Repr, null));
- // ensures Valid();
- var valid = new FunctionCallExpr(tok, "Valid", implicitSelf, tok, new List<Expression>());
- valid.Function = Valid;
- valid.Type = Type.Bool;
- m.Ens.Insert(0, new MaybeFreeExpression(valid));
- // ensures fresh(Repr - old(Repr));
- var e0 = new OldExpr(tok, Repr);
- e0.Type = Repr.Type;
- var e1 = new BinaryExpr(tok, BinaryExpr.Opcode.Sub, Repr, e0);
- e1.ResolvedOp = BinaryExpr.ResolvedOpcode.SetDifference;
- e1.Type = Repr.Type;
- var freshness = new FreshExpr(tok, e1);
- freshness.Type = Type.Bool;
- m.Ens.Insert(1, new MaybeFreeExpression(freshness));
-
- if (m.Body == null) {
- m.Body = new BlockStmt(tok, new List<Statement>());
- }
- // TODO: these assignments should be included on every return path
- var bodyStatements = ((BlockStmt)m.Body).Body;
- AddSubobjectReprs(tok, subobjects, bodyStatements, self, implicitSelf, cNull, Repr);
- }
- }
- }
- }
-
- void AddSubobjectReprs(Boogie.IToken tok, List<Tuple<Field, Field>> subobjects, List<Statement> bodyStatements,
- Expression self, Expression implicitSelf, Expression cNull, Expression Repr) {
-
- foreach (var ff in subobjects) {
- var F = new FieldSelectExpr(tok, implicitSelf, ff.Item1.Name);
- F.Field = ff.Item1;
- F.Type = ff.Item1.Type;
-
- Expression e = new SetDisplayExpr(tok, new List<Expression>() { F });
- e.Type = new SetType(new ObjectType());
- var rhs = new BinaryExpr(tok, BinaryExpr.Opcode.Add, Repr, e);
- rhs.ResolvedOp = BinaryExpr.ResolvedOpcode.Union;
- rhs.Type = Repr.Type;
- if (ff.Item2 == null) {
- // Repr := Repr + {F} (so, nothing else to do)
- } else {
- // Repr := Repr + {F} + F.Repr
- var FRepr = new FieldSelectExpr(tok, F, ff.Item2.Name);
- FRepr.Field = ff.Item2;
- FRepr.Type = ff.Item2.Type;
- rhs = new BinaryExpr(tok, BinaryExpr.Opcode.Add, rhs, FRepr);
- rhs.ResolvedOp = BinaryExpr.ResolvedOpcode.Union;
- rhs.Type = Repr.Type;
- }
- // Repr := Repr + ...;
- Statement s = new AssignStmt(tok, Repr, new ExprRhs(rhs));
- s.IsGhost = true;
- // wrap if statement around s
- e = BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.NeqCommon, F, cNull);
- var thn = new BlockStmt(tok, new List<Statement>() { s });
- thn.IsGhost = true;
- s = new IfStmt(tok, e, thn, null);
- s.IsGhost = true;
- // finally, add s to the body
- bodyStatements.Add(s);
- }
- }
-
- bool IsSimpleQueryMethod(Method m) {
- // A simple query method has out parameters, its body has no effect other than to assign to them,
- // and the postcondition does not explicitly mention the pre-state.
- return m.Outs.Count != 0 && m.Body != null && LocalAssignsOnly(m.Body) &&
- m.Ens.TrueForAll(mfe => !Translator.MentionsOldState(mfe.E));
- }
-
- bool LocalAssignsOnly(Statement s) {
- Contract.Requires(s != null);
- if (s is AssignStmt) {
- var ss = (AssignStmt)s;
- return ss.Lhs.Resolved is IdentifierExpr;
- } else if (s is ConcreteUpdateStatement) {
- var ss = (ConcreteUpdateStatement)s;
- return ss.Lhss.TrueForAll(e => e.Resolved is IdentifierExpr);
- } else if (s is CallStmt) {
- return false;
- } else {
- foreach (var ss in s.SubStatements) {
- if (!LocalAssignsOnly(ss)) {
- return false;
- }
- }
- }
- return true;
- }
-
- public static BinaryExpr BinBoolExpr(Boogie.IToken tok, BinaryExpr.ResolvedOpcode rop, Expression e0, Expression e1) {
- var p = new BinaryExpr(tok, BinaryExpr.ResolvedOp2SyntacticOp(rop), e0, e1);
- p.ResolvedOp = rop;
- p.Type = Type.Bool;
- return p;
- }
- }
-}
diff --git a/Source/Dafny/Scanner.cs b/Source/Dafny/Scanner.cs
deleted file mode 100644
index b23931b6..00000000
--- a/Source/Dafny/Scanner.cs
+++ /dev/null
@@ -1,823 +0,0 @@
-
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Diagnostics.Contracts;
-using Microsoft.Boogie;
-
-
-namespace Microsoft.Dafny {
-
-//-----------------------------------------------------------------------------------
-// Buffer
-//-----------------------------------------------------------------------------------
-public class Buffer {
- // This Buffer supports the following cases:
- // 1) seekable stream (file)
- // a) whole stream in buffer
- // b) part of stream in buffer
- // 2) non seekable stream (network, console)
-
- public const int EOF = 65535 + 1; // char.MaxValue + 1;
- const int MIN_BUFFER_LENGTH = 1024; // 1KB
- const int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
- byte[]/*!*/ buf; // input buffer
- int bufStart; // position of first byte in buffer relative to input stream
- int bufLen; // length of buffer
- int fileLen; // length of input stream (may change if the stream is no file)
- int bufPos; // current position in buffer
- Stream/*!*/ stream; // input stream (seekable)
- bool isUserStream; // was the stream opened by the user?
-
- [ContractInvariantMethod]
- void ObjectInvariant(){
- Contract.Invariant(buf != null);
- Contract.Invariant(stream != null);
- }
-
-// [NotDelayed]
- public Buffer (Stream/*!*/ s, bool isUserStream) : base() {
- Contract.Requires(s != null);
- stream = s; this.isUserStream = isUserStream;
-
- int fl, bl;
- if (s.CanSeek) {
- fl = (int) s.Length;
- bl = fl < MAX_BUFFER_LENGTH ? fl : MAX_BUFFER_LENGTH; // Math.Min(fileLen, MAX_BUFFER_LENGTH);
- bufStart = Int32.MaxValue; // nothing in the buffer so far
- } else {
- fl = bl = bufStart = 0;
- }
-
- buf = new byte[(bl>0) ? bl : MIN_BUFFER_LENGTH];
- fileLen = fl; bufLen = bl;
-
- if (fileLen > 0) Pos = 0; // setup buffer to position 0 (start)
- else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
- if (bufLen == fileLen && s.CanSeek) Close();
- }
-
- protected Buffer(Buffer/*!*/ b) { // called in UTF8Buffer constructor
- Contract.Requires(b != null);
- buf = b.buf;
- bufStart = b.bufStart;
- bufLen = b.bufLen;
- fileLen = b.fileLen;
- bufPos = b.bufPos;
- stream = b.stream;
- // keep destructor from closing the stream
- //b.stream = null;
- isUserStream = b.isUserStream;
- // keep destructor from closing the stream
- b.isUserStream = true;
- }
-
- ~Buffer() { Close(); }
-
- protected void Close() {
- if (!isUserStream && stream != null) {
- stream.Close();
- //stream = null;
- }
- }
-
- public virtual int Read () {
- if (bufPos < bufLen) {
- return buf[bufPos++];
- } else if (Pos < fileLen) {
- Pos = Pos; // shift buffer start to Pos
- return buf[bufPos++];
- } else if (stream != null && !stream.CanSeek && ReadNextStreamChunk() > 0) {
- return buf[bufPos++];
- } else {
- return EOF;
- }
- }
-
- public int Peek () {
- int curPos = Pos;
- int ch = Read();
- Pos = curPos;
- return ch;
- }
-
- public string/*!*/ GetString (int beg, int end) {
- Contract.Ensures(Contract.Result<string>() != null);
- int len = 0;
- char[] buf = new char[end - beg];
- int oldPos = Pos;
- Pos = beg;
- while (Pos < end) buf[len++] = (char) Read();
- Pos = oldPos;
- return new String(buf, 0, len);
- }
-
- public int Pos {
- get { return bufPos + bufStart; }
- set {
- if (value >= fileLen && stream != null && !stream.CanSeek) {
- // Wanted position is after buffer and the stream
- // is not seek-able e.g. network or console,
- // thus we have to read the stream manually till
- // the wanted position is in sight.
- while (value >= fileLen && ReadNextStreamChunk() > 0);
- }
-
- if (value < 0 || value > fileLen) {
- throw new FatalError("buffer out of bounds access, position: " + value);
- }
-
- if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
- bufPos = value - bufStart;
- } else if (stream != null) { // must be swapped in
- stream.Seek(value, SeekOrigin.Begin);
- bufLen = stream.Read(buf, 0, buf.Length);
- bufStart = value; bufPos = 0;
- } else {
- // set the position to the end of the file, Pos will return fileLen.
- bufPos = fileLen - bufStart;
- }
- }
- }
-
- // Read the next chunk of bytes from the stream, increases the buffer
- // if needed and updates the fields fileLen and bufLen.
- // Returns the number of bytes read.
- private int ReadNextStreamChunk() {
- int free = buf.Length - bufLen;
- if (free == 0) {
- // in the case of a growing input stream
- // we can neither seek in the stream, nor can we
- // foresee the maximum length, thus we must adapt
- // the buffer size on demand.
- byte[] newBuf = new byte[bufLen * 2];
- Array.Copy(buf, newBuf, bufLen);
- buf = newBuf;
- free = bufLen;
- }
- int read = stream.Read(buf, bufLen, free);
- if (read > 0) {
- fileLen = bufLen = (bufLen + read);
- return read;
- }
- // end of stream reached
- return 0;
- }
-}
-
-//-----------------------------------------------------------------------------------
-// UTF8Buffer
-//-----------------------------------------------------------------------------------
-public class UTF8Buffer: Buffer {
- public UTF8Buffer(Buffer/*!*/ b): base(b) {Contract.Requires(b != null);}
-
- public override int Read() {
- int ch;
- do {
- ch = base.Read();
- // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
- } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
- if (ch < 128 || ch == EOF) {
- // nothing to do, first 127 chars are the same in ascii and utf8
- // 0xxxxxxx or end of file character
- } else if ((ch & 0xF0) == 0xF0) {
- // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- int c1 = ch & 0x07; ch = base.Read();
- int c2 = ch & 0x3F; ch = base.Read();
- int c3 = ch & 0x3F; ch = base.Read();
- int c4 = ch & 0x3F;
- ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
- } else if ((ch & 0xE0) == 0xE0) {
- // 1110xxxx 10xxxxxx 10xxxxxx
- int c1 = ch & 0x0F; ch = base.Read();
- int c2 = ch & 0x3F; ch = base.Read();
- int c3 = ch & 0x3F;
- ch = (((c1 << 6) | c2) << 6) | c3;
- } else if ((ch & 0xC0) == 0xC0) {
- // 110xxxxx 10xxxxxx
- int c1 = ch & 0x1F; ch = base.Read();
- int c2 = ch & 0x3F;
- ch = (c1 << 6) | c2;
- }
- return ch;
- }
-}
-
-//-----------------------------------------------------------------------------------
-// Scanner
-//-----------------------------------------------------------------------------------
-public class Scanner {
- const char EOL = '\n';
- const int eofSym = 0; /* pdt */
- const int maxT = 115;
- const int noSym = 115;
-
-
- [ContractInvariantMethod]
- void objectInvariant(){
- Contract.Invariant(buffer!=null);
- Contract.Invariant(t != null);
- Contract.Invariant(start != null);
- Contract.Invariant(tokens != null);
- Contract.Invariant(pt != null);
- Contract.Invariant(tval != null);
- Contract.Invariant(Filename != null);
- Contract.Invariant(errorHandler != null);
- }
-
- public Buffer/*!*/ buffer; // scanner buffer
-
- Token/*!*/ t; // current token
- int ch; // current input character
- int pos; // byte position of current character
- int charPos;
- int col; // column number of current character
- int line; // line number of current character
- int oldEols; // EOLs that appeared in a comment;
- static readonly Hashtable/*!*/ start; // maps first token character to start state
-
- Token/*!*/ tokens; // list of tokens already peeked (first token is a dummy)
- Token/*!*/ pt; // current peek token
-
- char[]/*!*/ tval = new char[128]; // text of current token
- int tlen; // length of current token
-
- private string/*!*/ Filename;
- private Errors/*!*/ errorHandler;
-
- static Scanner() {
- start = new Hashtable(128);
- for (int i = 39; i <= 39; ++i) start[i] = 1;
- for (int i = 63; i <= 63; ++i) start[i] = 1;
- for (int i = 65; i <= 90; ++i) start[i] = 1;
- for (int i = 92; i <= 92; ++i) start[i] = 1;
- for (int i = 95; i <= 95; ++i) start[i] = 1;
- for (int i = 98; i <= 122; ++i) start[i] = 1;
- for (int i = 48; i <= 57; ++i) start[i] = 7;
- for (int i = 34; i <= 34; ++i) start[i] = 8;
- start[97] = 12;
- start[58] = 56;
- start[123] = 10;
- start[125] = 11;
- start[61] = 57;
- start[59] = 19;
- start[46] = 58;
- start[124] = 59;
- start[44] = 20;
- start[40] = 21;
- start[41] = 22;
- start[60] = 60;
- start[62] = 61;
- start[42] = 24;
- start[96] = 25;
- start[91] = 28;
- start[93] = 29;
- start[33] = 62;
- start[8800] = 33;
- start[8804] = 34;
- start[8805] = 35;
- start[8660] = 38;
- start[8658] = 40;
- start[38] = 41;
- start[8743] = 43;
- start[8744] = 45;
- start[43] = 47;
- start[45] = 48;
- start[47] = 49;
- start[37] = 50;
- start[172] = 51;
- start[8704] = 52;
- start[8707] = 53;
- start[8226] = 55;
- start[Buffer.EOF] = -1;
-
- }
-
-// [NotDelayed]
- public Scanner (string/*!*/ fileName, Errors/*!*/ errorHandler) : base() {
- Contract.Requires(fileName != null);
- Contract.Requires(errorHandler != null);
- this.errorHandler = errorHandler;
- pt = tokens = new Token(); // first token is a dummy
- t = new Token(); // dummy because t is a non-null field
- try {
- Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
- buffer = new Buffer(stream, false);
- Filename = fileName;
- Init();
- } catch (IOException) {
- throw new FatalError("Cannot open file " + fileName);
- }
- }
-
-// [NotDelayed]
- public Scanner (Stream/*!*/ s, Errors/*!*/ errorHandler, string/*!*/ fileName) : base() {
- Contract.Requires(s != null);
- Contract.Requires(errorHandler != null);
- Contract.Requires(fileName != null);
- pt = tokens = new Token(); // first token is a dummy
- t = new Token(); // dummy because t is a non-null field
- buffer = new Buffer(s, true);
- this.errorHandler = errorHandler;
- this.Filename = fileName;
- Init();
- }
-
- void Init() {
- pos = -1; line = 1; col = 0;
- oldEols = 0;
- NextCh();
- if (ch == 0xEF) { // check optional byte order mark for UTF-8
- NextCh(); int ch1 = ch;
- NextCh(); int ch2 = ch;
- if (ch1 != 0xBB || ch2 != 0xBF) {
- throw new FatalError(String.Format("illegal byte order mark: EF {0,2:X} {1,2:X}", ch1, ch2));
- }
- buffer = new UTF8Buffer(buffer); col = 0;
- NextCh();
- }
- pt = tokens = new Token(); // first token is a dummy
- }
-
- string/*!*/ ReadToEOL(){
- Contract.Ensures(Contract.Result<string>() != null);
- int p = buffer.Pos;
- int ch = buffer.Read();
- // replace isolated '\r' by '\n' in order to make
- // eol handling uniform across Windows, Unix and Mac
- if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
- while (ch != EOL && ch != Buffer.EOF){
- ch = buffer.Read();
- // replace isolated '\r' by '\n' in order to make
- // eol handling uniform across Windows, Unix and Mac
- if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
- }
- string/*!*/ s = buffer.GetString(p, buffer.Pos);
- Contract.Assert(s!=null);
- return s;
- }
-
- void NextCh() {
- if (oldEols > 0) { ch = EOL; oldEols--; }
- else {
-// pos = buffer.Pos;
-// ch = buffer.Read(); col++;
-// // replace isolated '\r' by '\n' in order to make
-// // eol handling uniform across Windows, Unix and Mac
-// if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
-// if (ch == EOL) { line++; col = 0; }
-
- while (true) {
- pos = buffer.Pos;
- ch = buffer.Read(); col++;
- // replace isolated '\r' by '\n' in order to make
- // eol handling uniform across Windows, Unix and Mac
- if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
- if (ch == EOL) {
- line++; col = 0;
- } else if (ch == '#' && col == 1) {
- int prLine = line;
- int prColumn = 0;
-
- string/*!*/ hashLine = ReadToEOL();
- Contract.Assert(hashLine!=null);
- col = 0;
- line++;
-
- hashLine = hashLine.TrimEnd(null);
- if (hashLine.StartsWith("line ") || hashLine == "line") {
- // parse #line pragma: #line num [filename]
- string h = hashLine.Substring(4).TrimStart(null);
- int x = h.IndexOf(' ');
- if (x == -1) {
- x = h.Length; // this will be convenient below when we look for a filename
- }
- try {
- int li = int.Parse(h.Substring(0, x));
-
- h = h.Substring(x).Trim();
-
- // act on #line
- line = li;
- if (h.Length != 0) {
- // a filename was specified
- Filename = h;
- }
- continue; // successfully parsed and acted on the #line pragma
-
- } catch (FormatException) {
- // just fall down through to produce an error message
- }
- this.errorHandler.SemErr(Filename, prLine, prColumn, "Malformed (#line num [filename]) pragma: #" + hashLine);
- continue;
- }
-
- this.errorHandler.SemErr(Filename, prLine, prColumn, "Unrecognized pragma: #" + hashLine);
- continue;
- }
- return;
- }
-
-
- }
-
- }
-
- void AddCh() {
- if (tlen >= tval.Length) {
- char[] newBuf = new char[2 * tval.Length];
- Array.Copy(tval, 0, newBuf, 0, tval.Length);
- tval = newBuf;
- }
- if (ch != Buffer.EOF) {
- tval[tlen++] = (char) ch;
- NextCh();
- }
- }
-
-
-
- bool Comment0() {
- int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
- NextCh();
- if (ch == '/') {
- NextCh();
- for(;;) {
- if (ch == 10) {
- level--;
- if (level == 0) { oldEols = line - line0; NextCh(); return true; }
- NextCh();
- } else if (ch == Buffer.EOF) return false;
- else NextCh();
- }
- } else {
- buffer.Pos = pos0; NextCh(); line = line0; col = col0; charPos = charPos0;
- }
- return false;
- }
-
- bool Comment1() {
- int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
- NextCh();
- if (ch == '*') {
- NextCh();
- for(;;) {
- if (ch == '*') {
- NextCh();
- if (ch == '/') {
- level--;
- if (level == 0) { oldEols = line - line0; NextCh(); return true; }
- NextCh();
- }
- } else if (ch == '/') {
- NextCh();
- if (ch == '*') {
- level++; NextCh();
- }
- } else if (ch == Buffer.EOF) return false;
- else NextCh();
- }
- } else {
- buffer.Pos = pos0; NextCh(); line = line0; col = col0; charPos = charPos0;
- }
- return false;
- }
-
-
- void CheckLiteral() {
- switch (t.val) {
- case "ghost": t.kind = 8; break;
- case "module": t.kind = 9; break;
- case "refines": t.kind = 10; break;
- case "import": t.kind = 11; break;
- case "opened": t.kind = 12; break;
- case "as": t.kind = 15; break;
- case "default": t.kind = 16; break;
- case "class": t.kind = 18; break;
- case "static": t.kind = 19; break;
- case "datatype": t.kind = 20; break;
- case "codatatype": t.kind = 21; break;
- case "var": t.kind = 23; break;
- case "type": t.kind = 25; break;
- case "iterator": t.kind = 29; break;
- case "yields": t.kind = 30; break;
- case "method": t.kind = 34; break;
- case "constructor": t.kind = 35; break;
- case "returns": t.kind = 36; break;
- case "modifies": t.kind = 37; break;
- case "free": t.kind = 38; break;
- case "requires": t.kind = 39; break;
- case "ensures": t.kind = 40; break;
- case "decreases": t.kind = 41; break;
- case "reads": t.kind = 42; break;
- case "yield": t.kind = 43; break;
- case "bool": t.kind = 44; break;
- case "nat": t.kind = 45; break;
- case "int": t.kind = 46; break;
- case "set": t.kind = 47; break;
- case "multiset": t.kind = 48; break;
- case "seq": t.kind = 49; break;
- case "map": t.kind = 50; break;
- case "object": t.kind = 51; break;
- case "function": t.kind = 52; break;
- case "predicate": t.kind = 53; break;
- case "copredicate": t.kind = 54; break;
- case "label": t.kind = 57; break;
- case "break": t.kind = 58; break;
- case "where": t.kind = 59; break;
- case "return": t.kind = 61; break;
- case "assume": t.kind = 63; break;
- case "new": t.kind = 64; break;
- case "choose": t.kind = 67; break;
- case "if": t.kind = 68; break;
- case "else": t.kind = 69; break;
- case "case": t.kind = 70; break;
- case "while": t.kind = 72; break;
- case "invariant": t.kind = 73; break;
- case "match": t.kind = 74; break;
- case "assert": t.kind = 75; break;
- case "print": t.kind = 76; break;
- case "parallel": t.kind = 77; break;
- case "calc": t.kind = 78; break;
- case "in": t.kind = 94; break;
- case "false": t.kind = 101; break;
- case "true": t.kind = 102; break;
- case "null": t.kind = 103; break;
- case "this": t.kind = 104; break;
- case "fresh": t.kind = 105; break;
- case "old": t.kind = 106; break;
- case "then": t.kind = 107; break;
- case "forall": t.kind = 109; break;
- case "exists": t.kind = 111; break;
- default: break;
- }
- }
-
- Token/*!*/ NextToken() {
- Contract.Ensures(Contract.Result<Token>() != null);
- while (ch == ' ' ||
- ch >= 9 && ch <= 10 || ch == 13
- ) NextCh();
- if (ch == '/' && Comment0() ||ch == '/' && Comment1()) return NextToken();
- int recKind = noSym;
- int recEnd = pos;
- t = new Token();
- t.pos = pos; t.col = col; t.line = line;
- t.filename = this.Filename;
- int state;
- if (start.ContainsKey(ch)) {
- Contract.Assert(start[ch] != null);
- state = (int) start[ch];
- }
- else { state = 0; }
- tlen = 0; AddCh();
-
- switch (state) {
- case -1: { t.kind = eofSym; break; } // NextCh already done
- case 0: {
- if (recKind != noSym) {
- tlen = recEnd - t.pos;
- SetScannerBehindT();
- }
- t.kind = recKind; break;
- } // NextCh already done
- case 1:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 1;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 2:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 2;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 3:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 3;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 4:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 4;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 5:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 5;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 6:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 6;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 7:
- recEnd = pos; recKind = 2;
- if (ch >= '0' && ch <= '9') {AddCh(); goto case 7;}
- else {t.kind = 2; break;}
- case 8:
- if (ch == '"') {AddCh(); goto case 9;}
- else if (ch >= ' ' && ch <= '!' || ch >= '#' && ch <= '~') {AddCh(); goto case 8;}
- else {goto case 0;}
- case 9:
- {t.kind = 4; break;}
- case 10:
- {t.kind = 6; break;}
- case 11:
- {t.kind = 7; break;}
- case 12:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'q' || ch >= 's' && ch <= 'z') {AddCh(); goto case 2;}
- else if (ch == 'r') {AddCh(); goto case 14;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 13:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 13;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 14:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'q' || ch >= 's' && ch <= 'z') {AddCh(); goto case 3;}
- else if (ch == 'r') {AddCh(); goto case 15;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 15:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'b' && ch <= 'z') {AddCh(); goto case 4;}
- else if (ch == 'a') {AddCh(); goto case 16;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 16:
- recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'x' || ch == 'z') {AddCh(); goto case 5;}
- else if (ch == 'y') {AddCh(); goto case 17;}
- else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 17:
- recEnd = pos; recKind = 3;
- if (ch == 39 || ch == '0' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 6;}
- else if (ch >= '1' && ch <= '9') {AddCh(); goto case 18;}
- else {t.kind = 3; break;}
- case 18:
- recEnd = pos; recKind = 3;
- if (ch == 39 || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 13;}
- else if (ch >= '0' && ch <= '9') {AddCh(); goto case 18;}
- else {t.kind = 3; break;}
- case 19:
- {t.kind = 14; break;}
- case 20:
- {t.kind = 24; break;}
- case 21:
- {t.kind = 26; break;}
- case 22:
- {t.kind = 28; break;}
- case 23:
- {t.kind = 31; break;}
- case 24:
- {t.kind = 55; break;}
- case 25:
- {t.kind = 56; break;}
- case 26:
- {t.kind = 60; break;}
- case 27:
- {t.kind = 62; break;}
- case 28:
- {t.kind = 65; break;}
- case 29:
- {t.kind = 66; break;}
- case 30:
- {t.kind = 71; break;}
- case 31:
- {t.kind = 80; break;}
- case 32:
- {t.kind = 81; break;}
- case 33:
- {t.kind = 82; break;}
- case 34:
- {t.kind = 83; break;}
- case 35:
- {t.kind = 84; break;}
- case 36:
- if (ch == '>') {AddCh(); goto case 37;}
- else {goto case 0;}
- case 37:
- {t.kind = 85; break;}
- case 38:
- {t.kind = 86; break;}
- case 39:
- {t.kind = 87; break;}
- case 40:
- {t.kind = 88; break;}
- case 41:
- if (ch == '&') {AddCh(); goto case 42;}
- else {goto case 0;}
- case 42:
- {t.kind = 89; break;}
- case 43:
- {t.kind = 90; break;}
- case 44:
- {t.kind = 91; break;}
- case 45:
- {t.kind = 92; break;}
- case 46:
- {t.kind = 93; break;}
- case 47:
- {t.kind = 96; break;}
- case 48:
- {t.kind = 97; break;}
- case 49:
- {t.kind = 98; break;}
- case 50:
- {t.kind = 99; break;}
- case 51:
- {t.kind = 100; break;}
- case 52:
- {t.kind = 110; break;}
- case 53:
- {t.kind = 112; break;}
- case 54:
- {t.kind = 113; break;}
- case 55:
- {t.kind = 114; break;}
- case 56:
- recEnd = pos; recKind = 5;
- if (ch == '=') {AddCh(); goto case 26;}
- else if (ch == '|') {AddCh(); goto case 27;}
- else if (ch == ':') {AddCh(); goto case 54;}
- else {t.kind = 5; break;}
- case 57:
- recEnd = pos; recKind = 13;
- if (ch == '=') {AddCh(); goto case 63;}
- else if (ch == '>') {AddCh(); goto case 30;}
- else {t.kind = 13; break;}
- case 58:
- recEnd = pos; recKind = 17;
- if (ch == '.') {AddCh(); goto case 64;}
- else {t.kind = 17; break;}
- case 59:
- recEnd = pos; recKind = 22;
- if (ch == '|') {AddCh(); goto case 44;}
- else {t.kind = 22; break;}
- case 60:
- recEnd = pos; recKind = 32;
- if (ch == '=') {AddCh(); goto case 65;}
- else {t.kind = 32; break;}
- case 61:
- recEnd = pos; recKind = 33;
- if (ch == '=') {AddCh(); goto case 31;}
- else {t.kind = 33; break;}
- case 62:
- recEnd = pos; recKind = 95;
- if (ch == '=') {AddCh(); goto case 32;}
- else if (ch == '!') {AddCh(); goto case 46;}
- else {t.kind = 95; break;}
- case 63:
- recEnd = pos; recKind = 27;
- if (ch == '>') {AddCh(); goto case 39;}
- else {t.kind = 27; break;}
- case 64:
- recEnd = pos; recKind = 108;
- if (ch == '.') {AddCh(); goto case 23;}
- else {t.kind = 108; break;}
- case 65:
- recEnd = pos; recKind = 79;
- if (ch == '=') {AddCh(); goto case 36;}
- else {t.kind = 79; break;}
-
- }
- t.val = new String(tval, 0, tlen);
- return t;
- }
-
- private void SetScannerBehindT() {
- buffer.Pos = t.pos;
- NextCh();
- line = t.line; col = t.col;
- for (int i = 0; i < tlen; i++) NextCh();
- }
-
- // get the next token (possibly a token already seen during peeking)
- public Token/*!*/ Scan () {
- Contract.Ensures(Contract.Result<Token>() != null);
- if (tokens.next == null) {
- return NextToken();
- } else {
- pt = tokens = tokens.next;
- return tokens;
- }
- }
-
- // peek for the next token, ignore pragmas
- public Token/*!*/ Peek () {
- Contract.Ensures(Contract.Result<Token>() != null);
- do {
- if (pt.next == null) {
- pt.next = NextToken();
- }
- pt = pt.next;
- } while (pt.kind > maxT); // skip pragmas
-
- return pt;
- }
-
- // make sure that peeking starts at the current scan position
- public void ResetPeek () { pt = tokens; }
-
-} // end Scanner
-
-public delegate void ErrorProc(int n, string filename, int line, int col);
-
-
-} \ No newline at end of file
diff --git a/Source/Dafny/SccGraph.cs b/Source/Dafny/SccGraph.cs
deleted file mode 100644
index 4ae1c185..00000000
--- a/Source/Dafny/SccGraph.cs
+++ /dev/null
@@ -1,370 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-
-namespace Microsoft.Dafny {
-
- public class Graph<Node> where Node : class
- {
- enum VisitedStatus { Unvisited, OnStack, Visited }
- class Vertex {
- public readonly Node N;
- public readonly List<Vertex/*!*/>/*!*/ Successors = new List<Vertex/*!*/>();
- public List<Vertex/*!*/> SccMembers; // non-null only for the representative of the SCC
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(cce.NonNullElements(Successors));
- Contract.Invariant(SccMembers==null || cce.NonNullElements(SccMembers));
- }
-
- public Vertex SccRepresentative; // null if not computed
-
- public int SccId; // valid only for SCC representatives; indicates position of this representative vertex in the graph's topological sort
- // the following field is used during the computation of SCCs and of reachability
- public VisitedStatus Visited;
- // the following fields are used during the computation of SCCs:
- public int DfNumber;
- public int LowLink;
- // the following field is used during a Reaches computation
- public int Gen; // generation <= Gen means this vertex has been visited in the current generation
-
- public Vertex(Node n) {
- N = n;
- }
- public void AddSuccessor(Vertex v) {
- Contract.Requires(v != null);
- Successors.Add(v);
- }
- }
-
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(vertices!=null);
- Contract.Invariant(cce.NonNullElements(vertices.Values));
- Contract.Invariant(topologicallySortedRepresentatives==null || cce.NonNullElements(topologicallySortedRepresentatives));
- Contract.Invariant(!sccComputed || topologicallySortedRepresentatives != null);
- }
-
- Dictionary<Node, Vertex/*!*/>/*!*/ vertices = new Dictionary<Node, Vertex/*!*/>();
- bool sccComputed = false;
- List<Vertex/*!*/> topologicallySortedRepresentatives; // computed by the SCC computation
-
- public int SccCount {
- get {
- ComputeSCCs();
- Contract.Assert(topologicallySortedRepresentatives != null); // follows from postcondition of ComputeSCCs and the object invariant
- return topologicallySortedRepresentatives.Count;
- }
- }
- int generation = 0;
-
- public Graph()
- {
- }
-
- /// <summary>
- /// Idempotently adds a vertex 'n' to the graph.
- /// </summary>
- public void AddVertex(Node n) {
- GetVertex(n);
- }
-
- /// <summary>
- /// Idempotently adds a vertex 'n' to the graph and then returns the Vertex for it.
- /// </summary>
- Vertex GetVertex(Node n) {
- Contract.Ensures(Contract.Result<Vertex>() != null);
-
- Vertex v = FindVertex(n);
- if (v == null) {
- v = new Vertex(n);
- vertices.Add(n, v);
- if (sccComputed) {
- Contract.Assert(topologicallySortedRepresentatives != null); // follows from object invariant
- v.SccRepresentative = v;
- v.SccMembers = new List<Vertex>();
- v.SccMembers.Add(v);
- v.SccId = topologicallySortedRepresentatives.Count;
- topologicallySortedRepresentatives.Add(v);
- }
- }
- return v;
- }
-
- /// <summary>
- /// Returns the vertex for 'n' if 'n' is in the graph. Otherwise, returns null.
- /// </summary>
- Vertex FindVertex(Node n) {
- Vertex v;
- if (vertices.TryGetValue(n, out v)) {
- Contract.Assert(v != null); // follows from postcondition of TryGetValue (since 'vertices' maps to the type Vertex!)
- return v;
- } else {
- return null;
- }
- }
-
- /// <summary>
- /// Idempotently adds verices 'from' and 'to' the graph, and then
- /// adds an edge from 'from' to 'to'.
- /// </summary>
- public void AddEdge(Node from, Node to) {
- Vertex v0 = GetVertex(from);
- Vertex v1 = GetVertex(to);
- v0.AddSuccessor(v1);
- sccComputed = false; // the addition of an edge may invalidate any previous computation of the graph's SCCs
- }
-
- /// <summary>
- /// Idempotently adds 'n' as a vertex and then returns a Node that is the representative element of the
- /// strongly connected component containing 'n'.
- /// </summary>
- public Node GetSCCRepresentative(Node n) {
- return GetSCCRepr(n).N;
- }
-
- /// <summary>
- /// Idempotently adds 'n' as a vertex. Then, returns the number of SCCs before the SCC of 'n' in the
- /// topologically sorting of SCCs.
- /// </summary>
- public int GetSCCRepresentativeId(Node n) {
- return GetSCCRepr(n).SccId;
- }
-
- Vertex GetSCCRepr(Node n) {
- Contract.Ensures(Contract.Result<Vertex>() != null);
-
- Vertex v = GetVertex(n);
- ComputeSCCs();
- Contract.Assert(v.SccRepresentative != null); // follows from what ComputeSCCs does
- return v.SccRepresentative;
- }
-
- /// <summary>
- /// Returns a list of the topologically sorted SCCs, each represented in the list by its representative node.
- /// </summary>
- public List<Node> TopologicallySortedComponents() {
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<Node>>()));
- ComputeSCCs();
- Contract.Assert(topologicallySortedRepresentatives != null); // follows from object invariant
- List<Node> nn = new List<Node>();
- foreach (Vertex v in topologicallySortedRepresentatives) {
- nn.Add(v.N);
- }
- return nn;
- }
-
- /// <summary>
- /// Idempotently adds 'n' as a vertex and then returns the set of Node's in the strongly connected component
- /// that contains 'n'.
- /// </summary>
- public List<Node> GetSCC(Node n) {Contract.Ensures(cce.NonNullElements(Contract.Result<List<Node>>()));
- Vertex v = GetVertex(n);
- ComputeSCCs();
- Vertex repr = v.SccRepresentative;
- Contract.Assert(repr != null && repr.SccMembers != null); // follows from postcondition of ComputeSCCs
- List<Node> nn = new List<Node>();
- foreach (Vertex w in repr.SccMembers) {
- nn.Add(w.N);
- }
- return nn;
- }
-
- /// <summary>
- /// Idempotently adds 'n' as a vertex and then returns the size of the set of Node's in the strongly connected component
- /// that contains 'n'.
- /// </summary>
- public int GetSCCSize(Node n){
- Contract.Ensures(1 <= Contract.Result<int>());
-
- Vertex v = GetVertex(n);
- ComputeSCCs();
- Vertex repr = v.SccRepresentative;
- Contract.Assert(repr != null && repr.SccMembers != null); // follows from postcondition of ComputeSCCs
- return repr.SccMembers.Count;
- }
-
- /// <summary>
- /// This method sets the SccRepresentative fields of the graph's vertices so that two
- /// vertices have the same representative iff they are in the same strongly connected
- /// component.
- /// As a side effect, this method may change the Visited, DfNumber, and LowLink fields
- /// of the vertices.
- /// </summary>
- void ComputeSCCs()
- {
- Contract.Ensures(sccComputed);
-
- if (sccComputed) { return; } // check if already computed
-
- // reset all SCC information
- topologicallySortedRepresentatives = new List<Vertex>();
- foreach (Vertex v in vertices.Values) {
- v.Visited = VisitedStatus.Unvisited;
- v.SccMembers = null;
- }
- Stack<Vertex> stack = new Stack<Vertex>();
- int cnt = 0;
- foreach (Vertex v in vertices.Values) {
- if (v.Visited == VisitedStatus.Unvisited) {
- SearchC(v, stack, ref cnt);
- }
- }
- Contract.Assert(cnt == vertices.Count); // sanity check that everything has been visited
-
- sccComputed = true;
- }
-
- /// <summary>
- /// This is the 'SearchC' procedure from the Aho, Hopcroft, and Ullman book 'The Design and Analysis of Computer Algorithms'.
- /// </summary>
- void SearchC(Vertex/*!*/ v, Stack<Vertex/*!*/>/*!*/ stack, ref int cnt){
- Contract.Requires(v != null);
- Contract.Requires(cce.NonNullElements(stack));
- Contract.Requires(v.Visited == VisitedStatus.Unvisited);
- Contract.Requires(topologicallySortedRepresentatives != null);
- Contract.Ensures(v.Visited != VisitedStatus.Unvisited);
-
- v.DfNumber = cnt;
- cnt++;
- v.LowLink = v.DfNumber;
- stack.Push(v);
- v.Visited = VisitedStatus.OnStack;
-
- foreach (Vertex w in v.Successors) {
- if (w.Visited == VisitedStatus.Unvisited) {
- SearchC(w, stack, ref cnt);
- v.LowLink = Math.Min(v.LowLink, w.LowLink);
- } else if (w.Visited == VisitedStatus.OnStack) {
- Contract.Assert(w.DfNumber < v.DfNumber || v.LowLink <= w.DfNumber); // the book also has the guard 'w.DfNumber < v.DfNumber', but that seems unnecessary to me, so this assert is checking my understanding
- v.LowLink = Math.Min(v.LowLink, w.DfNumber);
- }
- }
-
- if (v.LowLink == v.DfNumber) {
- // The SCC containing 'v' has now been computed.
- v.SccId = topologicallySortedRepresentatives.Count;
- topologicallySortedRepresentatives.Add(v);
- v.SccMembers = new List<Vertex>();
- while (true) {
- Vertex x = stack.Pop();
- x.Visited = VisitedStatus.Visited;
- x.SccRepresentative = v;
- v.SccMembers.Add(x);
- if (x == v) { break; }
- }
- }
- }
-
- /// <summary>
- /// Returns null if the graph has no cycles. If the graph does contain some cycle, returns the list of
- /// vertices on one such cycle.
- /// </summary>
- public List<Node> TryFindCycle() {
- // reset all visited information
- foreach (Vertex v in vertices.Values) {
- v.Visited = VisitedStatus.Unvisited;
- }
-
- foreach (Vertex v in vertices.Values) {
- Contract.Assert(v.Visited != VisitedStatus.OnStack);
- if (v.Visited == VisitedStatus.Unvisited) {
- List<Vertex> cycle = CycleSearch(v);
- if (cycle != null) {
- List<Node> nodes = new List<Node>();
- foreach (Vertex v_ in cycle) {
- nodes.Add(v_.N);
- }
- return nodes; // a cycle is found
- }
- }
- }
- return null; // there are no cycles
- }
-
- /// <summary>
- /// A return of null means there are no cycles involving any vertex in the subtree rooted at v.
- /// A non-null return means a cycle has been found. Then:
- /// If v.Visited == Visited, then the entire cycle is described in the returned list.
- /// If v.Visited == OnStack, then the cycle consists of the vertices strictly deeper than
- /// w on the stack followed by the vertices (in reverse order) in the returned list, where
- /// w is the first vertex in the list returned.
- /// </summary>
- List<Vertex/*!*/> CycleSearch(Vertex v)
- {
- Contract.Requires(v != null);
- Contract.Requires(v.Visited == VisitedStatus.Unvisited);
- Contract.Ensures(v.Visited != VisitedStatus.Unvisited);
- Contract.Ensures(Contract.Result<List<Vertex>>() != null || v.Visited == VisitedStatus.Visited);
- Contract.Ensures(Contract.Result<List<Vertex>>() == null || Contract.Result<List<Vertex>>().Count != 0);
-
- v.Visited = VisitedStatus.OnStack;
- foreach (Vertex succ in v.Successors) {
- // todo: I would use a 'switch' statement, but there seems to be a bug in the Spec# compiler's type checking.
- if (succ.Visited == VisitedStatus.Visited) {
- // there is no cycle in the subtree rooted at succ, hence this path does not give rise to any cycles
- } else if (succ.Visited == VisitedStatus.OnStack) {
- // we found a cycle!
- List<Vertex> cycle = new List<Vertex>();
- cycle.Add(succ);
- if (v == succ) {
- // entire cycle has been found
- v.Visited = VisitedStatus.Visited;
- }
- return cycle;
- } else {
- Contract.Assert(succ.Visited == VisitedStatus.Unvisited);
- List<Vertex> cycle = CycleSearch(succ);
- if (cycle != null) {
- if (succ.Visited == VisitedStatus.Visited) {
- // the entire cycle has been collected
- v.Visited = VisitedStatus.Visited;
- return cycle;
- } else {
- cycle.Add(succ);
- if (v == cycle[0]) {
- // the entire cycle has been collected and we are the first to find out
- v.Visited = VisitedStatus.Visited;
- }
- return cycle;
- }
- }
- }
- }
- v.Visited = VisitedStatus.Visited; // there are no cycles from here on
- return null;
- }
-
- /// <summary>
- /// Returns whether or not 'source' reaches 'sink' in the graph.
- /// 'source' and 'sink' need not be in the graph; if neither is, the return value
- /// is source==sink.
- /// </summary>
- public bool Reaches(Node source, Node sink) {
- Vertex a = FindVertex(source);
- Vertex b = FindVertex(sink);
- if (a == null || b == null) {
- return source.Equals(sink);
- }
- generation++;
- return ReachSearch(a, b);
- }
-
- bool ReachSearch(Vertex source, Vertex sink) {
- Contract.Requires(source != null);
- Contract.Requires(sink != null);
- if (source == sink) {
- return true;
- } else if (source.Gen == generation) {
- // already visited
- return false;
- } else {
- source.Gen = generation;
- return Contract.Exists(source.Successors,succ=> ReachSearch(succ, sink));
- }
- }
- }
-}
diff --git a/Source/Dafny/Translator.cs b/Source/Dafny/Translator.cs
deleted file mode 100644
index 40795129..00000000
--- a/Source/Dafny/Translator.cs
+++ /dev/null
@@ -1,9249 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using System.Diagnostics.Contracts;
-using Bpl = Microsoft.Boogie;
-using System.Text;
-using Microsoft.Boogie;
-
-namespace Microsoft.Dafny {
- public class Translator {
- [NotDelayed]
- public Translator() {
- Bpl.Program boogieProgram = ReadPrelude();
- if (boogieProgram != null) {
- sink = boogieProgram;
- predef = FindPredefinedDecls(boogieProgram);
- }
- }
-
- // translation state
- readonly Dictionary<TopLevelDecl/*!*/,Bpl.Constant/*!*/>/*!*/ classes = new Dictionary<TopLevelDecl/*!*/,Bpl.Constant/*!*/>();
- readonly Dictionary<Field/*!*/,Bpl.Constant/*!*/>/*!*/ fields = new Dictionary<Field/*!*/,Bpl.Constant/*!*/>();
- readonly Dictionary<Field/*!*/, Bpl.Function/*!*/>/*!*/ fieldFunctions = new Dictionary<Field/*!*/, Bpl.Function/*!*/>();
- readonly Dictionary<string, Bpl.Constant> fieldConstants = new Dictionary<string,Constant>();
- Program program;
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(cce.NonNullDictionaryAndValues(classes));
- Contract.Invariant(cce.NonNullDictionaryAndValues(fields));
- Contract.Invariant(cce.NonNullDictionaryAndValues(fieldFunctions));
- Contract.Invariant(codeContext == null || codeContext.EnclosingModule == currentModule);
- }
-
- readonly Bpl.Program sink;
- readonly PredefinedDecls predef;
-
- internal class PredefinedDecls {
- public readonly Bpl.Type RefType;
- public readonly Bpl.Type BoxType;
- public readonly Bpl.Type TickType;
- private readonly Bpl.TypeSynonymDecl setTypeCtor;
- private readonly Bpl.TypeSynonymDecl multiSetTypeCtor;
- private readonly Bpl.TypeCtorDecl mapTypeCtor;
- public readonly Bpl.Function ArrayLength;
- private readonly Bpl.TypeCtorDecl seqTypeCtor;
- readonly Bpl.TypeCtorDecl fieldName;
- public readonly Bpl.Type HeapType;
- public readonly string HeapVarName;
- public readonly Bpl.Type ClassNameType;
- public readonly Bpl.Type NameFamilyType;
- public readonly Bpl.Type DatatypeType;
- public readonly Bpl.Type DtCtorId;
- public readonly Bpl.Expr Null;
- private readonly Bpl.Constant allocField;
- public readonly Bpl.Constant ClassDotArray;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(RefType != null);
- Contract.Invariant(BoxType != null);
- Contract.Invariant(TickType != null);
- Contract.Invariant(setTypeCtor != null);
- Contract.Invariant(multiSetTypeCtor != null);
- Contract.Invariant(ArrayLength != null);
- Contract.Invariant(seqTypeCtor != null);
- Contract.Invariant(fieldName != null);
- Contract.Invariant(HeapType != null);
- Contract.Invariant(HeapVarName != null);
- Contract.Invariant(ClassNameType != null);
- Contract.Invariant(NameFamilyType != null);
- Contract.Invariant(DatatypeType != null);
- Contract.Invariant(DtCtorId != null);
- Contract.Invariant(Null != null);
- Contract.Invariant(allocField != null);
- Contract.Invariant(ClassDotArray != null);
- }
-
-
- public Bpl.Type SetType(IToken tok, Bpl.Type ty) {
- Contract.Requires(tok != null);
- Contract.Requires(ty != null);
- Contract.Ensures(Contract.Result<Bpl.Type>() != null);
-
- return new Bpl.TypeSynonymAnnotation(Token.NoToken, setTypeCtor, new Bpl.TypeSeq(ty));
- }
-
- public Bpl.Type MultiSetType(IToken tok, Bpl.Type ty) {
- Contract.Requires(tok != null);
- Contract.Requires(ty != null);
- Contract.Ensures(Contract.Result<Bpl.Type>() != null);
-
- return new Bpl.TypeSynonymAnnotation(Token.NoToken, multiSetTypeCtor, new Bpl.TypeSeq(ty));
- }
- public Bpl.Type MapType(IToken tok, Bpl.Type tya, Bpl.Type tyb) {
- Contract.Requires(tok != null);
- Contract.Requires(tya != null && tyb != null);
- Contract.Ensures(Contract.Result<Bpl.Type>() != null);
-
- return new Bpl.CtorType(Token.NoToken, mapTypeCtor, new Bpl.TypeSeq(tya, tyb));
- }
-
- public Bpl.Type SeqType(IToken tok, Bpl.Type ty) {
- Contract.Requires(tok != null);
- Contract.Requires(ty != null);
- Contract.Ensures(Contract.Result<Bpl.Type>() != null);
- return new Bpl.CtorType(Token.NoToken, seqTypeCtor, new Bpl.TypeSeq(ty));
- }
-
- public Bpl.Type FieldName(IToken tok, Bpl.Type ty) {
- Contract.Requires(tok != null);
- Contract.Requires(ty != null);
- Contract.Ensures(Contract.Result<Bpl.Type>() != null);
-
- return new Bpl.CtorType(tok, fieldName, new Bpl.TypeSeq(ty));
- }
-
- public Bpl.IdentifierExpr Alloc(IToken tok) {
- Contract.Requires(tok != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>() != null);
-
- return new Bpl.IdentifierExpr(tok, allocField);
- }
-
- public PredefinedDecls(Bpl.TypeCtorDecl refType, Bpl.TypeCtorDecl boxType, Bpl.TypeCtorDecl tickType,
- Bpl.TypeSynonymDecl setTypeCtor, Bpl.TypeSynonymDecl multiSetTypeCtor, Bpl.TypeCtorDecl mapTypeCtor, Bpl.Function arrayLength, Bpl.TypeCtorDecl seqTypeCtor, Bpl.TypeCtorDecl fieldNameType,
- Bpl.GlobalVariable heap, Bpl.TypeCtorDecl classNameType, Bpl.TypeCtorDecl nameFamilyType,
- Bpl.TypeCtorDecl datatypeType, Bpl.TypeCtorDecl dtCtorId,
- Bpl.Constant allocField, Bpl.Constant classDotArray) {
- #region Non-null preconditions on parameters
- Contract.Requires(refType != null);
- Contract.Requires(boxType != null);
- Contract.Requires(tickType != null);
- Contract.Requires(setTypeCtor != null);
- Contract.Requires(multiSetTypeCtor != null);
- Contract.Requires(seqTypeCtor != null);
- Contract.Requires(fieldNameType != null);
- Contract.Requires(heap != null);
- Contract.Requires(classNameType != null);
- Contract.Requires(datatypeType != null);
- Contract.Requires(dtCtorId != null);
- Contract.Requires(allocField != null);
- Contract.Requires(classDotArray != null);
- #endregion
-
- Bpl.CtorType refT = new Bpl.CtorType(Token.NoToken, refType, new Bpl.TypeSeq());
- this.RefType = refT;
- this.BoxType = new Bpl.CtorType(Token.NoToken, boxType, new Bpl.TypeSeq());
- this.TickType = new Bpl.CtorType(Token.NoToken, tickType, new Bpl.TypeSeq());
- this.setTypeCtor = setTypeCtor;
- this.multiSetTypeCtor = multiSetTypeCtor;
- this.mapTypeCtor = mapTypeCtor;
- this.ArrayLength = arrayLength;
- this.seqTypeCtor = seqTypeCtor;
- this.fieldName = fieldNameType;
- this.HeapType = heap.TypedIdent.Type;
- this.HeapVarName = heap.Name;
- this.ClassNameType = new Bpl.CtorType(Token.NoToken, classNameType, new Bpl.TypeSeq());
- this.NameFamilyType = new Bpl.CtorType(Token.NoToken, nameFamilyType, new Bpl.TypeSeq());
- this.DatatypeType = new Bpl.CtorType(Token.NoToken, datatypeType, new Bpl.TypeSeq());
- this.DtCtorId = new Bpl.CtorType(Token.NoToken, dtCtorId, new Bpl.TypeSeq());
- this.allocField = allocField;
- this.Null = new Bpl.IdentifierExpr(Token.NoToken, "null", refT);
- this.ClassDotArray = classDotArray;
- }
- }
-
- static PredefinedDecls FindPredefinedDecls(Bpl.Program prog) {
- Contract.Requires(prog != null);
- if (prog.Resolve() != 0) {
- Console.WriteLine("Error: resolution errors encountered in Dafny prelude");
- return null;
- }
-
- Bpl.TypeCtorDecl refType = null;
- Bpl.TypeSynonymDecl setTypeCtor = null;
- Bpl.TypeSynonymDecl multiSetTypeCtor = null;
- Bpl.Function arrayLength = null;
- Bpl.TypeCtorDecl seqTypeCtor = null;
- Bpl.TypeCtorDecl fieldNameType = null;
- Bpl.TypeCtorDecl classNameType = null;
- Bpl.TypeCtorDecl nameFamilyType = null;
- Bpl.TypeCtorDecl datatypeType = null;
- Bpl.TypeCtorDecl dtCtorId = null;
- Bpl.TypeCtorDecl boxType = null;
- Bpl.TypeCtorDecl tickType = null;
- Bpl.TypeCtorDecl mapTypeCtor = null;
- Bpl.GlobalVariable heap = null;
- Bpl.Constant allocField = null;
- Bpl.Constant classDotArray = null;
- foreach (var d in prog.TopLevelDeclarations) {
- if (d is Bpl.TypeCtorDecl) {
- Bpl.TypeCtorDecl dt = (Bpl.TypeCtorDecl)d;
- if (dt.Name == "Seq") {
- seqTypeCtor = dt;
- } else if (dt.Name == "Field") {
- fieldNameType = dt;
- } else if (dt.Name == "ClassName") {
- classNameType = dt;
- } else if (dt.Name == "DatatypeType") {
- datatypeType = dt;
- } else if (dt.Name == "DtCtorId") {
- dtCtorId = dt;
- } else if (dt.Name == "ref") {
- refType = dt;
- } else if (dt.Name == "NameFamily") {
- nameFamilyType = dt;
- } else if (dt.Name == "BoxType") {
- boxType = dt;
- } else if (dt.Name == "TickType") {
- tickType = dt;
- } else if (dt.Name == "Map") {
- mapTypeCtor = dt;
- }
- } else if (d is Bpl.TypeSynonymDecl) {
- Bpl.TypeSynonymDecl dt = (Bpl.TypeSynonymDecl)d;
- if (dt.Name == "Set") {
- setTypeCtor = dt;
- }
- if (dt.Name == "MultiSet") {
- multiSetTypeCtor = dt;
- }
- } else if (d is Bpl.Constant) {
- Bpl.Constant c = (Bpl.Constant)d;
- if (c.Name == "alloc") {
- allocField = c;
- } else if (c.Name == "class._System.array") {
- classDotArray = c;
- }
- } else if (d is Bpl.GlobalVariable) {
- Bpl.GlobalVariable v = (Bpl.GlobalVariable)d;
- if (v.Name == "$Heap") {
- heap = v;
- }
- } else if (d is Bpl.Function) {
- var f = (Bpl.Function)d;
- if (f.Name == "_System.array.Length")
- arrayLength = f;
- }
- }
- if (seqTypeCtor == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type Seq");
- } else if (setTypeCtor == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type Set");
- } else if (multiSetTypeCtor == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type MultiSet");
- } else if (mapTypeCtor == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type Map");
- } else if (arrayLength == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of function _System.array.Length");
- } else if (fieldNameType == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type Field");
- } else if (classNameType == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type ClassName");
- } else if (nameFamilyType == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type NameFamily");
- } else if (datatypeType == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type DatatypeType");
- } else if (dtCtorId == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type DtCtorId");
- } else if (refType == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type ref");
- } else if (boxType == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type BoxType");
- } else if (tickType == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of type TickType");
- } else if (heap == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of $Heap");
- } else if (allocField == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of constant alloc");
- } else if (classDotArray == null) {
- Console.WriteLine("Error: Dafny prelude is missing declaration of class._System.array");
- } else {
- return new PredefinedDecls(refType, boxType, tickType,
- setTypeCtor, multiSetTypeCtor, mapTypeCtor, arrayLength, seqTypeCtor, fieldNameType, heap, classNameType, nameFamilyType, datatypeType, dtCtorId,
- allocField, classDotArray);
- }
- return null;
- }
-
- static Bpl.Program ReadPrelude() {
- string preludePath = DafnyOptions.O.DafnyPrelude;
- if (preludePath == null)
- {
- //using (System.IO.Stream stream = cce.NonNull( System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("DafnyPrelude.bpl")) // Use this once Spec#/VSIP supports designating a non-.resx project item as an embedded resource
- string codebase = cce.NonNull(System.IO.Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location)));
- preludePath = System.IO.Path.Combine(codebase, "DafnyPrelude.bpl");
- }
-
- Bpl.Program prelude;
- int errorCount = Bpl.Parser.Parse(preludePath, (List<string>)null, out prelude);
- if (prelude == null || errorCount > 0) {
- return null;
- } else {
- return prelude;
- }
-/*
- List<string!> defines = new List<string!>();
- using (System.IO.Stream stream = new System.IO.FileStream(preludePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
- {
- BoogiePL.Buffer.Fill(new System.IO.StreamReader(stream), defines);
- //BoogiePL.Scanner.Init("<DafnyPrelude.bpl>");
- Bpl.Program prelude;
- int errorCount = BoogiePL.Parser.Parse(out prelude);
- if (prelude == null || errorCount > 0) {
- return null;
- } else {
- return prelude;
- }
- }
-*/
- }
-
- public Bpl.Program Translate(Program p) {
- Contract.Requires(p != null);
- Contract.Ensures(Contract.Result<Bpl.Program>() != null);
-
- program = p;
-
- if (sink == null || predef == null) {
- // something went wrong during construction, which reads the prelude; an error has
- // already been printed, so just return an empty program here (which is non-null)
- return new Bpl.Program();
- }
-
- foreach (TopLevelDecl d in program.BuiltIns.SystemModule.TopLevelDecls) {
- if (d is ArbitraryTypeDecl) {
- // nothing to do--this is treated just like a type parameter
- } else if (d is DatatypeDecl) {
- AddDatatype((DatatypeDecl)d);
- } else {
- AddClassMembers((ClassDecl)d);
- }
- }
- foreach (ModuleDefinition m in program.Modules) {
- foreach (TopLevelDecl d in m.TopLevelDecls) {
- if (d is ArbitraryTypeDecl) {
- // nothing to do--this is treated just like a type parameter
- } else if (d is DatatypeDecl) {
- AddDatatype((DatatypeDecl)d);
- } else if (d is ModuleDecl) {
- // submodules have already been added as a top level module, ignore this.
- } else if (d is ClassDecl) {
- AddClassMembers((ClassDecl)d);
- if (d is IteratorDecl) {
- AddIteratorSpecAndBody((IteratorDecl)d);
- }
- } else {
- Contract.Assert(false);
- }
- }
- }
- foreach(var c in fieldConstants.Values) {
- sink.TopLevelDeclarations.Add(c);
- }
- HashSet<Tuple<string, string>> checkedMethods = new HashSet<Tuple<string, string>>();
- HashSet<Tuple<string, string>> checkedFunctions = new HashSet<Tuple<string, string>>();
- foreach (var t in program.TranslationTasks) {
- if (t is MethodCheck) {
- var m = (MethodCheck)t;
- var id = new Tuple<string, string>(m.Refined.FullCompileName, m.Refining.FullCompileName);
- if (!checkedMethods.Contains(id)) {
- AddMethodRefinementCheck(m);
- checkedMethods.Add(id);
- }
- } else if (t is FunctionCheck) {
- var f = (FunctionCheck)t;
- var id = new Tuple<string, string>(f.Refined.FullCompileName, f.Refining.FullCompileName);
- if (!checkedFunctions.Contains(id)) {
- AddFunctionRefinementCheck(f);
- checkedFunctions.Add(id);
- }
- }
- }
- return sink;
- }
-
- void AddDatatype(DatatypeDecl dt)
- {
- Contract.Requires(dt != null);
- Contract.Requires(sink != null && predef != null);
- sink.TopLevelDeclarations.Add(GetClass(dt));
-
- foreach (DatatypeCtor ctor in dt.Ctors) {
- // Add: function #dt.ctor(paramTypes) returns (DatatypeType);
- Bpl.VariableSeq argTypes = new Bpl.VariableSeq();
- foreach (Formal arg in ctor.Formals) {
- Bpl.Variable a = new Bpl.Formal(arg.tok, new Bpl.TypedIdent(arg.tok, Bpl.TypedIdent.NoName, TrType(arg.Type)), true);
- argTypes.Add(a);
- }
- Bpl.Variable resType = new Bpl.Formal(ctor.tok, new Bpl.TypedIdent(ctor.tok, Bpl.TypedIdent.NoName, predef.DatatypeType), false);
- Bpl.Function fn = new Bpl.Function(ctor.tok, ctor.FullName, argTypes, resType);
- sink.TopLevelDeclarations.Add(fn);
-
- // Add: axiom (forall params :: #dt.ctor(params)-has-the-expected-type);
- Bpl.VariableSeq bvs;
- List<Bpl.Expr> args;
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- Bpl.Expr ct = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- List<Type> tpArgs = new List<Type>(); // we use an empty list of type arguments, because we don't want Good_Datatype to produce any DtTypeParams predicates anyway
- Bpl.Expr wh = new ExpressionTranslator(this, predef, ctor.tok).Good_Datatype(ctor.tok, ct, dt, tpArgs);
- if (bvs.Length != 0) {
- wh = new Bpl.ForallExpr(ctor.tok, bvs, wh);
- }
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, wh));
-
- // Add: const unique ##dt.ctor: DtCtorId;
- Bpl.Constant cid = new Bpl.Constant(ctor.tok, new Bpl.TypedIdent(ctor.tok, "#" + ctor.FullName, predef.DtCtorId), true);
- sink.TopLevelDeclarations.Add(cid);
-
- // Add: axiom (forall params :: DatatypeCtorId(#dt.ctor(params)) == ##dt.ctor);
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- Bpl.Expr lhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- lhs = FunctionCall(ctor.tok, BuiltinFunction.DatatypeCtorId, null, lhs);
- Bpl.Expr q = Bpl.Expr.Eq(lhs, new Bpl.IdentifierExpr(ctor.tok, cid));
- if (bvs.Length != 0) {
- q = new Bpl.ForallExpr(ctor.tok, bvs, q);
- }
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
- // Add: axiom (forall d: DatatypeType :: dt.ctor?(d) ==> (exists params :: d == #dt.ctor(params));
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- lhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- var dBv = new Bpl.BoundVariable(ctor.tok, new Bpl.TypedIdent(ctor.tok, "d", predef.DatatypeType));
- var dId = new Bpl.IdentifierExpr(ctor.tok, dBv.Name, predef.DatatypeType);
- q = Bpl.Expr.Eq(dId, lhs);
- if (bvs.Length != 0) {
- q = new Bpl.ExistsExpr(ctor.tok, bvs, q);
- }
- q = Bpl.Expr.Imp(FunctionCall(ctor.tok, ctor.QueryField.FullCompileName, Bpl.Type.Bool, dId), q);
- q = new Bpl.ForallExpr(ctor.tok, new VariableSeq(dBv), q);
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
-
- // Add: function dt.ctor?(this: DatatypeType): bool { DatatypeCtorId(this) == ##dt.ctor }
- fn = GetReadonlyField(ctor.QueryField);
- lhs = FunctionCall(ctor.tok, BuiltinFunction.DatatypeCtorId, null, new Bpl.IdentifierExpr(ctor.tok, fn.InParams[0].Name, predef.DatatypeType));
- fn.Body = Bpl.Expr.Eq(lhs, new Bpl.IdentifierExpr(ctor.tok, cid)); // this uses the "cid" defined for the previous axiom
- sink.TopLevelDeclarations.Add(fn);
-
- // Add: axiom (forall params, h: HeapType ::
- // { DtAlloc(#dt.ctor(params), h) }
- // $IsGoodHeap(h) ==>
- // (DtAlloc(#dt.ctor(params), h) <==> ...each param has its expected type...));
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- lhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- Bpl.BoundVariable hVar = new Bpl.BoundVariable(ctor.tok, new Bpl.TypedIdent(ctor.tok, "$h", predef.HeapType));
- Bpl.Expr h = new Bpl.IdentifierExpr(ctor.tok, hVar);
- bvs.Add(hVar); args.Add(h);
- ExpressionTranslator etranH = new ExpressionTranslator(this, predef, h);
- Bpl.Expr isGoodHeap = FunctionCall(ctor.tok, BuiltinFunction.IsGoodHeap, null, h);
- lhs = FunctionCall(ctor.tok, BuiltinFunction.DtAlloc, null, lhs, h);
- Bpl.Expr pt = Bpl.Expr.True;
- int i = 0;
- foreach (Formal arg in ctor.Formals) {
- Bpl.Expr whp = GetWhereClause(arg.tok, args[i], arg.Type, etranH);
- if (whp != null) {
- pt = BplAnd(pt, whp);
- }
- i++;
- }
- Bpl.Trigger tr = new Bpl.Trigger(ctor.tok, true, new ExprSeq(lhs));
- q = new Bpl.ForallExpr(ctor.tok, bvs, tr, Bpl.Expr.Imp(isGoodHeap, Bpl.Expr.Iff(lhs, pt)));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
-
- // Add injectivity axioms:
- i = 0;
- foreach (Formal arg in ctor.Formals) {
- // function ##dt.ctor#i(DatatypeType) returns (Ti);
- var sf = ctor.Destructors[i];
- if (sf != null) {
- fn = GetReadonlyField(sf);
- } else {
- Contract.Assert(!arg.HasName);
- argTypes = new Bpl.VariableSeq();
- argTypes.Add(new Bpl.Formal(ctor.tok, new Bpl.TypedIdent(ctor.tok, Bpl.TypedIdent.NoName, predef.DatatypeType), true));
- resType = new Bpl.Formal(arg.tok, new Bpl.TypedIdent(arg.tok, Bpl.TypedIdent.NoName, TrType(arg.Type)), false);
- string nm = "#" + ctor.FullName + "#" + i;
- fn = new Bpl.Function(ctor.tok, nm, argTypes, resType);
- }
- sink.TopLevelDeclarations.Add(fn);
- // axiom (forall params :: ##dt.ctor#i(#dt.ctor(params)) == params_i);
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- lhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- lhs = FunctionCall(ctor.tok, fn.Name, TrType(arg.Type), lhs);
- q = new Bpl.ForallExpr(ctor.tok, bvs, Bpl.Expr.Eq(lhs, args[i]));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
-
- if (dt is IndDatatypeDecl) {
- if (arg.Type.IsDatatype || arg.Type.IsTypeParameter) {
- // for datatype: axiom (forall params :: DtRank(params_i) < DtRank(#dt.ctor(params)));
- // for type-parameter type: axiom (forall params :: DtRank(Unbox(params_i)) < DtRank(#dt.ctor(params)));
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- lhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null,
- arg.Type.IsDatatype ? args[i] : FunctionCall(ctor.tok, BuiltinFunction.Unbox, predef.DatatypeType, args[i]));
- Bpl.Expr rhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- rhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null, rhs);
- q = new Bpl.ForallExpr(ctor.tok, bvs, Bpl.Expr.Lt(lhs, rhs));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
- } else if (arg.Type is SeqType) {
- // axiom (forall params, i: int :: 0 <= i && i < |arg| ==> DtRank(arg[i]) < DtRank(#dt.ctor(params)));
- // that is:
- // axiom (forall params, i: int :: 0 <= i && i < |arg| ==> DtRank(Unbox(Seq#Index(arg,i))) < DtRank(#dt.ctor(params)));
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- Bpl.Variable iVar = new Bpl.BoundVariable(arg.tok, new Bpl.TypedIdent(arg.tok, "i", Bpl.Type.Int));
- bvs.Add(iVar);
- Bpl.IdentifierExpr ie = new Bpl.IdentifierExpr(arg.tok, iVar);
- Bpl.Expr ante = Bpl.Expr.And(
- Bpl.Expr.Le(Bpl.Expr.Literal(0), ie),
- Bpl.Expr.Lt(ie, FunctionCall(arg.tok, BuiltinFunction.SeqLength, null, args[i])));
- lhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null,
- FunctionCall(arg.tok, BuiltinFunction.Unbox, predef.DatatypeType,
- FunctionCall(arg.tok, BuiltinFunction.SeqIndex, predef.DatatypeType, args[i], ie)));
- Bpl.Expr rhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- rhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null, rhs);
- q = new Bpl.ForallExpr(ctor.tok, bvs, Bpl.Expr.Imp(ante, Bpl.Expr.Lt(lhs, rhs)));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
- } else if (arg.Type is SetType) {
- // axiom (forall params, d: Datatype :: arg[d] ==> DtRank(d) < DtRank(#dt.ctor(params)));
- // that is:
- // axiom (forall params, d: Datatype :: arg[Box(d)] ==> DtRank(d) < DtRank(#dt.ctor(params)));
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- Bpl.Variable dVar = new Bpl.BoundVariable(arg.tok, new Bpl.TypedIdent(arg.tok, "d", predef.DatatypeType));
- bvs.Add(dVar);
- Bpl.IdentifierExpr ie = new Bpl.IdentifierExpr(arg.tok, dVar);
- Bpl.Expr ante = Bpl.Expr.SelectTok(arg.tok, args[i], FunctionCall(arg.tok, BuiltinFunction.Box, null, ie));
- lhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null, ie);
- Bpl.Expr rhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- rhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null, rhs);
- q = new Bpl.ForallExpr(ctor.tok, bvs, Bpl.Expr.Imp(ante, Bpl.Expr.Lt(lhs, rhs)));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
- } else if (arg.Type is MultiSetType) {
- // axiom (forall params, d: Datatype :: 0 < arg[d] ==> DtRank(d) < DtRank(#dt.ctor(params)));
- // that is:
- // axiom (forall params, d: Datatype :: 0 < arg[Box(d)] ==> DtRank(d) < DtRank(#dt.ctor(params)));
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- Bpl.Variable dVar = new Bpl.BoundVariable(arg.tok, new Bpl.TypedIdent(arg.tok, "d", predef.DatatypeType));
- bvs.Add(dVar);
- Bpl.IdentifierExpr ie = new Bpl.IdentifierExpr(arg.tok, dVar);
- Bpl.Expr ante = Bpl.Expr.Gt(Bpl.Expr.SelectTok(arg.tok, args[i], FunctionCall(arg.tok, BuiltinFunction.Box, null, ie)), Bpl.Expr.Literal(0));
- lhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null, ie);
- Bpl.Expr rhs = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- rhs = FunctionCall(ctor.tok, BuiltinFunction.DtRank, null, rhs);
- q = new Bpl.ForallExpr(ctor.tok, bvs, Bpl.Expr.Imp(ante, Bpl.Expr.Lt(lhs, rhs)));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(ctor.tok, q));
- }
- }
- i++;
- }
- }
-
- // Add:
- // function $IsA#Dt(d: DatatypeType): bool {
- // Dt.Ctor0?(d) || Dt.Ctor1?(d) || ...
- // }
- var cases_dBv = new Bpl.Formal(dt.tok, new Bpl.TypedIdent(dt.tok, "d", predef.DatatypeType), true);
- var cases_dId = new Bpl.IdentifierExpr(dt.tok, cases_dBv.Name, predef.DatatypeType);
- Bpl.Expr cases_body = null;
- foreach (DatatypeCtor ctor in dt.Ctors) {
- var disj = FunctionCall(ctor.tok, ctor.QueryField.FullCompileName, Bpl.Type.Bool, cases_dId);
- cases_body = cases_body == null ? disj : Bpl.Expr.Or(cases_body, disj);
- }
- var cases_resType = new Bpl.Formal(dt.tok, new Bpl.TypedIdent(dt.tok, Bpl.TypedIdent.NoName, Bpl.Type.Bool), false);
- var cases_fn = new Bpl.Function(dt.tok, "$IsA#" + dt.FullCompileName, new Bpl.VariableSeq(cases_dBv), cases_resType);
- cases_fn.Body = cases_body;
- sink.TopLevelDeclarations.Add(cases_fn);
- }
-
- void CreateBoundVariables(List<Formal/*!*/>/*!*/ formals, out Bpl.VariableSeq/*!*/ bvs, out List<Bpl.Expr/*!*/>/*!*/ args)
- {
- Contract.Requires(formals != null);
- Contract.Ensures(Contract.ValueAtReturn(out bvs).Length == Contract.ValueAtReturn(out args).Count);
- Contract.Ensures(Contract.ValueAtReturn(out bvs) != null);
- Contract.Ensures(cce.NonNullElements(Contract.ValueAtReturn(out args)));
-
- bvs = new Bpl.VariableSeq();
- args = new List<Bpl.Expr>();
- foreach (Formal arg in formals) {
- Contract.Assert(arg != null);
- var nm = string.Format("a{0}#{1}", bvs.Length, otherTmpVarCount);
- otherTmpVarCount++;
- Bpl.Variable bv = new Bpl.BoundVariable(arg.tok, new Bpl.TypedIdent(arg.tok, nm, TrType(arg.Type)));
- bvs.Add(bv);
- args.Add(new Bpl.IdentifierExpr(arg.tok, bv));
- }
- }
-
- void AddClassMembers(ClassDecl c)
- {
- Contract.Requires(sink != null && predef != null);
- Contract.Requires(c != null);
- if (c.Name == "array") {
- classes.Add(c, predef.ClassDotArray);
- } else {
- sink.TopLevelDeclarations.Add(GetClass(c));
- }
-
- foreach (MemberDecl member in c.Members) {
- if (member is Field) {
- Field f = (Field)member;
- if (f.IsMutable) {
- Bpl.Constant fc = GetField(f);
- sink.TopLevelDeclarations.Add(fc);
- } else {
- Bpl.Function ff = GetReadonlyField(f);
- if (ff != predef.ArrayLength)
- sink.TopLevelDeclarations.Add(ff);
- }
-
- AddAllocationAxiom(f);
-
- } else if (member is Function) {
- Function f = (Function)member;
- AddFunction(f);
- if (f.IsRecursive) {
- AddLimitedAxioms(f, 2);
- AddLimitedAxioms(f, 1);
- }
- for (int layerOffset = 0; layerOffset < 2; layerOffset++) {
- var body = f.Body == null ? null : f.Body.Resolved;
- if (body is MatchExpr) {
- AddFunctionAxiomCase(f, (MatchExpr)body, null, layerOffset);
- AddFunctionAxiom(f, null, f.Ens, null, layerOffset);
- } else {
- AddFunctionAxiom(f, body, f.Ens, null, layerOffset);
- }
- if (!f.IsRecursive) { break; }
- }
- AddFrameAxiom(f);
- AddWellformednessCheck(f);
- if (f is CoPredicate) {
- AddCoinductionPrinciple((CoPredicate)f);
- }
-
- } else if (member is Method) {
- Method m = (Method)member;
- bool isRefinementMethod = RefinementToken.IsInherited(m.tok, m.EnclosingClass.Module);
-
- // wellformedness check for method specification
- Bpl.Procedure proc = AddMethod(m, 0, isRefinementMethod);
- sink.TopLevelDeclarations.Add(proc);
- if (m.EnclosingClass is IteratorDecl && m == ((IteratorDecl)m.EnclosingClass).Member_MoveNext) {
- // skip the well-formedness check, because it has already been done for the iterator
- } else {
- AddMethodImpl(m, proc, true);
- }
- // the method itself
- proc = AddMethod(m, 1, isRefinementMethod);
- sink.TopLevelDeclarations.Add(proc);
- if (isRefinementMethod) {
- proc = AddMethod(m, 2, isRefinementMethod);
- sink.TopLevelDeclarations.Add(proc);
- proc = AddMethod(m, 3, isRefinementMethod);
- sink.TopLevelDeclarations.Add(proc);
- }
- if (m.Body != null) {
- // ...and its implementation
- AddMethodImpl(m, proc, false);
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member
- }
- }
- }
-
- void AddIteratorSpecAndBody(IteratorDecl iter) {
- Contract.Requires(iter != null);
-
- bool isRefinementMethod = RefinementToken.IsInherited(iter.tok, iter.Module);
-
- // wellformedness check for method specification
- Bpl.Procedure proc = AddIteratorProc(iter, 0, isRefinementMethod);
- sink.TopLevelDeclarations.Add(proc);
- AddIteratorWellformed(iter, proc);
- // the method itself
- if (iter.Body != null) {
- proc = AddIteratorProc(iter, 1, isRefinementMethod);
- sink.TopLevelDeclarations.Add(proc);
- if (isRefinementMethod) {
- proc = AddIteratorProc(iter, 3, isRefinementMethod);
- sink.TopLevelDeclarations.Add(proc);
- }
- // ...and its implementation
- AddIteratorImpl(iter, proc);
- }
- }
-
- /// <summary>
- /// This method is expected to be called at most 3 times for each procedure in the program:
- /// * once with kind==0, which says to create a procedure for the wellformedness check of the
- /// method's specification
- /// * once with kind==1, which says to create the ordinary procedure for the method, always
- /// suitable for inter-module callers, and for non-refinement methods also suitable for
- /// the implementation and intra-module callers of the method
- /// * possibly once with kind==3 (allowed only if isRefinementMethod), which says to create
- /// a procedure suitable for the implementation of a refinement method
- /// </summary>
- Bpl.Procedure AddIteratorProc(IteratorDecl iter, int kind, bool isRefinementMethod) {
- Contract.Requires(iter != null);
- Contract.Requires(0 <= kind && kind < 4 && kind != 2);
- Contract.Requires(isRefinementMethod || kind < 2);
- Contract.Requires(predef != null);
- Contract.Requires(currentModule == null && codeContext == null);
- Contract.Ensures(currentModule == null && codeContext == null);
- Contract.Ensures(Contract.Result<Bpl.Procedure>() != null);
-
- currentModule = iter.Module;
- codeContext = iter;
-
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, iter.tok);
-
- Bpl.VariableSeq inParams, outParams;
- GenerateMethodParametersChoose(iter.tok, iter, true, true, false, etran, out inParams, out outParams);
-
- var req = new Bpl.RequiresSeq();
- var mod = new Bpl.IdentifierExprSeq();
- var ens = new Bpl.EnsuresSeq();
- if (kind == 0 || (kind == 1 && !isRefinementMethod) || kind == 3) { // the other cases have no need for a free precondition
- // free requires mh == ModuleContextHeight && InMethodContext;
- Bpl.Expr context = Bpl.Expr.And(
- Bpl.Expr.Eq(Bpl.Expr.Literal(iter.Module.Height), etran.ModuleContextHeight()),
- etran.InMethodContext());
- req.Add(Requires(iter.tok, true, context, null, null));
- }
- mod.Add((Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr);
- mod.Add(etran.Tick());
-
- if (kind != 0) {
- string comment = "user-defined preconditions";
- foreach (var p in iter.Requires) {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p.E, etran, out splitHappened)) {
- if (kind == 2 && RefinementToken.IsInherited(s.E.tok, currentModule)) {
- // this precondition was inherited into this module, so just ignore it
- } else {
- req.Add(Requires(s.E.tok, s.IsFree, s.E, null, null));
- // the free here is not linked to the free on the original expression (this is free things generated in the splitting.)
- }
- }
- comment = null;
- }
- comment = "user-defined postconditions";
- foreach (MaybeFreeExpression p in iter.Ensures) {
- if (p.IsFree && !DafnyOptions.O.DisallowSoundnessCheating) {
- ens.Add(Ensures(p.E.tok, true, etran.TrExpr(p.E), null, comment));
- } else {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p.E, etran, out splitHappened)) {
- if (kind == 3 && RefinementToken.IsInherited(s.E.tok, currentModule)) {
- // this postcondition was inherited into this module, so just ignore it
- } else {
- ens.Add(Ensures(s.E.tok, s.IsFree, s.E, null, null));
- }
- }
- }
- comment = null;
- }
- foreach (BoilerplateTriple tri in GetTwoStateBoilerplate(iter.tok, iter.Modifies.Expressions, etran.Old, etran, etran.Old)) {
- ens.Add(Ensures(tri.tok, tri.IsFree, tri.Expr, tri.ErrorMessage, tri.Comment));
- }
- }
-
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(iter.TypeArgs);
- string name;
- switch (kind) {
- case 0: name = "CheckWellformed$$" + iter.FullCompileName; break;
- case 1: name = iter.FullCompileName; break;
- case 3: name = string.Format("RefinementImpl_{0}$${1}", iter.Module.Name, iter.FullCompileName); break;
- default: Contract.Assert(false); throw new cce.UnreachableException(); // unexpected kind
- }
- Bpl.Procedure proc = new Bpl.Procedure(iter.tok, name, typeParams, inParams, outParams, req, mod, ens);
-
- currentModule = null;
- codeContext = null;
-
- return proc;
- }
-
- void AddIteratorWellformed(IteratorDecl iter, Procedure proc) {
- currentModule = iter.Module;
- codeContext = iter;
-
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(iter.TypeArgs);
- Bpl.VariableSeq inParams = Bpl.Formal.StripWhereClauses(proc.InParams);
- Contract.Assert(1 <= inParams.Length); // there should at least be a receiver parameter
- Contract.Assert(proc.OutParams.Length == 0);
-
- var builder = new Bpl.StmtListBuilder();
- var etran = new ExpressionTranslator(this, predef, iter.tok);
- var localVariables = new Bpl.VariableSeq();
-
- Bpl.StmtList stmts;
- // check well-formedness of the preconditions, and then assume each one of them
- foreach (var p in iter.Requires) {
- CheckWellformed(p.E, new WFOptions(), localVariables, builder, etran);
- builder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
- // check well-formedness of the decreases clauses
- foreach (var p in iter.Decreases.Expressions) {
- CheckWellformed(p, new WFOptions(), localVariables, builder, etran);
- }
- // Note: the reads and modifies clauses are not checked for well-formedness (is that sound?), because it used to
- // be that the syntax was not rich enough for programmers to specify modifies clauses and always being
- // absolutely well-defined.
-
- // Next, we assume about this.* whatever we said that the iterator constructor promises
- foreach (var p in iter.Member_Init.Ens) {
- builder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
-
- // play havoc with the heap, except at the locations prescribed by (this._reads - this._modifies - {this})
- var th = new ThisExpr(iter.tok);
- th.Type = Resolver.GetThisType(iter.tok, iter); // resolve here
- var rds = new FieldSelectExpr(iter.tok, th, iter.Member_Reads.Name);
- rds.Field = iter.Member_Reads; // resolve here
- rds.Type = iter.Member_Reads.Type; // resolve here
- var mod = new FieldSelectExpr(iter.tok, th, iter.Member_Modifies.Name);
- mod.Field = iter.Member_Modifies; // resolve here
- mod.Type = iter.Member_Modifies.Type; // resolve here
- builder.Add(new Bpl.CallCmd(iter.tok, "$IterHavoc0",
- new List<Bpl.Expr>() { etran.TrExpr(th), etran.TrExpr(rds), etran.TrExpr(mod) },
- new List<Bpl.IdentifierExpr>()));
-
- // assume the automatic yield-requires precondition (which is always well-formed): this.Valid()
- var validCall = new FunctionCallExpr(iter.tok, "Valid", th, iter.tok, new List<Expression>());
- validCall.Function = iter.Member_Valid; // resolve here
- validCall.Type = Type.Bool; // resolve here
- builder.Add(new Bpl.AssumeCmd(iter.tok, etran.TrExpr(validCall)));
-
- // check well-formedness of the user-defined part of the yield-requires
- foreach (var p in iter.YieldRequires) {
- CheckWellformed(p.E, new WFOptions(), localVariables, builder, etran);
- builder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
-
- // simulate a modifies this, this._modifies, this._new;
- var nw = new FieldSelectExpr(iter.tok, th, iter.Member_New.Name);
- nw.Field = iter.Member_New; // resolve here
- nw.Type = iter.Member_New.Type; // resolve here
- builder.Add(new Bpl.CallCmd(iter.tok, "$IterHavoc1",
- new List<Bpl.Expr>() { etran.TrExpr(th), etran.TrExpr(mod), etran.TrExpr(nw) },
- new List<Bpl.IdentifierExpr>()));
-
- // check wellformedness of postconditions
- var yeBuilder = new Bpl.StmtListBuilder();
- var endBuilder = new Bpl.StmtListBuilder();
- foreach (var p in iter.YieldEnsures) {
- CheckWellformed(p.E, new WFOptions(), localVariables, yeBuilder, etran);
- yeBuilder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
- foreach (var p in iter.Ensures) {
- CheckWellformed(p.E, new WFOptions(), localVariables, endBuilder, etran);
- endBuilder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
- builder.Add(new Bpl.IfCmd(iter.tok, null, yeBuilder.Collect(iter.tok), null, endBuilder.Collect(iter.tok)));
-
- stmts = builder.Collect(iter.tok);
-
- QKeyValue kv = etran.TrAttributes(iter.Attributes, null);
-
- Bpl.Implementation impl = new Bpl.Implementation(iter.tok, proc.Name,
- typeParams, inParams, new VariableSeq(),
- localVariables, stmts, kv);
- sink.TopLevelDeclarations.Add(impl);
-
- currentModule = null;
- codeContext = null;
- loopHeapVarCount = 0;
- otherTmpVarCount = 0;
- _tmpIEs.Clear();
- }
-
- void AddIteratorImpl(IteratorDecl iter, Bpl.Procedure proc) {
- Contract.Requires(iter != null);
- Contract.Requires(proc != null);
- Contract.Requires(sink != null && predef != null);
- Contract.Requires(iter.Body != null);
- Contract.Requires(currentModule == null && codeContext == null && yieldCountVariable == null && loopHeapVarCount == 0 && _tmpIEs.Count == 0);
- Contract.Ensures(currentModule == null && codeContext == null && yieldCountVariable == null && loopHeapVarCount == 0 && _tmpIEs.Count == 0);
-
- currentModule = iter.Module;
- codeContext = iter;
-
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(iter.TypeArgs);
- Bpl.VariableSeq inParams = Bpl.Formal.StripWhereClauses(proc.InParams);
- Contract.Assert(1 <= inParams.Length); // there should at least be a receiver parameter
- Contract.Assert(proc.OutParams.Length == 0);
-
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, iter.tok);
- Bpl.VariableSeq localVariables = new Bpl.VariableSeq();
- GenerateIteratorImplPrelude(iter, inParams, new VariableSeq(), builder, localVariables);
-
- // add locals for the yield-history variables and the extra variables
- // Assume the precondition and postconditions of the iterator constructor method
- foreach (var p in iter.Member_Init.Req) {
- builder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
- foreach (var p in iter.Member_Init.Ens) {
- // these postconditions are two-state predicates, but that's okay, because we haven't changed anything yet
- builder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
- // add the _yieldCount variable, and assume its initial value to be 0
- yieldCountVariable = new Bpl.LocalVariable(iter.tok, new Bpl.TypedIdent(iter.tok, "_yieldCount", Bpl.Type.Int));
- yieldCountVariable.TypedIdent.WhereExpr = YieldCountAssumption(iter, etran); // by doing this after setting "yieldCountVariable", the variable can be used by YieldCountAssumption
- localVariables.Add(yieldCountVariable);
- builder.Add(new Bpl.AssumeCmd(iter.tok, Bpl.Expr.Eq(new Bpl.IdentifierExpr(iter.tok, yieldCountVariable), Bpl.Expr.Literal(0))));
- // add a variable $_OldIterHeap
- var oih = new Bpl.IdentifierExpr(iter.tok, "$_OldIterHeap", predef.HeapType);
- Bpl.Expr wh = BplAnd(
- FunctionCall(iter.tok, BuiltinFunction.IsGoodHeap, null, oih),
- FunctionCall(iter.tok, BuiltinFunction.HeapSucc, null, oih, etran.HeapExpr));
- localVariables.Add(new Bpl.LocalVariable(iter.tok, new Bpl.TypedIdent(iter.tok, "$_OldIterHeap", predef.HeapType, wh)));
-
- // do an initial YieldHavoc
- YieldHavoc(iter.tok, iter, builder, etran);
-
- // translate the body of the method
- var stmts = TrStmt2StmtList(builder, iter.Body, localVariables, etran);
-
- QKeyValue kv = etran.TrAttributes(iter.Attributes, null);
-
- Bpl.Implementation impl = new Bpl.Implementation(iter.tok, proc.Name,
- typeParams, inParams, new VariableSeq(),
- localVariables, stmts, kv);
- sink.TopLevelDeclarations.Add(impl);
-
- currentModule = null;
- codeContext = null;
- yieldCountVariable = null;
- loopHeapVarCount = 0;
- otherTmpVarCount = 0;
- _tmpIEs.Clear();
- }
-
- Bpl.Expr YieldCountAssumption(IteratorDecl iter, ExpressionTranslator etran) {
- Contract.Requires(iter != null);
- Contract.Requires(etran != null);
- Contract.Requires(yieldCountVariable != null);
- Bpl.Expr wh = Bpl.Expr.True;
- foreach (var ys in iter.OutsHistoryFields) {
- // add the conjunct: _yieldCount == |this.ys|
- wh = Bpl.Expr.And(wh, Bpl.Expr.Eq(new Bpl.IdentifierExpr(iter.tok, yieldCountVariable),
- FunctionCall(iter.tok, BuiltinFunction.SeqLength, null,
- ExpressionTranslator.ReadHeap(iter.tok, etran.HeapExpr,
- new Bpl.IdentifierExpr(iter.tok, etran.This, predef.RefType),
- new Bpl.IdentifierExpr(iter.tok, GetField(ys))))));
- }
- return wh;
- }
-
- void AddFunctionAxiomCase(Function f, MatchExpr me, Specialization prev, int layerOffset) {
- Contract.Requires(f != null);
- Contract.Requires(me != null);
- Contract.Requires(layerOffset == 0 || layerOffset == 1);
-
- IVariable formal = ((IdentifierExpr)me.Source.Resolved).Var; // correctness of casts follows from what resolution checks
- foreach (MatchCaseExpr mc in me.Cases) {
- Contract.Assert(mc.Ctor != null); // the field is filled in by resolution
- Specialization s = new Specialization(formal, mc, prev);
- var body = mc.Body.Resolved;
- if (body is MatchExpr) {
- AddFunctionAxiomCase(f, (MatchExpr)body, s, layerOffset);
- } else {
- AddFunctionAxiom(f, body, new List<Expression>(), s, layerOffset);
- }
- }
- }
-
- class Specialization
- {
- public readonly List<Formal/*!*/> Formals;
- public readonly List<Expression/*!*/> ReplacementExprs;
- public readonly List<BoundVar/*!*/> ReplacementFormals;
- public readonly Dictionary<IVariable, Expression> SubstMap;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(Formals));
- Contract.Invariant(cce.NonNullElements(ReplacementExprs));
- Contract.Invariant(Formals.Count == ReplacementExprs.Count);
- Contract.Invariant(cce.NonNullElements(ReplacementFormals));
- Contract.Invariant(SubstMap != null);
- }
-
- public Specialization(IVariable formal, MatchCase mc, Specialization prev) {
- Contract.Requires(formal is Formal || formal is BoundVar);
- Contract.Requires(mc != null);
- Contract.Requires(prev == null || formal is BoundVar || !prev.Formals.Contains((Formal)formal));
-
- List<Expression> rArgs = new List<Expression>();
- foreach (BoundVar p in mc.Arguments) {
- IdentifierExpr ie = new IdentifierExpr(p.tok, p.UniqueName);
- ie.Var = p; ie.Type = ie.Var.Type; // resolve it here
- rArgs.Add(ie);
- }
- // create and resolve datatype value
- var r = new DatatypeValue(mc.tok, mc.Ctor.EnclosingDatatype.Name, mc.Ctor.Name, rArgs);
- r.Ctor = mc.Ctor;
- r.Type = new UserDefinedType(mc.tok, mc.Ctor.EnclosingDatatype.Name, new List<Type>()/*this is not right, but it seems like it won't matter here*/, null);
-
- Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
- substMap.Add(formal, r);
-
- // Fill in the fields
- Formals = new List<Formal>();
- ReplacementExprs = new List<Expression>();
- ReplacementFormals = new List<BoundVar>();
- SubstMap = new Dictionary<IVariable, Expression>();
- if (prev != null) {
- Formals.AddRange(prev.Formals);
- foreach (var e in prev.ReplacementExprs) {
- ReplacementExprs.Add(Substitute(e, null, substMap));
- }
- foreach (var rf in prev.ReplacementFormals) {
- if (rf != formal) {
- ReplacementFormals.Add(rf);
- }
- }
- foreach (var entry in prev.SubstMap) {
- SubstMap.Add(entry.Key, Substitute(entry.Value, null, substMap));
- }
- }
- if (formal is Formal) {
- Formals.Add((Formal)formal);
- ReplacementExprs.Add(r);
- }
- ReplacementFormals.AddRange(mc.Arguments);
- SubstMap.Add(formal, r);
- }
- }
-
- void AddFunctionAxiom(Function/*!*/ f, Expression body, List<Expression/*!*/>/*!*/ ens, Specialization specialization, int layerOffset) {
- if (f is Predicate || f is CoPredicate) {
- var ax = FunctionAxiom(f, FunctionAxiomVisibility.IntraModuleOnly, body, ens, specialization, layerOffset);
- sink.TopLevelDeclarations.Add(ax);
- ax = FunctionAxiom(f, FunctionAxiomVisibility.ForeignModuleOnly, body, ens, specialization, layerOffset);
- sink.TopLevelDeclarations.Add(ax);
- } else {
- var ax = FunctionAxiom(f, FunctionAxiomVisibility.All, body, ens, specialization, layerOffset);
- sink.TopLevelDeclarations.Add(ax);
- }
- }
-
- enum FunctionAxiomVisibility { All, IntraModuleOnly, ForeignModuleOnly }
-
- Bpl.Axiom/*!*/ FunctionAxiom(Function/*!*/ f, FunctionAxiomVisibility visibility, Expression body, List<Expression/*!*/>/*!*/ ens, Specialization specialization, int layerOffset) {
- Contract.Requires(f != null);
- Contract.Requires(ens != null);
- Contract.Requires(layerOffset == 0 || (layerOffset == 1 && f.IsRecursive));
- Contract.Requires(predef != null);
- Contract.Requires(f.EnclosingClass != null);
-
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, f.tok);
-
- // axiom
- // mh < ModuleContextHeight || // (a)
- // (mh == ModuleContextHeight && (fh <= FunctionContextHeight || InMethodContext)) // (b)
- // ==>
- // (forall $Heap, formals ::
- // { f(args) }
- // f#canCall(args) ||
- // ( (mh != ModuleContextHeight || fh != FunctionContextHeight || InMethodContext) && // (c)
- // $IsHeap($Heap) && this != null && formals-have-the-expected-types &&
- // Pre($Heap,args))
- // ==>
- // body-can-make-its-calls && // generated only for layerOffset==0
- // f(args) == body && // (d)
- // ens && // generated only for layerOffset==0
- // f(args)-has-the-expected-type); // generated only for layerOffset==0
- //
- // The variables "formals" are the formals of function "f"; except, if a specialization is provided, then
- // "specialization.Formals" (which are expected to be among the formals of "f") are excluded and replaced by
- // "specialization.ReplacementFormals".
- // The list "args" is the list of formals of function "f"; except, if a specialization is provided, then
- // each of the "specialization.Formals" is replaced by the corresponding expression in "specialization.ReplacementExprs".
- // If a specialization is provided, occurrences of "specialization.Formals" in "body", "f.Req", and "f.Ens"
- // are also replaced by those corresponding expressions.
- //
- // The translation of "body" uses the #limited form whenever the callee is in the same SCC of the call graph.
- //
- // if layerOffset==1, then the names f#2 and f are used instead of f and f#limited.
- //
- // Visibility: The above description is for visibility==All. If visibility==IntraModuleOnly, then
- // disjunct (a) is dropped (which also has a simplifying effect on (c)). Finally, if visibility==ForeignModuleOnly,
- // then disjunct (b) is dropped (which also has a simplify effect on(c)); furthermore, if f is a Predicate,
- // then the equality in (d) is replaced by an implication.
- //
- // Note, an antecedent $Heap[this,alloc] is intentionally left out: including it would only weaken
- // the axiom. Moreover, leaving it out does not introduce any soundness problem, because the Dafny
- // allocation statement changes only an allocation bit and then re-assumes $IsGoodHeap; so if it is
- // sound after that, then it would also have been sound just before the allocation.
- //
- Bpl.VariableSeq formals = new Bpl.VariableSeq();
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- Bpl.BoundVariable bv = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, predef.HeapVarName, predef.HeapType));
- formals.Add(bv);
- args.Add(new Bpl.IdentifierExpr(f.tok, bv));
- // ante: $IsHeap($Heap) && this != null && formals-have-the-expected-types &&
- Bpl.Expr ante = FunctionCall(f.tok, BuiltinFunction.IsGoodHeap, null, etran.HeapExpr);
-
- Bpl.BoundVariable bvThis;
- Bpl.Expr bvThisIdExpr;
- if (f.IsStatic) {
- bvThis = null;
- bvThisIdExpr = null;
- } else {
- bvThis = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, etran.This, predef.RefType));
- formals.Add(bvThis);
- bvThisIdExpr = new Bpl.IdentifierExpr(f.tok, bvThis);
- args.Add(bvThisIdExpr);
- // add well-typedness conjunct to antecedent
- Type thisType = Resolver.GetReceiverType(f.tok, f);
- Bpl.Expr wh = Bpl.Expr.And(
- Bpl.Expr.Neq(bvThisIdExpr, predef.Null),
- etran.GoodRef(f.tok, bvThisIdExpr, thisType));
- ante = Bpl.Expr.And(ante, wh);
- }
- if (specialization != null) {
- foreach (BoundVar p in specialization.ReplacementFormals) {
- bv = new Bpl.BoundVariable(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, TrType(p.Type)));
- formals.Add(bv);
- // add well-typedness conjunct to antecedent
- Bpl.Expr wh = GetWhereClause(p.tok, new Bpl.IdentifierExpr(p.tok, bv), p.Type, etran);
- if (wh != null) { ante = Bpl.Expr.And(ante, wh); }
- }
- }
- foreach (Formal p in f.Formals) {
- int i = specialization == null ? -1 : specialization.Formals.FindIndex(val => val == p);
- if (i == -1) {
- bv = new Bpl.BoundVariable(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, TrType(p.Type)));
- formals.Add(bv);
- Bpl.Expr formal = new Bpl.IdentifierExpr(p.tok, bv);
- args.Add(formal);
- // add well-typedness conjunct to antecedent
- Bpl.Expr wh = GetWhereClause(p.tok, formal, p.Type, etran);
- if (wh != null) { ante = Bpl.Expr.And(ante, wh); }
- } else {
- args.Add(etran.TrExpr(specialization.ReplacementExprs[i]));
- // note, well-typedness conjuncts for the replacement formals has already been done above
- }
- }
-
- // mh < ModuleContextHeight || (mh == ModuleContextHeight && (fh <= FunctionContextHeight || InMethodContext))
- ModuleDefinition mod = f.EnclosingClass.Module;
- var activateForeign = Bpl.Expr.Lt(Bpl.Expr.Literal(mod.Height), etran.ModuleContextHeight());
- var activateIntra =
- Bpl.Expr.And(
- Bpl.Expr.Eq(Bpl.Expr.Literal(mod.Height), etran.ModuleContextHeight()),
- Bpl.Expr.Or(
- Bpl.Expr.Le(Bpl.Expr.Literal(mod.CallGraph.GetSCCRepresentativeId(f)), etran.FunctionContextHeight()),
- etran.InMethodContext()));
- Bpl.Expr activate =
- visibility == FunctionAxiomVisibility.All ? Bpl.Expr.Or(activateForeign, activateIntra) :
- visibility == FunctionAxiomVisibility.IntraModuleOnly ? activateIntra : activateForeign;
-
- var substMap = new Dictionary<IVariable, Expression>();
- if (specialization != null) {
- substMap = specialization.SubstMap;
- }
- Bpl.IdentifierExpr funcID = new Bpl.IdentifierExpr(f.tok, FunctionName(f, 1+layerOffset), TrType(f.ResultType));
- Bpl.Expr funcAppl = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(funcID), args);
-
- Bpl.Expr pre = Bpl.Expr.True;
- foreach (Expression req in f.Req) {
- pre = BplAnd(pre, etran.TrExpr(Substitute(req, null, substMap)));
- }
- // useViaContext: (mh != ModuleContextHeight || fh != FunctionContextHeight || InMethodContext)
- Bpl.Expr useViaContext = visibility == FunctionAxiomVisibility.ForeignModuleOnly ? Bpl.Expr.True :
- Bpl.Expr.Or(Bpl.Expr.Or(
- visibility == FunctionAxiomVisibility.IntraModuleOnly ?
- (Bpl.Expr)Bpl.Expr.False :
- Bpl.Expr.Neq(Bpl.Expr.Literal(mod.Height), etran.ModuleContextHeight()),
- Bpl.Expr.Neq(Bpl.Expr.Literal(mod.CallGraph.GetSCCRepresentativeId(f)), etran.FunctionContextHeight())),
- etran.InMethodContext());
- // useViaCanCall: f#canCall(args)
- Bpl.IdentifierExpr canCallFuncID = new Bpl.IdentifierExpr(f.tok, f.FullCompileName + "#canCall", Bpl.Type.Bool);
- Bpl.Expr useViaCanCall = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(canCallFuncID), args);
-
- // ante := useViaCanCall || (useViaContext && typeAnte && pre)
- ante = Bpl.Expr.Or(useViaCanCall, BplAnd(useViaContext, BplAnd(ante, pre)));
-
- Bpl.Trigger tr = new Bpl.Trigger(f.tok, true, new Bpl.ExprSeq(funcAppl));
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(f.TypeArgs);
- Bpl.Expr meat;
- if (body == null) {
- meat = Bpl.Expr.True;
- } else {
- Expression bodyWithSubst = Substitute(body, null, substMap);
- if (layerOffset == 0) {
- meat = Bpl.Expr.And(
- CanCallAssumption(bodyWithSubst, etran),
- visibility == FunctionAxiomVisibility.ForeignModuleOnly && (f is Predicate || f is CoPredicate) ?
- Bpl.Expr.Imp(funcAppl, etran.LimitedFunctions(f).TrExpr(bodyWithSubst)) :
- Bpl.Expr.Eq(funcAppl, etran.LimitedFunctions(f).TrExpr(bodyWithSubst)));
- } else {
- meat = visibility == FunctionAxiomVisibility.ForeignModuleOnly && (f is Predicate || f is CoPredicate) ?
- Bpl.Expr.Imp(funcAppl, etran.TrExpr(bodyWithSubst)) :
- Bpl.Expr.Eq(funcAppl, etran.TrExpr(bodyWithSubst));
- }
- }
- if (layerOffset == 0) {
- foreach (Expression p in ens) {
- Bpl.Expr q = etran.LimitedFunctions(f).TrExpr(Substitute(p, null, substMap));
- meat = BplAnd(meat, q);
- }
- Bpl.Expr whr = GetWhereClause(f.tok, funcAppl, f.ResultType, etran);
- if (whr != null) { meat = Bpl.Expr.And(meat, whr); }
- }
- Bpl.Expr ax = new Bpl.ForallExpr(f.tok, typeParams, formals, null, tr, Bpl.Expr.Imp(ante, meat));
- string comment = "definition axiom for " + FunctionName(f, 1+layerOffset);
- if (visibility == FunctionAxiomVisibility.IntraModuleOnly) {
- comment += " (intra-module)";
- } else if (visibility == FunctionAxiomVisibility.ForeignModuleOnly) {
- comment += " (foreign modules)";
- }
- if (specialization != null) {
- string sep = "{0}, specialized for '{1}'";
- foreach (var formal in specialization.Formals) {
- comment = string.Format(sep, comment, formal.Name);
- sep = "{0}, '{1}'";
- }
- }
- return new Bpl.Axiom(f.tok, Bpl.Expr.Imp(activate, ax), comment);
- }
-
- void AddLimitedAxioms(Function f, int fromLayer) {
- Contract.Requires(f != null);
- Contract.Requires(f.IsRecursive);
- Contract.Requires(fromLayer == 1 || fromLayer == 2);
- Contract.Requires(sink != null && predef != null);
- // With fromLayer==1, generate:
- // axiom (forall formals :: { f(args) } f(args) == f#limited(args))
- // With fromLayer==2, generate:
- // axiom (forall formals :: { f#2(args) } f#2(args) == f(args))
-
- Bpl.VariableSeq formals = new Bpl.VariableSeq();
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- Bpl.BoundVariable bv = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, predef.HeapVarName, predef.HeapType));
- formals.Add(bv);
- args.Add(new Bpl.IdentifierExpr(f.tok, bv));
- Bpl.BoundVariable bvThis;
- Bpl.Expr bvThisIdExpr;
- if (f.IsStatic) {
- bvThis = null;
- bvThisIdExpr = null;
- } else {
- bvThis = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "this", predef.RefType));
- formals.Add(bvThis);
- bvThisIdExpr = new Bpl.IdentifierExpr(f.tok, bvThis);
- args.Add(bvThisIdExpr);
- }
- foreach (Formal p in f.Formals) {
- bv = new Bpl.BoundVariable(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, TrType(p.Type)));
- formals.Add(bv);
- args.Add(new Bpl.IdentifierExpr(p.tok, bv));
- }
-
- Bpl.FunctionCall origFuncID = new Bpl.FunctionCall(new Bpl.IdentifierExpr(f.tok, FunctionName(f, fromLayer), TrType(f.ResultType)));
- Bpl.Expr origFuncAppl = new Bpl.NAryExpr(f.tok, origFuncID, args);
- Bpl.FunctionCall limitedFuncID = new Bpl.FunctionCall(new Bpl.IdentifierExpr(f.tok, FunctionName(f, fromLayer-1), TrType(f.ResultType)));
- Bpl.Expr limitedFuncAppl = new Bpl.NAryExpr(f.tok, limitedFuncID, args);
-
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(f.TypeArgs);
-
- Bpl.Trigger tr = new Bpl.Trigger(f.tok, true, new Bpl.ExprSeq(origFuncAppl));
- Bpl.Expr ax = new Bpl.ForallExpr(f.tok, typeParams, formals, null, tr, Bpl.Expr.Eq(origFuncAppl, limitedFuncAppl));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(f.tok, ax));
- }
-
- /// <summary>
- /// Returns the appropriate Boogie function for the given function. In particular:
- /// Layer 2: f#2 --currently used only for induction axioms
- /// Layer 1: f --this is the default name
- /// Layer 0: f#limited --does not trigger the function definition axiom
- /// </summary>
- public static string FunctionName(Function f, int layer) {
- Contract.Requires(f != null);
- Contract.Requires(0 <= layer && layer < 3);
- Contract.Ensures(Contract.Result<string>() != null);
-
- string name = f.FullCompileName;
- switch (layer) {
- case 2: name += "#2"; break;
- case 0: name += "#limited"; break;
- }
- return name;
- }
-
- /// <summary>
- /// Generate:
- /// axiom (forall h: [ref, Field x]x, o: ref ::
- /// { h[o,f] }
- /// $IsGoodHeap(h) && o != null && h[o,alloc] ==> h[o,f]-has-the-expected-type);
- /// </summary>
- void AddAllocationAxiom(Field f)
- {
- Contract.Requires(f != null);
- Contract.Requires(sink != null && predef != null);
-
- Bpl.BoundVariable hVar = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$h", predef.HeapType));
- Bpl.Expr h = new Bpl.IdentifierExpr(f.tok, hVar);
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, h);
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$o", predef.RefType));
- Bpl.Expr o = new Bpl.IdentifierExpr(f.tok, oVar);
-
- // h[o,f]
- Bpl.Expr oDotF;
- if (f.IsMutable) {
- oDotF = ExpressionTranslator.ReadHeap(f.tok, h, o, new Bpl.IdentifierExpr(f.tok, GetField(f)));
- } else {
- oDotF = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(GetReadonlyField(f)), new Bpl.ExprSeq(o));
- }
-
- Bpl.Expr wh = GetWhereClause(f.tok, oDotF, f.Type, etran);
- if (wh != null) {
- // ante: $IsGoodHeap(h) && o != null && h[o,alloc]
- Bpl.Expr ante = Bpl.Expr.And(Bpl.Expr.And(
- FunctionCall(f.tok, BuiltinFunction.IsGoodHeap, null, h),
- Bpl.Expr.Neq(o, predef.Null)),
- etran.IsAlloced(f.tok, o));
- Bpl.Expr body = Bpl.Expr.Imp(ante, wh);
- Bpl.Trigger tr = f.IsMutable ? new Bpl.Trigger(f.tok, true, new Bpl.ExprSeq(oDotF)) : null; // the trigger must include both "o" and "h"
- Bpl.Expr ax = new Bpl.ForallExpr(f.tok, new Bpl.VariableSeq(hVar, oVar), tr, body);
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(f.tok, ax));
- }
- }
-
- Bpl.Expr InSeqRange(IToken tok, Bpl.Expr index, Bpl.Expr seq, bool isSequence, Bpl.Expr lowerBound, bool includeUpperBound) {
- Contract.Requires(tok != null);
- Contract.Requires(index != null);
- Contract.Requires(seq != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (lowerBound == null) {
- lowerBound = Bpl.Expr.Literal(0);
- }
- Bpl.Expr lower = Bpl.Expr.Le(lowerBound, index);
- Bpl.Expr length = isSequence ?
- FunctionCall(tok, BuiltinFunction.SeqLength, null, seq) :
- ArrayLength(tok, seq, 1, 0);
- Bpl.Expr upper;
- if (includeUpperBound) {
- upper = Bpl.Expr.Le(index, length);
- } else {
- upper = Bpl.Expr.Lt(index, length);
- }
- return Bpl.Expr.And(lower, upper);
- }
-
- ModuleDefinition currentModule = null; // the name of the module whose members are currently being translated
- ICodeContext codeContext = null; // the method/iterator whose implementation is currently being translated
- LocalVariable yieldCountVariable = null; // non-null when an iterator body is being translated
- int loopHeapVarCount = 0;
- int otherTmpVarCount = 0;
- Dictionary<string, Bpl.IdentifierExpr> _tmpIEs = new Dictionary<string, Bpl.IdentifierExpr>();
- Bpl.IdentifierExpr GetTmpVar_IdExpr(IToken tok, string name, Bpl.Type ty, Bpl.VariableSeq locals) // local variable that's shared between statements that need it
- {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(ty != null);
- Contract.Requires(locals != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>() != null);
-
- Bpl.IdentifierExpr ie;
- if (_tmpIEs.TryGetValue(name, out ie)) {
- Contract.Assume(ie.Type.Equals(ty));
- } else {
- // the "tok" and "ty" of the first request for this variable is the one we use
- var v = new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, name, ty)); // important for the "$nw" client: no where clause (see GetNewVar_IdExpr)
- locals.Add(v);
- ie = new Bpl.IdentifierExpr(tok, v);
- _tmpIEs.Add(name, ie);
- }
- return ie;
- }
-
- Bpl.IdentifierExpr GetPrevHeapVar_IdExpr(IToken tok, Bpl.VariableSeq locals) { // local variable that's shared between statements that need it
- Contract.Requires(tok != null);
- Contract.Requires(locals != null); Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>() != null);
-
- return GetTmpVar_IdExpr(tok, "$prevHeap", predef.HeapType, locals);
- }
-
- Bpl.IdentifierExpr GetNewVar_IdExpr(IToken tok, Bpl.VariableSeq locals) // local variable that's shared between statements that need it
- {
- Contract.Requires(tok != null);
- Contract.Requires(locals != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>() != null);
-
- // important: the following declaration produces no where clause (that's why we're going through the trouble of setting of this variable in the first place)
- return GetTmpVar_IdExpr(tok, "$nw", predef.RefType, locals);
- }
-
- /// <summary>
- /// Returns an expression whose value is the same as "expr", but that is guaranteed to preserve the its value passed
- /// the evaluation of other expressions. If necessary, a new local variable called "name" with type "ty" is added to "locals" and
- /// assigned in "builder" to be used to hold the value of "expr". It is assumed that all requests for a given "name"
- /// have the same type "ty" and that these variables can be shared.
- /// As an optimization, if "otherExprsCanAffectPreviouslyKnownExpressions" is "false", then "expr" itself is returned.
- /// </summary>
- Bpl.Expr SaveInTemp(Bpl.Expr expr, bool otherExprsCanAffectPreviouslyKnownExpressions, string name, Bpl.Type ty, Bpl.StmtListBuilder builder, Bpl.VariableSeq locals) {
- Contract.Requires(expr != null);
- Contract.Requires(name != null);
- Contract.Requires(ty != null);
- Contract.Requires(locals != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (otherExprsCanAffectPreviouslyKnownExpressions) {
- var save = GetTmpVar_IdExpr(expr.tok, name, ty, locals);
- builder.Add(Bpl.Cmd.SimpleAssign(expr.tok, save, expr));
- return save;
- } else {
- return expr;
- }
- }
-
- void AddMethodImpl(Method m, Bpl.Procedure proc, bool wellformednessProc)
- {
- Contract.Requires(m != null);
- Contract.Requires(proc != null);
- Contract.Requires(sink != null && predef != null);
- Contract.Requires(wellformednessProc || m.Body != null);
- Contract.Requires(currentModule == null && codeContext == null && loopHeapVarCount == 0 && _tmpIEs.Count == 0);
- Contract.Ensures(currentModule == null && codeContext == null && loopHeapVarCount == 0 && _tmpIEs.Count == 0);
-
- currentModule = m.EnclosingClass.Module;
- codeContext = m;
-
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(m.TypeArgs);
- Bpl.VariableSeq inParams = Bpl.Formal.StripWhereClauses(proc.InParams);
- Bpl.VariableSeq outParams = Bpl.Formal.StripWhereClauses(proc.OutParams);
-
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, m.tok);
- Bpl.VariableSeq localVariables = new Bpl.VariableSeq();
- GenerateImplPrelude(m, inParams, outParams, builder, localVariables);
-
- Bpl.StmtList stmts;
- if (!wellformednessProc) {
- if (3 <= DafnyOptions.O.Induction && m.IsGhost && m.Mod.Expressions.Count == 0 && m.Outs.Count == 0) {
- var posts = new List<Expression>();
- m.Ens.ForEach(mfe => posts.Add(mfe.E));
- var allIns = new List<Formal>();
- if (!m.IsStatic) {
- allIns.Add(new ThisSurrogate(m.tok, Resolver.GetThisType(m.tok, (ClassDecl)m.EnclosingClass)));
- }
- allIns.AddRange(m.Ins);
- var inductionVars = ApplyInduction(allIns, m.Attributes, posts, delegate(System.IO.TextWriter wr) { wr.Write(m.FullName); });
- if (inductionVars.Count != 0) {
- // Let the parameters be this,x,y of the method M and suppose ApplyInduction returns this,y.
- // Also, let Pre be the precondition and VF be the decreases clause.
- // Then, insert into the method body what amounts to:
- // assume case-analysis-on-parameter[[ y' ]];
- // parallel (this', y' | Pre(this', x, y') && VF(this', x, y') << VF(this, x, y)) {
- // this'.M(x, y');
- // }
- // Generate bound variables for the parallel statement, and a substitution for the Pre and VF
-
- // assume case-analysis-on-parameter[[ y' ]];
- foreach (var inFormal in m.Ins) {
- var dt = inFormal.Type.AsDatatype;
- if (dt != null) {
- var funcID = new Bpl.FunctionCall(new Bpl.IdentifierExpr(inFormal.tok, "$IsA#" + dt.FullCompileName, Bpl.Type.Bool));
- var f = new Bpl.IdentifierExpr(inFormal.tok, inFormal.UniqueName, TrType(inFormal.Type));
- builder.Add(new Bpl.AssumeCmd(inFormal.tok, new Bpl.NAryExpr(inFormal.tok, funcID, new Bpl.ExprSeq(f))));
- }
- }
-
- var parBoundVars = new List<BoundVar>();
- Expression receiverReplacement = null;
- var substMap = new Dictionary<IVariable, Expression>();
- foreach (var iv in inductionVars) {
- BoundVar bv;
- IdentifierExpr ie;
- CloneVariableAsBoundVar(iv.tok, iv, "$ih#" + iv.Name, out bv, out ie);
- parBoundVars.Add(bv);
- if (iv is ThisSurrogate) {
- Contract.Assert(receiverReplacement == null && substMap.Count == 0); // the receiver comes first, if at all
- receiverReplacement = ie;
- } else {
- substMap.Add(iv, ie);
- }
- }
-
- // Generate a CallStmt for the recursive call
- Expression recursiveCallReceiver;
- if (receiverReplacement != null) {
- recursiveCallReceiver = receiverReplacement;
- } else if (m.IsStatic) {
- recursiveCallReceiver = new StaticReceiverExpr(m.tok, (ClassDecl)m.EnclosingClass); // this also resolves it
- } else {
- recursiveCallReceiver = new ImplicitThisExpr(m.tok);
- recursiveCallReceiver.Type = Resolver.GetThisType(m.tok, (ClassDecl)m.EnclosingClass); // resolve here
- }
- var recursiveCallArgs = new List<Expression>();
- foreach (var inFormal in m.Ins) {
- Expression inE;
- if (substMap.TryGetValue(inFormal, out inE)) {
- recursiveCallArgs.Add(inE);
- } else {
- var ie = new IdentifierExpr(inFormal.tok, inFormal.Name);
- ie.Var = inFormal; // resolve here
- ie.Type = inFormal.Type; // resolve here
- recursiveCallArgs.Add(ie);
- }
- }
- var recursiveCall = new CallStmt(m.tok, new List<Expression>(), recursiveCallReceiver, m.Name, recursiveCallArgs);
- recursiveCall.Method = m; // resolve here
-
- Expression parRange = new LiteralExpr(m.tok, true);
- parRange.Type = Type.Bool; // resolve here
- if (receiverReplacement != null) {
- // add "this' != null" to the range
- var nil = new LiteralExpr(receiverReplacement.tok);
- nil.Type = receiverReplacement.Type; // resolve here
- var neqNull = new BinaryExpr(receiverReplacement.tok, BinaryExpr.Opcode.Neq, receiverReplacement, nil);
- neqNull.ResolvedOp = BinaryExpr.ResolvedOpcode.NeqCommon; // resolve here
- neqNull.Type = Type.Bool; // resolve here
- parRange = DafnyAnd(parRange, neqNull);
- }
- foreach (var pre in m.Req) {
- if (!pre.IsFree) {
- parRange = DafnyAnd(parRange, Substitute(pre.E, receiverReplacement, substMap));
- }
- }
- // construct an expression (generator) for: VF' << VF
- ExpressionConverter decrCheck = delegate(Dictionary<IVariable, Expression> decrSubstMap, ExpressionTranslator exprTran) {
- var decrToks = new List<IToken>();
- var decrTypes = new List<Type>();
- var decrCallee = new List<Bpl.Expr>();
- var decrCaller = new List<Bpl.Expr>();
- bool decrInferred; // we don't actually care
- foreach (var ee in MethodDecreasesWithDefault(m, out decrInferred)) {
- decrToks.Add(ee.tok);
- decrTypes.Add(ee.Type);
- decrCaller.Add(exprTran.TrExpr(ee));
- Expression es = Substitute(ee, receiverReplacement, substMap);
- es = Substitute(es, null, decrSubstMap);
- decrCallee.Add(exprTran.TrExpr(es));
- }
- return DecreasesCheck(decrToks, decrTypes, decrCallee, decrCaller, exprTran, null, null, false, true);
- };
-
-#if VERIFY_CORRECTNESS_OF_TRANSLATION_PARALLEL_RANGE
- var definedness = new Bpl.StmtListBuilder();
- var exporter = new Bpl.StmtListBuilder();
- TrParallelCall(m.tok, parBoundVars, parRange, decrCheck, recursiveCall, definedness, exporter, localVariables, etran);
- // All done, so put the two pieces together
- builder.Add(new Bpl.IfCmd(m.tok, null, definedness.Collect(m.tok), null, exporter.Collect(m.tok)));
-#else
- TrParallelCall(m.tok, parBoundVars, parRange, decrCheck, recursiveCall, null, builder, localVariables, etran);
-#endif
- }
- }
- // translate the body of the method
- Contract.Assert(m.Body != null); // follows from method precondition and the if guard
- stmts = TrStmt2StmtList(builder, m.Body, localVariables, etran);
- } else {
- // check well-formedness of the preconditions, and then assume each one of them
- foreach (MaybeFreeExpression p in m.Req) {
- CheckWellformed(p.E, new WFOptions(), localVariables, builder, etran);
- builder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
- // Note: the modifies clauses are not checked for well-formedness (is that sound?), because it used to
- // be that the syntax was not rich enough for programmers to specify modifies clauses and always being
- // absolutely well-defined.
- // check well-formedness of the decreases clauses
- foreach (Expression p in m.Decreases.Expressions)
- {
- CheckWellformed(p, new WFOptions(), localVariables, builder, etran);
- }
-
- // play havoc with the heap according to the modifies clause
- builder.Add(new Bpl.HavocCmd(m.tok, new Bpl.IdentifierExprSeq((Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr)));
- // assume the usual two-state boilerplate information
- foreach (BoilerplateTriple tri in GetTwoStateBoilerplate(m.tok, m.Mod.Expressions, etran.Old, etran, etran.Old))
- {
- if (tri.IsFree) {
- builder.Add(new Bpl.AssumeCmd(m.tok, tri.Expr));
- }
- }
-
- // also play havoc with the out parameters
- if (outParams.Length != 0) { // don't create an empty havoc statement
- Bpl.IdentifierExprSeq outH = new Bpl.IdentifierExprSeq();
- foreach (Bpl.Variable b in outParams) {
- Contract.Assert(b != null);
- outH.Add(new Bpl.IdentifierExpr(b.tok, b));
- }
- builder.Add(new Bpl.HavocCmd(m.tok, outH));
- }
-
- // check wellformedness of postconditions
- foreach (MaybeFreeExpression p in m.Ens) {
- CheckWellformed(p.E, new WFOptions(), localVariables, builder, etran);
- builder.Add(new Bpl.AssumeCmd(p.E.tok, etran.TrExpr(p.E)));
- }
-
- stmts = builder.Collect(m.tok);
- }
-
- QKeyValue kv = etran.TrAttributes(m.Attributes, null);
-
- Bpl.Implementation impl = new Bpl.Implementation(m.tok, proc.Name,
- typeParams, inParams, outParams,
- localVariables, stmts, kv);
- sink.TopLevelDeclarations.Add(impl);
-
- currentModule = null;
- codeContext = null;
- loopHeapVarCount = 0;
- otherTmpVarCount = 0;
- _tmpIEs.Clear();
- }
-
- void GenerateImplPrelude(Method m, Bpl.VariableSeq inParams, Bpl.VariableSeq outParams,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq localVariables){
- Contract.Requires(m != null);
- Contract.Requires(inParams != null);
- Contract.Requires(outParams != null);
- Contract.Requires(builder != null);
- Contract.Requires(localVariables != null);
- Contract.Requires(predef != null);
-
- // set up the information used to verify the method's modifies clause
- DefineFrame(m.tok, m.Mod.Expressions, builder, localVariables, null);
- }
-
- void GenerateIteratorImplPrelude(IteratorDecl iter, Bpl.VariableSeq inParams, Bpl.VariableSeq outParams,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq localVariables) {
- Contract.Requires(iter != null);
- Contract.Requires(inParams != null);
- Contract.Requires(outParams != null);
- Contract.Requires(builder != null);
- Contract.Requires(localVariables != null);
- Contract.Requires(predef != null);
-
- // set up the information used to verify the method's modifies clause
- var iteratorFrame = new List<FrameExpression>();
- var th = new ThisExpr(iter.tok);
- th.Type = Resolver.GetThisType(iter.tok, iter); // resolve here
- iteratorFrame.Add(new FrameExpression(iter.tok, th, null));
- iteratorFrame.AddRange(iter.Modifies.Expressions);
- DefineFrame(iter.tok, iteratorFrame, builder, localVariables, null);
- }
-
- Bpl.Cmd CaptureState(IToken tok, string/*?*/ additionalInfo) {
- Contract.Requires(tok != null);
- Contract.Ensures(Contract.Result<Bpl.Cmd>() != null);
- string description = string.Format("{0}({1},{2}){3}{4}", tok.filename, tok.line, tok.col, additionalInfo == null ? "" : ": ", additionalInfo ?? "");
- QKeyValue kv = new QKeyValue(tok, "captureState", new List<object>() { description }, null);
- return new Bpl.AssumeCmd(tok, Bpl.Expr.True, kv);
- }
- Bpl.Cmd CaptureState(IToken tok) {
- Contract.Requires(tok != null);
- Contract.Ensures(Contract.Result<Bpl.Cmd>() != null);
- return CaptureState(tok, null);
- }
-
- void DefineFrame(IToken/*!*/ tok, List<FrameExpression/*!*/>/*!*/ frameClause, Bpl.StmtListBuilder/*!*/ builder, Bpl.VariableSeq/*!*/ localVariables, string name){
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(frameClause));
- Contract.Requires(builder != null);
- Contract.Requires(cce.NonNullElements(localVariables));
- Contract.Requires(predef != null);
-
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, tok);
- // Declare a local variable $_Frame: <alpha>[ref, Field alpha]bool
- Bpl.IdentifierExpr theFrame = etran.TheFrame(tok); // this is a throw-away expression, used only to extract the type of the $_Frame variable
- Contract.Assert(theFrame.Type != null); // follows from the postcondition of TheFrame
- Bpl.LocalVariable frame = new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, name ?? theFrame.Name, theFrame.Type));
- localVariables.Add(frame);
- // $_Frame := (lambda<alpha> $o: ref, $f: Field alpha :: $o != null && $Heap[$o,alloc] ==> ($o,$f) in Modifies/Reads-Clause);
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(tok, "alpha");
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$o", predef.RefType));
- Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(tok, oVar);
- Bpl.BoundVariable fVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$f", predef.FieldName(tok, alpha)));
- Bpl.IdentifierExpr f = new Bpl.IdentifierExpr(tok, fVar);
- Bpl.Expr ante = Bpl.Expr.And(Bpl.Expr.Neq(o, predef.Null), etran.IsAlloced(tok, o));
- Bpl.Expr consequent = InRWClause(tok, o, f, frameClause, etran, null, null);
- Bpl.Expr lambda = new Bpl.LambdaExpr(tok, new Bpl.TypeVariableSeq(alpha), new Bpl.VariableSeq(oVar, fVar), null,
- Bpl.Expr.Imp(ante, consequent));
-
- builder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, frame), lambda));
- }
-
- void CheckFrameSubset(IToken tok, List<FrameExpression/*!*/>/*!*/ calleeFrame,
- Expression receiverReplacement, Dictionary<IVariable,Expression/*!*/> substMap,
- ExpressionTranslator/*!*/ etran, Bpl.StmtListBuilder/*!*/ builder, string errorMessage,
- Bpl.QKeyValue kv)
- {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(calleeFrame));
- Contract.Requires((receiverReplacement == null) == (substMap == null));
- Contract.Requires(substMap == null || cce.NonNullDictionaryAndValues(substMap));
- Contract.Requires(etran != null);
- Contract.Requires(builder != null);
- Contract.Requires(errorMessage != null);
- Contract.Requires(predef != null);
-
- // emit: assert (forall<alpha> o: ref, f: Field alpha :: o != null && $Heap[o,alloc] && (o,f) in subFrame ==> $_Frame[o,f]);
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(tok, "alpha");
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$o", predef.RefType));
- Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(tok, oVar);
- Bpl.BoundVariable fVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$f", predef.FieldName(tok, alpha)));
- Bpl.IdentifierExpr f = new Bpl.IdentifierExpr(tok, fVar);
- Bpl.Expr ante = Bpl.Expr.And(Bpl.Expr.Neq(o, predef.Null), etran.IsAlloced(tok, o));
- Bpl.Expr oInCallee = InRWClause(tok, o, f, calleeFrame, etran, receiverReplacement, substMap);
- Bpl.Expr inEnclosingFrame = Bpl.Expr.Select(etran.TheFrame(tok), o, f);
- Bpl.Expr q = new Bpl.ForallExpr(tok, new Bpl.TypeVariableSeq(alpha), new Bpl.VariableSeq(oVar, fVar),
- Bpl.Expr.Imp(Bpl.Expr.And(ante, oInCallee), inEnclosingFrame));
- builder.Add(Assert(tok, q, errorMessage, kv));
- }
-
- /// <summary>
- /// Generates:
- /// axiom (forall h0: HeapType, h1: HeapType, formals... ::
- /// { HeapSucc(h0,h1), F(h1,formals) }
- /// heaps are well-formed and formals are allocated AND
- /// HeapSucc(h0,h1)
- /// AND
- /// (forall(alpha) o: ref, f: Field alpha ::
- /// o != null AND h0[o,alloc] AND h1[o,alloc] AND
- /// o in reads clause of formals in h0
- /// IMPLIES h0[o,f] == h1[o,f])
- /// IMPLIES
- /// F(h0,formals) == F(h1,formals)
- /// );
- ///
- /// If the function is a recursive function, then the same axiom is also produced for "F#limited" instead of "F".
- /// </summary>
- void AddFrameAxiom(Function f)
- {
- Contract.Requires(f != null);
- Contract.Requires(sink != null && predef != null);
-
- Bpl.BoundVariable h0Var = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$h0", predef.HeapType));
- Bpl.BoundVariable h1Var = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$h1", predef.HeapType));
- Bpl.Expr h0 = new Bpl.IdentifierExpr(f.tok, h0Var);
- Bpl.Expr h1 = new Bpl.IdentifierExpr(f.tok, h1Var);
- ExpressionTranslator etran0 = new ExpressionTranslator(this, predef, h0);
- ExpressionTranslator etran1 = new ExpressionTranslator(this, predef, h1);
-
- Bpl.Expr wellFormed = Bpl.Expr.And(
- FunctionCall(f.tok, BuiltinFunction.IsGoodHeap, null, etran0.HeapExpr),
- FunctionCall(f.tok, BuiltinFunction.IsGoodHeap, null, etran1.HeapExpr));
-
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(f.tok, "alpha");
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$o", predef.RefType));
- Bpl.Expr o = new Bpl.IdentifierExpr(f.tok, oVar);
- Bpl.BoundVariable fieldVar = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$f", predef.FieldName(f.tok, alpha)));
- Bpl.Expr field = new Bpl.IdentifierExpr(f.tok, fieldVar);
- Bpl.Expr oNotNull = Bpl.Expr.Neq(o, predef.Null);
- Bpl.Expr oNotNullAlloced = Bpl.Expr.And(oNotNull, Bpl.Expr.And(etran0.IsAlloced(f.tok, o), etran1.IsAlloced(f.tok, o)));
- Bpl.Expr unchanged = Bpl.Expr.Eq(ExpressionTranslator.ReadHeap(f.tok, h0, o, field), ExpressionTranslator.ReadHeap(f.tok, h1, o, field));
-
- Bpl.Expr heapSucc = FunctionCall(f.tok, BuiltinFunction.HeapSucc, null, h0, h1);
- Bpl.Expr r0 = InRWClause(f.tok, o, field, f.Reads, etran0, null, null);
- Bpl.Expr q0 = new Bpl.ForallExpr(f.tok, new Bpl.TypeVariableSeq(alpha), new Bpl.VariableSeq(oVar, fieldVar),
- Bpl.Expr.Imp(Bpl.Expr.And(oNotNullAlloced, r0), unchanged));
-
- // bvars: h0, h1, formals
- // f0args: h0, formals
- // f1args: h1, formals
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- Bpl.ExprSeq f0args = new Bpl.ExprSeq();
- Bpl.ExprSeq f1args = new Bpl.ExprSeq();
- bvars.Add(h0Var); bvars.Add(h1Var);
- f0args.Add(h0);
- f1args.Add(h1);
- if (!f.IsStatic) {
- Bpl.BoundVariable thVar = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "this", predef.RefType));
- Bpl.Expr th = new Bpl.IdentifierExpr(f.tok, thVar);
- bvars.Add(thVar);
- f0args.Add(th);
- f1args.Add(th);
-
- Type thisType = Resolver.GetReceiverType(f.tok, f);
- Bpl.Expr wh = Bpl.Expr.And(Bpl.Expr.Neq(th, predef.Null),
- Bpl.Expr.And(etran0.GoodRef(f.tok, th, thisType), etran1.GoodRef(f.tok, th, thisType)));
- wellFormed = Bpl.Expr.And(wellFormed, wh);
- }
-
- foreach (Formal p in f.Formals) {
- Bpl.BoundVariable bv = new Bpl.BoundVariable(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, TrType(p.Type)));
- bvars.Add(bv);
- Bpl.Expr formal = new Bpl.IdentifierExpr(p.tok, bv);
- f0args.Add(formal);
- f1args.Add(formal);
- Bpl.Expr wh = GetWhereClause(p.tok, formal, p.Type, etran0);
- if (wh != null) { wellFormed = Bpl.Expr.And(wellFormed, wh); }
- wh = GetWhereClause(p.tok, formal, p.Type, etran1);
- if (wh != null) { wellFormed = Bpl.Expr.And(wellFormed, wh); }
- }
-
- string axiomComment = "frame axiom for " + f.FullCompileName;
- Bpl.FunctionCall fn = new Bpl.FunctionCall(new Bpl.IdentifierExpr(f.tok, f.FullCompileName, TrType(f.ResultType)));
- while (fn != null) {
- Bpl.Expr F0 = new Bpl.NAryExpr(f.tok, fn, f0args);
- Bpl.Expr F1 = new Bpl.NAryExpr(f.tok, fn, f1args);
- Bpl.Expr eq = Bpl.Expr.Eq(F0, F1);
- Bpl.Trigger tr = new Bpl.Trigger(f.tok, true, new Bpl.ExprSeq(heapSucc, F1));
-
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(f.TypeArgs);
- Bpl.Expr ax = new Bpl.ForallExpr(f.tok, typeParams, bvars, null, tr,
- Bpl.Expr.Imp(Bpl.Expr.And(wellFormed, heapSucc),
- Bpl.Expr.Imp(q0, eq)));
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(f.tok, ax, axiomComment));
- if (axiomComment != null && f.IsRecursive) {
- fn = new Bpl.FunctionCall(new Bpl.IdentifierExpr(f.tok, FunctionName(f, 0), TrType(f.ResultType)));
- axiomComment = null; // the comment goes only with the first frame axiom
- } else {
- break; // no more frame axioms to produce
- }
- }
- }
-
- Bpl.Expr/*!*/ InRWClause(IToken/*!*/ tok, Bpl.Expr/*!*/ o, Bpl.Expr/*!*/ f, List<FrameExpression/*!*/>/*!*/ rw, ExpressionTranslator/*!*/ etran,
- Expression receiverReplacement, Dictionary<IVariable,Expression/*!*/> substMap) {
- Contract.Requires(tok != null);
- Contract.Requires(o != null);
- Contract.Requires(f != null);
- Contract.Requires(etran != null);
- Contract.Requires(cce.NonNullElements(rw));
- Contract.Requires(substMap == null || cce.NonNullDictionaryAndValues(substMap));
- Contract.Requires(predef != null);
- Contract.Requires((receiverReplacement == null) == (substMap == null));
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- // requires o to denote an expression of type RefType
- // "rw" is is allowed to contain a WildcardExpr
-
- Bpl.Expr disjunction = null;
- foreach (FrameExpression rwComponent in rw) {
- Expression e = rwComponent.E;
- if (receiverReplacement != null) {
- Contract.Assert(substMap != null);
- e = Substitute(e, receiverReplacement, substMap);
- }
- Bpl.Expr disjunct;
- if (e is WildcardExpr) {
- disjunct = Bpl.Expr.True;
- } else if (e.Type is SetType) {
- // old(e)[Box(o)]
- disjunct = etran.TrInSet(tok, o, e, ((SetType)e.Type).Arg);
- } else if (e.Type is SeqType) {
- // (exists i: int :: 0 <= i && i < Seq#Length(old(e)) && Seq#Index(old(e),i) == Box(o))
- Bpl.Expr boxO = FunctionCall(tok, BuiltinFunction.Box, null, o);
- Bpl.Variable iVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$i", Bpl.Type.Int));
- Bpl.Expr i = new Bpl.IdentifierExpr(tok, iVar);
- Bpl.Expr iBounds = InSeqRange(tok, i, etran.TrExpr(e), true, null, false);
- Bpl.Expr XsubI = FunctionCall(tok, BuiltinFunction.SeqIndex, predef.BoxType, etran.TrExpr(e), i);
- // TODO: the equality in the next line should be changed to one that understands extensionality
- disjunct = new Bpl.ExistsExpr(tok, new Bpl.VariableSeq(iVar), Bpl.Expr.And(iBounds, Bpl.Expr.Eq(XsubI, boxO)));
- } else {
- // o == old(e)
- disjunct = Bpl.Expr.Eq(o, etran.TrExpr(e));
- }
- disjunct = Bpl.Expr.And(IsTotal(e, etran), disjunct);
- if (rwComponent.Field != null) {
- disjunct = Bpl.Expr.And(disjunct, Bpl.Expr.Eq(f, new Bpl.IdentifierExpr(rwComponent.E.tok, GetField(rwComponent.Field))));
- }
- if (disjunction == null) {
- disjunction = disjunct;
- } else {
- disjunction = Bpl.Expr.Or(disjunction, disjunct);
- }
- }
- if (disjunction == null) {
- return Bpl.Expr.False;
- } else {
- return disjunction;
- }
- }
-
- void AddWellformednessCheck(Function f) {
- Contract.Requires(f != null);
- Contract.Requires(sink != null && predef != null);
- Contract.Requires(f.EnclosingClass != null);
- Contract.Requires(currentModule == null);
- Contract.Ensures(currentModule == null);
-
- currentModule = f.EnclosingClass.Module;
-
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, f.tok);
- // parameters of the procedure
- Bpl.VariableSeq inParams = new Bpl.VariableSeq();
- if (!f.IsStatic) {
- Bpl.Expr wh = Bpl.Expr.And(
- Bpl.Expr.Neq(new Bpl.IdentifierExpr(f.tok, "this", predef.RefType), predef.Null),
- etran.GoodRef(f.tok, new Bpl.IdentifierExpr(f.tok, "this", predef.RefType), Resolver.GetReceiverType(f.tok, f)));
- Bpl.Formal thVar = new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "this", predef.RefType, wh), true);
- inParams.Add(thVar);
- }
- foreach (Formal p in f.Formals) {
- Bpl.Type varType = TrType(p.Type);
- Bpl.Expr wh = GetWhereClause(p.tok, new Bpl.IdentifierExpr(p.tok, p.UniqueName, varType), p.Type, etran);
- inParams.Add(new Bpl.Formal(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, varType, wh), true));
- }
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(f.TypeArgs);
- // the procedure itself
- Bpl.RequiresSeq req = new Bpl.RequiresSeq();
- // free requires mh == ModuleContextHeight && fh == FunctionContextHeight;
- ModuleDefinition mod = f.EnclosingClass.Module;
- Bpl.Expr context = Bpl.Expr.And(
- Bpl.Expr.Eq(Bpl.Expr.Literal(mod.Height), etran.ModuleContextHeight()),
- Bpl.Expr.Eq(Bpl.Expr.Literal(mod.CallGraph.GetSCCRepresentativeId(f)), etran.FunctionContextHeight()));
- req.Add(Requires(f.tok, true, context, null, null));
- // check that postconditions hold
- var ens = new Bpl.EnsuresSeq();
- foreach (Expression p in f.Ens) {
- var functionHeight = currentModule.CallGraph.GetSCCRepresentativeId(f);
- var splits = new List<SplitExprInfo>();
- bool splitHappened/*we actually don't care*/ = TrSplitExpr(p, splits, true, functionHeight, etran);
- foreach (var s in splits) {
- if (!s.IsFree && !RefinementToken.IsInherited(s.E.tok, currentModule)) {
- ens.Add(Ensures(s.E.tok, s.IsFree, s.E, null, null));
- }
- }
- }
- Bpl.Procedure proc = new Bpl.Procedure(f.tok, "CheckWellformed$$" + f.FullCompileName, typeParams, inParams, new Bpl.VariableSeq(),
- req, new Bpl.IdentifierExprSeq(), ens, etran.TrAttributes(f.Attributes, null));
- sink.TopLevelDeclarations.Add(proc);
-
- VariableSeq implInParams = Bpl.Formal.StripWhereClauses(proc.InParams);
- Bpl.VariableSeq locals = new Bpl.VariableSeq();
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
-
- // check well-formedness of the preconditions (including termination, but no reads checks), and then
- // assume each one of them
- foreach (Expression p in f.Req) {
- CheckWellformed(p, new WFOptions(f, null, false), locals, builder, etran);
- builder.Add(new Bpl.AssumeCmd(p.tok, etran.TrExpr(p)));
- }
- // Note: the reads clauses are not checked for well-formedness (is that sound?), because it used to
- // be that the syntax was not rich enough for programmers to specify reads clauses and always being
- // absolutely well-defined.
- // check well-formedness of the decreases clauses (including termination, but no reads checks)
- foreach (Expression p in f.Decreases.Expressions)
- {
- CheckWellformed(p, new WFOptions(f, null, false), locals, builder, etran);
- }
- // Generate:
- // if (*) {
- // check well-formedness of postcondition
- // assume false; // don't go on to check the postconditions
- // } else {
- // check well-formedness of body
- // // fall through to check the postconditions themselves
- // }
- // Here go the postconditions (termination checks included, but no reads checks)
- StmtListBuilder postCheckBuilder = new StmtListBuilder();
- // Assume the type returned by the call itself respects its type (this matter if the type is "nat", for example)
- {
- var args = new Bpl.ExprSeq();
- args.Add(etran.HeapExpr);
- if (!f.IsStatic) {
- args.Add(new Bpl.IdentifierExpr(f.tok, etran.This, predef.RefType));
- }
- foreach (var p in f.Formals) {
- args.Add(new Bpl.IdentifierExpr(p.tok, p.UniqueName, TrType(p.Type)));
- }
- Bpl.IdentifierExpr funcID = new Bpl.IdentifierExpr(f.tok, FunctionName(f, 1), TrType(f.ResultType));
- Bpl.Expr funcAppl = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(funcID), args);
-
- var wh = GetWhereClause(f.tok, funcAppl, f.ResultType, etran);
- if (wh != null) {
- postCheckBuilder.Add(new Bpl.AssumeCmd(f.tok, wh));
- }
- }
- // Now for the ensures clauses
- foreach (Expression p in f.Ens) {
- CheckWellformed(p, new WFOptions(f, f, false), locals, postCheckBuilder, etran);
- // assume the postcondition for the benefit of checking the remaining postconditions
- postCheckBuilder.Add(new Bpl.AssumeCmd(p.tok, etran.TrExpr(p)));
- }
- // Here goes the body (and include both termination checks and reads checks)
- StmtListBuilder bodyCheckBuilder = new StmtListBuilder();
- if (f.Body == null) {
- // don't fall through to postcondition checks
- bodyCheckBuilder.Add(new Bpl.AssumeCmd(f.tok, Bpl.Expr.False));
- } else {
- Bpl.FunctionCall funcID = new Bpl.FunctionCall(new Bpl.IdentifierExpr(f.tok, f.FullCompileName, TrType(f.ResultType)));
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- args.Add(etran.HeapExpr);
- foreach (Variable p in implInParams) {
- args.Add(new Bpl.IdentifierExpr(f.tok, p));
- }
- Bpl.Expr funcAppl = new Bpl.NAryExpr(f.tok, funcID, args);
-
- DefineFrame(f.tok, f.Reads, bodyCheckBuilder, locals, null);
- CheckWellformedWithResult(f.Body, new WFOptions(f, null, true), funcAppl, f.ResultType, locals, bodyCheckBuilder, etran);
- }
- // Combine the two, letting the postcondition be checked on after the "bodyCheckBuilder" branch
- postCheckBuilder.Add(new Bpl.AssumeCmd(f.tok, Bpl.Expr.False));
- builder.Add(new Bpl.IfCmd(f.tok, null, postCheckBuilder.Collect(f.tok), null, bodyCheckBuilder.Collect(f.tok)));
-
- Bpl.Implementation impl = new Bpl.Implementation(f.tok, proc.Name,
- typeParams, implInParams, new Bpl.VariableSeq(),
- locals, builder.Collect(f.tok));
- sink.TopLevelDeclarations.Add(impl);
-
- Contract.Assert(currentModule == f.EnclosingClass.Module);
- currentModule = null;
- }
-
- Bpl.Expr CtorInvocation(MatchCase mc, ExpressionTranslator etran, Bpl.VariableSeq locals, StmtListBuilder localTypeAssumptions) {
- Contract.Requires(mc != null);
- Contract.Requires(etran != null);
- Contract.Requires(locals != null);
- Contract.Requires(localTypeAssumptions != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- for (int i = 0; i < mc.Arguments.Count; i++) {
- BoundVar p = mc.Arguments[i];
- Bpl.Variable local = new Bpl.LocalVariable(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, TrType(p.Type)));
- locals.Add(local);
- Type t = mc.Ctor.Formals[i].Type;
- Bpl.Expr wh = GetWhereClause(p.tok, new Bpl.IdentifierExpr(p.tok, local), p.Type, etran);
- if (wh != null) {
- localTypeAssumptions.Add(new Bpl.AssumeCmd(p.tok, wh));
- }
- args.Add(etran.CondApplyBox(mc.tok, new Bpl.IdentifierExpr(p.tok, local), cce.NonNull(p.Type), t));
- }
- Bpl.IdentifierExpr id = new Bpl.IdentifierExpr(mc.tok, mc.Ctor.FullName, predef.DatatypeType);
- return new Bpl.NAryExpr(mc.tok, new Bpl.FunctionCall(id), args);
- }
-
- Bpl.Expr CtorInvocation(IToken tok, DatatypeCtor ctor, ExpressionTranslator etran, Bpl.VariableSeq locals, StmtListBuilder localTypeAssumptions) {
- Contract.Requires(tok != null);
- Contract.Requires(ctor != null);
- Contract.Requires(etran != null);
- Contract.Requires(locals != null);
- Contract.Requires(localTypeAssumptions != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- // create local variables for the formals
- var args = new ExprSeq();
- foreach (Formal arg in ctor.Formals) {
- Contract.Assert(arg != null);
- var nm = string.Format("a{0}#{1}", args.Length, otherTmpVarCount);
- otherTmpVarCount++;
- Bpl.Variable bv = new Bpl.LocalVariable(arg.tok, new Bpl.TypedIdent(arg.tok, nm, TrType(arg.Type)));
- locals.Add(bv);
- args.Add(new Bpl.IdentifierExpr(arg.tok, bv));
- }
-
- Bpl.IdentifierExpr id = new Bpl.IdentifierExpr(tok, ctor.FullName, predef.DatatypeType);
- return new Bpl.NAryExpr(tok, new Bpl.FunctionCall(id), args);
- }
-
- Bpl.Expr IsTotal(Expression expr, ExpressionTranslator etran) {
- Contract.Requires(expr != null);Contract.Requires(etran != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (expr is LiteralExpr || expr is ThisExpr || expr is IdentifierExpr || expr is WildcardExpr || expr is BoogieWrapper) {
- return Bpl.Expr.True;
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- return IsTotal(e.Elements, etran);
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr e = (FieldSelectExpr)expr;
- if (e.Obj is ThisExpr) {
- return Bpl.Expr.True;
- } else {
- var t = IsTotal(e.Obj, etran);
- if (e.Obj.Type.IsRefType) {
- t = BplAnd(t, Bpl.Expr.Neq(etran.TrExpr(e.Obj), predef.Null));
- } else if (e.Field is DatatypeDestructor) {
- var dtor = (DatatypeDestructor)e.Field;
- t = BplAnd(t, FunctionCall(e.tok, dtor.EnclosingCtor.QueryField.FullCompileName, Bpl.Type.Bool, etran.TrExpr(e.Obj)));
- }
- return t;
- }
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- bool isSequence = e.Seq.Type is SeqType;
- if (e.Seq.Type is MapType) {
- Bpl.Expr total = IsTotal(e.Seq, etran);
- Bpl.Expr map = etran.TrExpr(e.Seq);
- var e0 = etran.TrExpr(e.E0);
- Bpl.Expr inDomain = FunctionCall(expr.tok, BuiltinFunction.MapDomain, predef.MapType(e.tok, predef.BoxType, predef.BoxType), map);
- inDomain = Bpl.Expr.Select(inDomain, etran.BoxIfNecessary(e.tok, e0, e.E0.Type));
- total = BplAnd(total, inDomain);
- return total;
- } else {
- Bpl.Expr total = IsTotal(e.Seq, etran);
- Bpl.Expr seq = etran.TrExpr(e.Seq);
- Bpl.Expr e0 = null;
- if (e.E0 != null) {
- e0 = etran.TrExpr(e.E0);
- total = BplAnd(total, IsTotal(e.E0, etran));
- total = BplAnd(total, InSeqRange(expr.tok, e0, seq, isSequence, null, !e.SelectOne));
- }
- if (e.E1 != null) {
- total = BplAnd(total, IsTotal(e.E1, etran));
- total = BplAnd(total, InSeqRange(expr.tok, etran.TrExpr(e.E1), seq, isSequence, e0, true));
- }
- return total;
- }
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
- Bpl.Expr total = IsTotal(e.Array, etran);
- Bpl.Expr array = etran.TrExpr(e.Array);
- int i = 0;
- foreach (Expression idx in e.Indices) {
- total = BplAnd(total, IsTotal(idx, etran));
-
- Bpl.Expr index = etran.TrExpr(idx);
- Bpl.Expr lower = Bpl.Expr.Le(Bpl.Expr.Literal(0), index);
- Bpl.Expr length = ArrayLength(idx.tok, array, e.Indices.Count, i);
- Bpl.Expr upper = Bpl.Expr.Lt(index, length);
- total = BplAnd(total, Bpl.Expr.And(lower, upper));
- i++;
- }
- return total;
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- Bpl.Expr total = IsTotal(e.Seq, etran);
- Bpl.Expr seq = etran.TrExpr(e.Seq);
- Bpl.Expr index = etran.TrExpr(e.Index);
- total = BplAnd(total, IsTotal(e.Index, etran));
- total = BplAnd(total, InSeqRange(expr.tok, index, seq, true, null, false));
- total = BplAnd(total, IsTotal(e.Value, etran));
- return total;
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- Contract.Assert(e.Function != null); // follows from the fact that expr has been successfully resolved
- // check well-formedness of receiver
- Bpl.Expr r = IsTotal(e.Receiver, etran);
- if (!e.Function.IsStatic && !(e.Receiver is ThisExpr)) {
- r = BplAnd(r, Bpl.Expr.Neq(etran.TrExpr(e.Receiver), predef.Null));
- }
- // check well-formedness of the other parameters
- r = BplAnd(r, IsTotal(e.Args, etran));
- // create a substitution map from each formal parameter to the corresponding actual parameter
- Dictionary<IVariable,Expression> substMap = new Dictionary<IVariable,Expression>();
- for (int i = 0; i < e.Function.Formals.Count; i++) {
- var formal = e.Function.Formals[i];
- var s = CheckSubrange_Expr(e.Args[i].tok, etran.TrExpr(e.Args[i]), formal.Type);
- if (s != null) {
- r = BplAnd(r, s);
- }
- substMap.Add(formal, e.Args[i]);
- }
- // check that the preconditions for the call hold
- foreach (Expression p in e.Function.Req) {
- Expression precond = Substitute(p, e.Receiver, substMap);
- r = BplAnd(r, etran.TrExpr(precond));
- }
- // TODO: if this is a recursive call, also conjoin the well-ordering predicate
- return r;
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- var r = IsTotal(dtv.Arguments, etran);
- for (int i = 0; i < dtv.Ctor.Formals.Count; i++) {
- var formal = dtv.Ctor.Formals[i];
- var arg = dtv.Arguments[i];
- var s = CheckSubrange_Expr(arg.tok, etran.TrExpr(arg), formal.Type);
- if (s != null) {
- r = BplAnd(r, s);
- }
- }
- return r;
- } else if (expr is OldExpr) {
- OldExpr e = (OldExpr)expr;
- return IsTotal(e.E, etran.Old);
- } else if (expr is MultiSetFormingExpr) {
- MultiSetFormingExpr e = (MultiSetFormingExpr)expr;
- return IsTotal(e.E, etran);
- } else if (expr is FreshExpr) {
- FreshExpr e = (FreshExpr)expr;
- return IsTotal(e.E, etran);
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- Bpl.Expr t = IsTotal(e.E, etran);
- if (e.Op == UnaryExpr.Opcode.SetChoose) {
- Bpl.Expr emptySet = FunctionCall(expr.tok, BuiltinFunction.SetEmpty, predef.BoxType);
- return Bpl.Expr.And(t, Bpl.Expr.Neq(etran.TrExpr(e.E), emptySet));
- } else if (e.Op == UnaryExpr.Opcode.SeqLength && !(e.E.Type is SeqType)) {
- return Bpl.Expr.And(t, Bpl.Expr.Neq(etran.TrExpr(e.E), predef.Null));
- }
- return t;
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- Bpl.Expr t0 = IsTotal(e.E0, etran);
- Bpl.Expr t1 = IsTotal(e.E1, etran);
- Bpl.Expr z = null;
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.And:
- case BinaryExpr.ResolvedOpcode.Imp:
- t1 = Bpl.Expr.Imp(etran.TrExpr(e.E0), t1);
- break;
- case BinaryExpr.ResolvedOpcode.Or:
- t1 = Bpl.Expr.Imp(Bpl.Expr.Not(etran.TrExpr(e.E0)), t1);
- break;
- case BinaryExpr.ResolvedOpcode.Div:
- case BinaryExpr.ResolvedOpcode.Mod:
- z = Bpl.Expr.Neq(etran.TrExpr(e.E1), Bpl.Expr.Literal(0));
- break;
- default:
- break;
- }
- Bpl.Expr r = BplAnd(t0, t1);
- return z == null ? r : BplAnd(r, z);
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- Bpl.Expr total = Bpl.Expr.True;
- foreach (var rhs in e.RHSs) {
- total = BplAnd(total, IsTotal(rhs, etran));
- }
- return BplAnd(total, IsTotal(etran.GetSubstitutedBody(e), etran));
-
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- var total = IsTotal(e.Term, etran);
- if (e.Range != null) {
- total = BplAnd(IsTotal(e.Range, etran), BplImp(etran.TrExpr(e.Range), total));
- }
- if (total != Bpl.Expr.True) {
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- Bpl.Expr typeAntecedent = etran.TrBoundVariables(e.BoundVars, bvars);
- total = new Bpl.ForallExpr(expr.tok, bvars, Bpl.Expr.Imp(typeAntecedent, total));
- }
- return total;
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- Bpl.Expr gTotal = IsTotal(e.Guard, etran);
- Bpl.Expr g = etran.TrExpr(e.Guard);
- Bpl.Expr bTotal = IsTotal(e.Body, etran);
- if (e is AssertExpr || DafnyOptions.O.DisallowSoundnessCheating) {
- return BplAnd(gTotal, BplAnd(g, bTotal));
- } else {
- return BplAnd(gTotal, Bpl.Expr.Imp(g, bTotal));
- }
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- Bpl.Expr total = IsTotal(e.Test, etran);
- Bpl.Expr test = etran.TrExpr(e.Test);
- total = BplAnd(total, Bpl.Expr.Imp(test, IsTotal(e.Thn, etran)));
- total = BplAnd(total, Bpl.Expr.Imp(Bpl.Expr.Not(test), IsTotal(e.Els, etran)));
- return total;
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return IsTotal(e.ResolvedExpression, etran);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
-
- Bpl.Expr/*!*/ IsTotal(List<Expression/*!*/>/*!*/ exprs, ExpressionTranslator/*!*/ etran) {
- Contract.Requires(etran != null);
- Contract.Requires(exprs != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- Bpl.Expr total = Bpl.Expr.True;
- foreach (Expression e in exprs) {
- Contract.Assert(e != null);
- total = BplAnd(total, IsTotal(e, etran));
- }
- return total;
- }
-
- Bpl.Expr CanCallAssumption(Expression expr, ExpressionTranslator etran) {
- Contract.Requires(expr != null);
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (expr is LiteralExpr || expr is ThisExpr || expr is IdentifierExpr || expr is WildcardExpr || expr is BoogieWrapper) {
- return Bpl.Expr.True;
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- return CanCallAssumption(e.Elements, etran);
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- List<Expression> l = new List<Expression>();
- foreach (ExpressionPair p in e.Elements) {
- l.Add(p.A); l.Add(p.B);
- }
- return CanCallAssumption(l, etran);
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr e = (FieldSelectExpr)expr;
- if (e.Obj is ThisExpr) {
- return Bpl.Expr.True;
- } else {
- Bpl.Expr r = CanCallAssumption(e.Obj, etran);
- return r;
- }
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- //bool isSequence = e.Seq.Type is SeqType;
- Bpl.Expr total = CanCallAssumption(e.Seq, etran);
- Bpl.Expr seq = etran.TrExpr(e.Seq);
- Bpl.Expr e0 = null;
- if (e.E0 != null) {
- e0 = etran.TrExpr(e.E0);
- total = BplAnd(total, CanCallAssumption(e.E0, etran));
- }
- if (e.E1 != null) {
- total = BplAnd(total, CanCallAssumption(e.E1, etran));
- }
- return total;
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
- Bpl.Expr total = CanCallAssumption(e.Array, etran);
- foreach (Expression idx in e.Indices) {
- total = BplAnd(total, CanCallAssumption(idx, etran));
- }
- return total;
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- Bpl.Expr total = CanCallAssumption(e.Seq, etran);
- Bpl.Expr seq = etran.TrExpr(e.Seq);
- Bpl.Expr index = etran.TrExpr(e.Index);
- total = BplAnd(total, CanCallAssumption(e.Index, etran));
- total = BplAnd(total, CanCallAssumption(e.Value, etran));
- return total;
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- Contract.Assert(e.Function != null); // follows from the fact that expr has been successfully resolved
- // check well-formedness of receiver
- Bpl.Expr r = CanCallAssumption(e.Receiver, etran);
- // check well-formedness of the other parameters
- r = BplAnd(r, CanCallAssumption(e.Args, etran));
- // get to assume canCall
- Bpl.IdentifierExpr canCallFuncID = new Bpl.IdentifierExpr(expr.tok, e.Function.FullCompileName + "#canCall", Bpl.Type.Bool);
- ExprSeq args = etran.FunctionInvocationArguments(e);
- Bpl.Expr canCallFuncAppl = new Bpl.NAryExpr(expr.tok, new Bpl.FunctionCall(canCallFuncID), args);
- r = BplAnd(r, canCallFuncAppl);
- return r;
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- return CanCallAssumption(dtv.Arguments, etran);
- } else if (expr is OldExpr) {
- OldExpr e = (OldExpr)expr;
- return CanCallAssumption(e.E, etran.Old);
- } else if (expr is MultiSetFormingExpr) {
- MultiSetFormingExpr e = (MultiSetFormingExpr)expr;
- return CanCallAssumption(e.E, etran);
- } else if (expr is FreshExpr) {
- FreshExpr e = (FreshExpr)expr;
- return CanCallAssumption(e.E, etran);
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- Bpl.Expr t = CanCallAssumption(e.E, etran);
- return t;
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- Bpl.Expr t0 = CanCallAssumption(e.E0, etran);
- Bpl.Expr t1 = CanCallAssumption(e.E1, etran);
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.And:
- case BinaryExpr.ResolvedOpcode.Imp:
- t1 = Bpl.Expr.Imp(etran.TrExpr(e.E0), t1);
- break;
- case BinaryExpr.ResolvedOpcode.Or:
- t1 = Bpl.Expr.Imp(Bpl.Expr.Not(etran.TrExpr(e.E0)), t1);
- break;
- default:
- break;
- }
- return BplAnd(t0, t1);
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- Bpl.Expr canCall = Bpl.Expr.True;
- foreach (var rhs in e.RHSs) {
- canCall = BplAnd(canCall, CanCallAssumption(rhs, etran));
- }
- return BplAnd(canCall, CanCallAssumption(etran.GetSubstitutedBody(e), etran));
-
- } else if (expr is NamedExpr) {
- var e = (NamedExpr)expr;
- var canCall = CanCallAssumption(e.Body, etran);
- if (e.Contract != null)
- return BplAnd(canCall, CanCallAssumption(e.Contract, etran));
- else return canCall;
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- var total = CanCallAssumption(e.Term, etran);
- if (e.Range != null) {
- total = BplAnd(CanCallAssumption(e.Range, etran), BplImp(etran.TrExpr(e.Range), total));
- }
- if (total != Bpl.Expr.True) {
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- Bpl.Expr typeAntecedent = etran.TrBoundVariables(e.BoundVars, bvars);
- total = new Bpl.ForallExpr(expr.tok, bvars, Bpl.Expr.Imp(typeAntecedent, total));
- }
- return total;
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- Bpl.Expr gCanCall = CanCallAssumption(e.Guard, etran);
- Bpl.Expr bCanCall = CanCallAssumption(e.Body, etran);
- if (e is AssertExpr || DafnyOptions.O.DisallowSoundnessCheating) {
- return BplAnd(gCanCall, bCanCall);
- } else {
- Bpl.Expr g = etran.TrExpr(e.Guard);
- return BplAnd(gCanCall, Bpl.Expr.Imp(g, bCanCall));
- }
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- Bpl.Expr total = CanCallAssumption(e.Test, etran);
- Bpl.Expr test = etran.TrExpr(e.Test);
- total = BplAnd(total, Bpl.Expr.Imp(test, CanCallAssumption(e.Thn, etran)));
- total = BplAnd(total, Bpl.Expr.Imp(Bpl.Expr.Not(test), CanCallAssumption(e.Els, etran)));
- return total;
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return CanCallAssumption(e.ResolvedExpression, etran);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
-
- Bpl.Expr/*!*/ CanCallAssumption(List<Expression/*!*/>/*!*/ exprs, ExpressionTranslator/*!*/ etran) {
- Contract.Requires(etran != null);
- Contract.Requires(exprs != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- Bpl.Expr total = Bpl.Expr.True;
- foreach (Expression e in exprs) {
- Contract.Assert(e != null);
- total = BplAnd(total, CanCallAssumption(e, etran));
- }
- return total;
- }
-
- Expression DafnyAnd(Expression a, Expression b) {
- Contract.Requires(a != null);
- Contract.Requires(b != null);
- Contract.Ensures(Contract.Result<Expression>() != null);
-
- if (LiteralExpr.IsTrue(a)) {
- return b;
- } else if (LiteralExpr.IsTrue(b)) {
- return a;
- } else {
- BinaryExpr and = new BinaryExpr(a.tok, BinaryExpr.Opcode.And, a, b);
- and.ResolvedOp = BinaryExpr.ResolvedOpcode.And; // resolve here
- and.Type = Type.Bool; // resolve here
- return and;
- }
- }
-
- Bpl.Expr BplAnd(Bpl.Expr a, Bpl.Expr b) {
- Contract.Requires(a != null);
- Contract.Requires(b != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (a == Bpl.Expr.True) {
- return b;
- } else if (b == Bpl.Expr.True) {
- return a;
- } else {
- return Bpl.Expr.And(a, b);
- }
- }
-
- Bpl.Expr BplOr(Bpl.Expr a, Bpl.Expr b) {
- Contract.Requires(a != null);
- Contract.Requires(b != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (a == Bpl.Expr.False) {
- return b;
- } else if (b == Bpl.Expr.False) {
- return a;
- } else {
- return Bpl.Expr.Or(a, b);
- }
- }
-
- Bpl.Expr BplImp(Bpl.Expr a, Bpl.Expr b) {
- Contract.Requires(a != null);
- Contract.Requires(b != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (a == Bpl.Expr.True || b == Bpl.Expr.True) {
- return b;
- } else if (a == Bpl.Expr.False) {
- return Bpl.Expr.True;
- } else {
- return Bpl.Expr.Imp(a, b);
- }
- }
-
- void CheckNonNull(IToken tok, Expression e, Bpl.StmtListBuilder builder, ExpressionTranslator etran, Bpl.QKeyValue kv) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(builder != null);
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
-
- if (e is ThisExpr) {
- // already known to be non-null
- } else {
- builder.Add(Assert(tok, Bpl.Expr.Neq(etran.TrExpr(e), predef.Null), "target object may be null", kv));
- }
- }
-
- /// <summary>
- /// Instances of WFContext are used as an argument to CheckWellformed, supplying options for the
- /// checks to be performed.
- /// If non-null, "Decr" gives the caller to be used for termination checks. If it is null, no
- /// termination checks are performed.
- /// If "SelfCallsAllowance" is non-null, termination checks will be omitted for calls that look
- /// like it. This is useful in function postconditions, where the result of the function is
- /// syntactically given as what looks like a recursive call with the same arguments.
- /// "DoReadsChecks" indicates whether or not to perform reads checks. If so, the generated code
- /// will make references to $_Frame.
- /// </summary>
- class WFOptions
- {
- public readonly Function Decr;
- public readonly Function SelfCallsAllowance;
- public readonly bool DoReadsChecks;
- public readonly Bpl.QKeyValue AssertKv;
- public WFOptions() { }
- public WFOptions(Function decr, Function selfCallsAllowance, bool doReadsChecks) {
- Decr = decr;
- SelfCallsAllowance = selfCallsAllowance;
- DoReadsChecks = doReadsChecks;
- }
- public WFOptions(Bpl.QKeyValue kv) {
- AssertKv = kv;
- }
- }
-
- void TrStmt_CheckWellformed(Expression expr, Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran, bool subsumption) {
- Contract.Requires(expr != null);
- Contract.Requires(builder != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
-
- Bpl.QKeyValue kv;
- if (subsumption) {
- kv = null; // this is the default behavior of Boogie's assert
- } else {
- List<object> args = new List<object>();
- // {:subsumption 0}
- args.Add(Bpl.Expr.Literal(0));
- kv = new Bpl.QKeyValue(expr.tok, "subsumption", args, null);
- }
- CheckWellformed(expr, new WFOptions(kv), locals, builder, etran);
- builder.Add(new Bpl.AssumeCmd(expr.tok, CanCallAssumption(expr, etran)));
- }
-
- void CheckWellformed(Expression expr, WFOptions options, Bpl.VariableSeq locals, Bpl.StmtListBuilder builder, ExpressionTranslator etran) {
- CheckWellformedWithResult(expr, options, null, null, locals, builder, etran);
- }
-
- /// <summary>
- /// Adds to "builder" code that checks the well-formedness of "expr". Any local variables introduced
- /// in this code are added to "locals".
- /// If "result" is non-null, then after checking the well-formedness of "expr", the generated code will
- /// assume the equivalent of "result == expr".
- /// See class WFOptions for descriptions of the specified options.
- /// </summary>
- void CheckWellformedWithResult(Expression expr, WFOptions options, Bpl.Expr result, Type resultType,
- Bpl.VariableSeq locals, Bpl.StmtListBuilder builder, ExpressionTranslator etran) {
- Contract.Requires(expr != null);
- Contract.Requires(options != null);
- Contract.Requires((result == null) == (resultType == null));
- Contract.Requires(locals != null);
- Contract.Requires(builder != null);
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
-
- if (expr is LiteralExpr || expr is ThisExpr || expr is IdentifierExpr || expr is WildcardExpr || expr is BoogieWrapper) {
- // always allowed
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- foreach (Expression el in e.Elements) {
- CheckWellformed(el, options, locals, builder, etran);
- }
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- foreach (ExpressionPair p in e.Elements) {
- CheckWellformed(p.A, options, locals, builder, etran);
- CheckWellformed(p.B, options, locals, builder, etran);
- }
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr e = (FieldSelectExpr)expr;
- CheckWellformed(e.Obj, options, locals, builder, etran);
- if (e.Obj.Type.IsRefType) {
- CheckNonNull(expr.tok, e.Obj, builder, etran, options.AssertKv);
- } else if (e.Field is DatatypeDestructor) {
- var dtor = (DatatypeDestructor)e.Field;
- var correctConstructor = FunctionCall(e.tok, dtor.EnclosingCtor.QueryField.FullCompileName, Bpl.Type.Bool, etran.TrExpr(e.Obj));
- if (dtor.EnclosingCtor.EnclosingDatatype.Ctors.Count == 1) {
- // There is only one constructor, so the value must be been constructed by it; might as well assume that here.
- builder.Add(new Bpl.AssumeCmd(expr.tok, correctConstructor));
- } else {
- builder.Add(Assert(expr.tok, correctConstructor,
- string.Format("destructor '{0}' can only be applied to datatype values constructed by '{1}'", dtor.Name, dtor.EnclosingCtor.Name)));
- }
- }
- if (options.DoReadsChecks && e.Field.IsMutable) {
- builder.Add(Assert(expr.tok, Bpl.Expr.SelectTok(expr.tok, etran.TheFrame(expr.tok), etran.TrExpr(e.Obj), GetField(e)), "insufficient reads clause to read field", options.AssertKv));
- }
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- bool isSequence = e.Seq.Type is SeqType;
- CheckWellformed(e.Seq, options, locals, builder, etran);
- Bpl.Expr seq = etran.TrExpr(e.Seq);
- if (e.Seq.Type.IsArrayType) {
- builder.Add(Assert(e.Seq.tok, Bpl.Expr.Neq(seq, predef.Null), "array may be null"));
- }
- Bpl.Expr e0 = null;
- if (e.Seq.Type is MapType) {
- e0 = etran.TrExpr(e.E0);
- CheckWellformed(e.E0, options, locals, builder, etran);
- Bpl.Expr inDomain = FunctionCall(expr.tok, BuiltinFunction.MapDomain, predef.MapType(e.tok, predef.BoxType, predef.BoxType), seq);
- inDomain = Bpl.Expr.Select(inDomain, etran.BoxIfNecessary(e.tok, e0, e.E0.Type));
- builder.Add(Assert(expr.tok, inDomain, "element may not be in domain", options.AssertKv));
-
- } else {
- if (e.E0 != null) {
- e0 = etran.TrExpr(e.E0);
- CheckWellformed(e.E0, options, locals, builder, etran);
- builder.Add(Assert(expr.tok, InSeqRange(expr.tok, e0, seq, isSequence, null, !e.SelectOne), e.SelectOne ? "index out of range" : "lower bound out of range", options.AssertKv));
- }
- if (e.E1 != null) {
- CheckWellformed(e.E1, options, locals, builder, etran);
- builder.Add(Assert(expr.tok, InSeqRange(expr.tok, etran.TrExpr(e.E1), seq, isSequence, e0, true), "upper bound " + (e.E0 == null ? "" : "below lower bound or ") + "above length of " + (isSequence ? "sequence" : "array"), options.AssertKv));
- }
- }
- if (options.DoReadsChecks && cce.NonNull(e.Seq.Type).IsArrayType) {
- if (e.SelectOne) {
- Contract.Assert(e.E0 != null);
- Bpl.Expr fieldName = FunctionCall(expr.tok, BuiltinFunction.IndexField, null, etran.TrExpr(e.E0));
- builder.Add(Assert(expr.tok, Bpl.Expr.SelectTok(expr.tok, etran.TheFrame(expr.tok), seq, fieldName), "insufficient reads clause to read array element", options.AssertKv));
- } else {
- Bpl.Expr lowerBound = e.E0 == null ? Bpl.Expr.Literal(0) : etran.TrExpr(e.E0);
- Contract.Assert((e.Seq.Type).AsArrayType.Dims == 1);
- Bpl.Expr upperBound = e.E1 == null ? ArrayLength(e.tok, seq, 1, 0) : etran.TrExpr(e.E1);
- // check that, for all i in lowerBound..upperBound, a[i] is in the frame
- Bpl.BoundVariable iVar = new Bpl.BoundVariable(e.tok, new Bpl.TypedIdent(e.tok, "$i", Bpl.Type.Int));
- Bpl.IdentifierExpr i = new Bpl.IdentifierExpr(e.tok, iVar);
- var range = BplAnd(Bpl.Expr.Le(lowerBound, i), Bpl.Expr.Lt(i, upperBound));
- var fieldName = FunctionCall(e.tok, BuiltinFunction.IndexField, null, i);
- var allowedToRead = Bpl.Expr.SelectTok(e.tok, etran.TheFrame(e.tok), seq, fieldName);
- var qq = new Bpl.ForallExpr(e.tok, new Bpl.VariableSeq(iVar), Bpl.Expr.Imp(range, allowedToRead));
- builder.Add(Assert(expr.tok, qq, "insufficient reads clause to read the indicated range of array elements", options.AssertKv));
- }
- }
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
- CheckWellformed(e.Array, options, locals, builder, etran);
- Bpl.Expr array = etran.TrExpr(e.Array);
- int i = 0;
- foreach (Expression idx in e.Indices) {
- CheckWellformed(idx, options, locals, builder, etran);
-
- Bpl.Expr index = etran.TrExpr(idx);
- Bpl.Expr lower = Bpl.Expr.Le(Bpl.Expr.Literal(0), index);
- Bpl.Expr length = ArrayLength(idx.tok, array, e.Indices.Count, i);
- Bpl.Expr upper = Bpl.Expr.Lt(index, length);
- builder.Add(Assert(idx.tok, Bpl.Expr.And(lower, upper), "index " + i + " out of range", options.AssertKv));
- i++;
- }
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- CheckWellformed(e.Seq, options, locals, builder, etran);
- Bpl.Expr seq = etran.TrExpr(e.Seq);
- Bpl.Expr index = etran.TrExpr(e.Index);
- CheckWellformed(e.Index, options, locals, builder, etran);
- if (e.Seq.Type is SeqType) {
- builder.Add(Assert(expr.tok, InSeqRange(expr.tok, index, seq, true, null, false), "index out of range", options.AssertKv));
- } else {
- Contract.Assert(e.Seq.Type is MapType);
- // updates add to maps, so are always valid if the values are well formed.
- }
- CheckWellformed(e.Value, options, locals, builder, etran);
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- Contract.Assert(e.Function != null); // follows from the fact that expr has been successfully resolved
- // check well-formedness of receiver
- CheckWellformed(e.Receiver, options, locals, builder, etran);
- if (!e.Function.IsStatic && !(e.Receiver is ThisExpr)) {
- CheckNonNull(expr.tok, e.Receiver, builder, etran, options.AssertKv);
- }
- // check well-formedness of the other parameters
- foreach (Expression arg in e.Args) {
- CheckWellformed(arg, options, locals, builder, etran);
- }
- // create a local variable for each formal parameter, and assign each actual parameter to the corresponding local
- Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
- for (int i = 0; i < e.Function.Formals.Count; i++) {
- Formal p = e.Function.Formals[i];
- VarDecl local = new VarDecl(p.tok, p.Name, p.Type, p.IsGhost);
- local.type = local.OptionalType; // resolve local here
- IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
- ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
- substMap.Add(p, ie);
- locals.Add(new Bpl.LocalVariable(local.Tok, new Bpl.TypedIdent(local.Tok, local.UniqueName, TrType(local.Type))));
- Bpl.IdentifierExpr lhs = (Bpl.IdentifierExpr)etran.TrExpr(ie); // TODO: is this cast always justified?
- Expression ee = e.Args[i];
- CheckSubrange(ee.tok, etran.TrExpr(ee), p.Type, builder);
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(p.tok, lhs, etran.CondApplyBox(p.tok, etran.TrExpr(ee), cce.NonNull(ee.Type), p.Type));
- builder.Add(cmd);
- }
- // Check that every parameter is available in the state in which the function is invoked; this means checking that it has
- // the right type and is allocated. These checks usually hold trivially, on account of that the Dafny language only gives
- // access to expressions of the appropriate type and that are allocated in the current state. However, if the function is
- // invoked in the 'old' state, then we need to check that its arguments were all available at that time as well.
- if (etran.UsesOldHeap) {
- if (!e.Function.IsStatic) {
- Bpl.Expr wh = GetWhereClause(e.Receiver.tok, etran.TrExpr(e.Receiver), e.Receiver.Type, etran);
- if (wh != null) {
- builder.Add(Assert(e.Receiver.tok, wh, "receiver argument must be allocated in the state in which the function is invoked"));
- }
- }
- for (int i = 0; i < e.Args.Count; i++) {
- Expression ee = e.Args[i];
- Bpl.Expr wh = GetWhereClause(ee.tok, etran.TrExpr(ee), ee.Type, etran);
- if (wh != null) {
- builder.Add(Assert(ee.tok, wh, "argument must be allocated in the state in which the function is invoked"));
- }
- }
- }
- // check that the preconditions for the call hold
- foreach (Expression p in e.Function.Req) {
- Expression precond = Substitute(p, e.Receiver, substMap);
- builder.Add(Assert(expr.tok, etran.TrExpr(precond), "possible violation of function precondition", options.AssertKv));
- }
- Bpl.Expr allowance = null;
- if (options.Decr != null || options.DoReadsChecks) {
- if (options.DoReadsChecks) {
- // check that the callee reads only what the caller is already allowed to read
- CheckFrameSubset(expr.tok, e.Function.Reads, e.Receiver, substMap, etran, builder, "insufficient reads clause to invoke function", options.AssertKv);
- }
-
- if (options.Decr != null && e.CoCall != FunctionCallExpr.CoCallResolution.Yes && !(e.Function is CoPredicate)) {
- // check that the decreases measure goes down
- ModuleDefinition module = cce.NonNull(e.Function.EnclosingClass).Module;
- if (module == cce.NonNull(options.Decr.EnclosingClass).Module) {
- if (module.CallGraph.GetSCCRepresentative(e.Function) == module.CallGraph.GetSCCRepresentative(options.Decr)) {
- bool contextDecrInferred, calleeDecrInferred;
- List<Expression> contextDecreases = FunctionDecreasesWithDefault(options.Decr, out contextDecrInferred);
- List<Expression> calleeDecreases = FunctionDecreasesWithDefault(e.Function, out calleeDecrInferred);
- if (e.Function == options.SelfCallsAllowance) {
- allowance = Bpl.Expr.True;
- if (!e.Function.IsStatic) {
- allowance = BplAnd(allowance, Bpl.Expr.Eq(etran.TrExpr(e.Receiver), new Bpl.IdentifierExpr(e.tok, etran.This, predef.RefType)));
- }
- for (int i = 0; i < e.Args.Count; i++) {
- Expression ee = e.Args[i];
- Formal ff = e.Function.Formals[i];
- allowance = BplAnd(allowance, Bpl.Expr.Eq(etran.TrExpr(ee), new Bpl.IdentifierExpr(e.tok, ff.UniqueName, TrType(ff.Type))));
- }
- }
- string hint;
- switch (e.CoCall) {
- case FunctionCallExpr.CoCallResolution.NoBecauseFunctionHasSideEffects:
- hint = "note that only functions without side effects can called co-recursively";
- break;
- case FunctionCallExpr.CoCallResolution.NoBecauseIsNotGuarded:
- hint = "note that the call is not sufficiently guarded to be used co-recursively";
- break;
- case FunctionCallExpr.CoCallResolution.NoBecauseRecursiveCallsAreNotAllowedInThisContext:
- hint = "note that calls cannot be co-recursive in this context";
- break;
- case FunctionCallExpr.CoCallResolution.No:
- hint = null;
- break;
- default:
- Contract.Assert(false); // unexpected CoCallResolution
- goto case FunctionCallExpr.CoCallResolution.No; // please the compiler
- }
- CheckCallTermination(expr.tok, contextDecreases, calleeDecreases, allowance, e.Receiver, substMap, etran, builder,
- contextDecrInferred, hint);
- }
- }
- }
- }
- // all is okay, so allow this function application access to the function's axiom, except if it was okay because of the self-call allowance.
- Bpl.IdentifierExpr canCallFuncID = new Bpl.IdentifierExpr(expr.tok, e.Function.FullCompileName + "#canCall", Bpl.Type.Bool);
- ExprSeq args = etran.FunctionInvocationArguments(e);
- Bpl.Expr canCallFuncAppl = new Bpl.NAryExpr(expr.tok, new Bpl.FunctionCall(canCallFuncID), args);
- builder.Add(new Bpl.AssumeCmd(expr.tok, allowance == null ? canCallFuncAppl : Bpl.Expr.Or(allowance, canCallFuncAppl)));
-
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- for (int i = 0; i < dtv.Ctor.Formals.Count; i++) {
- var formal = dtv.Ctor.Formals[i];
- var arg = dtv.Arguments[i];
- CheckWellformed(arg, options, locals, builder, etran);
- CheckSubrange(arg.tok, etran.TrExpr(arg), formal.Type, builder);
- }
- } else if (expr is OldExpr) {
- OldExpr e = (OldExpr)expr;
- CheckWellformed(e.E, options, locals, builder, etran.Old);
- } else if (expr is MultiSetFormingExpr) {
- MultiSetFormingExpr e = (MultiSetFormingExpr)expr;
- CheckWellformed(e.E, options, locals, builder, etran);
- } else if (expr is FreshExpr) {
- FreshExpr e = (FreshExpr)expr;
- CheckWellformed(e.E, options, locals, builder, etran);
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- CheckWellformed(e.E, options, locals, builder, etran);
- if (e.Op == UnaryExpr.Opcode.SetChoose) {
- Bpl.Expr emptySet = FunctionCall(expr.tok, BuiltinFunction.SetEmpty, predef.BoxType);
- builder.Add(Assert(expr.tok, Bpl.Expr.Neq(etran.TrExpr(e.E), emptySet), "choose is defined only on nonempty sets"));
- } else if (e.Op == UnaryExpr.Opcode.SeqLength && !(e.E.Type is SeqType)) {
- CheckNonNull(expr.tok, e.E, builder, etran, options.AssertKv);
- }
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- CheckWellformed(e.E0, options, locals, builder, etran);
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.And:
- case BinaryExpr.ResolvedOpcode.Imp: {
- Bpl.StmtListBuilder b = new Bpl.StmtListBuilder();
- CheckWellformed(e.E1, options, locals, b, etran);
- builder.Add(new Bpl.IfCmd(expr.tok, etran.TrExpr(e.E0), b.Collect(expr.tok), null, null));
- }
- break;
- case BinaryExpr.ResolvedOpcode.Or: {
- Bpl.StmtListBuilder b = new Bpl.StmtListBuilder();
- CheckWellformed(e.E1, options, locals, b, etran);
- builder.Add(new Bpl.IfCmd(expr.tok, Bpl.Expr.Not(etran.TrExpr(e.E0)), b.Collect(expr.tok), null, null));
- }
- break;
- case BinaryExpr.ResolvedOpcode.Div:
- case BinaryExpr.ResolvedOpcode.Mod:
- CheckWellformed(e.E1, options, locals, builder, etran);
- builder.Add(Assert(expr.tok, Bpl.Expr.Neq(etran.TrExpr(e.E1), Bpl.Expr.Literal(0)), "possible division by zero", options.AssertKv));
- break;
- default:
- CheckWellformed(e.E1, options, locals, builder, etran);
- break;
- }
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
-
- var substMap = new Dictionary<IVariable, Expression>();
- Contract.Assert(e.Vars.Count == e.RHSs.Count); // checked by resolution
- for (int i = 0; i < e.Vars.Count; i++) {
- var vr = e.Vars[i];
- var tp = TrType(vr.Type);
- var v = new Bpl.LocalVariable(vr.tok, new Bpl.TypedIdent(vr.tok, vr.UniqueName, tp));
- locals.Add(v);
- var lhs = new Bpl.IdentifierExpr(vr.tok, vr.UniqueName, tp);
-
- CheckWellformedWithResult(e.RHSs[i], options, lhs, vr.Type, locals, builder, etran);
- substMap.Add(vr, new BoogieWrapper(lhs, vr.Type));
- }
- CheckWellformedWithResult(Substitute(e.Body, null, substMap), options, result, resultType, locals, builder, etran);
- result = null;
-
- } else if (expr is NamedExpr) {
- var e = (NamedExpr)expr;
- CheckWellformedWithResult(e.Body, options, result, resultType, locals, builder, etran);
- if (e.Contract != null) {
- CheckWellformedWithResult(e.Contract, options, result, resultType, locals, builder, etran);
- var theSame = Bpl.Expr.Eq(etran.TrExpr(e.Body), etran.TrExpr(e.Contract));
- builder.Add(Assert(new ForceCheckToken(e.ReplacerToken), theSame, "replacement must be the same value"));
- }
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- var substMap = SetupBoundVarsAsLocals(e.BoundVars, builder, locals, etran);
- Expression body = Substitute(e.Term, null, substMap);
- if (e.Range == null) {
- CheckWellformed(body, options, locals, builder, etran);
- } else {
- Expression range = Substitute(e.Range, null, substMap);
- CheckWellformed(range, options, locals, builder, etran);
-
- Bpl.StmtListBuilder b = new Bpl.StmtListBuilder();
- CheckWellformed(body, options, locals, b, etran);
- builder.Add(new Bpl.IfCmd(expr.tok, etran.TrExpr(range), b.Collect(expr.tok), null, null));
- }
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- CheckWellformed(e.Guard, options, locals, builder, etran);
- if (e is AssertExpr || DafnyOptions.O.DisallowSoundnessCheating) {
- bool splitHappened;
- var ss = TrSplitExpr(e.Guard, etran, out splitHappened);
- if (!splitHappened) {
- builder.Add(Assert(e.Guard.tok, etran.TrExpr(e.Guard), "condition in assert expression might not hold"));
- } else {
- foreach (var split in ss) {
- if (!split.IsFree) {
- builder.Add(AssertNS(split.E.tok, split.E, "condition in assert expression might not hold"));
- }
- }
- builder.Add(new Bpl.AssumeCmd(e.tok, etran.TrExpr(e.Guard)));
- }
- } else {
- builder.Add(new Bpl.AssumeCmd(e.tok, etran.TrExpr(e.Guard)));
- }
- CheckWellformed(e.Body, options, locals, builder, etran);
-
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- CheckWellformed(e.Test, options, locals, builder, etran);
- Bpl.StmtListBuilder bThen = new Bpl.StmtListBuilder();
- Bpl.StmtListBuilder bElse = new Bpl.StmtListBuilder();
- CheckWellformed(e.Thn, options, locals, bThen, etran);
- CheckWellformed(e.Els, options, locals, bElse, etran);
- builder.Add(new Bpl.IfCmd(expr.tok, etran.TrExpr(e.Test), bThen.Collect(expr.tok), null, bElse.Collect(expr.tok)));
-
- } else if (expr is MatchExpr) {
- MatchExpr me = (MatchExpr)expr;
- CheckWellformed(me.Source, options, locals, builder, etran);
- Bpl.Expr src = etran.TrExpr(me.Source);
- Bpl.IfCmd ifCmd = null;
- StmtListBuilder elsBldr = new StmtListBuilder();
- elsBldr.Add(new Bpl.AssumeCmd(expr.tok, Bpl.Expr.False));
- StmtList els = elsBldr.Collect(expr.tok);
- foreach (var missingCtor in me.MissingCases) {
- // havoc all bound variables
- var b = new Bpl.StmtListBuilder();
- VariableSeq newLocals = new VariableSeq();
- Bpl.Expr r = CtorInvocation(me.tok, missingCtor, etran, newLocals, b);
- locals.AddRange(newLocals);
-
- if (newLocals.Length != 0) {
- Bpl.IdentifierExprSeq havocIds = new Bpl.IdentifierExprSeq();
- foreach (Variable local in newLocals) {
- havocIds.Add(new Bpl.IdentifierExpr(local.tok, local));
- }
- builder.Add(new Bpl.HavocCmd(me.tok, havocIds));
- }
- b.Add(Assert(me.tok, Bpl.Expr.False, "missing case in case statement: " + missingCtor.Name));
-
- Bpl.Expr guard = Bpl.Expr.Eq(src, r);
- ifCmd = new Bpl.IfCmd(me.tok, guard, b.Collect(me.tok), ifCmd, els);
- els = null;
- }
- for (int i = me.Cases.Count; 0 <= --i; ) {
- MatchCaseExpr mc = me.Cases[i];
- Bpl.StmtListBuilder b = new Bpl.StmtListBuilder();
- Bpl.Expr ct = CtorInvocation(mc, etran, locals, b);
- // generate: if (src == ctor(args)) { assume args-is-well-typed; mc.Body is well-formed; assume Result == TrExpr(case); } else ...
- CheckWellformedWithResult(mc.Body, options, result, resultType, locals, b, etran);
- ifCmd = new Bpl.IfCmd(mc.tok, Bpl.Expr.Eq(src, ct), b.Collect(mc.tok), ifCmd, els);
- els = null;
- }
- builder.Add(ifCmd);
- result = null;
-
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- CheckWellformedWithResult(e.ResolvedExpression, options, result, resultType, locals, builder, etran);
- result = null;
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
-
- if (result != null) {
- Contract.Assert(resultType != null);
- var bResult = etran.TrExpr(expr);
- CheckSubrange(expr.tok, bResult, resultType, builder);
- builder.Add(new Bpl.AssumeCmd(expr.tok, Bpl.Expr.Eq(result, bResult)));
- builder.Add(new Bpl.AssumeCmd(expr.tok, CanCallAssumption(expr, etran)));
- }
- }
-
- /// <summary>
- /// Returns true if it is known how to meaningfully compare the type's inhabitants.
- /// </summary>
- static bool IsOrdered(Type t) {
- return !t.IsTypeParameter && !t.IsCoDatatype;
- }
-
- public static List<Expression> MethodDecreasesWithDefault(ICodeContext m, out bool inferredDecreases) {
- Contract.Requires(m != null);
-
- inferredDecreases = false;
- List<Expression> decr = m.Decreases.Expressions;
- if (decr.Count == 0) {
- decr = new List<Expression>();
- foreach (Formal p in m.Ins) {
- if (IsOrdered(p.Type)) {
- IdentifierExpr ie = new IdentifierExpr(p.tok, p.Name);
- ie.Var = p; ie.Type = ie.Var.Type; // resolve it here
- decr.Add(ie); // use the method's first parameter instead
- }
- }
- inferredDecreases = true;
- } else if (m is IteratorDecl) {
- inferredDecreases = ((IteratorDecl)m).InferredDecreases;
- }
- return decr;
- }
-
- List<Expression> FunctionDecreasesWithDefault(Function f, out bool inferredDecreases) {
- Contract.Requires(f != null);
-
- inferredDecreases = false;
- List<Expression> decr = f.Decreases.Expressions;
- if (decr.Count == 0) {
- decr = new List<Expression>();
- if (f.Reads.Count == 0) {
- foreach (Formal p in f.Formals) {
- if (IsOrdered(p.Type)) {
- IdentifierExpr ie = new IdentifierExpr(p.tok, p.UniqueName);
- ie.Var = p; ie.Type = ie.Var.Type; // resolve it here
- decr.Add(ie); // use the function's first parameter instead
- }
- }
- inferredDecreases = true;
- } else {
- decr.Add(FrameToObjectSet(f.Reads)); // use its reads clause instead
- }
- }
- return decr;
- }
-
- List<Expression> LoopDecreasesWithDefault(IToken tok, Expression Guard, List<Expression> Decreases, out bool inferredDecreases) {
- Contract.Requires(tok != null);
- Contract.Requires(Decreases != null);
-
- List<Expression> theDecreases = Decreases;
- inferredDecreases = false;
- if (theDecreases.Count == 0 && Guard != null) {
- theDecreases = new List<Expression>();
- Expression prefix = null;
- foreach (Expression guardConjunct in Conjuncts(Guard)) {
- Expression guess = null;
- BinaryExpr bin = guardConjunct as BinaryExpr;
- if (bin != null) {
- switch (bin.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.Lt:
- case BinaryExpr.ResolvedOpcode.Le:
- // for A < B and A <= B, use the decreases B - A
- guess = CreateIntSub(tok, bin.E1, bin.E0);
- break;
- case BinaryExpr.ResolvedOpcode.Ge:
- case BinaryExpr.ResolvedOpcode.Gt:
- // for A >= B and A > B, use the decreases A - B
- guess = CreateIntSub(tok, bin.E0, bin.E1);
- break;
- case BinaryExpr.ResolvedOpcode.NeqCommon:
- if (bin.E0.Type is IntType) {
- // for A != B where A and B are integers, use the absolute difference between A and B (that is: if 0 <= A-B then A-B else B-A)
- Expression AminusB = CreateIntSub(tok, bin.E0, bin.E1);
- Expression BminusA = CreateIntSub(tok, bin.E1, bin.E0);
- Expression zero = CreateIntLiteral(tok, 0);
- BinaryExpr test = new BinaryExpr(tok, BinaryExpr.Opcode.Le, zero, AminusB);
- test.ResolvedOp = BinaryExpr.ResolvedOpcode.Le; // resolve here
- test.Type = Type.Bool; // resolve here
- guess = CreateIntITE(tok, test, AminusB, BminusA);
- }
- break;
- default:
- break;
- }
- }
- if (guess != null) {
- if (prefix != null) {
- // Make the following guess: if prefix then guess else -1
- Expression negativeOne = CreateIntLiteral(tok, -1);
- guess = CreateIntITE(tok, prefix, guess, negativeOne);
- }
- theDecreases.Add(guess);
- inferredDecreases = true;
- break; // ignore any further conjuncts
- }
- if (prefix == null) {
- prefix = guardConjunct;
- } else {
- prefix = DafnyAnd(prefix, guardConjunct);
- }
- }
- }
- if (yieldCountVariable != null) {
- var decr = new List<Expression>();
- decr.Add(new BoogieWrapper(new Bpl.IdentifierExpr(tok, yieldCountVariable), new EverIncreasingType()));
- decr.AddRange(theDecreases);
- theDecreases = decr;
- }
- return theDecreases;
- }
-
- /// <summary>
- /// This Dafny type, which exists only during translation of Dafny into Boogie, represents
- /// an integer component in a "decreases" clause whose order is (\lambda x,y :: x GREATER y),
- /// not the usual (\lambda x,y :: x LESS y AND 0 ATMOST y).
- /// </summary>
- public class EverIncreasingType : BasicType
- {
- [Pure]
- public override string TypeName(ModuleDefinition context) {
- return "_increasingInt";
- }
- }
-
- Expression FrameToObjectSet(List<FrameExpression> fexprs) {
- Contract.Requires(fexprs != null);
- Contract.Ensures(Contract.Result<Expression>() != null);
-
- List<Expression> sets = new List<Expression>();
- List<Expression> singletons = null;
- foreach (FrameExpression fe in fexprs) {
- Contract.Assert(fe != null);
- if (fe.E is WildcardExpr) {
- // drop wildcards altogether
- } else {
- Expression e = fe.E; // keep only fe.E, drop any fe.Field designation
- Contract.Assert(e.Type != null); // should have been resolved already
- if (e.Type.IsRefType) {
- // e represents a singleton set
- if (singletons == null) {
- singletons = new List<Expression>();
- }
- singletons.Add(e);
- } else if (e.Type is SeqType) {
- // e represents a sequence
- // Add: set x :: x in e
- var bv = new BoundVar(e.tok, "_s2s_" + otherTmpVarCount, ((SeqType)e.Type).Arg);
- otherTmpVarCount++; // use this counter, but for a Dafny name (the idea being that the number and the initial "_" in the name might avoid name conflicts)
- var bvIE = new IdentifierExpr(e.tok, bv.Name);
- bvIE.Var = bv; // resolve here
- bvIE.Type = bv.Type; // resolve here
- var sInE = new BinaryExpr(e.tok, BinaryExpr.Opcode.In, bvIE, e);
- sInE.ResolvedOp = BinaryExpr.ResolvedOpcode.InSeq; // resolve here
- sInE.Type = Type.Bool; // resolve here
- var s = new SetComprehension(e.tok, new List<BoundVar>() { bv }, sInE, bvIE);
- s.Type = new SetType(new ObjectType()); // resolve here
- sets.Add(s);
- } else {
- // e is already a set
- Contract.Assert(e.Type is SetType);
- sets.Add(e);
- }
- }
- }
- if (singletons != null) {
- Expression display = new SetDisplayExpr(singletons[0].tok, singletons);
- display.Type = new SetType(new ObjectType()); // resolve here
- sets.Add(display);
- }
- if (sets.Count == 0) {
- Expression emptyset = new SetDisplayExpr(Token.NoToken, new List<Expression>());
- emptyset.Type = new SetType(new ObjectType()); // resolve here
- return emptyset;
- } else {
- Expression s = sets[0];
- for (int i = 1; i < sets.Count; i++) {
- BinaryExpr union = new BinaryExpr(s.tok, BinaryExpr.Opcode.Add, s, sets[i]);
- union.ResolvedOp = BinaryExpr.ResolvedOpcode.Union; // resolve here
- union.Type = new SetType(new ObjectType()); // resolve here
- s = union;
- }
- return s;
- }
- }
-
- void CloneVariableAsBoundVar(IToken tok, IVariable iv, string prefix, out BoundVar bv, out IdentifierExpr ie) {
- Contract.Requires(tok != null);
- Contract.Requires(iv != null);
- Contract.Requires(prefix != null);
- Contract.Ensures(Contract.ValueAtReturn(out bv) != null);
- Contract.Ensures(Contract.ValueAtReturn(out ie) != null);
-
- bv = new BoundVar(tok, prefix + otherTmpVarCount, iv.Type);
- otherTmpVarCount++; // use this counter, but for a Dafny name (the idea being that the number and the initial "_" in the name might avoid name conflicts)
- ie = new IdentifierExpr(tok, bv.Name);
- ie.Var = bv; // resolve here
- ie.Type = bv.Type; // resolve here
- }
-
- Bpl.Constant GetClass(TopLevelDecl cl)
- {
- Contract.Requires(cl != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Constant>() != null);
-
- Bpl.Constant cc;
- if (classes.TryGetValue(cl, out cc)) {
- Contract.Assert(cc != null);
- } else {
- cc = new Bpl.Constant(cl.tok, new Bpl.TypedIdent(cl.tok, "class." + cl.FullCompileName, predef.ClassNameType), !cl.Module.IsAbstract);
- classes.Add(cl, cc);
- }
- return cc;
- }
-
- Bpl.Constant GetFieldNameFamily(string n) {
- Contract.Requires(n != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Constant>() != null);
- Bpl.Constant cc;
- if (fieldConstants.TryGetValue(n, out cc)) {
- Contract.Assert(cc != null);
- } else {
- cc = new Bpl.Constant(Token.NoToken, new Bpl.TypedIdent(Token.NoToken, "field$" + n, predef.NameFamilyType), true);
- fieldConstants.Add(n, cc);
- }
- return cc;
- }
-
- Bpl.Expr GetTypeExpr(IToken tok, Type type)
- {
- Contract.Requires(tok != null);
- Contract.Requires(type != null);
- Contract.Requires(predef != null);
- while (true) {
- TypeProxy tp = type as TypeProxy;
- if (tp == null) {
- break;
- } else if (tp.T == null) {
- // unresolved proxy
- // TODO: what to do here?
- return null;
- } else {
- type = tp.T;
- }
- }
-
- if (type is BoolType) {
- return new Bpl.IdentifierExpr(tok, "class._System.bool", predef.ClassNameType);
- } else if (type is IntType) {
- return new Bpl.IdentifierExpr(tok, "class._System.int", predef.ClassNameType);
- } else if (type is ObjectType) {
- return new Bpl.IdentifierExpr(tok, GetClass(program.BuiltIns.ObjectDecl));
- } else if (type is CollectionType) {
- CollectionType ct = (CollectionType)type;
- Bpl.Expr a = GetTypeExpr(tok, ct.Arg);
- if (a == null) {
- return null;
- }
- Bpl.Expr t = new Bpl.IdentifierExpr(tok,
- ct is SetType ? "class._System.set" :
- ct is SeqType ? "class._System.seq" :
- "class._System.multiset",
- predef.ClassNameType);
- return FunctionCall(tok, BuiltinFunction.TypeTuple, null, t, a);
- } else {
- UserDefinedType ct = (UserDefinedType)type;
- if (ct.ResolvedClass == null) {
- return null; // TODO: what to do here?
- }
- Bpl.Expr t = new Bpl.IdentifierExpr(tok, GetClass(ct.ResolvedClass));
- foreach (Type arg in ct.TypeArgs) {
- Bpl.Expr a = GetTypeExpr(tok, arg);
- if (a == null) {
- return null;
- }
- t = FunctionCall(tok, BuiltinFunction.TypeTuple, null, t, a);
- }
- return t;
- }
- }
-
- Bpl.Constant GetField(Field f)
- {
- Contract.Requires(f != null && f.IsMutable);
- Contract.Requires(sink != null && predef != null);
- Contract.Ensures(Contract.Result<Bpl.Constant>() != null);
-
- Bpl.Constant fc;
- if (fields.TryGetValue(f, out fc)) {
- Contract.Assert(fc != null);
- } else {
- // const f: Field ty;
- Bpl.Type ty = predef.FieldName(f.tok, TrType(f.Type));
- fc = new Bpl.Constant(f.tok, new Bpl.TypedIdent(f.tok, f.FullCompileName, ty), false);
- fields.Add(f, fc);
- // axiom FDim(f) == 0 && FieldOfDecl(C, name) == f;
- Bpl.Expr fdim = Bpl.Expr.Eq(FunctionCall(f.tok, BuiltinFunction.FDim, ty, Bpl.Expr.Ident(fc)), Bpl.Expr.Literal(0));
- Bpl.Expr declType = Bpl.Expr.Eq(FunctionCall(f.tok, BuiltinFunction.FieldOfDecl, ty, new Bpl.IdentifierExpr(f.tok, GetClass(cce.NonNull(f.EnclosingClass))), new Bpl.IdentifierExpr(f.tok, GetFieldNameFamily(f.Name))), Bpl.Expr.Ident(fc));
- Bpl.Axiom ax = new Bpl.Axiom(f.tok, Bpl.Expr.And(fdim, declType));
- sink.TopLevelDeclarations.Add(ax);
- }
- return fc;
- }
-
- Bpl.Function GetReadonlyField(Field f)
- {
- Contract.Requires(f != null && !f.IsMutable);
- Contract.Requires(sink != null && predef != null);
- Contract.Ensures(Contract.Result<Bpl.Function>() != null);
-
- Bpl.Function ff;
- if (fieldFunctions.TryGetValue(f, out ff)) {
- Contract.Assert(ff != null);
- } else {
- if (f.EnclosingClass is ArrayClassDecl && f.Name == "Length") { // link directly to the function in the prelude.
- fieldFunctions.Add(f, predef.ArrayLength);
- return predef.ArrayLength;
- }
- // function f(Ref): ty;
- Bpl.Type ty = TrType(f.Type);
- Bpl.VariableSeq args = new Bpl.VariableSeq();
- Bpl.Type receiverType = f.EnclosingClass is ClassDecl ? predef.RefType : predef.DatatypeType;
- args.Add(new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "this", receiverType), true));
- Bpl.Formal result = new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, Bpl.TypedIdent.NoName, ty), false);
- ff = new Bpl.Function(f.tok, f.FullCompileName, args, result);
- fieldFunctions.Add(f, ff);
- // treat certain fields specially
- if (f.EnclosingClass is ArrayClassDecl) {
- // add non-negative-range axioms for array Length fields
- // axiom (forall o: Ref :: 0 <= array.Length(o));
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "o", predef.RefType));
- Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(f.tok, oVar);
- Bpl.Expr body = Bpl.Expr.Le(Bpl.Expr.Literal(0), new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(ff), new Bpl.ExprSeq(o)));
- Bpl.Expr qq = new Bpl.ForallExpr(f.tok, new Bpl.VariableSeq(oVar), body);
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(f.tok, qq));
- }
- }
- return ff;
- }
-
- Bpl.Expr GetField(FieldSelectExpr fse)
- {
- Contract.Requires(fse != null);
- Contract.Requires(fse.Field != null && fse.Field.IsMutable);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- return new Bpl.IdentifierExpr(fse.tok, GetField(fse.Field));
- }
-
- /// <summary>
- /// This method is expected to be called just once for each function in the program.
- /// </summary>
- void AddFunction(Function f)
- {
- Contract.Requires(f != null);
- Contract.Requires(predef != null && sink != null);
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(f.TypeArgs);
- Bpl.VariableSeq args = new Bpl.VariableSeq();
- args.Add(new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "$heap", predef.HeapType), true));
- if (!f.IsStatic) {
- args.Add(new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "this", predef.RefType), true));
- }
- foreach (Formal p in f.Formals) {
- args.Add(new Bpl.Formal(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, TrType(p.Type)), true));
- }
- Bpl.Formal res = new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, Bpl.TypedIdent.NoName, TrType(f.ResultType)), false);
- Bpl.Function func = new Bpl.Function(f.tok, f.FullCompileName, typeParams, args, res);
- sink.TopLevelDeclarations.Add(func);
-
- if (f.IsRecursive) {
- sink.TopLevelDeclarations.Add(new Bpl.Function(f.tok, FunctionName(f, 0), args, res));
- sink.TopLevelDeclarations.Add(new Bpl.Function(f.tok, FunctionName(f, 2), args, res));
- }
-
- res = new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, Bpl.TypedIdent.NoName, Bpl.Type.Bool), false);
- Bpl.Function canCallF = new Bpl.Function(f.tok, f.FullCompileName + "#canCall", args, res);
- sink.TopLevelDeclarations.Add(canCallF);
- }
-
- /// <summary>
- /// This method is expected to be called at most 4 times for each procedure in the program:
- /// * once with kind==0, which says to create a procedure for the wellformedness check of the
- /// method's specification
- /// * once with kind==1, which says to create the ordinary procedure for the method, always
- /// suitable for inter-module callers, and for non-refinement methods also suitable for
- /// the implementation and intra-module callers of the method
- /// * possibly once with kind==2 (allowed only if isRefinementMethod), which says to create
- /// a procedure suitable for intra-module callers of a refinement method
- /// * possibly once with kind==3 (allowed only if isRefinementMethod), which says to create
- /// a procedure suitable for the implementation of a refinement method
- /// </summary>
- Bpl.Procedure AddMethod(Method m, int kind, bool isRefinementMethod)
- {
- Contract.Requires(m != null);
- Contract.Requires(m.EnclosingClass != null);
- Contract.Requires(0 <= kind && kind < 4);
- Contract.Requires(isRefinementMethod || kind < 2);
- Contract.Requires(predef != null);
- Contract.Requires(currentModule == null && codeContext == null);
- Contract.Ensures(currentModule == null && codeContext == null);
- Contract.Ensures(Contract.Result<Bpl.Procedure>() != null);
-
- currentModule = m.EnclosingClass.Module;
- codeContext = m;
-
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, m.tok);
-
- Bpl.VariableSeq inParams, outParams;
- GenerateMethodParameters(m.tok, m, etran, out inParams, out outParams);
-
- Bpl.RequiresSeq req = new Bpl.RequiresSeq();
- Bpl.IdentifierExprSeq mod = new Bpl.IdentifierExprSeq();
- Bpl.EnsuresSeq ens = new Bpl.EnsuresSeq();
- if (kind == 0 || (kind == 1 && !isRefinementMethod) || kind == 3) { // the other cases have no need for a free precondition
- // free requires mh == ModuleContextHeight && InMethodContext;
- Bpl.Expr context = Bpl.Expr.And(
- Bpl.Expr.Eq(Bpl.Expr.Literal(m.EnclosingClass.Module.Height), etran.ModuleContextHeight()),
- etran.InMethodContext());
- req.Add(Requires(m.tok, true, context, null, null));
- }
- mod.Add((Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr);
- mod.Add(etran.Tick());
-
- if (kind != 0) {
- string comment = "user-defined preconditions";
- foreach (MaybeFreeExpression p in m.Req) {
- if ((p.IsFree && !DafnyOptions.O.DisallowSoundnessCheating) || kind == 3) { // kind==3 never has callers, so no reason to bother splitting
- req.Add(Requires(p.E.tok, true, etran.TrExpr(p.E), null, comment));
- } else {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p.E, etran, out splitHappened)) {
- if (kind == 2 && RefinementToken.IsInherited(s.E.tok, currentModule)) {
- // this precondition was inherited into this module, so just ignore it
- } else {
- req.Add(Requires(s.E.tok, s.IsFree, s.E, null, null));
- // the free here is not linked to the free on the original expression (this is free things generated in the splitting.)
- }
- }
- }
- comment = null;
- }
- comment = "user-defined postconditions";
- foreach (MaybeFreeExpression p in m.Ens) {
- if ((p.IsFree && !DafnyOptions.O.DisallowSoundnessCheating) || (kind == 1 && isRefinementMethod) || kind == 2) { // for refinement methods, kind==1 has no implementations, and kind==2 never has implementations
- ens.Add(Ensures(p.E.tok, true, etran.TrExpr(p.E), null, comment));
- } else {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p.E, etran, out splitHappened)) {
- if (kind == 3 && RefinementToken.IsInherited(s.E.tok, currentModule)) {
- // this postcondition was inherited into this module, so just ignore it
- } else {
- ens.Add(Ensures(s.E.tok, s.IsFree, s.E, null, null));
- }
- }
- }
- comment = null;
- }
- foreach (BoilerplateTriple tri in GetTwoStateBoilerplate(m.tok, m.Mod.Expressions, etran.Old, etran, etran.Old)) {
- ens.Add(Ensures(tri.tok, tri.IsFree, tri.Expr, tri.ErrorMessage, tri.Comment));
- }
- }
-
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(m.TypeArgs);
- string name;
- switch (kind) {
- case 0: name = "CheckWellformed$$" + m.FullCompileName; break;
- case 1: name = m.FullCompileName; break;
- case 2: name = string.Format("RefinementCall_{0}$${1}", m.EnclosingClass.Module.Name, m.FullCompileName); break;
- case 3: name = string.Format("RefinementImpl_{0}$${1}", m.EnclosingClass.Module.Name, m.FullCompileName); break;
- default: Contract.Assert(false); throw new cce.UnreachableException(); // unexpected kind
- }
- Bpl.Procedure proc = new Bpl.Procedure(m.tok, name, typeParams, inParams, outParams, req, mod, ens);
-
- currentModule = null;
- codeContext = null;
-
- return proc;
- }
-
- private void AddMethodRefinementCheck(MethodCheck methodCheck) {
-
- // First, we generate the declaration of the procedure. This procedure has the same
- // pre and post conditions as the refined method. The body implementation will be a call
- // to the refining method.
- Method m = methodCheck.Refined;
- currentModule = m.EnclosingClass.Module;
- codeContext = m;
-
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, m.tok);
-
- Bpl.VariableSeq inParams, outParams;
- GenerateMethodParameters(m.tok, m, etran, out inParams, out outParams);
-
- Bpl.RequiresSeq req = new Bpl.RequiresSeq();
- Bpl.IdentifierExprSeq mod = new Bpl.IdentifierExprSeq();
- Bpl.EnsuresSeq ens = new Bpl.EnsuresSeq();
-
- Bpl.Expr context = Bpl.Expr.And(
- Bpl.Expr.Eq(Bpl.Expr.Literal(m.EnclosingClass.Module.Height), etran.ModuleContextHeight()),
- etran.InMethodContext());
- req.Add(Requires(m.tok, true, context, null, null));
-
- mod.Add((Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr);
- mod.Add(etran.Tick());
-
- foreach (MaybeFreeExpression p in m.Req) {
- if ((p.IsFree && !DafnyOptions.O.DisallowSoundnessCheating)) {
- req.Add(Requires(p.E.tok, true, etran.TrExpr(p.E), null, null));
- } else {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p.E, etran, out splitHappened)) {
- req.Add(Requires(s.E.tok, s.IsFree, s.E, null, null));
- }
- }
- }
- foreach (MaybeFreeExpression p in m.Ens) {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p.E, etran, out splitHappened)) {
- ens.Add(Ensures(s.E.tok, s.IsFree, s.E, "Error: postcondition of refined method may be violated", null));
- }
- }
- foreach (BoilerplateTriple tri in GetTwoStateBoilerplate(m.tok, m.Mod.Expressions, etran.Old, etran, etran.Old)) {
- ens.Add(Ensures(tri.tok, tri.IsFree, tri.Expr, tri.ErrorMessage, tri.Comment));
- }
-
- // Generate procedure, and then add it to the sink
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(m.TypeArgs);
- string name = "CheckRefinement$$" + m.FullCompileName + "$" + methodCheck.Refining.FullCompileName;
- Bpl.Procedure proc = new Bpl.Procedure(m.tok, name, typeParams, inParams, outParams, req, mod, new Bpl.EnsuresSeq());
-
- sink.TopLevelDeclarations.Add(proc);
-
-
- // Generate the implementation
- typeParams = TrTypeParamDecls(m.TypeArgs);
- inParams = Bpl.Formal.StripWhereClauses(proc.InParams);
- outParams = Bpl.Formal.StripWhereClauses(proc.OutParams);
-
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
- Bpl.VariableSeq localVariables = new Bpl.VariableSeq();
- GenerateImplPrelude(m, inParams, outParams, builder, localVariables);
-
- // Generate the call to the refining method
- Method method = methodCheck.Refining;
- Expression receiver = new ThisExpr(Token.NoToken);
- Bpl.ExprSeq ins = new Bpl.ExprSeq();
- if (!method.IsStatic) {
- ins.Add(etran.TrExpr(receiver));
- }
-
- // Ideally, the modifies and decreases checks would be done after the precondition check,
- // but Boogie doesn't give us a hook for that. So, we set up our own local variables here to
- // store the actual parameters.
- // Create a local variable for each formal parameter, and assign each actual parameter to the corresponding local
- Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
- for (int i = 0; i < method.Ins.Count; i++) {
- Formal p = method.Ins[i];
- VarDecl local = new VarDecl(p.tok, p.Name + "#", p.Type, p.IsGhost);
- local.type = local.OptionalType; // resolve local here
- IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
- ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
- substMap.Add(p, ie);
- localVariables.Add(new Bpl.LocalVariable(local.Tok, new Bpl.TypedIdent(local.Tok, local.UniqueName, TrType(local.Type))));
-
- Bpl.IdentifierExpr param = (Bpl.IdentifierExpr)etran.TrExpr(ie); // TODO: is this cast always justified?
- var bActual = new Bpl.IdentifierExpr(Token.NoToken, m.Ins[i].UniqueName, TrType(m.Ins[i].Type));
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(p.tok, param, etran.CondApplyUnbox(Token.NoToken, bActual, cce.NonNull( m.Ins[i].Type),p.Type));
- builder.Add(cmd);
- ins.Add(param);
- }
-
- // Check modifies clause of a subcall is a subset of the current frame.
- CheckFrameSubset(method.tok, method.Mod.Expressions, receiver, substMap, etran, builder, "call may modify locations not in the refined method's modifies clause", null);
-
- // Create variables to hold the output parameters of the call, so that appropriate unboxes can be introduced.
- Bpl.IdentifierExprSeq outs = new Bpl.IdentifierExprSeq();
- List<Bpl.IdentifierExpr> tmpOuts = new List<Bpl.IdentifierExpr>();
- for (int i = 0; i < m.Outs.Count; i++) {
- var bLhs = m.Outs[i];
- if (!ExpressionTranslator.ModeledAsBoxType(method.Outs[i].Type) && ExpressionTranslator.ModeledAsBoxType(bLhs.Type)) {
- // we need an Box
- Bpl.LocalVariable var = new Bpl.LocalVariable(bLhs.tok, new Bpl.TypedIdent(bLhs.tok, "$tmp##" + otherTmpVarCount, TrType(method.Outs[i].Type)));
- otherTmpVarCount++;
- localVariables.Add(var);
- Bpl.IdentifierExpr varIdE = new Bpl.IdentifierExpr(bLhs.tok, var.Name, TrType(method.Outs[i].Type));
- tmpOuts.Add(varIdE);
- outs.Add(varIdE);
- } else {
- tmpOuts.Add(null);
- outs.Add(new Bpl.IdentifierExpr(Token.NoToken, bLhs.UniqueName, TrType(bLhs.Type)));
- }
- }
-
- // Make the call
- Bpl.CallCmd call = new Bpl.CallCmd(method.tok, method.FullCompileName, ins, outs);
- builder.Add(call);
-
- for (int i = 0; i < m.Outs.Count; i++) {
- var bLhs = m.Outs[i];
- var tmpVarIdE = tmpOuts[i];
- if (tmpVarIdE != null) {
- // e := Box(tmpVar);
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(Token.NoToken, new Bpl.IdentifierExpr(Token.NoToken, bLhs.UniqueName, TrType(bLhs.Type)), FunctionCall(Token.NoToken, BuiltinFunction.Box, null, tmpVarIdE));
- builder.Add(cmd);
- }
- }
-
- foreach (MaybeFreeExpression p in m.Ens) {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p.E, etran, out splitHappened)) {
- var assert = new Bpl.AssertCmd(method.tok, s.E, ErrorMessageAttribute(s.E.tok, "This is the postcondition that may not hold."));
- assert.ErrorData = "Error: A postcondition of the refined method may not hold.";
- builder.Add(assert);
- }
- }
- Bpl.StmtList stmts = builder.Collect(method.tok); // this token is for the implict return, which should be for the refining method,
- // as this is where the error is.
-
- Bpl.Implementation impl = new Bpl.Implementation(m.tok, proc.Name,
- typeParams, inParams, outParams,
- localVariables, stmts, etran.TrAttributes(m.Attributes, null));
- sink.TopLevelDeclarations.Add(impl);
-
- // Clean up
- currentModule = null;
- codeContext = null;
- otherTmpVarCount = 0;
- _tmpIEs.Clear();
- }
-
- private static QKeyValue ErrorMessageAttribute(IToken t, string error) {
- var l = new List<object>(1);
- l.Add(error);
- return new QKeyValue(t, "msg", l, null);
- }
- private static QKeyValue ErrorMessageAttribute(IToken t, string error, QKeyValue qv) {
- var l = new List<object>(1);
- l.Add(error);
- return new QKeyValue(t, "msg", l, qv);
- }
-
- private void AddFunctionRefinementCheck(FunctionCheck functionCheck) {
- Contract.Requires(sink != null && predef != null);
- Contract.Requires(currentModule == null);
- Contract.Ensures(currentModule == null);
-
- Function f = functionCheck.Refined;
- Function function = functionCheck.Refining;
- currentModule = function.EnclosingClass.Module;
-
- ExpressionTranslator etran = new ExpressionTranslator(this, predef, f.tok);
- // parameters of the procedure
- Bpl.VariableSeq inParams = new Bpl.VariableSeq();
- if (!f.IsStatic) {
- Bpl.Expr wh = Bpl.Expr.And(
- Bpl.Expr.Neq(new Bpl.IdentifierExpr(f.tok, "this", predef.RefType), predef.Null),
- etran.GoodRef(f.tok, new Bpl.IdentifierExpr(f.tok, "this", predef.RefType), Resolver.GetReceiverType(f.tok, f)));
- Bpl.Formal thVar = new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "this", predef.RefType, wh), true);
- inParams.Add(thVar);
- }
- foreach (Formal p in f.Formals) {
- Bpl.Type varType = TrType(p.Type);
- Bpl.Expr wh = GetWhereClause(p.tok, new Bpl.IdentifierExpr(p.tok, p.UniqueName, varType), p.Type, etran);
- inParams.Add(new Bpl.Formal(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, varType, wh), true));
- }
- Bpl.TypeVariableSeq typeParams = TrTypeParamDecls(f.TypeArgs);
- // the procedure itself
- Bpl.RequiresSeq req = new Bpl.RequiresSeq();
- // free requires mh == ModuleContextHeight && fh == FunctionContextHeight;
- ModuleDefinition mod = function.EnclosingClass.Module;
- Bpl.Expr context = Bpl.Expr.And(
- Bpl.Expr.Eq(Bpl.Expr.Literal(mod.Height), etran.ModuleContextHeight()),
- Bpl.Expr.Eq(Bpl.Expr.Literal(mod.CallGraph.GetSCCRepresentativeId(function)), etran.FunctionContextHeight()));
- req.Add(Requires(f.tok, true, context, null, null));
-
- foreach (Expression p in f.Req) {
- req.Add(Requires(p.tok, true, etran.TrExpr(p), null, null));
- }
-
- // check that postconditions hold
- var ens = new Bpl.EnsuresSeq();
- foreach (Expression p in f.Ens) {
- bool splitHappened; // we actually don't care
- foreach (var s in TrSplitExpr(p, etran, out splitHappened)) {
- if (!s.IsFree) {
- ens.Add(Ensures(s.E.tok, s.IsFree, s.E, null, null));
- }
- }
- }
- Bpl.Procedure proc = new Bpl.Procedure(function.tok, "CheckIsRefinement$$" + f.FullCompileName + "$" + functionCheck.Refining.FullCompileName, typeParams, inParams, new Bpl.VariableSeq(),
- req, new Bpl.IdentifierExprSeq(), ens, etran.TrAttributes(f.Attributes, null));
- sink.TopLevelDeclarations.Add(proc);
-
- VariableSeq implInParams = Bpl.Formal.StripWhereClauses(proc.InParams);
- Bpl.VariableSeq locals = new Bpl.VariableSeq();
- Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
-
- Bpl.FunctionCall funcOriginal = new Bpl.FunctionCall(new Bpl.IdentifierExpr(f.tok, f.FullCompileName, TrType(f.ResultType)));
- Bpl.FunctionCall funcRefining = new Bpl.FunctionCall(new Bpl.IdentifierExpr(functionCheck.Refining.tok, functionCheck.Refining.FullCompileName, TrType(f.ResultType)));
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- args.Add(etran.HeapExpr);
- foreach (Variable p in implInParams) {
- args.Add(new Bpl.IdentifierExpr(f.tok, p));
- }
- Bpl.Expr funcAppl = new Bpl.NAryExpr(f.tok, funcOriginal, args);
- Bpl.Expr funcAppl2 = new Bpl.NAryExpr(f.tok, funcRefining, args);
-
- Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
- for (int i = 0; i < function.Formals.Count; i++) {
- Formal p = function.Formals[i];
- IdentifierExpr ie = new IdentifierExpr(f.Formals[i].tok, f.Formals[i].UniqueName);
- ie.Var = f.Formals[i]; ie.Type = ie.Var.Type; // resolve ie here
- substMap.Add(p, ie);
- }
- // add canCall
- Bpl.IdentifierExpr canCallFuncID = new Bpl.IdentifierExpr(Token.NoToken, function.FullCompileName + "#canCall", Bpl.Type.Bool);
- Bpl.Expr canCall = new Bpl.NAryExpr(Token.NoToken, new Bpl.FunctionCall(canCallFuncID), args);
- builder.Add(new AssumeCmd(function.tok, canCall));
-
- // check that the preconditions for the call hold
- foreach (Expression p in function.Req) {
- Expression precond = Substitute(p, new ThisExpr(Token.NoToken), substMap);
- var assert = new AssertCmd(p.tok, etran.TrExpr(precond));
- assert.ErrorData = "Error: the refining function is not allowed to add preconditions";
- builder.Add(assert);
- }
- builder.Add(new AssumeCmd(f.tok, Bpl.Expr.Eq(funcAppl, funcAppl2)));
-
- foreach (Expression p in f.Ens) {
- var s = new FunctionCallSubstituter(new ThisExpr(Token.NoToken), substMap, f, function);
- Expression precond = s.Substitute(p);
- var assert = new AssertCmd(p.tok, etran.TrExpr(precond));
- assert.ErrorData = "Error: A postcondition of the refined function may not hold";
- builder.Add(assert);
- }
- Bpl.Implementation impl = new Bpl.Implementation(function.tok, proc.Name,
- typeParams, implInParams, new Bpl.VariableSeq(),
- locals, builder.Collect(function.tok));
- sink.TopLevelDeclarations.Add(impl);
-
- Contract.Assert(currentModule == function.EnclosingClass.Module);
- currentModule = null;
- }
-
- private void GenerateMethodParameters(IToken tok, ICodeContext m, ExpressionTranslator etran, out Bpl.VariableSeq inParams, out Bpl.VariableSeq outParams) {
- GenerateMethodParametersChoose(tok, m, !m.IsStatic, true, true, etran, out inParams, out outParams);
- }
-
- private void GenerateMethodParametersChoose(IToken tok, ICodeContext m, bool includeReceiver, bool includeInParams, bool includeOutParams,
- ExpressionTranslator etran, out Bpl.VariableSeq inParams, out Bpl.VariableSeq outParams) {
- inParams = new Bpl.VariableSeq();
- outParams = new Bpl.VariableSeq();
- if (includeReceiver) {
- var receiverType = m is MemberDecl ? Resolver.GetReceiverType(tok, (MemberDecl)m) : Resolver.GetThisType(tok, (IteratorDecl)m);
- Bpl.Expr wh = Bpl.Expr.And(
- Bpl.Expr.Neq(new Bpl.IdentifierExpr(tok, "this", predef.RefType), predef.Null),
- etran.GoodRef(tok, new Bpl.IdentifierExpr(tok, "this", predef.RefType), receiverType));
- Bpl.Formal thVar = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "this", predef.RefType, wh), true);
- inParams.Add(thVar);
- }
- if (includeInParams) {
- foreach (Formal p in m.Ins) {
- Bpl.Type varType = TrType(p.Type);
- Bpl.Expr wh = GetWhereClause(p.tok, new Bpl.IdentifierExpr(p.tok, p.UniqueName, varType), p.Type, etran);
- inParams.Add(new Bpl.Formal(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, varType, wh), true));
- }
- }
- if (includeOutParams) {
- foreach (Formal p in m.Outs) {
- Bpl.Type varType = TrType(p.Type);
- Bpl.Expr wh = GetWhereClause(p.tok, new Bpl.IdentifierExpr(p.tok, p.UniqueName, varType), p.Type, etran);
- outParams.Add(new Bpl.Formal(p.tok, new Bpl.TypedIdent(p.tok, p.UniqueName, varType, wh), false));
- }
- }
- }
-
- class BoilerplateTriple
- { // a triple that is now a quintuple
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(tok != null);
- Contract.Invariant(Expr != null);
- Contract.Invariant(IsFree || ErrorMessage != null);
- }
-
- public readonly IToken tok;
- public readonly bool IsFree;
- public readonly Bpl.Expr Expr;
- public readonly string ErrorMessage;
- public readonly string Comment;
-
-
- public BoilerplateTriple(IToken tok, bool isFree, Bpl.Expr expr, string errorMessage, string comment)
- {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- Contract.Requires(isFree || errorMessage != null);
- this.tok = tok;
- IsFree = isFree;
- Expr = expr;
- ErrorMessage = errorMessage;
- Comment = comment;
- }
- }
-
- /// <summary>
- /// There are 3 states of interest when generating two-state boilerplate:
- /// S0. the beginning of the method or loop, which is where the modifies clause is interpreted
- /// S1. the pre-state of the two-state interval
- /// S2. the post-state of the two-state interval
- /// This method assumes that etranPre denotes S1, etran denotes S2, and that etranMod denotes S0.
- /// </summary>
- List<BoilerplateTriple/*!*/>/*!*/ GetTwoStateBoilerplate(IToken/*!*/ tok, List<FrameExpression/*!*/>/*!*/ modifiesClause, ExpressionTranslator/*!*/ etranPre, ExpressionTranslator/*!*/ etran, ExpressionTranslator/*!*/ etranMod)
- {
- Contract.Requires(tok != null);
- Contract.Requires(modifiesClause != null);
- Contract.Requires(etranPre != null);
- Contract.Requires(etran != null);
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<BoilerplateTriple>>()));
-
- List<BoilerplateTriple> boilerplate = new List<BoilerplateTriple>();
-
- // the frame condition, which is free since it is checked with every heap update and call
- boilerplate.Add(new BoilerplateTriple(tok, true, FrameCondition(tok, modifiesClause, etranPre, etran, etranMod), null, "frame condition"));
-
- // HeapSucc(S1, S2)
- Bpl.Expr heapSucc = FunctionCall(tok, BuiltinFunction.HeapSucc, null, etranPre.HeapExpr, etran.HeapExpr);
- boilerplate.Add(new BoilerplateTriple(tok, true, heapSucc, null, "boilerplate"));
-
- return boilerplate;
- }
-
- /// <summary>
- /// There are 3 states of interest when generating a frame condition:
- /// S0. the beginning of the method/loop, which is where the modifies clause is interpreted
- /// S1. the pre-state of the two-state interval
- /// S2. the post-state of the two-state interval
- /// This method assumes that etranPre denotes S1, etran denotes S2, and that etranMod denotes S0.
- /// </summary>
- Bpl.Expr/*!*/ FrameCondition(IToken/*!*/ tok, List<FrameExpression/*!*/>/*!*/ modifiesClause, ExpressionTranslator/*!*/ etranPre, ExpressionTranslator/*!*/ etran, ExpressionTranslator/*!*/ etranMod)
- {
- Contract.Requires(tok != null);
- Contract.Requires(etran != null);
- Contract.Requires(etranPre != null);
- Contract.Requires(cce.NonNullElements(modifiesClause));
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- // generate:
- // (forall<alpha> o: ref, f: Field alpha :: { $Heap[o,f] }
- // o != null && old($Heap)[o,alloc] ==>
- // $Heap[o,f] == PreHeap[o,f] ||
- // (o,f) in modifiesClause)
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(tok, "alpha");
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$o", predef.RefType));
- Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(tok, oVar);
- Bpl.BoundVariable fVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$f", predef.FieldName(tok, alpha)));
- Bpl.IdentifierExpr f = new Bpl.IdentifierExpr(tok, fVar);
-
- Bpl.Expr heapOF = ExpressionTranslator.ReadHeap(tok, etran.HeapExpr, o, f);
- Bpl.Expr preHeapOF = ExpressionTranslator.ReadHeap(tok, etranPre.HeapExpr, o, f);
- Bpl.Expr ante = Bpl.Expr.And(Bpl.Expr.Neq(o, predef.Null), etranMod.IsAlloced(tok, o));
- Bpl.Expr consequent = Bpl.Expr.Eq(heapOF, preHeapOF);
-
- consequent = Bpl.Expr.Or(consequent, InRWClause(tok, o, f, modifiesClause, etranMod, null, null));
-
- Bpl.Trigger tr = new Bpl.Trigger(tok, true, new Bpl.ExprSeq(heapOF));
- return new Bpl.ForallExpr(tok, new Bpl.TypeVariableSeq(alpha), new Bpl.VariableSeq(oVar, fVar), null, tr, Bpl.Expr.Imp(ante, consequent));
- }
- Bpl.Expr/*!*/ FrameConditionUsingDefinedFrame(IToken/*!*/ tok, ExpressionTranslator/*!*/ etranPre, ExpressionTranslator/*!*/ etran, ExpressionTranslator/*!*/ etranMod)
- {
- Contract.Requires(tok != null);
- Contract.Requires(etran != null);
- Contract.Requires(etranPre != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- // generate:
- // (forall<alpha> o: ref, f: Field alpha :: { $Heap[o,f] }
- // o != null && old($Heap)[o,alloc] ==>
- // $Heap[o,f] == PreHeap[o,f] ||
- // $_Frame[o,f])
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(tok, "alpha");
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$o", predef.RefType));
- Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(tok, oVar);
- Bpl.BoundVariable fVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$f", predef.FieldName(tok, alpha)));
- Bpl.IdentifierExpr f = new Bpl.IdentifierExpr(tok, fVar);
-
- Bpl.Expr heapOF = ExpressionTranslator.ReadHeap(tok, etran.HeapExpr, o, f);
- Bpl.Expr preHeapOF = ExpressionTranslator.ReadHeap(tok, etranPre.HeapExpr, o, f);
- Bpl.Expr ante = Bpl.Expr.And(Bpl.Expr.Neq(o, predef.Null), etranPre.IsAlloced(tok, o));
- Bpl.Expr consequent = Bpl.Expr.Eq(heapOF, preHeapOF);
-
- consequent = Bpl.Expr.Or(consequent, Bpl.Expr.SelectTok(tok, etranMod.TheFrame(tok), o, f));
-
- Bpl.Trigger tr = new Bpl.Trigger(tok, true, new Bpl.ExprSeq(heapOF));
- return new Bpl.ForallExpr(tok, new Bpl.TypeVariableSeq(alpha), new Bpl.VariableSeq(oVar, fVar), null, tr, Bpl.Expr.Imp(ante, consequent));
- }
- // ----- Type ---------------------------------------------------------------------------------
-
- Bpl.Type TrType(Type type)
- {
- Contract.Requires(type != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.Type>() != null);
-
- while (true) {
- TypeProxy tp = type as TypeProxy;
- if (tp == null) {
- break;
- } else if (tp.T == null) {
- // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
- return predef.RefType;
- } else {
- type = tp.T;
- }
- }
-
- if (type is BoolType) {
- return Bpl.Type.Bool;
- } else if (type is IntType) {
- return Bpl.Type.Int;
- } else if (type is EverIncreasingType) {
- return Bpl.Type.Int;
- } else if (type.IsTypeParameter) {
- return predef.BoxType;
- } else if (type.IsRefType) {
- // object and class types translate to ref
- return predef.RefType;
- } else if (type.IsDatatype || type is DatatypeProxy) {
- return predef.DatatypeType;
- } else if (type is SetType) {
- return predef.SetType(Token.NoToken, predef.BoxType);
- } else if (type is MultiSetType) {
- return predef.MultiSetType(Token.NoToken, predef.BoxType);
- } else if (type is MapType) {
- return predef.MapType(Token.NoToken, predef.BoxType, predef.BoxType);
- } else if (type is SeqType) {
- return predef.SeqType(Token.NoToken, predef.BoxType);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- Bpl.TypeVariableSeq TrTypeParamDecls(List<TypeParameter/*!*/>/*!*/ tps)
- {
- Contract.Requires(cce.NonNullElements(tps));
- Contract.Ensures(Contract.Result<Bpl.TypeVariableSeq>() != null);
-
- Bpl.TypeVariableSeq typeParams = new Bpl.TypeVariableSeq();
- return typeParams;
- }
-
- // ----- Statement ----------------------------------------------------------------------------
-
- /// <summary>
- /// A ForceCheckToken is a token wrapper whose purpose is to hide inheritance.
- /// </summary>
- public class ForceCheckToken : TokenWrapper
- {
- public ForceCheckToken(IToken tok)
- : base(tok) {
- Contract.Requires(tok != null);
- }
- public static IToken Unwrap(IToken tok) {
- Contract.Requires(tok != null);
- Contract.Ensures(Contract.Result<IToken>() != null);
- var ftok = tok as ForceCheckToken;
- return ftok != null ? ftok.WrappedToken : tok;
- }
- }
-
- Bpl.PredicateCmd Assert(Bpl.IToken tok, Bpl.Expr condition, string errorMessage) {
- return Assert(tok, condition, errorMessage, tok);
- }
-
- Bpl.PredicateCmd Assert(Bpl.IToken tok, Bpl.Expr condition, string errorMessage, Bpl.IToken refinesToken) {
- Contract.Requires(tok != null);
- Contract.Requires(condition != null);
- Contract.Requires(errorMessage != null);
- Contract.Ensures(Contract.Result<Bpl.PredicateCmd>() != null);
-
- if (RefinementToken.IsInherited(refinesToken, currentModule) && (codeContext == null || !codeContext.MustReverify)) {
- // produce an assume instead
- return new Bpl.AssumeCmd(tok, condition);
- } else {
- var cmd = new Bpl.AssertCmd(ForceCheckToken.Unwrap(tok), condition);
- cmd.ErrorData = "Error: " + errorMessage;
- return cmd;
- }
- }
- Bpl.PredicateCmd AssertNS(Bpl.IToken tok, Bpl.Expr condition, string errorMessage) {
- return AssertNS(tok, condition, errorMessage, tok);
- }
- Bpl.PredicateCmd AssertNS(Bpl.IToken tok, Bpl.Expr condition, string errorMessage, Bpl.IToken refinesTok)
- {
- Contract.Requires(tok != null);
- Contract.Requires(errorMessage != null);
- Contract.Requires(condition != null);
- Contract.Ensures(Contract.Result<Bpl.PredicateCmd>() != null);
-
- if (RefinementToken.IsInherited(refinesTok, currentModule) && (codeContext == null || !codeContext.MustReverify)) {
- // produce a "skip" instead
- return new Bpl.AssumeCmd(tok, Bpl.Expr.True);
- } else {
- tok = ForceCheckToken.Unwrap(tok);
- var args = new List<object>();
- args.Add(Bpl.Expr.Literal(0));
- Bpl.QKeyValue kv = new Bpl.QKeyValue(tok, "subsumption", args, null);
- Bpl.AssertCmd cmd = new Bpl.AssertCmd(tok, condition, kv);
- cmd.ErrorData = "Error: " + errorMessage;
- return cmd;
- }
- }
-
- Bpl.PredicateCmd Assert(Bpl.IToken tok, Bpl.Expr condition, string errorMessage, Bpl.QKeyValue kv) {
- Contract.Requires(tok != null);
- Contract.Requires(errorMessage != null);
- Contract.Requires(condition != null);
- Contract.Ensures(Contract.Result<Bpl.PredicateCmd>() != null);
-
- if (RefinementToken.IsInherited(tok, currentModule) && (codeContext == null || !codeContext.MustReverify)) {
- // produce an assume instead
- return new Bpl.AssumeCmd(tok, condition, kv);
- } else {
- var cmd = new Bpl.AssertCmd(ForceCheckToken.Unwrap(tok), condition, kv);
- cmd.ErrorData = "Error: " + errorMessage;
- return cmd;
- }
- }
-
- Bpl.Ensures Ensures(IToken tok, bool free, Bpl.Expr condition, string errorMessage, string comment)
- {
- Contract.Requires(tok != null);
- Contract.Requires(condition != null);
- Contract.Ensures(Contract.Result<Bpl.Ensures>() != null);
-
- Bpl.Ensures ens = new Bpl.Ensures(ForceCheckToken.Unwrap(tok), free, condition, comment);
- if (errorMessage != null) {
- ens.ErrorData = errorMessage;
- }
- return ens;
- }
-
- Bpl.Requires Requires(IToken tok, bool free, Bpl.Expr condition, string errorMessage, string comment)
- {
- Contract.Requires(tok != null);
- Contract.Requires(condition != null);
- Bpl.Requires req = new Bpl.Requires(ForceCheckToken.Unwrap(tok), free, condition, comment);
- if (errorMessage != null) {
- req.ErrorData = errorMessage;
- }
- return req;
- }
-
- Bpl.StmtList TrStmt2StmtList(Statement block, Bpl.VariableSeq locals, ExpressionTranslator etran)
- {
- Contract.Requires(block != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
- Contract.Requires(codeContext != null && predef != null);
- Contract.Ensures(Contract.Result<Bpl.StmtList>() != null);
-
- return TrStmt2StmtList(new Bpl.StmtListBuilder(), block, locals, etran);
- }
-
- Bpl.StmtList TrStmt2StmtList(Bpl.StmtListBuilder builder, Statement block, Bpl.VariableSeq locals, ExpressionTranslator etran)
- {
- Contract.Requires(builder != null);
- Contract.Requires(block != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
- Contract.Requires(codeContext != null && predef != null);
- Contract.Ensures(Contract.Result<Bpl.StmtList>() != null);
-
- TrStmt(block, builder, locals, etran);
- return builder.Collect(block.Tok); // TODO: would be nice to have an end-curly location for "block"
- }
-
- void TrStmt(Statement stmt, Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran)
- {
- Contract.Requires(stmt != null);
- Contract.Requires(builder != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
- Contract.Requires(codeContext != null && predef != null);
- if (stmt is PredicateStmt) {
- if (stmt is AssertStmt || DafnyOptions.O.DisallowSoundnessCheating) {
- AddComment(builder, stmt, "assert statement");
- PredicateStmt s = (PredicateStmt)stmt;
- TrStmt_CheckWellformed(s.Expr, builder, locals, etran, false);
- IToken enclosingToken = null;
- if (Attributes.Contains(stmt.Attributes, "prependAssertToken")) {
- enclosingToken = stmt.Tok;
- }
- bool splitHappened;
- var ss = TrSplitExpr(s.Expr, etran, out splitHappened);
- if (!splitHappened) {
- var tok = enclosingToken == null ? s.Expr.tok : new NestedToken(enclosingToken, s.Expr.tok);
- builder.Add(Assert(tok, etran.TrExpr(s.Expr), "assertion violation", stmt.Tok));
- } else {
- foreach (var split in ss) {
- if (!split.IsFree) {
- var tok = enclosingToken == null ? split.E.tok : new NestedToken(enclosingToken, split.E.tok);
- builder.Add(AssertNS(tok, split.E, "assertion violation", stmt.Tok));
- }
- }
- builder.Add(new Bpl.AssumeCmd(stmt.Tok, etran.TrExpr(s.Expr)));
- }
- } else if (stmt is AssumeStmt) {
- AddComment(builder, stmt, "assume statement");
- AssumeStmt s = (AssumeStmt)stmt;
- TrStmt_CheckWellformed(s.Expr, builder, locals, etran, false);
- builder.Add(new Bpl.AssumeCmd(stmt.Tok, etran.TrExpr(s.Expr)));
- }
- } else if (stmt is PrintStmt) {
- AddComment(builder, stmt, "print statement");
- PrintStmt s = (PrintStmt)stmt;
- foreach (Attributes.Argument arg in s.Args) {
- if (arg.E != null) {
- TrStmt_CheckWellformed(arg.E, builder, locals, etran, false);
- }
- }
-
- } else if (stmt is BreakStmt) {
- AddComment(builder, stmt, "break statement");
- var s = (BreakStmt)stmt;
- builder.Add(new GotoCmd(s.Tok, new StringSeq("after_" + s.TargetStmt.Labels.Data.UniqueId)));
- } else if (stmt is ReturnStmt) {
- var s = (ReturnStmt)stmt;
- AddComment(builder, stmt, "return statement");
- if (s.hiddenUpdate != null) {
- TrStmt(s.hiddenUpdate, builder, locals, etran);
- }
- builder.Add(new Bpl.ReturnCmd(stmt.Tok));
- } else if (stmt is YieldStmt) {
- var s = (YieldStmt)stmt;
- AddComment(builder, s, "yield statement");
- Contract.Assert(codeContext is IteratorDecl);
- var iter = (IteratorDecl)codeContext;
- // this.ys := this.ys + [this.y];
- var th = new ThisExpr(iter.tok);
- th.Type = Resolver.GetThisType(iter.tok, iter); // resolve here
- Contract.Assert(iter.OutsFields.Count == iter.OutsHistoryFields.Count);
- for (int i = 0; i < iter.OutsFields.Count; i++) {
- var y = iter.OutsFields[i];
- var dafnyY = new FieldSelectExpr(s.Tok, th, y.Name);
- dafnyY.Field = y; dafnyY.Type = y.Type; // resolve here
- var ys = iter.OutsHistoryFields[i];
- var dafnyYs = new FieldSelectExpr(s.Tok, th, ys.Name);
- dafnyYs.Field = ys; dafnyYs.Type = ys.Type; // resolve here
- var dafnySingletonY = new SeqDisplayExpr(s.Tok, new List<Expression>() { dafnyY });
- dafnySingletonY.Type = ys.Type; // resolve here
- var rhs = new BinaryExpr(s.Tok, BinaryExpr.Opcode.Add, dafnyYs, dafnySingletonY);
- rhs.ResolvedOp = BinaryExpr.ResolvedOpcode.Concat;
- rhs.Type = ys.Type; // resolve here
- var cmd = Bpl.Cmd.SimpleAssign(s.Tok, (Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr,
- ExpressionTranslator.UpdateHeap(s.Tok, etran.HeapExpr, etran.TrExpr(th), new Bpl.IdentifierExpr(s.Tok, GetField(ys)), etran.TrExpr(rhs)));
- builder.Add(cmd);
- }
- // yieldCount := yieldCount + 1; assume yieldCount == |ys|;
- var yc = new Bpl.IdentifierExpr(s.Tok, yieldCountVariable);
- var incYieldCount = Bpl.Cmd.SimpleAssign(s.Tok, yc, Bpl.Expr.Binary(s.Tok, Bpl.BinaryOperator.Opcode.Add, yc, Bpl.Expr.Literal(1)));
- builder.Add(incYieldCount);
- builder.Add(new Bpl.AssumeCmd(s.Tok, YieldCountAssumption(iter, etran)));
- // assert YieldEnsures[subst]; // where 'subst' replaces "old(E)" with "E" being evaluated in $_OldIterHeap
- var yeEtran = new ExpressionTranslator(this, predef, etran.HeapExpr, new Bpl.IdentifierExpr(s.Tok, "$_OldIterHeap", predef.HeapType));
- foreach (var p in iter.YieldEnsures) {
- if (p.IsFree && !DafnyOptions.O.DisallowSoundnessCheating) {
- // do nothing
- } else {
- bool splitHappened; // actually, we don't care
- var ss = TrSplitExpr(p.E, yeEtran, out splitHappened);
- foreach (var split in ss) {
- if (RefinementToken.IsInherited(split.E.tok, currentModule)) {
- // this postcondition was inherited into this module, so just ignore it
- } else if (!split.IsFree) {
- var yieldToken = new NestedToken(s.Tok, split.E.tok);
- builder.Add(AssertNS(yieldToken, split.E, "possible violation of yield-ensures condition", stmt.Tok));
- }
- }
- builder.Add(new Bpl.AssumeCmd(stmt.Tok, yeEtran.TrExpr(p.E)));
- }
- }
- YieldHavoc(iter.tok, iter, builder, etran);
- builder.Add(CaptureState(s.Tok));
-
- } else if (stmt is AssignSuchThatStmt) {
- var s = (AssignSuchThatStmt)stmt;
- AddComment(builder, s, "assign-such-that statement");
- // Essentially, treat like an assert, a parallel havoc, and an assume. However, we also need to check
- // the well-formedness of the expression, which is easiest to do after the havoc. So, we do the havoc
- // first, then the well-formedness check, then the assert (unless the whole statement is an assume), and
- // finally the assume.
-
- // Here comes the havoc part
- var lhss = new List<Expression>();
- var havocRhss = new List<AssignmentRhs>();
- foreach (var lhs in s.Lhss) {
- lhss.Add(lhs.Resolved);
- havocRhss.Add(new HavocRhs(lhs.tok)); // note, a HavocRhs is constructed as already resolved
- }
- List<AssignToLhs> lhsBuilder;
- List<Bpl.IdentifierExpr> bLhss;
- Bpl.Expr[] ignore1, ignore2;
- string[] ignore3;
- ProcessLhss(lhss, false, true, builder, locals, etran, out lhsBuilder, out bLhss, out ignore1, out ignore2, out ignore3);
- ProcessRhss(lhsBuilder, bLhss, lhss, havocRhss, builder, locals, etran);
- // Here comes the well-formedness check
- TrStmt_CheckWellformed(s.Expr, builder, locals, etran, false);
- // Here comes the assert part
- if (s.AssumeToken == null) {
- var substMap = new Dictionary<IVariable, Expression>();
- var bvars = new List<BoundVar>();
- foreach (var lhs in s.Lhss) {
- var l = lhs.Resolved;
- if (l is IdentifierExpr) {
- var x = (IdentifierExpr)l;
- BoundVar bv;
- IdentifierExpr ie;
- CloneVariableAsBoundVar(x.tok, x.Var, "$as#" + x.Name, out bv, out ie);
- bvars.Add(bv);
- substMap.Add(x.Var, ie);
- } else {
- // other forms of LHSs have been ruled out by the resolver (it would be possible to
- // handle them, but it would involve heap-update expressions--the translation would take
- // effort, and it's not certain that the existential would be successful in verification).
- Contract.Assume(false); // unexpected case
- }
- }
-
- List<Tuple<List<BoundVar>, Expression>> partialGuesses = GeneratePartialGuesses(bvars, Substitute(s.Expr, null, substMap));
- Bpl.Expr w = Bpl.Expr.False;
- foreach (var tup in partialGuesses) {
- var body = etran.TrExpr(tup.Item2);
- if (tup.Item1.Count != 0) {
- var bvs = new VariableSeq();
- var typeAntecedent = etran.TrBoundVariables(tup.Item1, bvs);
- body = new Bpl.ExistsExpr(s.Tok, bvs, BplAnd(typeAntecedent, body));
- }
- w = BplOr(body, w);
- }
- builder.Add(Assert(s.Tok, w, "cannot establish the existence of LHS values that satisfy the such-that predicate"));
- }
- // End by doing the assume
- builder.Add(new Bpl.AssumeCmd(s.Tok, etran.TrExpr(s.Expr)));
- builder.Add(CaptureState(s.Tok)); // just do one capture state--here, at the very end (that is, don't do one before the assume)
-
- } else if (stmt is UpdateStmt) {
- var s = (UpdateStmt)stmt;
- // This UpdateStmt can be single-target assignment, a multi-assignment, a call statement, or
- // an array-range update. Handle the multi-assignment here and handle the others as for .ResolvedStatements.
- var resolved = s.ResolvedStatements;
- if (resolved.Count == 1) {
- TrStmt(resolved[0], builder, locals, etran);
- } else {
- AddComment(builder, s, "update statement");
- var lhss = new List<Expression>();
- foreach (var lhs in s.Lhss) {
- lhss.Add(lhs.Resolved);
- }
- List<AssignToLhs> lhsBuilder;
- List<Bpl.IdentifierExpr> bLhss;
- // note: because we have more than one expression, we always must assign to Boogie locals in a two
- // phase operation. Thus rhssCanAffectPreviouslyKnownExpressions is just true.
- Contract.Assert(1 < lhss.Count);
-
- Bpl.Expr[] lhsObjs, lhsFields;
- string[] lhsNames;
- ProcessLhss(lhss, true, false, builder, locals, etran, out lhsBuilder, out bLhss, out lhsObjs, out lhsFields, out lhsNames);
- // We know that, because the translation saves to a local variable, that the RHS always need to
- // generate a new local, i.e. bLhss is just all nulls.
- Contract.Assert(Contract.ForAll(bLhss, lhs => lhs == null));
- // This generates the assignments, and gives them to us as finalRhss.
- var finalRhss = ProcessUpdateAssignRhss(lhss, s.Rhss, builder, locals, etran);
- // ProcessLhss has laid down framing conditions and the ProcessUpdateAssignRhss will check subranges (nats),
- // but we need to generate the distinctness condition (two LHS are equal only when the RHS is also
- // equal). We need both the LHS and the RHS to do this, which is why we need to do it here.
- CheckLhssDistinctness(finalRhss, lhss, builder, etran, lhsObjs, lhsFields, lhsNames);
- // Now actually perform the assignments to the LHS.
- for (int i = 0; i < lhss.Count; i++) {
- lhsBuilder[i](finalRhss[i], builder, etran);
- }
- builder.Add(CaptureState(s.Tok));
- }
-
- } else if (stmt is AssignStmt) {
- AddComment(builder, stmt, "assignment statement");
- AssignStmt s = (AssignStmt)stmt;
- TrAssignment(stmt.Tok, s.Lhs.Resolved, s.Rhs, builder, locals, etran);
- } else if (stmt is VarDecl) {
- AddComment(builder, stmt, "var-declaration statement");
- VarDecl s = (VarDecl)stmt;
- Bpl.Type varType = TrType(s.Type);
- Bpl.Expr wh = GetWhereClause(stmt.Tok, new Bpl.IdentifierExpr(stmt.Tok, s.UniqueName, varType), s.Type, etran);
- Bpl.LocalVariable var = new Bpl.LocalVariable(stmt.Tok, new Bpl.TypedIdent(stmt.Tok, s.UniqueName, varType, wh));
- locals.Add(var);
-
- } else if (stmt is CallStmt) {
- AddComment(builder, stmt, "call statement");
- TrCallStmt((CallStmt)stmt, builder, locals, etran, null);
-
- } else if (stmt is BlockStmt) {
- foreach (Statement ss in ((BlockStmt)stmt).Body) {
- TrStmt(ss, builder, locals, etran);
- if (ss.Labels != null) {
- builder.AddLabelCmd("after_" + ss.Labels.Data.UniqueId);
- }
- }
- } else if (stmt is IfStmt) {
- AddComment(builder, stmt, "if statement");
- IfStmt s = (IfStmt)stmt;
- Bpl.Expr guard;
- if (s.Guard == null) {
- guard = null;
- } else {
- TrStmt_CheckWellformed(s.Guard, builder, locals, etran, true);
- guard = etran.TrExpr(s.Guard);
- }
- Bpl.StmtListBuilder b = new Bpl.StmtListBuilder();
- Bpl.StmtList thn = TrStmt2StmtList(b, s.Thn, locals, etran);
- Bpl.StmtList els;
- Bpl.IfCmd elsIf = null;
- if (s.Els == null) {
- b = new Bpl.StmtListBuilder();
- els = b.Collect(s.Tok);
- } else {
- b = new Bpl.StmtListBuilder();
- els = TrStmt2StmtList(b, s.Els, locals, etran);
- if (els.BigBlocks.Count == 1) {
- Bpl.BigBlock bb = els.BigBlocks[0];
- if (bb.LabelName == null && bb.simpleCmds.Length == 0 && bb.ec is Bpl.IfCmd) {
- elsIf = (Bpl.IfCmd)bb.ec;
- els = null;
- }
- }
- }
- builder.Add(new Bpl.IfCmd(stmt.Tok, guard, thn, elsIf, els));
-
- } else if (stmt is AlternativeStmt) {
- AddComment(builder, stmt, "alternative statement");
- var s = (AlternativeStmt)stmt;
- var elseCase = Assert(s.Tok, Bpl.Expr.False, "alternative cases fail to cover all possibilties");
- TrAlternatives(s.Alternatives, elseCase, null, builder, locals, etran);
-
- } else if (stmt is WhileStmt) {
- AddComment(builder, stmt, "while statement");
- var s = (WhileStmt)stmt;
- TrLoop(s, s.Guard,
- delegate(Bpl.StmtListBuilder bld, ExpressionTranslator e) { TrStmt(s.Body, bld, locals, e); },
- builder, locals, etran);
-
- } else if (stmt is AlternativeLoopStmt) {
- AddComment(builder, stmt, "alternative loop statement");
- var s = (AlternativeLoopStmt)stmt;
- var tru = new LiteralExpr(s.Tok, true);
- tru.Type = Type.Bool; // resolve here
- TrLoop(s, tru,
- delegate(Bpl.StmtListBuilder bld, ExpressionTranslator e) { TrAlternatives(s.Alternatives, null, new Bpl.BreakCmd(s.Tok, null), bld, locals, e); },
- builder, locals, etran);
-
- } else if (stmt is ParallelStmt) {
- AddComment(builder, stmt, "parallel statement");
- var s = (ParallelStmt)stmt;
- if (s.Kind == ParallelStmt.ParBodyKind.Assign) {
- Contract.Assert(s.Ens.Count == 0);
- if (s.BoundVars.Count == 0) {
- TrStmt(s.Body, builder, locals, etran);
- } else {
- var s0 = (AssignStmt)s.S0;
- var definedness = new Bpl.StmtListBuilder();
- var updater = new Bpl.StmtListBuilder();
- TrParallelAssign(s, s0, definedness, updater, locals, etran);
- // All done, so put the two pieces together
- builder.Add(new Bpl.IfCmd(s.Tok, null, definedness.Collect(s.Tok), null, updater.Collect(s.Tok)));
- builder.Add(CaptureState(stmt.Tok));
- }
-
- } else if (s.Kind == ParallelStmt.ParBodyKind.Call) {
- Contract.Assert(s.Ens.Count == 0);
- if (s.BoundVars.Count == 0) {
- TrStmt(s.Body, builder, locals, etran);
- } else {
- var s0 = (CallStmt)s.S0;
- var definedness = new Bpl.StmtListBuilder();
- var exporter = new Bpl.StmtListBuilder();
- TrParallelCall(s.Tok, s.BoundVars, s.Range, null, s0, definedness, exporter, locals, etran);
- // All done, so put the two pieces together
- builder.Add(new Bpl.IfCmd(s.Tok, null, definedness.Collect(s.Tok), null, exporter.Collect(s.Tok)));
- builder.Add(CaptureState(stmt.Tok));
- }
-
- } else if (s.Kind == ParallelStmt.ParBodyKind.Proof) {
- var definedness = new Bpl.StmtListBuilder();
- var exporter = new Bpl.StmtListBuilder();
- TrParallelProof(s, definedness, exporter, locals, etran);
- // All done, so put the two pieces together
- builder.Add(new Bpl.IfCmd(s.Tok, null, definedness.Collect(s.Tok), null, exporter.Collect(s.Tok)));
- builder.Add(CaptureState(stmt.Tok));
-
- } else {
- Contract.Assert(false); // unexpected kind
- }
-
- } else if (stmt is CalcStmt) {
- /* Translate into:
- if (*) {
- // line well-formedness checks;
- } else if (*) {
- hint0;
- assert t0 op t1;
- assume false;
- } else if (*) { ...
- } else if (*) {
- hint<n-1>;
- assert t<n-1> op tn;
- assume false;
- }
- assume t0 op tn;
- */
- var s = (CalcStmt)stmt;
- Contract.Assert(s.Steps.Count == s.Hints.Count); // established by the resolver
- AddComment(builder, stmt, "calc statement");
- if (s.Lines.Count > 0) {
- Bpl.IfCmd ifCmd = null;
- Bpl.StmtListBuilder b;
- // check steps:
- for (int i = s.Steps.Count; 0 <= --i; ) {
- b = new Bpl.StmtListBuilder();
- TrStmt(s.Hints[i], b, locals, etran);
- bool splitHappened;
- var ss = TrSplitExpr(s.Steps[i], etran, out splitHappened);
- if (!splitHappened) {
- b.Add(AssertNS(s.Lines[i + 1].tok, etran.TrExpr(s.Steps[i]), "the calculation step between the previous line and this line might not hold"));
- } else {
- foreach (var split in ss) {
- if (!split.IsFree) {
- b.Add(AssertNS(s.Lines[i + 1].tok, split.E, "the calculation step between the previous line and this line might not hold"));
- }
- }
- }
- b.Add(new Bpl.AssumeCmd(s.Tok, Bpl.Expr.False));
- ifCmd = new Bpl.IfCmd(s.Tok, null, b.Collect(s.Tok), ifCmd, null);
- }
- // check well-formedness of lines:
- b = new Bpl.StmtListBuilder();
- foreach (var e in s.Lines) {
- TrStmt_CheckWellformed(e, b, locals, etran, false);
- }
- b.Add(new Bpl.AssumeCmd(s.Tok, Bpl.Expr.False));
- ifCmd = new Bpl.IfCmd(s.Tok, null, b.Collect(s.Tok), ifCmd, null);
- builder.Add(ifCmd);
- // assume result:
- if (s.Steps.Count > 0) {
- Contract.Assert(s.Result != null); // established by the resolver
- builder.Add(new Bpl.AssumeCmd(s.Tok, etran.TrExpr(s.Result)));
- }
- }
-
- } else if (stmt is MatchStmt) {
- var s = (MatchStmt)stmt;
- TrStmt_CheckWellformed(s.Source, builder, locals, etran, true);
- Bpl.Expr source = etran.TrExpr(s.Source);
-
- var b = new Bpl.StmtListBuilder();
- b.Add(new Bpl.AssumeCmd(stmt.Tok, Bpl.Expr.False));
- Bpl.StmtList els = b.Collect(stmt.Tok);
- Bpl.IfCmd ifCmd = null;
- foreach (var missingCtor in s.MissingCases) {
- // havoc all bound variables
- b = new Bpl.StmtListBuilder();
- VariableSeq newLocals = new VariableSeq();
- Bpl.Expr r = CtorInvocation(s.Tok, missingCtor, etran, newLocals, b);
- locals.AddRange(newLocals);
-
- if (newLocals.Length != 0) {
- Bpl.IdentifierExprSeq havocIds = new Bpl.IdentifierExprSeq();
- foreach (Variable local in newLocals) {
- havocIds.Add(new Bpl.IdentifierExpr(local.tok, local));
- }
- builder.Add(new Bpl.HavocCmd(s.Tok, havocIds));
- }
- b.Add(Assert(s.Tok, Bpl.Expr.False, "missing case in case statement: " + missingCtor.Name));
-
- Bpl.Expr guard = Bpl.Expr.Eq(source, r);
- ifCmd = new Bpl.IfCmd(s.Tok, guard, b.Collect(s.Tok), ifCmd, els);
- els = null;
- }
- for (int i = s.Cases.Count; 0 <= --i; ) {
- var mc = (MatchCaseStmt)s.Cases[i];
- // havoc all bound variables
- b = new Bpl.StmtListBuilder();
- VariableSeq newLocals = new VariableSeq();
- Bpl.Expr r = CtorInvocation(mc, etran, newLocals, b);
- locals.AddRange(newLocals);
-
- if (newLocals.Length != 0) {
- Bpl.IdentifierExprSeq havocIds = new Bpl.IdentifierExprSeq();
- foreach (Variable local in newLocals) {
- havocIds.Add(new Bpl.IdentifierExpr(local.tok, local));
- }
- builder.Add(new Bpl.HavocCmd(mc.tok, havocIds));
- }
-
- // translate the body into b
- foreach (Statement ss in mc.Body) {
- TrStmt(ss, b, locals, etran);
- }
-
- Bpl.Expr guard = Bpl.Expr.Eq(source, r);
- ifCmd = new Bpl.IfCmd(mc.tok, guard, b.Collect(mc.tok), ifCmd, els);
- els = null;
- }
- Contract.Assert(ifCmd != null); // follows from the fact that s.Cases.Count + s.MissingCases.Count != 0.
- builder.Add(ifCmd);
-
- } else if (stmt is ConcreteSyntaxStatement) {
- var s = (ConcreteSyntaxStatement)stmt;
- foreach (var ss in s.ResolvedStatements) {
- TrStmt(ss, builder, locals, etran);
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
- }
- }
-
- /// <summary>
- /// Generate:
- /// havoc Heap \ {this} \ _reads \ _new;
- /// assume this.Valid();
- /// assume YieldRequires;
- /// $_OldIterHeap := Heap;
- /// </summary>
- void YieldHavoc(IToken tok, IteratorDecl iter, StmtListBuilder builder, ExpressionTranslator etran) {
- Contract.Requires(tok != null);
- Contract.Requires(iter != null);
- Contract.Requires(builder != null);
- Contract.Requires(etran != null);
- // havoc Heap \ {this} \ _reads \ _new;
- var th = new ThisExpr(tok);
- th.Type = Resolver.GetThisType(tok, iter); // resolve here
- var rds = new FieldSelectExpr(tok, th, iter.Member_Reads.Name);
- rds.Field = iter.Member_Reads; // resolve here
- rds.Type = iter.Member_Reads.Type; // resolve here
- var nw = new FieldSelectExpr(tok, th, iter.Member_New.Name);
- nw.Field = iter.Member_New; // resolve here
- nw.Type = iter.Member_New.Type; // resolve here
- builder.Add(new Bpl.CallCmd(tok, "$YieldHavoc",
- new List<Bpl.Expr>() { etran.TrExpr(th), etran.TrExpr(rds), etran.TrExpr(nw) },
- new List<Bpl.IdentifierExpr>()));
- // assume YieldRequires;
- foreach (var p in iter.YieldRequires) {
- builder.Add(new Bpl.AssumeCmd(tok, etran.TrExpr(p.E)));
- }
- // $_OldIterHeap := Heap;
- builder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, "$_OldIterHeap", predef.HeapType), etran.HeapExpr));
- }
-
- List<Tuple<List<BoundVar>, Expression>> GeneratePartialGuesses(List<BoundVar> bvars, Expression expression) {
- if (bvars.Count == 0) {
- var tup = new Tuple<List<BoundVar>, Expression>(new List<BoundVar>(), expression);
- return new List<Tuple<List<BoundVar>, Expression>>() { tup };
- }
- var result = new List<Tuple<List<BoundVar>, Expression>>();
- var x = bvars[0];
- var otherBvars = bvars.GetRange(1, bvars.Count - 1);
- foreach (var tup in GeneratePartialGuesses(otherBvars, expression)) {
- // in the special case that x does not even occur in expression, we can just ignore x
- if (!ContainsFreeVariable(tup.Item2, false, x)) {
- result.Add(tup);
- continue;
- }
- // one possible result is to quantify over all the variables
- var vs = new List<BoundVar>() { x };
- vs.AddRange(tup.Item1);
- result.Add(new Tuple<List<BoundVar>, Expression>(vs, tup.Item2));
- // other possibilities involve guessing a value for x
- foreach (var guess in GuessWitnesses(x, tup.Item2)) {
- var substMap = new Dictionary<IVariable, Expression>();
- substMap.Add(x, guess);
- result.Add(new Tuple<List<BoundVar>, Expression>(tup.Item1, Substitute(tup.Item2, null, substMap)));
- }
- }
- return result;
- }
-
- IEnumerable<Expression> GuessWitnesses(BoundVar x, Expression expr) {
- Contract.Requires(x != null);
- Contract.Requires(expr != null);
- var lookForBounds = false;
- if (x.Type is BoolType) {
- var lit = new LiteralExpr(x.tok, false);
- lit.Type = Type.Bool; // resolve here
- yield return lit;
- lit = new LiteralExpr(x.tok, true);
- lit.Type = Type.Bool; // resolve here
- yield return lit;
- } else if (x.Type.IsRefType) {
- var lit = new LiteralExpr(x.tok);
- lit.Type = x.Type;
- yield return lit;
- } else if (x.Type.IsIndDatatype) {
- var dt = x.Type.AsIndDatatype;
- Expression zero = Zero(x.tok, x.Type);
- if (zero != null) {
- yield return zero;
- }
- } else if (x.Type is SetType) {
- var empty = new SetDisplayExpr(x.tok, new List<Expression>());
- empty.Type = x.Type;
- yield return empty;
- lookForBounds = true;
- } else if (x.Type is MultiSetType) {
- var empty = new MultiSetDisplayExpr(x.tok, new List<Expression>());
- empty.Type = x.Type;
- yield return empty;
- lookForBounds = true;
- } else if (x.Type is SeqType) {
- var empty = new SeqDisplayExpr(x.tok, new List<Expression>());
- empty.Type = x.Type;
- yield return empty;
- lookForBounds = true;
- } else if (x.Type is IntType) {
- var lit = new LiteralExpr(x.tok, 0);
- lit.Type = Type.Int; // resolve here
- yield return lit;
- lookForBounds = true;
- }
- if (lookForBounds) {
- var missingBounds = new List<BoundVar>();
- var bounds = Resolver.DiscoverBounds(x.tok, new List<BoundVar>() { x }, expr, true, true, missingBounds);
- if (missingBounds.Count == 0) {
- foreach (var bound in bounds) {
- if (bound is ComprehensionExpr.IntBoundedPool) {
- var bnd = (ComprehensionExpr.IntBoundedPool)bound;
- if (bnd.LowerBound != null) yield return bnd.LowerBound;
- if (bnd.UpperBound != null) yield return Resolver.Minus(bnd.UpperBound, 1);
- } else if (bound is ComprehensionExpr.SuperSetBoundedPool) {
- var bnd = (ComprehensionExpr.SuperSetBoundedPool)bound;
- yield return bnd.LowerBound;
- }
- }
- }
- }
- }
-
- /// <summary>
- /// Return a zero-equivalent value for "typ", or return null (for any reason whatsoever).
- /// </summary>
- Expression Zero(Bpl.IToken tok, Type typ) {
- Contract.Requires(tok != null);
- Contract.Requires(typ != null);
- return null; // TODO: this can be improved
- }
-
- void TrParallelAssign(ParallelStmt s, AssignStmt s0,
- Bpl.StmtListBuilder definedness, Bpl.StmtListBuilder updater, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- // The statement:
- // parallel (x,y | Range(x,y)) {
- // (a) E(x,y) . f := G(x,y);
- // (b) A(x,y) [ I0(x,y), I1(x,y), ... ] := G(x,y);
- // }
- // translate into:
- // if (*) {
- // // check definedness of Range
- // var x,y;
- // havoc x,y;
- // CheckWellformed( Range );
- // assume Range;
- // // check definedness of the other expressions
- // (a)
- // CheckWellformed( E.F );
- // check that E.f is in the modifies frame;
- // CheckWellformed( G );
- // check nat restrictions for the RHS
- // (b)
- // CheckWellformed( A[I0,I1,...] );
- // check that A[I0,I1,...] is in the modifies frame;
- // CheckWellformed( G );
- // check nat restrictions for the RHS
- // // check for duplicate LHSs
- // var x', y';
- // havoc x', y';
- // assume Range[x,y := x',y'];
- // assume !(x == x' && y == y');
- // (a)
- // assert E(x,y) != E(x',y');
- // (b)
- // assert !( A(x,y)==A(x',y') && I0(x,y)==I0(x',y') && I1(x,y)==I1(x',y') && ... );
- //
- // assume false;
- //
- // } else {
- // var oldHeap := $Heap;
- // havoc $Heap;
- // assume $HeapSucc(oldHeap, $Heap);
- // (a)
- // assume (forall<alpha> o: ref, F: Field alpha ::
- // $Heap[o,F] = oldHeap[o,F] ||
- // (exists x,y :: Range(x,y) && o == E(x,y) && F = f));
- // assume (forall x,y :: Range ==> $Heap[ E[$Heap:=oldHeap], F] == G[$Heap:=oldHeap]);
- // (b)
- // assume (forall<alpha> o: ref, F: Field alpha ::
- // $Heap[o,F] = oldHeap[o,F] ||
- // (exists x,y :: Range(x,y) && o == A(x,y) && F = Index(I0,I1,...)));
- // assume (forall x,y :: Range ==> $Heap[ A[$Heap:=oldHeap], Index(I0,I1,...)] == G[$Heap:=oldHeap]);
- // }
-
- var substMap = SetupBoundVarsAsLocals(s.BoundVars, definedness, locals, etran);
- Expression range = Substitute(s.Range, null, substMap);
- TrStmt_CheckWellformed(range, definedness, locals, etran, false);
- definedness.Add(new Bpl.AssumeCmd(s.Range.tok, etran.TrExpr(range)));
-
- var lhs = Substitute(s0.Lhs.Resolved, null, substMap);
- TrStmt_CheckWellformed(lhs, definedness, locals, etran, false);
- Bpl.Expr obj, F;
- string description = GetObjFieldDetails(lhs, etran, out obj, out F);
- definedness.Add(Assert(lhs.tok, Bpl.Expr.SelectTok(lhs.tok, etran.TheFrame(lhs.tok), obj, F),
- "assignment may update " + description + " not in the enclosing context's modifies clause"));
- if (s0.Rhs is ExprRhs) {
- var r = (ExprRhs)s0.Rhs;
- var rhs = Substitute(r.Expr, null, substMap);
- TrStmt_CheckWellformed(rhs, definedness, locals, etran, false);
- // check nat restrictions for the RHS
- Type lhsType;
- if (lhs is FieldSelectExpr) {
- lhsType = ((FieldSelectExpr)lhs).Type;
- } else if (lhs is SeqSelectExpr) {
- lhsType = ((SeqSelectExpr)lhs).Type;
- } else {
- lhsType = ((MultiSelectExpr)lhs).Type;
- }
- var translatedRhs = etran.TrExpr(rhs);
- CheckSubrange(r.Tok, translatedRhs, lhsType, definedness);
- if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- Check_NewRestrictions(fse.tok, obj, fse.Field, translatedRhs, definedness, etran);
- }
- }
-
- // check for duplicate LHSs
- var substMapPrime = SetupBoundVarsAsLocals(s.BoundVars, definedness, locals, etran);
- var lhsPrime = Substitute(s0.Lhs.Resolved, null, substMapPrime);
- range = Substitute(s.Range, null, substMapPrime);
- definedness.Add(new Bpl.AssumeCmd(range.tok, etran.TrExpr(range)));
- // assume !(x == x' && y == y');
- Bpl.Expr eqs = Bpl.Expr.True;
- foreach (var bv in s.BoundVars) {
- var x = substMap[bv];
- var xPrime = substMapPrime[bv];
- // TODO: in the following line, is the term equality okay, or does it have to include things like Set#Equal sometimes too?
- eqs = BplAnd(eqs, Bpl.Expr.Eq(etran.TrExpr(x), etran.TrExpr(xPrime)));
- }
- definedness.Add(new Bpl.AssumeCmd(s.Tok, Bpl.Expr.Not(eqs)));
- Bpl.Expr objPrime, FPrime;
- GetObjFieldDetails(lhsPrime, etran, out objPrime, out FPrime);
- definedness.Add(Assert(s0.Tok,
- Bpl.Expr.Or(Bpl.Expr.Neq(obj, objPrime), Bpl.Expr.Neq(F, FPrime)),
- "left-hand sides for different parallel-statement bound variables may refer to the same location"));
-
- definedness.Add(new Bpl.AssumeCmd(s.Tok, Bpl.Expr.False));
-
- // Now for the translation of the update itself
-
- Bpl.IdentifierExpr prevHeap = GetPrevHeapVar_IdExpr(s.Tok, locals);
- var prevEtran = new ExpressionTranslator(this, predef, prevHeap);
- updater.Add(Bpl.Cmd.SimpleAssign(s.Tok, prevHeap, etran.HeapExpr));
- updater.Add(new Bpl.HavocCmd(s.Tok, new Bpl.IdentifierExprSeq((Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr)));
- updater.Add(new Bpl.AssumeCmd(s.Tok, FunctionCall(s.Tok, BuiltinFunction.HeapSucc, null, prevHeap, etran.HeapExpr)));
-
- // Here comes:
- // assume (forall<alpha> o: ref, f: Field alpha ::
- // $Heap[o,f] = oldHeap[o,f] ||
- // (exists x,y :: Range(x,y)[$Heap:=oldHeap] &&
- // o == Object(x,y)[$Heap:=oldHeap] && f == Field(x,y)[$Heap:=oldHeap]));
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(s.Tok, "alpha");
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$o", predef.RefType));
- Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(s.Tok, oVar);
- Bpl.BoundVariable fVar = new Bpl.BoundVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$f", predef.FieldName(s.Tok, alpha)));
- Bpl.IdentifierExpr f = new Bpl.IdentifierExpr(s.Tok, fVar);
- Bpl.Expr heapOF = ExpressionTranslator.ReadHeap(s.Tok, etran.HeapExpr, o, f);
- Bpl.Expr oldHeapOF = ExpressionTranslator.ReadHeap(s.Tok, prevHeap, o, f);
- Bpl.VariableSeq xBvars = new Bpl.VariableSeq();
- var xBody = etran.TrBoundVariables(s.BoundVars, xBvars);
- xBody = BplAnd(xBody, prevEtran.TrExpr(s.Range));
- Bpl.Expr xObj, xField;
- GetObjFieldDetails(s0.Lhs.Resolved, prevEtran, out xObj, out xField);
- xBody = BplAnd(xBody, Bpl.Expr.Eq(o, xObj));
- xBody = BplAnd(xBody, Bpl.Expr.Eq(f, xField));
- Bpl.Expr xObjField = new Bpl.ExistsExpr(s.Tok, xBvars, xBody);
- Bpl.Expr body = Bpl.Expr.Or(Bpl.Expr.Eq(heapOF, oldHeapOF), xObjField);
- Bpl.Expr qq = new Bpl.ForallExpr(s.Tok, new Bpl.TypeVariableSeq(alpha), new Bpl.VariableSeq(oVar, fVar), body);
- updater.Add(new Bpl.AssumeCmd(s.Tok, qq));
-
- if (s0.Rhs is ExprRhs) {
- // assume (forall x,y :: Range(x,y)[$Heap:=oldHeap] ==>
- // $Heap[ Object(x,y)[$Heap:=oldHeap], Field(x,y)[$Heap:=oldHeap] ] == G[$Heap:=oldHeap] ));
- xBvars = new Bpl.VariableSeq();
- Bpl.Expr xAnte = etran.TrBoundVariables(s.BoundVars, xBvars);
- xAnte = BplAnd(xAnte, prevEtran.TrExpr(s.Range));
- var rhs = ((ExprRhs)s0.Rhs).Expr;
- var g = prevEtran.TrExpr(rhs);
- GetObjFieldDetails(s0.Lhs.Resolved, prevEtran, out xObj, out xField);
- var xHeapOF = ExpressionTranslator.ReadHeap(s.Tok, etran.HeapExpr, xObj, xField);
-
- Type lhsType;
- if (lhs is FieldSelectExpr) {
- lhsType = ((FieldSelectExpr)lhs).Type;
- } else {
- lhsType = null;
- }
- g = etran.CondApplyBox(rhs.tok, g, rhs.Type, lhsType);
-
- qq = new Bpl.ForallExpr(s.Tok, xBvars, Bpl.Expr.Imp(xAnte, Bpl.Expr.Eq(xHeapOF, g)));
- updater.Add(new Bpl.AssumeCmd(s.Tok, qq));
- }
- }
-
- delegate Bpl.Expr ExpressionConverter(Dictionary<IVariable, Expression> substMap, ExpressionTranslator etran);
-
- void TrParallelCall(IToken tok, List<BoundVar> boundVars, Expression range, ExpressionConverter additionalRange, CallStmt s0,
- Bpl.StmtListBuilder definedness, Bpl.StmtListBuilder exporter, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(tok != null);
- Contract.Requires(boundVars != null);
- Contract.Requires(range != null);
- // additionalRange is allowed to be null
- Contract.Requires(s0 != null);
- // definedness is allowed to be null
- Contract.Requires(exporter != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
-
- // Translate:
- // parallel (x,y | Range(x,y)) {
- // E(x,y) . M( Args(x,y) );
- // }
- // as:
- // if (*) {
- // var x,y;
- // havoc x,y;
- // CheckWellformed( Range );
- // assume Range(x,y);
- // assume additionalRange;
- // Tr( Call );
- // assume false;
- // } else {
- // initHeap := $Heap;
- // advance $Heap, Tick;
- // assume (forall x,y :: (Range(x,y) && additionalRange)[INIT] &&
- // ==> Post[old($Heap) := initHeap]( E(x,y)[INIT], Args(x,y)[INIT] ));
- // }
- // where Post(this,args) is the postcondition of method M and
- // INIT is the substitution [old($Heap),$Heap := old($Heap),initHeap].
-
- if (definedness != null) {
- // Note, it would be nicer (and arguably more appropriate) to do a SetupBoundVarsAsLocals
- // here (rather than a TrBoundVariables). However, there is currently no way to apply
- // a substMap to a statement (in particular, to s.Body), so that doesn't work here.
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- var ante = etran.TrBoundVariables(boundVars, bvars, true);
- locals.AddRange(bvars);
- var havocIds = new Bpl.IdentifierExprSeq();
- foreach (Bpl.Variable bv in bvars) {
- havocIds.Add(new Bpl.IdentifierExpr(tok, bv));
- }
- definedness.Add(new Bpl.HavocCmd(tok, havocIds));
- definedness.Add(new Bpl.AssumeCmd(tok, ante));
- TrStmt_CheckWellformed(range, definedness, locals, etran, false);
- definedness.Add(new Bpl.AssumeCmd(range.tok, etran.TrExpr(range)));
- if (additionalRange != null) {
- var es = additionalRange(new Dictionary<IVariable, Expression>(), etran);
- definedness.Add(new Bpl.AssumeCmd(es.tok, es));
- }
-
- TrStmt(s0, definedness, locals, etran);
-
- definedness.Add(new Bpl.AssumeCmd(tok, Bpl.Expr.False));
- }
-
- // Now for the other branch, where the postcondition of the call is exported.
- {
- var initHeapVar = new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, "$initHeapParallelStmt#" + otherTmpVarCount, predef.HeapType));
- otherTmpVarCount++;
- locals.Add(initHeapVar);
- var initHeap = new Bpl.IdentifierExpr(tok, initHeapVar);
- var initEtran = new ExpressionTranslator(this, predef, initHeap, etran.Old.HeapExpr);
- // initHeap := $Heap;
- exporter.Add(Bpl.Cmd.SimpleAssign(tok, initHeap, etran.HeapExpr));
- if (s0.Method.Ens.Exists(ens => MentionsOldState(ens.E))) {
- var heapIdExpr = (Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr;
- // advance $Heap, Tick;
- exporter.Add(new Bpl.HavocCmd(tok, new Bpl.IdentifierExprSeq(heapIdExpr, etran.Tick())));
- foreach (BoilerplateTriple tri in GetTwoStateBoilerplate(tok, new List<FrameExpression>(), initEtran, etran, initEtran)) {
- if (tri.IsFree) {
- exporter.Add(new Bpl.AssumeCmd(tok, tri.Expr));
- }
- }
- if (codeContext is IteratorDecl) {
- var iter = (IteratorDecl)codeContext;
- RecordNewObjectsIn_New(tok, iter, initHeap, heapIdExpr, exporter, locals, etran);
- }
- } else {
- // As an optimization, create the illusion that the $Heap is unchanged by the parallel body.
- exporter.Add(new Bpl.HavocCmd(tok, new Bpl.IdentifierExprSeq(etran.Tick())));
- }
-
- var bvars = new Bpl.VariableSeq();
- Dictionary<IVariable, Expression> substMap;
- var ante = initEtran.TrBoundVariablesRename(boundVars, bvars, out substMap);
- ante = BplAnd(ante, initEtran.TrExpr(Substitute(range, null, substMap)));
- if (additionalRange != null) {
- ante = BplAnd(ante, additionalRange(substMap, initEtran));
- }
-
- // Note, in the following, we need to do a bit of a song and dance. The actual arguements of the
- // call should be translated using "initEtran", whereas the method postcondition should be translated
- // using "callEtran". To accomplish this, we translate the argument and then tuck the resulting
- // Boogie expressions into BoogieExprWrappers that are used in the DafnyExpr-to-DafnyExpr substitution.
- // TODO
- var argsSubstMap = new Dictionary<IVariable, Expression>(); // maps formal arguments to actuals
- Contract.Assert(s0.Method.Ins.Count == s0.Args.Count);
- for (int i = 0; i < s0.Method.Ins.Count; i++) {
- var arg = Substitute(s0.Args[i], null, substMap); // substitute the renamed bound variables for the declared ones
- argsSubstMap.Add(s0.Method.Ins[i], new BoogieWrapper(initEtran.TrExpr(arg), s0.Args[i].Type));
- }
- var receiver = new BoogieWrapper(initEtran.TrExpr(Substitute(s0.Receiver, null, substMap)), s0.Receiver.Type);
- var callEtran = new ExpressionTranslator(this, predef, etran.HeapExpr, initHeap);
- Bpl.Expr post = Bpl.Expr.True;
- foreach (var ens in s0.Method.Ens) {
- var p = Substitute(ens.E, receiver, argsSubstMap); // substitute the call's actuals for the method's formals
- post = BplAnd(post, callEtran.TrExpr(p));
- }
-
- Bpl.Expr qq = new Bpl.ForallExpr(tok, bvars, Bpl.Expr.Imp(ante, post));
- exporter.Add(new Bpl.AssumeCmd(tok, qq));
- }
- }
-
- void RecordNewObjectsIn_New(IToken tok, IteratorDecl iter, Bpl.Expr initHeap, Bpl.IdentifierExpr currentHeap,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(tok != null);
- Contract.Requires(iter != null);
- Contract.Requires(initHeap != null);
- Contract.Requires(currentHeap != null);
- Contract.Requires(builder != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
- // Add all newly allocated objects to the set this._new
- var updatedSet = new Bpl.LocalVariable(iter.tok, new Bpl.TypedIdent(iter.tok, "$iter_newUpdate" + otherTmpVarCount, predef.SetType(iter.tok, predef.BoxType)));
- otherTmpVarCount++;
- locals.Add(updatedSet);
- var updatedSetIE = new Bpl.IdentifierExpr(iter.tok, updatedSet);
- // call $iter_newUpdate := $IterCollectNewObjects(initHeap, $Heap, this, _new);
- var th = new Bpl.IdentifierExpr(iter.tok, etran.This, predef.RefType);
- var nwField = new Bpl.IdentifierExpr(tok, GetField(iter.Member_New));
- Bpl.Cmd cmd = new CallCmd(iter.tok, "$IterCollectNewObjects",
- new List<Bpl.Expr>() { initHeap, etran.HeapExpr, th, nwField },
- new List<Bpl.IdentifierExpr>() { updatedSetIE });
- builder.Add(cmd);
- // $Heap[this, _new] := $iter_newUpdate;
- cmd = Bpl.Cmd.SimpleAssign(iter.tok, currentHeap, ExpressionTranslator.UpdateHeap(iter.tok, currentHeap, th, nwField, updatedSetIE));
- builder.Add(cmd);
- }
-
- void TrParallelProof(ParallelStmt s, Bpl.StmtListBuilder definedness, Bpl.StmtListBuilder exporter, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- // Translate:
- // parallel (x,y | Range(x,y))
- // ensures Post(x,y);
- // {
- // Body;
- // }
- // as:
- // if (*) {
- // var x,y;
- // havoc x,y;
- // CheckWellformed( Range );
- // assume Range(x,y);
- // Tr( Body );
- // CheckWellformed( Post );
- // assert Post;
- // assume false;
- // } else {
- // initHeap := $Heap;
- // advance $Heap, Tick;
- // assume (forall x,y :: Range(x,y)[old($Heap),$Heap := old($Heap),initHeap] ==> Post(x,y));
- // }
-
- // Note, it would be nicer (and arguably more appropriate) to do a SetupBoundVarsAsLocals
- // here (rather than a TrBoundVariables). However, there is currently no way to apply
- // a substMap to a statement (in particular, to s.Body), so that doesn't work here.
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- var ante = etran.TrBoundVariables(s.BoundVars, bvars, true);
- locals.AddRange(bvars);
- var havocIds = new Bpl.IdentifierExprSeq();
- foreach (Bpl.Variable bv in bvars) {
- havocIds.Add(new Bpl.IdentifierExpr(s.Tok, bv));
- }
- definedness.Add(new Bpl.HavocCmd(s.Tok, havocIds));
- definedness.Add(new Bpl.AssumeCmd(s.Tok, ante));
- TrStmt_CheckWellformed(s.Range, definedness, locals, etran, false);
- definedness.Add(new Bpl.AssumeCmd(s.Range.tok, etran.TrExpr(s.Range)));
-
- TrStmt(s.Body, definedness, locals, etran);
-
- // check that postconditions hold
- foreach (var ens in s.Ens) {
- TrStmt_CheckWellformed(ens.E, definedness, locals, etran, false);
- if (!ens.IsFree) {
- bool splitHappened; // we actually don't care
- foreach (var split in TrSplitExpr(ens.E, etran, out splitHappened)) {
- if (!split.IsFree) {
- definedness.Add(Assert(split.E.tok, split.E, "possible violation of postcondition of parallel statement"));
- }
- }
- }
- }
-
- definedness.Add(new Bpl.AssumeCmd(s.Tok, Bpl.Expr.False));
-
- // Now for the other branch, where the ensures clauses are exported.
-
- var initHeapVar = new Bpl.LocalVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$initHeapParallelStmt#" + otherTmpVarCount, predef.HeapType));
- otherTmpVarCount++;
- locals.Add(initHeapVar);
- var initHeap = new Bpl.IdentifierExpr(s.Tok, initHeapVar);
- var initEtran = new ExpressionTranslator(this, predef, initHeap, etran.Old.HeapExpr);
- // initHeap := $Heap;
- exporter.Add(Bpl.Cmd.SimpleAssign(s.Tok, initHeap, etran.HeapExpr));
- if (s.Ens.Exists(ens => MentionsOldState(ens.E))) {
- // advance $Heap;
- exporter.Add(new Bpl.HavocCmd(s.Tok, new Bpl.IdentifierExprSeq((Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr, etran.Tick())));
- foreach (BoilerplateTriple tri in GetTwoStateBoilerplate(s.Tok, new List<FrameExpression>(), initEtran, etran, initEtran)) {
- if (tri.IsFree) {
- exporter.Add(new Bpl.AssumeCmd(s.Tok, tri.Expr));
- }
- }
- } else {
- // As an optimization, create the illusion that the $Heap is unchanged by the parallel body.
- exporter.Add(new Bpl.HavocCmd(s.Tok, new Bpl.IdentifierExprSeq(etran.Tick())));
- }
-
- bvars = new Bpl.VariableSeq();
- Dictionary<IVariable, Expression> substMap;
- ante = initEtran.TrBoundVariablesRename(s.BoundVars, bvars, out substMap);
- var range = Substitute(s.Range, null, substMap);
- ante = BplAnd(ante, initEtran.TrExpr(range));
-
- Bpl.Expr post = Bpl.Expr.True;
- foreach (var ens in s.Ens) {
- var p = Substitute(ens.E, null, substMap);
- post = BplAnd(post, etran.TrExpr(p));
- }
-
- Bpl.Expr qq = Bpl.Expr.Imp(ante, post);
- if (bvars.Length != 0) {
- qq = new Bpl.ForallExpr(s.Tok, bvars, qq);
- }
- exporter.Add(new Bpl.AssumeCmd(s.Tok, qq));
- }
-
- private string GetObjFieldDetails(Expression lhs, ExpressionTranslator etran, out Bpl.Expr obj, out Bpl.Expr F) {
- string description;
- if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- obj = etran.TrExpr(fse.Obj);
- F = GetField(fse);
- description = "an object field";
- } else if (lhs is SeqSelectExpr) {
- var sel = (SeqSelectExpr)lhs;
- obj = etran.TrExpr(sel.Seq);
- F = FunctionCall(sel.tok, BuiltinFunction.IndexField, null, etran.TrExpr(sel.E0));
- description = "an array element";
- } else {
- MultiSelectExpr mse = (MultiSelectExpr)lhs;
- obj = etran.TrExpr(mse.Array);
- F = etran.GetArrayIndexFieldName(mse.tok, mse.Indices);
- description = "an array element";
- }
- return description;
- }
-
-
- delegate void BodyTranslator(Bpl.StmtListBuilder builder, ExpressionTranslator etran);
-
-
- void TrLoop(LoopStmt s, Expression Guard, BodyTranslator bodyTr,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(s != null);
- Contract.Requires(bodyTr != null);
- Contract.Requires(builder != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
-
- int loopId = loopHeapVarCount;
- loopHeapVarCount++;
-
- // use simple heuristics to create a default decreases clause, if none is given
- bool inferredDecreases;
- List<Expression> theDecreases = LoopDecreasesWithDefault(s.Tok, Guard, s.Decreases.Expressions, out inferredDecreases);
-
- Bpl.LocalVariable preLoopHeapVar = new Bpl.LocalVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$PreLoopHeap" + loopId, predef.HeapType));
- locals.Add(preLoopHeapVar);
- Bpl.IdentifierExpr preLoopHeap = new Bpl.IdentifierExpr(s.Tok, preLoopHeapVar);
- ExpressionTranslator etranPreLoop = new ExpressionTranslator(this, predef, preLoopHeap);
- ExpressionTranslator updatedFrameEtran;
- string loopFrameName = "#_Frame#" + loopId;
- if(s.Mod.Expressions != null)
- updatedFrameEtran = new ExpressionTranslator(etran, loopFrameName);
- else
- updatedFrameEtran = etran;
-
- if (s.Mod.Expressions != null) { // check that the modifies is a strict subset
- CheckFrameSubset(s.Tok, s.Mod.Expressions, null, null, etran, builder, "loop modifies clause may violate context's modifies clause", null);
- DefineFrame(s.Tok, s.Mod.Expressions, builder, locals, loopFrameName);
- }
- builder.Add(Bpl.Cmd.SimpleAssign(s.Tok, preLoopHeap, etran.HeapExpr));
-
- List<Bpl.Expr> initDecr = null;
- if (!Contract.Exists(theDecreases, e => e is WildcardExpr)) {
- initDecr = RecordDecreasesValue(theDecreases, builder, locals, etran, "$decr" + loopId + "$init$");
- }
-
- // the variable w is used to coordinate the definedness checking of the loop invariant
- Bpl.LocalVariable wVar = new Bpl.LocalVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$w" + loopId, Bpl.Type.Bool));
- Bpl.IdentifierExpr w = new Bpl.IdentifierExpr(s.Tok, wVar);
- locals.Add(wVar);
- // havoc w;
- builder.Add(new Bpl.HavocCmd(s.Tok, new Bpl.IdentifierExprSeq(w)));
-
- List<Bpl.PredicateCmd> invariants = new List<Bpl.PredicateCmd>();
- Bpl.StmtListBuilder invDefinednessBuilder = new Bpl.StmtListBuilder();
- foreach (MaybeFreeExpression loopInv in s.Invariants) {
- TrStmt_CheckWellformed(loopInv.E, invDefinednessBuilder, locals, etran, false);
- invDefinednessBuilder.Add(new Bpl.AssumeCmd(loopInv.E.tok, etran.TrExpr(loopInv.E)));
-
- invariants.Add(new Bpl.AssumeCmd(loopInv.E.tok, Bpl.Expr.Imp(w, CanCallAssumption(loopInv.E, etran))));
- if (loopInv.IsFree && !DafnyOptions.O.DisallowSoundnessCheating) {
- invariants.Add(new Bpl.AssumeCmd(loopInv.E.tok, Bpl.Expr.Imp(w, etran.TrExpr(loopInv.E))));
- } else {
- bool splitHappened;
- var ss = TrSplitExpr(loopInv.E, etran, out splitHappened);
- if (!splitHappened) {
- var wInv = Bpl.Expr.Imp(w, etran.TrExpr(loopInv.E));
- invariants.Add(Assert(loopInv.E.tok, wInv, "loop invariant violation"));
- } else {
- foreach (var split in ss) {
- var wInv = Bpl.Expr.Binary(split.E.tok, BinaryOperator.Opcode.Imp, w, split.E);
- if (split.IsFree) {
- invariants.Add(new Bpl.AssumeCmd(split.E.tok, wInv));
- } else {
- invariants.Add(Assert(split.E.tok, wInv, "loop invariant violation")); // TODO: it would be fine to have this use {:subsumption 0}
- }
- }
- }
- }
- }
- // check definedness of decreases clause
- // TODO: can this check be omitted if the decreases clause is inferred?
- foreach (Expression e in theDecreases) {
- TrStmt_CheckWellformed(e, invDefinednessBuilder, locals, etran, true);
- }
- // include boilerplate invariants
- foreach (BoilerplateTriple tri in GetTwoStateBoilerplate(s.Tok, codeContext.Modifies.Expressions, etranPreLoop, etran, etran.Old))
- {
- if (tri.IsFree) {
- invariants.Add(new Bpl.AssumeCmd(s.Tok, tri.Expr));
- }
- else {
- Contract.Assert(tri.ErrorMessage != null); // follows from BoilerplateTriple invariant
- invariants.Add(Assert(s.Tok, tri.Expr, tri.ErrorMessage));
- }
- }
- // add a free invariant which says that the heap hasn't changed outside of the modifies clause.
- invariants.Add(new Bpl.AssumeCmd(s.Tok, FrameConditionUsingDefinedFrame(s.Tok, etranPreLoop, etran, updatedFrameEtran)));
-
- // include a free invariant that says that all completed iterations so far have only decreased the termination metric
- if (initDecr != null) {
- List<IToken> toks = new List<IToken>();
- List<Type> types = new List<Type>();
- List<Bpl.Expr> decrs = new List<Bpl.Expr>();
- foreach (Expression e in theDecreases) {
- toks.Add(e.tok);
- types.Add(cce.NonNull(e.Type));
- decrs.Add(etran.TrExpr(e));
- }
- Bpl.Expr decrCheck = DecreasesCheck(toks, types, decrs, initDecr, etran, null, null, true, false);
- invariants.Add(new Bpl.AssumeCmd(s.Tok, decrCheck));
- }
-
- Bpl.StmtListBuilder loopBodyBuilder = new Bpl.StmtListBuilder();
- // as the first thing inside the loop, generate: if (!w) { assert IsTotal(inv); assume false; }
- invDefinednessBuilder.Add(new Bpl.AssumeCmd(s.Tok, Bpl.Expr.False));
- loopBodyBuilder.Add(new Bpl.IfCmd(s.Tok, Bpl.Expr.Not(w), invDefinednessBuilder.Collect(s.Tok), null, null));
- // generate: assert IsTotal(guard); if (!guard) { break; }
- Bpl.Expr guard = null;
- if (Guard != null) {
- TrStmt_CheckWellformed(Guard, loopBodyBuilder, locals, etran, true);
- guard = Bpl.Expr.Not(etran.TrExpr(Guard));
- }
- Bpl.StmtListBuilder guardBreak = new Bpl.StmtListBuilder();
- guardBreak.Add(new Bpl.BreakCmd(s.Tok, null));
- loopBodyBuilder.Add(new Bpl.IfCmd(s.Tok, guard, guardBreak.Collect(s.Tok), null, null));
-
- loopBodyBuilder.Add(CaptureState(s.Tok, "loop entered"));
- // termination checking
- if (Contract.Exists(theDecreases, e => e is WildcardExpr)) {
- // omit termination checking for this loop
- bodyTr(loopBodyBuilder, updatedFrameEtran);
- } else {
- List<Bpl.Expr> oldBfs = RecordDecreasesValue(theDecreases, loopBodyBuilder, locals, etran, "$decr" + loopId + "$");
- // time for the actual loop body
- bodyTr(loopBodyBuilder, updatedFrameEtran);
- // check definedness of decreases expressions
- List<IToken> toks = new List<IToken>();
- List<Type> types = new List<Type>();
- List<Bpl.Expr> decrs = new List<Bpl.Expr>();
- foreach (Expression e in theDecreases) {
- toks.Add(e.tok);
- types.Add(cce.NonNull(e.Type));
- decrs.Add(etran.TrExpr(e));
- }
- Bpl.Expr decrCheck = DecreasesCheck(toks, types, decrs, oldBfs, etran, loopBodyBuilder, " at end of loop iteration", false, false);
- string msg;
- if (inferredDecreases) {
- msg = "cannot prove termination; try supplying a decreases clause for the loop";
- if (s is RefinedWhileStmt) {
- msg += " (note that a refined loop does not inherit 'decreases *' from the refined loop)";
- }
- } else {
- msg = "decreases expression might not decrease";
- }
- loopBodyBuilder.Add(Assert(s.Tok, decrCheck, msg));
- }
- // Finally, assume the well-formedness of the invariant (which has been checked once and for all above), so that the check
- // of invariant-maintenance can use the appropriate canCall predicates.
- foreach (MaybeFreeExpression loopInv in s.Invariants) {
- loopBodyBuilder.Add(new Bpl.AssumeCmd(loopInv.E.tok, CanCallAssumption(loopInv.E, etran)));
- }
- Bpl.StmtList body = loopBodyBuilder.Collect(s.Tok);
-
- builder.Add(new Bpl.WhileCmd(s.Tok, Bpl.Expr.True, invariants, body));
- builder.Add(CaptureState(s.Tok, "loop exit"));
- }
-
- void TrAlternatives(List<GuardedAlternative> alternatives, Bpl.Cmd elseCase0, Bpl.StructuredCmd elseCase1,
- Bpl.StmtListBuilder builder, VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(alternatives != null);
- Contract.Requires((elseCase0 != null) == (elseCase1 == null)); // ugly way of doing a type union
- Contract.Requires(builder != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
-
- if (alternatives.Count == 0) {
- if (elseCase0 != null) {
- builder.Add(elseCase0);
- } else {
- builder.Add(elseCase1);
- }
- return;
- }
-
- // build the negation of the disjunction of all guards (that is, the conjunction of their negations)
- Bpl.Expr noGuard = Bpl.Expr.True;
- foreach (var alternative in alternatives) {
- noGuard = BplAnd(noGuard, Bpl.Expr.Not(etran.TrExpr(alternative.Guard)));
- }
-
- var b = new Bpl.StmtListBuilder();
- var elseTok = elseCase0 != null ? elseCase0.tok : elseCase1.tok;
- b.Add(new Bpl.AssumeCmd(elseTok, noGuard));
- if (elseCase0 != null) {
- b.Add(elseCase0);
- } else {
- b.Add(elseCase1);
- }
- Bpl.StmtList els = b.Collect(elseTok);
-
- Bpl.IfCmd elsIf = null;
- for (int i = alternatives.Count; 0 <= --i; ) {
- Contract.Assert(elsIf == null || els == null); // loop invariant
- var alternative = alternatives[i];
- b = new Bpl.StmtListBuilder();
- TrStmt_CheckWellformed(alternative.Guard, b, locals, etran, true);
- b.Add(new AssumeCmd(alternative.Guard.tok, etran.TrExpr(alternative.Guard)));
- foreach (var s in alternative.Body) {
- TrStmt(s, b, locals, etran);
- }
- Bpl.StmtList thn = b.Collect(alternative.Tok);
- elsIf = new Bpl.IfCmd(alternative.Tok, null, thn, elsIf, els);
- els = null;
- }
- Contract.Assert(elsIf != null && els == null); // follows from loop invariant and the fact that there's more than one alternative
- builder.Add(elsIf);
- }
-
- void TrCallStmt(CallStmt s, Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran, Bpl.Expr actualReceiver) {
- List<AssignToLhs> lhsBuilders;
- List<Bpl.IdentifierExpr> bLhss;
- Bpl.Expr[] ignore1, ignore2;
- string[] ignore3;
- ProcessLhss(s.Lhs, true, true, builder, locals, etran, out lhsBuilders, out bLhss, out ignore1, out ignore2, out ignore3);
- Contract.Assert(s.Lhs.Count == lhsBuilders.Count);
- Contract.Assert(s.Lhs.Count == bLhss.Count);
- var lhsTypes = new List<Type>();
- for (int i = 0; i < s.Lhs.Count; i++) {
- var lhs = s.Lhs[i];
- lhsTypes.Add(lhs.Type);
- if (bLhss[i] == null) { // (in the current implementation, the second parameter "true" to ProcessLhss implies that all bLhss[*] will be null)
- // create temporary local and assign it to bLhss[i]
- string nm = "$rhs##" + otherTmpVarCount;
- otherTmpVarCount++;
- var ty = TrType(lhs.Type);
- Bpl.Expr wh = GetWhereClause(lhs.tok, new Bpl.IdentifierExpr(lhs.tok, nm, ty), lhs.Type, etran);
- Bpl.LocalVariable var = new Bpl.LocalVariable(lhs.tok, new Bpl.TypedIdent(lhs.tok, nm, ty, wh));
- locals.Add(var);
- bLhss[i] = new Bpl.IdentifierExpr(lhs.tok, var.Name, ty);
- }
- }
- Bpl.IdentifierExpr initHeap = null;
- if (codeContext is IteratorDecl) {
- // var initHeap := $Heap;
- var initHeapVar = new Bpl.LocalVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$initHeapCallStmt#" + otherTmpVarCount, predef.HeapType));
- otherTmpVarCount++;
- locals.Add(initHeapVar);
- initHeap = new Bpl.IdentifierExpr(s.Tok, initHeapVar);
- // initHeap := $Heap;
- builder.Add(Bpl.Cmd.SimpleAssign(s.Tok, initHeap, etran.HeapExpr));
- }
- ProcessCallStmt(s.Tok, s.Receiver, actualReceiver, s.Method, s.Args, bLhss, lhsTypes, builder, locals, etran);
- for (int i = 0; i < lhsBuilders.Count; i++) {
- var lhs = s.Lhs[i];
- Type lhsType = null;
- if (lhs is IdentifierExpr) {
- lhsType = lhs.Type;
- } else if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- lhsType = fse.Field.Type;
- }
-
- Bpl.Expr bRhs = bLhss[i]; // the RHS (bRhs) of the assignment to the actual call-LHS (lhs) was a LHS (bLhss[i]) in the Boogie call statement
- if (lhsType != null) {
- CheckSubrange(lhs.tok, bRhs, lhsType, builder);
- }
- bRhs = etran.CondApplyBox(lhs.tok, bRhs, lhs.Type, lhsType);
-
- lhsBuilders[i](bRhs, builder, etran);
- }
- if (codeContext is IteratorDecl) {
- var iter = (IteratorDecl)codeContext;
- Contract.Assert(initHeap != null);
- RecordNewObjectsIn_New(s.Tok, iter, initHeap, (Bpl.IdentifierExpr/*TODO: this cast is dubious*/)etran.HeapExpr, builder, locals, etran);
- }
- builder.Add(CaptureState(s.Tok));
- }
-
- void ProcessCallStmt(IToken tok,
- Expression dafnyReceiver, Bpl.Expr bReceiver,
- Method method, List<Expression> Args,
- List<Bpl.IdentifierExpr> Lhss, List<Type> LhsTypes,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran) {
-
- Contract.Requires(tok != null);
- Contract.Requires(dafnyReceiver != null || bReceiver != null);
- Contract.Requires(method != null);
- Contract.Requires(cce.NonNullElements(Args));
- Contract.Requires(cce.NonNullElements(Lhss));
- Contract.Requires(cce.NonNullElements(LhsTypes));
- Contract.Requires(method.Outs.Count == Lhss.Count);
- Contract.Requires(method.Outs.Count == LhsTypes.Count);
- Contract.Requires(builder != null);
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
-
- Expression receiver = bReceiver == null ? dafnyReceiver : new BoogieWrapper(bReceiver, dafnyReceiver.Type);
- Bpl.ExprSeq ins = new Bpl.ExprSeq();
- if (!method.IsStatic) {
- if (bReceiver == null) {
- if (!(dafnyReceiver is ThisExpr)) {
- CheckNonNull(dafnyReceiver.tok, dafnyReceiver, builder, etran, null);
- }
- }
- ins.Add(etran.TrExpr(receiver));
- }
-
- // Ideally, the modifies and decreases checks would be done after the precondition check,
- // but Boogie doesn't give us a hook for that. So, we set up our own local variables here to
- // store the actual parameters.
- // Create a local variable for each formal parameter, and assign each actual parameter to the corresponding local
- Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
- for (int i = 0; i < method.Ins.Count; i++) {
- Formal p = method.Ins[i];
- VarDecl local = new VarDecl(p.tok, p.Name + "#", p.Type, p.IsGhost);
- local.type = local.OptionalType; // resolve local here
- IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
- ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
- substMap.Add(p, ie);
- locals.Add(new Bpl.LocalVariable(local.Tok, new Bpl.TypedIdent(local.Tok, local.UniqueName, TrType(local.Type))));
-
- Bpl.IdentifierExpr param = (Bpl.IdentifierExpr)etran.TrExpr(ie); // TODO: is this cast always justified?
- Expression actual = Args[i];
- TrStmt_CheckWellformed(actual, builder, locals, etran, true);
- var bActual = etran.TrExpr(actual);
- CheckSubrange(actual.tok, bActual, p.Type, builder);
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(p.tok, param, etran.CondApplyBox(actual.tok, bActual, cce.NonNull(actual.Type), method.Ins[i].Type));
- builder.Add(cmd);
- ins.Add(param);
- }
-
- // Check modifies clause of a subcall is a subset of the current frame.
- CheckFrameSubset(tok, method.Mod.Expressions, receiver, substMap, etran, builder, "call may violate context's modifies clause", null);
-
- // Check termination
- ModuleDefinition module = method.EnclosingClass.Module;
- if (module == currentModule) {
- var caller = codeContext is Method ? (Method)codeContext : ((IteratorDecl)codeContext).Member_MoveNext;
- if (module.CallGraph.GetSCCRepresentative(method) == module.CallGraph.GetSCCRepresentative(caller)) {
- bool contextDecrInferred, calleeDecrInferred;
- List<Expression> contextDecreases = MethodDecreasesWithDefault(caller, out contextDecrInferred);
- List<Expression> calleeDecreases = MethodDecreasesWithDefault(method, out calleeDecrInferred);
- CheckCallTermination(tok, contextDecreases, calleeDecreases, null, receiver, substMap, etran, builder, contextDecrInferred, null);
- }
- }
-
- // Create variables to hold the output parameters of the call, so that appropriate unboxes can be introduced.
- Bpl.IdentifierExprSeq outs = new Bpl.IdentifierExprSeq();
- List<Bpl.IdentifierExpr> tmpOuts = new List<Bpl.IdentifierExpr>();
- for (int i = 0; i < Lhss.Count; i++) {
- var bLhs = Lhss[i];
- if (ExpressionTranslator.ModeledAsBoxType(method.Outs[i].Type) && !ExpressionTranslator.ModeledAsBoxType(LhsTypes[i])) {
- // we need an Unbox
- Bpl.LocalVariable var = new Bpl.LocalVariable(bLhs.tok, new Bpl.TypedIdent(bLhs.tok, "$tmp##" + otherTmpVarCount, predef.BoxType));
- otherTmpVarCount++;
- locals.Add(var);
- Bpl.IdentifierExpr varIdE = new Bpl.IdentifierExpr(bLhs.tok, var.Name, predef.BoxType);
- tmpOuts.Add(varIdE);
- outs.Add(varIdE);
- } else {
- tmpOuts.Add(null);
- outs.Add(bLhs);
- }
- }
-
- // Make the call
- string name;
- if (RefinementToken.IsInherited(method.tok, currentModule) && (codeContext == null || !codeContext.MustReverify)) {
- name = string.Format("RefinementCall_{0}$${1}", currentModule.Name, method.FullCompileName);
- } else {
- name = method.FullCompileName;
- }
- Bpl.CallCmd call = new Bpl.CallCmd(tok, name, ins, outs);
- builder.Add(call);
-
- // Unbox results as needed
- for (int i = 0; i < Lhss.Count; i++) {
- Bpl.IdentifierExpr bLhs = Lhss[i];
- Bpl.IdentifierExpr tmpVarIdE = tmpOuts[i];
- if (tmpVarIdE != null) {
- // Instead of an assignment:
- // e := UnBox(tmpVar);
- // we use:
- // havoc e; assume e == UnBox(tmpVar);
- // because that will reap the benefits of e's where clause, so that some additional type information will be known about
- // the out-parameter.
- Bpl.Cmd cmd = new Bpl.HavocCmd(bLhs.tok, new IdentifierExprSeq(bLhs));
- builder.Add(cmd);
- cmd = new Bpl.AssumeCmd(bLhs.tok, Bpl.Expr.Eq(bLhs, FunctionCall(bLhs.tok, BuiltinFunction.Unbox, TrType(LhsTypes[i]), tmpVarIdE)));
- builder.Add(cmd);
- }
- }
- }
-
- static Expression CreateIntLiteral(IToken tok, int n)
- {
- Contract.Requires(tok != null);
- Contract.Ensures(Contract.Result<Expression>() != null);
-
- if (0 <= n) {
- Expression lit = new LiteralExpr(tok, n);
- lit.Type = Type.Int; // resolve here
- return lit;
- } else {
- return CreateIntSub(tok, CreateIntLiteral(tok, 0), CreateIntLiteral(tok, -n));
- }
- }
-
- static Expression CreateIntSub(IToken tok, Expression e0, Expression e1)
- {
- Contract.Requires(tok != null);
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Requires(e0.Type is IntType && e1.Type is IntType);
- Contract.Ensures(Contract.Result<Expression>() != null);
- BinaryExpr s = new BinaryExpr(tok, BinaryExpr.Opcode.Sub, e0, e1);
- s.ResolvedOp = BinaryExpr.ResolvedOpcode.Sub; // resolve here
- s.Type = Type.Int; // resolve here
- return s;
- }
-
- static Expression CreateIntITE(IToken tok, Expression test, Expression e0, Expression e1)
- {
- Contract.Requires(tok != null);
- Contract.Requires(test != null);
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Requires(test.Type is BoolType && e0.Type is IntType && e1.Type is IntType);
- Contract.Ensures(Contract.Result<Expression>() != null);
-
- ITEExpr ite = new ITEExpr(tok, test, e0, e1);
- ite.Type = Type.Int; // resolve here
- return ite;
- }
-
- public IEnumerable<Expression> Conjuncts(Expression expr)
- {
- Contract.Requires(expr != null);
- Contract.Requires(expr.Type is BoolType);
- Contract.Ensures(cce.NonNullElements(Contract.Result<IEnumerable<Expression>>()));
-
- var bin = expr as BinaryExpr;
- if (bin != null && bin.ResolvedOp == BinaryExpr.ResolvedOpcode.And) {
- foreach (Expression e in Conjuncts(bin.E0)) {
- yield return e;
- }
- foreach (Expression e in Conjuncts(bin.E1)) {
- yield return e;
- }
- yield break;
- }
- yield return expr;
- }
-
- Dictionary<IVariable, Expression> SetupBoundVarsAsLocals(List<BoundVar> boundVars, StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(boundVars != null);
- Contract.Requires(builder != null);
- Contract.Requires(locals != null);
-
- var substMap = new Dictionary<IVariable, Expression>();
- foreach (BoundVar bv in boundVars) {
- VarDecl local = new VarDecl(bv.tok, bv.Name, bv.Type, bv.IsGhost);
- local.type = local.OptionalType; // resolve local here
- IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
- ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
- substMap.Add(bv, ie);
- Bpl.LocalVariable bvar = new Bpl.LocalVariable(local.Tok, new Bpl.TypedIdent(local.Tok, local.UniqueName, TrType(local.Type)));
- locals.Add(bvar);
- var bIe = new Bpl.IdentifierExpr(bvar.tok, bvar);
- builder.Add(new Bpl.HavocCmd(bv.tok, new IdentifierExprSeq(bIe)));
- Bpl.Expr wh = GetWhereClause(bv.tok, bIe, local.Type, etran);
- if (wh != null) {
- builder.Add(new Bpl.AssumeCmd(bv.tok, wh));
- }
- }
- return substMap;
- }
-
- List<Bpl.Expr> RecordDecreasesValue(List<Expression> decreases, Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran, string varPrefix)
- {
- Contract.Requires(locals != null);
- Contract.Requires(etran != null);
- Contract.Requires(varPrefix != null);
- Contract.Requires(builder != null);
- Contract.Requires(decreases != null);
- List<Bpl.Expr> oldBfs = new List<Bpl.Expr>();
- int c = 0;
- foreach (Expression e in decreases) {
- Contract.Assert(e != null);
- Bpl.LocalVariable bfVar = new Bpl.LocalVariable(e.tok, new Bpl.TypedIdent(e.tok, varPrefix + c, TrType(cce.NonNull(e.Type))));
- locals.Add(bfVar);
- Bpl.IdentifierExpr bf = new Bpl.IdentifierExpr(e.tok, bfVar);
- oldBfs.Add(bf);
- // record value of each decreases expression at beginning of the loop iteration
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(e.tok, bf, etran.TrExpr(e));
- builder.Add(cmd);
-
- c++;
- }
- return oldBfs;
- }
-
- /// <summary>
- /// Emit to "builder" a check that calleeDecreases is less than contextDecreases. More precisely,
- /// the check is:
- /// allowance || (calleeDecreases LESS contextDecreases).
- /// </summary>
- void CheckCallTermination(IToken/*!*/ tok, List<Expression/*!*/>/*!*/ contextDecreases, List<Expression/*!*/>/*!*/ calleeDecreases,
- Bpl.Expr allowance,
- Expression receiverReplacement, Dictionary<IVariable,Expression/*!*/>/*!*/ substMap,
- ExpressionTranslator/*!*/ etran, Bpl.StmtListBuilder/*!*/ builder, bool inferredDecreases, string hint) {
- Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(contextDecreases));
- Contract.Requires(cce.NonNullElements(calleeDecreases));
- Contract.Requires(cce.NonNullDictionaryAndValues(substMap));
- Contract.Requires(etran != null);
- Contract.Requires(builder != null);
-
- // The interpretation of the given decreases-clause expression tuples is as a lexicographic tuple, extended into
- // an infinite tuple by appending TOP elements. The TOP element is strictly larger than any other value given
- // by a Dafny expression. Each Dafny types has its own ordering, and these orderings are combined into a partial
- // order where elements from different Dafny types are incomparable. Thus, as an optimization below, if two
- // components from different types are compared, the answer is taken to be false.
-
- if (Contract.Exists(calleeDecreases, e => e is WildcardExpr)) {
- // no check needed
- return;
- }
-
- int N = Math.Min(contextDecreases.Count, calleeDecreases.Count);
- List<IToken> toks = new List<IToken>();
- List<Type> types = new List<Type>();
- List<Bpl.Expr> callee = new List<Bpl.Expr>();
- List<Bpl.Expr> caller = new List<Bpl.Expr>();
- for (int i = 0; i < N; i++) {
- Expression e0 = Substitute(calleeDecreases[i], receiverReplacement, substMap);
- Expression e1 = contextDecreases[i];
- if (!CompatibleDecreasesTypes(cce.NonNull(e0.Type), cce.NonNull(e1.Type))) {
- N = i;
- break;
- }
- toks.Add(tok);
- types.Add(e0.Type);
- callee.Add(etran.TrExpr(e0));
- caller.Add(etran.TrExpr(e1));
- }
- bool endsWithWinningTopComparison = N == contextDecreases.Count && N < calleeDecreases.Count;
- Bpl.Expr decrExpr = DecreasesCheck(toks, types, callee, caller, etran, builder, "", endsWithWinningTopComparison, false);
- if (allowance != null) {
- decrExpr = Bpl.Expr.Or(allowance, decrExpr);
- }
- string msg = inferredDecreases ? "cannot prove termination; try supplying a decreases clause" : "failure to decrease termination measure";
- if (hint != null) {
- msg += " (" + hint + ")";
- }
- builder.Add(Assert(tok, decrExpr, msg));
- }
-
- /// <summary>
- /// Returns the expression that says whether or not the decreases function has gone down (if !allowNoChange)
- /// or has gone down or stayed the same (if allowNoChange).
- /// ee0 represents the new values and ee1 represents old values.
- /// If builder is non-null, then the check '0 ATMOST decr' is generated to builder.
- /// </summary>
- Bpl.Expr DecreasesCheck(List<IToken/*!*/>/*!*/ toks, List<Type/*!*/>/*!*/ types, List<Bpl.Expr/*!*/>/*!*/ ee0, List<Bpl.Expr/*!*/>/*!*/ ee1,
- ExpressionTranslator/*!*/ etran, Bpl.StmtListBuilder builder, string suffixMsg, bool allowNoChange, bool includeLowerBound)
- {
- Contract.Requires(cce.NonNullElements(toks));
- Contract.Requires(cce.NonNullElements(types));
- Contract.Requires(cce.NonNullElements(ee0));
- Contract.Requires(cce.NonNullElements(ee1));
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
- Contract.Requires(types.Count == ee0.Count && ee0.Count == ee1.Count);
- Contract.Requires(builder == null || suffixMsg != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- int N = types.Count;
-
- // compute eq and less for each component of the lexicographic pair
- List<Bpl.Expr> Eq = new List<Bpl.Expr>(N);
- List<Bpl.Expr> Less = new List<Bpl.Expr>(N);
- for (int i = 0; i < N; i++) {
- Bpl.Expr less, atmost, eq;
- ComputeLessEq(toks[i], types[i], ee0[i], ee1[i], out less, out atmost, out eq, etran, includeLowerBound);
- Eq.Add(eq);
- Less.Add(allowNoChange ? atmost : less);
- }
- if (builder != null) {
- // check: 0 <= ee1
- // more precisely, for component k of the lexicographic decreases function, check:
- // ee0[0] < ee1[0] || ee0[1] < ee1[1] || ... || ee0[k-1] < ee1[k-1] || ee0[k] == ee1[k] || 0 <= ee1[k]
- for (int k = 0; k < N; k++) {
- // we only need to check lower bound for integers--sets, sequences, booleans, references, and datatypes all have natural lower bounds
- Bpl.Expr prefixIsLess = Bpl.Expr.False;
- for (int i = 0; i < k; i++) {
- prefixIsLess = Bpl.Expr.Or(prefixIsLess, Less[i]);
- }
- if (types[k] is IntType) {
- Bpl.Expr bounded = Bpl.Expr.Le(Bpl.Expr.Literal(0), ee1[k]);
- for (int i = 0; i < k; i++) {
- bounded = Bpl.Expr.Or(bounded, Less[i]);
- }
- string component = N == 1 ? "" : " (component " + k + ")";
- Bpl.Cmd cmd = Assert(toks[k], Bpl.Expr.Or(bounded, Eq[k]), "decreases expression" + component + " must be bounded below by 0" + suffixMsg);
- builder.Add(cmd);
- }
- }
- }
- // check: ee0 < ee1 (or ee0 <= ee1, if allowNoChange)
- Bpl.Expr decrCheck = allowNoChange ? Bpl.Expr.True : Bpl.Expr.False;
- for (int i = N; 0 <= --i; ) {
- Bpl.Expr less = Less[i];
- Bpl.Expr eq = Eq[i];
- if (allowNoChange) {
- // decrCheck = atmost && (eq ==> decrCheck)
- decrCheck = Bpl.Expr.And(less, Bpl.Expr.Imp(eq, decrCheck));
- } else {
- // decrCheck = less || (eq && decrCheck)
- decrCheck = Bpl.Expr.Or(less, Bpl.Expr.And(eq, decrCheck));
- }
- }
- return decrCheck;
- }
-
- bool CompatibleDecreasesTypes(Type t, Type u) {
- Contract.Requires(t != null);
- Contract.Requires(u != null);
- if (t is BoolType) {
- return u is BoolType;
- } else if (t is IntType) {
- return u is IntType;
- } else if (t is SetType) {
- return u is SetType;
- } else if (t is SeqType) {
- return u is SeqType;
- } else if (t.IsDatatype) {
- return u.IsDatatype;
- } else if (t.IsRefType) {
- return u.IsRefType;
- } else if (t is MapType) {
- return false;
- } else {
- Contract.Assert(t.IsTypeParameter);
- return false; // don't consider any type parameters to be the same (since we have no comparison function for them anyway)
- }
- }
-
- void ComputeLessEq(IToken/*!*/ tok, Type/*!*/ ty, Bpl.Expr/*!*/ e0, Bpl.Expr/*!*/ e1, out Bpl.Expr/*!*/ less, out Bpl.Expr/*!*/ atmost, out Bpl.Expr/*!*/ eq,
- ExpressionTranslator/*!*/ etran, bool includeLowerBound)
- {
- Contract.Requires(tok != null);
- Contract.Requires(ty != null);
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.ValueAtReturn(out less)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out atmost)!=null);
- Contract.Ensures(Contract.ValueAtReturn(out eq)!=null);
-
- if (ty is BoolType) {
- eq = Bpl.Expr.Iff(e0, e1);
- less = Bpl.Expr.And(Bpl.Expr.Not(e0), e1);
- atmost = Bpl.Expr.Imp(e0, e1);
- } else if (ty is IntType) {
- eq = Bpl.Expr.Eq(e0, e1);
- less = Bpl.Expr.Lt(e0, e1);
- atmost = Bpl.Expr.Le(e0, e1);
- if (includeLowerBound) {
- less = Bpl.Expr.And(Bpl.Expr.Le(Bpl.Expr.Literal(0), e0), less);
- atmost = Bpl.Expr.And(Bpl.Expr.Le(Bpl.Expr.Literal(0), e0), atmost);
- }
- } else if (ty is EverIncreasingType) {
- eq = Bpl.Expr.Eq(e0, e1);
- less = Bpl.Expr.Gt(e0, e1);
- atmost = Bpl.Expr.Ge(e0, e1);
- } else if (ty is SetType) {
- eq = FunctionCall(tok, BuiltinFunction.SetEqual, null, e0, e1);
- less = etran.ProperSubset(tok, e0, e1);
- atmost = FunctionCall(tok, BuiltinFunction.SetSubset, null, e0, e1);
- } else if (ty is SeqType) {
- Bpl.Expr b0 = FunctionCall(tok, BuiltinFunction.SeqLength, null, e0);
- Bpl.Expr b1 = FunctionCall(tok, BuiltinFunction.SeqLength, null, e1);
- eq = Bpl.Expr.Eq(b0, b1);
- less = Bpl.Expr.Lt(b0, b1);
- atmost = Bpl.Expr.Le(b0, b1);
- } else if (ty.IsDatatype) {
- Bpl.Expr b0 = FunctionCall(tok, BuiltinFunction.DtRank, null, e0);
- Bpl.Expr b1 = FunctionCall(tok, BuiltinFunction.DtRank, null, e1);
- eq = Bpl.Expr.Eq(b0, b1);
- less = Bpl.Expr.Lt(b0, b1);
- atmost = Bpl.Expr.Le(b0, b1);
-
- } else {
- // reference type
- Bpl.Expr b0 = Bpl.Expr.Neq(e0, predef.Null);
- Bpl.Expr b1 = Bpl.Expr.Neq(e1, predef.Null);
- eq = Bpl.Expr.Iff(b0, b1);
- less = Bpl.Expr.And(Bpl.Expr.Not(b0), b1);
- atmost = Bpl.Expr.Imp(b0, b1);
- }
- }
-
- void AddComment(Bpl.StmtListBuilder builder, Statement stmt, string comment) {
- Contract.Requires(builder != null);
- Contract.Requires(stmt != null);
- Contract.Requires(comment != null);
- builder.Add(new Bpl.CommentCmd(string.Format("----- {0} ----- {1}({2},{3})", comment, stmt.Tok.filename, stmt.Tok.line, stmt.Tok.col)));
- }
-
- Bpl.Expr GetWhereClause(IToken tok, Bpl.Expr x, Type type, ExpressionTranslator etran)
- {
- Contract.Requires(tok != null);
- Contract.Requires(x != null);
- Contract.Requires(type != null);
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
- while (true) {
- TypeProxy proxy = type as TypeProxy;
- if (proxy == null) {
- break;
- } else if (proxy.T == null) {
- // Unresolved proxy
- // Omit where clause (in other places, unresolved proxies are treated as a reference type; we could do that here too, but
- // we might as well leave out the where clause altogether).
- return null;
- } else {
- type = proxy.T;
- }
- }
-
- if (type is NatType) {
- // nat:
- // 0 <= x
- return Bpl.Expr.Le(Bpl.Expr.Literal(0), x);
-
- } else if (type is BoolType || type is IntType) {
- // nothing to do
-
- } else if (type is SetType) {
- SetType st = (SetType)type;
- // (forall t: BoxType :: { x[t] } x[t] ==> Unbox(t)-has-the-expected-type)
- Bpl.BoundVariable tVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$t#" + otherTmpVarCount, predef.BoxType));
- otherTmpVarCount++;
- Bpl.Expr t = new Bpl.IdentifierExpr(tok, tVar);
- Bpl.Expr xSubT = Bpl.Expr.SelectTok(tok, x, t);
- Bpl.Expr unboxT = ExpressionTranslator.ModeledAsBoxType(st.Arg) ? t : FunctionCall(tok, BuiltinFunction.Unbox, TrType(st.Arg), t);
-
- Bpl.Expr wh = GetWhereClause(tok, unboxT, st.Arg, etran);
- if (wh != null) {
- Bpl.Trigger tr = new Bpl.Trigger(tok, true, new Bpl.ExprSeq(xSubT));
- return new Bpl.ForallExpr(tok, new Bpl.VariableSeq(tVar), tr, Bpl.Expr.Imp(xSubT, wh));
- }
-
- } else if (type is MultiSetType) {
- MultiSetType st = (MultiSetType)type;
- // $IsGoodMultiSet(x) && (forall t: BoxType :: { x[t] } 0 < x[t] ==> Unbox(t)-has-the-expected-type)
- Bpl.BoundVariable tVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$t#" + otherTmpVarCount, predef.BoxType));
- otherTmpVarCount++;
- Bpl.Expr t = new Bpl.IdentifierExpr(tok, tVar);
- Bpl.Expr xSubT = Bpl.Expr.Gt(Bpl.Expr.SelectTok(tok, x, t), Bpl.Expr.Literal(0));
- Bpl.Expr unboxT = ExpressionTranslator.ModeledAsBoxType(st.Arg) ? t : FunctionCall(tok, BuiltinFunction.Unbox, TrType(st.Arg), t);
-
- Bpl.Expr isGoodMultiset = FunctionCall(tok, BuiltinFunction.IsGoodMultiSet, null, x);
- Bpl.Expr wh = GetWhereClause(tok, unboxT, st.Arg, etran);
- if (wh != null) {
- Bpl.Trigger tr = new Bpl.Trigger(tok, true, new Bpl.ExprSeq(xSubT));
- var q = new Bpl.ForallExpr(tok, new Bpl.VariableSeq(tVar), tr, Bpl.Expr.Imp(xSubT, wh));
- isGoodMultiset = Bpl.Expr.And(isGoodMultiset, q);
- }
- return isGoodMultiset;
- } else if (type is SeqType) {
- SeqType st = (SeqType)type;
- // (forall i: int :: { Seq#Index(x,i) }
- // 0 <= i && i < Seq#Length(x) ==> Unbox(Seq#Index(x,i))-has-the-expected-type)
- Bpl.BoundVariable iVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$i#" + otherTmpVarCount, Bpl.Type.Int));
- otherTmpVarCount++;
- Bpl.Expr i = new Bpl.IdentifierExpr(tok, iVar);
- Bpl.Expr xSubI = FunctionCall(tok, BuiltinFunction.SeqIndex, predef.BoxType, x, i);
- Bpl.Expr unbox = ExpressionTranslator.ModeledAsBoxType(st.Arg) ? xSubI : FunctionCall(tok, BuiltinFunction.Unbox, TrType(st.Arg), xSubI);
-
- Bpl.Expr c = GetBoolBoxCondition(xSubI, st.Arg);
- Bpl.Expr wh = GetWhereClause(tok, unbox, st.Arg, etran);
- if (wh != null) {
- c = BplAnd(c, wh);
- }
- if (c != Bpl.Expr.True) {
- Bpl.Expr range = InSeqRange(tok, i, x, true, null, false);
- Bpl.Trigger tr = new Bpl.Trigger(tok, true, new Bpl.ExprSeq(xSubI));
- return new Bpl.ForallExpr(tok, new Bpl.VariableSeq(iVar), tr, Bpl.Expr.Imp(range, c));
- }
-
- } else if (type is MapType) {
- MapType mt = (MapType)type;
- Bpl.Type maptype = predef.MapType(tok, predef.BoxType, predef.BoxType);
- Bpl.Expr clause = null;
- // (forall i: BoxType :: { Map#Domain(x)[i] }
- // Map#Domain(x)[i] ==> Unbox(i)-has-the-expected-type)
- // (forall i: BoxType :: { Map#Elements(x)[i] }
- // Map#Domain(x)[i] ==> Unbox(Map#Elements(x)[i])-has-the-expected-type)
- Bpl.BoundVariable tVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$t#" + otherTmpVarCount, predef.BoxType));
- otherTmpVarCount++;
- Bpl.Expr t = new Bpl.IdentifierExpr(tok, tVar);
- Bpl.Expr xSubT = Bpl.Expr.SelectTok(tok, FunctionCall(tok, BuiltinFunction.MapDomain, maptype, x), t);
- Bpl.Expr xElemSubT = Bpl.Expr.SelectTok(tok, FunctionCall(tok, BuiltinFunction.MapElements, maptype, x), t);
- Bpl.Expr unboxT = ExpressionTranslator.ModeledAsBoxType(mt.Domain) ? t : FunctionCall(tok, BuiltinFunction.Unbox, TrType(mt.Domain), t);
- Bpl.Expr unboxElemT = ExpressionTranslator.ModeledAsBoxType(mt.Domain) ? xElemSubT : FunctionCall(tok, BuiltinFunction.Unbox, TrType(mt.Domain), xElemSubT);
-
- Bpl.Expr wh = GetWhereClause(tok, unboxT, mt.Domain, etran);
- if (wh != null) {
- Bpl.Trigger tr = new Bpl.Trigger(tok, true, new Bpl.ExprSeq(xSubT));
- clause = new Bpl.ForallExpr(tok, new Bpl.VariableSeq(tVar), tr, Bpl.Expr.Imp(xSubT, wh));
- }
-
- Bpl.Expr wh2 = GetWhereClause(tok, xElemSubT, mt.Range, etran);
- if (wh2 != null) {
- Bpl.Trigger tr = new Bpl.Trigger(tok, true, new Bpl.ExprSeq(xElemSubT));
- Bpl.Expr forall = new Bpl.ForallExpr(tok, new Bpl.VariableSeq(tVar), tr, Bpl.Expr.Imp(xSubT, wh));
- if (clause == null) {
- clause = forall;
- } else {
- clause = Bpl.Expr.And(clause, forall);
- }
- }
- return clause;
- } else if (type.IsRefType) {
- // reference type:
- // x == null || ($Heap[x,alloc] && dtype(x) == ...)
- return Bpl.Expr.Or(Bpl.Expr.Eq(x, predef.Null), etran.GoodRef(tok, x, type));
-
- } else if (type.IsDatatype) {
- UserDefinedType udt = (UserDefinedType)type;
-
- // DtAlloc(e, heap) && e-has-the-expected-type
- Bpl.Expr alloc = FunctionCall(tok, BuiltinFunction.DtAlloc, null, x, etran.HeapExpr);
- Bpl.Expr goodType = etran.Good_Datatype(tok, x, udt.ResolvedClass, udt.TypeArgs);
- return Bpl.Expr.And(alloc, goodType);
-
- } else if (type.IsTypeParameter) {
- return FunctionCall(tok, BuiltinFunction.GenericAlloc, null, x, etran.HeapExpr);
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
-
- return null;
- }
-
- Bpl.Expr GetBoolBoxCondition(Expr box, Type type) {
- Contract.Requires(box != null);
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (type.Normalize() is BoolType) {
- return FunctionCall(box.tok, BuiltinFunction.IsCanonicalBoolBox, null, box);
- } else {
- return Bpl.Expr.True;
- }
- }
-
- /// <summary>
- /// "lhs" is expected to be a resolved form of an expression, i.e., not a conrete-syntax expression.
- /// </summary>
- void TrAssignment(IToken tok, Expression lhs, AssignmentRhs rhs,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran)
- {
- Contract.Requires(tok != null);
- Contract.Requires(lhs != null);
- Contract.Requires(!(lhs is ConcreteSyntaxExpression));
- Contract.Requires(!(lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne)); // these were once allowed, but their functionality is now provided by 'parallel' statements
- Contract.Requires(rhs != null);
- Contract.Requires(builder != null);
- Contract.Requires(cce.NonNullElements(locals));
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
-
- List<AssignToLhs> lhsBuilder;
- List<Bpl.IdentifierExpr> bLhss;
- var lhss = new List<Expression>() { lhs };
- Bpl.Expr[] ignore1, ignore2;
- string[] ignore3;
- ProcessLhss(lhss, rhs.CanAffectPreviouslyKnownExpressions, true, builder, locals, etran,
- out lhsBuilder, out bLhss, out ignore1, out ignore2, out ignore3);
- Contract.Assert(lhsBuilder.Count == 1 && bLhss.Count == 1); // guaranteed by postcondition of ProcessLhss
-
- var rhss = new List<AssignmentRhs>() { rhs };
- ProcessRhss(lhsBuilder, bLhss, lhss, rhss, builder, locals, etran);
- builder.Add(CaptureState(tok));
- }
-
- void ProcessRhss(List<AssignToLhs> lhsBuilder, List<Bpl.IdentifierExpr/*may be null*/> bLhss,
- List<Expression> lhss, List<AssignmentRhs> rhss,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(lhsBuilder != null);
- Contract.Requires(bLhss != null);
- Contract.Requires(cce.NonNullElements(lhss));
- Contract.Requires(cce.NonNullElements(rhss));
- Contract.Requires(builder != null);
- Contract.Requires(cce.NonNullElements(locals));
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
-
- var finalRhss = new List<Bpl.IdentifierExpr>();
- for (int i = 0; i < lhss.Count; i++) {
- var lhs = lhss[i];
- // the following assumes are part of the precondition, really
- Contract.Assume(!(lhs is ConcreteSyntaxExpression));
- Contract.Assume(!(lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne)); // array-range assignments are not allowed
-
- Type lhsType = null;
- if (lhs is IdentifierExpr) {
- lhsType = lhs.Type;
- } else if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- lhsType = fse.Field.Type;
- }
- var bRhs = TrAssignmentRhs(rhss[i].Tok, bLhss[i], lhsType, rhss[i], lhs.Type, builder, locals, etran);
- if (bRhs != bLhss[i]) {
- finalRhss.Add(bRhs);
- } else {
- // assignment has already been done by by TrAssignmentRhs
- finalRhss.Add(null);
- }
- }
- for (int i = 0; i < lhss.Count; i++) {
- if (finalRhss[i] != null) {
- lhsBuilder[i](finalRhss[i], builder, etran);
- }
- }
- }
-
- List<Bpl.IdentifierExpr> ProcessUpdateAssignRhss(List<Expression> lhss, List<AssignmentRhs> rhss,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(cce.NonNullElements(lhss));
- Contract.Requires(cce.NonNullElements(rhss));
- Contract.Requires(builder != null);
- Contract.Requires(cce.NonNullElements(locals));
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.ForAll(Contract.Result<List<Bpl.IdentifierExpr>>(), i => i != null));
-
- var finalRhss = new List<Bpl.IdentifierExpr>();
- for (int i = 0; i < lhss.Count; i++) {
- var lhs = lhss[i];
- // the following assumes are part of the precondition, really
- Contract.Assume(!(lhs is ConcreteSyntaxExpression));
- Contract.Assume(!(lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne)); // array-range assignments are not allowed
-
- Type lhsType = null;
- if (lhs is IdentifierExpr) {
- lhsType = lhs.Type;
- } else if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- lhsType = fse.Field.Type;
- }
- var bRhs = TrAssignmentRhs(rhss[i].Tok, null, lhsType, rhss[i], lhs.Type, builder, locals, etran);
- finalRhss.Add(bRhs);
- }
- return finalRhss;
- }
-
-
- private void CheckLhssDistinctness(List<Bpl.IdentifierExpr> rhs, List<Expression> lhss, StmtListBuilder builder, ExpressionTranslator etran,
- Bpl.Expr[] objs, Bpl.Expr[] fields, string[] names) {
- Contract.Requires(cce.NonNullElements(lhss));
- Contract.Requires(builder != null);
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
-
- for (int i = 0; i < lhss.Count; i++) {
- var lhs = lhss[i];
- Contract.Assume(!(lhs is ConcreteSyntaxExpression));
- IToken tok = lhs.tok;
-
- if (lhs is IdentifierExpr) {
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as IdentifierExpr;
- if (prev != null && names[i] == names[j]) {
- builder.Add(Assert(tok, Bpl.Expr.Imp(Bpl.Expr.True, Bpl.Expr.Eq(rhs[i],rhs[j])), string.Format("when left-hand sides {0} and {1} refer to the same location, they must have the same value", j, i)));
- }
- }
- } else if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- // check that this LHS is not the same as any previous LHSs
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as FieldSelectExpr;
- if (prev != null && prev.Field == fse.Field) {
- builder.Add(Assert(tok, Bpl.Expr.Imp(Bpl.Expr.Eq(objs[j], objs[i]), Bpl.Expr.Eq(rhs[i], rhs[j])), string.Format("when left-hand sides {0} and {1} refer to the same location, they must have the same value", j, i)));
- }
- }
- } else if (lhs is SeqSelectExpr) {
- SeqSelectExpr sel = (SeqSelectExpr)lhs;
- // check that this LHS is not the same as any previous LHSs
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as SeqSelectExpr;
- if (prev != null) {
- builder.Add(Assert(tok,
- Bpl.Expr.Imp(Bpl.Expr.And(Bpl.Expr.Eq(objs[j], objs[i]), Bpl.Expr.Eq(fields[j], fields[i])), Bpl.Expr.Eq(rhs[i], rhs[j])),
- string.Format("when left-hand sides {0} and {1} may refer to the same location, they must have the same value", j, i)));
- }
- }
- } else {
- MultiSelectExpr mse = (MultiSelectExpr)lhs;
- // check that this LHS is not the same as any previous LHSs
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as MultiSelectExpr;
- if (prev != null) {
- builder.Add(Assert(tok,
- Bpl.Expr.Imp(Bpl.Expr.And(Bpl.Expr.Eq(objs[j], objs[i]), Bpl.Expr.Eq(fields[j], fields[i])), Bpl.Expr.Eq(rhs[i], rhs[j])),
- string.Format("when left-hand sides {0} and {1} refer to the same location, they must have the same value", j, i)));
- }
- }
-
- }
- }
- }
-
- delegate void AssignToLhs(Bpl.Expr rhs, Bpl.StmtListBuilder builder, ExpressionTranslator etran);
-
- /// <summary>
- /// Creates a list of protected Boogie LHSs for the given Dafny LHSs. Along the way,
- /// builds code that checks that the LHSs are well-defined,
- /// and are allowed by the enclosing modifies clause.
- /// Checks that they denote different locations iff checkDistinctness is true.
- /// </summary>
- void ProcessLhss(List<Expression> lhss, bool rhsCanAffectPreviouslyKnownExpressions, bool checkDistinctness,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran,
- out List<AssignToLhs> lhsBuilders, out List<Bpl.IdentifierExpr/*may be null*/> bLhss,
- out Bpl.Expr[] prevObj, out Bpl.Expr[] prevIndex, out string[] prevNames) {
-
- Contract.Requires(cce.NonNullElements(lhss));
- Contract.Requires(builder != null);
- Contract.Requires(cce.NonNullElements(locals));
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.ValueAtReturn(out lhsBuilders).Count == lhss.Count);
- Contract.Ensures(Contract.ValueAtReturn(out lhsBuilders).Count == Contract.ValueAtReturn(out bLhss).Count);
-
- rhsCanAffectPreviouslyKnownExpressions = rhsCanAffectPreviouslyKnownExpressions || lhss.Count != 1;
-
- // for each Dafny LHS, build a protected Boogie LHS for the eventual assignment
- lhsBuilders = new List<AssignToLhs>();
- bLhss = new List<Bpl.IdentifierExpr>();
- prevObj = new Bpl.Expr[lhss.Count];
- prevIndex = new Bpl.Expr[lhss.Count];
- prevNames = new string[lhss.Count];
- int i = 0;
-
- var lhsNameSet = new Dictionary<string, object>();
-
- foreach (var lhs in lhss) {
- Contract.Assume(!(lhs is ConcreteSyntaxExpression));
- IToken tok = lhs.tok;
- TrStmt_CheckWellformed(lhs, builder, locals, etran, true);
-
- if (lhs is IdentifierExpr) {
- var ie = (IdentifierExpr)lhs;
- // Note, the resolver does not check for duplicate IdentifierExpr's in LHSs, so do it here.
- if (checkDistinctness) {
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as IdentifierExpr;
- if (prev != null && ie.Name == prev.Name) {
- builder.Add(Assert(tok, Bpl.Expr.False, string.Format("left-hand sides {0} and {1} refer to the same location", j, i)));
- }
- }
- }
- prevNames[i] = ie.Name;
- var bLhs = (Bpl.IdentifierExpr)etran.TrExpr(lhs); // TODO: is this cast always justified?
- bLhss.Add(rhsCanAffectPreviouslyKnownExpressions ? null : bLhs);
- lhsBuilders.Add(delegate(Bpl.Expr rhs, Bpl.StmtListBuilder bldr, ExpressionTranslator et) {
- bldr.Add(Bpl.Cmd.SimpleAssign(tok, bLhs, rhs));
- });
-
- } else if (lhs is FieldSelectExpr) {
- var fse = (FieldSelectExpr)lhs;
- Contract.Assert(fse.Field != null);
- var obj = SaveInTemp(etran.TrExpr(fse.Obj), rhsCanAffectPreviouslyKnownExpressions,
- "$obj" + i, predef.RefType, builder, locals);
- prevObj[i] = obj;
- // check that the enclosing modifies clause allows this object to be written: assert $_Frame[obj]);
- builder.Add(Assert(tok, Bpl.Expr.SelectTok(tok, etran.TheFrame(tok), obj, GetField(fse)), "assignment may update an object not in the enclosing context's modifies clause"));
-
- if (checkDistinctness) {
- // check that this LHS is not the same as any previous LHSs
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as FieldSelectExpr;
- if (prev != null && prev.Field == fse.Field) {
- builder.Add(Assert(tok, Bpl.Expr.Neq(prevObj[j], obj), string.Format("left-hand sides {0} and {1} may refer to the same location", j, i)));
- }
- }
- }
-
- bLhss.Add(null);
- lhsBuilders.Add(delegate(Bpl.Expr rhs, Bpl.StmtListBuilder bldr, ExpressionTranslator et) {
- Check_NewRestrictions(tok, obj, fse.Field, rhs, bldr, et);
- var h = (Bpl.IdentifierExpr)et.HeapExpr; // TODO: is this cast always justified?
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(tok, h, ExpressionTranslator.UpdateHeap(tok, h, obj, new Bpl.IdentifierExpr(tok, GetField(fse.Field)), rhs));
- bldr.Add(cmd);
- // assume $IsGoodHeap($Heap);
- bldr.Add(AssumeGoodHeap(tok, et));
- });
-
- } else if (lhs is SeqSelectExpr) {
- SeqSelectExpr sel = (SeqSelectExpr)lhs;
- Contract.Assert(sel.SelectOne); // array-range assignments are not allowed
- Contract.Assert(sel.Seq.Type != null && sel.Seq.Type.IsArrayType);
- Contract.Assert(sel.E0 != null);
- var obj = SaveInTemp(etran.TrExpr(sel.Seq), rhsCanAffectPreviouslyKnownExpressions,
- "$obj" + i, predef.RefType, builder, locals);
- var fieldName = SaveInTemp(FunctionCall(tok, BuiltinFunction.IndexField, null, etran.TrExpr(sel.E0)), rhsCanAffectPreviouslyKnownExpressions,
- "$index" + i, predef.FieldName(tok, predef.BoxType), builder, locals);
- prevObj[i] = obj;
- prevIndex[i] = fieldName;
- // check that the enclosing modifies clause allows this object to be written: assert $_Frame[obj,index]);
- builder.Add(Assert(tok, Bpl.Expr.SelectTok(tok, etran.TheFrame(tok), obj, fieldName), "assignment may update an array element not in the enclosing context's modifies clause"));
-
- if (checkDistinctness) {
- // check that this LHS is not the same as any previous LHSs
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as SeqSelectExpr;
- if (prev != null) {
- builder.Add(Assert(tok,
- Bpl.Expr.Or(Bpl.Expr.Neq(prevObj[j], obj), Bpl.Expr.Neq(prevIndex[j], fieldName)),
- string.Format("left-hand sides {0} and {1} may refer to the same location", j, i)));
- }
- }
- }
- bLhss.Add(null);
- lhsBuilders.Add(delegate(Bpl.Expr rhs, Bpl.StmtListBuilder bldr, ExpressionTranslator et) {
- var h = (Bpl.IdentifierExpr)et.HeapExpr; // TODO: is this cast always justified?
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(tok, h, ExpressionTranslator.UpdateHeap(tok, h, obj, fieldName, rhs));
- bldr.Add(cmd);
- // assume $IsGoodHeap($Heap);
- bldr.Add(AssumeGoodHeap(tok, et));
- });
-
- } else {
- MultiSelectExpr mse = (MultiSelectExpr)lhs;
- Contract.Assert(mse.Array.Type != null && mse.Array.Type.IsArrayType);
-
- var obj = SaveInTemp(etran.TrExpr(mse.Array), rhsCanAffectPreviouslyKnownExpressions,
- "$obj" + i, predef.RefType, builder, locals);
- var fieldName = SaveInTemp(etran.GetArrayIndexFieldName(mse.tok, mse.Indices), rhsCanAffectPreviouslyKnownExpressions,
- "$index" + i, predef.FieldName(mse.tok, predef.BoxType), builder, locals);
- prevObj[i] = obj;
- prevIndex[i] = fieldName;
- builder.Add(Assert(tok, Bpl.Expr.SelectTok(tok, etran.TheFrame(tok), obj, fieldName), "assignment may update an array element not in the enclosing context's modifies clause"));
-
- if (checkDistinctness) {
- // check that this LHS is not the same as any previous LHSs
- for (int j = 0; j < i; j++) {
- var prev = lhss[j] as MultiSelectExpr;
- if (prev != null) {
- builder.Add(Assert(tok,
- Bpl.Expr.Or(Bpl.Expr.Neq(prevObj[j], obj), Bpl.Expr.Neq(prevIndex[j], fieldName)),
- string.Format("left-hand sides {0} and {1} may refer to the same location", j, i)));
- }
- }
- }
- bLhss.Add(null);
- lhsBuilders.Add(delegate(Bpl.Expr rhs, Bpl.StmtListBuilder bldr, ExpressionTranslator et) {
- var h = (Bpl.IdentifierExpr)et.HeapExpr; // TODO: is this cast always justified?
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(tok, h, ExpressionTranslator.UpdateHeap(tok, h, obj, fieldName, rhs));
- bldr.Add(cmd);
- // assume $IsGoodHeap($Heap);
- bldr.Add(AssumeGoodHeap(tok, etran));
- });
- }
-
- i++;
- }
- }
-
- /// <summary>
- /// Generates an assignment of the translation of "rhs" to "bLhs" and then return "bLhs". If "bLhs" is
- /// passed in as "null", this method will create a new temporary Boogie variable to hold the result.
- /// Before the assignment, the generated code will check that "rhs" obeys any subrange requirements
- /// entailed by "checkSubrangeType".
- /// </summary>
- Bpl.IdentifierExpr TrAssignmentRhs(IToken tok, Bpl.IdentifierExpr bLhs, Type lhsType, AssignmentRhs rhs, Type checkSubrangeType,
- Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran) {
- Contract.Requires(tok != null);
- Contract.Requires(rhs != null);
- Contract.Requires(!(rhs is CallRhs)); // calls are handled in a different translation method
- Contract.Requires(builder != null);
- Contract.Requires(cce.NonNullElements(locals));
- Contract.Requires(etran != null);
- Contract.Requires(predef != null);
-
- if (bLhs == null) {
- var nm = string.Format("$rhs#{0}", otherTmpVarCount);
- otherTmpVarCount++;
- var v = new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, nm, lhsType == null ? predef.BoxType : TrType(lhsType)));
- locals.Add(v);
- bLhs = new Bpl.IdentifierExpr(tok, v);
- }
-
- if (rhs is ExprRhs) {
- var e = (ExprRhs)rhs;
-
- TrStmt_CheckWellformed(e.Expr, builder, locals, etran, true);
-
- Bpl.Expr bRhs = etran.TrExpr(e.Expr);
- CheckSubrange(tok, bRhs, checkSubrangeType, builder);
- bRhs = etran.CondApplyBox(tok, bRhs, e.Expr.Type, lhsType);
-
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(tok, bLhs, bRhs);
- builder.Add(cmd);
- var ch = e.Expr as UnaryExpr;
- if (ch != null && ch.Op == UnaryExpr.Opcode.SetChoose) {
- // havoc $Tick;
- builder.Add(new Bpl.HavocCmd(ch.tok, new Bpl.IdentifierExprSeq(etran.Tick())));
- }
-
- } else if (rhs is HavocRhs) {
- builder.Add(new Bpl.HavocCmd(tok, new Bpl.IdentifierExprSeq(bLhs)));
- var isNat = CheckSubrange_Expr(tok, bLhs, checkSubrangeType);
- if (isNat != null) {
- builder.Add(new Bpl.AssumeCmd(tok, isNat));
- }
- } else {
- Contract.Assert(rhs is TypeRhs); // otherwise, an unexpected AssignmentRhs
- TypeRhs tRhs = (TypeRhs)rhs;
-
- if (tRhs.ArrayDimensions != null) {
- int i = 0;
- foreach (Expression dim in tRhs.ArrayDimensions) {
- CheckWellformed(dim, new WFOptions(), locals, builder, etran);
- if (tRhs.ArrayDimensions.Count == 1) {
- builder.Add(Assert(tok, Bpl.Expr.Le(Bpl.Expr.Literal(0), etran.TrExpr(dim)),
- tRhs.ArrayDimensions.Count == 1 ? "array size might be negative" : string.Format("array size (dimension {0}) might be negative", i)));
- }
- i++;
- }
- }
-
- Bpl.IdentifierExpr nw = GetNewVar_IdExpr(tok, locals);
- builder.Add(new Bpl.HavocCmd(tok, new Bpl.IdentifierExprSeq(nw)));
- // assume $nw != null && !$Heap[$nw, alloc] && dtype($nw) == RHS;
- Bpl.Expr nwNotNull = Bpl.Expr.Neq(nw, predef.Null);
- Bpl.Expr rightType;
- if (tRhs.ArrayDimensions != null) {
- // array allocation
- List<Type> typeArgs = new List<Type>();
- typeArgs.Add(tRhs.EType);
- rightType = etran.GoodRef_Ref(tok, nw, new Bpl.IdentifierExpr(tok, "class._System." + BuiltIns.ArrayClassName(tRhs.ArrayDimensions.Count), predef.ClassNameType), typeArgs, true);
- } else if (tRhs.EType is ObjectType) {
- rightType = etran.GoodRef_Ref(tok, nw, new Bpl.IdentifierExpr(Token.NoToken, GetClass(program.BuiltIns.ObjectDecl)), new List<Type>(), true);
- } else {
- rightType = etran.GoodRef_Class(tok, nw, (UserDefinedType)tRhs.EType, true);
- }
- builder.Add(new Bpl.AssumeCmd(tok, Bpl.Expr.And(nwNotNull, rightType)));
- if (tRhs.ArrayDimensions != null) {
- int i = 0;
- foreach (Expression dim in tRhs.ArrayDimensions) {
- // assume Array#Length($nw, i) == arraySize;
- Bpl.Expr arrayLength = ArrayLength(tok, nw, tRhs.ArrayDimensions.Count, i);
- builder.Add(new Bpl.AssumeCmd(tok, Bpl.Expr.Eq(arrayLength, etran.TrExpr(dim))));
- i++;
- }
- }
- // $Heap[$nw, alloc] := true;
- Bpl.Expr alloc = predef.Alloc(tok);
- Bpl.IdentifierExpr heap = (Bpl.IdentifierExpr/*TODO: this cast is dubious*/)etran.HeapExpr;
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(tok, heap, ExpressionTranslator.UpdateHeap(tok, heap, nw, alloc, Bpl.Expr.True));
- builder.Add(cmd);
- if (codeContext is IteratorDecl) {
- var iter = (IteratorDecl)codeContext;
- // $Heap[this, _new] := Set#UnionOne<BoxType>($Heap[this, _new], $Box($nw));
- var th = new Bpl.IdentifierExpr(tok, etran.This, predef.RefType);
- var nwField = new Bpl.IdentifierExpr(tok, GetField(iter.Member_New));
- var thisDotNew = ExpressionTranslator.ReadHeap(tok, etran.HeapExpr, th, nwField);
- var unionOne = FunctionCall(tok, BuiltinFunction.SetUnionOne, predef.BoxType, thisDotNew, FunctionCall(tok, BuiltinFunction.Box, null, nw));
- var heapRhs = ExpressionTranslator.UpdateHeap(tok, etran.HeapExpr, th, nwField, unionOne);
- builder.Add(Bpl.Cmd.SimpleAssign(tok, heap, heapRhs));
- }
- // assume $IsGoodHeap($Heap);
- builder.Add(AssumeGoodHeap(tok, etran));
- if (tRhs.InitCall != null) {
- AddComment(builder, tRhs.InitCall, "init call statement");
- TrCallStmt(tRhs.InitCall, builder, locals, etran, nw);
- }
- // bLhs := $nw;
- builder.Add(Bpl.Cmd.SimpleAssign(tok, bLhs, etran.CondApplyBox(tok, nw, tRhs.Type, lhsType)));
- }
- return bLhs;
- }
-
- void CheckSubrange(IToken tok, Expr bRhs, Type tp, StmtListBuilder builder) {
- Contract.Requires(tok != null);
- Contract.Requires(bRhs != null);
- Contract.Requires(tp != null);
- Contract.Requires(builder != null);
-
- var isNat = CheckSubrange_Expr(tok, bRhs, tp);
- if (isNat != null) {
- builder.Add(Assert(tok, isNat, "value assigned to a nat must be non-negative"));
- }
- }
-
- Bpl.Expr CheckSubrange_Expr(IToken tok, Expr bRhs, Type tp) {
- Contract.Requires(tok != null);
- Contract.Requires(bRhs != null);
- Contract.Requires(tp != null);
-
- if (tp is NatType) {
- return Bpl.Expr.Le(Bpl.Expr.Literal(0), bRhs);
- }
- return null;
- }
-
- void Check_NewRestrictions(IToken tok, Bpl.Expr obj, Field f, Bpl.Expr rhs, StmtListBuilder builder, ExpressionTranslator etran) {
- Contract.Requires(tok != null);
- Contract.Requires(obj != null);
- Contract.Requires(f != null);
- Contract.Requires(rhs != null);
- Contract.Requires(builder != null);
- Contract.Requires(etran != null);
- var iter = f.EnclosingClass as IteratorDecl;
- if (iter != null && f == iter.Member_New) {
- // Assignments to an iterator _new field is only allowed to shrink the set, so:
- // assert Set#Subset(rhs, obj._new);
- var fId = new Bpl.IdentifierExpr(tok, GetField(f));
- var subset = FunctionCall(tok, BuiltinFunction.SetSubset, null, rhs, ExpressionTranslator.ReadHeap(tok, etran.HeapExpr, obj, fId));
- builder.Add(Assert(tok, subset, "an assignment to " + f.Name + " is only allowed to shrink the set"));
- }
- }
-
- Bpl.AssumeCmd AssumeGoodHeap(IToken tok, ExpressionTranslator etran) {
- Contract.Requires(tok != null);
- Contract.Requires(etran != null);
- Contract.Ensures(Contract.Result<AssumeCmd>() != null);
-
- return new Bpl.AssumeCmd(tok, FunctionCall(tok, BuiltinFunction.IsGoodHeap, null, etran.HeapExpr));
- }
-
- // ----- Expression ---------------------------------------------------------------------------
-
- /// <summary>
- /// This class gives a way to represent a Boogie translation target as if it were still a Dafny expression.
- /// </summary>
- internal class BoogieWrapper : Expression
- {
- public readonly Bpl.Expr Expr;
- public BoogieWrapper(Bpl.Expr expr, Type dafnyType)
- : base(expr.tok)
- {
- Contract.Requires(expr != null);
- Contract.Requires(dafnyType != null);
- Expr = expr;
- Type = dafnyType; // resolve immediately
- }
- }
-
- internal class ExpressionTranslator
- {
- public readonly Bpl.Expr HeapExpr;
- public readonly PredefinedDecls predef;
- public readonly Translator translator;
- public readonly string This;
- public readonly string modifiesFrame; // the name of the context's frame variable.
- readonly Function applyLimited_CurrentFunction;
- public readonly int layerOffset = 0;
- public int Statistics_CustomLayerFunctionCount = 0;
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(HeapExpr != null);
- Contract.Invariant(HeapExpr is Bpl.OldExpr || HeapExpr is Bpl.IdentifierExpr);
- Contract.Invariant(predef != null);
- Contract.Invariant(translator != null);
- Contract.Invariant(This != null);
- Contract.Invariant(modifiesFrame != null);
- Contract.Invariant(layerOffset == 0 || layerOffset == 1);
- Contract.Invariant(0 <= Statistics_CustomLayerFunctionCount);
- }
-
- /// <summary>
- /// This is the most general constructor. It is private and takes all the parameters. Whenever
- /// one ExpressionTranslator is constructed from another, unchanged parameters are just copied in.
- /// </summary>
- ExpressionTranslator(Translator translator, PredefinedDecls predef, Bpl.Expr heap, string thisVar,
- Function applyLimited_CurrentFunction, int layerOffset, string modifiesFrame) {
-
- Contract.Requires(translator != null);
- Contract.Requires(predef != null);
- Contract.Requires(heap != null);
- Contract.Requires(thisVar != null);
- Contract.Requires(layerOffset == 0 || layerOffset == 1);
- Contract.Requires(modifiesFrame != null);
-
- this.translator = translator;
- this.predef = predef;
- this.HeapExpr = heap;
- this.This = thisVar;
- this.applyLimited_CurrentFunction = applyLimited_CurrentFunction;
- this.layerOffset = layerOffset;
- this.modifiesFrame = modifiesFrame;
- }
-
- public ExpressionTranslator(Translator translator, PredefinedDecls predef, IToken heapToken)
- : this(translator, predef, new Bpl.IdentifierExpr(heapToken, predef.HeapVarName, predef.HeapType)) {
- Contract.Requires(translator != null);
- Contract.Requires(predef != null);
- Contract.Requires(heapToken != null);
- }
-
- public ExpressionTranslator(Translator translator, PredefinedDecls predef, Bpl.Expr heap)
- : this(translator, predef, heap, "this") {
- Contract.Requires(translator != null);
- Contract.Requires(predef != null);
- Contract.Requires(heap != null);
- }
-
- public ExpressionTranslator(Translator translator, PredefinedDecls predef, Bpl.Expr heap, Bpl.Expr oldHeap)
- : this(translator, predef, heap, "this") {
- Contract.Requires(translator != null);
- Contract.Requires(predef != null);
- Contract.Requires(heap != null);
- Contract.Requires(oldHeap != null);
-
- var old = new ExpressionTranslator(translator, predef, oldHeap);
- old.oldEtran = old;
- this.oldEtran = old;
-
- }
-
- public ExpressionTranslator(Translator translator, PredefinedDecls predef, Bpl.Expr heap, string thisVar)
- : this(translator, predef, heap, thisVar, null, 0, "$_Frame") {
- Contract.Requires(translator != null);
- Contract.Requires(predef != null);
- Contract.Requires(heap != null);
- Contract.Requires(thisVar != null);
- }
-
- public ExpressionTranslator(ExpressionTranslator etran, string modifiesFrame)
- : this(etran.translator, etran.predef, etran.HeapExpr, etran.This, etran.applyLimited_CurrentFunction, etran.layerOffset, modifiesFrame) {
- Contract.Requires(etran != null);
- Contract.Requires(modifiesFrame != null);
- }
-
- ExpressionTranslator oldEtran;
- public ExpressionTranslator Old {
- get {
- Contract.Ensures(Contract.Result<ExpressionTranslator>() != null);
-
- if (oldEtran == null) {
- oldEtran = new ExpressionTranslator(translator, predef, new Bpl.OldExpr(HeapExpr.tok, HeapExpr), This, applyLimited_CurrentFunction, layerOffset, modifiesFrame);
- oldEtran.oldEtran = oldEtran;
- }
- return oldEtran;
- }
- }
-
- public bool UsesOldHeap {
- get {
- return HeapExpr is Bpl.OldExpr;
- }
- }
-
- public ExpressionTranslator LimitedFunctions(Function applyLimited_CurrentFunction) {
- Contract.Requires(applyLimited_CurrentFunction != null);
- Contract.Ensures(Contract.Result<ExpressionTranslator>() != null);
-
- return new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, layerOffset, modifiesFrame);
- }
-
- public ExpressionTranslator LayerOffset(int offset) {
- Contract.Requires(0 <= offset);
- Contract.Requires(layerOffset + offset <= 1);
- Contract.Ensures(Contract.Result<ExpressionTranslator>() != null);
-
- var et = new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, layerOffset + offset, modifiesFrame);
- if (this.oldEtran != null) {
- var etOld = new ExpressionTranslator(translator, predef, Old.HeapExpr, This, applyLimited_CurrentFunction, layerOffset + offset, modifiesFrame);
- etOld.oldEtran = etOld;
- et.oldEtran = etOld;
- }
- return et;
- }
-
- public Bpl.IdentifierExpr TheFrame(IToken tok)
- {
- Contract.Requires(tok != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>() != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>().Type != null);
-
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(tok, "beta");
- Bpl.Type fieldAlpha = predef.FieldName(tok, alpha);
- Bpl.Type ty = new Bpl.MapType(tok, new Bpl.TypeVariableSeq(alpha), new Bpl.TypeSeq(predef.RefType, fieldAlpha), Bpl.Type.Bool);
- return new Bpl.IdentifierExpr(tok, this.modifiesFrame, ty);
- }
-
- public Bpl.IdentifierExpr Tick() {
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>() != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>().Type != null);
-
- return new Bpl.IdentifierExpr(Token.NoToken, "$Tick", predef.TickType);
- }
-
- public Bpl.IdentifierExpr ModuleContextHeight() {
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>().Type != null);
- return new Bpl.IdentifierExpr(Token.NoToken, "$ModuleContextHeight", Bpl.Type.Int);
- }
-
- public Bpl.IdentifierExpr FunctionContextHeight() {
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>().Type != null);
- return new Bpl.IdentifierExpr(Token.NoToken, "$FunctionContextHeight", Bpl.Type.Int);
- }
-
- public Bpl.IdentifierExpr InMethodContext() {
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>().Type != null);
- return new Bpl.IdentifierExpr(Token.NoToken, "$InMethodContext", Bpl.Type.Bool);
- }
-
- public Expression GetSubstitutedBody(LetExpr e) {
- Contract.Requires(e != null);
- var substMap = new Dictionary<IVariable, Expression>();
- Contract.Assert(e.Vars.Count == e.RHSs.Count); // checked by resolution
- for (int i = 0; i < e.Vars.Count; i++) {
- Expression rhs = e.RHSs[i];
- substMap.Add(e.Vars[i], new BoogieWrapper(TrExpr(rhs), rhs.Type));
- }
- return Translator.Substitute(e.Body, null, substMap);
- }
-
-
- /// <summary>
- /// Translates Dafny expression "expr" into a Boogie expression. If the type of "expr" can be a boolean, then the
- /// token (source location) of the resulting expression is filled in (it wouldn't hurt if the token were always
- /// filled in, but it is really necessary for anything that may show up in a Boogie assert, since that location may
- /// then show up in an error message).
- /// </summary>
- public Bpl.Expr TrExpr(Expression expr)
- {
- Contract.Requires(expr != null);
- Contract.Requires(predef != null);
-
- if (expr is LiteralExpr) {
- LiteralExpr e = (LiteralExpr)expr;
- if (e.Value == null) {
- return predef.Null;
- } else if (e.Value is bool) {
- return new Bpl.LiteralExpr(e.tok, (bool)e.Value);
- } else if (e.Value is BigInteger) {
- return Bpl.Expr.Literal(Microsoft.Basetypes.BigNum.FromBigInt((BigInteger)e.Value));
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected literal
- }
-
- } else if (expr is ThisExpr) {
- return new Bpl.IdentifierExpr(expr.tok, This, predef.RefType);
-
- } else if (expr is IdentifierExpr) {
- IdentifierExpr e = (IdentifierExpr)expr;
- return TrVar(expr.tok, cce.NonNull(e.Var));
-
- } else if (expr is BoogieWrapper) {
- var e = (BoogieWrapper)expr;
- return e.Expr;
-
- } else if (expr is SetDisplayExpr) {
- SetDisplayExpr e = (SetDisplayExpr)expr;
- Bpl.Expr s = translator.FunctionCall(expr.tok, BuiltinFunction.SetEmpty, predef.BoxType);
- foreach (Expression ee in e.Elements) {
- Bpl.Expr ss = BoxIfNecessary(expr.tok, TrExpr(ee), cce.NonNull(ee.Type));
- s = translator.FunctionCall(expr.tok, BuiltinFunction.SetUnionOne, predef.BoxType, s, ss);
- }
- return s;
-
- } else if (expr is MultiSetDisplayExpr) {
- MultiSetDisplayExpr e = (MultiSetDisplayExpr)expr;
- Bpl.Expr s = translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetEmpty, predef.BoxType);
- foreach (Expression ee in e.Elements) {
- Bpl.Expr ss = BoxIfNecessary(expr.tok, TrExpr(ee), cce.NonNull(ee.Type));
- s = translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetUnionOne, predef.BoxType, s, ss);
- }
- return s;
-
- } else if (expr is SeqDisplayExpr) {
- SeqDisplayExpr e = (SeqDisplayExpr)expr;
- Bpl.Expr s = translator.FunctionCall(expr.tok, BuiltinFunction.SeqEmpty, predef.BoxType);
- foreach (Expression ee in e.Elements) {
- Bpl.Expr elt = BoxIfNecessary(expr.tok, TrExpr(ee), cce.NonNull(ee.Type));
- s = translator.FunctionCall(expr.tok, BuiltinFunction.SeqBuild, predef.BoxType, s, elt);
- }
- return s;
-
- } else if (expr is MapDisplayExpr) {
- MapDisplayExpr e = (MapDisplayExpr)expr;
- Bpl.Type maptype = predef.MapType(expr.tok, predef.BoxType, predef.BoxType);
- Bpl.Expr s = translator.FunctionCall(expr.tok, "Map#Empty", maptype);
- foreach (ExpressionPair p in e.Elements) {
- Bpl.Expr elt = BoxIfNecessary(expr.tok, TrExpr(p.A), cce.NonNull(p.A.Type));
- Bpl.Expr elt2 = BoxIfNecessary(expr.tok, TrExpr(p.B), cce.NonNull(p.B.Type));
- s = translator.FunctionCall(expr.tok, "Map#Build", maptype, s, elt, elt2);
- }
- return s;
-
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr e = (FieldSelectExpr)expr;
- Contract.Assert(e.Field != null);
- Bpl.Expr obj = TrExpr(e.Obj);
- Bpl.Expr result;
- if (e.Field.IsMutable) {
- result = ReadHeap(expr.tok, HeapExpr, obj, new Bpl.IdentifierExpr(expr.tok, translator.GetField(e.Field)));
- } else {
- result = new Bpl.NAryExpr(expr.tok, new Bpl.FunctionCall(translator.GetReadonlyField(e.Field)), new Bpl.ExprSeq(obj));
- }
- return CondApplyUnbox(expr.tok, result, e.Field.Type, cce.NonNull(expr.Type));
-
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr e = (SeqSelectExpr)expr;
- Bpl.Expr seq = TrExpr(e.Seq);
- Type elmtType = null;
- Type domainType = null;
- Contract.Assert(e.Seq.Type != null); // the expression has been successfully resolved
- if (e.Seq.Type.IsArrayType) {
- domainType = Type.Int;
- elmtType = UserDefinedType.ArrayElementType(e.Seq.Type);
- } else if (e.Seq.Type is SeqType) {
- domainType = Type.Int;
- elmtType = ((SeqType)e.Seq.Type).Arg;
- } else if (e.Seq.Type is MapType) {
- domainType = ((MapType)e.Seq.Type).Domain;
- elmtType = ((MapType)e.Seq.Type).Range;
- } else { Contract.Assert(false); }
- Bpl.Type elType = translator.TrType(elmtType);
- Bpl.Type dType = translator.TrType(domainType);
- Bpl.Expr e0 = e.E0 == null ? null : TrExpr(e.E0);
- Bpl.Expr e1 = e.E1 == null ? null : TrExpr(e.E1);
- if (e.SelectOne) {
- Contract.Assert(e1 == null);
- Bpl.Expr x;
- if (e.Seq.Type.IsArrayType) {
- Bpl.Expr fieldName = translator.FunctionCall(expr.tok, BuiltinFunction.IndexField, null, e0);
- x = ReadHeap(expr.tok, HeapExpr, TrExpr(e.Seq), fieldName);
- } else if(e.Seq.Type is SeqType) {
- x = translator.FunctionCall(expr.tok, BuiltinFunction.SeqIndex, predef.BoxType, seq, e0);
- } else if (e.Seq.Type is MapType) {
- x = translator.FunctionCall(expr.tok, BuiltinFunction.MapElements, predef.MapType(e.tok, predef.BoxType, predef.BoxType), seq);
- x = Bpl.Expr.Select(x, BoxIfNecessary(e.tok, e0, domainType));
- } else { Contract.Assert(false); x = null; }
- if (!ModeledAsBoxType(elmtType)) {
- x = translator.FunctionCall(expr.tok, BuiltinFunction.Unbox, elType, x);
- }
- return x;
- } else {
- if (e.Seq.Type.IsArrayType) {
- seq = translator.FunctionCall(expr.tok, BuiltinFunction.SeqFromArray, elType, HeapExpr, seq);
- }
- if (e1 != null) {
- seq = translator.FunctionCall(expr.tok, BuiltinFunction.SeqTake, elType, seq, e1);
- }
- if (e0 != null) {
- seq = translator.FunctionCall(expr.tok, BuiltinFunction.SeqDrop, elType, seq, e0);
- }
- // if e0 == null && e1 == null, then we have the identity operation seq[..] == seq;
- return seq;
- }
-
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr e = (SeqUpdateExpr)expr;
- Bpl.Expr seq = TrExpr(e.Seq);
- if (e.Seq.Type is SeqType) {
- Type elmtType = cce.NonNull((SeqType)e.Seq.Type).Arg;
- Bpl.Expr index = TrExpr(e.Index);
- Bpl.Expr val = BoxIfNecessary(expr.tok, TrExpr(e.Value), elmtType);
- return translator.FunctionCall(expr.tok, BuiltinFunction.SeqUpdate, predef.BoxType, seq, index, val);
- } else {
- Contract.Assert(e.Seq.Type is MapType);
- MapType mt = (MapType)e.Seq.Type;
- Bpl.Type maptype = predef.MapType(expr.tok, predef.BoxType, predef.BoxType);
- Bpl.Expr index = BoxIfNecessary(expr.tok, TrExpr(e.Index), mt.Domain);
- Bpl.Expr val = BoxIfNecessary(expr.tok, TrExpr(e.Value), mt.Range);
- return translator.FunctionCall(expr.tok, "Map#Build", maptype, seq, index, val);
- }
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr e = (MultiSelectExpr)expr;
- Type elmtType = UserDefinedType.ArrayElementType(e.Array.Type);;
- Bpl.Type elType = translator.TrType(elmtType);
-
- Bpl.Expr fieldName = GetArrayIndexFieldName(expr.tok, e.Indices);
- Bpl.Expr x = ReadHeap(expr.tok, HeapExpr, TrExpr(e.Array), fieldName);
- if (!ModeledAsBoxType(elmtType)) {
- x = translator.FunctionCall(expr.tok, BuiltinFunction.Unbox, elType, x);
- }
- return x;
-
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- int offsetToUse = e.Function.IsRecursive ? this.layerOffset : 0;
- if (e.Function.IsRecursive) {
- Statistics_CustomLayerFunctionCount++;
- }
- string nm = FunctionName(e.Function, 1 + offsetToUse);
- if (this.applyLimited_CurrentFunction != null && e.Function.IsRecursive) {
- ModuleDefinition module = cce.NonNull(e.Function.EnclosingClass).Module;
- if (module == cce.NonNull(applyLimited_CurrentFunction.EnclosingClass).Module) {
- if (module.CallGraph.GetSCCRepresentative(e.Function) == module.CallGraph.GetSCCRepresentative(applyLimited_CurrentFunction)) {
- nm = FunctionName(e.Function, 0 + offsetToUse);
- }
- }
- }
- Bpl.IdentifierExpr id = new Bpl.IdentifierExpr(expr.tok, nm, translator.TrType(cce.NonNull(e.Type)));
- Bpl.ExprSeq args = FunctionInvocationArguments(e);
- Bpl.Expr result = new Bpl.NAryExpr(expr.tok, new Bpl.FunctionCall(id), args);
- return CondApplyUnbox(expr.tok, result, e.Function.ResultType, expr.Type);
-
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- Contract.Assert(dtv.Ctor != null); // since dtv has been successfully resolved
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- for (int i = 0; i < dtv.Arguments.Count; i++) {
- Expression arg = dtv.Arguments[i];
- Type t = dtv.Ctor.Formals[i].Type;
- var bArg = TrExpr(arg);
- args.Add(CondApplyBox(expr.tok, bArg, cce.NonNull(arg.Type), t));
- }
- Bpl.IdentifierExpr id = new Bpl.IdentifierExpr(dtv.tok, dtv.Ctor.FullName, predef.DatatypeType);
- return new Bpl.NAryExpr(dtv.tok, new Bpl.FunctionCall(id), args);
-
- } else if (expr is OldExpr) {
- OldExpr e = (OldExpr)expr;
- return Old.TrExpr(e.E);
-
- } else if (expr is MultiSetFormingExpr) {
- MultiSetFormingExpr e = (MultiSetFormingExpr)expr;
- if (e.E.Type is SetType) {
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetFromSet, translator.TrType(cce.NonNull((SetType)e.E.Type).Arg), TrExpr(e.E));
- } else if (e.E.Type is SeqType) {
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetFromSeq, translator.TrType(cce.NonNull((SeqType)e.E.Type).Arg), TrExpr(e.E));
- } else {
- Contract.Assert(false); throw new cce.UnreachableException();
- }
-
-
- } else if (expr is FreshExpr) {
- FreshExpr e = (FreshExpr)expr;
- if (e.E.Type is SetType) {
- // generate: (forall $o: ref :: $o != null && X[Box($o)] ==> !old($Heap)[$o,alloc])
- // TODO: trigger?
- Bpl.Variable oVar = new Bpl.BoundVariable(expr.tok, new Bpl.TypedIdent(expr.tok, "$o", predef.RefType));
- Bpl.Expr o = new Bpl.IdentifierExpr(expr.tok, oVar);
- Bpl.Expr oNotNull = Bpl.Expr.Neq(o, predef.Null);
- Bpl.Expr oInSet = TrInSet(expr.tok, o, e.E, ((SetType)e.E.Type).Arg);
- Bpl.Expr oIsFresh = Bpl.Expr.Not(Old.IsAlloced(expr.tok, o));
- Bpl.Expr body = Bpl.Expr.Imp(Bpl.Expr.And(oNotNull, oInSet), oIsFresh);
- return new Bpl.ForallExpr(expr.tok, new Bpl.VariableSeq(oVar), body);
- } else if (e.E.Type is SeqType) {
- // generate: (forall $i: int :: 0 <= $i && $i < Seq#Length(X) && Unbox(Seq#Index(X,$i)) != null && !old($Heap)[Seq#Index(X,$i),alloc])
- // TODO: trigger?
- Bpl.Variable iVar = new Bpl.BoundVariable(expr.tok, new Bpl.TypedIdent(expr.tok, "$i", Bpl.Type.Int));
- Bpl.Expr i = new Bpl.IdentifierExpr(expr.tok, iVar);
- Bpl.Expr iBounds = translator.InSeqRange(expr.tok, i, TrExpr(e.E), true, null, false);
- Bpl.Expr XsubI = translator.FunctionCall(expr.tok, BuiltinFunction.SeqIndex, predef.RefType, TrExpr(e.E), i);
- Bpl.Expr oIsFresh = Bpl.Expr.Not(Old.IsAlloced(expr.tok, XsubI));
- Bpl.Expr xsubiNotNull = Bpl.Expr.Neq(translator.FunctionCall(expr.tok, BuiltinFunction.Unbox, predef.RefType, XsubI), predef.Null);
- Bpl.Expr body = Bpl.Expr.And(Bpl.Expr.And(iBounds, xsubiNotNull), oIsFresh);
- return new Bpl.ForallExpr(expr.tok, new Bpl.VariableSeq(iVar), body);
- } else if (e.E.Type.IsDatatype) {
- Bpl.Expr alloc = translator.FunctionCall(e.tok, BuiltinFunction.DtAlloc, null, TrExpr(e.E), Old.HeapExpr);
- return Bpl.Expr.Not(alloc);
- } else {
- // generate: x != null && !old($Heap)[x]
- Bpl.Expr oNull = Bpl.Expr.Neq(TrExpr(e.E), predef.Null);
- Bpl.Expr oIsFresh = Bpl.Expr.Not(Old.IsAlloced(expr.tok, TrExpr(e.E)));
- return Bpl.Expr.And(oNull, oIsFresh);
- }
-
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- Bpl.Expr arg = TrExpr(e.E);
- switch (e.Op) {
- case UnaryExpr.Opcode.Not:
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, arg);
- case UnaryExpr.Opcode.SetChoose:
- var x = translator.FunctionCall(expr.tok, BuiltinFunction.SetChoose, predef.BoxType, arg, Tick());
- if (!ModeledAsBoxType(e.Type)) {
- x = translator.FunctionCall(expr.tok, BuiltinFunction.Unbox, translator.TrType(e.Type), x);
- }
- return x;
- case UnaryExpr.Opcode.SeqLength:
- if (e.E.Type is SeqType) {
- return translator.FunctionCall(expr.tok, BuiltinFunction.SeqLength, null, arg);
- } else {
- return translator.ArrayLength(expr.tok, arg, 1, 0);
- }
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected unary expression
- }
-
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- Bpl.Expr e0 = TrExpr(e.E0);
- if (e.ResolvedOp == BinaryExpr.ResolvedOpcode.InSet) {
- return TrInSet(expr.tok, e0, e.E1, cce.NonNull(e.E0.Type)); // let TrInSet translate e.E1
- } else if (e.ResolvedOp == BinaryExpr.ResolvedOpcode.NotInSet) {
- Bpl.Expr arg = TrInSet(expr.tok, e0, e.E1, cce.NonNull(e.E0.Type)); // let TrInSet translate e.E1
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, arg);
- } else if (e.ResolvedOp == BinaryExpr.ResolvedOpcode.InMultiSet) {
- return TrInMultiSet(expr.tok, e0, e.E1, cce.NonNull(e.E0.Type)); // let TrInMultiSet translate e.E1
- } else if (e.ResolvedOp == BinaryExpr.ResolvedOpcode.NotInMultiSet) {
- Bpl.Expr arg = TrInMultiSet(expr.tok, e0, e.E1, cce.NonNull(e.E0.Type)); // let TrInMultiSet translate e.E1
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, arg);
- }
- Bpl.Expr e1 = TrExpr(e.E1);
- BinaryOperator.Opcode bOpcode;
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.Iff:
- bOpcode = BinaryOperator.Opcode.Iff; break;
- case BinaryExpr.ResolvedOpcode.Imp:
- bOpcode = BinaryOperator.Opcode.Imp; break;
- case BinaryExpr.ResolvedOpcode.And:
- bOpcode = BinaryOperator.Opcode.And; break;
- case BinaryExpr.ResolvedOpcode.Or:
- bOpcode = BinaryOperator.Opcode.Or; break;
-
- case BinaryExpr.ResolvedOpcode.EqCommon:
- bOpcode = BinaryOperator.Opcode.Eq; break;
- case BinaryExpr.ResolvedOpcode.NeqCommon:
- bOpcode = BinaryOperator.Opcode.Neq; break;
-
- case BinaryExpr.ResolvedOpcode.Lt:
- bOpcode = BinaryOperator.Opcode.Lt; break;
- case BinaryExpr.ResolvedOpcode.Le:
- bOpcode = BinaryOperator.Opcode.Le; break;
- case BinaryExpr.ResolvedOpcode.Ge:
- bOpcode = BinaryOperator.Opcode.Ge; break;
- case BinaryExpr.ResolvedOpcode.Gt:
- bOpcode = BinaryOperator.Opcode.Gt; break;
- case BinaryExpr.ResolvedOpcode.Add:
- bOpcode = BinaryOperator.Opcode.Add; break;
- case BinaryExpr.ResolvedOpcode.Sub:
- bOpcode = BinaryOperator.Opcode.Sub; break;
- case BinaryExpr.ResolvedOpcode.Mul:
- bOpcode = BinaryOperator.Opcode.Mul; break;
- case BinaryExpr.ResolvedOpcode.Div:
- bOpcode = BinaryOperator.Opcode.Div; break;
- case BinaryExpr.ResolvedOpcode.Mod:
- bOpcode = BinaryOperator.Opcode.Mod; break;
-
- case BinaryExpr.ResolvedOpcode.SetEq:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SetEqual, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.SetNeq:
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, translator.FunctionCall(expr.tok, BuiltinFunction.SetEqual, null, e0, e1));
- case BinaryExpr.ResolvedOpcode.ProperSubset:
- return Bpl.Expr.Binary(expr.tok, BinaryOperator.Opcode.And,
- translator.FunctionCall(expr.tok, BuiltinFunction.SetSubset, null, e0, e1),
- Bpl.Expr.Not(translator.FunctionCall(expr.tok, BuiltinFunction.SetEqual, null, e0, e1)));
- case BinaryExpr.ResolvedOpcode.Subset:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SetSubset, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.Superset:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SetSubset, null, e1, e0);
- case BinaryExpr.ResolvedOpcode.ProperSuperset:
- return Bpl.Expr.Binary(expr.tok, BinaryOperator.Opcode.And,
- translator.FunctionCall(expr.tok, BuiltinFunction.SetSubset, null, e1, e0),
- Bpl.Expr.Not(translator.FunctionCall(expr.tok, BuiltinFunction.SetEqual, null, e0, e1)));
- case BinaryExpr.ResolvedOpcode.Disjoint:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SetDisjoint, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.InSet:
- Contract.Assert(false); throw new cce.UnreachableException(); // this case handled above
- case BinaryExpr.ResolvedOpcode.NotInSet:
- Contract.Assert(false); throw new cce.UnreachableException(); // this case handled above
- case BinaryExpr.ResolvedOpcode.Union:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SetUnion, translator.TrType(cce.NonNull((SetType)expr.Type).Arg), e0, e1);
- case BinaryExpr.ResolvedOpcode.Intersection:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SetIntersection, translator.TrType(cce.NonNull((SetType)expr.Type).Arg), e0, e1);
- case BinaryExpr.ResolvedOpcode.SetDifference:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SetDifference, translator.TrType(cce.NonNull((SetType)expr.Type).Arg), e0, e1);
-
- case BinaryExpr.ResolvedOpcode.MultiSetEq:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetEqual, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.MultiSetNeq:
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetEqual, null, e0, e1));
- case BinaryExpr.ResolvedOpcode.MapEq:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MapEqual, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.MapNeq:
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, translator.FunctionCall(expr.tok, BuiltinFunction.MapEqual, null, e0, e1));
- case BinaryExpr.ResolvedOpcode.ProperMultiSubset:
- return Bpl.Expr.Binary(expr.tok, BinaryOperator.Opcode.And,
- translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetSubset, null, e0, e1),
- Bpl.Expr.Not(translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetEqual, null, e0, e1)));
- case BinaryExpr.ResolvedOpcode.MultiSubset:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetSubset, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.MultiSuperset:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetSubset, null, e1, e0);
- case BinaryExpr.ResolvedOpcode.ProperMultiSuperset:
- return Bpl.Expr.Binary(expr.tok, BinaryOperator.Opcode.And,
- translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetSubset, null, e1, e0),
- Bpl.Expr.Not(translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetEqual, null, e0, e1)));
- case BinaryExpr.ResolvedOpcode.MultiSetDisjoint:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetDisjoint, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.InMultiSet:
- Contract.Assert(false); throw new cce.UnreachableException(); // this case handled above
- case BinaryExpr.ResolvedOpcode.NotInMultiSet:
- Contract.Assert(false); throw new cce.UnreachableException(); // this case handled above
- case BinaryExpr.ResolvedOpcode.MultiSetUnion:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetUnion, translator.TrType(cce.NonNull((MultiSetType)expr.Type).Arg), e0, e1);
- case BinaryExpr.ResolvedOpcode.MultiSetIntersection:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetIntersection, translator.TrType(cce.NonNull((MultiSetType)expr.Type).Arg), e0, e1);
- case BinaryExpr.ResolvedOpcode.MultiSetDifference:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MultiSetDifference, translator.TrType(cce.NonNull((MultiSetType)expr.Type).Arg), e0, e1);
-
- case BinaryExpr.ResolvedOpcode.SeqEq:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SeqEqual, null, e0, e1);
- case BinaryExpr.ResolvedOpcode.SeqNeq:
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, translator.FunctionCall(expr.tok, BuiltinFunction.SeqEqual, null, e0, e1));
- case BinaryExpr.ResolvedOpcode.ProperPrefix:
- return ProperPrefix(expr.tok, e0, e1);
- case BinaryExpr.ResolvedOpcode.Prefix:
- {
- Bpl.Expr len0 = translator.FunctionCall(expr.tok, BuiltinFunction.SeqLength, null, e0);
- Bpl.Expr len1 = translator.FunctionCall(expr.tok, BuiltinFunction.SeqLength, null, e1);
- return Bpl.Expr.Binary(expr.tok, BinaryOperator.Opcode.And,
- Bpl.Expr.Le(len0, len1),
- translator.FunctionCall(expr.tok, BuiltinFunction.SeqSameUntil, null, e0, e1, len0));
- }
- case BinaryExpr.ResolvedOpcode.Concat:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SeqAppend, translator.TrType(cce.NonNull((SeqType)expr.Type).Arg), e0, e1);
- case BinaryExpr.ResolvedOpcode.InSeq:
- return translator.FunctionCall(expr.tok, BuiltinFunction.SeqContains, null, e1,
- BoxIfNecessary(expr.tok, e0, cce.NonNull(e.E0.Type)));
- case BinaryExpr.ResolvedOpcode.NotInSeq:
- Bpl.Expr arg = translator.FunctionCall(expr.tok, BuiltinFunction.SeqContains, null, e1,
- BoxIfNecessary(expr.tok, e0, cce.NonNull(e.E0.Type)));
- return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, arg);
- case BinaryExpr.ResolvedOpcode.InMap:
- return Bpl.Expr.Select(translator.FunctionCall(expr.tok, BuiltinFunction.MapDomain, predef.MapType(e.tok, predef.BoxType, predef.BoxType), e1),
- BoxIfNecessary(expr.tok, e0, e.E0.Type));
- case BinaryExpr.ResolvedOpcode.NotInMap:
- return Bpl.Expr.Not(Bpl.Expr.Select(translator.FunctionCall(expr.tok, BuiltinFunction.MapDomain, predef.MapType(e.tok, predef.BoxType, predef.BoxType), e1),
- BoxIfNecessary(expr.tok, e0, e.E0.Type)));
- case BinaryExpr.ResolvedOpcode.MapDisjoint:
- return translator.FunctionCall(expr.tok, BuiltinFunction.MapDisjoint, null, e0, e1);
-
- case BinaryExpr.ResolvedOpcode.RankLt:
- return Bpl.Expr.Binary(expr.tok, BinaryOperator.Opcode.Lt,
- translator.FunctionCall(expr.tok, BuiltinFunction.DtRank, null, e0),
- translator.FunctionCall(expr.tok, BuiltinFunction.DtRank, null, e1));
- case BinaryExpr.ResolvedOpcode.RankGt:
- return Bpl.Expr.Binary(expr.tok, BinaryOperator.Opcode.Gt,
- translator.FunctionCall(expr.tok, BuiltinFunction.DtRank, null, e0),
- translator.FunctionCall(expr.tok, BuiltinFunction.DtRank, null, e1));
-
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected binary expression
- }
- return Bpl.Expr.Binary(expr.tok, bOpcode, e0, e1);
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- return TrExpr(GetSubstitutedBody(e));
- } else if (expr is NamedExpr) {
- return TrExpr(((NamedExpr)expr).Body);
- } else if (expr is QuantifierExpr) {
- QuantifierExpr e = (QuantifierExpr)expr;
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- Bpl.Expr typeAntecedent = TrBoundVariables(e.BoundVars, bvars);
- Bpl.QKeyValue kv = TrAttributes(e.Attributes, "trigger");
- Bpl.Trigger tr = null;
- for (Attributes aa = e.Attributes; aa != null; aa = aa.Prev) {
- if (aa.Name == "trigger") {
- Bpl.ExprSeq tt = new Bpl.ExprSeq();
- foreach (var arg in aa.Args) {
- if (arg.E == null) {
- Console.WriteLine("Warning: string argument to 'trigger' attribute ignored");
- } else {
- tt.Add(TrExpr(arg.E));
- }
- }
- tr = new Bpl.Trigger(expr.tok, true, tt, tr);
- }
- }
- var antecedent = typeAntecedent;
- if (e.Range != null) {
- antecedent = Bpl.Expr.And(antecedent, TrExpr(e.Range));
- }
- Bpl.Expr body = TrExpr(e.Term);
-
- if (e is ForallExpr) {
- return new Bpl.ForallExpr(expr.tok, new Bpl.TypeVariableSeq(), bvars, kv, tr, Bpl.Expr.Imp(antecedent, body));
- } else {
- Contract.Assert(e is ExistsExpr);
- return new Bpl.ExistsExpr(expr.tok, new Bpl.TypeVariableSeq(), bvars, kv, tr, Bpl.Expr.And(antecedent, body));
- }
-
- } else if (expr is SetComprehension) {
- var e = (SetComprehension)expr;
- // Translate "set xs | R :: T" into "lambda y: BoxType :: (exists xs :: CorrectType(xs) && R && y==Box(T))".
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- Bpl.Expr typeAntecedent = TrBoundVariables(e.BoundVars, bvars);
- Bpl.QKeyValue kv = TrAttributes(e.Attributes, null);
-
- var yVar = new Bpl.BoundVariable(expr.tok, new Bpl.TypedIdent(expr.tok, "$y#" + translator.otherTmpVarCount, predef.BoxType));
- translator.otherTmpVarCount++;
- Bpl.Expr y = new Bpl.IdentifierExpr(expr.tok, yVar);
-
- var eq = Bpl.Expr.Eq(y, BoxIfNecessary(expr.tok, TrExpr(e.Term), e.Term.Type));
- var ebody = Bpl.Expr.And(translator.BplAnd(typeAntecedent, TrExpr(e.Range)), eq);
- var exst = new Bpl.ExistsExpr(expr.tok, bvars, ebody);
-
- return new Bpl.LambdaExpr(expr.tok, new Bpl.TypeVariableSeq(), new VariableSeq(yVar), kv, exst);
-
- } else if (expr is MapComprehension) {
- var e = (MapComprehension)expr;
- // Translate "map x | R :: T" into
- // Map#Glue(lambda y: BoxType :: [unbox(y)/x]R,
- // lambda y: BoxType :: [unbox(y)/x]T)".
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- var bv = e.BoundVars[0];
- TrBoundVariables(e.BoundVars, bvars);
-
- Bpl.QKeyValue kv = TrAttributes(e.Attributes, null);
-
- var yVar = new Bpl.BoundVariable(expr.tok, new Bpl.TypedIdent(expr.tok, "$y#" + translator.otherTmpVarCount, predef.BoxType));
- translator.otherTmpVarCount++;
-
- Bpl.Expr unboxy = !ModeledAsBoxType(bv.Type) ? translator.FunctionCall(e.tok, BuiltinFunction.Unbox, translator.TrType(bv.Type), new Bpl.IdentifierExpr(expr.tok, yVar))
- : (Bpl.Expr)(new Bpl.IdentifierExpr(expr.tok, yVar));
- Bpl.Expr typeAntecedent = translator.GetWhereClause(bv.tok, unboxy, bv.Type, this);
-
-
- Dictionary<IVariable, Expression> subst = new Dictionary<IVariable,Expression>();
- subst.Add(e.BoundVars[0], new BoogieWrapper(unboxy,e.BoundVars[0].Type));
-
- var ebody = translator.BplAnd(typeAntecedent ?? Bpl.Expr.True, TrExpr(Substitute(e.Range, null, subst)));
- Bpl.Expr l1 = new Bpl.LambdaExpr(e.tok, new Bpl.TypeVariableSeq(), new VariableSeq(yVar), kv, ebody);
- ebody = TrExpr(Substitute(e.Term, null, subst));
- Bpl.Expr l2 = new Bpl.LambdaExpr(e.tok, new Bpl.TypeVariableSeq(), new VariableSeq(yVar), kv, BoxIfNecessary(expr.tok, ebody, e.Term.Type));
-
-
- return translator.FunctionCall(e.tok, BuiltinFunction.MapGlue, null, l1, l2);
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- return TrExpr(e.Body);
-
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- Bpl.Expr g = TrExpr(e.Test);
- Bpl.Expr thn = TrExpr(e.Thn);
- Bpl.Expr els = TrExpr(e.Els);
- return new NAryExpr(expr.tok, new IfThenElse(expr.tok), new ExprSeq(g, thn, els));
-
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return TrExpr(e.ResolvedExpression);
-
- } else if (expr is BoxingCastExpr) {
- BoxingCastExpr e = (BoxingCastExpr)expr;
- return CondApplyBox(e.tok, TrExpr(e.E), e.FromType, e.ToType);
-
- } else if (expr is UnboxingCastExpr) {
- UnboxingCastExpr e = (UnboxingCastExpr)expr;
- return CondApplyUnbox(e.tok, TrExpr(e.E), e.FromType, e.ToType);
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
- }
- }
-
- public Bpl.Expr TrBoundVariables(List<BoundVar/*!*/> boundVars, Bpl.VariableSeq bvars) {
- return TrBoundVariables(boundVars, bvars, false);
- }
-
- public Bpl.Expr TrBoundVariables(List<BoundVar/*!*/> boundVars, Bpl.VariableSeq bvars, bool translateAsLocals) {
- Contract.Requires(boundVars != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- Bpl.Expr typeAntecedent = Bpl.Expr.True;
- foreach (BoundVar bv in boundVars) {
- var tid = new Bpl.TypedIdent(bv.tok, bv.UniqueName, translator.TrType(bv.Type));
- Bpl.Variable bvar;
- if (translateAsLocals) {
- bvar = new Bpl.LocalVariable(bv.tok, tid);
- } else {
- bvar = new Bpl.BoundVariable(bv.tok, tid);
- }
- bvars.Add(bvar);
- Bpl.Expr wh = translator.GetWhereClause(bv.tok, new Bpl.IdentifierExpr(bv.tok, bvar), bv.Type, this);
- if (wh != null) {
- typeAntecedent = translator.BplAnd(typeAntecedent, wh);
- }
- }
- return typeAntecedent;
- }
-
- public Bpl.Expr TrBoundVariablesRename(List<BoundVar> boundVars, Bpl.VariableSeq bvars, out Dictionary<IVariable, Expression> substMap) {
- Contract.Requires(boundVars != null);
- Contract.Requires(bvars != null);
-
- substMap = new Dictionary<IVariable, Expression>();
- Bpl.Expr typeAntecedent = Bpl.Expr.True;
- foreach (BoundVar bv in boundVars) {
- var newBoundVar = new BoundVar(bv.tok, bv.Name, bv.Type);
- IdentifierExpr ie = new IdentifierExpr(newBoundVar.tok, newBoundVar.UniqueName);
- ie.Var = newBoundVar; ie.Type = ie.Var.Type; // resolve ie here
- substMap.Add(bv, ie);
- Bpl.Variable bvar = new Bpl.BoundVariable(newBoundVar.tok, new Bpl.TypedIdent(newBoundVar.tok, newBoundVar.UniqueName, translator.TrType(newBoundVar.Type)));
- bvars.Add(bvar);
- var bIe = new Bpl.IdentifierExpr(bvar.tok, bvar);
- Bpl.Expr wh = translator.GetWhereClause(bv.tok, bIe, newBoundVar.Type, this);
- if (wh != null) {
- typeAntecedent = translator.BplAnd(typeAntecedent, wh);
- }
- }
- return typeAntecedent;
- }
-
- public ExprSeq FunctionInvocationArguments(FunctionCallExpr e) {
- Contract.Requires(e != null);
- Contract.Ensures(Contract.Result<ExprSeq>() != null);
-
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- args.Add(HeapExpr);
- if (!e.Function.IsStatic) {
- args.Add(TrExpr(e.Receiver));
- }
- for (int i = 0; i < e.Args.Count; i++) {
- Expression ee = e.Args[i];
- Type t = e.Function.Formals[i].Type;
- args.Add(CondApplyBox(e.tok, TrExpr(ee), cce.NonNull(ee.Type), t));
- }
- return args;
- }
-
- public Bpl.Expr GetArrayIndexFieldName(IToken tok, List<Expression> indices) {
- Bpl.Expr fieldName = null;
- foreach (Expression idx in indices) {
- Bpl.Expr index = TrExpr(idx);
- if (fieldName == null) {
- // the index in dimension 0: IndexField(index0)
- fieldName = translator.FunctionCall(tok, BuiltinFunction.IndexField, null, index);
- } else {
- // the index in dimension n: MultiIndexField(...field name for first n indices..., index_n)
- fieldName = translator.FunctionCall(tok, BuiltinFunction.MultiIndexField, null, fieldName, index);
- }
- }
- return fieldName;
- }
-
- public Bpl.Expr ProperSubset(IToken tok, Bpl.Expr e0, Bpl.Expr e1) {
- Contract.Requires(tok != null);
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- return Bpl.Expr.And(
- translator.FunctionCall(tok, BuiltinFunction.SetSubset, null, e0, e1),
- Bpl.Expr.Not(translator.FunctionCall(tok, BuiltinFunction.SetSubset, null, e1, e0)));
- }
- public Bpl.Expr ProperPrefix(IToken tok, Bpl.Expr e0, Bpl.Expr e1) {
- Contract.Requires(tok != null);
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
- Bpl.Expr len0 = translator.FunctionCall(tok, BuiltinFunction.SeqLength, null, e0);
- Bpl.Expr len1 = translator.FunctionCall(tok, BuiltinFunction.SeqLength, null, e1);
- return Bpl.Expr.And(
- Bpl.Expr.Lt(len0, len1),
- translator.FunctionCall(tok, BuiltinFunction.SeqSameUntil, null, e0, e1, len0));
- }
-
- public Bpl.Expr CondApplyBox(IToken tok, Bpl.Expr e, Type fromType, Type toType) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(fromType != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (!ModeledAsBoxType(fromType) && (toType == null || ModeledAsBoxType(toType))) {
- return translator.FunctionCall(tok, BuiltinFunction.Box, null, e);
- } else {
- return e;
- }
- }
-
- public Bpl.Expr BoxIfNecessary(IToken tok, Bpl.Expr e, Type fromType) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(fromType != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- return CondApplyBox(tok, e, fromType, null);
- }
-
- public Bpl.Expr CondApplyUnbox(IToken tok, Bpl.Expr e, Type fromType, Type toType) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(fromType != null);
- Contract.Requires(toType != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (ModeledAsBoxType(fromType) && !ModeledAsBoxType(toType)) {
- return translator.FunctionCall(tok, BuiltinFunction.Unbox, translator.TrType(toType), e);
- } else {
- return e;
- }
- }
-
- public static bool ModeledAsBoxType(Type t) {
- Contract.Requires(t != null);
- while (true) {
- TypeProxy tp = t as TypeProxy;
- if (tp == null) {
- break;
- } else if (tp.T == null) {
- // unresolved proxy
- return false;
- } else {
- t = tp.T;
- }
- }
- return t.IsTypeParameter;
- }
-
- public Bpl.IdentifierExpr TrVar(IToken tok, IVariable var) {
- Contract.Requires(var != null);
- Contract.Requires(tok != null);
- Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>() != null);
-
- return new Bpl.IdentifierExpr(tok, var.UniqueName, translator.TrType(var.Type));
- }
-
- public static Bpl.NAryExpr ReadHeap(IToken tok, Expr heap, Expr r, Expr f) {
- Contract.Requires(tok != null);
- Contract.Requires(heap != null);
- Contract.Requires(r != null);
- Contract.Requires(f != null);
- Contract.Ensures(Contract.Result<Bpl.NAryExpr>() != null);
-
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- args.Add(heap);
- args.Add(r);
- args.Add(f);
- Bpl.Type t = (f.Type != null) ? f.Type : f.ShallowType;
- return new Bpl.NAryExpr(tok,
- new Bpl.FunctionCall(new Bpl.IdentifierExpr(tok, "read", t.AsCtor.Arguments[0])),
- args);
- }
-
- public static Bpl.NAryExpr UpdateHeap(IToken tok, Expr heap, Expr r, Expr f, Expr v) {
- Contract.Requires(tok != null);
- Contract.Requires(heap != null);
- Contract.Requires(r != null);
- Contract.Requires(f != null);
- Contract.Requires(v != null);
- Contract.Ensures(Contract.Result<Bpl.NAryExpr>() != null);
-
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- args.Add(heap);
- args.Add(r);
- args.Add(f);
- args.Add(v);
- return new Bpl.NAryExpr(tok,
- new Bpl.FunctionCall(new Bpl.IdentifierExpr(tok, "update", heap.Type)),
- args);
- }
-
- /// <summary>
- /// Translate like s[Box(elmt)], but try to avoid as many set functions as possible in the
- /// translation, because such functions can mess up triggering.
- /// </summary>
- public Bpl.Expr TrInSet(IToken tok, Bpl.Expr elmt, Expression s, Type elmtType) {
- Contract.Requires(tok != null);
- Contract.Requires(elmt != null);
- Contract.Requires(s != null);
- Contract.Requires(elmtType != null);
-
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (s is BinaryExpr) {
- BinaryExpr bin = (BinaryExpr)s;
- switch (bin.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.Union:
- return Bpl.Expr.Or(TrInSet(tok, elmt, bin.E0, elmtType), TrInSet(tok, elmt, bin.E1, elmtType));
- case BinaryExpr.ResolvedOpcode.Intersection:
- return Bpl.Expr.And(TrInSet(tok, elmt, bin.E0, elmtType), TrInSet(tok, elmt, bin.E1, elmtType));
- case BinaryExpr.ResolvedOpcode.SetDifference:
- return Bpl.Expr.And(TrInSet(tok, elmt, bin.E0, elmtType), Bpl.Expr.Not(TrInSet(tok, elmt, bin.E1, elmtType)));
- default:
- break;
- }
- } else if (s is SetDisplayExpr) {
- SetDisplayExpr disp = (SetDisplayExpr)s;
- Bpl.Expr disjunction = null;
- foreach (Expression a in disp.Elements) {
- Bpl.Expr disjunct = Bpl.Expr.Eq(elmt, TrExpr(a));
- if (disjunction == null) {
- disjunction = disjunct;
- } else {
- disjunction = Bpl.Expr.Or(disjunction, disjunct);
- }
- }
- if (disjunction == null) {
- return Bpl.Expr.False;
- } else {
- return disjunction;
- }
- }
- return Bpl.Expr.SelectTok(tok, TrExpr(s), BoxIfNecessary(tok, elmt, elmtType));
- }
-
- /// <summary>
- /// Translate like 0 < s[Box(elmt)], but try to avoid as many set functions as possible in the
- /// translation, because such functions can mess up triggering.
- /// </summary>
- public Bpl.Expr TrInMultiSet(IToken tok, Bpl.Expr elmt, Expression s, Type elmtType) {
- Contract.Requires(tok != null);
- Contract.Requires(elmt != null);
- Contract.Requires(s != null);
- Contract.Requires(elmtType != null);
-
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (s is BinaryExpr) {
- BinaryExpr bin = (BinaryExpr)s;
- switch (bin.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.MultiSetUnion:
- return Bpl.Expr.Or(TrInMultiSet(tok, elmt, bin.E0, elmtType), TrInMultiSet(tok, elmt, bin.E1, elmtType));
- case BinaryExpr.ResolvedOpcode.MultiSetIntersection:
- return Bpl.Expr.And(TrInMultiSet(tok, elmt, bin.E0, elmtType), TrInMultiSet(tok, elmt, bin.E1, elmtType));
- default:
- break;
- }
- } else if (s is MultiSetDisplayExpr) {
- MultiSetDisplayExpr disp = (MultiSetDisplayExpr)s;
- Bpl.Expr disjunction = null;
- foreach (Expression a in disp.Elements) {
- Bpl.Expr disjunct = Bpl.Expr.Eq(elmt, TrExpr(a));
- if (disjunction == null) {
- disjunction = disjunct;
- } else {
- disjunction = Bpl.Expr.Or(disjunction, disjunct);
- }
- }
- if (disjunction == null) {
- return Bpl.Expr.False;
- } else {
- return disjunction;
- }
- }
- return Bpl.Expr.Gt(Bpl.Expr.SelectTok(tok, TrExpr(s), BoxIfNecessary(tok, elmt, elmtType)), Bpl.Expr.Literal(0));
- }
-
- public Bpl.QKeyValue TrAttributes(Attributes attrs, string skipThisAttribute) {
- Bpl.QKeyValue kv = null;
- for ( ; attrs != null; attrs = attrs.Prev) {
- if (attrs.Name == skipThisAttribute) { continue; }
- List<object> parms = new List<object>();
- foreach (Attributes.Argument arg in attrs.Args) {
- if (arg.E != null) {
- parms.Add(TrExpr(arg.E));
- } else {
- parms.Add(cce.NonNull(arg.S));
- }
- }
- kv = new Bpl.QKeyValue(Token.NoToken, attrs.Name, parms, kv);
- }
- return kv;
- }
-
- // --------------- help routines ---------------
-
- public Bpl.Expr IsAlloced(IToken tok, Bpl.Expr e) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- return ReadHeap(tok, HeapExpr, e, predef.Alloc(tok));
- }
-
- public Bpl.Expr GoodRef(IToken tok, Bpl.Expr e, Type type) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- if (type is UserDefinedType && ((UserDefinedType)type).ResolvedClass != null) {
- // Heap[e, alloc] && dtype(e) == T
- return GoodRef_Class(tok, e, (UserDefinedType)type, false);
- } else {
- // Heap[e, alloc]
- return IsAlloced(tok, e);
- }
- }
-
- public Bpl.Expr GoodRef_Class(IToken tok, Bpl.Expr e, UserDefinedType type, bool isNew)
- {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(type != null);
- Contract.Requires(type.ResolvedClass is ClassDecl);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
- return GoodRef_Ref(tok, e, new Bpl.IdentifierExpr(tok, translator.GetClass(type.ResolvedClass)), type.TypeArgs, isNew);
- }
-
- public Bpl.Expr GoodRef_Ref(IToken tok, Bpl.Expr e, Bpl.Expr type, List<Type/*!*/>/*!*/ typeArgs, bool isNew) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(type != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
-
- // Heap[e, alloc]
- Bpl.Expr r = IsAlloced(tok, e);
- if (isNew) {
- r = Bpl.Expr.Not(r); // use the conjunct: !Heap[e, alloc]
- }
-
- // dtype(e) == C
- Bpl.Expr dtypeFunc = translator.FunctionCall(tok, BuiltinFunction.DynamicType, null, e);
- Bpl.Expr dtype = Bpl.Expr.Eq(dtypeFunc, type);
- r = r == null ? dtype : Bpl.Expr.And(r, dtype);
-
- // TypeParams(e, #) == T
- int n = 0;
- foreach (Type arg in typeArgs) {
- Bpl.Expr tpFunc = translator.FunctionCall(tok, BuiltinFunction.TypeParams, null, e, Bpl.Expr.Literal(n));
- Bpl.Expr ta = translator.GetTypeExpr(tok, arg);
- if (ta != null) {
- r = Bpl.Expr.And(r, Bpl.Expr.Eq(tpFunc, ta));
- }
- n++;
- }
-
- return r;
- }
-
- public Bpl.Expr Good_Datatype(IToken tok, Bpl.Expr e, TopLevelDecl resolvedClass, List<Type> typeArgs) {
- Contract.Requires(tok != null);
- Contract.Requires(e != null);
- Contract.Requires(resolvedClass != null);
- Contract.Requires(typeArgs != null);
-
- // DtType(e) == C
- Bpl.Expr dttypeFunc = translator.FunctionCall(tok, BuiltinFunction.DtType, null, e);
- Bpl.Expr r = Bpl.Expr.Eq(dttypeFunc, new Bpl.IdentifierExpr(tok, translator.GetClass(resolvedClass)));
-
- // DtTypeParams(e, #) == T
- int n = 0;
- foreach (Type arg in typeArgs) {
- Bpl.Expr tpFunc = translator.FunctionCall(tok, BuiltinFunction.DtTypeParams, null, e, Bpl.Expr.Literal(n));
- Bpl.Expr ta = translator.GetTypeExpr(tok, arg);
- if (ta != null) {
- r = Bpl.Expr.And(r, Bpl.Expr.Eq(tpFunc, ta));
- }
- n++;
- }
-
- return r;
- }
- }
-
- enum BuiltinFunction
- {
- SetEmpty,
- SetUnionOne,
- SetUnion,
- SetIntersection,
- SetDifference,
- SetEqual,
- SetSubset,
- SetDisjoint,
- SetChoose,
-
- MultiSetEmpty,
- MultiSetUnionOne,
- MultiSetUnion,
- MultiSetIntersection,
- MultiSetDifference,
- MultiSetEqual,
- MultiSetSubset,
- MultiSetDisjoint,
- MultiSetFromSet,
- MultiSetFromSeq,
- IsGoodMultiSet,
-
- SeqLength,
- SeqEmpty,
- SeqBuild,
- SeqAppend,
- SeqIndex,
- SeqUpdate,
- SeqContains,
- SeqDrop,
- SeqTake,
- SeqEqual,
- SeqSameUntil,
- SeqFromArray,
-
- MapDomain,
- MapElements,
- MapEqual,
- MapBuild,
- MapDisjoint,
- MapUnion,
- MapGlue,
-
- IndexField,
- MultiIndexField,
-
- Box,
- Unbox,
- IsCanonicalBoolBox,
-
- IsGoodHeap,
- HeapSucc,
-
- DynamicType, // allocated type (of object reference)
- DtType, // type of datatype value
- TypeParams, // type parameters of allocated type
- DtTypeParams, // type parameters of datatype
- TypeTuple,
- DeclType,
- FieldOfDecl,
- FDim, // field dimension (0 - named, 1 or more - indexed)
-
- DatatypeCtorId,
- DtRank,
- DtAlloc,
-
- GenericAlloc
- }
-
- // The "typeInstantiation" argument is passed in to help construct the result type of the function.
- Bpl.NAryExpr FunctionCall(IToken tok, BuiltinFunction f, Bpl.Type typeInstantiation, params Bpl.Expr[] args)
- {
- Contract.Requires(tok != null);
- Contract.Requires(args != null);
- Contract.Requires(predef != null);
- Contract.Ensures(Contract.Result<Bpl.NAryExpr>() != null);
-
- switch (f) {
- case BuiltinFunction.SetEmpty: {
- Contract.Assert(args.Length == 0);
- Contract.Assert(typeInstantiation != null);
- Bpl.Type resultType = predef.SetType(tok, typeInstantiation);
- return Bpl.Expr.CoerceType(tok, FunctionCall(tok, "Set#Empty", resultType, args), resultType);
- }
- case BuiltinFunction.SetUnionOne:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Set#UnionOne", predef.SetType(tok, typeInstantiation), args);
- case BuiltinFunction.SetUnion:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Set#Union", predef.SetType(tok, typeInstantiation), args);
- case BuiltinFunction.SetIntersection:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Set#Intersection", predef.SetType(tok, typeInstantiation), args);
- case BuiltinFunction.SetDifference:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Set#Difference", predef.SetType(tok, typeInstantiation), args);
- case BuiltinFunction.SetEqual:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Set#Equal", Bpl.Type.Bool, args);
- case BuiltinFunction.SetSubset:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Set#Subset", Bpl.Type.Bool, args);
- case BuiltinFunction.SetDisjoint:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Set#Disjoint", Bpl.Type.Bool, args);
- case BuiltinFunction.SetChoose:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Set#Choose", typeInstantiation, args);
-
-
- case BuiltinFunction.MultiSetEmpty: {
- Contract.Assert(args.Length == 0);
- Contract.Assert(typeInstantiation != null);
- Bpl.Type resultType = predef.MultiSetType(tok, typeInstantiation);
- return Bpl.Expr.CoerceType(tok, FunctionCall(tok, "MultiSet#Empty", resultType, args), resultType);
- }
- case BuiltinFunction.MultiSetUnionOne:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "MultiSet#UnionOne", predef.MultiSetType(tok, typeInstantiation), args);
- case BuiltinFunction.MultiSetUnion:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "MultiSet#Union", predef.MultiSetType(tok, typeInstantiation), args);
- case BuiltinFunction.MultiSetIntersection:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "MultiSet#Intersection", predef.MultiSetType(tok, typeInstantiation), args);
- case BuiltinFunction.MultiSetDifference:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "MultiSet#Difference", predef.MultiSetType(tok, typeInstantiation), args);
- case BuiltinFunction.MultiSetEqual:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "MultiSet#Equal", Bpl.Type.Bool, args);
- case BuiltinFunction.MultiSetSubset:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "MultiSet#Subset", Bpl.Type.Bool, args);
- case BuiltinFunction.MultiSetDisjoint:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "MultiSet#Disjoint", Bpl.Type.Bool, args);
- case BuiltinFunction.MultiSetFromSet:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "MultiSet#FromSet", predef.MultiSetType(tok, typeInstantiation), args);
- case BuiltinFunction.MultiSetFromSeq:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "MultiSet#FromSeq", predef.MultiSetType(tok, typeInstantiation), args);
- case BuiltinFunction.IsGoodMultiSet:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "$IsGoodMultiSet", Bpl.Type.Bool, args);
- // avoiding this for now
- /*case BuiltinFunction.SetChoose:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Set#Choose", typeInstantiation, args);*/
-
- case BuiltinFunction.SeqLength:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Seq#Length", Bpl.Type.Int, args);
- case BuiltinFunction.SeqEmpty: {
- Contract.Assert(args.Length == 0);
- Contract.Assert(typeInstantiation != null);
- Bpl.Type resultType = predef.SeqType(tok, typeInstantiation);
- return Bpl.Expr.CoerceType(tok, FunctionCall(tok, "Seq#Empty", resultType, args), resultType);
- }
- case BuiltinFunction.SeqBuild:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Seq#Build", predef.SeqType(tok, typeInstantiation), args);
- case BuiltinFunction.SeqAppend:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Seq#Append", predef.SeqType(tok, typeInstantiation), args);
- case BuiltinFunction.SeqIndex:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Seq#Index", typeInstantiation, args);
- case BuiltinFunction.SeqUpdate:
- Contract.Assert(args.Length == 3);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Seq#Update", predef.SeqType(tok, typeInstantiation), args);
- case BuiltinFunction.SeqContains:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Seq#Contains", Bpl.Type.Bool, args);
- case BuiltinFunction.SeqDrop:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Seq#Drop", predef.SeqType(tok, typeInstantiation), args);
- case BuiltinFunction.SeqTake:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Seq#Take", predef.SeqType(tok, typeInstantiation), args);
- case BuiltinFunction.SeqEqual:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Seq#Equal", Bpl.Type.Bool, args);
- case BuiltinFunction.SeqSameUntil:
- Contract.Assert(args.Length == 3);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Seq#SameUntil", Bpl.Type.Bool, args);
- case BuiltinFunction.SeqFromArray:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "Seq#FromArray", typeInstantiation, args);
-
- case BuiltinFunction.MapDomain:
- Contract.Assert(args.Length == 1);
- return FunctionCall(tok, "Map#Domain", typeInstantiation, args);
- case BuiltinFunction.MapElements:
- Contract.Assert(args.Length == 1);
- return FunctionCall(tok, "Map#Elements", typeInstantiation, args);
- case BuiltinFunction.MapGlue:
- Contract.Assert(args.Length == 2);
- return FunctionCall(tok, "Map#Glue", predef.MapType(tok, predef.BoxType, predef.BoxType), args);
- case BuiltinFunction.MapEqual:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Map#Equal", Bpl.Type.Bool, args);
- case BuiltinFunction.MapDisjoint:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Map#Disjoint", Bpl.Type.Bool, args);
- case BuiltinFunction.MapUnion:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "Map#Disjoint", typeInstantiation, args);
-
- case BuiltinFunction.IndexField:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "IndexField", predef.FieldName(tok, predef.BoxType), args);
- case BuiltinFunction.MultiIndexField:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "MultiIndexField", predef.FieldName(tok, predef.BoxType), args);
-
- case BuiltinFunction.Box:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "$Box", predef.BoxType, args);
- case BuiltinFunction.Unbox:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation != null);
- return Bpl.Expr.CoerceType(tok, FunctionCall(tok, "$Unbox", typeInstantiation, args), typeInstantiation);
- case BuiltinFunction.IsCanonicalBoolBox:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "$IsCanonicalBoolBox", Bpl.Type.Bool, args);
-
- case BuiltinFunction.IsGoodHeap:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "$IsGoodHeap", Bpl.Type.Bool, args);
- case BuiltinFunction.HeapSucc:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "$HeapSucc", Bpl.Type.Bool, args);
-
- case BuiltinFunction.DynamicType:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "dtype", predef.ClassNameType, args);
- case BuiltinFunction.DtType:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "DtType", predef.ClassNameType, args);
- case BuiltinFunction.TypeParams:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "TypeParams", predef.ClassNameType, args);
- case BuiltinFunction.DtTypeParams:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "DtTypeParams", predef.ClassNameType, args);
- case BuiltinFunction.TypeTuple:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "TypeTuple", predef.ClassNameType, args);
- case BuiltinFunction.DeclType:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "DeclType", predef.ClassNameType, args);
- case BuiltinFunction.FieldOfDecl:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "FieldOfDecl", predef.FieldName(tok, typeInstantiation) , args);
- case BuiltinFunction.FDim:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation != null);
- return FunctionCall(tok, "FDim", Bpl.Type.Int, args);
-
- case BuiltinFunction.DatatypeCtorId:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "DatatypeCtorId", predef.DtCtorId, args);
- case BuiltinFunction.DtRank:
- Contract.Assert(args.Length == 1);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "DtRank", Bpl.Type.Int, args);
- case BuiltinFunction.DtAlloc:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "DtAlloc", Bpl.Type.Bool, args);
-
- case BuiltinFunction.GenericAlloc:
- Contract.Assert(args.Length == 2);
- Contract.Assert(typeInstantiation == null);
- return FunctionCall(tok, "GenericAlloc", Bpl.Type.Bool, args);
-
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected built-in function
- }
- }
-
- Bpl.NAryExpr FunctionCall(IToken tok, string function, Bpl.Type returnType, params Bpl.Expr[] args)
- {
- Contract.Requires(tok != null);
- Contract.Requires(function != null);
- Contract.Requires(args != null);
- Contract.Ensures(Contract.Result<Bpl.NAryExpr>() != null);
-
- return new Bpl.NAryExpr(tok, new Bpl.FunctionCall(new Bpl.IdentifierExpr(tok, function, returnType)), new Bpl.ExprSeq(args));
- }
-
- Bpl.NAryExpr FunctionCall(IToken tok, string function, Bpl.Type returnType, List<Bpl.Expr> args)
- {
- Contract.Requires(tok != null);
- Contract.Requires(function != null);
- Contract.Requires(returnType != null);
- Contract.Requires(cce.NonNullElements(args));
- Contract.Ensures(Contract.Result<Bpl.NAryExpr>() != null);
-
- Bpl.ExprSeq aa = new Bpl.ExprSeq();
- foreach (Bpl.Expr arg in args) {
- aa.Add(arg);
- }
- return new Bpl.NAryExpr(tok, new Bpl.FunctionCall(new Bpl.IdentifierExpr(tok, function, returnType)), aa);
- }
-
- Bpl.Expr ArrayLength(IToken tok, Bpl.Expr arr, int totalDims, int dim) {
- Contract.Requires(tok != null);
- Contract.Requires(arr != null);
- Contract.Requires(1 <= totalDims);
- Contract.Requires(0 <= dim && dim < totalDims);
-
- string name = "_System." + BuiltIns.ArrayClassName(totalDims) + ".Length";
- if (totalDims != 1) {
- name += dim;
- }
- return new Bpl.NAryExpr(tok, new Bpl.FunctionCall(new Bpl.IdentifierExpr(tok, name, Bpl.Type.Int)), new Bpl.ExprSeq(arr));
- }
-
- public class SplitExprInfo
- {
- public readonly bool IsFree;
- public readonly Bpl.Expr E;
- public SplitExprInfo(bool isFree, Bpl.Expr e) {
- Contract.Requires(e != null);
- IsFree = isFree;
- E = e;
- }
- }
-
- internal List<SplitExprInfo/*!*/>/*!*/ TrSplitExpr(Expression expr, ExpressionTranslator etran, out bool splitHappened) {
- Contract.Requires(expr != null);
- Contract.Requires(etran != null);
- Contract.Ensures(Contract.Result<List<SplitExprInfo>>() != null);
-
- var splits = new List<SplitExprInfo>();
- splitHappened = TrSplitExpr(expr, splits, true, int.MaxValue, etran);
- return splits;
- }
-
- /// <summary>
- /// Tries to split the expression into tactical conjuncts (if "position") or disjuncts (if "!position").
- /// If a (necessarily boolean) function call appears as a top-level conjunct, then inline the function if
- /// if it declared in the current module and its height is less than "heightLimit".
- /// </summary>
- internal bool TrSplitExpr(Expression expr, List<SplitExprInfo/*!*/>/*!*/ splits, bool position, int heightLimit, ExpressionTranslator etran) {
- Contract.Requires(expr != null);
- Contract.Requires(expr.Type is BoolType || (expr is BoxingCastExpr && ((BoxingCastExpr)expr).E.Type is BoolType));
- Contract.Requires(splits != null);
- Contract.Requires(etran != null);
-
- if (expr is BoxingCastExpr) {
- var bce = (BoxingCastExpr)expr;
- var ss = new List<SplitExprInfo>();
- if (TrSplitExpr(bce.E, ss, position, heightLimit, etran)) {
- foreach (var s in ss) {
- splits.Add(new SplitExprInfo(s.IsFree, etran.CondApplyBox(s.E.tok, s.E, bce.FromType, bce.ToType)));
- }
- return true;
- }
-
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return TrSplitExpr(e.ResolvedExpression, splits, position, heightLimit, etran);
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- return TrSplitExpr(etran.GetSubstitutedBody(e), splits, position, heightLimit, etran);
-
- } else if (expr is UnaryExpr) {
- var e = (UnaryExpr)expr;
- if (e.Op == UnaryExpr.Opcode.Not) {
- var ss = new List<SplitExprInfo>();
- if (TrSplitExpr(e.E, ss, !position, heightLimit, etran)) {
- foreach (var s in ss) {
- splits.Add(new SplitExprInfo(s.IsFree, Bpl.Expr.Unary(s.E.tok, UnaryOperator.Opcode.Not, s.E)));
- }
- return true;
- }
- }
-
- } else if (expr is BinaryExpr) {
- var bin = (BinaryExpr)expr;
- if (position && bin.ResolvedOp == BinaryExpr.ResolvedOpcode.And) {
- TrSplitExpr(bin.E0, splits, position, heightLimit, etran);
- TrSplitExpr(bin.E1, splits, position, heightLimit, etran);
- return true;
-
- } else if (!position && bin.ResolvedOp == BinaryExpr.ResolvedOpcode.Or) {
- TrSplitExpr(bin.E0, splits, position, heightLimit, etran);
- TrSplitExpr(bin.E1, splits, position, heightLimit, etran);
- return true;
-
- } else if (bin.ResolvedOp == BinaryExpr.ResolvedOpcode.Imp) {
- // non-conditionally split these, so we get the source location to point to a subexpression
- if (position) {
- var lhs = etran.TrExpr(bin.E0);
- var ss = new List<SplitExprInfo>();
- TrSplitExpr(bin.E1, ss, position, heightLimit, etran);
- foreach (var s in ss) {
- // as the source location in the following implication, use that of the translated "s"
- splits.Add(new SplitExprInfo(s.IsFree, Bpl.Expr.Binary(s.E.tok, BinaryOperator.Opcode.Imp, lhs, s.E)));
- }
- } else {
- var ss = new List<SplitExprInfo>();
- TrSplitExpr(bin.E0, ss, !position, heightLimit, etran);
- var lhs = etran.TrExpr(bin.E1);
- foreach (var s in ss) {
- // as the source location in the following implication, use that of the translated "s"
- splits.Add(new SplitExprInfo(s.IsFree, Bpl.Expr.Binary(s.E.tok, BinaryOperator.Opcode.Imp, s.E, lhs)));
- }
- }
- return true;
- }
-
- } else if (expr is ITEExpr) {
- var ite = (ITEExpr)expr;
-
- var ssThen = new List<SplitExprInfo>();
- var ssElse = new List<SplitExprInfo>();
- // Note: The following lines intentionally uses | instead of ||, because we need both calls to TrSplitExpr
- if (TrSplitExpr(ite.Thn, ssThen, position, heightLimit, etran) | TrSplitExpr(ite.Els, ssElse, position, heightLimit, etran)) {
- var op = position ? BinaryOperator.Opcode.Imp : BinaryOperator.Opcode.And;
- var test = etran.TrExpr(ite.Test);
- foreach (var s in ssThen) {
- // as the source location in the following implication, use that of the translated "s"
- splits.Add(new SplitExprInfo(s.IsFree, Bpl.Expr.Binary(s.E.tok, op, test, s.E)));
- }
-
- var negatedTest = Bpl.Expr.Not(test);
- foreach (var s in ssElse) {
- // as the source location in the following implication, use that of the translated "s"
- splits.Add(new SplitExprInfo(s.IsFree, Bpl.Expr.Binary(s.E.tok, op, negatedTest, s.E)));
- }
-
- return true;
- }
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- // For a predicate expression in split position, the predicate can be used as an assumption. Unfortunately,
- // this assumption is not generated in non-split positions (because I don't know how.)
- // So, treat "assert/assume P; E" like "P ==> E".
- if (position) {
- var guard = etran.TrExpr(e.Guard);
- var ss = new List<SplitExprInfo>();
- TrSplitExpr(e.Body, ss, position, heightLimit, etran);
- foreach (var s in ss) {
- // as the source location in the following implication, use that of the translated "s"
- splits.Add(new SplitExprInfo(s.IsFree, Bpl.Expr.Binary(s.E.tok, BinaryOperator.Opcode.Imp, guard, s.E)));
- }
- } else {
- var ss = new List<SplitExprInfo>();
- TrSplitExpr(e.Guard, ss, !position, heightLimit, etran);
- var rhs = etran.TrExpr(e.Body);
- foreach (var s in ss) {
- // as the source location in the following implication, use that of the translated "s"
- splits.Add(new SplitExprInfo(s.IsFree, Bpl.Expr.Binary(s.E.tok, BinaryOperator.Opcode.Imp, s.E, rhs)));
- }
- }
- return true;
-
- } else if (expr is OldExpr) {
- var e = (OldExpr)expr;
- return TrSplitExpr(e.E, splits, position, heightLimit, etran.Old);
-
- } else if (expr is FunctionCallExpr) {
- if (position) {
- var fexp = (FunctionCallExpr)expr;
- var f = fexp.Function;
- Contract.Assert(f != null); // filled in during resolution
- var module = f.EnclosingClass.Module;
- var functionHeight = module.CallGraph.GetSCCRepresentativeId(f);
-
- if (module == currentModule && functionHeight < heightLimit) {
- if (f.Body != null && !(f.Body.Resolved is MatchExpr)) {
- if (RefinementToken.IsInherited(fexp.tok, currentModule) &&
- f is Predicate && ((Predicate)f).BodyOrigin == Predicate.BodyOriginKind.DelayedDefinition &&
- (codeContext == null || !codeContext.MustReverify)) {
- // The function was inherited as body-less but is now given a body. Don't inline the body (since, apparently, everything
- // that needed to be proved about the function was proved already in the previous module, even without the body definition).
- } else {
- // inline this body
- Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
- Contract.Assert(fexp.Args.Count == f.Formals.Count);
- for (int i = 0; i < f.Formals.Count; i++) {
- Formal p = f.Formals[i];
- Expression arg = fexp.Args[i];
- arg = new BoxingCastExpr(arg, cce.NonNull(arg.Type), p.Type);
- arg.Type = p.Type; // resolve here
- substMap.Add(p, arg);
- }
- Expression body = Substitute(f.Body, fexp.Receiver, substMap);
-
- // Produce, for a "body" split into b0, b1, b2:
- // free F#canCall(args) && F(args) && (b0 && b1 && b2)
- // checked F#canCall(args) ==> F(args) || b0
- // checked F#canCall(args) ==> F(args) || b1
- // checked F#canCall(args) ==> F(args) || b2
- // Note that "body" does not contain limited calls.
-
- // F#canCall(args)
- Bpl.IdentifierExpr canCallFuncID = new Bpl.IdentifierExpr(expr.tok, f.FullCompileName + "#canCall", Bpl.Type.Bool);
- ExprSeq args = etran.FunctionInvocationArguments(fexp);
- Bpl.Expr canCall = new Bpl.NAryExpr(expr.tok, new Bpl.FunctionCall(canCallFuncID), args);
-
- // F(args)
- Bpl.Expr fargs = etran.TrExpr(fexp);
-
- // body
- Bpl.Expr trBody = etran.TrExpr(body);
- trBody = etran.CondApplyUnbox(trBody.tok, trBody, f.ResultType, expr.Type);
-
- // here goes the free piece:
- splits.Add(new SplitExprInfo(true, Bpl.Expr.Binary(trBody.tok, BinaryOperator.Opcode.And, canCall, BplAnd(fargs, trBody))));
-
- // recurse on body
- var ss = new List<SplitExprInfo>();
- TrSplitExpr(body, ss, position, functionHeight, etran);
- foreach (var s in ss) {
- var unboxedConjunct = etran.CondApplyUnbox(s.E.tok, s.E, f.ResultType, expr.Type);
- var bodyOrConjunct = Bpl.Expr.Or(fargs, unboxedConjunct);
- var p = Bpl.Expr.Binary(new NestedToken(fexp.tok, s.E.tok), BinaryOperator.Opcode.Imp, canCall, bodyOrConjunct);
- splits.Add(new SplitExprInfo(s.IsFree, p));
- }
-
- return true;
- }
- }
- }
- }
-
- } else if ((position && expr is ForallExpr) || (!position && expr is ExistsExpr)) {
- var e = (QuantifierExpr)expr;
- var inductionVariables = ApplyInduction(e);
- if (2 <= DafnyOptions.O.Induction && inductionVariables.Count != 0) {
- // From the given quantifier (forall n :: P(n)), generate the seemingly weaker proof obligation
- // (forall n :: (forall k :: k < n ==> P(k)) ==> P(n))
- // For an existential (exists n :: P(n)), it is
- // (exists n :: (forall k :: k < n ==> !P(k)) && P(n))
- // ^^^^^^ ^ ^^ <--- note these 3 differences
- var kvars = new List<BoundVar>();
- var kk = new List<Bpl.Expr>();
- var nn = new List<Bpl.Expr>();
- var toks = new List<IToken>();
- var types = new List<Type>();
- var substMap = new Dictionary<IVariable, Expression>();
- foreach (var n in inductionVariables) {
- toks.Add(n.tok);
- types.Add(n.Type);
- BoundVar k = new BoundVar(n.tok, n.Name + "$ih#" + otherTmpVarCount, n.Type);
- otherTmpVarCount++;
- kvars.Add(k);
-
- IdentifierExpr ieK = new IdentifierExpr(k.tok, k.UniqueName);
- ieK.Var = k; ieK.Type = ieK.Var.Type; // resolve it here
- kk.Add(etran.TrExpr(ieK));
-
- IdentifierExpr ieN = new IdentifierExpr(n.tok, n.UniqueName);
- ieN.Var = n; ieN.Type = ieN.Var.Type; // resolve it here
- nn.Add(etran.TrExpr(ieN));
-
- substMap.Add(n, ieK);
- }
- Expression bodyK = Substitute(e.LogicalBody(), null, substMap);
-
- Bpl.Expr less = DecreasesCheck(toks, types, kk, nn, etran, null, null, false, true);
-
- Bpl.Expr ihBody = etran.TrExpr(bodyK);
- if (!position) {
- ihBody = Bpl.Expr.Not(ihBody);
- }
- ihBody = Bpl.Expr.Imp(less, ihBody);
- Bpl.VariableSeq bvars = new Bpl.VariableSeq();
- Bpl.Expr typeAntecedent = etran.TrBoundVariables(kvars, bvars);
- Bpl.Expr ih = new Bpl.ForallExpr(expr.tok, bvars, Bpl.Expr.Imp(typeAntecedent, ihBody));
-
- // More precisely now:
- // (forall n :: n-has-expected-type && (forall k :: k < n ==> P(k)) && case0(n) ==> P(n))
- // (forall n :: n-has-expected-type && (forall k :: k < n ==> P(k)) && case...(n) ==> P(n))
- // or similar for existentials.
- var caseProduct = new List<Bpl.Expr>() { new Bpl.LiteralExpr(expr.tok, true) }; // make sure to include the correct token information
- var i = 0;
- foreach (var n in inductionVariables) {
- var newCases = new List<Bpl.Expr>();
- foreach (var kase in InductionCases(n.Type, nn[i], etran)) {
- foreach (var cs in caseProduct) {
- if (kase != Bpl.Expr.True) { // if there's no case, don't add anything to the token
- newCases.Add(Bpl.Expr.Binary(new NestedToken(cs.tok, kase.tok), Bpl.BinaryOperator.Opcode.And, cs, kase));
- } else {
- newCases.Add(cs);
- }
- }
- }
- caseProduct = newCases;
- i++;
- }
- bvars = new Bpl.VariableSeq();
- typeAntecedent = etran.TrBoundVariables(e.BoundVars, bvars);
- foreach (var kase in caseProduct) {
- var ante = BplAnd(BplAnd(typeAntecedent, ih), kase);
- var bdy = etran.LayerOffset(1).TrExpr(e.LogicalBody());
- Bpl.Expr q;
- if (position) {
- q = new Bpl.ForallExpr(kase.tok, bvars, Bpl.Expr.Imp(ante, bdy));
- } else {
- q = new Bpl.ExistsExpr(kase.tok, bvars, Bpl.Expr.And(ante, bdy));
- }
- splits.Add(new SplitExprInfo(false, q));
- }
-
- // Finally, assume the original quantifier (forall/exists n :: P(n))
- splits.Add(new SplitExprInfo(true, etran.TrExpr(expr)));
- return true;
- }
- }
-
- Bpl.Expr translatedExpression;
- bool splitHappened;
- if ((position && expr is ExistsExpr) || (!position && expr is ForallExpr)) {
- translatedExpression = etran.TrExpr(expr);
- splitHappened = false;
- } else {
- etran = etran.LayerOffset(1);
- translatedExpression = etran.TrExpr(expr);
- splitHappened = etran.Statistics_CustomLayerFunctionCount != 0; // return true if the LayerOffset(1) came into play
- }
- // TODO: Is the the following call to ContainsChange expensive? It's linear in the size of "expr", but we get here many times in TrSpliExpr, so wouldn't the total
- // time in the size of the expression passed to the first TrSpliExpr be quadratic?
- if (RefinementToken.IsInherited(expr.tok, currentModule) && (codeContext == null || !codeContext.MustReverify) && RefinementTransformer.ContainsChange(expr, currentModule)) {
- // If "expr" contains a subexpression that has changed from the inherited expression, we'll destructively
- // change the token of the translated expression to make it look like it's not inherited. This will cause "e" to
- // be verified again in the refining module.
- translatedExpression.tok = new ForceCheckToken(expr.tok);
- splitHappened = true; // count this as a split, so this translated expression is not ignored
- }
- splits.Add(new SplitExprInfo(false, translatedExpression));
- return splitHappened;
- }
-
- List<BoundVar> ApplyInduction(QuantifierExpr e) {
- return ApplyInduction(e.BoundVars, e.Attributes, new List<Expression>() { e.LogicalBody() },
- delegate(System.IO.TextWriter wr) { new Printer(Console.Out).PrintExpression(e); });
- }
-
- delegate void TracePrinter(System.IO.TextWriter wr);
-
- /// <summary>
- /// Return a subset of "boundVars" (in the order giving in "boundVars") to which to apply induction to,
- /// according to :induction attributes in "attributes" and heuristically interesting subexpressions of
- /// "searchExprs".
- /// </summary>
- List<VarType> ApplyInduction<VarType>(List<VarType> boundVars, Attributes attributes, List<Expression> searchExprs, TracePrinter tracePrinter) where VarType : class, IVariable
- {
- Contract.Requires(boundVars != null);
- Contract.Requires(searchExprs != null);
- Contract.Requires(tracePrinter != null);
- Contract.Ensures(Contract.Result<List<VarType>>() != null);
-
- if (DafnyOptions.O.Induction == 0) {
- return new List<VarType>(); // don't apply induction
- }
-
- for (var a = attributes; a != null; a = a.Prev) {
- if (a.Name == "induction") {
- // Here are the supported forms of the :induction attribute.
- // :induction -- apply induction to all bound variables
- // :induction false -- suppress induction, that is, don't apply it to any bound variable
- // :induction L where L is a list consisting entirely of bound variables:
- // -- apply induction to the specified bound variables
- // :induction X where X is anything else
- // -- treat the same as {:induction}, that is, apply induction to all
- // bound variables
-
- // Handle {:induction false}
- if (a.Args.Count == 1) {
- var arg = a.Args[0].E as LiteralExpr;
- if (arg != null && arg.Value is bool && !(bool)arg.Value) {
- if (CommandLineOptions.Clo.Trace) {
- Console.Write("Suppressing automatic induction for: ");
- tracePrinter(Console.Out);
- Console.WriteLine();
- }
- return new List<VarType>();
- }
- }
-
- // Handle {:induction L}
- if (a.Args.Count != 0) {
- // check that all attribute arguments refer to bound variables; otherwise, go to default_form
- var argsAsVars = new List<VarType>();
- foreach (var arg in a.Args) {
- var theArg = arg.E.Resolved;
- if (theArg is ThisExpr) {
- foreach (var bv in boundVars) {
- if (bv is ThisSurrogate) {
- argsAsVars.Add(bv);
- goto TRY_NEXT_ATTRIBUTE_ARGUMENT;
- }
- }
- } else if (theArg is IdentifierExpr) {
- var id = (IdentifierExpr)theArg;
- var bv = id.Var as VarType;
- if (bv != null && boundVars.Contains(bv)) {
- argsAsVars.Add(bv);
- goto TRY_NEXT_ATTRIBUTE_ARGUMENT;
- }
- }
- // the attribute argument was not one of the possible induction variables
- goto USE_DEFAULT_FORM;
- TRY_NEXT_ATTRIBUTE_ARGUMENT:
- ;
- }
- // so, all attribute arguments are variables; add them to L in the order of the bound variables (not necessarily the order in the attribute)
- var L = new List<VarType>();
- foreach (var bv in boundVars) {
- if (argsAsVars.Contains(bv)) {
- L.Add(bv);
- }
- }
- if (CommandLineOptions.Clo.Trace) {
- string sep = "Applying requested induction on ";
- foreach (var bv in L) {
- Console.Write("{0}{1}", sep, bv.Name);
- sep = ", ";
- }
- Console.Write(" of: ");
- tracePrinter(Console.Out);
- Console.WriteLine();
- }
- return L;
- USE_DEFAULT_FORM: ;
- }
-
- // We have the {:induction} case, or something to be treated in the same way
- if (CommandLineOptions.Clo.Trace) {
- Console.Write("Applying requested induction on all bound variables of: ");
- tracePrinter(Console.Out);
- Console.WriteLine();
- }
- return boundVars;
- }
- }
-
- if (DafnyOptions.O.Induction < 2) {
- return new List<VarType>(); // don't apply induction
- }
-
- // consider automatically applying induction
- var inductionVariables = new List<VarType>();
- foreach (var n in boundVars) {
- if (!n.Type.IsTypeParameter && searchExprs.Exists(expr => VarOccursInArgumentToRecursiveFunction(expr, n))) {
- if (CommandLineOptions.Clo.Trace) {
- Console.Write("Applying automatic induction on variable '{0}' of: ", n.Name);
- tracePrinter(Console.Out);
- Console.WriteLine();
- }
- inductionVariables.Add(n);
- }
- }
-
- return inductionVariables;
- }
-
- /// <summary>
- /// Returns 'true' iff by looking at 'expr' the Induction Heuristic determines that induction should be applied to 'n'.
- /// More precisely:
- /// DafnyInductionHeuristic Return 'true'
- /// ----------------------- -------------
- /// 0 always
- /// 1 if 'n' occurs as any subexpression (of 'expr')
- /// 2 if 'n' occurs as any subexpression of any index argument of an array/sequence select expression or any argument to a recursive function
- /// 3 if 'n' occurs as a prominent subexpression of any index argument of an array/sequence select expression or any argument to a recursive function
- /// 4 if 'n' occurs as any subexpression of any argument to a recursive function
- /// 5 if 'n' occurs as a prominent subexpression of any argument to a recursive function
- /// 6 if 'n' occurs as a prominent subexpression of any decreases-influencing argument to a recursive function
- /// Parameter 'n' is allowed to be a ThisSurrogate.
- /// </summary>
- bool VarOccursInArgumentToRecursiveFunction(Expression expr, IVariable n) {
- switch (DafnyOptions.O.InductionHeuristic) {
- case 0: return true;
- case 1: return ContainsFreeVariable(expr, false, n);
- default: return VarOccursInArgumentToRecursiveFunction(expr, n, false);
- }
- }
-
- /// <summary>
- /// Worker routine for VarOccursInArgumentToRecursiveFunction(expr,n), where the additional parameter 'exprIsProminent' says whether or
- /// not 'expr' prominent status in its context.
- /// DafnyInductionHeuristic cases 0 and 1 are assumed to be handled elsewhere (i.e., a precondition of this method is DafnyInductionHeuristic is at least 2).
- /// Parameter 'n' is allowed to be a ThisSurrogate.
- /// </summary>
- bool VarOccursInArgumentToRecursiveFunction(Expression expr, IVariable n, bool exprIsProminent) {
- Contract.Requires(expr != null);
- Contract.Requires(n != null);
-
- // The following variable is what gets passed down to recursive calls if the subexpression does not itself acquire prominent status.
- var subExprIsProminent = DafnyOptions.O.InductionHeuristic == 2 || DafnyOptions.O.InductionHeuristic == 4 ? /*once prominent, always prominent*/exprIsProminent : /*reset the prominent status*/false;
-
- if (expr is ThisExpr) {
- return exprIsProminent && n is ThisSurrogate;
- } else if (expr is IdentifierExpr) {
- var e = (IdentifierExpr)expr;
- return exprIsProminent && e.Var == n;
- } else if (expr is SeqSelectExpr) {
- var e = (SeqSelectExpr)expr;
- var q = DafnyOptions.O.InductionHeuristic < 4 || subExprIsProminent;
- return VarOccursInArgumentToRecursiveFunction(e.Seq, n, subExprIsProminent) || // this subexpression does not acquire "prominent" status
- (e.E0 != null && VarOccursInArgumentToRecursiveFunction(e.E0, n, q)) || // this one does (unless arrays/sequences are excluded)
- (e.E1 != null && VarOccursInArgumentToRecursiveFunction(e.E1, n, q)); // ditto
- } else if (expr is MultiSelectExpr) {
- var e = (MultiSelectExpr)expr;
- var q = DafnyOptions.O.InductionHeuristic < 4 || subExprIsProminent;
- return VarOccursInArgumentToRecursiveFunction(e.Array, n, subExprIsProminent) ||
- e.Indices.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, q));
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- // For recursive functions: arguments are "prominent"
- // For non-recursive function: arguments are "prominent" if the call is
- var rec = e.Function.IsRecursive && e.CoCall != FunctionCallExpr.CoCallResolution.Yes;
- bool inferredDecreases; // we don't actually care
- var decr = FunctionDecreasesWithDefault(e.Function, out inferredDecreases);
- bool variantArgument;
- if (DafnyOptions.O.InductionHeuristic < 6) {
- variantArgument = rec;
- } else {
- // The receiver is considered to be "variant" if the function is recursive and the receiver participates
- // in the effective decreases clause of the function. The receiver participates if it's a free variable
- // of a term in the explicit decreases clause.
- variantArgument = rec && decr.Exists(ee => ContainsFreeVariable(ee, true, null));
- }
- if (VarOccursInArgumentToRecursiveFunction(e.Receiver, n, variantArgument || subExprIsProminent)) {
- return true;
- }
- Contract.Assert(e.Function.Formals.Count == e.Args.Count);
- for (int i = 0; i < e.Function.Formals.Count; i++) {
- var f = e.Function.Formals[i];
- var exp = e.Args[i];
- if (DafnyOptions.O.InductionHeuristic < 6) {
- variantArgument = rec;
- } else {
- // The argument position is considered to be "variant" if the function is recursive and the argument participates
- // in the effective decreases clause of the function. The argument participates if it's a free variable
- // of a term in the explicit decreases clause.
- variantArgument = rec && decr.Exists(ee => ContainsFreeVariable(ee, false, f));
- }
- if (VarOccursInArgumentToRecursiveFunction(exp, n, variantArgument || subExprIsProminent)) {
- return true;
- }
- }
- return false;
- } else if (expr is DatatypeValue) {
- var e = (DatatypeValue)expr;
- var q = n.Type.IsDatatype ? exprIsProminent : subExprIsProminent; // prominent status continues, if we're looking for a variable whose type is a datatype
- return e.Arguments.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, q));
- } else if (expr is UnaryExpr) {
- var e = (UnaryExpr)expr;
- // both Not and SeqLength preserve prominence
- return VarOccursInArgumentToRecursiveFunction(e.E, n, exprIsProminent);
- } else if (expr is BinaryExpr) {
- var e = (BinaryExpr)expr;
- bool q;
- switch (e.ResolvedOp) {
- case BinaryExpr.ResolvedOpcode.Add:
- case BinaryExpr.ResolvedOpcode.Sub:
- case BinaryExpr.ResolvedOpcode.Mul:
- case BinaryExpr.ResolvedOpcode.Div:
- case BinaryExpr.ResolvedOpcode.Mod:
- case BinaryExpr.ResolvedOpcode.Union:
- case BinaryExpr.ResolvedOpcode.Intersection:
- case BinaryExpr.ResolvedOpcode.SetDifference:
- case BinaryExpr.ResolvedOpcode.Concat:
- // these operators preserve prominence
- q = exprIsProminent;
- break;
- default:
- // whereas all other binary operators do not
- q = subExprIsProminent;
- break;
- }
- return VarOccursInArgumentToRecursiveFunction(e.E0, n, q) ||
- VarOccursInArgumentToRecursiveFunction(e.E1, n, q);
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- // ignore the guard
- return VarOccursInArgumentToRecursiveFunction(e.Body, n);
-
- } else if (expr is ITEExpr) {
- var e = (ITEExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.Test, n, subExprIsProminent) || // test is not "prominent"
- VarOccursInArgumentToRecursiveFunction(e.Thn, n, exprIsProminent) || // but the two branches are
- VarOccursInArgumentToRecursiveFunction(e.Els, n, exprIsProminent);
- } else if (expr is OldExpr ||
- expr is ConcreteSyntaxExpression ||
- expr is BoxingCastExpr ||
- expr is UnboxingCastExpr) {
- foreach (var exp in expr.SubExpressions) {
- if (VarOccursInArgumentToRecursiveFunction(exp, n, exprIsProminent)) { // maintain prominence
- return true;
- }
- }
- return false;
- } else {
- // in all other cases, reset the prominence status and recurse on the subexpressions
- foreach (var exp in expr.SubExpressions) {
- if (VarOccursInArgumentToRecursiveFunction(exp, n, subExprIsProminent)) {
- return true;
- }
- }
- return false;
- }
- }
-
- IEnumerable<Bpl.Expr> InductionCases(Type ty, Bpl.Expr expr, ExpressionTranslator etran) {
- IndDatatypeDecl dt = ty.AsIndDatatype;
- if (dt == null) {
- yield return Bpl.Expr.True;
- } else {
- UserDefinedType instantiatedType = (UserDefinedType)ty; // correctness of cast follows from the non-null return of ty.AsDatatype
- var subst = new Dictionary<TypeParameter, Type>();
- for (int i = 0; i < dt.TypeArgs.Count; i++) {
- subst.Add(dt.TypeArgs[i], instantiatedType.TypeArgs[i]);
- }
-
- foreach (DatatypeCtor ctor in dt.Ctors) {
- Bpl.VariableSeq bvs;
- List<Bpl.Expr> args;
- CreateBoundVariables(ctor.Formals, out bvs, out args);
- Bpl.Expr ct = FunctionCall(ctor.tok, ctor.FullName, predef.DatatypeType, args);
- // (exists args :: args-have-the-expected-types && ct(args) == expr)
- Bpl.Expr q = Bpl.Expr.Binary(ctor.tok, BinaryOperator.Opcode.Eq, ct, expr);
- if (bvs.Length != 0) {
- int i = 0;
- Bpl.Expr typeAntecedent = Bpl.Expr.True;
- foreach (Formal arg in ctor.Formals) {
- var instantiatedArgType = Resolver.SubstType(arg.Type, subst);
- Bpl.Expr wh = GetWhereClause(arg.tok, etran.CondApplyUnbox(arg.tok, args[i], arg.Type, instantiatedArgType), instantiatedArgType, etran);
- if (wh != null) {
- typeAntecedent = BplAnd(typeAntecedent, wh);
- }
- i++;
- }
- q = new Bpl.ExistsExpr(ctor.tok, bvs, BplAnd(typeAntecedent, q));
- }
- yield return q;
- }
- }
- }
-
- void AddCoinductionPrinciple(CoPredicate coPredicate) {
- Contract.Requires(coPredicate != null);
- if (coPredicate.Body == null) {
- return; // we can't generate any useful coinduction principle if the copredicate doesn't have a body
- } else if (2 <= coPredicate.EnclosingClass.Module.CallGraph.GetSCCSize(coPredicate)) {
- return; // this copredicate involves mutually recursive calls; for now, we don't handle those
- }
- var n = (coPredicate.IsStatic ? 0 : 1) + coPredicate.Formals.Count;
- var templates = new List<FunctionCallExpr[/*of length n*/]>();
- foreach (var fce in coPredicate.Uses) {
- // Compute a template of instantiation for this use: for each actual argument, record
- // a function F if the argument is a call to F, or record null otherwise.
- var t = new FunctionCallExpr[n];
- var i = 0;
- if (!coPredicate.IsStatic) {
- t[i] = fce.Receiver.Resolved as FunctionCallExpr;
- i++;
- }
- foreach (var a in fce.Args) {
- t[i] = a.Resolved as FunctionCallExpr;
- i++;
- }
- Contract.Assert(i == t.Length);
- // See if this template has been done before (for now, this is a slow check; it would be nice to speed it up)
- foreach (var prev in templates) {
- var j = 0;
- for (; j < n; j++) {
- if (prev[j] == null && t[j] == null) {
- // things are equal
- } else if (prev[j] != null && t[j] != null && prev[j].Function == t[j].Function) {
- // things are equal
- } else {
- // we found an unequal part of the template
- break;
- }
- }
- if (j == n) {
- // template 't' matches 'prev', so we've already spilled out an axiom for this template
- // TODO: this is not the complete test, because of possible type parameters
- goto Next_Use;
- }
- // 't' does not match this 'prev'; try the next 'prev'
- }
- // No 'prev' matches the current template 't'. So, generate an axiom for 't'.
- string comment = string.Format("Coinduction principle for copredicate {0} instantiated like:", coPredicate.FullName);
- foreach (var tf in t) {
- comment += tf == null ? " ." : " " + tf.Name;
- }
- sink.TopLevelDeclarations.Add(new Bpl.Axiom(fce.tok, CoinductionPrinciple(coPredicate, fce, t), comment));
- templates.Add(t);
- Next_Use: ;
- }
- }
-
- /// <summary>
- /// It's the "callOfInterest" that determines the (type-parameter instantiated) types of the arguments
- /// </summary>
- Bpl.Expr CoinductionPrinciple(CoPredicate coPredicate, FunctionCallExpr callOfInterest, FunctionCallExpr[] t) {
- Contract.Requires(coPredicate != null);
- Contract.Requires(coPredicate.Body != null);
- Contract.Requires(t != null);
- Contract.Requires(t.Length == (coPredicate.IsStatic ? 0 : 1) + coPredicate.Formals.Count);
- // Let C be the name of the coPredicate, and suppose it is defined by:
- // copredicate C(x)
- // requires PreC(x);
- // {
- // Body[C]
- // }
- // where the notation Body[_] means an expression Body with holes and in particular one whole
- // for every recursive use of C.
- // The general form of the coinduction principle of which we will generate an instance is:
- // forall P ::
- // forall s :: // where s is a list of arguments to coPredicate
- // P(s) &&
- // (forall s' :: P(s') ==> Body[P][x := s'])
- // ==>
- // C(s)
- // We will pick particular P's, and will therefore instead generate the axiom once for each
- // such P. We will also redistribute the terms as follows:
- // (forall s :: P(s) ==> Body[P][x := s])
- // ==>
- // (forall s :: P(s) ==> C(s))
- // Furthermore, if the C of interest has actual parameters that are function-call expressions,
- // then the P will be chosen to fit that pattern. As a specific example, suppose C takes 3
- // parameters (that is, 's' is a triple (s0,s1,s2)) and that the actual arguments for these, in
- // the C use of interest, are of the form C(E0,F(E1),G(E2,E3)), where E0 denotes an expression that
- // is not a function-call expression and E1,E2,E3 are any expressions. Also, suppose the
- // preconditions of C,F,G are PreC(s0,s1,s2), PreF(f), PreG(g0,g1).
- // Then, we pick P(s0,s1,s2) :=
- // exists a,b,c,d :: PreF(b) && PreG(c,d) && PredC(a,F(b),G(c,d)) && (s0,s1,s2) == (a,F(b),G(c,d))
- // So, the axiom looks like:
- // (forall a,b,c,d :: PreF(b) && PreG(c,d) && PredC(a,F(b),G(c,d))
- // ==> Body[P][x0,x1,x2 := a,F(b),G(c,d)])
- // ==>
- // (forall a,b,c,d { C(a,F(b),G(c,d)) } ::
- // PreF(b) && PreG(c,d) && PredC(a,F(b),G(c,d))
- // ==> C(a,F(b),G(c,d)))
- //
- // To be usable, we need to do more. In particular, we need to do some preprocessing of the expressions
- // of the form C(E0,E1,E2) in Body, which are turned into P(E0,E1,E2) in Body[P] (where these are any
- // expressions E0,E1,E2, not necessarily the ones as above). We know that such C(E0,E1,E2) occurrences
- // sit only in positive positions. Hence, we can soundly replace each (exists a,b,c,d :: Q(a,b,c,d))
- // expressions in Body[P] in the axiom with Q(A,B,C,D) for any A,B,C,D. For this to be useful, we need
- // good guesses for A,B,C,D.
- //
- // TODO: also need a module/function-height antecedent for the axiom!
- var tok = coPredicate.tok;
- var bvs = new Bpl.VariableSeq();
- var boundVars = new List<BoundVar>();
- Bpl.BoundVariable heapVar = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$h", predef.HeapType));
- bvs.Add(heapVar);
- var bHeap = new Bpl.IdentifierExpr(tok, heapVar);
- Bpl.Expr typeAntecedents = FunctionCall(tok, BuiltinFunction.IsGoodHeap, null, bHeap);
- var etran = new ExpressionTranslator(this, predef, bHeap);
- Expression pre = new LiteralExpr(tok, true);
- var i = 0;
- Expression receiverReplacement = null;
- if (!coPredicate.IsStatic) {
- Expression preF;
- receiverReplacement = FG(tok, callOfInterest.Receiver.Type, t[i], boundVars, bvs, ref typeAntecedents, out preF, etran);
- typeAntecedents = BplAnd(typeAntecedents, Bpl.Expr.Neq(etran.TrExpr(receiverReplacement), predef.Null));
- if (preF != null) {
- pre = AutoContractsRewriter.BinBoolExpr(receiverReplacement.tok, BinaryExpr.ResolvedOpcode.And, pre, preF);
- }
- i++;
- }
- var substMap = new Dictionary<IVariable, Expression>();
- var j = 0;
- foreach (var p in coPredicate.Formals) {
- Expression preF;
- var e = FG(tok, callOfInterest.Args[j].Type, t[i], boundVars, bvs, ref typeAntecedents, out preF, etran);
- substMap.Add(p, e);
- if (preF != null) {
- pre = AutoContractsRewriter.BinBoolExpr(e.tok, BinaryExpr.ResolvedOpcode.And, pre, preF);
- }
- i++; j++;
- }
- // conjoin subst(preC) to pre
- foreach (var req in coPredicate.Req) {
- var preC = Substitute(req, receiverReplacement, substMap);
- pre = AutoContractsRewriter.BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.And, pre, preC);
- }
- // build up the term C(a,F(b),G(c,d))
- var args = new List<Expression>();
- foreach (var p in coPredicate.Formals) {
- args.Add(substMap[p]);
- }
- var C = new FunctionCallExpr(tok, coPredicate.Name, receiverReplacement, tok, args);
- C.Function = coPredicate;
- C.Type = coPredicate.ResultType;
- // We are now ready to produce the Conclusion of the axiom
- var preStuff = Bpl.Expr.And(typeAntecedents, etran.TrExpr(pre));
- Bpl.Expr Conclusion = new Bpl.ForallExpr(tok, bvs, new Bpl.Trigger(tok, true, new ExprSeq(etran.TrExpr(C))),
- Bpl.Expr.Imp(preStuff, etran.TrExpr(C)));
- // Now for the antecedent of the axiom
- if (coPredicate.Body is MatchExpr) {
- return Bpl.Expr.True; // TODO: if coPredicate.Body uses a 'match' expression, first desugar it into an ordinary expression
- }
- var s = new CoinductionSubstituter(coPredicate, receiverReplacement, substMap, pre, boundVars, receiverReplacement, args);
- var body = s.Substitute(coPredicate.Body);
- Bpl.Expr Antecedent = new Bpl.ForallExpr(tok, bvs, Bpl.Expr.Imp(preStuff, etran.TrExpr(body)));
- // Put it all together and we're ready to go
- return Bpl.Expr.Imp(Antecedent, Conclusion);
- }
-
- /// <summary>
- /// "templateFunc" is passed in as "null", then "precondition" is guaranteed to come out as "null".
- /// </summary>
- Expression FG(IToken tok, Type argumentType, FunctionCallExpr templateFunc, List<BoundVar> boundVars, Bpl.VariableSeq bvs, ref Bpl.Expr typeAntecedents, out Expression precondition, ExpressionTranslator etran) {
- Contract.Requires(tok != null);
- Contract.Requires(argumentType != null);
- Contract.Requires(boundVars != null);
- Contract.Requires(bvs != null);
- Contract.Requires(etran != null);
- Contract.Ensures(Contract.Result<Expression>() != null);
- Contract.Ensures(Contract.ValueAtReturn<Expression>(out precondition) != null);
- // TODO: also need to return type antecedents
- precondition = new LiteralExpr(tok, true);
- if (templateFunc == null) {
- // generate a fresh variable of type "argumentType"
- var k = new BoundVar(tok, "_coind" + otherTmpVarCount, argumentType);
- otherTmpVarCount++;
- boundVars.Add(k);
- // convert it to a Boogie variable and add it to "bvs"
- var bvar = new Bpl.BoundVariable(k.tok, new Bpl.TypedIdent(k.tok, k.UniqueName, TrType(k.Type)));
- bvs.Add(bvar);
- // update typeAntecedents
- var wh = GetWhereClause(k.tok, new Bpl.IdentifierExpr(k.tok, bvar), k.Type, etran);
- if (wh != null) {
- typeAntecedents = BplAnd(typeAntecedents, wh);
- }
- // make an IdentifierExpr out of it and return it
- IdentifierExpr ie = new IdentifierExpr(k.tok, k.UniqueName);
- ie.Var = k; ie.Type = ie.Var.Type; // resolve it here
- return ie;
-
- } else {
- // for each formal parameter to "templateFunc", generate a fresh variable
- // for each one, convert it to a Boogie variable and add it to "bvs"
- // make a FunctionCallExpr, passing in these variables as arguments, and then returning the FunctionCallExpr
- Expression preIgnore;
- Expression receiver = null;
- if (!templateFunc.Function.IsStatic) {
- receiver = FG(tok, templateFunc.Receiver.Type, null, boundVars, bvs, ref typeAntecedents, out preIgnore, etran);
- typeAntecedents = BplAnd(typeAntecedents, Bpl.Expr.Neq(etran.TrExpr(receiver), predef.Null));
- }
- var args = new List<Expression>();
- var i = 0;
- var substMap = new Dictionary<IVariable, Expression>();
- foreach (var arg in templateFunc.Args) {
- var e = FG(tok, arg.Type, null, boundVars, bvs, ref typeAntecedents, out preIgnore, etran);
- args.Add(e);
- substMap.Add(templateFunc.Function.Formals[i], e);
- i++;
- }
- var F = new FunctionCallExpr(tok, templateFunc.Name, receiver, tok, args);
- F.Function = templateFunc.Function;
- F.Type = templateFunc.Function.ResultType;
-
- foreach (var req in templateFunc.Function.Req) {
- var pre = Substitute(req, receiver, substMap);
- precondition = AutoContractsRewriter.BinBoolExpr(tok, BinaryExpr.ResolvedOpcode.And, precondition, pre);
- }
- return F;
- }
- }
-
- /// <summary>
- /// Returns true iff 'v' occurs as a free variable in 'expr'.
- /// Parameter 'v' is allowed to be a ThisSurrogate, in which case the method return true iff 'this'
- /// occurs in 'expr'.
- /// </summary>
- static bool ContainsFreeVariable(Expression expr, bool lookForReceiver, IVariable v) {
- Contract.Requires(expr != null);
- Contract.Requires(lookForReceiver || v != null);
-
- if (expr is ThisExpr) {
- return lookForReceiver || v is ThisSurrogate;
- } else if (expr is IdentifierExpr) {
- IdentifierExpr e = (IdentifierExpr)expr;
- return e.Var == v;
- } else {
- foreach (var ee in expr.SubExpressions) {
- if (ContainsFreeVariable(ee, lookForReceiver, v)) {
- return true;
- }
- }
- return false;
- }
- }
-
- /// <summary>
- /// Returns true iff 'expr' is a two-state expression, that is, if it mentions "old(...)" or "fresh(...)".
- /// </summary>
- public static bool MentionsOldState(Expression expr) {
- Contract.Requires(expr != null);
- if (expr is OldExpr || expr is FreshExpr) {
- return true;
- }
- foreach (var ee in expr.SubExpressions) {
- if (MentionsOldState(ee)) {
- return true;
- }
- }
- return false;
- }
-
- public static Expression Substitute(Expression expr, Expression receiverReplacement, Dictionary<IVariable, Expression/*!*/>/*!*/ substMap) {
- Contract.Requires(expr != null);
- Contract.Requires(cce.NonNullDictionaryAndValues(substMap));
- Contract.Ensures(Contract.Result<Expression>() != null);
- var s = new Substituter(receiverReplacement, substMap);
- return s.Substitute(expr);
- }
-
- public class CoinductionSubstituter : Substituter
- {
- CoPredicate coPredicate;
- Expression existentialAntecedent;
- List<BoundVar> existentialVariables;
- Expression existentialReceiver;
- List<Expression> existentialTemplates;
-
- public CoinductionSubstituter(CoPredicate coPredicate, Expression receiverReplacement, Dictionary<IVariable, Expression> substMap,
- Expression existentialAntecedent, List<BoundVar> existentialVariables, Expression existentialReceiver, List<Expression> existentialTemplates)
- : base(receiverReplacement, substMap)
- {
- Contract.Requires(coPredicate != null);
- Contract.Requires(substMap != null);
- Contract.Requires(existentialAntecedent != null);
- Contract.Requires(existentialVariables != null);
- Contract.Requires(existentialTemplates != null);
- this.coPredicate = coPredicate;
- this.existentialAntecedent = existentialAntecedent;
- this.existentialVariables = existentialVariables;
- this.existentialReceiver = existentialReceiver;
- this.existentialTemplates = existentialTemplates;
- }
- public override Expression Substitute(Expression expr) {
- expr = base.Substitute(expr);
- var e = expr as FunctionCallExpr;
- if (e == null || e.Function != coPredicate) {
- return expr;
- }
- // We found a call coPredicate(args). Replace it with P(args), where P is the predicate we're
- // using in the coinduction principle. As described in method CoinductionPrinciple above, the
- // predicate P has the form:
- // exists a,b,c,d :: PreF(b) && PreG(c,d) && PredC(a,F(b),G(c,d)) && (s0,s1,s2) == (a,F(b),G(c,d))
- // where s0,s1,s2 are shows as the actual arguments to coPredicate (called "args" four lines
- // above). This existential corresponds to the parameters passed to this CoinductionSubstituter
- // as follows:
- // exists existentialVariables :: existentialAntecedent && (s0,s1,s2) == (existentialTemplate)
- // The idea is now to build up a substitution for a,b,c,d, such that the last conjunct
- // in the existential will be true in any context. We can then replace coPredicate(s0,s1,s2) with
- // existentialAntecedent[a,b,c,d := A,B,C,D]
- var substMap = new Dictionary<IVariable, Expression>();
- var j = 0;
- for (int i = -1; i < existentialTemplates.Count; i++) {
- Expression templ;
- Expression si;
- if (0 <= i) {
- templ = existentialTemplates[i].Resolved;
- si = e.Args[i];
- } else if (existentialReceiver != null) {
- templ = existentialReceiver.Resolved;
- si = e.Receiver;
- } else {
- continue;
- }
- templ = PossiblyInline(templ);
- if (templ is IdentifierExpr) {
- // this one is easy--use the instantiation a:=si
- Contract.Assert(((IdentifierExpr)templ).Var == existentialVariables[j]);
- substMap.Add(existentialVariables[j], si);
- j++;
- } else {
- var templFce = (FunctionCallExpr)templ;
- var psi = PartiallyEvaluate(si, 1);
- var fce = psi as FunctionCallExpr;
- if (fce == null || fce.Function != templFce.Function) {
- // This is not what we were hoping for. What can we do?
- // One option would be to existentially quantify over the variable for which we didn't get an instantiation.
- // Another option would be to guess some arbitrary but value.
- // A third option, which is what we'll do, is to return false.
- return new LiteralExpr(e.tok, false);
- } else {
- // We're in luck. Pick the parameters of the partially evaluated call
- if (templFce.Receiver != null) {
- Contract.Assert(templFce.Receiver is IdentifierExpr && ((IdentifierExpr)templFce.Receiver).Var == existentialVariables[j]);
- substMap.Add(existentialVariables[j], fce.Receiver);
- j++;
- }
- var k = 0;
- foreach (var arg in fce.Args) {
- Contract.Assert(templFce.Args[k] is IdentifierExpr && ((IdentifierExpr)templFce.Args[k]).Var == existentialVariables[j]);
- substMap.Add(existentialVariables[j], arg);
- j++;
- k++;
- }
- }
- }
- }
- Contract.Assert(j == existentialVariables.Count);
- return Translator.Substitute(existentialAntecedent, null, substMap);
- }
-
- Expression PossiblyInline(Expression expr) {
- Contract.Requires(expr != null);
- Contract.Ensures(Contract.Result<Expression>() != null);
- if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- if (e.Function.Body != null && !e.Function.IsRecursive) {
- var inlinedBody = InlineFunctionCall(e);
- // use the inlinedBody if it consists of only IdentifierExpr's and FunctionCallExpr's
- if (IsTemplateLike(inlinedBody)) {
- return PossiblyInline(inlinedBody);
- }
- }
- }
- return expr;
- }
-
- bool IsTemplateLike(Expression expr) {
- Contract.Requires(expr != null);
- expr = expr.Resolved;
- if (expr is IdentifierExpr) {
- return true;
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- if (e.Receiver == null || IsTemplateLike(e.Receiver)) {
- return e.Args.TrueForAll(IsTemplateLike);
- }
- }
- return false;
- }
- }
-
- /// <summary>
- /// Returns a (resolved) expression that evaluates to the same value as "expr".
- /// Assumes "expr" to be well defined.
- /// </summary>
- public static Expression PartiallyEvaluate(Expression expr, int recursiveInlineDepth) {
- Contract.Requires(expr != null);
- Contract.Requires(0 <= recursiveInlineDepth);
- if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return PartiallyEvaluate(e.ResolvedExpression, recursiveInlineDepth);
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- // check if it's a destructor around a constructor
- var dtor = e.Field as DatatypeDestructor;
- if (dtor != null) {
- var obj = PartiallyEvaluate(e.Obj, recursiveInlineDepth);
- var dtv = obj as DatatypeValue;
- if (dtv != null) {
- for (int i = 0; i < dtv.Ctor.Formals.Count; i++) {
- if (dtv.Ctor.Formals[i] == dtor.CorrespondingFormal) {
- return dtv.Arguments[i];
- }
- }
- Contract.Assert(false); // we expect to have found the destructor among the constructor's formals
- } else if (obj != e.Obj) {
- var peE = new FieldSelectExpr(e.tok, obj, e.FieldName);
- peE.Field = e.Field; // resolve here
- peE.Type = e.Type; // resolve here
- return peE;
- }
- }
- } else if (expr is FunctionCallExpr) {
- var e = (FunctionCallExpr)expr;
- if (e.Function.Body != null && (!e.Function.IsRecursive || 0 < recursiveInlineDepth)) {
- var inlinedBody = InlineFunctionCall(e);
- return PartiallyEvaluate(inlinedBody, recursiveInlineDepth - (e.Function.IsRecursive ? 1 : 0));
- }
- }
- return expr;
- }
-
- static Expression InlineFunctionCall(FunctionCallExpr fce) {
- Contract.Requires(fce != null);
- var substMap = new Dictionary<IVariable, Expression>();
- for (int i = 0; i < fce.Args.Count; i++) {
- substMap.Add(fce.Function.Formals[i], fce.Args[i]);
- }
- // TODO: in the following substitution, it may be that we also need to update the types of the resulting subexpressions (is this true for all Substitute calls?)
- return Substitute(fce.Function.Body, fce.Receiver, substMap);
- }
- public class FunctionCallSubstituter : Substituter
- {
- public readonly Function A, B;
- public FunctionCallSubstituter(Expression receiverReplacement, Dictionary<IVariable, Expression/*!*/>/*!*/ substMap, Function a, Function b)
- : base(receiverReplacement, substMap) {
- A = a;
- B = b;
- }
- public override Expression Substitute(Expression expr) {
- if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- Expression receiver = Substitute(e.Receiver);
- List<Expression> newArgs = SubstituteExprList(e.Args);
- FunctionCallExpr newFce = new FunctionCallExpr(expr.tok, e.Name, receiver, e.OpenParen, newArgs);
- if (e.Function == A) {
- newFce.Function = B;
- newFce.Type = e.Type; // TODO: this may not work with type parameters.
- } else {
- newFce.Function = e.Function;
- newFce.Type = e.Type;
- }
- return newFce;
- }
- return base.Substitute(expr);
- }
- }
- public class Substituter
- {
- public readonly Expression receiverReplacement;
- public readonly Dictionary<IVariable, Expression/*!*/>/*!*/ substMap;
- public Substituter(Expression receiverReplacement, Dictionary<IVariable, Expression/*!*/>/*!*/ substMap) {
- Contract.Requires(substMap != null);
- this.receiverReplacement = receiverReplacement;
- this.substMap = substMap;
- }
- public virtual Expression Substitute(Expression expr) {
- Contract.Requires(expr != null);
- Contract.Ensures(Contract.Result<Expression>() != null);
-
- Expression newExpr = null; // set to non-null value only if substitution has any effect; if non-null, newExpr will be resolved at end
-
- if (expr is LiteralExpr || expr is WildcardExpr || expr is BoogieWrapper) {
- // nothing to substitute
- } else if (expr is ThisExpr) {
- return receiverReplacement == null ? expr : receiverReplacement;
- } else if (expr is IdentifierExpr) {
- IdentifierExpr e = (IdentifierExpr)expr;
- Expression substExpr;
- if (substMap.TryGetValue(e.Var, out substExpr)) {
- return cce.NonNull(substExpr);
- }
- } else if (expr is DisplayExpression) {
- DisplayExpression e = (DisplayExpression)expr;
- List<Expression> newElements = SubstituteExprList(e.Elements);
- if (newElements != e.Elements) {
- if (expr is SetDisplayExpr) {
- newExpr = new SetDisplayExpr(expr.tok, newElements);
- } else if (expr is MultiSetDisplayExpr) {
- newExpr = new MultiSetDisplayExpr(expr.tok, newElements);
- } else {
- newExpr = new SeqDisplayExpr(expr.tok, newElements);
- }
- }
-
- } else if (expr is FieldSelectExpr) {
- FieldSelectExpr fse = (FieldSelectExpr)expr;
- Expression substE = Substitute(fse.Obj);
- if (substE != fse.Obj) {
- FieldSelectExpr fseNew = new FieldSelectExpr(fse.tok, substE, fse.FieldName);
- fseNew.Field = fse.Field; // resolve on the fly (and fseExpr.Type is set at end of method)
- newExpr = fseNew;
- }
-
- } else if (expr is SeqSelectExpr) {
- SeqSelectExpr sse = (SeqSelectExpr)expr;
- Expression seq = Substitute(sse.Seq);
- Expression e0 = sse.E0 == null ? null : Substitute(sse.E0);
- Expression e1 = sse.E1 == null ? null : Substitute(sse.E1);
- if (seq != sse.Seq || e0 != sse.E0 || e1 != sse.E1) {
- newExpr = new SeqSelectExpr(sse.tok, sse.SelectOne, seq, e0, e1);
- }
-
- } else if (expr is SeqUpdateExpr) {
- SeqUpdateExpr sse = (SeqUpdateExpr)expr;
- Expression seq = Substitute(sse.Seq);
- Expression index = Substitute(sse.Index);
- Expression val = Substitute(sse.Value);
- if (seq != sse.Seq || index != sse.Index || val != sse.Value) {
- newExpr = new SeqUpdateExpr(sse.tok, seq, index, val);
- }
-
- } else if (expr is MultiSelectExpr) {
- MultiSelectExpr mse = (MultiSelectExpr)expr;
- Expression array = Substitute(mse.Array);
- List<Expression> newArgs = SubstituteExprList(mse.Indices);
- if (array != mse.Array || newArgs != mse.Indices) {
- newExpr = new MultiSelectExpr(mse.tok, array, newArgs);
- }
-
- } else if (expr is FunctionCallExpr) {
- FunctionCallExpr e = (FunctionCallExpr)expr;
- Expression receiver = Substitute(e.Receiver);
- List<Expression> newArgs = SubstituteExprList(e.Args);
- if (receiver != e.Receiver || newArgs != e.Args) {
- FunctionCallExpr newFce = new FunctionCallExpr(expr.tok, e.Name, receiver, e.OpenParen, newArgs);
- newFce.Function = e.Function; // resolve on the fly (and set newFce.Type below, at end)
- newExpr = newFce;
- }
-
- } else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- List<Expression> newArgs = SubstituteExprList(dtv.Arguments);
- if (newArgs != dtv.Arguments) {
- DatatypeValue newDtv = new DatatypeValue(dtv.tok, dtv.DatatypeName, dtv.MemberName, newArgs);
- newDtv.Ctor = dtv.Ctor; // resolve on the fly (and set newDtv.Type below, at end)
- newExpr = newDtv;
- }
-
- } else if (expr is OldExpr) {
- OldExpr e = (OldExpr)expr;
- // Note, it is up to the caller to avoid variable capture. In most cases, this is not a
- // problem, since variables have unique declarations. However, it is an issue if the substitution
- // takes place inside an OldExpr. In those cases (see LetExpr), the caller can use a
- // BoogieWrapper before calling Substitute.
- Expression se = Substitute(e.E);
- if (se != e.E) {
- newExpr = new OldExpr(expr.tok, se);
- }
- } else if (expr is FreshExpr) {
- FreshExpr e = (FreshExpr)expr;
- Expression se = Substitute(e.E);
- if (se != e.E) {
- newExpr = new FreshExpr(expr.tok, se);
- }
- } else if (expr is UnaryExpr) {
- UnaryExpr e = (UnaryExpr)expr;
- Expression se = Substitute(e.E);
- if (se != e.E) {
- newExpr = new UnaryExpr(expr.tok, e.Op, se);
- }
- } else if (expr is BinaryExpr) {
- BinaryExpr e = (BinaryExpr)expr;
- Expression e0 = Substitute(e.E0);
- Expression e1 = Substitute(e.E1);
- if (e0 != e.E0 || e1 != e.E1) {
- BinaryExpr newBin = new BinaryExpr(expr.tok, e.Op, e0, e1);
- newBin.ResolvedOp = e.ResolvedOp; // part of what needs to be done to resolve on the fly (newBin.Type is set below, at end)
- newExpr = newBin;
- }
-
- } else if (expr is LetExpr) {
- var e = (LetExpr)expr;
- var rhss = new List<Expression>();
- bool anythingChanged = false;
- foreach (var rhs in e.RHSs) {
- var r = Substitute(rhs);
- if (r != rhs) {
- anythingChanged = true;
- }
- rhss.Add(r);
- }
- var body = Substitute(e.Body);
- if (anythingChanged || body != e.Body) {
- newExpr = new LetExpr(e.tok, e.Vars, rhss, body);
- }
-
- } else if (expr is NamedExpr) {
- var e = (NamedExpr)expr;
- var body = Substitute(e.Body);
- var contract = e.Contract == null ? null : Substitute(e.Contract);
- newExpr = new NamedExpr(e.tok, e.Name, body, contract, e.ReplacerToken);
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- Expression newRange = e.Range == null ? null : Substitute(e.Range);
- Expression newTerm = Substitute(e.Term);
- Attributes newAttrs = SubstAttributes(e.Attributes);
- if (e is SetComprehension) {
- if (newRange != e.Range || newTerm != e.Term || newAttrs != e.Attributes) {
- newExpr = new SetComprehension(expr.tok, e.BoundVars, newRange, newTerm);
- }
- } else if (e is MapComprehension) {
- if (newRange != e.Range || newTerm != e.Term || newAttrs != e.Attributes) {
- newExpr = new MapComprehension(expr.tok, e.BoundVars, newRange, newTerm);
- }
- } else if (e is QuantifierExpr) {
- var q = (QuantifierExpr)e;
- if (newRange != e.Range || newTerm != e.Term || newAttrs != e.Attributes) {
- if (expr is ForallExpr) {
- newExpr = new ForallExpr(expr.tok, e.BoundVars, newRange, newTerm, newAttrs);
- } else {
- newExpr = new ExistsExpr(expr.tok, e.BoundVars, newRange, newTerm, newAttrs);
- }
- }
- } else {
- Contract.Assert(false); // unexpected ComprehensionExpr
- }
-
- } else if (expr is PredicateExpr) {
- var e = (PredicateExpr)expr;
- Expression g = Substitute(e.Guard);
- Expression b = Substitute(e.Body);
- if (g != e.Guard || b != e.Body) {
- if (expr is AssertExpr) {
- newExpr = new AssertExpr(e.tok, g, b);
- } else {
- newExpr = new AssumeExpr(e.tok, g, b);
- }
- }
-
- } else if (expr is ITEExpr) {
- ITEExpr e = (ITEExpr)expr;
- Expression test = Substitute(e.Test);
- Expression thn = Substitute(e.Thn);
- Expression els = Substitute(e.Els);
- if (test != e.Test || thn != e.Thn || els != e.Els) {
- newExpr = new ITEExpr(expr.tok, test, thn, els);
- }
-
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return Substitute(e.ResolvedExpression);
- }
-
- if (newExpr == null) {
- return expr;
- } else {
- newExpr.Type = expr.Type; // resolve on the fly (any additional resolution must be done above)
- return newExpr;
- }
- }
-
- protected List<Expression/*!*/>/*!*/ SubstituteExprList(List<Expression/*!*/>/*!*/ elist) {
- Contract.Requires(cce.NonNullElements(elist));
- Contract.Ensures(cce.NonNullElements(Contract.Result<List<Expression>>()));
-
- List<Expression> newElist = null; // initialized lazily
- for (int i = 0; i < elist.Count; i++) {
- cce.LoopInvariant(newElist == null || newElist.Count == i);
-
- Expression substE = Substitute(elist[i]);
- if (substE != elist[i] && newElist == null) {
- newElist = new List<Expression>();
- for (int j = 0; j < i; j++) {
- newElist.Add(elist[j]);
- }
- }
- if (newElist != null) {
- newElist.Add(substE);
- }
- }
- if (newElist == null) {
- return elist;
- } else {
- return newElist;
- }
- }
-
- public Attributes SubstAttributes(Attributes attrs) {
- Contract.Requires(cce.NonNullDictionaryAndValues(substMap));
- if (attrs != null) {
- List<Attributes.Argument> newArgs = new List<Attributes.Argument>(); // allocate it eagerly, what the heck, it doesn't seem worth the extra complexity in the code to do it lazily for the infrequently occurring attributes
- bool anyArgSubst = false;
- foreach (Attributes.Argument arg in attrs.Args) {
- Attributes.Argument newArg = arg;
- if (arg.E != null) {
- Expression newE = Substitute(arg.E);
- if (newE != arg.E) {
- newArg = new Attributes.Argument(arg.Tok, newE);
- anyArgSubst = true;
- }
- }
- newArgs.Add(newArg);
- }
- if (!anyArgSubst) {
- newArgs = attrs.Args;
- }
-
- Attributes prev = SubstAttributes(attrs.Prev);
- if (newArgs != attrs.Args || prev != attrs.Prev) {
- return new Attributes(attrs.Name, newArgs, prev);
- }
- }
- return attrs;
- }
- }
-
- }
-}
diff --git a/Source/Dafny/Util.cs b/Source/Dafny/Util.cs
deleted file mode 100644
index 8db3ebc8..00000000
--- a/Source/Dafny/Util.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Microsoft.Dafny {
- class Util
- {
- public delegate string ToString<T>(T t);
- public static string Comma<T>(string comma, IEnumerable<T> l, ToString<T> f) {
- string res = "";
- string c = "";
- foreach(var t in l) {
- res += c + f(t);
- c = comma;
- }
- return res;
- }
- }
-}
diff --git a/Source/Dafny/cce.cs b/Source/Dafny/cce.cs
deleted file mode 100644
index ff5152d0..00000000
--- a/Source/Dafny/cce.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Text;
-using Microsoft.Boogie;
-
- /// <summary>
- /// A class containing static methods to extend the functionality of Code Contracts
- /// </summary>
-
-public static class cce {
- [Pure]
- public static T NonNull<T>(T t) where T : class {
- Contract.Assert(t != null);
- return t;
- }
- [Pure]
- public static bool NonNullElements<T>(IEnumerable<T> collection) where T : class {
- return collection != null && Contract.ForAll(collection, c => c != null);
- }
- [Pure]
- public static bool NonNullDictionaryAndValues<TKey, TValue>(IDictionary<TKey, TValue> collection) where TValue : class {
- return collection != null && NonNullElements(collection.Values);
- }
- [Pure]
- public static bool NonNullElements(VariableSeq collection) {
- return collection != null && Contract.ForAll(0, collection.Length, i => collection[i] != null);
- }
- [Pure]
- public static bool NonNullElements<T>(Microsoft.Dafny.Graph<T> collection) where T : class {
- return collection != null && cce.NonNullElements(collection.TopologicallySortedComponents());
- }
- [Pure]
- public static void BeginExpose(object o) {
- }
- [Pure]
- public static void EndExpose() {
- }
- [Pure]
- public static bool IsPeerConsistent(object o) {
- return true;
- }
- [Pure]
- public static bool IsConsistent(object o) {
- return true;
- }
- [Pure]
- public static bool IsExposable(object o) {
- return true;
- }
- [Pure]
- public static bool IsExposed(object o) {
- return true;
- }
- public static class Owner {
- [Pure]
- public static bool Same(object o, object p) {
- return true;
- }
- [Pure]
- public static void AssignSame(object o, object p) {
- }
- [Pure]
- public static object ElementProxy(object o) {
- return o;
- }
- [Pure]
- public static bool None(object o) {
- return true;
- }
- }
- [Pure]
- public static void LoopInvariant(bool p) {
- Contract.Assert(p);
- }
-
- public class UnreachableException : Exception {
- public UnreachableException() {
- }
- }
- [Pure]
- public static bool IsValid(Microsoft.Dafny.Expression expression) {
- return true;
- }
-}
-
-public class PeerAttribute : System.Attribute {
-}
-public class RepAttribute : System.Attribute {
-}
-public class CapturedAttribute : System.Attribute {
-}
-public class NotDelayedAttribute : System.Attribute {
-}
-public class NoDefaultContractAttribute : System.Attribute {
-}
-public class VerifyAttribute : System.Attribute {
- public VerifyAttribute(bool b) {
-
- }
-}
-public class StrictReadonlyAttribute : System.Attribute {
- }
-public class AdditiveAttribute : System.Attribute {
-}
-public class ReadsAttribute : System.Attribute {
- public enum Reads {
- Nothing,
- };
- public ReadsAttribute(object o) {
- }
-} \ No newline at end of file
diff --git a/Source/DafnyDriver/DafnyDriver.cs b/Source/DafnyDriver/DafnyDriver.cs
deleted file mode 100644
index e7679a11..00000000
--- a/Source/DafnyDriver/DafnyDriver.cs
+++ /dev/null
@@ -1,796 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) Microsoft Corporation. All Rights Reserved.
-//
-//-----------------------------------------------------------------------------
-//---------------------------------------------------------------------------------------------
-// DafnyDriver
-// - main program for taking a Dafny program and verifying it
-//---------------------------------------------------------------------------------------------
-
-namespace Microsoft.Dafny
-{
- using System;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using PureCollections;
- using Microsoft.Boogie;
- using Bpl = Microsoft.Boogie;
- using Microsoft.Boogie.AbstractInterpretation;
- using System.Diagnostics;
- using VC;
- using System.CodeDom.Compiler;
-
- public class DafnyDriver
- {
- // ------------------------------------------------------------------------
- // Main
-
- public static int Main(string[] args)
- {
- Contract.Requires(cce.NonNullElements(args));
-
- DafnyOptions.Install(new DafnyOptions());
-
- //assert forall{int i in (0:args.Length); args[i] != null};
- ExitValue exitValue = ExitValue.VERIFIED;
- CommandLineOptions.Clo.RunningBoogieFromCommandLine = true;
- if (!CommandLineOptions.Clo.Parse(args)) {
- exitValue = ExitValue.PREPROCESSING_ERROR;
- goto END;
- }
- if (CommandLineOptions.Clo.Files.Count == 0)
- {
- ErrorWriteLine("*** Error: No input files were specified.");
- exitValue = ExitValue.PREPROCESSING_ERROR;
- goto END;
- }
- if (CommandLineOptions.Clo.XmlSink != null) {
- string errMsg = CommandLineOptions.Clo.XmlSink.Open();
- if (errMsg != null) {
- ErrorWriteLine("*** Error: " + errMsg);
- exitValue = ExitValue.PREPROCESSING_ERROR;
- goto END;
- }
- }
- if (!CommandLineOptions.Clo.DontShowLogo)
- {
- Console.WriteLine(CommandLineOptions.Clo.Version);
- }
- if (CommandLineOptions.Clo.ShowEnv == CommandLineOptions.ShowEnvironment.Always)
- {
- Console.WriteLine("---Command arguments");
- foreach (string arg in args)
- {Contract.Assert(arg != null);
- Console.WriteLine(arg);
- }
- Console.WriteLine("--------------------");
- }
-
- foreach (string file in CommandLineOptions.Clo.Files)
- {Contract.Assert(file != null);
- string extension = Path.GetExtension(file);
- if (extension != null) { extension = extension.ToLower(); }
- if (extension != ".dfy")
- {
- ErrorWriteLine("*** Error: '{0}': Filename extension '{1}' is not supported. Input files must be Dafny programs (.dfy).", file,
- extension == null ? "" : extension);
- exitValue = ExitValue.PREPROCESSING_ERROR;
- goto END;
- }
- }
- exitValue = ProcessFiles(CommandLineOptions.Clo.Files);
-
- END:
- if (CommandLineOptions.Clo.XmlSink != null) {
- CommandLineOptions.Clo.XmlSink.Close();
- }
- if (CommandLineOptions.Clo.Wait)
- {
- Console.WriteLine("Press Enter to exit.");
- Console.ReadLine();
- }
- return (int)exitValue;
- }
-
- public static void ErrorWriteLine(string s) {Contract.Requires(s != null);
- if (!s.Contains("Error: ") && !s.Contains("Error BP")) {
- Console.WriteLine(s);
- return;
- }
-
- // split the string up into its first line and the remaining lines
- string remaining = null;
- int i = s.IndexOf('\r');
- if (0 <= i) {
- remaining = s.Substring(i+1);
- if (remaining.StartsWith("\n")) {
- remaining = remaining.Substring(1);
- }
- s = s.Substring(0, i);
- }
-
- ConsoleColor col = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine(s);
- Console.ForegroundColor = col;
-
- if (remaining != null) {
- Console.WriteLine(remaining);
- }
- }
-
- public static void ErrorWriteLine(string format, params object[] args) {
- Contract.Requires(format != null);
- string s = string.Format(format, args);
- ErrorWriteLine(s);
- }
-
- public static void AdvisoryWriteLine(string format, params object[] args) {
- Contract.Requires(format != null);
- ConsoleColor col = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine(format, args);
- Console.ForegroundColor = col;
- }
-
- enum FileType { Unknown, Cil, Bpl, Dafny };
-
- static ExitValue ProcessFiles (List<string/*!*/>/*!*/ fileNames)
- {
- Contract.Requires(cce.NonNullElements(fileNames));
- ExitValue exitValue = ExitValue.VERIFIED;
- using (XmlFileScope xf = new XmlFileScope(CommandLineOptions.Clo.XmlSink, fileNames[fileNames.Count-1])) {
- Dafny.Program dafnyProgram;
- string programName = fileNames.Count == 1 ? fileNames[0] : "the program";
- string err = Dafny.Main.ParseCheck(fileNames, programName, out dafnyProgram);
- if (err != null) {
- exitValue = ExitValue.DAFNY_ERROR;
- ErrorWriteLine(err);
- } else if (dafnyProgram != null && !CommandLineOptions.Clo.NoResolve && !CommandLineOptions.Clo.NoTypecheck) {
- Dafny.Translator translator = new Dafny.Translator();
- Bpl.Program boogieProgram = translator.Translate(dafnyProgram);
- if (CommandLineOptions.Clo.PrintFile != null)
- {
- PrintBplFile(CommandLineOptions.Clo.PrintFile, boogieProgram, false);
- }
-
- string bplFilename;
- if (CommandLineOptions.Clo.PrintFile != null) {
- bplFilename = CommandLineOptions.Clo.PrintFile;
- } else {
- string baseName = cce.NonNull(Path.GetFileName(fileNames[fileNames.Count-1]));
- baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl"));
- bplFilename = Path.Combine(Path.GetTempPath(), baseName);
- }
-
- int errorCount, verified, inconclusives, timeOuts, outOfMemories;
- PipelineOutcome oc = BoogiePipelineWithRerun(boogieProgram, bplFilename, out errorCount, out verified, out inconclusives, out timeOuts, out outOfMemories);
- bool allOk = errorCount == 0 && inconclusives == 0 && timeOuts == 0 && outOfMemories == 0;
- switch (oc) {
- case PipelineOutcome.VerificationCompleted:
- WriteTrailer(verified, errorCount, inconclusives, timeOuts, outOfMemories);
- if ((DafnyOptions.O.Compile && allOk && CommandLineOptions.Clo.ProcsToCheck == null) || DafnyOptions.O.ForceCompile)
- CompileDafnyProgram(dafnyProgram, fileNames[0]);
- break;
- case PipelineOutcome.Done:
- WriteTrailer(verified, errorCount, inconclusives, timeOuts, outOfMemories);
- if (DafnyOptions.O.ForceCompile)
- CompileDafnyProgram(dafnyProgram, fileNames[0]);
- break;
- default:
- // error has already been reported to user
- break;
- }
- exitValue = allOk ? ExitValue.VERIFIED : ExitValue.NOT_VERIFIED;
- }
- }
- return exitValue;
- }
-
- private static void CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName)
- {
- // Compile the Dafny program into a string that contains the C# program
- StringWriter sw = new StringWriter();
- Dafny.Compiler compiler = new Dafny.Compiler(sw);
- compiler.Compile(dafnyProgram);
- var csharpProgram = sw.ToString();
- bool completeProgram = compiler.ErrorCount == 0;
-
- // blurt out the code to a file
- if (DafnyOptions.O.SpillTargetCode) {
- string targetFilename = Path.ChangeExtension(dafnyProgramName, "cs");
- using (TextWriter target = new StreamWriter(new FileStream(targetFilename, System.IO.FileMode.Create))) {
- target.Write(csharpProgram);
- if (completeProgram) {
- Console.WriteLine("Compiled program written to {0}", targetFilename);
- } else {
- Console.WriteLine("File {0} contains the partially compiled program", targetFilename);
- }
- }
- }
-
- // compile the program into an assembly
- if (!completeProgram) {
- // don't compile
- } else if (!CodeDomProvider.IsDefinedLanguage("CSharp")) {
- Console.WriteLine("Error: cannot compile, because there is no provider configured for input language CSharp");
- } else {
- var provider = CodeDomProvider.CreateProvider("CSharp");
- var cp = new System.CodeDom.Compiler.CompilerParameters();
- cp.GenerateExecutable = true;
- if (compiler.HasMain(dafnyProgram)) {
- cp.OutputAssembly = Path.ChangeExtension(dafnyProgramName, "exe");
- cp.CompilerOptions = "/debug";
- } else {
- cp.OutputAssembly = Path.ChangeExtension(dafnyProgramName, "dll");
- cp.CompilerOptions = "/debug /target:library";
- }
- cp.GenerateInMemory = false;
- cp.ReferencedAssemblies.Add("System.Numerics.dll");
-
- var cr = provider.CompileAssemblyFromSource(cp, csharpProgram);
- if (cr.Errors.Count == 0) {
- Console.WriteLine("Compiled assembly into {0}", cr.PathToAssembly);
- } else {
- Console.WriteLine("Errors compiling program into {0}", cr.PathToAssembly);
- foreach (var ce in cr.Errors) {
- Console.WriteLine(ce.ToString());
- Console.WriteLine();
- }
- }
- }
- }
-
- static void PrintBplFile (string filename, Bpl.Program program, bool allowPrintDesugaring)
- {
- Contract.Requires(filename != null);
- Contract.Requires(program != null);
- bool oldPrintDesugaring = CommandLineOptions.Clo.PrintDesugarings;
- if (!allowPrintDesugaring) {
- CommandLineOptions.Clo.PrintDesugarings = false;
- }
- using (TokenTextWriter writer = filename == "-" ?
- new TokenTextWriter("<console>", Console.Out, false) :
- new TokenTextWriter(filename, false))
- {
- writer.WriteLine("// " + CommandLineOptions.Clo.Version);
- writer.WriteLine("// " + CommandLineOptions.Clo.Environment);
- writer.WriteLine();
- program.Emit(writer);
- }
- CommandLineOptions.Clo.PrintDesugarings = oldPrintDesugaring;
- }
-
-
- static bool ProgramHasDebugInfo (Bpl.Program program)
- {
- Contract.Requires(program != null);
- // We inspect the last declaration because the first comes from the prelude and therefore always has source context.
- return program.TopLevelDeclarations.Count > 0 &&
- cce.NonNull(program.TopLevelDeclarations[program.TopLevelDeclarations.Count - 1]).tok.IsValid;
- }
-
-
- /// <summary>
- /// Inform the user about something and proceed with translation normally.
- /// Print newline after the message.
- /// </summary>
- public static void Inform(string s) {
- if (CommandLineOptions.Clo.Trace || CommandLineOptions.Clo.TraceProofObligations) {
- Console.WriteLine(s);
- }
- }
-
- static void WriteTrailer(int verified, int errors, int inconclusives, int timeOuts, int outOfMemories){
- Contract.Requires(0 <= errors && 0 <= inconclusives && 0 <= timeOuts && 0 <= outOfMemories);
- Console.WriteLine();
- Console.Write("{0} finished with {1} verified, {2} error{3}", CommandLineOptions.Clo.DescriptiveToolName, verified, errors, errors == 1 ? "" : "s");
- if (inconclusives != 0) {
- Console.Write(", {0} inconclusive{1}", inconclusives, inconclusives == 1 ? "" : "s");
- }
- if (timeOuts != 0) {
- Console.Write(", {0} time out{1}", timeOuts, timeOuts == 1 ? "" : "s");
- }
- if (outOfMemories != 0) {
- Console.Write(", {0} out of memory", outOfMemories);
- }
- Console.WriteLine();
- Console.Out.Flush();
- }
-
-
-
- static void ReportBplError(IToken tok, string message, bool error)
- {
- Contract.Requires(message != null);
- string s;
- if (tok == null) {
- s = message;
- } else {
- s = string.Format("{0}({1},{2}): {3}", tok.filename, tok.line, tok.col, message);
- }
- if (error) {
- ErrorWriteLine(s);
- } else {
- Console.WriteLine(s);
- }
- if (tok is Dafny.NestedToken) {
- var nt = (Dafny.NestedToken)tok;
- ReportBplError(nt.Inner, "Related location: Related location", false);
- }
- }
-
- /// <summary>
- /// Parse the given files into one Boogie program. If an I/O or parse error occurs, an error will be printed
- /// and null will be returned. On success, a non-null program is returned.
- /// </summary>
- static Bpl.Program ParseBoogieProgram(List<string/*!*/>/*!*/ fileNames, bool suppressTraceOutput)
- {
- Contract.Requires(cce.NonNullElements(fileNames));
- //BoogiePL.Errors.count = 0;
- Bpl.Program program = null;
- bool okay = true;
- foreach (string bplFileName in fileNames) {
- if (!suppressTraceOutput) {
- if (CommandLineOptions.Clo.XmlSink != null) {
- CommandLineOptions.Clo.XmlSink.WriteFileFragment(bplFileName);
- }
- if (CommandLineOptions.Clo.Trace) {
- Console.WriteLine("Parsing " + bplFileName);
- }
- }
-
- Bpl.Program programSnippet;
- int errorCount;
- try {
- errorCount = Microsoft.Boogie.Parser.Parse(bplFileName, (List<string>)null, out programSnippet);
- if (programSnippet == null || errorCount != 0) {
- Console.WriteLine("{0} parse errors detected in {1}", errorCount, bplFileName);
- okay = false;
- continue;
- }
- } catch (IOException e) {
- ErrorWriteLine("Error opening file \"{0}\": {1}", bplFileName, e.Message);
- okay = false;
- continue;
- }
- if (program == null) {
- program = programSnippet;
- } else if (programSnippet != null) {
- program.TopLevelDeclarations.AddRange(programSnippet.TopLevelDeclarations);
- }
- }
- if (!okay) {
- return null;
- } else if (program == null) {
- return new Bpl.Program();
- } else {
- return program;
- }
- }
-
- /// <summary>
- /// Resolve, type check, infer invariants for, and verify the given Boogie program.
- /// The intention is that this Boogie program has been produced by translation from something
- /// else. Hence, any resolution errors and type checking errors are due to errors in
- /// the translation.
- /// The method prints errors for resolution and type checking errors, but still returns
- /// their error code.
- /// </summary>
- static PipelineOutcome BoogiePipelineWithRerun (Bpl.Program/*!*/ program, string/*!*/ bplFileName,
- out int errorCount, out int verified, out int inconclusives, out int timeOuts, out int outOfMemories)
- {
- Contract.Requires(program != null);
- Contract.Requires(bplFileName != null);
- Contract.Ensures(0 <= Contract.ValueAtReturn(out inconclusives) && 0 <= Contract.ValueAtReturn(out timeOuts));
-
- errorCount = verified = inconclusives = timeOuts = outOfMemories = 0;
- PipelineOutcome oc = ResolveAndTypecheck(program, bplFileName);
- switch (oc) {
- case PipelineOutcome.Done:
- return oc;
-
- case PipelineOutcome.ResolutionError:
- case PipelineOutcome.TypeCheckingError:
- {
- PrintBplFile(bplFileName, program, false);
- Console.WriteLine();
- Console.WriteLine("*** Encountered internal translation error - re-running Boogie to get better debug information");
- Console.WriteLine();
-
- List<string/*!*/>/*!*/ fileNames = new List<string/*!*/>();
- fileNames.Add(bplFileName);
- Bpl.Program reparsedProgram = ParseBoogieProgram(fileNames, true);
- if (reparsedProgram != null) {
- ResolveAndTypecheck(reparsedProgram, bplFileName);
- }
- }
- return oc;
-
- case PipelineOutcome.ResolvedAndTypeChecked:
- EliminateDeadVariablesAndInline(program);
- return InferAndVerify(program, out errorCount, out verified, out inconclusives, out timeOuts, out outOfMemories);
-
- default:
- Contract.Assert(false);throw new cce.UnreachableException(); // unexpected outcome
- }
- }
-
- static void EliminateDeadVariablesAndInline(Bpl.Program program) {
- Contract.Requires(program != null);
- // Eliminate dead variables
- Microsoft.Boogie.UnusedVarEliminator.Eliminate(program);
-
- // Collect mod sets
- if (CommandLineOptions.Clo.DoModSetAnalysis) {
- Microsoft.Boogie.ModSetCollector.DoModSetAnalysis(program);
- }
-
- // Coalesce blocks
- if (CommandLineOptions.Clo.CoalesceBlocks) {
- Microsoft.Boogie.BlockCoalescer.CoalesceBlocks(program);
- }
-
- // Inline
- var TopLevelDeclarations = program.TopLevelDeclarations;
-
- if (CommandLineOptions.Clo.ProcedureInlining != CommandLineOptions.Inlining.None) {
- bool inline = false;
- foreach (var d in TopLevelDeclarations) {
- if (d.FindExprAttribute("inline") != null) {
- inline = true;
- }
- }
- if (inline && CommandLineOptions.Clo.StratifiedInlining == 0) {
- foreach (var d in TopLevelDeclarations) {
- var impl = d as Implementation;
- if (impl != null) {
- impl.OriginalBlocks = impl.Blocks;
- impl.OriginalLocVars = impl.LocVars;
- }
- }
- foreach (var d in TopLevelDeclarations) {
- var impl = d as Implementation;
- if (impl != null && !impl.SkipVerification) {
- Inliner.ProcessImplementation(program, impl);
- }
- }
- foreach (var d in TopLevelDeclarations) {
- var impl = d as Implementation;
- if (impl != null) {
- impl.OriginalBlocks = null;
- impl.OriginalLocVars = null;
- }
- }
- }
- }
- }
-
- enum PipelineOutcome { Done, ResolutionError, TypeCheckingError, ResolvedAndTypeChecked, FatalError, VerificationCompleted }
- enum ExitValue { VERIFIED = 0, PREPROCESSING_ERROR, DAFNY_ERROR, NOT_VERIFIED }
-
- /// <summary>
- /// Resolves and type checks the given Boogie program. Any errors are reported to the
- /// console. Returns:
- /// - Done if no errors occurred, and command line specified no resolution or no type checking.
- /// - ResolutionError if a resolution error occurred
- /// - TypeCheckingError if a type checking error occurred
- /// - ResolvedAndTypeChecked if both resolution and type checking succeeded
- /// </summary>
- static PipelineOutcome ResolveAndTypecheck (Bpl.Program program, string bplFileName)
- {
- Contract.Requires(program != null);
- Contract.Requires(bplFileName != null);
- // ---------- Resolve ------------------------------------------------------------
-
- if (CommandLineOptions.Clo.NoResolve) { return PipelineOutcome.Done; }
-
- int errorCount = program.Resolve();
- if (errorCount != 0) {
- Console.WriteLine("{0} name resolution errors detected in {1}", errorCount, bplFileName);
- return PipelineOutcome.ResolutionError;
- }
-
- // ---------- Type check ------------------------------------------------------------
-
- if (CommandLineOptions.Clo.NoTypecheck) { return PipelineOutcome.Done; }
-
- errorCount = program.Typecheck();
- if (errorCount != 0) {
- Console.WriteLine("{0} type checking errors detected in {1}", errorCount, bplFileName);
- return PipelineOutcome.TypeCheckingError;
- }
-
- if (CommandLineOptions.Clo.PrintFile != null && CommandLineOptions.Clo.PrintDesugarings)
- {
- // if PrintDesugaring option is engaged, print the file here, after resolution and type checking
- PrintBplFile(CommandLineOptions.Clo.PrintFile, program, true);
- }
-
- return PipelineOutcome.ResolvedAndTypeChecked;
- }
-
- /// <summary>
- /// Given a resolved and type checked Boogie program, infers invariants for the program
- /// and then attempts to verify it. Returns:
- /// - Done if command line specified no verification
- /// - FatalError if a fatal error occurred, in which case an error has been printed to console
- /// - VerificationCompleted if inference and verification completed, in which the out
- /// parameters contain meaningful values
- /// </summary>
- static PipelineOutcome InferAndVerify (Bpl.Program program,
- out int errorCount, out int verified, out int inconclusives, out int timeOuts, out int outOfMemories)
- {
- Contract.Requires(program != null);
- Contract.Ensures(0 <= Contract.ValueAtReturn(out inconclusives) && 0 <= Contract.ValueAtReturn(out timeOuts));
-
- errorCount = verified = inconclusives = timeOuts = outOfMemories = 0;
-
- // ---------- Infer invariants --------------------------------------------------------
-
- // Abstract interpretation -> Always use (at least) intervals, if not specified otherwise (e.g. with the "/noinfer" switch)
- if (CommandLineOptions.Clo.UseAbstractInterpretation) {
- if (CommandLineOptions.Clo.Ai.J_Intervals || CommandLineOptions.Clo.Ai.J_Trivial) {
- Microsoft.Boogie.AbstractInterpretation.NativeAbstractInterpretation.RunAbstractInterpretation(program);
- } else {
- // use /infer:j as the default
- CommandLineOptions.Clo.Ai.J_Intervals = true;
- Microsoft.Boogie.AbstractInterpretation.NativeAbstractInterpretation.RunAbstractInterpretation(program);
- }
- }
-
- if (CommandLineOptions.Clo.LoopUnrollCount != -1) {
- program.UnrollLoops(CommandLineOptions.Clo.LoopUnrollCount, CommandLineOptions.Clo.SoundLoopUnrolling);
- }
-
- if (CommandLineOptions.Clo.PrintInstrumented) {
- program.Emit(new TokenTextWriter(Console.Out));
- }
-
- if (CommandLineOptions.Clo.ExpandLambdas) {
- LambdaHelper.ExpandLambdas(program);
- //PrintBplFile ("-", program, true);
- }
-
- // ---------- Verify ------------------------------------------------------------
-
- if (!CommandLineOptions.Clo.Verify) { return PipelineOutcome.Done; }
-
- #region Verify each implementation
-
-#if ROB_DEBUG
- string now = DateTime.Now.ToString().Replace(' ','-').Replace('/','-').Replace(':','-');
- System.IO.StreamWriter w = new System.IO.StreamWriter(@"\temp\batch_"+now+".bpl");
- program.Emit(new TokenTextWriter(w));
- w.Close();
-#endif
-
- ConditionGeneration vcgen = null;
- try
- {
- vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend);
- }
- catch (ProverException e)
- {
- ErrorWriteLine("Fatal Error: ProverException: {0}", e);
- return PipelineOutcome.FatalError;
- }
-
- var decls = program.TopLevelDeclarations.ToArray();
- foreach (var decl in decls )
- {
- Contract.Assert(decl != null);
- Implementation impl = decl as Implementation;
- if (impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification)
- {
- List<Counterexample>/*?*/ errors;
-
- DateTime start = new DateTime(); // to please compiler's definite assignment rules
- if (CommandLineOptions.Clo.Trace || CommandLineOptions.Clo.TraceProofObligations || CommandLineOptions.Clo.XmlSink != null)
- {
- start = DateTime.Now;
- if (CommandLineOptions.Clo.Trace || CommandLineOptions.Clo.TraceProofObligations)
- {
- Console.WriteLine();
- Console.WriteLine("Verifying {0} ...", impl.Name);
- }
- if (CommandLineOptions.Clo.XmlSink != null)
- {
- CommandLineOptions.Clo.XmlSink.WriteStartMethod(impl.Name, start);
- }
- }
-
- ConditionGeneration.Outcome outcome;
- int prevAssertionCount = vcgen.CumulativeAssertionCount;
- try
- {
- outcome = vcgen.VerifyImplementation(impl, out errors);
- }
- catch (VCGenException e)
- {
- ReportBplError(impl.tok, String.Format("Error BP5010: {0} Encountered in implementation {1}.", e.Message, impl.Name), true);
- errors = null;
- outcome = VCGen.Outcome.Inconclusive;
- }
- catch (UnexpectedProverOutputException upo)
- {
- AdvisoryWriteLine("Advisory: {0} SKIPPED because of internal error: unexpected prover output: {1}", impl.Name, upo.Message);
- errors = null;
- outcome = VCGen.Outcome.Inconclusive;
- }
-
- string timeIndication = "";
- DateTime end = DateTime.Now;
- TimeSpan elapsed = end - start;
- if (CommandLineOptions.Clo.Trace) {
- int poCount = vcgen.CumulativeAssertionCount - prevAssertionCount;
- timeIndication = string.Format(" [{0:F3} s, {1} proof obligation{2}] ", elapsed.TotalSeconds, poCount, poCount == 1 ? "" : "s");
- } else if (CommandLineOptions.Clo.TraceProofObligations) {
- int poCount = vcgen.CumulativeAssertionCount - prevAssertionCount;
- timeIndication = string.Format(" [{0} proof obligation{1}] ", poCount, poCount == 1 ? "" : "s");
- }
-
- switch (outcome)
- {
- default:
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected outcome
- case VCGen.Outcome.Correct:
- Inform(String.Format("{0}verified", timeIndication));
- verified++;
- break;
- case VCGen.Outcome.TimedOut:
- timeOuts++;
- Inform(String.Format("{0}timed out", timeIndication));
- break;
- case VCGen.Outcome.OutOfMemory:
- outOfMemories++;
- Inform(String.Format("{0}out of memory", timeIndication));
- break;
- case VCGen.Outcome.Inconclusive:
- inconclusives++;
- Inform(String.Format("{0}inconclusive", timeIndication));
- break;
- case VCGen.Outcome.Errors:
- Contract.Assert(errors != null); // guaranteed by postcondition of VerifyImplementation
- // BP1xxx: Parsing errors
- // BP2xxx: Name resolution errors
- // BP3xxx: Typechecking errors
- // BP4xxx: Abstract interpretation errors (Is there such a thing?)
- // BP5xxx: Verification errors
-
- errors.Sort(new CounterexampleComparer());
- foreach (Counterexample error in errors)
- {
- if (error is CallCounterexample)
- {
- CallCounterexample err = (CallCounterexample)error;
- ReportBplError(err.FailingCall.tok, (err.FailingCall.ErrorData as string) ?? "Error BP5002: A precondition for this call might not hold.", true);
- ReportBplError(err.FailingRequires.tok, (err.FailingRequires.ErrorData as string) ?? "Related location: This is the precondition that might not hold.", false);
- if (CommandLineOptions.Clo.XmlSink != null)
- {
- CommandLineOptions.Clo.XmlSink.WriteError("precondition violation", err.FailingCall.tok, err.FailingRequires.tok, error.Trace);
- }
- }
- else if (error is ReturnCounterexample)
- {
- ReturnCounterexample err = (ReturnCounterexample)error;
- ReportBplError(err.FailingReturn.tok, "Error BP5003: A postcondition might not hold on this return path.", true);
- ReportBplError(err.FailingEnsures.tok, (err.FailingEnsures.ErrorData as string) ?? "Related location: This is the postcondition that might not hold.", false);
- ReportAllBplErrors(err.FailingEnsures.Attributes);
- if (CommandLineOptions.Clo.XmlSink != null)
- {
- CommandLineOptions.Clo.XmlSink.WriteError("postcondition violation", err.FailingReturn.tok, err.FailingEnsures.tok, error.Trace);
- }
- }
- else // error is AssertCounterexample
- {
- AssertCounterexample err = (AssertCounterexample)error;
- if (err.FailingAssert is LoopInitAssertCmd)
- {
- ReportBplError(err.FailingAssert.tok, "Error BP5004: This loop invariant might not hold on entry.", true);
- if (CommandLineOptions.Clo.XmlSink != null)
- {
- CommandLineOptions.Clo.XmlSink.WriteError("loop invariant entry violation", err.FailingAssert.tok, null, error.Trace);
- }
- }
- else if (err.FailingAssert is LoopInvMaintainedAssertCmd)
- {
- // this assertion is a loop invariant which is not maintained
- ReportBplError(err.FailingAssert.tok, "Error BP5005: This loop invariant might not be maintained by the loop.", true);
- if (CommandLineOptions.Clo.XmlSink != null)
- {
- CommandLineOptions.Clo.XmlSink.WriteError("loop invariant maintenance violation", err.FailingAssert.tok, null, error.Trace);
- }
- }
- else
- {
- string msg = err.FailingAssert.ErrorData as string;
- if (msg == null)
- {
- msg = "Error BP5001: This assertion might not hold.";
- }
- ReportBplError(err.FailingAssert.tok, msg, true);
- var attr = err.FailingAssert.Attributes;
- ReportAllBplErrors(attr);
- if (CommandLineOptions.Clo.XmlSink != null)
- {
- CommandLineOptions.Clo.XmlSink.WriteError("assertion violation", err.FailingAssert.tok, null, error.Trace);
- }
- }
- }
- if (CommandLineOptions.Clo.EnhancedErrorMessages == 1)
- {
- foreach (string info in error.relatedInformation)
- {
- Contract.Assert(info != null);
- Console.WriteLine(" " + info);
- }
- }
- if (CommandLineOptions.Clo.ErrorTrace > 0)
- {
- Console.WriteLine("Execution trace:");
- foreach (Block b in error.Trace)
- {
- Contract.Assert(b != null);
- if (b.tok == null)
- {
- Console.WriteLine(" <intermediate block>");
- }
- else
- {
- // for ErrorTrace == 1 restrict the output;
- // do not print tokens with -17:-4 as their location because they have been
- // introduced in the translation and do not give any useful feedback to the user
- if (!(CommandLineOptions.Clo.ErrorTrace == 1 && b.tok.line == -17 && b.tok.col == -4))
- {
- Console.WriteLine(" {0}({1},{2}): {3}", b.tok.filename, b.tok.line, b.tok.col, b.Label);
- }
- }
- }
- }
- if (CommandLineOptions.Clo.ModelViewFile != null)
- {
- error.PrintModel();
- }
- errorCount++;
- }
-
- Inform(String.Format("{0}error{1}", timeIndication, errors.Count == 1 ? "" : "s"));
- break;
- }
-
- if (CommandLineOptions.Clo.XmlSink != null)
- {
- CommandLineOptions.Clo.XmlSink.WriteEndMethod(outcome.ToString().ToLowerInvariant(), end, elapsed);
- }
- if (outcome == VCGen.Outcome.Errors || CommandLineOptions.Clo.Trace)
- {
- Console.Out.Flush();
- }
- }
- }
- vcgen.Close();
- cce.NonNull(CommandLineOptions.Clo.TheProverFactory).Close();
-
- #endregion
-
- return PipelineOutcome.VerificationCompleted;
- }
-
- private static void ReportAllBplErrors(QKeyValue attr) {
- while (attr != null) {
- if (attr.Key == "msg" && attr.Params.Count == 1) {
- var str = attr.Params[0] as string;
- if (str != null) {
- ReportBplError(attr.tok, "Error: "+str, false);
- }
- }
- attr = attr.Next;
- }
- }
-
- }
-}
diff --git a/Source/DafnyDriver/DafnyDriver.csproj b/Source/DafnyDriver/DafnyDriver.csproj
deleted file mode 100644
index 6f32302d..00000000
--- a/Source/DafnyDriver/DafnyDriver.csproj
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{63400D1F-05B2-453E-9592-1EAB74B2C9CC}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Dafny</RootNamespace>
- <AssemblyName>Dafny</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
- <SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\InterimKey.snk</AssemblyOriginatorKeyFile>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>3.5</OldToolsVersion>
- <UpgradeBackupLocation />
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <TargetFrameworkProfile />
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>..\..\Binaries\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
- <CodeContractsContainerAnalysis>False</CodeContractsContainerAnalysis>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly>
- </CodeContractsCustomRewriterAssembly>
- <CodeContractsCustomRewriterClass>
- </CodeContractsCustomRewriterClass>
- <CodeContractsLibPaths>
- </CodeContractsLibPaths>
- <CodeContractsExtraRewriteOptions>
- </CodeContractsExtraRewriteOptions>
- <CodeContractsExtraAnalysisOptions>
- </CodeContractsExtraAnalysisOptions>
- <CodeContractsBaseLineFile>
- </CodeContractsBaseLineFile>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|AnyCPU'">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>..\..\Binaries\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
- <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
- <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
- <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
- <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
- <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
- <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
- <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
- <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
- <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
- <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
- <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
- <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
- <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
- <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
- <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
- <CodeContractsCustomRewriterAssembly />
- <CodeContractsCustomRewriterClass />
- <CodeContractsLibPaths />
- <CodeContractsExtraRewriteOptions />
- <CodeContractsExtraAnalysisOptions />
- <CodeContractsBaseLineFile />
- <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
- <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
- <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="AbsInt">
- <HintPath>..\..\Binaries\AbsInt.dll</HintPath>
- </Reference>
- <Reference Include="Core">
- <HintPath>..\..\Binaries\Core.dll</HintPath>
- </Reference>
- <Reference Include="ParserHelper, Version=2.2.30705.1126, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\Binaries\ParserHelper.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- <Reference Include="VCGeneration">
- <HintPath>..\..\Binaries\VCGeneration.dll</HintPath>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="DafnyDriver.cs" />
- <Compile Include="..\version.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\Dafny\DafnyPipeline.csproj">
- <Project>{FE44674A-1633-4917-99F4-57635E6FA740}</Project>
- <Name>DafnyPipeline</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/Source/DafnyDriver/app.config b/Source/DafnyDriver/app.config
deleted file mode 100644
index cb2586be..00000000
--- a/Source/DafnyDriver/app.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<configuration>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
diff --git a/Test/Makefile b/Test/Makefile
index 3fd662c4..29e8c844 100644
--- a/Test/Makefile
+++ b/Test/Makefile
@@ -3,12 +3,10 @@ LONG = $(shell awk '{ if (tolower($$2) ~ /^long$$/) print $$1 }' $(TESTS_FILE))
NORMAL = $(shell awk '{ if (tolower($$2) ~ /^use$$/) print $$1 }' $(TESTS_FILE))
TESTS = $(NORMAL)
-all: boogie dafny
+all: boogie
boogie: $(addprefix run-, $(TESTS))
-dafny: $(addprefix rundfy-, $(TESTS))
-
show:
@echo $(TESTS)
diff --git a/Test/alltests.txt b/Test/alltests.txt
index 51334da8..ebe396e9 100644
--- a/Test/alltests.txt
+++ b/Test/alltests.txt
@@ -27,11 +27,4 @@ livevars Use STORM benchmarks for testing correctness of live variabl
stratifiedinline Use Stratified inlining benchmarks
extractloops Use Extract loops benchmarks
havoc0 Use HAVOC-generated bpl files
-dafny0 Dafny Dafny functionality tests
-dafny1 Dafny Various Dafny examples
-dafny2 Dafny More Dafny examples
-VSI-Benchmarks Dafny Solutions to Verified Software Initiative verification challenges
-vacid0 Dafny Dafny attempts to VACID Edition 0 benchmarks
-vstte2012 Dafny Dafny solutions for the VSTTE 2012 program verification competition
-VSComp2010 Dafny Dafny solutions to VSComp (verified software competition) problems
AbsHoudini Postponed Test for abstract houdini
diff --git a/Util/BoogieDafnyBuildandTest.cmd b/Util/BoogieBuildAndTest.cmd
index 97bf32ce..08d5baeb 100644
--- a/Util/BoogieDafnyBuildandTest.cmd
+++ b/Util/BoogieBuildAndTest.cmd
@@ -12,14 +12,6 @@ if errorlevel 1 goto fail
devenv ..\source\Boogie.sln /Build
@echo off
if errorlevel 1 goto fail
-@echo on
-devenv ..\Source\Dafny.sln /Clean
-@echo off
-if errorlevel 1 goto fail
-@echo on
-devenv ..\Source\Dafny.sln /Build
-@echo off
-if errorlevel 1 goto fail
goto reg
:Reg
diff --git a/Util/Emacs/chalice-mode.el b/Util/Emacs/chalice-mode.el
deleted file mode 100644
index c8cef685..00000000
--- a/Util/Emacs/chalice-mode.el
+++ /dev/null
@@ -1,118 +0,0 @@
-;; chalice-mode.el - GNU Emacs mode for Chalice
-;; Adapted by Rustan Leino from Jean-Christophe FILLIATRE's GNU Emancs mode for Why
-
-(defvar chalice-mode-hook nil)
-
-(defvar chalice-mode-map nil
- "Keymap for Chalice major mode")
-
-(if chalice-mode-map nil
- (setq chalice-mode-map (make-keymap))
- (define-key chalice-mode-map "\C-c\C-c" 'chalice-run-boogie)
- (define-key chalice-mode-map [(control return)] 'font-lock-fontify-buffer))
-
-(setq auto-mode-alist
- (append
- '(("\\.chalice" . chalice-mode))
- auto-mode-alist))
-
-;; font-lock
-
-(defun chalice-regexp-opt (l)
- (concat "\\<" (concat (regexp-opt l t) "\\>")))
-
-(defconst chalice-font-lock-keywords-1
- (list
- ; comments have the form /* ... */
- '("/\\*\\([^*]\\|\\*[^/]\\)*\\*/" . font-lock-comment-face)
- ; or // ...
- '("//\\([^
-]\\)*" . font-lock-comment-face)
-
- `(,(chalice-regexp-opt '(
- "class" "ghost" "var" "const" "external" "function" "method"
- "predicate" "returns" "requires" "ensures" "lockchange"
- "invariant" "channel" "condition" "where"
- "refines" "transforms"
- )) . font-lock-builtin-face)
- `(,(chalice-regexp-opt '(
- "above" "acc" "acquire" "and" "assert" "assigned" "assume"
- "below" "between" "call" "credit"
- "downgrade" "else" "eval" "exists" "fold" "forall" "fork" "free" "havoc" "holds"
- "spec" "replaces" "by"
- "if" "in" "ite" "join" "lock" "lockbottom" "waitlevel" "module" "new" "nil"
- "old" "rd" "receive" "release" "reorder" "result" "send" "share"
- "this" "unfold" "unfolding" "unshare" "while"
- "false" "true" "null")) . font-lock-keyword-face)
- `(,(chalice-regexp-opt '("bool" "int" "string" "seq" "token")) . font-lock-type-face)
- )
- "Minimal highlighting for Chalice mode")
-
-(defvar chalice-font-lock-keywords chalice-font-lock-keywords-1
- "Default highlighting for Chalice mode")
-
-;; syntax
-
-(defvar chalice-mode-syntax-table nil
- "Syntax table for chalice-mode")
-
-(defun chalice-create-syntax-table ()
- (if chalice-mode-syntax-table
- ()
- (setq chalice-mode-syntax-table (make-syntax-table))
- (set-syntax-table chalice-mode-syntax-table)
- (modify-syntax-entry ?' "w" chalice-mode-syntax-table)
- (modify-syntax-entry ?_ "w" chalice-mode-syntax-table)))
-
-;; menu
-
-(require 'easymenu)
-
-(defun chalice-menu ()
- (easy-menu-define
- chalice-mode-menu (list chalice-mode-map)
- "Chalice Mode Menu."
- '("Chalice"
- ["Run Boogie" chalice-run-boogie t]
- "---"
- ["Recolor buffer" font-lock-fontify-buffer t]
- "---"
- ))
- (easy-menu-add chalice-mode-menu))
-
-;; commands
-
-(defun chalice-command-line (file)
- (concat "boogie " file))
-
-(defun chalice-run-boogie ()
- "run Boogie to check the Chalice program"
- (interactive)
- (let ((f (buffer-name)))
- (compile (chalice-command-line f))))
-
-;; setting the mode
-
-(defun chalice-mode ()
- "Major mode for editing Chalice programs.
-
-\\{chalice-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (chalice-create-syntax-table)
- ; hilight
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(chalice-font-lock-keywords))
- ; indentation
- ; (make-local-variable 'indent-line-function)
- ; (setq indent-line-function 'chalice-indent-line)
- ; menu
- ; providing the mode
- (setq major-mode 'chalice-mode)
- (setq mode-name "Chalice")
- (use-local-map chalice-mode-map)
- (font-lock-mode 1)
- (chalice-menu)
- (run-hooks 'chalice-mode-hook))
-
-(provide 'chalice-mode)
diff --git a/Util/Emacs/dafny-mode.el b/Util/Emacs/dafny-mode.el
deleted file mode 100644
index 1ba6186b..00000000
--- a/Util/Emacs/dafny-mode.el
+++ /dev/null
@@ -1,116 +0,0 @@
-;; dafny-mode.el - GNU Emacs mode for Dafny
-;; Adapted by Rustan Leino from Jean-Christophe FILLIATRE's GNU Emancs mode for Why
-
-(defvar dafny-mode-hook nil)
-
-(defvar dafny-mode-map nil
- "Keymap for Dafny major mode")
-
-(if dafny-mode-map nil
- (setq dafny-mode-map (make-keymap))
- (define-key dafny-mode-map "\C-c\C-c" 'dafny-run-verifier)
- (define-key dafny-mode-map [(control return)] 'font-lock-fontify-buffer))
-
-(setq auto-mode-alist
- (append
- '(("\\.dfy" . dafny-mode))
- auto-mode-alist))
-
-;; font-lock
-
-(defun dafny-regexp-opt (l)
- (concat "\\<" (concat (regexp-opt l t) "\\>")))
-
-(defconst dafny-font-lock-keywords-1
- (list
- ; comments have the form /* ... */
- '("/\\*\\([^*]\\|\\*[^/]\\)*\\*/" . font-lock-comment-face)
- ; or // ...
- '("//\\([^
-]\\)*" . font-lock-comment-face)
-
- `(,(dafny-regexp-opt '(
- "class" "datatype" "codatatype" "type" "function" "predicate" "copredicate"
- "iterator"
- "ghost" "var" "method" "constructor"
- "module" "import" "default" "as" "opened" "static" "refines"
- "returns" "yields" "requires" "ensures" "modifies" "reads" "free"
- "invariant" "decreases"
- )) . font-lock-builtin-face)
- `(,(dafny-regexp-opt '(
- "assert" "assume" "break" "choose" "then" "else" "if" "label" "return" "yield"
- "while" "print" "where"
- "old" "forall" "exists" "new" "parallel" "calc" "in" "this" "fresh"
- "match" "case" "false" "true" "null")) . font-lock-keyword-face)
- `(,(dafny-regexp-opt '("array" "array2" "array3" "bool" "multiset" "map" "nat" "int" "object" "set" "seq")) . font-lock-type-face)
- )
- "Minimal highlighting for Dafny mode")
-
-(defvar dafny-font-lock-keywords dafny-font-lock-keywords-1
- "Default highlighting for Dafny mode")
-
-;; syntax
-
-(defvar dafny-mode-syntax-table nil
- "Syntax table for dafny-mode")
-
-(defun dafny-create-syntax-table ()
- (if dafny-mode-syntax-table
- ()
- (setq dafny-mode-syntax-table (make-syntax-table))
- (set-syntax-table dafny-mode-syntax-table)
- (modify-syntax-entry ?' "w" dafny-mode-syntax-table)
- (modify-syntax-entry ?_ "w" dafny-mode-syntax-table)))
-
-;; menu
-
-(require 'easymenu)
-
-(defun dafny-menu ()
- (easy-menu-define
- dafny-mode-menu (list dafny-mode-map)
- "Dafny Mode Menu."
- '("Dafny"
- ["Run Dafny" dafny-run-verifier t]
- "---"
- ["Recolor buffer" font-lock-fontify-buffer t]
- "---"
- ))
- (easy-menu-add dafny-mode-menu))
-
-;; commands
-
-(defun dafny-command-line (file)
- (concat "boogie " file))
-
-(defun dafny-run-verifier ()
- "run Dafny verifier"
- (interactive)
- (let ((f (buffer-name)))
- (compile (dafny-command-line f))))
-
-;; setting the mode
-
-(defun dafny-mode ()
- "Major mode for editing Dafny programs.
-
-\\{dafny-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (dafny-create-syntax-table)
- ; hilight
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(dafny-font-lock-keywords))
- ; indentation
- ; (make-local-variable 'indent-line-function)
- ; (setq indent-line-function 'dafny-indent-line)
- ; menu
- ; providing the mode
- (setq major-mode 'dafny-mode)
- (setq mode-name "Dafny")
- (use-local-map dafny-mode-map)
- (font-lock-mode 1)
- (dafny-menu)
- (run-hooks 'dafny-mode-hook))
-
-(provide 'dafny-mode)
diff --git a/Util/Emacs/jennisys-mode.el b/Util/Emacs/jennisys-mode.el
deleted file mode 100644
index d8f20a31..00000000
--- a/Util/Emacs/jennisys-mode.el
+++ /dev/null
@@ -1,113 +0,0 @@
-;; jennisys-mode.el - GNU Emacs mode for Jennisys
-;; Adapted by Rustan Leino from Jean-Christophe FILLIATRE's GNU Emancs mode for Why
-
-(defvar jennisys-mode-hook nil)
-
-(defvar jennisys-mode-map nil
- "Keymap for Jennisys major mode")
-
-(if jennisys-mode-map nil
- (setq jennisys-mode-map (make-keymap))
- (define-key jennisys-mode-map "\C-c\C-c" 'jennisys-run-boogie)
- (define-key jennisys-mode-map [(control return)] 'font-lock-fontify-buffer))
-
-(setq auto-mode-alist
- (append
- '(("\\.jen" . jennisys-mode))
- auto-mode-alist))
-
-;; font-lock
-
-(defun jennisys-regexp-opt (l)
- (concat "\\<" (concat (regexp-opt l t) "\\>")))
-
-(defconst jennisys-font-lock-keywords-1
- (list
- ; comments have the form /* ... */
- '("/\\*\\([^*]\\|\\*[^/]\\)*\\*/" . font-lock-comment-face)
- ; or // ...
- '("//\\([^
-]\\)*" . font-lock-comment-face)
-
- `(,(jennisys-regexp-opt '(
- "interface" "datamodel" "code"
- "var" "constructor" "method"
- "frame" "invariant" "returns" "requires" "ensures"
- )) . font-lock-builtin-face)
- `(,(jennisys-regexp-opt '(
- "if" "then" "else"
- "forall" "exists"
- "this" "in"
- "false" "true" "null")) . font-lock-keyword-face)
- `(,(jennisys-regexp-opt '("array" "bool" "int" "set" "seq")) . font-lock-type-face)
- )
- "Minimal highlighting for Jennisys mode")
-
-(defvar jennisys-font-lock-keywords jennisys-font-lock-keywords-1
- "Default highlighting for Jennisys mode")
-
-;; syntax
-
-(defvar jennisys-mode-syntax-table nil
- "Syntax table for jennisys-mode")
-
-(defun jennisys-create-syntax-table ()
- (if jennisys-mode-syntax-table
- ()
- (setq jennisys-mode-syntax-table (make-syntax-table))
- (set-syntax-table jennisys-mode-syntax-table)
- (modify-syntax-entry ?' "w" jennisys-mode-syntax-table)
- (modify-syntax-entry ?_ "w" jennisys-mode-syntax-table)))
-
-;; menu
-
-(require 'easymenu)
-
-(defun jennisys-menu ()
- (easy-menu-define
- jennisys-mode-menu (list jennisys-mode-map)
- "Jennisys Mode Menu."
- '("Jennisys"
- ["Run Boogie" jennisys-run-boogie t]
- "---"
- ["Recolor buffer" font-lock-fontify-buffer t]
- "---"
- ))
- (easy-menu-add jennisys-mode-menu))
-
-;; commands
-
-(defun jennisys-command-line (file)
- (concat "boogie " file))
-
-(defun jennisys-run-boogie ()
- "run Boogie to check the Jennisys program"
- (interactive)
- (let ((f (buffer-name)))
- (compile (jennisys-command-line f))))
-
-;; setting the mode
-
-(defun jennisys-mode ()
- "Major mode for editing Jennisys programs.
-
-\\{jennisys-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (jennisys-create-syntax-table)
- ; hilight
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(jennisys-font-lock-keywords))
- ; indentation
- ; (make-local-variable 'indent-line-function)
- ; (setq indent-line-function 'jennisys-indent-line)
- ; menu
- ; providing the mode
- (setq major-mode 'jennisys-mode)
- (setq mode-name "Jennisys")
- (use-local-map jennisys-mode-map)
- (font-lock-mode 1)
- (jennisys-menu)
- (run-hooks 'jennisys-mode-hook))
-
-(provide 'jennisys-mode)
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService.sln b/Util/VS2010/Chalice/ChaliceLanguageService.sln
deleted file mode 100644
index dfda1244..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaliceLanguageService", "ChaliceLanguageService\ChaliceLanguageService.csproj", "{66E611EE-84D8-4EB9-9A33-164A53E00553}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/ChaliceLanguageService.csproj b/Util/VS2010/Chalice/ChaliceLanguageService/ChaliceLanguageService.csproj
deleted file mode 100644
index 44a36137..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/ChaliceLanguageService.csproj
+++ /dev/null
@@ -1,179 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Demo.ChaliceLanguageService</RootNamespace>
- <AssemblyName>ChaliceLanguageService</AssemblyName>
- <SignAssembly>True</SignAssembly>
- <AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <ProjectGuid>{66E611EE-84D8-4EB9-9A33-164A53E00553}</ProjectGuid>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>4.0</OldToolsVersion>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- <TargetFrameworkProfile />
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <RunCodeAnalysis>true</RunCodeAnalysis>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Irony, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ca48ace7223ead47, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>Resources\Irony.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.OLE.Interop" />
- <Reference Include="Microsoft.VisualStudio.Package.LanguageService.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Package.LanguageService.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.10.0">
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Shell.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Shell.Immutable.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Interop" />
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <SpecificVersion>False</SpecificVersion>
- <EmbedInteropTypes>True</EmbedInteropTypes>
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Shell.Interop.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
- <Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
- <Reference Include="Microsoft.VisualStudio.TextManager.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\..\Program Files\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.TextManager.Interop.8.0.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Data" />
- <Reference Include="System.Design" />
- <Reference Include="System.Drawing" />
- <Reference Include="System.Windows.Forms" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Configuration.cs" />
- <Compile Include="Grammar.cs" />
- <Compile Include="Guids.cs" />
- <Compile Include="Integration\AuthoringScope.cs" />
- <Compile Include="Integration\Configuration.cs" />
- <Compile Include="Integration\Declaration.cs" />
- <Compile Include="Integration\Declarations.cs" />
- <Compile Include="Integration\IASTResolver.cs" />
- <Compile Include="Integration\IronyViewFilter.cs" />
- <Compile Include="Integration\IronyLanguageService.cs" />
- <Compile Include="Integration\LineScanner.cs" />
- <Compile Include="Integration\Method.cs" />
- <Compile Include="Integration\Methods.cs" />
- <Compile Include="Integration\Package.cs" />
- <Compile Include="Integration\Resolver.cs" />
- <Compile Include="Integration\Source.cs" />
- <Compile Include="Resources.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>Resources.resx</DependentUpon>
- </Compile>
- <Compile Include="GlobalSuppressions.cs" />
- <Compile Include="IronyLanguageServicePackage.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Resources.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Resources.Designer.cs</LastGenOutput>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- <EmbeddedResource Include="VSPackage.resx">
- <MergeWithCTO>true</MergeWithCTO>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- </ItemGroup>
- <ItemGroup>
- <Content Include="Resources\Irony.dll" />
- <None Include="source.extension.vsixmanifest" />
- </ItemGroup>
- <ItemGroup>
- <None Include="Key.snk" />
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.VisualBasic.PowerPacks.10.0">
- <Visible>False</Visible>
- <ProductName>Microsoft Visual Basic PowerPacks 10.0</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
- <PropertyGroup>
- <!--
- To specify a different registry root to register your package, uncomment the TargetRegistryRoot
- tag and specify a registry root in it.
- <TargetRegistryRoot></TargetRegistryRoot>
- -->
- <RegisterOutputPackage>true</RegisterOutputPackage>
- <RegisterWithCodebase>true</RegisterWithCodebase>
- </PropertyGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\VSSDK\Microsoft.VsSDK.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Configuration.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Configuration.cs
deleted file mode 100644
index e5b10f00..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Configuration.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Microsoft.VisualStudio.Package;
-using Microsoft.VisualStudio.TextManager.Interop;
-
-namespace Demo
-{
- public static partial class Configuration
- {
- public const string Name = "Chalice";
- public const string FormatList = "Chalice File (*.chalice)\n*.chalice";
-
- static Configuration()
- {
- // default colors - currently, these need to be declared
- CreateColor("Keyword", COLORINDEX.CI_BLUE, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Comment", COLORINDEX.CI_DARKGREEN, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Identifier", COLORINDEX.CI_SYSPLAINTEXT_FG, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("String", COLORINDEX.CI_MAROON, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Number", COLORINDEX.CI_MAROON, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Text", COLORINDEX.CI_SYSPLAINTEXT_FG, COLORINDEX.CI_USERTEXT_BK);
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/GlobalSuppressions.cs b/Util/VS2010/Chalice/ChaliceLanguageService/GlobalSuppressions.cs
deleted file mode 100644
index f0857cbb..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/GlobalSuppressions.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// This file is used by Code Analysis to maintain SuppressMessage
-// attributes that are applied to this project. Project-level
-// suppressions either have no target or are given a specific target
-// and scoped to a namespace, type, member, etc.
-//
-// To add a suppression to this file, right-click the message in the
-// Error List, point to "Suppress Message(s)", and click "In Project
-// Suppression File". You do not need to add suppressions to this
-// file manually.
-
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Grammar.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Grammar.cs
deleted file mode 100644
index 8a05d7b2..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Grammar.cs
+++ /dev/null
@@ -1,399 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Irony.Parsing;
-
-namespace Demo
-{
- [Language("Chalice", "1.0", "Chalice Programming Language")]
- public class Grammar : Irony.Parsing.Grammar
- {
- public Grammar() {
- #region 1. Terminals
- NumberLiteral n = TerminalFactory.CreateCSharpNumber("number");
- StringLiteral s = new StringLiteral("String", "\"", StringFlags.AllowsAllEscapes);
- IdentifierTerminal ident = new IdentifierTerminal("Identifier");
-
- // Copy pasted directly from Parser.scala
- string[] reserved = new string[] {
- "class", "ghost", "var", "const", "method", "channel", "condition",
- "assert", "assume", "new", "this", "reorder",
- "between", "and", "above", "below", "share", "unshare", "acquire", "release", "downgrade",
- "lock", "fork", "join", "rd", "acc", "credit", "holds", "old", "assigned",
- "call", "if", "else", "while",
- "invariant", "lockchange",
- "returns", "requires", "ensures", "where",
- "int", "bool", "false", "true", "null", "string", "waitlevel", "lockbottom",
- "module", "external",
- "predicate", "function", "free", "send", "receive",
- "ite", "fold", "unfold", "unfolding", "in", "forall", "exists",
- "seq", "nil", "result", "eval", "token",
- "wait", "signal",
- "refines", "transforms", "replaces", "by", "spec"
- };
-
- string[] delimiters = new string[] {
- "(", ")", "{", "}", "[[", "]]",
- "<==>", "==>", "&&", "||",
- "==", "!=", "<", "<=", ">=", ">", "<<", "in", "!in",
- "+", "-", "*", "/", "%", "!", ".", "..",
- ";", ":", ":=", ",", "?", "|", "[", "]", "++", "::",
- "_"
- };
-
- this.MarkReservedWords(reserved);
-
- Terminal Comment = new CommentTerminal("Comment", "/*", "*/");
- NonGrammarTerminals.Add(Comment);
- Terminal LineComment = new CommentTerminal("LineComment", "//", "\n");
- NonGrammarTerminals.Add(LineComment);
-
- #endregion
-
- #region Disabled for a simpler grammar
- /*
- Terminal dot = ToTerm(".", "dot");
- Terminal less = ToTerm("<");
- Terminal greater = ToTerm(">");
- Terminal arrow = ToTerm("->");
- Terminal LBracket = ToTerm("[");
- Terminal RBracket = ToTerm("]");
- Terminal LParen = ToTerm("(");
- Terminal RParen = ToTerm(")");
- Terminal RCurly = ToTerm("}");
- Terminal LCurly = ToTerm("{");
- Terminal LMb = ToTerm("<[");
- Terminal RMb = ToTerm("]>");
- Terminal comma = ToTerm(",");
- Terminal semicolon = ToTerm(";");
- Terminal colon = ToTerm(":");
-
- #region 2. Non-terminals
- #region 2.1 Expressions
- NonTerminal expression = new NonTerminal("Expr");
- NonTerminal BinOp = new NonTerminal("BinOp");
- NonTerminal LUnOp = new NonTerminal("LUnOp");
- NonTerminal RUnOp = new NonTerminal("RUnOp");
-
- NonTerminal ArrayConstructor = new NonTerminal("ArrayConstructor");
- NonTerminal MObjectConstructor = new NonTerminal("MObjectConstructor");
- NonTerminal MObjectList = new NonTerminal("MObjectList");
- #endregion
-
- #region 2.2 QualifiedName
- //Expression List: expr1, expr2, expr3, ..
- NonTerminal expressionList = new NonTerminal("ExprList");
- NonTerminal identList = new NonTerminal("identList");
- //A name in form: a.b.c().d[1,2].e ....
- NonTerminal NewStmt = new NonTerminal("NewStmt");
- NonTerminal NewArrStmt = new NonTerminal("NewArrStmt");
- NonTerminal QualifiedName = new NonTerminal("QualifiedName");
- NonTerminal AccessQualName = new NonTerminal("AccessQualName");
- NonTerminal GenericsPostfix = new NonTerminal("GenericsPostfix");
- NonTerminal ArrayExpression = new NonTerminal("ArrayExpression");
- NonTerminal FunctionExpression = new NonTerminal("FunctionExpression");
- NonTerminal selectExpr = new NonTerminal("selectExpr");
- NonTerminal accessExpr = new NonTerminal("accessExpr");
- #endregion
-
- #region 2.3 Statement
- NonTerminal Condition = new NonTerminal("Condition");
-
- NonTerminal Statement = new NonTerminal("Statement");
- NonTerminal Statements = new NonTerminal("Statements");
-
- //Block
- NonTerminal blockStatement = new NonTerminal("CompoundStatement");
- #endregion
-
- #region 2.4 Program and Functions
- NonTerminal Prog = new NonTerminal("Prog");
- NonTerminal declaration = new NonTerminal("declaration");
- NonTerminal classDecl = new NonTerminal("class decl");
- NonTerminal memberDecl = new NonTerminal("member decl");
- NonTerminal fieldDecl = new NonTerminal("field declaration");
- NonTerminal idType = new NonTerminal("identifier type");
- NonTerminal typeDecl = new NonTerminal("type reference");
- NonTerminal methodDecl = new NonTerminal("method declaration");
- NonTerminal formalParameters = new NonTerminal("formals");
- NonTerminal methodSpec = new NonTerminal("method spec");
- NonTerminal formalsList = new NonTerminal("ParamaterListOpt");
- NonTerminal functionDecl = new NonTerminal("function declaration");
- NonTerminal predicateDecl = new NonTerminal("predicate declaration");
- NonTerminal invariantDecl = new NonTerminal("invariant declaration");
- NonTerminal Semi = new NonTerminal("semi");
- NonTerminal Rhs = new NonTerminal("right-hand side");
- NonTerminal FieldInit = new NonTerminal("field init");
- NonTerminal FieldInits = new NonTerminal("field inits");
- NonTerminal installBounds = new NonTerminal("installBounds");
- NonTerminal localVarStmt = new NonTerminal("localVarStmt");
- NonTerminal evalstate = new NonTerminal("evalstate");
- NonTerminal channelDecl = new NonTerminal("channel declaration");
- NonTerminal loopSpec = new NonTerminal("loop specification");
- NonTerminal rdPermArg = new NonTerminal("rdPermArg");
- #endregion
-
- #endregion
-
- #region 3. BNF rules
-
- Semi.Rule = semicolon;
-
- #region 3.1 Expressions
- selectExpr.Rule = (ToTerm("this") + ".").Q() + QualifiedName;
- accessExpr.Rule = (ToTerm("this") + ".").Q() + AccessQualName;
- evalstate.Rule =
- ident + ToTerm(".") +
- (ToTerm("acquire")
- | "release"
- | "fork" + FunctionExpression
- )
- ;
- rdPermArg.Rule = ToTerm("*") | expression;
-
- expression.Rule = ToTerm("true")
- | "false"
- | "null"
- | "waitlevel"
- | "lockbottom"
- | "this"
- | "result"
- | s
- | n
- | QualifiedName
- // The following is needed: to parse "A<B ..." either as comparison or as beginning of GenericsPostfix
- | QualifiedName + less + expression
- //| QualifiedName + less + QualifiedName + greater
- //| NewStmt
- | NewArrStmt
- | ArrayExpression
- | FunctionExpression
- | ArrayConstructor
- | MObjectConstructor
- | expression + BinOp + expression
- | LUnOp + expression
- | expression + RUnOp
- | LMb + declaration.Star() + RMb
- | LParen + expression + RParen
- | ToTerm("unfolding") + expression + "in" + expression
- | ToTerm("acc") + "(" + accessExpr + (("," + expression) | Empty) + ")"
- | ToTerm("old") + "(" + expression + ")"
- | ToTerm("eval") + "(" + evalstate + "," + expression + ")"
- | ToTerm("credit") + "(" + expression + "," + expression + ")"
- | ToTerm("credit") + "(" + expression + ")"
- | expression + PreferShiftHere() + "?" + expression + ":" + expression
- | ToTerm("rd") +
- (ToTerm("holds") + "(" + expression + ")"
- | "(" + accessExpr + rdPermArg.Q() + ")"
- )
-
- ;
- expressionList.Rule = MakePlusRule(expressionList, comma, expression);
- identList.Rule = MakePlusRule(identList, comma, ident);
- NewStmt.Rule = "new" + QualifiedName + GenericsPostfix.Q() + LParen + expressionList.Q() + RParen;
- NewArrStmt.Rule = "new" + QualifiedName + GenericsPostfix.Q() + LBracket + expressionList.Q() + RBracket;
- BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "%" | "^" | "&" | "|"
- | "&&" | "||" | "==" | "!=" | greater | less
- | ">=" | "<=" | "is"
- | "=" | "+=" | "-="
- | "."
- | "==>" | "<==>" | "<<"
- ;
-
- LUnOp.Rule = ToTerm("-") | "~" | "!";
- RUnOp.Rule = ToTerm("++") | "--";
-
- ArrayConstructor.Rule = LBracket + expressionList + RBracket;
- MObjectConstructor.Rule = LBracket + ident + arrow + expression + MObjectList.Star() + RBracket;
- MObjectList.Rule = comma + ident + arrow + expression;
- #endregion
-
- #region 3.2 QualifiedName
- ArrayExpression.Rule = QualifiedName + LBracket + expressionList + RBracket;
- FunctionExpression.Rule = QualifiedName + LParen + expressionList.Q() + RParen;
-
- QualifiedName.Rule = ident | QualifiedName + dot + ident;
- AccessQualName.Rule = ident | "*" | QualifiedName + dot + (ident | "*" | "[*]" + dot + "*" | "[*]" + dot + ident);
-
-
- GenericsPostfix.Rule = less + QualifiedName + greater;
-
- //ExprList.Rule = Expr.Plus(comma);
- #endregion
-
- #region 3.3 Statement
- Condition.Rule = LParen + expression + RParen;
- installBounds.Rule
- = "installBounds"
- //= ToTerm("between") + expressionList + "and" + expressionList
- //| "below" + expressionList
- //| "below" + expressionList + "above" + expressionList
- //| "above" + expressionList
- //| "above" + expressionList + "below" + expressionList
- ;
- FieldInit.Rule
- = ident + ":=" + expression
- ;
- FieldInits.Rule = MakeStarRule(FieldInits, ToTerm(","), FieldInit);
- Rhs.Rule
- = ToTerm("new") + ident
- | ToTerm("new") + ident + "{" + FieldInits + "}"
- | ToTerm("new") + ident + installBounds
- | ToTerm("new") + ident + "{" + FieldInits + "}" + installBounds
- | expression
- ;
- localVarStmt.Rule
- = idType + ":=" + Rhs + Semi
- | idType + Semi
- ;
- loopSpec.Rule
- = ToTerm("invariant") + expression + Semi
- | "lockchange" + expressionList + Semi
- ;
-
-
-
- Statement.Rule = Semi
- | "if" + Condition + Statement
- | "if" + Condition + Statement + PreferShiftHere() + "else" + Statement
- | "while" + Condition + loopSpec.Star() + Statement
- | "for" + LParen + expression.Q() + Semi + expression.Q() + Semi + expression.Q() + RParen + Statement
- | "foreach" + LParen + ident + "in" + expression + RParen + Statement
- | blockStatement
- | expression + Semi
- | "break" + Semi
- | "continue" + Semi
- | "return" + expression + Semi
- | QualifiedName + ":=" + Rhs
-
- | "var" + localVarStmt
- | "const" + localVarStmt
-
- | "call" + identList + ":=" + FunctionExpression + Semi
- | "call" + FunctionExpression + Semi
- | "assert" + expression + Semi
- | "assume" + expression + Semi
- | "unshare" + expression + Semi
- | "lock" + Condition + Statement
- | "[[" + Statements + "]]"
- | "acquire" + expression + Semi
- | "release" + expression + Semi
- | "downgrade" + expression + Semi
- | "free" + expression + Semi
- | "fold" + expression + Semi
- | "unfold" + expression + Semi
- | "reorder" + expression + installBounds + Semi
- | "reorder" + expression + Semi
- | "share" + expression + installBounds + Semi
- | "share" + expression + Semi
- | "fork" + identList + ":=" + FunctionExpression + Semi
- | "fork" + FunctionExpression + Semi
- | "join" + identList + ":=" + expression + Semi
- | "join" + expression + Semi
- | "send" + expression + Semi
- | "receive" + identList + ":=" + expression + Semi
- | "receive" + expression + Semi
-
- ;
- Statements.Rule = MakeStarRule(Statements, null, Statement);
- blockStatement.Rule = LCurly + Statements + RCurly;
-
-
- #endregion
-
- #region 3.4 Prog
- Prog.Rule = declaration.Star() + Eof;
- idType.Rule
- = ident + ":" + typeDecl
- | ident
- ;
-
- typeDecl.Rule
- = (ToTerm("int") | "bool" | ident | "seq") + (("<" + MakePlusRule(typeDecl, ToTerm(","), typeDecl) + ">") | Empty)
- | ToTerm("token") + "<" + (typeDecl + ".") + ident + ">"
- ;
-
- fieldDecl.Rule
- = ToTerm("var") + idType + Semi
- | ToTerm("ghost") + "var" + idType + Semi
- ;
-
- methodSpec.Rule = (ToTerm("requires") | "ensures" | "lockchange") + expression + Semi;
-
- formalsList.Rule = MakeStarRule(formalsList, comma, idType);
- formalParameters.Rule = LParen + formalsList + RParen;
- methodDecl.Rule = "method" + ident + formalParameters
- + (("returns" + formalParameters) | Empty)
- + methodSpec.Star()
- + blockStatement;
- functionDecl.Rule
- = ToTerm("function") + ident + formalParameters + ":" + typeDecl + methodSpec.Star() + "{" + expression + "}";
- predicateDecl.Rule
- = ToTerm("predicate") + ident + "{" + expression + "}";
- invariantDecl.Rule
- = ToTerm("invariant") + expression + Semi;
-
- memberDecl.Rule
- = fieldDecl
- | invariantDecl
- | methodDecl
- //| conditionDecl
- | predicateDecl
- | functionDecl
- ;
- classDecl.Rule
- = (ToTerm("external") | Empty) + "class" + ident + ("module" + ident | Empty) + "{" + memberDecl.Star() + "}";
- channelDecl.Rule
- = ToTerm("channel") + ident + formalParameters + "where" + expression + Semi
- | ToTerm("channel") + ident + formalParameters + Semi;
- declaration.Rule = classDecl | channelDecl
- ;
-
- #endregion
- #endregion
-
- #region 4. Set starting symbol
- this.Root = Prog; // Set grammar root
- #endregion
-
-
- #region 5. Operators precedence
- RegisterOperators(1, "=", "+=", "-=");
- RegisterOperators(2, "+", "-");
- RegisterOperators(3, "*", "/", "%");
- RegisterOperators(4, Associativity.Right, "^");
- RegisterOperators(5, "|", "||");
- RegisterOperators(6, "&", "&&");
- RegisterOperators(7, "==", "!=", ">", "<", ">=", "<=", "<<");
- RegisterOperators(8, "is");
- RegisterOperators(9, "~", "!", "++", "--");
- RegisterOperators(10, "==>", "<==>");
- RegisterOperators(11, ".");
-
- //RegisterOperators(10, Associativity.Right, ".",",", ")", "(", "]", "[", "{", "}");
- //RegisterOperators(11, Associativity.Right, "else");
- #endregion
-
- #region 6. Punctuation symbols
- RegisterPunctuation("(", ")", "[", "]", "{", "}", ",", ";");
- #endregion
- */
- #endregion
-
- #region Simple grammar
- NonTerminal Simple = new NonTerminal("SimpleProg");
- NonTerminal Anything = new NonTerminal("Token");
- Simple.Rule = Anything.Star() + Eof;
- Anything.Rule = n | s;
- foreach (string keyword in reserved) Anything.Rule = Anything.Rule | ToTerm(keyword);
- Anything.Rule = Anything.Rule | ident;
- foreach (string delimiter in delimiters) Anything.Rule = Anything.Rule | ToTerm(delimiter);
-
- RegisterBracePair("{", "}");
- RegisterBracePair("(", ")");
-
- this.Root = Simple;
- #endregion
- }
- }
-}
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Guids.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Guids.cs
deleted file mode 100644
index ba02ca8c..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Guids.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace Demo
-{
- static class GuidList
- {
- public const string guidIronyLanguageServiceString = "7bcbed0f-df47-4729-b796-b54f14853e2e";
- public const string guidIronyLanguageServicePkgString = "a681f79a-0ed1-4ae0-b79f-4ae69e178800";
- public const string guidIronyLanguageServiceCmdSetString = "be21e7e3-e9c5-4287-95ab-e5125c5063f7";
-
- public static readonly Guid guidIronyLanguageServiceCmdSet = new Guid(guidIronyLanguageServiceCmdSetString);
- };
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/AuthoringScope.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/AuthoringScope.cs
deleted file mode 100644
index 9a49dbe4..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/AuthoringScope.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class AuthoringScope : Microsoft.VisualStudio.Package.AuthoringScope
- {
- public AuthoringScope(object parseResult)
- {
- this.parseResult = parseResult;
-
- // how should this be set?
- this.resolver = new Resolver();
- }
-
- object parseResult;
- IASTResolver resolver;
-
- // ParseReason.QuickInfo
- public override string GetDataTipText(int line, int col, out TextSpan span)
- {
- span = new TextSpan();
- return null;
- }
-
- // ParseReason.CompleteWord
- // ParseReason.DisplayMemberList
- // ParseReason.MemberSelect
- // ParseReason.MemberSelectAndHilightBraces
- public override Microsoft.VisualStudio.Package.Declarations GetDeclarations(IVsTextView view, int line, int col, TokenInfo info, ParseReason reason)
- {
- IList<Declaration> declarations;
- switch (reason)
- {
- case ParseReason.CompleteWord:
- declarations = resolver.FindCompletions(parseResult, line, col);
- break;
- case ParseReason.DisplayMemberList:
- case ParseReason.MemberSelect:
- case ParseReason.MemberSelectAndHighlightBraces:
- declarations = resolver.FindMembers(parseResult, line, col);
- break;
- default:
- throw new ArgumentException("reason");
- }
-
- return new Declarations(declarations);
- }
-
- // ParseReason.GetMethods
- public override Microsoft.VisualStudio.Package.Methods GetMethods(int line, int col, string name)
- {
- return new Methods(resolver.FindMethods(parseResult, line, col, name));
- }
-
- // ParseReason.Goto
- public override string Goto(VSConstants.VSStd97CmdID cmd, IVsTextView textView, int line, int col, out TextSpan span)
- {
- span = new TextSpan();
- return null;
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Configuration.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Configuration.cs
deleted file mode 100644
index f7412393..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Configuration.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Microsoft.VisualStudio.Package;
-using Microsoft.VisualStudio.TextManager.Interop;
-
-namespace Demo
-{
- public static partial class Configuration
- {
- public static Grammar Grammar = new Grammar();
- static List<Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem> colorableItems = new List<Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem>();
-
- public static IList<Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem> ColorableItems
- {
- get { return colorableItems; }
- }
-
- public static TokenColor CreateColor(string name, COLORINDEX foreground, COLORINDEX background)
- {
- return CreateColor(name, foreground, background, false, false);
- }
-
- public static TokenColor CreateColor(string name, COLORINDEX foreground, COLORINDEX background, bool bold, bool strikethrough)
- {
- colorableItems.Add(new ColorableItem(name, foreground, background, bold, strikethrough));
- return (TokenColor)colorableItems.Count;
- }
-
- public static void ColorToken(string tokenName, TokenType type, TokenColor color, TokenTriggers trigger)
- {
- definitions[tokenName] = new TokenDefinition(type, color, trigger);
- }
-
- public static TokenDefinition GetDefinition(string tokenName)
- {
- TokenDefinition result;
- return definitions.TryGetValue(tokenName, out result) ? result : defaultDefinition;
- }
-
- private static TokenDefinition defaultDefinition = new TokenDefinition(TokenType.Text, TokenColor.Text, TokenTriggers.None);
- private static Dictionary<string, TokenDefinition> definitions = new Dictionary<string, TokenDefinition>();
-
- public struct TokenDefinition
- {
- public TokenDefinition(TokenType type, TokenColor color, TokenTriggers triggers)
- {
- this.TokenType = type;
- this.TokenColor = color;
- this.TokenTriggers = triggers;
- }
-
- public TokenType TokenType;
- public TokenColor TokenColor;
- public TokenTriggers TokenTriggers;
- }
- }
-
- public class ColorableItem : Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem
- {
- private string displayName;
- private COLORINDEX background;
- private COLORINDEX foreground;
- private uint fontFlags = (uint)FONTFLAGS.FF_DEFAULT;
-
- public ColorableItem(string displayName, COLORINDEX foreground, COLORINDEX background, bool bold, bool strikethrough)
- {
- this.displayName = displayName;
- this.background = background;
- this.foreground = foreground;
-
- if (bold)
- this.fontFlags = this.fontFlags | (uint)FONTFLAGS.FF_BOLD;
- if (strikethrough)
- this.fontFlags = this.fontFlags | (uint)FONTFLAGS.FF_STRIKETHROUGH;
- }
-
- #region IVsColorableItem Members
- public int GetDefaultColors(COLORINDEX[] piForeground, COLORINDEX[] piBackground)
- {
- if (null == piForeground)
- {
- throw new ArgumentNullException("piForeground");
- }
- if (0 == piForeground.Length)
- {
- throw new ArgumentOutOfRangeException("piForeground");
- }
- piForeground[0] = foreground;
-
- if (null == piBackground)
- {
- throw new ArgumentNullException("piBackground");
- }
- if (0 == piBackground.Length)
- {
- throw new ArgumentOutOfRangeException("piBackground");
- }
- piBackground[0] = background;
-
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
-
- public int GetDefaultFontFlags(out uint pdwFontFlags)
- {
- pdwFontFlags = this.fontFlags;
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
-
- public int GetDisplayName(out string pbstrName)
- {
- pbstrName = displayName;
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
- #endregion
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declaration.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declaration.cs
deleted file mode 100644
index c0fda5ca..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declaration.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Demo
-{
- public struct Declaration : IComparable<Declaration>
- {
- public Declaration(string description, string displayText, int glyph, string name)
- {
- this.Description = description;
- this.DisplayText = displayText;
- this.Glyph = glyph;
- this.Name = name;
- }
-
- public string Description;
- public string DisplayText;
- public int Glyph;
- public string Name;
-
- #region IComparable<Declaration> Members
-
- public int CompareTo(Declaration other)
- {
- return DisplayText.CompareTo(other.DisplayText);
- }
-
- #endregion
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declarations.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declarations.cs
deleted file mode 100644
index 98a411ce..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Declarations.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-This code is licensed under the Visual Studio SDK license terms.
-THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
-***************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class Declarations : Microsoft.VisualStudio.Package.Declarations
- {
- IList<Declaration> declarations;
- public Declarations(IList<Declaration> declarations)
- {
- this.declarations = declarations;
- }
-
- public override int GetCount()
- {
- return declarations.Count;
- }
-
- public override string GetDescription(int index)
- {
- return declarations[index].Description;
- }
-
- public override string GetDisplayText(int index)
- {
- return declarations[index].DisplayText;
- }
-
- public override int GetGlyph(int index)
- {
- return declarations[index].Glyph;
- }
-
- public override string GetName(int index)
- {
- if (index >= 0)
- return declarations[index].Name;
-
- return null;
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IASTResolver.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IASTResolver.cs
deleted file mode 100644
index 8de1a454..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IASTResolver.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Demo
-{
- interface IASTResolver
- {
- IList<Declaration> FindCompletions(object result, int line, int col);
- IList<Declaration> FindMembers(object result, int line, int col);
- string FindQuickInfo(object result, int line, int col);
- IList<Method> FindMethods(object result, int line, int col, string name);
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyLanguageService.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyLanguageService.cs
deleted file mode 100644
index bb7cfebb..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyLanguageService.cs
+++ /dev/null
@@ -1,347 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-using Irony.Parsing;
-using Irony.Ast;
-
-using System.IO;
-using System.Text.RegularExpressions;
-
-namespace Demo
-{
- public class IronyLanguageService : Microsoft.VisualStudio.Package.LanguageService
- {
- private Grammar grammar;
- private Parser parser;
- private ParsingContext context;
-
- public IronyLanguageService()
- {
- grammar = new Grammar();
- parser = new Parser(Configuration.Grammar);
- context = new ParsingContext(parser);
- }
-
-
- #region Custom Colors
- public override int GetColorableItem(int index, out IVsColorableItem item)
- {
- if (index <= Configuration.ColorableItems.Count)
- {
- item = Configuration.ColorableItems[index - 1];
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
- else
- {
- throw new ArgumentNullException("index");
- }
- }
-
- public override int GetItemCount(out int count)
- {
- count = Configuration.ColorableItems.Count;
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
- #endregion
-
- #region MPF Accessor and Factory specialisation
- private LanguagePreferences preferences;
- public override LanguagePreferences GetLanguagePreferences()
- {
- if (this.preferences == null)
- {
- this.preferences = new LanguagePreferences(this.Site,
- typeof(IronyLanguageService).GUID,
- this.Name);
- this.preferences.Init();
- }
-
- return this.preferences;
- }
-
- public override Microsoft.VisualStudio.Package.Source CreateSource(IVsTextLines buffer)
- {
- return new Source(this, buffer, this.GetColorizer(buffer));
- }
-
- private IScanner scanner;
- public override IScanner GetScanner(IVsTextLines buffer)
- {
- if (scanner == null)
- this.scanner = new LineScanner(grammar);
-
- return this.scanner;
- }
- #endregion
-
- public override void OnIdle(bool periodic)
- {
- // from IronPythonLanguage sample
- // this appears to be necessary to get a parse request with ParseReason = Check?
- Source src = (Source)GetSource(this.LastActiveTextView);
- if (src != null && src.LastParseTime >= Int32.MaxValue >> 12)
- {
- src.LastParseTime = 0;
- }
- base.OnIdle(periodic);
- }
-
- public override Microsoft.VisualStudio.Package.AuthoringScope ParseSource(ParseRequest req)
- {
- Debug.Print("ParseSource at ({0}:{1}), reason {2}", req.Line, req.Col, req.Reason);
- Source source = (Source)this.GetSource(req.FileName);
- switch (req.Reason)
- {
- case ParseReason.Check:
- // This is where you perform your syntax highlighting.
- // Parse entire source as given in req.Text.
- // Store results in the AuthoringScope object.
- var parsed = parser.Parse(req.Text, req.FileName);
- var root = parsed.Root;
- if (root != null) {
-
- AstNode node = (AstNode)root.AstNode;
- source.ParseResult = node;
- }
-
- // Used for brace matching.
- //TokenStack braces = parser.Context.OpenBraces;
- //foreach (Token brace in braces) {
- // if (brace.OtherBrace == null) continue;
- // TextSpan openBrace = new TextSpan();
- // openBrace.iStartLine = brace.Location.Line;
- // openBrace.iStartIndex = brace.Location.Column;
- // openBrace.iEndLine = brace.Location.Line;
- // openBrace.iEndIndex = openBrace.iStartIndex + brace.Length;
-
- // TextSpan closeBrace = new TextSpan();
- // closeBrace.iStartLine = brace.OtherBrace.Location.Line;
- // closeBrace.iStartIndex = brace.OtherBrace.Location.Column;
- // closeBrace.iEndLine = brace.OtherBrace.Location.Line;
- // closeBrace.iEndIndex = closeBrace.iStartIndex + brace.OtherBrace.Length;
-
- // if (source.Braces == null) {
- // source.Braces = new List<TextSpan[]>();
- // }
- // source.Braces.Add(new TextSpan[2] { openBrace, closeBrace });
- //}
-
- if (parser.Context.CurrentParseTree.ParserMessages.Count > 0) {
- foreach (ParserMessage error in parser.Context.CurrentParseTree.ParserMessages) {
- TextSpan span = new TextSpan();
- span.iStartLine = span.iEndLine = error.Location.Line;
- span.iStartIndex = error.Location.Column;
- span.iEndIndex = error.Location.Position;
- req.Sink.AddError(req.FileName, error.Message, span, Severity.Error);
- }
- } else { // parse looks okay, send it to Chalice.
- if (!File.Exists(@"C:\tmp\StartChalice.bat")) {
- AddErrorBecauseOfToolProblems(req, @"Can't find C:\tmp\StartChalice.bat");
- } else {
-
- // From: http://dotnetperls.com/process-redirect-standard-output
- // (Also, see: http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx)
- //
- // Setup the process with the ProcessStartInfo class.
- //
- ProcessStartInfo start = new ProcessStartInfo();
- start.FileName = @"cmd.exe";
- start.Arguments = @"/c C:\tmp\StartChalice.bat"; // Specify exe name.
- start.UseShellExecute = false;
- start.RedirectStandardInput = true;
- start.RedirectStandardOutput = true;
- start.CreateNoWindow = true;
- //start.WindowStyle = ProcessWindowStyle.Minimized; // need this or else you see the window pop up
- //
- // Start the process.
- //
- using (Process process = Process.Start(start)) {
- //
- // Push the file contents to the new process
- //
- StreamWriter myStreamWriter = process.StandardInput;
- myStreamWriter.WriteLine(req.Text);
- myStreamWriter.Close();
- //
- // Read in all the text from the process with the StreamReader.
- //
- using (StreamReader reader = process.StandardOutput) {
- //string result = reader.ReadToEnd();
- //Console.Write(result);
-
- for (string line = reader.ReadLine(); line != null; line = reader.ReadLine()) {
- if (line == "")
- continue;
- if (line.StartsWith("Boogie program verifier")) {
- if (!Regex.IsMatch(line, "Boogie program verifier finished with [0-9]* verified, 0 errors"))
- AddErrorBecauseOfToolProblems(req, line, false);
- continue;
- }
-
- // each line is of the form: "x,y,w,z:arbitrary text"
- int colonIndex = line.IndexOf(':');
- if (colonIndex == -1) {
- AddErrorBecauseOfToolProblems(req, "Couldn't find colon in '" + line + "'");
- continue;
- }
- string numbers = line.Substring(0, colonIndex);
- var message = line.Substring(colonIndex + 1);
- string[] positions = numbers.Split(',');
- if (positions.Length != 4) {
- AddErrorBecauseOfToolProblems(req, "Couldn't find four numbers in '" + numbers + "'");
- continue;
- }
- try {
- TextSpan span = new TextSpan();
- span.iStartLine = span.iEndLine = Math.Max(0, Int32.Parse(positions[0]) - 1);
- span.iStartIndex = Math.Max(0, Int32.Parse(positions[1]) - 1);
- span.iEndLine = Math.Max(0, Int32.Parse(positions[2]) - 1);
- span.iEndIndex = Math.Max(0, Int32.Parse(positions[3]) - 1);
- req.Sink.AddError(req.FileName, message, span, Severity.Error);
- } catch (System.ArgumentNullException) {
- AddErrorBecauseOfToolProblems(req, "Couldn't parse numbers: '" + numbers + "'");
- } catch (System.FormatException) {
- AddErrorBecauseOfToolProblems(req, "Couldn't parse numbers: '" + numbers + "'");
- } catch (System.OverflowException) {
- AddErrorBecauseOfToolProblems(req, "Couldn't parse numbers: '" + numbers + "'");
- }
- }
- }
- }
- }
- }
-
- break;
-
- case ParseReason.DisplayMemberList:
- // Parse the line specified in req.Line for the two
- // tokens just before req.Col to obtain the identifier
- // and the member connector symbol.
- // Examine existing parse tree for members of the identifer
- // and return a list of members in your version of the
- // Declarations class as stored in the AuthoringScope
- // object.
- break;
-
- case ParseReason.MethodTip:
- // Parse the line specified in req.Line for the token
- // just before req.Col to obtain the name of the method
- // being entered.
- // Examine the existing parse tree for all method signatures
- // with the same name and return a list of those signatures
- // in your version of the Methods class as stored in the
- // AuthoringScope object.
- break;
-
- case ParseReason.HighlightBraces:
- case ParseReason.MemberSelectAndHighlightBraces:
- //if (source.Braces != null)
- //{
- // foreach (TextSpan[] brace in source.Braces)
- // {
- // if (brace.Length == 2)
- // req.Sink.MatchPair(brace[0], brace[1], 1);
- // else if (brace.Length >= 3)
- // req.Sink.MatchTriple(brace[0], brace[1], brace[2], 1);
- // }
- //}
- break;
- }
-
- return new AuthoringScope(source.ParseResult);
- }
-
- private static void AddErrorBecauseOfToolProblems(ParseRequest req, string msg) {
- AddErrorBecauseOfToolProblems(req, msg, true);
- }
- private static void AddErrorBecauseOfToolProblems(ParseRequest req, string msg, bool error) {
- TextSpan span = new TextSpan();
- span.iStartLine = span.iEndLine = 0;
- span.iStartIndex = 0;
- span.iEndIndex = 5;
- req.Sink.AddError(req.FileName, msg, span, error ? Severity.Error : Severity.Hint);
- }
-
- /// <summary>
- /// Called to determine if the given location can have a breakpoint applied to it.
- /// </summary>
- /// <param name="buffer">The IVsTextBuffer object containing the source file.</param>
- /// <param name="line">The line number where the breakpoint is to be set.</param>
- /// <param name="col">The offset into the line where the breakpoint is to be set.</param>
- /// <param name="pCodeSpan">
- /// Returns the TextSpan giving the extent of the code affected by the breakpoint if the
- /// breakpoint can be set.
- /// </param>
- /// <returns>
- /// If successful, returns S_OK; otherwise returns S_FALSE if there is no code at the given
- /// position or returns an error code (the validation is deferred until the debug engine is loaded).
- /// </returns>
- /// <remarks>
- /// <para>
- /// CAUTION: Even if you do not intend to support the ValidateBreakpointLocation but your language
- /// does support breakpoints, you must override the ValidateBreakpointLocation method and return a
- /// span that contains the specified line and column; otherwise, breakpoints cannot be set anywhere
- /// except line 1. You can return E_NOTIMPL to indicate that you do not otherwise support this
- /// method but the span must always be set. The example shows how this can be done.
- /// </para>
- /// <para>
- /// Since the language service parses the code, it generally knows what is considered code and what
- /// is not. Normally, the debug engine is loaded and the pending breakpoints are bound to the source. It is at this time the breakpoint location is validated. This method is a fast way to determine if a breakpoint can be set at a particular location without loading the debug engine.
- /// </para>
- /// <para>
- /// You can implement this method to call the ParseSource method with the parse reason of CodeSpan.
- /// The parser examines the specified location and returns a span identifying the code at that
- /// location. If there is code at the location, the span identifying that code should be passed to
- /// your implementation of the CodeSpan method in your version of the AuthoringSink class. Then your
- /// implementation of the ValidateBreakpointLocation method retrieves that span from your version of
- /// the AuthoringSink class and returns that span in the pCodeSpan argument.
- /// </para>
- /// <para>
- /// The base method returns E_NOTIMPL.
- /// </para>
- /// </remarks>
- public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan)
- {
- // TODO: Add code to not allow breakpoints to be placed on non-code lines.
- // TODO: Refactor to allow breakpoint locations to span multiple lines.
- if (pCodeSpan != null)
- {
- pCodeSpan[0].iStartLine = line;
- pCodeSpan[0].iStartIndex = col;
- pCodeSpan[0].iEndLine = line;
- pCodeSpan[0].iEndIndex = col;
- if (buffer != null)
- {
- int length;
- buffer.GetLengthOfLine(line, out length);
- pCodeSpan[0].iStartIndex = 0;
- pCodeSpan[0].iEndIndex = length;
- }
- return VSConstants.S_OK;
- }
- else
- {
- return VSConstants.S_FALSE;
- }
- }
-
- public override ViewFilter CreateViewFilter(CodeWindowManager mgr, IVsTextView newView)
- {
- return new IronyViewFilter(mgr, newView);
- }
-
- public override string Name
- {
- get { return Configuration.Name; }
- }
-
- public override string GetFormatFilterList()
- {
- return Configuration.FormatList;
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyViewFilter.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyViewFilter.cs
deleted file mode 100644
index 55c3509e..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/IronyViewFilter.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.VisualStudio.Package;
-using Microsoft.VisualStudio.TextManager.Interop;
-
-using VsCommands2K = Microsoft.VisualStudio.VSConstants.VSStd2KCmdID;
-
-namespace Demo
-{
- public class IronyViewFilter : ViewFilter
- {
- public IronyViewFilter(CodeWindowManager mgr, IVsTextView view)
- : base(mgr, view)
- {
-
- }
-
- public override void HandlePostExec(ref Guid guidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut, bool bufferWasChanged)
- {
- if (guidCmdGroup == typeof(VsCommands2K).GUID)
- {
- VsCommands2K cmd = (VsCommands2K)nCmdId;
- switch (cmd)
- {
- case VsCommands2K.UP:
- case VsCommands2K.UP_EXT:
- case VsCommands2K.UP_EXT_COL:
- case VsCommands2K.DOWN:
- case VsCommands2K.DOWN_EXT:
- case VsCommands2K.DOWN_EXT_COL:
- Source.OnCommand(TextView, cmd, '\0');
- return;
- }
- }
-
-
- base.HandlePostExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut, bufferWasChanged);
- }
- }
-}
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/LineScanner.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/LineScanner.cs
deleted file mode 100644
index 966e9c43..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/LineScanner.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-using Microsoft.VisualStudio.Package;
-using Irony.Parsing;
-
-namespace Demo
-{
- public class LineScanner : IScanner
- {
- private Parser parser;
-
- public LineScanner(Grammar grammar)
- {
- this.parser = new Parser(grammar);
- this.parser.Context.Mode = ParseMode.VsLineScan;
- }
-
- public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state)
- {
- // Reads each token in a source line and performs syntax coloring. It will continue to
- // be called for the source until false is returned.
- Token token = parser.Scanner.VsReadToken(ref state);
-
- // !EOL and !EOF
- if (token != null && token.Terminal != Grammar.CurrentGrammar.Eof && token.Category != TokenCategory.Error)
- {
- tokenInfo.StartIndex = token.Location.Position;
- tokenInfo.EndIndex = tokenInfo.StartIndex + token.Length - 1;
- if (token.EditorInfo != null) {
- tokenInfo.Color = (Microsoft.VisualStudio.Package.TokenColor)token.EditorInfo.Color;
- tokenInfo.Type = (Microsoft.VisualStudio.Package.TokenType)token.EditorInfo.Type;
- }
-
- if (token.KeyTerm != null && token.KeyTerm.EditorInfo != null)
- {
- tokenInfo.Trigger =
- (Microsoft.VisualStudio.Package.TokenTriggers)token.KeyTerm.EditorInfo.Triggers;
- }
- else
- {
- if (token.EditorInfo != null) {
- tokenInfo.Trigger =
- (Microsoft.VisualStudio.Package.TokenTriggers)token.EditorInfo.Triggers;
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- public void SetSource(string source, int offset)
- {
- // Stores line of source to be used by ScanTokenAndProvideInfoAboutIt.
- parser.Scanner.VsSetSource(source, offset);
- }
- }
-}
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Method.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Method.cs
deleted file mode 100644
index c5071612..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Method.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Demo
-{
- public struct Method
- {
- public string Name;
- public string Description;
- public string Type;
- public IList<Parameter> Parameters;
- }
-
- public struct Parameter
- {
- public string Name;
- public string Display;
- public string Description;
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Methods.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Methods.cs
deleted file mode 100644
index 1d7c124f..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Methods.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class Methods : Microsoft.VisualStudio.Package.Methods
- {
- IList<Method> methods;
- public Methods(IList<Method> methods)
- {
- this.methods = methods;
- }
-
- public override int GetCount()
- {
- return methods.Count;
- }
-
- public override string GetName(int index)
- {
- return methods[index].Name;
- }
-
- public override string GetDescription(int index)
- {
- return methods[index].Description;
- }
-
- public override string GetType(int index)
- {
- return methods[index].Type;
- }
-
- public override int GetParameterCount(int index)
- {
- return (methods[index].Parameters == null) ? 0 : methods[index].Parameters.Count;
- }
-
- public override void GetParameterInfo(int index, int paramIndex, out string name, out string display, out string description)
- {
- Parameter parameter = methods[index].Parameters[paramIndex];
- name = parameter.Name;
- display = parameter.Display;
- description = parameter.Description;
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Package.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Package.cs
deleted file mode 100644
index dc1244d6..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Package.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-using Microsoft.VisualStudio.OLE.Interop;
-using MPF = Microsoft.VisualStudio.Package;
-using System.ComponentModel.Design;
-
-namespace Demo
-{
- public class IronyPackage : Microsoft.VisualStudio.Shell.Package, IOleComponent
- {
- uint componentID = 0;
- public IronyPackage()
- {
- ServiceCreatorCallback callback = new ServiceCreatorCallback(
- delegate(IServiceContainer container, Type serviceType)
- {
- if (typeof(IronyLanguageService) == serviceType)
- {
- IronyLanguageService language = new IronyLanguageService();
- language.SetSite(this);
-
- // register for idle time callbacks
- IOleComponentManager mgr = GetService(typeof(SOleComponentManager)) as IOleComponentManager;
- if (componentID == 0 && mgr != null)
- {
- OLECRINFO[] crinfo = new OLECRINFO[1];
- crinfo[0].cbSize = (uint)Marshal.SizeOf(typeof(OLECRINFO));
- crinfo[0].grfcrf = (uint)_OLECRF.olecrfNeedIdleTime |
- (uint)_OLECRF.olecrfNeedPeriodicIdleTime;
- crinfo[0].grfcadvf = (uint)_OLECADVF.olecadvfModal |
- (uint)_OLECADVF.olecadvfRedrawOff |
- (uint)_OLECADVF.olecadvfWarningsOff;
- crinfo[0].uIdleTimeInterval = 300;
- int hr = mgr.FRegisterComponent(this, crinfo, out componentID);
- }
-
- return language;
- }
- else
- {
- return null;
- }
- });
-
- // proffer the LanguageService
- (this as IServiceContainer).AddService(typeof(IronyLanguageService), callback, true);
- }
-
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (componentID != 0)
- {
- IOleComponentManager mgr = GetService(typeof(SOleComponentManager)) as IOleComponentManager;
- if (mgr != null)
- {
- mgr.FRevokeComponent(componentID);
- }
- componentID = 0;
- }
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
-
- #region IOleComponent Members
- public int FContinueMessageLoop(uint uReason, IntPtr pvLoopData, MSG[] pMsgPeeked)
- {
- return 1;
- }
-
- public int FDoIdle(uint grfidlef)
- {
- IronyLanguageService ls = GetService(typeof(IronyLanguageService)) as IronyLanguageService;
-
- if (ls != null)
- {
- ls.OnIdle((grfidlef & (uint)_OLEIDLEF.oleidlefPeriodic) != 0);
- }
-
- return 0;
- }
-
- public int FPreTranslateMessage(MSG[] pMsg)
- {
- return 0;
- }
-
- public int FQueryTerminate(int fPromptUser)
- {
- return 1;
- }
-
- public int FReserved1(uint dwReserved, uint message, IntPtr wParam, IntPtr lParam)
- {
- return 1;
- }
-
- public IntPtr HwndGetWindow(uint dwWhich, uint dwReserved)
- {
- return IntPtr.Zero;
- }
-
- public void OnActivationChange(IOleComponent pic, int fSameComponent, OLECRINFO[] pcrinfo, int fHostIsActivating, OLECHOSTINFO[] pchostinfo, uint dwReserved)
- {
- }
-
- public void OnAppActivate(int fActive, uint dwOtherThreadID)
- {
- }
-
- public void OnEnterState(uint uStateID, int fEnter)
- {
- }
-
- public void OnLoseActivation()
- {
- }
-
- public void Terminate()
- {
- }
- #endregion
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Resolver.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Resolver.cs
deleted file mode 100644
index 9f6ddeba..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Resolver.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Irony.Parsing;
-
-namespace Demo
-{
- public class Resolver : Demo.IASTResolver
- {
- #region IASTResolver Members
-
-
- public IList<Demo.Declaration> FindCompletions(object result, int line, int col)
- {
- // Used for intellisense.
- List<Demo.Declaration> declarations = new List<Demo.Declaration>();
-
- // Add keywords defined by grammar
- foreach (KeyTerm key in Configuration.Grammar.KeyTerms.Values)
- {
- if(key.OptionIsSet(TermOptions.IsKeyword))
- {
- declarations.Add(new Declaration("", key.Name, 206, key.Name));
- }
- }
-
- declarations.Sort();
- return declarations;
- }
-
- public IList<Demo.Declaration> FindMembers(object result, int line, int col)
- {
- List<Demo.Declaration> members = new List<Demo.Declaration>();
-
- return members;
- }
-
- public string FindQuickInfo(object result, int line, int col)
- {
- return "unknown";
- }
-
- public IList<Demo.Method> FindMethods(object result, int line, int col, string name)
- {
- return new List<Demo.Method>();
- }
-
- #endregion
- }
-}
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Source.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Source.cs
deleted file mode 100644
index 418bec01..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Integration/Source.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-This code is licensed under the Visual Studio SDK license terms.
-THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
-***************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class Source : Microsoft.VisualStudio.Package.Source
- {
- public Source(LanguageService service, IVsTextLines textLines, Colorizer colorizer)
- : base(service, textLines, colorizer)
- {
- }
-
- private object parseResult;
- public object ParseResult
- {
- get { return parseResult; }
- set { parseResult = value; }
- }
-
- private IList<TextSpan[]> braces;
- public IList<TextSpan[]> Braces
- {
- get { return braces; }
- set { braces = value; }
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/IronyLanguageServicePackage.cs b/Util/VS2010/Chalice/ChaliceLanguageService/IronyLanguageServicePackage.cs
deleted file mode 100644
index 8b9cb825..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/IronyLanguageServicePackage.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-// VsPkg.cs : Implementation of IronyLanguageService
-//
-
-using System;
-using System.Diagnostics;
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.ComponentModel.Design;
-using Microsoft.Win32;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.OLE.Interop;
-using Microsoft.VisualStudio.Shell;
-
-namespace Demo
-{
- /// <summary>
- /// This is the class that implements the package exposed by this assembly.
- ///
- /// The minimum requirement for a class to be considered a valid package for Visual Studio
- /// is to implement the IVsPackage interface and register itself with the shell.
- /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
- /// to do it: it derives from the Package class that provides the implementation of the
- /// IVsPackage interface and uses the registration attributes defined in the framework to
- /// register itself and its components with the shell.
- /// </summary>
- // This attribute tells the registration utility (regpkg.exe) that this class needs
- // to be registered as package.
- [PackageRegistration(UseManagedResourcesOnly = true)]
- // A Visual Studio component can be registered under different regitry roots; for instance
- // when you debug your package you want to register it in the experimental hive. This
- // attribute specifies the registry root to use if no one is provided to regpkg.exe with
- // the /root switch.
- [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\10.0Exp")]
- // This attribute is used to register the informations needed to show the this package
- // in the Help/About dialog of Visual Studio.
- [InstalledProductRegistration(/*false,*/ "#110", "#112", "1.0", IconResourceID = 400)]
- // This attribute will make your language service accessible by other packages installed.
- [ProvideService(typeof(IronyLanguageService))]
- // This attribute(s) associates file extensions with your language service.
-// [ProvideLanguageExtension(typeof(IronyLanguageService), ".myc")]
- [ProvideLanguageExtension(typeof(IronyLanguageService), ".chalice")]
-
- // This attributes informs Visual Studio that this package provides a langauge service and
- // which features are implemented.
- [ProvideLanguageService(typeof(IronyLanguageService), Configuration.Name, 0,
- CodeSense = true,
- EnableCommenting = true,
- MatchBraces = true,
- MatchBracesAtCaret = true,
- ShowMatchingBrace = true,
- AutoOutlining = true)]
- // In order be loaded inside Visual Studio in a machine that has not the VS SDK installed,
- // package needs to have a valid load key (it can be requested at
- // http://msdn.microsoft.com/vstudio/extend/). This attributes tells the shell that this
- // package has a load key embedded in its resources.
- [ProvideLoadKey("Standard", "1.0", "Chalice", "Demo", 104)]
- [Guid(GuidList.guidIronyLanguageServicePkgString)]
- public sealed class MyCLanguageService : IronyPackage
- {
- /// <summary>
- /// Default constructor of the package.
- /// Inside this method you can place any initialization code that does not require
- /// any Visual Studio service because at this point the package object is created but
- /// not sited yet inside Visual Studio environment. The place to do all the other
- /// initialization is the Initialize method.
- /// </summary>
- public MyCLanguageService()
- {
- Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Overriden Package Implementation
- #region Package Members
-
- /// <summary>
- /// Initialization of the package; this method is called right after the package is sited, so this is the place
- /// where you can put all the initilaization code that rely on services provided by VisualStudio.
- /// </summary>
- protected override void Initialize()
- {
- Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
- base.Initialize();
-
- }
- #endregion
-
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Key.snk b/Util/VS2010/Chalice/ChaliceLanguageService/Key.snk
deleted file mode 100644
index f80a4ceb..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Key.snk
+++ /dev/null
Binary files differ
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Properties/AssemblyInfo.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Properties/AssemblyInfo.cs
deleted file mode 100644
index 118d4488..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Reflection;
-using System.Resources;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Package Name")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Company")]
-[assembly: AssemblyProduct("Package Name")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-[assembly: CLSCompliant(false)]
-[assembly: NeutralResourcesLanguage("en-US")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-
-
-
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Resources.Designer.cs b/Util/VS2010/Chalice/ChaliceLanguageService/Resources.Designer.cs
deleted file mode 100644
index cd9f79db..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Resources.Designer.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-// This code was generated by a tool.
-// Runtime Version:4.0.21006.1
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Demo {
- using System;
-
-
- /// <summary>
- /// A strongly-typed resource class, for looking up localized strings, etc.
- /// </summary>
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- /// <summary>
- /// Returns the cached ResourceManager instance used by this class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.MyCLanguageService.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- /// <summary>
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
- }
-}
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Resources.resx b/Util/VS2010/Chalice/ChaliceLanguageService/Resources.resx
deleted file mode 100644
index 03fef612..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Resources.resx
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- VS SDK Notes: This resx file contains the resources that will be consumed directly by your package.
- For example, if you chose to create a tool window, there is a resource with ID 'CanNotCreateWindow'. This
- is used in VsPkg.cs to determine the string to show the user if there is an error when attempting to create
- the tool window.
-
- Resources that are accessed directly from your package *by Visual Studio* are stored in the VSPackage.resx
- file.
--->
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-</root> \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/Resources/Irony.dll b/Util/VS2010/Chalice/ChaliceLanguageService/Resources/Irony.dll
deleted file mode 100644
index e2021a72..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/Resources/Irony.dll
+++ /dev/null
Binary files differ
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/VSPackage.resx b/Util/VS2010/Chalice/ChaliceLanguageService/VSPackage.resx
deleted file mode 100644
index 4c4adabd..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/VSPackage.resx
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <data name="104" xml:space="preserve">
- <value>Paste PLK Here</value>
- </data>
- <data name="110" xml:space="preserve">
- <value>Chalice</value>
- </data>
- <data name="112" xml:space="preserve">
- <value>Chalice Programming Language</value>
- </data>
-</root> \ No newline at end of file
diff --git a/Util/VS2010/Chalice/ChaliceLanguageService/source.extension.vsixmanifest b/Util/VS2010/Chalice/ChaliceLanguageService/source.extension.vsixmanifest
deleted file mode 100644
index 15fd4e9a..00000000
--- a/Util/VS2010/Chalice/ChaliceLanguageService/source.extension.vsixmanifest
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Vsix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
-
- <Identifier Id="ChaliceService.MicrosoftResearch.A38156F6-63DF-4E3C-8D23-07D3DE0D3388">
- <Name>ChaliceService</Name>
- <Author>Microsoft Research</Author>
- <Version>1.0</Version>
- <Description>Information about my package</Description>
- <Locale>1033</Locale>
- <!--<InstalledByMSI>false</InstalledByMSI>-->
- <SupportedProducts>
- <VisualStudio Version="10.0">
- <Edition>Pro</Edition>
- <Edition>VST_All</Edition>
- </VisualStudio>
- </SupportedProducts>
- <SupportedFrameworkRuntimeEdition MinVersion="2.0" MaxVersion="4.0" />
- </Identifier>
-
- <References/>
-
- <Content>
- <VsPackage>
- ChaliceService.pkgdef
- </VsPackage>
- </Content>
-</Vsix>
diff --git a/Util/VS2010/Chalice/StartChalice.bat b/Util/VS2010/Chalice/StartChalice.bat
deleted file mode 100644
index e2de0e65..00000000
--- a/Util/VS2010/Chalice/StartChalice.bat
+++ /dev/null
@@ -1,10 +0,0 @@
-@echo off
-echo ---------- Starting ------------ < nul >> c:\tmp\coo.out
-time < nul >> c:\tmp\coo.out
-echo. < nul >> c:\tmp\coo.out
-
-call "c:\Program Files\Scala\bin\scala" -cp c:\boogie\Chalice\target\scala-2.8.1.final\classes chalice.Chalice /boogieOpt:nologo /vs %* 2>> c:\tmp\coo.out
-
-time < nul >> c:\tmp\coo.out
-echo. < nul >> c:\tmp\coo.out
-echo ---------- Done ------------ < nul >> c:\tmp\coo.out
diff --git a/Util/VS2010/Dafny/DafnyLanguageService.sln b/Util/VS2010/Dafny/DafnyLanguageService.sln
deleted file mode 100644
index d900cbb5..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DafnyLanguageService", "DafnyLanguageService\DafnyLanguageService.csproj", "{66E611EE-84D8-4EB9-9A33-164A53E00553}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {66E611EE-84D8-4EB9-9A33-164A53E00553}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Configuration.cs b/Util/VS2010/Dafny/DafnyLanguageService/Configuration.cs
deleted file mode 100644
index f32c75ab..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Configuration.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Microsoft.VisualStudio.Package;
-using Microsoft.VisualStudio.TextManager.Interop;
-
-namespace Demo
-{
- public static partial class Configuration
- {
- public const string Name = "Dafny";
- public const string FormatList = "Dafny File (*.dfy)\n*.dfy";
-
- static Configuration()
- {
- // default colors - currently, these need to be declared
- CreateColor("Keyword", COLORINDEX.CI_BLUE, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Comment", COLORINDEX.CI_DARKGREEN, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Identifier", COLORINDEX.CI_SYSPLAINTEXT_FG, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("String", COLORINDEX.CI_MAROON, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Number", COLORINDEX.CI_RED, COLORINDEX.CI_USERTEXT_BK);
- CreateColor("Text", COLORINDEX.CI_SYSPLAINTEXT_FG, COLORINDEX.CI_USERTEXT_BK);
- }
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/DafnyLanguageService.csproj b/Util/VS2010/Dafny/DafnyLanguageService/DafnyLanguageService.csproj
deleted file mode 100644
index 175c12dc..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/DafnyLanguageService.csproj
+++ /dev/null
@@ -1,179 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Demo.DafnyLanguageService</RootNamespace>
- <AssemblyName>DafnyLanguageService</AssemblyName>
- <SignAssembly>True</SignAssembly>
- <AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <ProjectGuid>{66E611EE-84D8-4EB9-9A33-164A53E00553}</ProjectGuid>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <OldToolsVersion>4.0</OldToolsVersion>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- <PublishUrl>publish\</PublishUrl>
- <Install>true</Install>
- <InstallFrom>Disk</InstallFrom>
- <UpdateEnabled>false</UpdateEnabled>
- <UpdateMode>Foreground</UpdateMode>
- <UpdateInterval>7</UpdateInterval>
- <UpdateIntervalUnits>Days</UpdateIntervalUnits>
- <UpdatePeriodically>false</UpdatePeriodically>
- <UpdateRequired>false</UpdateRequired>
- <MapFileExtensions>true</MapFileExtensions>
- <ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
- <UseApplicationTrust>false</UseApplicationTrust>
- <BootstrapperEnabled>true</BootstrapperEnabled>
- <TargetFrameworkProfile />
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <RunCodeAnalysis>true</RunCodeAnalysis>
- <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Irony, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ca48ace7223ead47, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>Resources\Irony.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.OLE.Interop" />
- <Reference Include="Microsoft.VisualStudio.Package.LanguageService.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Package.LanguageService.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.10.0">
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Shell.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Shell.Immutable.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Interop" />
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <SpecificVersion>False</SpecificVersion>
- <EmbedInteropTypes>True</EmbedInteropTypes>
- <HintPath>C:\Program Files\Microsoft Visual Studio 2010 Beta2 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Shell.Interop.10.0.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
- <Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
- <Reference Include="Microsoft.VisualStudio.TextManager.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\..\Program Files\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.TextManager.Interop.8.0.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Data" />
- <Reference Include="System.Design" />
- <Reference Include="System.Drawing" />
- <Reference Include="System.Windows.Forms" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Configuration.cs" />
- <Compile Include="Grammar.cs" />
- <Compile Include="Guids.cs" />
- <Compile Include="Integration\AuthoringScope.cs" />
- <Compile Include="Integration\Configuration.cs" />
- <Compile Include="Integration\Declaration.cs" />
- <Compile Include="Integration\Declarations.cs" />
- <Compile Include="Integration\IASTResolver.cs" />
- <Compile Include="Integration\IronyViewFilter.cs" />
- <Compile Include="Integration\IronyLanguageService.cs" />
- <Compile Include="Integration\LineScanner.cs" />
- <Compile Include="Integration\Method.cs" />
- <Compile Include="Integration\Methods.cs" />
- <Compile Include="Integration\Package.cs" />
- <Compile Include="Integration\Resolver.cs" />
- <Compile Include="Integration\Source.cs" />
- <Compile Include="Resources.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>Resources.resx</DependentUpon>
- </Compile>
- <Compile Include="GlobalSuppressions.cs" />
- <Compile Include="IronyLanguageServicePackage.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Resources.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Resources.Designer.cs</LastGenOutput>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- <EmbeddedResource Include="VSPackage.resx">
- <MergeWithCTO>true</MergeWithCTO>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- </ItemGroup>
- <ItemGroup>
- <Content Include="Resources\Irony.dll" />
- <None Include="source.extension.vsixmanifest" />
- </ItemGroup>
- <ItemGroup>
- <None Include="Key.snk" />
- </ItemGroup>
- <ItemGroup>
- <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
- <Install>false</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
- <Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.VisualBasic.PowerPacks.10.0">
- <Visible>False</Visible>
- <ProductName>Microsoft Visual Basic PowerPacks 10.0</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
- <Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
- <Install>true</Install>
- </BootstrapperPackage>
- </ItemGroup>
- <PropertyGroup>
- <!--
- To specify a different registry root to register your package, uncomment the TargetRegistryRoot
- tag and specify a registry root in it.
- <TargetRegistryRoot></TargetRegistryRoot>
- -->
- <RegisterOutputPackage>true</RegisterOutputPackage>
- <RegisterWithCodebase>true</RegisterWithCodebase>
- </PropertyGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\VSSDK\Microsoft.VsSDK.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/GlobalSuppressions.cs b/Util/VS2010/Dafny/DafnyLanguageService/GlobalSuppressions.cs
deleted file mode 100644
index f0857cbb..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/GlobalSuppressions.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// This file is used by Code Analysis to maintain SuppressMessage
-// attributes that are applied to this project. Project-level
-// suppressions either have no target or are given a specific target
-// and scoped to a namespace, type, member, etc.
-//
-// To add a suppression to this file, right-click the message in the
-// Error List, point to "Suppress Message(s)", and click "In Project
-// Suppression File". You do not need to add suppressions to this
-// file manually.
-
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs b/Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs
deleted file mode 100644
index ac1b755c..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs
+++ /dev/null
@@ -1,388 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Irony.Parsing;
-
-namespace Demo
-{
- [Language("Dafny", "1.0", "Dafny Programming Language")]
- public class Grammar : Irony.Parsing.Grammar
- {
- public Grammar() {
- #region 1. Terminals
- NumberLiteral n = TerminalFactory.CreateCSharpNumber("number");
-
- IdentifierTerminal ident = new IdentifierTerminal("Identifier", "'_?", "'_?");
-
- StringLiteral stringLiteral = TerminalFactory.CreateCSharpString("String");
-
- this.MarkReservedWords( // NOTE: these keywords must also appear once more below
- "class", "ghost", "static", "var", "method", "constructor", "datatype", "codatatype",
- "iterator", "type",
- "assert", "assume", "new", "this", "object", "refines",
- "module", "import", "as", "default", "opened",
- "if", "then", "else", "while", "invariant",
- "break", "label", "return", "yield", "parallel", "print",
- "returns", "yields", "requires", "ensures", "modifies", "reads", "decreases",
- "bool", "nat", "int", "false", "true", "null",
- "function", "predicate", "copredicate", "free",
- "in", "forall", "exists",
- "seq", "set", "map", "multiset", "array", "array2", "array3",
- "match", "case",
- "fresh", "old", "choose", "where", "calc"
- );
-
- StringLiteral s = new StringLiteral("String", "'", StringFlags.AllowsDoubledQuote);
-
- Terminal dot = ToTerm(".", "dot");
- Terminal less = ToTerm("<");
- Terminal greater = ToTerm(">");
- Terminal arrow = ToTerm("=>");
- Terminal LBracket = ToTerm("[");
- Terminal RBracket = ToTerm("]");
- Terminal LParen = ToTerm("(");
- Terminal RParen = ToTerm(")");
- Terminal RCurly = ToTerm("}");
- Terminal LCurly = ToTerm("{");
- Terminal LMb = ToTerm("<[");
- Terminal RMb = ToTerm("]>");
- Terminal comma = ToTerm(",");
- Terminal semicolon = ToTerm(";");
- Terminal colon = ToTerm(":");
-
- #endregion
-
- #region 2. Non-terminals
- #region 2.1 Expressions
- NonTerminal expression = new NonTerminal("Expr");
- NonTerminal BinOp = new NonTerminal("BinOp");
- NonTerminal LUnOp = new NonTerminal("LUnOp");
- NonTerminal RUnOp = new NonTerminal("RUnOp");
-
- NonTerminal ArrayConstructor = new NonTerminal("ArrayConstructor");
- NonTerminal MObjectConstructor = new NonTerminal("MObjectConstructor");
- NonTerminal MObjectList = new NonTerminal("MObjectList");
- #endregion
-
- #region 2.2 QualifiedName
- //Expression List: expr1, expr2, expr3, ..
- NonTerminal expressionList = new NonTerminal("ExprList");
- NonTerminal identList = new NonTerminal("identList");
- //A name in form: a.b.c().d[1,2].e ....
- NonTerminal NewStmt = new NonTerminal("NewStmt");
- NonTerminal NewArrStmt = new NonTerminal("NewArrStmt");
- NonTerminal QualifiedName = new NonTerminal("QualifiedName");
- NonTerminal GenericsPostfix = new NonTerminal("GenericsPostfix");
- NonTerminal ArrayExpression = new NonTerminal("ArrayExpression");
- NonTerminal FunctionExpression = new NonTerminal("FunctionExpression");
- NonTerminal selectExpr = new NonTerminal("selectExpr");
- #endregion
-
- #region 2.3 Statement
- NonTerminal Condition = new NonTerminal("Condition");
-
- NonTerminal Statement = new NonTerminal("Statement");
- NonTerminal Statements = new NonTerminal("Statements");
-
- //Block
- NonTerminal blockStatement = new NonTerminal("CompoundStatement");
- #endregion
-
- #region 2.4 Program and Functions
- NonTerminal Prog = new NonTerminal("Prog");
- NonTerminal anything = new NonTerminal("anything"); // temporary hack
- NonTerminal declaration = new NonTerminal("declaration");
- NonTerminal classDecl = new NonTerminal("class decl");
- NonTerminal memberDecl = new NonTerminal("member decl");
- NonTerminal fieldDecl = new NonTerminal("field declaration");
- NonTerminal idType = new NonTerminal("identifier type");
- NonTerminal typeDecl = new NonTerminal("type reference");
- NonTerminal methodDecl = new NonTerminal("method declaration");
- NonTerminal formalParameters = new NonTerminal("formals");
- NonTerminal methodSpec = new NonTerminal("method spec");
- NonTerminal formalsList = new NonTerminal("ParamaterListOpt");
- NonTerminal functionDecl = new NonTerminal("function declaration");
- NonTerminal predicateDecl = new NonTerminal("predicate declaration");
- NonTerminal invariantDecl = new NonTerminal("invariant declaration");
- NonTerminal Semi = new NonTerminal("semi");
- NonTerminal Rhs = new NonTerminal("right-hand side");
- NonTerminal FieldInit = new NonTerminal("field init");
- NonTerminal FieldInits = new NonTerminal("field inits");
- NonTerminal installBounds = new NonTerminal("installBounds");
- NonTerminal localVarStmt = new NonTerminal("localVarStmt");
- NonTerminal evalstate = new NonTerminal("evalstate");
- NonTerminal channelDecl = new NonTerminal("channel declaration");
- NonTerminal loopSpec = new NonTerminal("loop specification");
- NonTerminal rdPermArg = new NonTerminal("rdPermArg");
- #endregion
-
- #endregion
-
- #region 3. BNF rules
-
- Semi.Rule = semicolon;
-
- #region 3.1 Expressions
- selectExpr.Rule = (ToTerm("this") + ".").Q() + QualifiedName;
- evalstate.Rule =
- ident + ToTerm(".") +
- (ToTerm("acquire")
- | "release"
- | "fork" + FunctionExpression
- )
- ;
- rdPermArg.Rule = ToTerm("*") | expression;
-
- expression.Rule = ToTerm("true")
- | "false"
- | "null"
- | "maxlock"
- | "lockbottom"
- | "this"
- | "result"
- | s
- | n
- | QualifiedName
- // The following is needed: to parse "A<B ..." either as comparison or as beginning of GenericsPostfix
- | QualifiedName + less + expression
- //| QualifiedName + less + QualifiedName + greater
- //| NewStmt
- | NewArrStmt
- | ArrayExpression
- | FunctionExpression
- | ArrayConstructor
- | MObjectConstructor
- | expression + BinOp + expression
- | LUnOp + expression
- | expression + RUnOp
- | LMb + declaration.Star() + RMb
- | LParen + expression + RParen
- | ToTerm("unfolding") + expression + "in" + expression
- | ToTerm("acc") + "(" + selectExpr + (("," + expression) | Empty) + ")"
- | ToTerm("old") + "(" + expression + ")"
- | ToTerm("eval") + "(" + evalstate + "," + expression + ")"
- | ToTerm("credit") + "(" + expression + "," + expression + ")"
- | ToTerm("credit") + "(" + expression + ")"
- | expression + PreferShiftHere() + "?" + expression + ":" + expression
- | ToTerm("rd") +
- (ToTerm("holds") + "(" + expression + ")"
- | "(" + selectExpr + rdPermArg.Q() + ")"
- )
-
- ;
- expressionList.Rule = MakePlusRule(expressionList, comma, expression);
- identList.Rule = MakePlusRule(identList, comma, ident);
- NewStmt.Rule = "new" + QualifiedName + GenericsPostfix.Q() + LParen + expressionList.Q() + RParen;
- NewArrStmt.Rule = "new" + QualifiedName + GenericsPostfix.Q() + LBracket + expressionList.Q() + RBracket;
- BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "%" | "^" | "&" | "|"
- | "&&" | "||" | "==" | "!=" | greater | less
- | ">=" | "<=" | "is"
- | "=" | "+=" | "-="
- | "."
- | "==>" | "<==>" | "<<"
- | "=" // this is for datatype declarations, not an operator
- ;
-
- LUnOp.Rule = ToTerm("-") | "~" | "!";
- RUnOp.Rule = ToTerm("++") | "--";
-
- ArrayConstructor.Rule = LBracket + expressionList + RBracket;
- MObjectConstructor.Rule = LBracket + ident + arrow + expression + MObjectList.Star() + RBracket;
- MObjectList.Rule = comma + ident + arrow + expression;
- #endregion
-
- #region 3.2 QualifiedName
- ArrayExpression.Rule = QualifiedName + LBracket + expressionList + RBracket;
- FunctionExpression.Rule = QualifiedName + LParen + expressionList.Q() + RParen;
-
- QualifiedName.Rule = ident | QualifiedName + dot + ident;
-
-
- GenericsPostfix.Rule = less + QualifiedName + greater;
-
- //ExprList.Rule = Expr.Plus(comma);
- #endregion
-
- #region 3.3 Statement
- Condition.Rule = LParen + expression + RParen;
- installBounds.Rule
- = "installBounds"
- //= ToTerm("between") + expressionList + "and" + expressionList
- //| "below" + expressionList
- //| "below" + expressionList + "above" + expressionList
- //| "above" + expressionList
- //| "above" + expressionList + "below" + expressionList
- ;
- FieldInit.Rule
- = ident + ":=" + expression
- ;
- FieldInits.Rule = MakeStarRule(FieldInits, ToTerm(","), FieldInit);
- Rhs.Rule
- = ToTerm("new") + ident
- | ToTerm("new") + ident + "{" + FieldInits + "}"
- | ToTerm("new") + ident + installBounds
- | ToTerm("new") + ident + "{" + FieldInits + "}" + installBounds
- | expression
- ;
- localVarStmt.Rule
- = idType + ":=" + Rhs + Semi
- | idType + Semi
- ;
- loopSpec.Rule
- = ToTerm("invariant") + expression + Semi
- | "lockchange" + expressionList + Semi
- ;
-
-
-
- Statement.Rule = Semi
- | "if" + Condition + Statement
- | "if" + Condition + Statement + PreferShiftHere() + "else" + Statement
- | "while" + Condition + loopSpec.Star() + Statement
- | "for" + LParen + expression.Q() + Semi + expression.Q() + Semi + expression.Q() + RParen + Statement
- | blockStatement
- | expression + Semi
- | "break" + Semi
- | QualifiedName + ":=" + Rhs
-
- | "var" + localVarStmt
-
- | "assert" + expression + Semi
- | "assume" + expression + Semi
-
- ;
- Statements.Rule = MakeStarRule(Statements, null, Statement);
- blockStatement.Rule = LCurly + Statements + RCurly;
-
-
- #endregion
-
- #region 3.4 Prog
- Prog.Rule = anything.Star() + Eof;
-
- anything.Rule
- = ToTerm("class")
- | "ghost"
- | "static"
- | "var"
- | "method"
- | "constructor"
- | "datatype"
- | "codatatype"
- | "type"
- | "iterator"
- | "assert"
- | "assume"
- | "new"
- | "this"
- | "object"
- | "refines"
- | "module"
- | "import"
- | "default"
- | "opened"
- | "as"
- | "if"
- | "then"
- | "else"
- | "while"
- | "invariant"
- | "break"
- | "label"
- | "return"
- | "yield"
- | "parallel"
- | "calc"
- | "print"
- | "returns"
- | "yields"
- | "requires"
- | "ensures"
- | "modifies"
- | "reads"
- | "decreases"
- | "bool"
- | "nat"
- | "int"
- | "false"
- | "true"
- | "null"
- | "function"
- | "predicate"
- | "copredicate"
- | "free"
- | "in"
- | "forall"
- | "exists"
- | "seq"
- | "set"
- | "map"
- | "multiset"
- | "array"
- | "array2"
- | "array3"
- | "match"
- | "case"
- | "fresh"
- | "old"
- | "choose"
- | "where"
- | ident
- | "}"
- | "{"
- | "("
- | ")"
- | "["
- | "]"
- | ","
- | ":"
- | ";"
- | "=" // this is for datatype declarations, not an operator
- | "."
- | "`"
- | "=="
- | "!="
- | "<"
- | "<="
- | ">="
- | ">"
- | "=>"
- | ":="
- | "+"
- | "-"
- | "*"
- | "/"
- | "%"
- | "!!"
- | "|"
- | "!"
- | "&&"
- | "||"
- | "==>"
- | "<==>"
- | "#"
- | n
- | stringLiteral
- ;
-
- Terminal Comment = new CommentTerminal("Comment", "/*", "*/");
- NonGrammarTerminals.Add(Comment);
- Terminal LineComment = new CommentTerminal("LineComment", "//", "\n");
- NonGrammarTerminals.Add(LineComment);
- #endregion
- #endregion
-
- #region 4. Set starting symbol
- this.Root = Prog; // Set grammar root
- #endregion
-
- #region 5. Operators precedence
- // not used
- #endregion
-
- #region 6. Punctuation symbols
- RegisterPunctuation("(", ")", "[", "]", "{", "}", ",", ";");
- #endregion
- }
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Guids.cs b/Util/VS2010/Dafny/DafnyLanguageService/Guids.cs
deleted file mode 100644
index 61ea05d4..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Guids.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace Demo
-{
- static class GuidList
- {
- public const string guidIronyLanguageServiceString = "1F9687D0-937C-428E-ACFF-A7622A14100C";
- public const string guidIronyLanguageServicePkgString = "F85E7515-4CA6-42A5-86E0-D2312AE91D23";
- public const string guidIronyLanguageServiceCmdSetString = "68251AE3-0205-4FC9-8B12-D4C3EA9F8D6C";
-
- public static readonly Guid guidIronyLanguageServiceCmdSet = new Guid(guidIronyLanguageServiceCmdSetString);
- };
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/AuthoringScope.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/AuthoringScope.cs
deleted file mode 100644
index 9a49dbe4..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/AuthoringScope.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class AuthoringScope : Microsoft.VisualStudio.Package.AuthoringScope
- {
- public AuthoringScope(object parseResult)
- {
- this.parseResult = parseResult;
-
- // how should this be set?
- this.resolver = new Resolver();
- }
-
- object parseResult;
- IASTResolver resolver;
-
- // ParseReason.QuickInfo
- public override string GetDataTipText(int line, int col, out TextSpan span)
- {
- span = new TextSpan();
- return null;
- }
-
- // ParseReason.CompleteWord
- // ParseReason.DisplayMemberList
- // ParseReason.MemberSelect
- // ParseReason.MemberSelectAndHilightBraces
- public override Microsoft.VisualStudio.Package.Declarations GetDeclarations(IVsTextView view, int line, int col, TokenInfo info, ParseReason reason)
- {
- IList<Declaration> declarations;
- switch (reason)
- {
- case ParseReason.CompleteWord:
- declarations = resolver.FindCompletions(parseResult, line, col);
- break;
- case ParseReason.DisplayMemberList:
- case ParseReason.MemberSelect:
- case ParseReason.MemberSelectAndHighlightBraces:
- declarations = resolver.FindMembers(parseResult, line, col);
- break;
- default:
- throw new ArgumentException("reason");
- }
-
- return new Declarations(declarations);
- }
-
- // ParseReason.GetMethods
- public override Microsoft.VisualStudio.Package.Methods GetMethods(int line, int col, string name)
- {
- return new Methods(resolver.FindMethods(parseResult, line, col, name));
- }
-
- // ParseReason.Goto
- public override string Goto(VSConstants.VSStd97CmdID cmd, IVsTextView textView, int line, int col, out TextSpan span)
- {
- span = new TextSpan();
- return null;
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Configuration.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Configuration.cs
deleted file mode 100644
index f7412393..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Configuration.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Microsoft.VisualStudio.Package;
-using Microsoft.VisualStudio.TextManager.Interop;
-
-namespace Demo
-{
- public static partial class Configuration
- {
- public static Grammar Grammar = new Grammar();
- static List<Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem> colorableItems = new List<Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem>();
-
- public static IList<Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem> ColorableItems
- {
- get { return colorableItems; }
- }
-
- public static TokenColor CreateColor(string name, COLORINDEX foreground, COLORINDEX background)
- {
- return CreateColor(name, foreground, background, false, false);
- }
-
- public static TokenColor CreateColor(string name, COLORINDEX foreground, COLORINDEX background, bool bold, bool strikethrough)
- {
- colorableItems.Add(new ColorableItem(name, foreground, background, bold, strikethrough));
- return (TokenColor)colorableItems.Count;
- }
-
- public static void ColorToken(string tokenName, TokenType type, TokenColor color, TokenTriggers trigger)
- {
- definitions[tokenName] = new TokenDefinition(type, color, trigger);
- }
-
- public static TokenDefinition GetDefinition(string tokenName)
- {
- TokenDefinition result;
- return definitions.TryGetValue(tokenName, out result) ? result : defaultDefinition;
- }
-
- private static TokenDefinition defaultDefinition = new TokenDefinition(TokenType.Text, TokenColor.Text, TokenTriggers.None);
- private static Dictionary<string, TokenDefinition> definitions = new Dictionary<string, TokenDefinition>();
-
- public struct TokenDefinition
- {
- public TokenDefinition(TokenType type, TokenColor color, TokenTriggers triggers)
- {
- this.TokenType = type;
- this.TokenColor = color;
- this.TokenTriggers = triggers;
- }
-
- public TokenType TokenType;
- public TokenColor TokenColor;
- public TokenTriggers TokenTriggers;
- }
- }
-
- public class ColorableItem : Microsoft.VisualStudio.TextManager.Interop.IVsColorableItem
- {
- private string displayName;
- private COLORINDEX background;
- private COLORINDEX foreground;
- private uint fontFlags = (uint)FONTFLAGS.FF_DEFAULT;
-
- public ColorableItem(string displayName, COLORINDEX foreground, COLORINDEX background, bool bold, bool strikethrough)
- {
- this.displayName = displayName;
- this.background = background;
- this.foreground = foreground;
-
- if (bold)
- this.fontFlags = this.fontFlags | (uint)FONTFLAGS.FF_BOLD;
- if (strikethrough)
- this.fontFlags = this.fontFlags | (uint)FONTFLAGS.FF_STRIKETHROUGH;
- }
-
- #region IVsColorableItem Members
- public int GetDefaultColors(COLORINDEX[] piForeground, COLORINDEX[] piBackground)
- {
- if (null == piForeground)
- {
- throw new ArgumentNullException("piForeground");
- }
- if (0 == piForeground.Length)
- {
- throw new ArgumentOutOfRangeException("piForeground");
- }
- piForeground[0] = foreground;
-
- if (null == piBackground)
- {
- throw new ArgumentNullException("piBackground");
- }
- if (0 == piBackground.Length)
- {
- throw new ArgumentOutOfRangeException("piBackground");
- }
- piBackground[0] = background;
-
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
-
- public int GetDefaultFontFlags(out uint pdwFontFlags)
- {
- pdwFontFlags = this.fontFlags;
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
-
- public int GetDisplayName(out string pbstrName)
- {
- pbstrName = displayName;
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
- #endregion
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Declaration.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Declaration.cs
deleted file mode 100644
index c0fda5ca..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Declaration.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Demo
-{
- public struct Declaration : IComparable<Declaration>
- {
- public Declaration(string description, string displayText, int glyph, string name)
- {
- this.Description = description;
- this.DisplayText = displayText;
- this.Glyph = glyph;
- this.Name = name;
- }
-
- public string Description;
- public string DisplayText;
- public int Glyph;
- public string Name;
-
- #region IComparable<Declaration> Members
-
- public int CompareTo(Declaration other)
- {
- return DisplayText.CompareTo(other.DisplayText);
- }
-
- #endregion
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Declarations.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Declarations.cs
deleted file mode 100644
index 98a411ce..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Declarations.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-This code is licensed under the Visual Studio SDK license terms.
-THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
-***************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class Declarations : Microsoft.VisualStudio.Package.Declarations
- {
- IList<Declaration> declarations;
- public Declarations(IList<Declaration> declarations)
- {
- this.declarations = declarations;
- }
-
- public override int GetCount()
- {
- return declarations.Count;
- }
-
- public override string GetDescription(int index)
- {
- return declarations[index].Description;
- }
-
- public override string GetDisplayText(int index)
- {
- return declarations[index].DisplayText;
- }
-
- public override int GetGlyph(int index)
- {
- return declarations[index].Glyph;
- }
-
- public override string GetName(int index)
- {
- if (index >= 0)
- return declarations[index].Name;
-
- return null;
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IASTResolver.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/IASTResolver.cs
deleted file mode 100644
index 8de1a454..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IASTResolver.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Demo
-{
- interface IASTResolver
- {
- IList<Declaration> FindCompletions(object result, int line, int col);
- IList<Declaration> FindMembers(object result, int line, int col);
- string FindQuickInfo(object result, int line, int col);
- IList<Method> FindMethods(object result, int line, int col, string name);
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs
deleted file mode 100644
index ce43e6e4..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs
+++ /dev/null
@@ -1,373 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-using Irony.Parsing;
-using Irony.Ast;
-
-using System.IO;
-
-namespace Demo
-{
- public class IronyLanguageService : Microsoft.VisualStudio.Package.LanguageService
- {
- private Grammar grammar;
- private Parser parser;
- private ParsingContext context;
-
- public IronyLanguageService()
- {
- grammar = new Grammar();
- parser = new Parser(Configuration.Grammar);
- context = new ParsingContext(parser);
- }
-
-
- #region Custom Colors
- public override int GetColorableItem(int index, out IVsColorableItem item)
- {
- if (index <= Configuration.ColorableItems.Count)
- {
- item = Configuration.ColorableItems[index - 1];
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
- else
- {
- throw new ArgumentNullException("index");
- }
- }
-
- public override int GetItemCount(out int count)
- {
- count = Configuration.ColorableItems.Count;
- return Microsoft.VisualStudio.VSConstants.S_OK;
- }
- #endregion
-
- #region MPF Accessor and Factory specialisation
- private LanguagePreferences preferences;
- public override LanguagePreferences GetLanguagePreferences()
- {
- if (this.preferences == null)
- {
- this.preferences = new LanguagePreferences(this.Site,
- typeof(IronyLanguageService).GUID,
- this.Name);
- this.preferences.Init();
- }
-
- return this.preferences;
- }
-
- public override Microsoft.VisualStudio.Package.Source CreateSource(IVsTextLines buffer)
- {
- return new Source(this, buffer, this.GetColorizer(buffer));
- }
-
- private IScanner scanner;
- public override IScanner GetScanner(IVsTextLines buffer)
- {
- if (scanner == null)
- this.scanner = new LineScanner(grammar);
-
- return this.scanner;
- }
- #endregion
-
- public override void OnIdle(bool periodic)
- {
- // from IronPythonLanguage sample
- // this appears to be necessary to get a parse request with ParseReason = Check?
- Source src = (Source)GetSource(this.LastActiveTextView);
- if (src != null && src.LastParseTime >= Int32.MaxValue >> 12)
- {
- src.LastParseTime = 0;
- }
- base.OnIdle(periodic);
- }
-
- public override Microsoft.VisualStudio.Package.AuthoringScope ParseSource(ParseRequest req)
- {
- Debug.Print("ParseSource at ({0}:{1}), reason {2}", req.Line, req.Col, req.Reason);
- Source source = (Source)this.GetSource(req.FileName);
- switch (req.Reason)
- {
- case ParseReason.Check:
- // This is where you perform your syntax highlighting.
- // Parse entire source as given in req.Text.
- // Store results in the AuthoringScope object.
- var parsed = parser.Parse(req.Text, req.FileName);
- var root = parsed.Root;
- if (root != null) {
-
- AstNode node = (AstNode)root.AstNode;
- source.ParseResult = node;
- }
-
- // Used for brace matching.
- TokenStack braces = parser.Context.OpenBraces;
- foreach (Token brace in braces) {
- if (brace.OtherBrace == null) continue;
- TextSpan openBrace = new TextSpan();
- openBrace.iStartLine = brace.Location.Line;
- openBrace.iStartIndex = brace.Location.Column;
- openBrace.iEndLine = brace.Location.Line;
- openBrace.iEndIndex = openBrace.iStartIndex + brace.Length;
-
- TextSpan closeBrace = new TextSpan();
- closeBrace.iStartLine = brace.OtherBrace.Location.Line;
- closeBrace.iStartIndex = brace.OtherBrace.Location.Column;
- closeBrace.iEndLine = brace.OtherBrace.Location.Line;
- closeBrace.iEndIndex = closeBrace.iStartIndex + brace.OtherBrace.Length;
-
- if (source.Braces == null) {
- source.Braces = new List<TextSpan[]>();
- }
- source.Braces.Add(new TextSpan[2] { openBrace, closeBrace });
- }
-
- if (parser.Context.CurrentParseTree.ParserMessages.Count > 0) {
- foreach (ParserMessage error in parser.Context.CurrentParseTree.ParserMessages) {
- TextSpan span = new TextSpan();
- span.iStartLine = span.iEndLine = error.Location.Line - 1;
- span.iStartIndex = error.Location.Column;
- span.iEndIndex = error.Location.Position;
- req.Sink.AddError(req.FileName, error.Message, span, Severity.Error);
- }
- } else { // parse looks okay, send it to Dafny.
- if (!File.Exists(@"C:\tmp\StartDafny.bat")) {
- AddErrorBecauseOfToolProblems(req, @"Can't find C:\tmp\StartDafny.bat");
- } else {
-
- // From: http://dotnetperls.com/process-redirect-standard-output
- // (Also, see: http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx)
- //
- // Setup the process with the ProcessStartInfo class.
- //
- ProcessStartInfo start = new ProcessStartInfo();
- start.FileName = @"cmd.exe";
- start.Arguments = @"/c C:\tmp\StartDafny.bat"; // Specify exe name.
- start.UseShellExecute = false;
- start.RedirectStandardInput = true;
- start.RedirectStandardOutput = true;
- start.CreateNoWindow = true;
- //start.WindowStyle = ProcessWindowStyle.Minimized; // need this or else you see the window pop up
- //
- // Start the process.
- //
- using (Process process = Process.Start(start)) {
- //
- // Push the file contents to the new process
- //
- StreamWriter myStreamWriter = process.StandardInput;
- myStreamWriter.WriteLine(req.Text);
- myStreamWriter.Close();
- //
- // Read in all the text from the process with the StreamReader.
- //
- using (StreamReader reader = process.StandardOutput) {
- //string result = reader.ReadToEnd();
- //Console.Write(result);
-
- for (string line = reader.ReadLine(); line != null; line = reader.ReadLine()) {
- // the lines of interest have the form "filename(line,col): some_error_label: error_message"
- // where "some_error_label" is "Error" or "syntax error" or "Error BP5003" or "Related location"
- if (line.Equals("")) continue;
- if (line.StartsWith("Dafny program verifier finished with"))
- {
- if (line.Contains("time out"))
- {
- AddErrorBecauseOfToolProblems(req, "Verification timed out.");
- }
- else
- {
- if (!line.Contains("inconclusive") && !line.Contains("out of memory"))
- {
- if (line.Contains(" 0 errors"))
- AddMessage(req, "Verification successful.");
- }
- else
- {
- AddErrorBecauseOfToolProblems(req, "Internal verification fault.");
- }
- }
- break;
- }
- string message;
- int n = line.IndexOf("): ", 2); // we start at 2, to avoid problems with "C:\..."
- if (n == -1) {
- continue;
- } else {
- int m = line.IndexOf(": ", n + 3);
- if (m == -1) {
- continue;
- }
- message = line.Substring(m + 2);
- }
- line = line.Substring(0, n); // line now has the form "filename(line,col"
-
- n = line.LastIndexOf(',');
- if (n == -1) { continue; }
- var colString = line.Substring(n + 1);
- line = line.Substring(0, n); // line now has the form "filename(line"
-
- n = line.LastIndexOf('(');
- if (n == -1) { continue; }
- var lineString = line.Substring(n + 1);
-
- try {
- TextSpan span = new TextSpan();
- span.iStartLine = span.iEndLine = Int32.Parse(lineString) - 1;
- span.iStartIndex = Int32.Parse(colString) - 1;
- span.iEndIndex = span.iStartIndex + 5; // hack
- req.Sink.AddError(req.FileName, message, span, Severity.Error);
- } catch (System.FormatException) {
- continue;
- } catch (System.OverflowException) {
- continue;
- }
- }
- }
- }
- }
- }
-
- break;
-
- case ParseReason.DisplayMemberList:
- // Parse the line specified in req.Line for the two
- // tokens just before req.Col to obtain the identifier
- // and the member connector symbol.
- // Examine existing parse tree for members of the identifer
- // and return a list of members in your version of the
- // Declarations class as stored in the AuthoringScope
- // object.
- break;
-
- case ParseReason.MethodTip:
- // Parse the line specified in req.Line for the token
- // just before req.Col to obtain the name of the method
- // being entered.
- // Examine the existing parse tree for all method signatures
- // with the same name and return a list of those signatures
- // in your version of the Methods class as stored in the
- // AuthoringScope object.
- break;
-
- case ParseReason.HighlightBraces:
- case ParseReason.MemberSelectAndHighlightBraces:
- if (source.Braces != null)
- {
- foreach (TextSpan[] brace in source.Braces)
- {
- if (brace.Length == 2)
- req.Sink.MatchPair(brace[0], brace[1], 1);
- else if (brace.Length >= 3)
- req.Sink.MatchTriple(brace[0], brace[1], brace[2], 1);
- }
- }
- break;
- }
-
- return new AuthoringScope(source.ParseResult);
- }
-
- private static void AddErrorBecauseOfToolProblems(ParseRequest req, string msg)
- {
- TextSpan span = new TextSpan();
- span.iStartLine = span.iEndLine = 0;
- span.iStartIndex = 0;
- span.iEndIndex = 0;
- req.Sink.AddError(req.FileName, msg, span, Severity.Error);
- }
- private static void AddMessage(ParseRequest req, string msg)
- {
- TextSpan span = new TextSpan();
- span.iStartLine = span.iEndLine = 0;
- span.iStartIndex = 0;
- span.iEndIndex = 1;
- req.Sink.AddError(req.FileName, msg, span, Severity.Hint);
- }
-
- /// <summary>
- /// Called to determine if the given location can have a breakpoint applied to it.
- /// </summary>
- /// <param name="buffer">The IVsTextBuffer object containing the source file.</param>
- /// <param name="line">The line number where the breakpoint is to be set.</param>
- /// <param name="col">The offset into the line where the breakpoint is to be set.</param>
- /// <param name="pCodeSpan">
- /// Returns the TextSpan giving the extent of the code affected by the breakpoint if the
- /// breakpoint can be set.
- /// </param>
- /// <returns>
- /// If successful, returns S_OK; otherwise returns S_FALSE if there is no code at the given
- /// position or returns an error code (the validation is deferred until the debug engine is loaded).
- /// </returns>
- /// <remarks>
- /// <para>
- /// CAUTION: Even if you do not intend to support the ValidateBreakpointLocation but your language
- /// does support breakpoints, you must override the ValidateBreakpointLocation method and return a
- /// span that contains the specified line and column; otherwise, breakpoints cannot be set anywhere
- /// except line 1. You can return E_NOTIMPL to indicate that you do not otherwise support this
- /// method but the span must always be set. The example shows how this can be done.
- /// </para>
- /// <para>
- /// Since the language service parses the code, it generally knows what is considered code and what
- /// is not. Normally, the debug engine is loaded and the pending breakpoints are bound to the source. It is at this time the breakpoint location is validated. This method is a fast way to determine if a breakpoint can be set at a particular location without loading the debug engine.
- /// </para>
- /// <para>
- /// You can implement this method to call the ParseSource method with the parse reason of CodeSpan.
- /// The parser examines the specified location and returns a span identifying the code at that
- /// location. If there is code at the location, the span identifying that code should be passed to
- /// your implementation of the CodeSpan method in your version of the AuthoringSink class. Then your
- /// implementation of the ValidateBreakpointLocation method retrieves that span from your version of
- /// the AuthoringSink class and returns that span in the pCodeSpan argument.
- /// </para>
- /// <para>
- /// The base method returns E_NOTIMPL.
- /// </para>
- /// </remarks>
- public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan)
- {
- // TODO: Add code to not allow breakpoints to be placed on non-code lines.
- // TODO: Refactor to allow breakpoint locations to span multiple lines.
- if (pCodeSpan != null)
- {
- pCodeSpan[0].iStartLine = line;
- pCodeSpan[0].iStartIndex = col;
- pCodeSpan[0].iEndLine = line;
- pCodeSpan[0].iEndIndex = col;
- if (buffer != null)
- {
- int length;
- buffer.GetLengthOfLine(line, out length);
- pCodeSpan[0].iStartIndex = 0;
- pCodeSpan[0].iEndIndex = length;
- }
- return VSConstants.S_OK;
- }
- else
- {
- return VSConstants.S_FALSE;
- }
- }
-
- public override ViewFilter CreateViewFilter(CodeWindowManager mgr, IVsTextView newView)
- {
- return new IronyViewFilter(mgr, newView);
- }
-
- public override string Name
- {
- get { return Configuration.Name; }
- }
-
- public override string GetFormatFilterList()
- {
- return Configuration.FormatList;
- }
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyViewFilter.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyViewFilter.cs
deleted file mode 100644
index 55c3509e..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyViewFilter.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.VisualStudio.Package;
-using Microsoft.VisualStudio.TextManager.Interop;
-
-using VsCommands2K = Microsoft.VisualStudio.VSConstants.VSStd2KCmdID;
-
-namespace Demo
-{
- public class IronyViewFilter : ViewFilter
- {
- public IronyViewFilter(CodeWindowManager mgr, IVsTextView view)
- : base(mgr, view)
- {
-
- }
-
- public override void HandlePostExec(ref Guid guidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut, bool bufferWasChanged)
- {
- if (guidCmdGroup == typeof(VsCommands2K).GUID)
- {
- VsCommands2K cmd = (VsCommands2K)nCmdId;
- switch (cmd)
- {
- case VsCommands2K.UP:
- case VsCommands2K.UP_EXT:
- case VsCommands2K.UP_EXT_COL:
- case VsCommands2K.DOWN:
- case VsCommands2K.DOWN_EXT:
- case VsCommands2K.DOWN_EXT_COL:
- Source.OnCommand(TextView, cmd, '\0');
- return;
- }
- }
-
-
- base.HandlePostExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut, bufferWasChanged);
- }
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/LineScanner.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/LineScanner.cs
deleted file mode 100644
index 966e9c43..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/LineScanner.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-using Microsoft.VisualStudio.Package;
-using Irony.Parsing;
-
-namespace Demo
-{
- public class LineScanner : IScanner
- {
- private Parser parser;
-
- public LineScanner(Grammar grammar)
- {
- this.parser = new Parser(grammar);
- this.parser.Context.Mode = ParseMode.VsLineScan;
- }
-
- public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state)
- {
- // Reads each token in a source line and performs syntax coloring. It will continue to
- // be called for the source until false is returned.
- Token token = parser.Scanner.VsReadToken(ref state);
-
- // !EOL and !EOF
- if (token != null && token.Terminal != Grammar.CurrentGrammar.Eof && token.Category != TokenCategory.Error)
- {
- tokenInfo.StartIndex = token.Location.Position;
- tokenInfo.EndIndex = tokenInfo.StartIndex + token.Length - 1;
- if (token.EditorInfo != null) {
- tokenInfo.Color = (Microsoft.VisualStudio.Package.TokenColor)token.EditorInfo.Color;
- tokenInfo.Type = (Microsoft.VisualStudio.Package.TokenType)token.EditorInfo.Type;
- }
-
- if (token.KeyTerm != null && token.KeyTerm.EditorInfo != null)
- {
- tokenInfo.Trigger =
- (Microsoft.VisualStudio.Package.TokenTriggers)token.KeyTerm.EditorInfo.Triggers;
- }
- else
- {
- if (token.EditorInfo != null) {
- tokenInfo.Trigger =
- (Microsoft.VisualStudio.Package.TokenTriggers)token.EditorInfo.Triggers;
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- public void SetSource(string source, int offset)
- {
- // Stores line of source to be used by ScanTokenAndProvideInfoAboutIt.
- parser.Scanner.VsSetSource(source, offset);
- }
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Method.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Method.cs
deleted file mode 100644
index c5071612..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Method.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Demo
-{
- public struct Method
- {
- public string Name;
- public string Description;
- public string Type;
- public IList<Parameter> Parameters;
- }
-
- public struct Parameter
- {
- public string Name;
- public string Display;
- public string Description;
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Methods.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Methods.cs
deleted file mode 100644
index 1d7c124f..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Methods.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class Methods : Microsoft.VisualStudio.Package.Methods
- {
- IList<Method> methods;
- public Methods(IList<Method> methods)
- {
- this.methods = methods;
- }
-
- public override int GetCount()
- {
- return methods.Count;
- }
-
- public override string GetName(int index)
- {
- return methods[index].Name;
- }
-
- public override string GetDescription(int index)
- {
- return methods[index].Description;
- }
-
- public override string GetType(int index)
- {
- return methods[index].Type;
- }
-
- public override int GetParameterCount(int index)
- {
- return (methods[index].Parameters == null) ? 0 : methods[index].Parameters.Count;
- }
-
- public override void GetParameterInfo(int index, int paramIndex, out string name, out string display, out string description)
- {
- Parameter parameter = methods[index].Parameters[paramIndex];
- name = parameter.Name;
- display = parameter.Display;
- description = parameter.Description;
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Package.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Package.cs
deleted file mode 100644
index dc1244d6..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Package.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-using Microsoft.VisualStudio.OLE.Interop;
-using MPF = Microsoft.VisualStudio.Package;
-using System.ComponentModel.Design;
-
-namespace Demo
-{
- public class IronyPackage : Microsoft.VisualStudio.Shell.Package, IOleComponent
- {
- uint componentID = 0;
- public IronyPackage()
- {
- ServiceCreatorCallback callback = new ServiceCreatorCallback(
- delegate(IServiceContainer container, Type serviceType)
- {
- if (typeof(IronyLanguageService) == serviceType)
- {
- IronyLanguageService language = new IronyLanguageService();
- language.SetSite(this);
-
- // register for idle time callbacks
- IOleComponentManager mgr = GetService(typeof(SOleComponentManager)) as IOleComponentManager;
- if (componentID == 0 && mgr != null)
- {
- OLECRINFO[] crinfo = new OLECRINFO[1];
- crinfo[0].cbSize = (uint)Marshal.SizeOf(typeof(OLECRINFO));
- crinfo[0].grfcrf = (uint)_OLECRF.olecrfNeedIdleTime |
- (uint)_OLECRF.olecrfNeedPeriodicIdleTime;
- crinfo[0].grfcadvf = (uint)_OLECADVF.olecadvfModal |
- (uint)_OLECADVF.olecadvfRedrawOff |
- (uint)_OLECADVF.olecadvfWarningsOff;
- crinfo[0].uIdleTimeInterval = 300;
- int hr = mgr.FRegisterComponent(this, crinfo, out componentID);
- }
-
- return language;
- }
- else
- {
- return null;
- }
- });
-
- // proffer the LanguageService
- (this as IServiceContainer).AddService(typeof(IronyLanguageService), callback, true);
- }
-
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (componentID != 0)
- {
- IOleComponentManager mgr = GetService(typeof(SOleComponentManager)) as IOleComponentManager;
- if (mgr != null)
- {
- mgr.FRevokeComponent(componentID);
- }
- componentID = 0;
- }
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
-
- #region IOleComponent Members
- public int FContinueMessageLoop(uint uReason, IntPtr pvLoopData, MSG[] pMsgPeeked)
- {
- return 1;
- }
-
- public int FDoIdle(uint grfidlef)
- {
- IronyLanguageService ls = GetService(typeof(IronyLanguageService)) as IronyLanguageService;
-
- if (ls != null)
- {
- ls.OnIdle((grfidlef & (uint)_OLEIDLEF.oleidlefPeriodic) != 0);
- }
-
- return 0;
- }
-
- public int FPreTranslateMessage(MSG[] pMsg)
- {
- return 0;
- }
-
- public int FQueryTerminate(int fPromptUser)
- {
- return 1;
- }
-
- public int FReserved1(uint dwReserved, uint message, IntPtr wParam, IntPtr lParam)
- {
- return 1;
- }
-
- public IntPtr HwndGetWindow(uint dwWhich, uint dwReserved)
- {
- return IntPtr.Zero;
- }
-
- public void OnActivationChange(IOleComponent pic, int fSameComponent, OLECRINFO[] pcrinfo, int fHostIsActivating, OLECHOSTINFO[] pchostinfo, uint dwReserved)
- {
- }
-
- public void OnAppActivate(int fActive, uint dwOtherThreadID)
- {
- }
-
- public void OnEnterState(uint uStateID, int fEnter)
- {
- }
-
- public void OnLoseActivation()
- {
- }
-
- public void Terminate()
- {
- }
- #endregion
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Resolver.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Resolver.cs
deleted file mode 100644
index 9f6ddeba..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Resolver.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Irony.Parsing;
-
-namespace Demo
-{
- public class Resolver : Demo.IASTResolver
- {
- #region IASTResolver Members
-
-
- public IList<Demo.Declaration> FindCompletions(object result, int line, int col)
- {
- // Used for intellisense.
- List<Demo.Declaration> declarations = new List<Demo.Declaration>();
-
- // Add keywords defined by grammar
- foreach (KeyTerm key in Configuration.Grammar.KeyTerms.Values)
- {
- if(key.OptionIsSet(TermOptions.IsKeyword))
- {
- declarations.Add(new Declaration("", key.Name, 206, key.Name));
- }
- }
-
- declarations.Sort();
- return declarations;
- }
-
- public IList<Demo.Declaration> FindMembers(object result, int line, int col)
- {
- List<Demo.Declaration> members = new List<Demo.Declaration>();
-
- return members;
- }
-
- public string FindQuickInfo(object result, int line, int col)
- {
- return "unknown";
- }
-
- public IList<Demo.Method> FindMethods(object result, int line, int col, string name)
- {
- return new List<Demo.Method>();
- }
-
- #endregion
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Source.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/Source.cs
deleted file mode 100644
index 418bec01..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/Source.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-This code is licensed under the Visual Studio SDK license terms.
-THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
-***************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Package;
-
-namespace Demo
-{
- public class Source : Microsoft.VisualStudio.Package.Source
- {
- public Source(LanguageService service, IVsTextLines textLines, Colorizer colorizer)
- : base(service, textLines, colorizer)
- {
- }
-
- private object parseResult;
- public object ParseResult
- {
- get { return parseResult; }
- set { parseResult = value; }
- }
-
- private IList<TextSpan[]> braces;
- public IList<TextSpan[]> Braces
- {
- get { return braces; }
- set { braces = value; }
- }
- }
-} \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/IronyLanguageServicePackage.cs b/Util/VS2010/Dafny/DafnyLanguageService/IronyLanguageServicePackage.cs
deleted file mode 100644
index 29371f91..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/IronyLanguageServicePackage.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-// VsPkg.cs : Implementation of IronyLanguageService
-//
-
-using System;
-using System.Diagnostics;
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.ComponentModel.Design;
-using Microsoft.Win32;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.OLE.Interop;
-using Microsoft.VisualStudio.Shell;
-
-namespace Demo
-{
- /// <summary>
- /// This is the class that implements the package exposed by this assembly.
- ///
- /// The minimum requirement for a class to be considered a valid package for Visual Studio
- /// is to implement the IVsPackage interface and register itself with the shell.
- /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
- /// to do it: it derives from the Package class that provides the implementation of the
- /// IVsPackage interface and uses the registration attributes defined in the framework to
- /// register itself and its components with the shell.
- /// </summary>
- // This attribute tells the registration utility (regpkg.exe) that this class needs
- // to be registered as package.
- [PackageRegistration(UseManagedResourcesOnly = true)]
- // A Visual Studio component can be registered under different regitry roots; for instance
- // when you debug your package you want to register it in the experimental hive. This
- // attribute specifies the registry root to use if no one is provided to regpkg.exe with
- // the /root switch.
- [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\10.0Exp")]
- // This attribute is used to register the informations needed to show the this package
- // in the Help/About dialog of Visual Studio.
- [InstalledProductRegistration(/*false,*/ "#110", "#112", "1.0", IconResourceID = 400)]
- // This attribute will make your language service accessible by other packages installed.
- [ProvideService(typeof(IronyLanguageService))]
- // This attribute(s) associates file extensions with your language service.
- [ProvideLanguageExtension(typeof(IronyLanguageService), ".dfy")]
-
- // This attributes informs Visual Studio that this package provides a langauge service and
- // which features are implemented.
- [ProvideLanguageService(typeof(IronyLanguageService), Configuration.Name, 0,
- CodeSense = true,
- EnableCommenting = true,
- MatchBraces = true,
- MatchBracesAtCaret = true,
- ShowMatchingBrace = true,
- AutoOutlining = true)]
- // In order be loaded inside Visual Studio in a machine that has not the VS SDK installed,
- // package needs to have a valid load key (it can be requested at
- // http://msdn.microsoft.com/vstudio/extend/). This attributes tells the shell that this
- // package has a load key embedded in its resources.
- [ProvideLoadKey("Standard", "1.0", "Dafny", "Demo", 104)]
- [Guid(GuidList.guidIronyLanguageServicePkgString)]
- public sealed class DafnyLanguageService : IronyPackage
- {
- /// <summary>
- /// Default constructor of the package.
- /// Inside this method you can place any initialization code that does not require
- /// any Visual Studio service because at this point the package object is created but
- /// not sited yet inside Visual Studio environment. The place to do all the other
- /// initialization is the Initialize method.
- /// </summary>
- public DafnyLanguageService()
- {
- Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Overriden Package Implementation
- #region Package Members
-
- /// <summary>
- /// Initialization of the package; this method is called right after the package is sited, so this is the place
- /// where you can put all the initilaization code that rely on services provided by VisualStudio.
- /// </summary>
- protected override void Initialize()
- {
- Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
- base.Initialize();
-
- }
- #endregion
-
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Key.snk b/Util/VS2010/Dafny/DafnyLanguageService/Key.snk
deleted file mode 100644
index f80a4ceb..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Key.snk
+++ /dev/null
Binary files differ
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Properties/AssemblyInfo.cs b/Util/VS2010/Dafny/DafnyLanguageService/Properties/AssemblyInfo.cs
deleted file mode 100644
index 118d4488..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Reflection;
-using System.Resources;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Package Name")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Company")]
-[assembly: AssemblyProduct("Package Name")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-[assembly: CLSCompliant(false)]
-[assembly: NeutralResourcesLanguage("en-US")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-
-
-
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Resources.Designer.cs b/Util/VS2010/Dafny/DafnyLanguageService/Resources.Designer.cs
deleted file mode 100644
index 0ca81303..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Resources.Designer.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-// This code was generated by a tool.
-// Runtime Version:4.0.21006.1
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Demo {
- using System;
-
-
- /// <summary>
- /// A strongly-typed resource class, for looking up localized strings, etc.
- /// </summary>
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- /// <summary>
- /// Returns the cached ResourceManager instance used by this class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.DafnyLanguageService.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- /// <summary>
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
- }
-}
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Resources.resx b/Util/VS2010/Dafny/DafnyLanguageService/Resources.resx
deleted file mode 100644
index 03fef612..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Resources.resx
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- VS SDK Notes: This resx file contains the resources that will be consumed directly by your package.
- For example, if you chose to create a tool window, there is a resource with ID 'CanNotCreateWindow'. This
- is used in VsPkg.cs to determine the string to show the user if there is an error when attempting to create
- the tool window.
-
- Resources that are accessed directly from your package *by Visual Studio* are stored in the VSPackage.resx
- file.
--->
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-</root> \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Resources/Irony.dll b/Util/VS2010/Dafny/DafnyLanguageService/Resources/Irony.dll
deleted file mode 100644
index e2021a72..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/Resources/Irony.dll
+++ /dev/null
Binary files differ
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/VSPackage.resx b/Util/VS2010/Dafny/DafnyLanguageService/VSPackage.resx
deleted file mode 100644
index 68782536..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/VSPackage.resx
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <data name="104" xml:space="preserve">
- <value>Paste PLK Here</value>
- </data>
- <data name="110" xml:space="preserve">
- <value>Dafny</value>
- </data>
- <data name="112" xml:space="preserve">
- <value>Dafny Programming Language</value>
- </data>
-</root> \ No newline at end of file
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/source.extension.vsixmanifest b/Util/VS2010/Dafny/DafnyLanguageService/source.extension.vsixmanifest
deleted file mode 100644
index 58e160cd..00000000
--- a/Util/VS2010/Dafny/DafnyLanguageService/source.extension.vsixmanifest
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Vsix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
-
- <Identifier Id="DafnyService.MicrosoftResearch.A38156F6-63DF-4E3C-8D23-07D3DE0D3388">
- <Name>DafnyService</Name>
- <Author>Microsoft Research</Author>
- <Version>1.0</Version>
- <Description>Information about my package</Description>
- <Locale>1033</Locale>
- <!--<InstalledByMSI>false</InstalledByMSI>-->
- <SupportedProducts>
- <VisualStudio Version="10.0">
- <Edition>Pro</Edition>
- <Edition>VST_All</Edition>
- </VisualStudio>
- </SupportedProducts>
- <SupportedFrameworkRuntimeEdition MinVersion="2.0" MaxVersion="4.0" />
- </Identifier>
-
- <References/>
-
- <Content>
- <VsPackage>
- DafnyService.pkgdef
- </VsPackage>
- </Content>
-</Vsix>
diff --git a/Util/VS2010/Dafny/StartDafny.bat b/Util/VS2010/Dafny/StartDafny.bat
deleted file mode 100644
index 71dc149a..00000000
--- a/Util/VS2010/Dafny/StartDafny.bat
+++ /dev/null
@@ -1,10 +0,0 @@
-@echo off
-echo ---------- Starting ------------ < nul >> c:\tmp\doo.out
-time < nul >> c:\tmp\doo.out
-echo. < nul >> c:\tmp\doo.out
-
-"c:\boogie\Binaries\Dafny.exe" -nologo stdin.dfy -compile:0 -timeLimit:10 %* 2>> c:\tmp\doo.out
-
-time < nul >> c:\tmp\doo.out
-echo. < nul >> c:\tmp\doo.out
-echo ---------- Done ------------ < nul >> c:\tmp\doo.out
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension.sln b/Util/VS2010/DafnyExtension/DafnyExtension.sln
deleted file mode 100644
index fd450cc8..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DafnyExtension", "DafnyExtension\DafnyExtension.csproj", "{6E9A5E14-0763-471C-A129-80A879D9E7BA}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6E9A5E14-0763-471C-A129-80A879D9E7BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6E9A5E14-0763-471C-A129-80A879D9E7BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6E9A5E14-0763-471C-A129-80A879D9E7BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6E9A5E14-0763-471C-A129-80A879D9E7BA}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/BraceMatching.cs b/Util/VS2010/DafnyExtension/DafnyExtension/BraceMatching.cs
deleted file mode 100644
index 44b1affe..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/BraceMatching.cs
+++ /dev/null
@@ -1,253 +0,0 @@
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Utilities;
-
-namespace DafnyLanguage
-{
- [Export(typeof(IViewTaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(TextMarkerTag))]
- internal class BraceMatchingTaggerProvider : IViewTaggerProvider
- {
- [Import]
- internal IBufferTagAggregatorFactoryService AggregatorFactory = null;
-
- public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag {
- if (textView == null)
- return null;
-
- //provide highlighting only on the top-level buffer
- if (textView.TextBuffer != buffer)
- return null;
-
- ITagAggregator<DafnyTokenTag> tagAggregator = AggregatorFactory.CreateTagAggregator<DafnyTokenTag>(buffer);
- return new BraceMatchingTagger(textView, buffer, tagAggregator) as ITagger<T>;
- }
- }
-
- internal abstract class TokenBasedTagger
- {
- ITagAggregator<DafnyTokenTag> _aggregator;
-
- internal TokenBasedTagger(ITagAggregator<DafnyTokenTag> tagAggregator) {
- _aggregator = tagAggregator;
- }
-
- public bool InsideComment(SnapshotPoint pt) {
- SnapshotSpan span = new SnapshotSpan(pt, 1);
- foreach (var tagSpan in this._aggregator.GetTags(span)) {
- switch (tagSpan.Tag.Kind) {
- case DafnyTokenKinds.Comment:
- case DafnyTokenKinds.String:
- foreach (var s in tagSpan.Span.GetSpans(pt.Snapshot)) {
- if (s.Contains(span))
- return true;
- }
- break;
- default:
- break;
- }
- }
- return false;
- }
- }
-
- internal class BraceMatchingTagger : TokenBasedTagger, ITagger<TextMarkerTag>
- {
- ITextView View { get; set; }
- ITextBuffer SourceBuffer { get; set; }
- SnapshotPoint? CurrentChar { get; set; }
- private char[] openBraces;
- private char[] closeBraces;
-
- static TextMarkerTag Blue = new TextMarkerTag("blue");
-
- internal BraceMatchingTagger(ITextView view, ITextBuffer sourceBuffer, ITagAggregator<DafnyTokenTag> tagAggregator)
- : base(tagAggregator)
- {
- //here the keys are the open braces, and the values are the close braces
- openBraces = new char[] { '(', '{', '[' };
- closeBraces = new char[] { ')', '}', ']' };
- this.View = view;
- this.SourceBuffer = sourceBuffer;
- this.CurrentChar = null;
-
- this.View.Caret.PositionChanged += CaretPositionChanged;
- this.View.LayoutChanged += ViewLayoutChanged;
- }
-
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- void ViewLayoutChanged(object sender, TextViewLayoutChangedEventArgs e) {
- if (e.NewSnapshot != e.OldSnapshot) //make sure that there has really been a change
- {
- UpdateAtCaretPosition(View.Caret.Position);
- }
- }
-
- void CaretPositionChanged(object sender, CaretPositionChangedEventArgs e) {
- UpdateAtCaretPosition(e.NewPosition);
- }
-
- void UpdateAtCaretPosition(CaretPosition caretPosition) {
- CurrentChar = caretPosition.Point.GetPoint(SourceBuffer, caretPosition.Affinity);
-
- if (!CurrentChar.HasValue)
- return;
-
- var chngd = TagsChanged;
- if (chngd != null)
- chngd(this, new SnapshotSpanEventArgs(new SnapshotSpan(SourceBuffer.CurrentSnapshot, 0, SourceBuffer.CurrentSnapshot.Length)));
- }
-
- public IEnumerable<ITagSpan<TextMarkerTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0) //there is no content in the buffer
- yield break;
-
- //don't do anything if the current SnapshotPoint is not initialized
- if (!CurrentChar.HasValue)
- yield break;
-
- //hold on to a snapshot of the current character
- SnapshotPoint currentChar = CurrentChar.Value;
-
- //if the requested snapshot isn't the same as the one the brace is on, translate our spans to the expected snapshot
- if (spans[0].Snapshot != currentChar.Snapshot) {
- currentChar = currentChar.TranslateTo(spans[0].Snapshot, PointTrackingMode.Positive);
- }
-
- if (currentChar.Position < spans[0].Snapshot.Length) {
- // Check if the current character is an open brace
- char ch = currentChar.GetChar();
- char closeCh;
- if (MatchBrace(currentChar, ch, true, out closeCh)) {
- SnapshotSpan pairSpan;
- if (FindMatchingCloseChar(currentChar, ch, closeCh, View.TextViewLines.Count, out pairSpan)) {
- yield return new TagSpan<TextMarkerTag>(new SnapshotSpan(currentChar, 1), Blue);
- yield return new TagSpan<TextMarkerTag>(pairSpan, Blue);
- }
- }
- }
-
- if (0 < currentChar.Position) {
- // Check if the previous character is a close brace (note, caret may be between a close brace and an open brace, in which case we'll tag two pairs)
- SnapshotPoint prevChar = currentChar - 1;
- char ch = prevChar.GetChar();
- char openCh;
- if (MatchBrace(prevChar, ch, false, out openCh)) {
- SnapshotSpan pairSpan;
- if (FindMatchingOpenChar(prevChar, openCh, ch, View.TextViewLines.Count, out pairSpan)) {
- yield return new TagSpan<TextMarkerTag>(new SnapshotSpan(prevChar, 1), Blue);
- yield return new TagSpan<TextMarkerTag>(pairSpan, Blue);
- }
- }
- }
- }
-
- private bool MatchBrace(SnapshotPoint pt, char query, bool sourceIsOpen, out char match) {
- if (!InsideComment(pt)) {
- char[] source = sourceIsOpen ? openBraces : closeBraces;
- int i = 0;
- foreach (char ch in source) {
- if (ch == query) {
- char[] dest = sourceIsOpen ? closeBraces : openBraces;
- match = dest[i];
- return true;
- }
- i++;
- }
- }
- match = query; // satisfy compiler
- return false;
- }
-
- private bool FindMatchingCloseChar(SnapshotPoint startPoint, char open, char close, int linesViewed, out SnapshotSpan pairSpan) {
- ITextSnapshotLine line = startPoint.GetContainingLine();
- int lineNumber = line.LineNumber;
- int offset = startPoint.Position - line.Start.Position + 1;
-
- int lineNumberLimit = Math.Min(startPoint.Snapshot.LineCount, lineNumber + linesViewed);
-
- int openCount = 0;
- while (true) {
- string lineText = line.GetText();
-
- //walk the entire line
- for (; offset < line.Length; offset++) {
- char currentChar = lineText[offset];
- if (currentChar == open || currentChar == close) {
- if (!InsideComment(new SnapshotPoint(line.Snapshot, line.Start.Position + offset))) {
- if (currentChar == open) {
- openCount++;
- } else if (0 < openCount) {
- openCount--;
- } else {
- //found the matching close
- pairSpan = new SnapshotSpan(startPoint.Snapshot, line.Start + offset, 1);
- return true;
- }
- }
- }
- }
-
- //move on to the next line
- lineNumber++;
- if (lineNumberLimit <= lineNumber)
- break;
-
- line = line.Snapshot.GetLineFromLineNumber(lineNumber);
- offset = 0;
- }
-
- pairSpan = new SnapshotSpan(startPoint, startPoint); // satisfy the compiler
- return false;
- }
-
- private bool FindMatchingOpenChar(SnapshotPoint startPoint, char open, char close, int linesViewed, out SnapshotSpan pairSpan) {
- ITextSnapshotLine line = startPoint.GetContainingLine();
- int lineNumber = line.LineNumber;
- int offset = startPoint.Position - line.Start.Position - 1; //move the offset to the character before this one
-
- int lineNumberLimit = Math.Max(0, lineNumber - linesViewed);
-
- int closeCount = 0;
- while (true) {
- string lineText = line.GetText();
-
- //walk the entire line
- for (; 0 <= offset; offset--) {
- char currentChar = lineText[offset];
- if (currentChar == open || currentChar == close) {
- if (!InsideComment(new SnapshotPoint(line.Snapshot, line.Start.Position + offset))) {
- if (currentChar == close) {
- closeCount++;
- } else if (0 < closeCount) {
- closeCount--;
- } else {
- // We've found the open character
- pairSpan = new SnapshotSpan(line.Start + offset, 1); //we just want the character itself
- return true;
- }
- }
- }
- }
-
- // Move to the previous line
- lineNumber--;
- if (lineNumber < lineNumberLimit)
- break;
-
- line = line.Snapshot.GetLineFromLineNumber(lineNumber);
- offset = line.Length - 1;
- }
-
- pairSpan = new SnapshotSpan(startPoint, startPoint); // satisfy the compiler
- return false;
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/BufferIdleEventUtil.cs b/Util/VS2010/DafnyExtension/DafnyExtension/BufferIdleEventUtil.cs
deleted file mode 100644
index 1aea1385..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/BufferIdleEventUtil.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-//***************************************************************************
-// Copyright © 2010 Microsoft Corporation. All Rights Reserved.
-// This code released under the terms of the
-// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
-//***************************************************************************
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.VisualStudio.Text;
-using System.Windows.Threading;
-
-namespace DafnyLanguage
-{
- /// <summary>
- /// Handy reusable utility to listen for change events on the associated buffer, but
- /// only pass these along to a set of listeners when the user stops typing for a half second
- /// </summary>
- static class BufferIdleEventUtil
- {
- static object bufferListenersKey = new object();
- static object bufferTimerKey = new object();
-
- #region Public interface
-
- public static bool AddBufferIdleEventListener(ITextBuffer buffer, EventHandler handler)
- {
- HashSet<EventHandler> listenersForBuffer;
- if (!TryGetBufferListeners(buffer, out listenersForBuffer))
- listenersForBuffer = ConnectToBuffer(buffer);
-
- if (listenersForBuffer.Contains(handler))
- return false;
-
- listenersForBuffer.Add(handler);
-
- return true;
- }
-
- public static bool RemoveBufferIdleEventListener(ITextBuffer buffer, EventHandler handler)
- {
- HashSet<EventHandler> listenersForBuffer;
- if (!TryGetBufferListeners(buffer, out listenersForBuffer))
- return false;
-
- if (!listenersForBuffer.Contains(handler))
- return false;
-
- listenersForBuffer.Remove(handler);
-
- if (listenersForBuffer.Count == 0)
- DisconnectFromBuffer(buffer);
-
- return true;
- }
-
- #endregion
-
- #region Helpers
-
- static bool TryGetBufferListeners(ITextBuffer buffer, out HashSet<EventHandler> listeners)
- {
- return buffer.Properties.TryGetProperty(bufferListenersKey, out listeners);
- }
-
- static void ClearBufferListeners(ITextBuffer buffer)
- {
- buffer.Properties.RemoveProperty(bufferListenersKey);
- }
-
- static bool TryGetBufferTimer(ITextBuffer buffer, out DispatcherTimer timer)
- {
- return buffer.Properties.TryGetProperty(bufferTimerKey, out timer);
- }
-
- static void ClearBufferTimer(ITextBuffer buffer)
- {
- DispatcherTimer timer;
- if (TryGetBufferTimer(buffer, out timer))
- {
- if (timer != null)
- timer.Stop();
- buffer.Properties.RemoveProperty(bufferTimerKey);
- }
- }
-
- static void DisconnectFromBuffer(ITextBuffer buffer)
- {
- buffer.Changed -= BufferChanged;
-
- ClearBufferListeners(buffer);
- ClearBufferTimer(buffer);
-
- buffer.Properties.RemoveProperty(bufferListenersKey);
- }
-
- static HashSet<EventHandler> ConnectToBuffer(ITextBuffer buffer)
- {
- buffer.Changed += BufferChanged;
-
- RestartTimerForBuffer(buffer);
-
- HashSet<EventHandler> listenersForBuffer = new HashSet<EventHandler>();
- buffer.Properties[bufferListenersKey] = listenersForBuffer;
-
- return listenersForBuffer;
- }
-
- static void RestartTimerForBuffer(ITextBuffer buffer)
- {
- DispatcherTimer timer;
-
- if (TryGetBufferTimer(buffer, out timer))
- {
- timer.Stop();
- }
- else
- {
- timer = new DispatcherTimer(DispatcherPriority.ApplicationIdle)
- {
- Interval = TimeSpan.FromMilliseconds(500)
- };
-
- timer.Tick += (s, e) =>
- {
- ClearBufferTimer(buffer);
-
- HashSet<EventHandler> handlers;
- if (TryGetBufferListeners(buffer, out handlers))
- {
- foreach (var handler in handlers)
- {
- handler(buffer, new EventArgs());
- }
- }
- };
-
- buffer.Properties[bufferTimerKey] = timer;
- }
-
- timer.Start();
- }
-
- static void BufferChanged(object sender, TextContentChangedEventArgs e)
- {
- ITextBuffer buffer = sender as ITextBuffer;
- if (buffer == null)
- return;
-
- RestartTimerForBuffer(buffer);
- }
-
- #endregion
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/ClassificationTagger.cs b/Util/VS2010/DafnyExtension/DafnyExtension/ClassificationTagger.cs
deleted file mode 100644
index 09835ac9..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/ClassificationTagger.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.Windows.Media;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Utilities;
-
-
-namespace DafnyLanguage
-{
- [Export(typeof(ITaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(ClassificationTag))]
- internal sealed class DafnyClassifierProvider : ITaggerProvider
- {
- [Import]
- internal IBufferTagAggregatorFactoryService AggregatorFactory = null;
-
- [Import]
- internal IClassificationTypeRegistryService ClassificationTypeRegistry = null;
-
- [Import]
- internal Microsoft.VisualStudio.Language.StandardClassification.IStandardClassificationService Standards = null;
-
- public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
- ITagAggregator<DafnyTokenTag> tagAggregator = AggregatorFactory.CreateTagAggregator<DafnyTokenTag>(buffer);
- return new DafnyClassifier(buffer, tagAggregator, ClassificationTypeRegistry, Standards) as ITagger<T>;
- }
- }
-
- internal sealed class DafnyClassifier : ITagger<ClassificationTag>
- {
- ITextBuffer _buffer;
- ITagAggregator<DafnyTokenTag> _aggregator;
- IDictionary<DafnyTokenKinds, IClassificationType> _typeMap;
-
- internal DafnyClassifier(ITextBuffer buffer,
- ITagAggregator<DafnyTokenTag> tagAggregator,
- IClassificationTypeRegistryService typeService, Microsoft.VisualStudio.Language.StandardClassification.IStandardClassificationService standards) {
- _buffer = buffer;
- _aggregator = tagAggregator;
- _aggregator.TagsChanged += new EventHandler<TagsChangedEventArgs>(_aggregator_TagsChanged);
- // use built-in classification types:
- _typeMap = new Dictionary<DafnyTokenKinds, IClassificationType>();
- _typeMap[DafnyTokenKinds.Keyword] = standards.Keyword;
- _typeMap[DafnyTokenKinds.Number] = standards.NumberLiteral;
- _typeMap[DafnyTokenKinds.String] = standards.StringLiteral;
- _typeMap[DafnyTokenKinds.Comment] = standards.Comment;
- _typeMap[DafnyTokenKinds.VariableIdentifier] = standards.Identifier;
- _typeMap[DafnyTokenKinds.VariableIdentifierDefinition] = typeService.GetClassificationType("Dafny identifier");
- }
-
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- public IEnumerable<ITagSpan<ClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0) yield break;
- var snapshot = spans[0].Snapshot;
- foreach (var tagSpan in this._aggregator.GetTags(spans)) {
- IClassificationType t = _typeMap[tagSpan.Tag.Kind];
- foreach (SnapshotSpan s in tagSpan.Span.GetSpans(snapshot)) {
- yield return new TagSpan<ClassificationTag>(s, new ClassificationTag(t));
- }
- }
- }
-
- void _aggregator_TagsChanged(object sender, TagsChangedEventArgs e) {
- var chng = TagsChanged;
- if (chng != null) {
- NormalizedSnapshotSpanCollection spans = e.Span.GetSpans(_buffer.CurrentSnapshot);
- if (spans.Count > 0) {
- SnapshotSpan span = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End);
- chng(this, new SnapshotSpanEventArgs(span));
- }
- }
- }
- }
-
- /// <summary>
- /// Defines an editor format for user-defined type.
- /// </summary>
- [Export(typeof(EditorFormatDefinition))]
- [ClassificationType(ClassificationTypeNames = "Dafny identifier")]
- [Name("Dafny identifier")]
- [UserVisible(true)]
- //set the priority to be after the default classifiers
- [Order(Before = Priority.Default)]
- internal sealed class DafnyTypeFormat : ClassificationFormatDefinition
- {
- public DafnyTypeFormat() {
- this.DisplayName = "Dafny identifier"; //human readable version of the name
- this.ForegroundColor = Colors.CornflowerBlue;
- }
- }
-
- internal static class ClassificationDefinition
- {
- /// <summary>
- /// Defines the "ordinary" classification type.
- /// </summary>
- [Export(typeof(ClassificationTypeDefinition))]
- [Name("Dafny identifier")]
- internal static ClassificationTypeDefinition UserType = null;
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/ContentType.cs b/Util/VS2010/DafnyExtension/DafnyExtension/ContentType.cs
deleted file mode 100644
index d8487f74..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/ContentType.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.ComponentModel.Composition;
-using Microsoft.VisualStudio.Utilities;
-
-namespace DafnyLanguage
-{
- class DafnyContentType
- {
- [Export]
- [Name("dafny")]
- [BaseDefinition("code")]
- internal static ContentTypeDefinition ContentType = null;
-
- [Export]
- [FileExtension(".dfy")]
- [ContentType("dafny")]
- internal static FileExtensionToContentTypeDefinition FileType = null;
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/DafnyDriver.cs b/Util/VS2010/DafnyExtension/DafnyExtension/DafnyDriver.cs
deleted file mode 100644
index 39829bb0..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/DafnyDriver.cs
+++ /dev/null
@@ -1,419 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.IO;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-// Here come the Dafny/Boogie specific imports
-//using PureCollections;
-using Bpl = Microsoft.Boogie;
-using Dafny = Microsoft.Dafny;
-using Microsoft.Boogie.AbstractInterpretation;
-using VC;
-// using AI = Microsoft.AbstractInterpretationFramework;
-
-
-namespace DafnyLanguage
-{
- class DafnyDriver
- {
- readonly string _programText;
- readonly string _filename;
- Dafny.Program _program;
- List<DafnyError> _errors = new List<DafnyError>();
- public List<DafnyError> Errors { get { return _errors; } }
-
- public DafnyDriver(string programText, string filename) {
- _programText = programText;
- _filename = filename;
- }
-
- void RecordError(int line, int col, ErrorCategory cat, string msg) {
- _errors.Add(new DafnyError(line, col, cat, msg));
- }
-
- static DafnyDriver() {
- Initialize();
- }
-
- static void Initialize() {
- if (Dafny.DafnyOptions.O == null) {
- var options = new Dafny.DafnyOptions();
- options.ProverKillTime = 10;
- options.ErrorTrace = 0;
- Dafny.DafnyOptions.Install(options);
- options.ApplyDefaultOptions();
- }
- }
-
- public Dafny.Program ProcessResolution() {
- if (!ParseAndTypeCheck()) {
- return null;
- }
- return _program;
- }
-
- bool ParseAndTypeCheck() {
- Dafny.ModuleDecl module = new Dafny.LiteralModuleDecl(new Dafny.DefaultModuleDecl(), null);
- Dafny.BuiltIns builtIns = new Dafny.BuiltIns();
- int errorCount = Dafny.Parser.Parse(_programText, _filename, module, builtIns, new VSErrors(this));
- if (errorCount != 0)
- return false;
- Dafny.Program program = new Dafny.Program(_filename, module, builtIns);
-
- Dafny.Resolver r = new VSResolver(program, this);
- r.ResolveProgram(program);
- if (r.ErrorCount != 0)
- return false;
-
- _program = program;
- return true; // success
- }
-
- class VSErrors : Dafny.Errors
- {
- DafnyDriver dd;
- public VSErrors(DafnyDriver dd) {
- this.dd = dd;
- }
- public override void SynErr(string filename, int line, int col, string msg) {
- dd.RecordError(line - 1, col - 1, ErrorCategory.ParseError, msg);
- count++;
- }
- public override void SemErr(string filename, int line, int col, string msg) {
- dd.RecordError(line - 1, col - 1, ErrorCategory.ResolveError, msg);
- count++;
- }
- public override void Warning(string filename, int line, int col, string msg) {
- dd.RecordError(line - 1, col - 1, ErrorCategory.ParseWarning, msg);
- }
- }
-
- class VSResolver : Dafny.Resolver
- {
- DafnyDriver dd;
- public VSResolver(Dafny.Program program, DafnyDriver dd)
- : base(program) {
- this.dd = dd;
- }
- public override void Error(Bpl.IToken tok, string msg, params object[] args) {
- string s = string.Format(msg, args);
- dd.RecordError(tok.line - 1, tok.col - 1, ErrorCategory.ResolveError, s);
- ErrorCount++;
- }
- }
-
- public static bool Verify(Dafny.Program dafnyProgram, ErrorReporterDelegate er) {
- Dafny.Translator translator = new Dafny.Translator();
- Bpl.Program boogieProgram = translator.Translate(dafnyProgram);
-
- PipelineOutcome oc = BoogiePipeline(boogieProgram, er);
- switch (oc) {
- case PipelineOutcome.Done:
- case PipelineOutcome.VerificationCompleted:
- // TODO: This would be the place to proceed to compile the program, if desired
- return true;
- case PipelineOutcome.FatalError:
- default:
- return false;
- }
- }
-
- enum PipelineOutcome { Done, ResolutionError, TypeCheckingError, ResolvedAndTypeChecked, FatalError, VerificationCompleted }
-
- /// <summary>
- /// Resolve, type check, infer invariants for, and verify the given Boogie program.
- /// The intention is that this Boogie program has been produced by translation from something
- /// else. Hence, any resolution errors and type checking errors are due to errors in
- /// the translation.
- /// </summary>
- static PipelineOutcome BoogiePipeline(Bpl.Program/*!*/ program, ErrorReporterDelegate er) {
- Contract.Requires(program != null);
-
- PipelineOutcome oc = BoogieResolveAndTypecheck(program);
- if (oc == PipelineOutcome.ResolvedAndTypeChecked) {
- EliminateDeadVariablesAndInline(program);
- return BoogieInferAndVerify(program, er);
- }
- return oc;
- }
-
- static void EliminateDeadVariablesAndInline(Bpl.Program program) {
- Contract.Requires(program != null);
- // Eliminate dead variables
- Microsoft.Boogie.UnusedVarEliminator.Eliminate(program);
-
- // Collect mod sets
- if (Bpl.CommandLineOptions.Clo.DoModSetAnalysis) {
- Microsoft.Boogie.ModSetCollector.DoModSetAnalysis(program);
- }
-
- // Coalesce blocks
- if (Bpl.CommandLineOptions.Clo.CoalesceBlocks) {
- Microsoft.Boogie.BlockCoalescer.CoalesceBlocks(program);
- }
-
- // Inline
- var TopLevelDeclarations = program.TopLevelDeclarations;
-
- if (Bpl.CommandLineOptions.Clo.ProcedureInlining != Bpl.CommandLineOptions.Inlining.None) {
- bool inline = false;
- foreach (var d in TopLevelDeclarations) {
- if (d.FindExprAttribute("inline") != null) {
- inline = true;
- }
- }
- if (inline && Bpl.CommandLineOptions.Clo.StratifiedInlining == 0) {
- foreach (var d in TopLevelDeclarations) {
- var impl = d as Bpl.Implementation;
- if (impl != null) {
- impl.OriginalBlocks = impl.Blocks;
- impl.OriginalLocVars = impl.LocVars;
- }
- }
- foreach (var d in TopLevelDeclarations) {
- var impl = d as Bpl.Implementation;
- if (impl != null && !impl.SkipVerification) {
- Bpl.Inliner.ProcessImplementation(program, impl);
- }
- }
- foreach (var d in TopLevelDeclarations) {
- var impl = d as Bpl.Implementation;
- if (impl != null) {
- impl.OriginalBlocks = null;
- impl.OriginalLocVars = null;
- }
- }
- }
- }
- }
-
- /// <summary>
- /// Resolves and type checks the given Boogie program.
- /// Returns:
- /// - Done if no errors occurred, and command line specified no resolution or no type checking.
- /// - ResolutionError if a resolution error occurred
- /// - TypeCheckingError if a type checking error occurred
- /// - ResolvedAndTypeChecked if both resolution and type checking succeeded
- /// </summary>
- static PipelineOutcome BoogieResolveAndTypecheck(Bpl.Program program) {
- Contract.Requires(program != null);
- // ---------- Resolve ------------------------------------------------------------
- int errorCount = program.Resolve();
- if (errorCount != 0) {
- return PipelineOutcome.ResolutionError;
- }
-
- // ---------- Type check ------------------------------------------------------------
- errorCount = program.Typecheck();
- if (errorCount != 0) {
- return PipelineOutcome.TypeCheckingError;
- }
-
- return PipelineOutcome.ResolvedAndTypeChecked;
- }
-
- /// <summary>
- /// Given a resolved and type checked Boogie program, infers invariants for the program
- /// and then attempts to verify it. Returns:
- /// - Done if command line specified no verification
- /// - FatalError if a fatal error occurred
- /// - VerificationCompleted if inference and verification completed, in which the out
- /// parameters contain meaningful values
- /// </summary>
- static PipelineOutcome BoogieInferAndVerify(Bpl.Program program, ErrorReporterDelegate er) {
- Contract.Requires(program != null);
-
- // ---------- Infer invariants --------------------------------------------------------
-
- // Abstract interpretation -> Always use (at least) intervals, if not specified otherwise (e.g. with the "/noinfer" switch)
- if (Bpl.CommandLineOptions.Clo.UseAbstractInterpretation) {
- if (Bpl.CommandLineOptions.Clo.Ai.J_Intervals || Bpl.CommandLineOptions.Clo.Ai.J_Trivial) {
- Microsoft.Boogie.AbstractInterpretation.NativeAbstractInterpretation.RunAbstractInterpretation(program);
- } else {
- // use /infer:j as the default
- Bpl.CommandLineOptions.Clo.Ai.J_Intervals = true;
- Microsoft.Boogie.AbstractInterpretation.NativeAbstractInterpretation.RunAbstractInterpretation(program);
- }
- }
-
- if (Bpl.CommandLineOptions.Clo.LoopUnrollCount != -1) {
- program.UnrollLoops(Bpl.CommandLineOptions.Clo.LoopUnrollCount);
- }
-
- if (Bpl.CommandLineOptions.Clo.ExpandLambdas) {
- Bpl.LambdaHelper.ExpandLambdas(program);
- //PrintBplFile ("-", program, true);
- }
-
- // ---------- Verify ------------------------------------------------------------
-
- if (!Bpl.CommandLineOptions.Clo.Verify) { return PipelineOutcome.Done; }
-
- #region Verify each implementation
-
- ConditionGeneration vcgen = null;
- try {
- vcgen = new VCGen(program, Bpl.CommandLineOptions.Clo.SimplifyLogFilePath, Bpl.CommandLineOptions.Clo.SimplifyLogFileAppend);
- } catch (Bpl.ProverException) {
- return PipelineOutcome.FatalError;
- }
-
- var decls = program.TopLevelDeclarations.ToArray();
- foreach (var decl in decls) {
- Contract.Assert(decl != null);
- Bpl.Implementation impl = decl as Bpl.Implementation;
- if (impl != null && Bpl.CommandLineOptions.Clo.UserWantsToCheckRoutine(impl.Name) && !impl.SkipVerification) {
- List<Bpl.Counterexample>/*?*/ errors;
-
- ConditionGeneration.Outcome outcome;
- int prevAssertionCount = vcgen.CumulativeAssertionCount;
- try {
- outcome = vcgen.VerifyImplementation(impl, out errors);
- } catch (VCGenException) {
- errors = null;
- outcome = VCGen.Outcome.Inconclusive;
- } catch (Bpl.UnexpectedProverOutputException) {
- errors = null;
- outcome = VCGen.Outcome.Inconclusive;
- }
-
- switch (outcome) {
- default:
- Contract.Assert(false); throw new Exception(); // unexpected outcome
- case VCGen.Outcome.Correct:
- break;
- case VCGen.Outcome.TimedOut:
- er(new DafnyErrorInformation(impl.tok, "Verification timed out (" + impl.Name + ")"));
- break;
- case VCGen.Outcome.OutOfMemory:
- er(new DafnyErrorInformation(impl.tok, "Verification out of memory (" + impl.Name + ")"));
- break;
- case VCGen.Outcome.Inconclusive:
- er(new DafnyErrorInformation(impl.tok, "Verification inconclusive (" + impl.Name + ")"));
- break;
- case VCGen.Outcome.Errors:
- Contract.Assert(errors != null); // guaranteed by postcondition of VerifyImplementation
-
- errors.Sort(new Bpl.CounterexampleComparer());
- foreach (var error in errors) {
- DafnyErrorInformation errorInfo;
-
- if (error is Bpl.CallCounterexample) {
- var err = (Bpl.CallCounterexample)error;
- errorInfo = new DafnyErrorInformation(err.FailingCall.tok, err.FailingCall.ErrorData as string ?? "A precondition for this call might not hold.");
- errorInfo.AddAuxInfo(err.FailingRequires.tok, err.FailingRequires.ErrorData as string ?? "Related location: This is the precondition that might not hold.");
-
- } else if (error is Bpl.ReturnCounterexample) {
- var err = (Bpl.ReturnCounterexample)error;
- errorInfo = new DafnyErrorInformation(err.FailingReturn.tok, "A postcondition might not hold on this return path.");
- errorInfo.AddAuxInfo(err.FailingEnsures.tok, err.FailingEnsures.ErrorData as string ?? "Related location: This is the postcondition that might not hold.");
- errorInfo.AddAuxInfo(err.FailingEnsures.Attributes);
-
- } else { // error is AssertCounterexample
- var err = (Bpl.AssertCounterexample)error;
- if (err.FailingAssert is Bpl.LoopInitAssertCmd) {
- errorInfo = new DafnyErrorInformation(err.FailingAssert.tok, "This loop invariant might not hold on entry.");
- } else if (err.FailingAssert is Bpl.LoopInvMaintainedAssertCmd) {
- // this assertion is a loop invariant which is not maintained
- errorInfo = new DafnyErrorInformation(err.FailingAssert.tok, "This loop invariant might not be maintained by the loop.");
- } else {
- string msg = err.FailingAssert.ErrorData as string;
- if (msg == null) {
- msg = "This assertion might not hold.";
- }
- errorInfo = new DafnyErrorInformation(err.FailingAssert.tok, msg);
- errorInfo.AddAuxInfo(err.FailingAssert.Attributes);
- }
- }
- if (Bpl.CommandLineOptions.Clo.ErrorTrace > 0) {
- foreach (Bpl.Block b in error.Trace) {
- // for ErrorTrace == 1 restrict the output;
- // do not print tokens with -17:-4 as their location because they have been
- // introduced in the translation and do not give any useful feedback to the user
- if (!(Bpl.CommandLineOptions.Clo.ErrorTrace == 1 && b.tok.line == -17 && b.tok.col == -4) &&
- b.tok.line != 0 && b.tok.col != 0) {
- errorInfo.AddAuxInfo(b.tok, "Execution trace: " + b.Label);
- }
- }
- }
- // if (Bpl.CommandLineOptions.Clo.ModelViewFile != null) {
- // error.PrintModel();
- // }
- er(errorInfo);
- }
- break;
- }
- }
- }
- vcgen.Close();
- Bpl.CommandLineOptions.Clo.TheProverFactory.Close();
-
- #endregion
-
- return PipelineOutcome.VerificationCompleted;
- }
-
- public delegate void ErrorReporterDelegate(DafnyErrorInformation errInfo);
-
- public class DafnyErrorInformation
- {
- public readonly Bpl.IToken Tok;
- public readonly string Msg;
- public readonly List<DafnyErrorAuxInfo> Aux = new List<DafnyErrorAuxInfo>();
-
- public class DafnyErrorAuxInfo
- {
- public readonly Bpl.IToken Tok;
- public readonly string Msg;
- public DafnyErrorAuxInfo(Bpl.IToken tok, string msg) {
- Tok = tok;
- Msg = CleanUp(msg);
- }
- }
-
- public DafnyErrorInformation(Bpl.IToken tok, string msg) {
- Contract.Requires(tok != null);
- Contract.Requires(1 <= tok.line && 1 <= tok.col);
- Contract.Requires(msg != null);
- Tok = tok;
- Msg = CleanUp(msg);
- AddNestingsAsAux(tok);
- }
- public void AddAuxInfo(Bpl.IToken tok, string msg) {
- Contract.Requires(tok != null);
- Contract.Requires(1 <= tok.line && 1 <= tok.col);
- Contract.Requires(msg != null);
- Aux.Add(new DafnyErrorAuxInfo(tok, msg));
- AddNestingsAsAux(tok);
- }
- void AddNestingsAsAux(Bpl.IToken tok) {
- while (tok is Dafny.NestedToken) {
- var nt = (Dafny.NestedToken)tok;
- tok = nt.Inner;
- Aux.Add(new DafnyErrorAuxInfo(tok, "Related location"));
- }
- }
- public void AddAuxInfo(Bpl.QKeyValue attr) {
- while (attr != null) {
- if (attr.Key == "msg" && attr.Params.Count == 1 && attr.tok.line != 0 && attr.tok.col != 0) {
- var str = attr.Params[0] as string;
- if (str != null) {
- AddAuxInfo(attr.tok, str);
- }
- }
- attr = attr.Next;
- }
- }
-
- public static string CleanUp(string msg) {
- if (msg.ToLower().StartsWith("error: ")) {
- return msg.Substring(7);
- } else {
- return msg;
- }
- }
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/DafnyExtension.csproj b/Util/VS2010/DafnyExtension/DafnyExtension/DafnyExtension.csproj
deleted file mode 100644
index 2580c396..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/DafnyExtension.csproj
+++ /dev/null
@@ -1,191 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>10.0.20305</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <ProjectGuid>{6E9A5E14-0763-471C-A129-80A879D9E7BA}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>DafnyLanguage</RootNamespace>
- <AssemblyName>DafnyLanguageService</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <GeneratePkgDefFile>false</GeneratePkgDefFile>
- <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- <OldToolsVersion>4.0</OldToolsVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="AbsInt, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\Binaries\AbsInt.dll</HintPath>
- </Reference>
- <Reference Include="AIFramework, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\Binaries\AIFramework.dll</HintPath>
- </Reference>
- <Reference Include="Basetypes, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\Binaries\Basetypes.dll</HintPath>
- </Reference>
- <Reference Include="CodeContractsExtender, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\Binaries\CodeContractsExtender.dll</HintPath>
- </Reference>
- <Reference Include="Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\Binaries\Core.dll</HintPath>
- </Reference>
- <Reference Include="DafnyPipeline, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\Binaries\DafnyPipeline.dll</HintPath>
- </Reference>
- <Reference Include="Graph">
- <HintPath>..\..\..\..\Binaries\Graph.dll</HintPath>
- </Reference>
- <Reference Include="Houdini">
- <HintPath>..\..\..\..\Binaries\Houdini.dll</HintPath>
- </Reference>
- <Reference Include="Model">
- <HintPath>..\..\..\..\Binaries\Model.dll</HintPath>
- </Reference>
- <Reference Include="ParserHelper">
- <HintPath>..\..\..\..\Binaries\ParserHelper.dll</HintPath>
- </Reference>
- <Reference Include="Provers.Z3">
- <HintPath>..\..\..\..\Binaries\Provers.Z3.dll</HintPath>
- </Reference>
- <Reference Include="Provers.SMTLib">
- <HintPath>..\..\..\..\Binaries\Provers.SMTLib.dll</HintPath>
- </Reference>
- <Reference Include="VCExpr">
- <HintPath>..\..\..\..\Binaries\VCExpr.dll</HintPath>
- </Reference>
- <Reference Include="VCGeneration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\..\Binaries\VCGeneration.dll</HintPath>
- </Reference>
- <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <EmbedInteropTypes>False</EmbedInteropTypes>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.CoreUtility">
- <Private>False</Private>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Editor, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
- <Reference Include="Microsoft.VisualStudio.Language.Intellisense, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
- <Reference Include="Microsoft.VisualStudio.Language.StandardClassification, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
- <Reference Include="Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- <Reference Include="Microsoft.VisualStudio.Shell, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <Private>False</Private>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
- <Reference Include="Microsoft.VisualStudio.Shell.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <EmbedInteropTypes>True</EmbedInteropTypes>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- <Reference Include="Microsoft.VisualStudio.Text.Data">
- <Private>False</Private>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Text.Logic">
- <Private>False</Private>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Text.UI">
- <Private>False</Private>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Text.UI.Wpf">
- <Private>False</Private>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.TextManager.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- <Reference Include="PresentationCore" />
- <Reference Include="PresentationFramework" />
- <Reference Include="System" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.ComponentModel.Composition" />
- <Reference Include="System.Core" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- <Reference Include="System.Xaml" />
- <Reference Include="WindowsBase" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="BufferIdleEventUtil.cs" />
- <Compile Include="HoverText.cs" />
- <Compile Include="IdentifierTagger.cs" />
- <Compile Include="ProgressMargin.cs" />
- <Compile Include="OutliningTagger.cs" />
- <Compile Include="ResolverTagger.cs" />
- <Compile Include="DafnyDriver.cs" />
- <Compile Include="ContentType.cs" />
- <Compile Include="BraceMatching.cs" />
- <Compile Include="WordHighlighter.cs" />
- <Compile Include="ErrorTagger.cs" />
- <Compile Include="TokenTagger.cs" />
- <Compile Include="ClassificationTagger.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <Content Include="DafnyPrelude.bpl">
- <IncludeInVSIX>true</IncludeInVSIX>
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </Content>
- <None Include="source.extension.vsixmanifest">
- <SubType>Designer</SubType>
- </None>
- <Content Include="UnivBackPred2.smt2">
- <IncludeInVSIX>true</IncludeInVSIX>
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </Content>
- </ItemGroup>
- <ItemGroup>
- <WCFMetadata Include="Service References\" />
- </ItemGroup>
- <PropertyGroup>
- <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
- <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
- </PropertyGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\VSSDK\Microsoft.VsSDK.targets" Condition="false" />
- <PropertyGroup>
- <PostBuildEvent>cd</PostBuildEvent>
- <PostBuildEvent>
- </PostBuildEvent>
- </PropertyGroup>
- <PropertyGroup>
- <PreBuildEvent>copy ..\..\..\..\..\..\Binaries\DafnyPrelude.bpl $(ProjectDir)
-copy ..\..\..\..\..\..\Binaries\UnivBackPred2.smt2 $(ProjectDir)</PreBuildEvent>
- </PropertyGroup>
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/ErrorTagger.cs b/Util/VS2010/DafnyExtension/DafnyExtension/ErrorTagger.cs
deleted file mode 100644
index efd755d8..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/ErrorTagger.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-//***************************************************************************
-// Copyright © 2010 Microsoft Corporation. All Rights Reserved.
-// This code released under the terms of the
-// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
-//***************************************************************************
-using EnvDTE;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.ComponentModel.Composition;
-using System.Windows.Threading;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Text.Projection;
-using Microsoft.VisualStudio.Utilities;
-
-namespace DafnyLanguage
-{
- [Export(typeof(ITaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(ErrorTag))]
- internal sealed class ErrorTaggerProvider : ITaggerProvider
- {
- [Import]
- internal IBufferTagAggregatorFactoryService AggregatorFactory = null;
-
- public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
- ITagAggregator<DafnyResolverTag> tagAggregator = AggregatorFactory.CreateTagAggregator<DafnyResolverTag>(buffer);
- // create a single tagger for each buffer.
- Func<ITagger<T>> sc = delegate() { return new ErrorTagger(buffer, tagAggregator) as ITagger<T>; };
- return buffer.Properties.GetOrCreateSingletonProperty<ITagger<T>>(sc);
- }
- }
-
- /// <summary>
- /// Translate PkgDefTokenTags into ErrorTags and Error List items
- /// </summary>
- internal sealed class ErrorTagger : ITagger<ErrorTag>
- {
- ITextBuffer _buffer;
- ITagAggregator<DafnyResolverTag> _aggregator;
-
- internal ErrorTagger(ITextBuffer buffer, ITagAggregator<DafnyResolverTag> tagAggregator) {
- _buffer = buffer;
- _aggregator = tagAggregator;
- _aggregator.TagsChanged += new EventHandler<TagsChangedEventArgs>(_aggregator_TagsChanged);
- }
-
- /// <summary>
- /// Find the Error tokens in the set of all tokens and create an ErrorTag for each
- /// </summary>
- public IEnumerable<ITagSpan<ErrorTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0) yield break;
- var snapshot = spans[0].Snapshot;
- foreach (var tagSpan in this._aggregator.GetTags(spans)) {
- DafnyResolverTag t = tagSpan.Tag;
- DafnyErrorResolverTag et = t as DafnyErrorResolverTag;
- if (et != null) {
- foreach (SnapshotSpan s in tagSpan.Span.GetSpans(snapshot)) {
- yield return new TagSpan<ErrorTag>(s, new ErrorTag(et.Typ, et.Msg));
- }
- }
- }
- }
-
- // the Classifier tagger is translating buffer change events into TagsChanged events, so we don't have to
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- void _aggregator_TagsChanged(object sender, TagsChangedEventArgs e) {
- var chng = TagsChanged;
- if (chng != null) {
- NormalizedSnapshotSpanCollection spans = e.Span.GetSpans(_buffer.CurrentSnapshot);
- if (spans.Count > 0) {
- SnapshotSpan span = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End);
- chng(this, new SnapshotSpanEventArgs(span));
- }
- }
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/HoverText.cs b/Util/VS2010/DafnyExtension/DafnyExtension/HoverText.cs
deleted file mode 100644
index be806f5b..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/HoverText.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Windows.Input;
-using Microsoft.VisualStudio.Language.Intellisense;
-using System.Collections.ObjectModel;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using System.ComponentModel.Composition;
-using Microsoft.VisualStudio.Utilities;
-using System.Diagnostics.Contracts;
-
-
-namespace DafnyLanguage
-{
- [Export(typeof(IQuickInfoSourceProvider))]
- [ContentType("dafny")]
- [Name("Dafny QuickInfo")]
- class OokQuickInfoSourceProvider : IQuickInfoSourceProvider
- {
- [Import]
- IBufferTagAggregatorFactoryService aggService = null;
-
- public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer) {
- return new DafnyQuickInfoSource(textBuffer, aggService.CreateTagAggregator<DafnyTokenTag>(textBuffer));
- }
- }
-
- class DafnyQuickInfoSource : IQuickInfoSource
- {
- private ITagAggregator<DafnyTokenTag> _aggregator;
- private ITextBuffer _buffer;
-
- public DafnyQuickInfoSource(ITextBuffer buffer, ITagAggregator<DafnyTokenTag> aggregator) {
- _aggregator = aggregator;
- _buffer = buffer;
- }
-
- public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) {
- applicableToSpan = null;
-
- var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(_buffer.CurrentSnapshot);
- if (triggerPoint == null)
- return;
-
- foreach (IMappingTagSpan<DafnyTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) {
- var s = curTag.Tag.HoverText;
- if (s != null) {
- var tagSpan = curTag.Span.GetSpans(_buffer).First();
- applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive);
- quickInfoContent.Add(s);
- }
- }
- }
- public void Dispose() {
- }
- }
- // --------------------------------- QuickInfo controller ------------------------------------------
-
- [Export(typeof(IIntellisenseControllerProvider))]
- [Name("Dafny QuickInfo controller")]
- [ContentType("dafny")]
- class DafnyQuickInfoControllerProvider : IIntellisenseControllerProvider
- {
- [Import]
- internal IQuickInfoBroker QuickInfoBroker { get; set; }
-
- public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList<ITextBuffer> subjectBuffers) {
- return new DafnyQuickInfoController(textView, subjectBuffers, this);
- }
- }
-
- class DafnyQuickInfoController : IIntellisenseController
- {
- private ITextView _textView;
- private IList<ITextBuffer> _subjectBuffers;
- private DafnyQuickInfoControllerProvider _componentContext;
-
- private IQuickInfoSession _session;
-
- internal DafnyQuickInfoController(ITextView textView, IList<ITextBuffer> subjectBuffers, DafnyQuickInfoControllerProvider componentContext) {
- _textView = textView;
- _subjectBuffers = subjectBuffers;
- _componentContext = componentContext;
-
- _textView.MouseHover += this.OnTextViewMouseHover;
- }
-
- public void ConnectSubjectBuffer(ITextBuffer subjectBuffer) {
- }
-
- public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer) {
- }
-
- public void Detach(ITextView textView) {
- if (_textView == textView) {
- _textView.MouseHover -= OnTextViewMouseHover;
- _textView = null;
- }
- }
-
- void OnTextViewMouseHover(object sender, MouseHoverEventArgs e) {
- SnapshotPoint? point = GetMousePosition(new SnapshotPoint(_textView.TextSnapshot, e.Position));
-
- if (point != null) {
- ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, PointTrackingMode.Positive);
-
- // Find the broker for this buffer
- if (!_componentContext.QuickInfoBroker.IsQuickInfoActive(_textView)) {
- _session = _componentContext.QuickInfoBroker.CreateQuickInfoSession(_textView, triggerPoint, true);
- _session.Start();
- }
- }
- }
-
- SnapshotPoint? GetMousePosition(SnapshotPoint topPosition) {
- return _textView.BufferGraph.MapDownToFirstMatch(
- topPosition,
- PointTrackingMode.Positive,
- snapshot => _subjectBuffers.Contains(snapshot.TextBuffer),
- PositionAffinity.Predecessor);
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/IdentifierTagger.cs b/Util/VS2010/DafnyExtension/DafnyExtension/IdentifierTagger.cs
deleted file mode 100644
index 5ecc8dc2..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/IdentifierTagger.cs
+++ /dev/null
@@ -1,344 +0,0 @@
-//***************************************************************************
-// Copyright © 2010 Microsoft Corporation. All Rights Reserved.
-// This code released under the terms of the
-// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
-//***************************************************************************
-using EnvDTE;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.ComponentModel.Composition;
-using System.Windows.Threading;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Text.Projection;
-using Microsoft.VisualStudio.Utilities;
-using System.Diagnostics.Contracts;
-using Bpl = Microsoft.Boogie;
-using Microsoft.Dafny;
-
-namespace DafnyLanguage
-{
- [Export(typeof(ITaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(DafnyTokenTag))]
- internal sealed class IdentifierTaggerProvider : ITaggerProvider
- {
- [Import]
- internal IBufferTagAggregatorFactoryService AggregatorFactory = null;
-
- public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
- ITagAggregator<DafnyResolverTag> tagAggregator = AggregatorFactory.CreateTagAggregator<DafnyResolverTag>(buffer);
- // create a single tagger for each buffer.
- Func<ITagger<T>> sc = delegate() { return new IdentifierTagger(buffer, tagAggregator) as ITagger<T>; };
- return buffer.Properties.GetOrCreateSingletonProperty<ITagger<T>>(sc);
- }
- }
-
- /// <summary>
- /// Translate DafnyResolverTag's into IOutliningRegionTag's
- /// </summary>
- internal sealed class IdentifierTagger : ITagger<DafnyTokenTag>
- {
- ITextBuffer _buffer;
- ITextSnapshot _snapshot; // the most recent snapshot of _buffer that we have been informed about
- Microsoft.Dafny.Program _program; // the program parsed from _snapshot
- List<IdRegion> _regions = new List<IdRegion>(); // the regions generated from _program
- ITagAggregator<DafnyResolverTag> _aggregator;
-
- internal IdentifierTagger(ITextBuffer buffer, ITagAggregator<DafnyResolverTag> tagAggregator) {
- _buffer = buffer;
- _snapshot = _buffer.CurrentSnapshot;
- _aggregator = tagAggregator;
- _aggregator.TagsChanged += new EventHandler<TagsChangedEventArgs>(_aggregator_TagsChanged);
- }
-
- /// <summary>
- /// Find the Error tokens in the set of all tokens and create an ErrorTag for each
- /// </summary>
- public IEnumerable<ITagSpan<DafnyTokenTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0) yield break;
- // (A NormalizedSnapshotSpanCollection contains spans that all come from the same snapshot.)
- // The spans are ordered by the .Start component, and the collection contains no adjacent or abutting spans.
- // Hence, to find a span that includes all the ones in "spans", we only need to look at the .Start for the
- // first spand and the .End of the last span:
- var startPoint = spans[0].Start;
- var endPoint = spans[spans.Count - 1].End;
-
- // Note, (startPoint,endPoint) are points in the spans for which we're being asked to provide tags. We need to translate
- // these back into the most recent snapshot that we've computed regions for, namely _snapshot.
- var entire = new SnapshotSpan(startPoint, endPoint).TranslateTo(_snapshot, SpanTrackingMode.EdgeExclusive);
- int start = entire.Start;
- int end = entire.End;
- foreach (var r in _regions) {
- if (0 <= r.Length && r.Start <= end && start <= r.Start + r.Length) {
- DafnyTokenKinds kind;
- switch (r.Kind) {
- case IdRegion.OccurrenceKind.Use:
- kind = DafnyTokenKinds.VariableIdentifier; break;
- case IdRegion.OccurrenceKind.Definition:
- kind = DafnyTokenKinds.VariableIdentifierDefinition; break;
- case IdRegion.OccurrenceKind.WildDefinition:
- kind = DafnyTokenKinds.Keyword; break;
- default:
- Contract.Assert(false); // unexpected OccurrenceKind
- goto case IdRegion.OccurrenceKind.Use; // to please compiler
- }
- yield return new TagSpan<DafnyTokenTag>(
- new SnapshotSpan(_snapshot, r.Start, r.Length),
- new DafnyTokenTag(kind, r.HoverText));
- }
- }
- }
-
- // the Classifier tagger is translating buffer change events into TagsChanged events, so we don't have to
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- void _aggregator_TagsChanged(object sender, TagsChangedEventArgs e) {
- var r = sender as ResolverTagger;
- if (r != null) {
- ITextSnapshot snap;
- Microsoft.Dafny.Program prog;
- lock (this) {
- snap = r._snapshot;
- prog = r._program;
- }
- if (prog != null) {
- if (!ComputeIdentifierRegions(prog, snap))
- return; // no new regions
-
- var chng = TagsChanged;
- if (chng != null) {
- NormalizedSnapshotSpanCollection spans = e.Span.GetSpans(_buffer.CurrentSnapshot);
- if (spans.Count > 0) {
- SnapshotSpan span = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End);
- chng(this, new SnapshotSpanEventArgs(span));
- }
- }
- }
- }
- }
-
- bool ComputeIdentifierRegions(Microsoft.Dafny.Program program, ITextSnapshot snapshot) {
- Contract.Requires(snapshot != null);
-
- if (program == _program)
- return false; // no new regions
-
- List<IdRegion> newRegions = new List<IdRegion>();
-
- foreach (var module in program.Modules) {
- foreach (var d in module.TopLevelDecls) {
- if (d is DatatypeDecl) {
- var dt = (DatatypeDecl)d;
- foreach (var ctor in dt.Ctors) {
- foreach (var dtor in ctor.Destructors) {
- if (dtor != null) {
- IdRegion.Add(newRegions, dtor.tok, dtor, null, "destructor", true, module);
- }
- }
- }
- } else if (d is ClassDecl) {
- var cl = (ClassDecl)d;
- foreach (var member in cl.Members) {
- if (member is Function) {
- var f = (Function)member;
- foreach (var p in f.Formals) {
- IdRegion.Add(newRegions, p.tok, p, true, module);
- }
- f.Req.ForEach(e => ExprRegions(e, newRegions, module));
- f.Reads.ForEach(fe => FrameExprRegions(fe, newRegions, true, module));
- f.Ens.ForEach(e => ExprRegions(e, newRegions, module));
- f.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, module));
- if (f.Body != null) {
- ExprRegions(f.Body, newRegions, module);
- }
- } else if (member is Method) {
- var m = (Method)member;
- foreach (var p in m.Ins) {
- IdRegion.Add(newRegions, p.tok, p, true, module);
- }
- foreach (var p in m.Outs) {
- IdRegion.Add(newRegions, p.tok, p, true, module);
- }
- m.Req.ForEach(e => ExprRegions(e.E, newRegions, module));
- m.Mod.Expressions.ForEach(fe => FrameExprRegions(fe, newRegions, true, module));
- m.Ens.ForEach(e => ExprRegions(e.E, newRegions, module));
- m.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, module));
- if (m.Body != null) {
- StatementRegions(m.Body, newRegions, module);
- }
- } else if (member is Field) {
- var fld = (Field)member;
- IdRegion.Add(newRegions, fld.tok, fld, null, "field", true, module);
- }
- }
- }
- }
- }
- _snapshot = snapshot;
- _regions = newRegions;
- _program = program;
- return true;
- }
-
- static void FrameExprRegions(FrameExpression fe, List<IdRegion> regions, bool descendIntoExpressions, ModuleDefinition module) {
- Contract.Requires(fe != null);
- Contract.Requires(regions != null);
- if (descendIntoExpressions) {
- ExprRegions(fe.E, regions, module);
- }
- if (fe.Field != null) {
- Microsoft.Dafny.Type showType = null; // TODO: if we had the instantiated type of this field, that would have been nice to use here (but the Resolver currently does not compute or store the instantiated type for a FrameExpression)
- IdRegion.Add(regions, fe.tok, fe.Field, showType, "field", false, module);
- }
- }
-
- static void ExprRegions(Microsoft.Dafny.Expression expr, List<IdRegion> regions, ModuleDefinition module) {
- Contract.Requires(expr != null);
- Contract.Requires(regions != null);
- if (expr is IdentifierExpr) {
- var e = (IdentifierExpr)expr;
- IdRegion.Add(regions, e.tok, e.Var, false, module);
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- IdRegion.Add(regions, e.tok, e.Field, e.Type, "field", false, module);
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- foreach (var bv in e.BoundVars) {
- IdRegion.Add(regions, bv.tok, bv, true, module);
- }
- } else if (expr is MatchExpr) {
- var e = (MatchExpr)expr;
- foreach (var kase in e.Cases) {
- kase.Arguments.ForEach(bv => IdRegion.Add(regions, bv.tok, bv, true, module));
- }
- } else if (expr is ChainingExpression) {
- var e = (ChainingExpression)expr;
- // Do the subexpressions only once (that is, avoid the duplication that occurs in the desugared form of the ChainingExpression)
- e.Operands.ForEach(ee => ExprRegions(ee, regions, module));
- return; // return here, so as to avoid doing the subexpressions below
- }
- foreach (var ee in expr.SubExpressions) {
- ExprRegions(ee, regions, module);
- }
- }
-
- static void StatementRegions(Statement stmt, List<IdRegion> regions, ModuleDefinition module) {
- Contract.Requires(stmt != null);
- Contract.Requires(regions != null);
- if (stmt is VarDeclStmt) {
- var s = (VarDeclStmt)stmt;
- // Add the variables here, once, and then go directly to the RHS's (without letting the sub-statements re-do the LHS's)
- foreach (var lhs in s.Lhss) {
- IdRegion.Add(regions, lhs.Tok, lhs, true, module);
- }
- if (s.Update == null) {
- // the VarDeclStmt has no associated assignment
- } else if (s.Update is UpdateStmt) {
- var upd = (UpdateStmt)s.Update;
- foreach (var rhs in upd.Rhss) {
- foreach (var ee in rhs.SubExpressions) {
- ExprRegions(ee, regions, module);
- }
- }
- } else {
- var upd = (AssignSuchThatStmt)s.Update;
- ExprRegions(upd.Expr, regions, module);
- }
- // we're done, so don't do the sub-statements/expressions again
- return;
- } else if (stmt is VarDecl) {
- var s = (VarDecl)stmt;
- IdRegion.Add(regions, s.Tok, s, true, module);
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- s.BoundVars.ForEach(bv => IdRegion.Add(regions, bv.tok, bv, true, module));
- } else if (stmt is MatchStmt) {
- var s = (MatchStmt)stmt;
- foreach (var kase in s.Cases) {
- kase.Arguments.ForEach(bv => IdRegion.Add(regions, bv.tok, bv, true, module));
- }
- } else if (stmt is LoopStmt) {
- var s = (LoopStmt)stmt;
- if (s.Mod.Expressions != null) {
- s.Mod.Expressions.ForEach(fe => FrameExprRegions(fe, regions, false, module));
- }
- }
- foreach (var ee in stmt.SubExpressions) {
- ExprRegions(ee, regions, module);
- }
- foreach (var ss in stmt.SubStatements) {
- StatementRegions(ss, regions, module);
- }
- }
-
- class IdRegion
- {
- public readonly int Start;
- public readonly int Length;
- public readonly string HoverText;
- public enum OccurrenceKind { Use, Definition, WildDefinition }
- public readonly OccurrenceKind Kind;
-
- static bool SurfaceSyntaxToken(Bpl.IToken tok) {
- Contract.Requires(tok != null);
- return !(tok is TokenWrapper);
- }
-
- public static void Add(List<IdRegion> regions, Bpl.IToken tok, IVariable v, bool isDefinition, ModuleDefinition context) {
- Contract.Requires(regions != null);
- Contract.Requires(tok != null);
- Contract.Requires(v != null);
- if (SurfaceSyntaxToken(tok)) {
- regions.Add(new IdRegion(tok, v, isDefinition, context));
- }
- }
- public static void Add(List<IdRegion> regions, Bpl.IToken tok, Field decl, Microsoft.Dafny.Type showType, string kind, bool isDefinition, ModuleDefinition context) {
- Contract.Requires(regions != null);
- Contract.Requires(tok != null);
- Contract.Requires(decl != null);
- Contract.Requires(kind != null);
- if (SurfaceSyntaxToken(tok)) {
- regions.Add(new IdRegion(tok, decl, showType, kind, isDefinition, context));
- }
- }
-
- private IdRegion(Bpl.IToken tok, IVariable v, bool isDefinition, ModuleDefinition context) {
- Contract.Requires(tok != null);
- Contract.Requires(v != null);
- Start = tok.pos;
- Length = v.DisplayName.Length;
- string kind;
- if (v is VarDecl) {
- kind = "local variable";
- } else if (v is BoundVar) {
- kind = "bound variable";
- } else {
- var formal = (Formal)v;
- kind = formal.InParam ? "in-parameter" : "out-parameter";
- }
- HoverText = string.Format("({2}{3}) {0}: {1}", v.DisplayName, v.Type.TypeName(context), v.IsGhost ? "ghost " : "", kind);
- Kind = !isDefinition ? OccurrenceKind.Use : VarDecl.HasWildcardName(v) ? OccurrenceKind.WildDefinition : OccurrenceKind.Definition;
- }
- private IdRegion(Bpl.IToken tok, Field decl, Microsoft.Dafny.Type showType, string kind, bool isDefinition, ModuleDefinition context) {
- Contract.Requires(tok != null);
- Contract.Requires(decl != null);
- Contract.Requires(kind != null);
- if (showType == null) {
- showType = decl.Type;
- }
- Start = tok.pos;
- Length = decl.Name.Length;
- HoverText = string.Format("({2}{3}) {0}: {1}", decl.FullNameInContext(context), showType.TypeName(context), decl.IsGhost ? "ghost " : "", kind);
- Kind = !isDefinition ? OccurrenceKind.Use : OccurrenceKind.Definition;
- }
- }
- }
-
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/OutliningTagger.cs b/Util/VS2010/DafnyExtension/DafnyExtension/OutliningTagger.cs
deleted file mode 100644
index a47cdba7..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/OutliningTagger.cs
+++ /dev/null
@@ -1,185 +0,0 @@
-//***************************************************************************
-// Copyright © 2010 Microsoft Corporation. All Rights Reserved.
-// This code released under the terms of the
-// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
-//***************************************************************************
-using EnvDTE;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.ComponentModel.Composition;
-using System.Windows.Threading;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Text.Projection;
-using Microsoft.VisualStudio.Utilities;
-using System.Diagnostics.Contracts;
-using Bpl = Microsoft.Boogie;
-using Dafny = Microsoft.Dafny;
-
-namespace DafnyLanguage
-{
- [Export(typeof(ITaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(IOutliningRegionTag))]
- internal sealed class OutliningTaggerProvider : ITaggerProvider
- {
- [Import]
- internal IBufferTagAggregatorFactoryService AggregatorFactory = null;
-
- public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
- ITagAggregator<DafnyResolverTag> tagAggregator = AggregatorFactory.CreateTagAggregator<DafnyResolverTag>(buffer);
- // create a single tagger for each buffer.
- Func<ITagger<T>> sc = delegate() { return new OutliningTagger(buffer, tagAggregator) as ITagger<T>; };
- return buffer.Properties.GetOrCreateSingletonProperty<ITagger<T>>(sc);
- }
- }
-
- /// <summary>
- /// Translate DafnyResolverTag's into IOutliningRegionTag's
- /// </summary>
- internal sealed class OutliningTagger : ITagger<IOutliningRegionTag>
- {
- ITextBuffer _buffer;
- ITextSnapshot _snapshot; // the most recent snapshot of _buffer that we have been informed about
- Dafny.Program _program; // the program parsed from _snapshot
- List<ORegion> _regions = new List<ORegion>(); // the regions generated from _program
- ITagAggregator<DafnyResolverTag> _aggregator;
-
- internal OutliningTagger(ITextBuffer buffer, ITagAggregator<DafnyResolverTag> tagAggregator) {
- _buffer = buffer;
- _snapshot = _buffer.CurrentSnapshot;
- _aggregator = tagAggregator;
- _aggregator.TagsChanged += new EventHandler<TagsChangedEventArgs>(_aggregator_TagsChanged);
- }
-
- /// <summary>
- /// Find the Error tokens in the set of all tokens and create an ErrorTag for each
- /// </summary>
- public IEnumerable<ITagSpan<IOutliningRegionTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0) yield break;
- // (A NormalizedSnapshotSpanCollection contains spans that all come from the same snapshot.)
- // The spans are ordered by the .Start component, and the collection contains no adjacent or abutting spans.
- // Hence, to find a span that includes all the ones in "spans", we only need to look at the .Start for the
- // first spand and the .End of the last span:
- var startPoint = spans[0].Start;
- var endPoint = spans[spans.Count - 1].End;
-
- // Note, (startPoint,endPoint) are points in the spans for which we're being asked to provide tags. We need to translate
- // these back into the most recent snapshot that we've computed regions for, namely _snapshot.
- var entire = new SnapshotSpan(startPoint, endPoint).TranslateTo(_snapshot, SpanTrackingMode.EdgeExclusive);
- int start = entire.Start;
- int end = entire.End;
- if (start == end) yield break;
-
- foreach (var r in _regions) {
- if (0 <= r.Length && r.Start <= end && start <= r.Start + r.Length) {
- yield return new TagSpan<OutliningRegionTag>(
- new SnapshotSpan(_snapshot, r.Start, r.Length),
- new OutliningRegionTag(false, false, "...", r.HoverText));
- }
- }
- }
-
- // the Classifier tagger is translating buffer change events into TagsChanged events, so we don't have to
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- void _aggregator_TagsChanged(object sender, TagsChangedEventArgs e) {
- var r = sender as ResolverTagger;
- if (r != null) {
- ITextSnapshot snap;
- Microsoft.Dafny.Program prog;
- lock (this) {
- snap = r._snapshot;
- prog = r._program;
- }
- if (prog != null) {
- if (!ComputeOutliningRegions(prog, snap))
- return; // no new regions
-
- var chng = TagsChanged;
- if (chng != null) {
- NormalizedSnapshotSpanCollection spans = e.Span.GetSpans(_buffer.CurrentSnapshot);
- if (spans.Count > 0) {
- SnapshotSpan span = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End);
- chng(this, new SnapshotSpanEventArgs(span));
- }
- }
- }
- }
- }
-
- bool ComputeOutliningRegions(Dafny.Program program, ITextSnapshot snapshot) {
- Contract.Requires(snapshot != null);
-
- if (program == _program)
- return false; // no new regions
-
- List<ORegion> newRegions = new List<ORegion>();
-
- foreach (var module in program.Modules) {
- if (!module.IsDefaultModule) {
- newRegions.Add(new ORegion(module, "module"));
- }
- foreach (Dafny.TopLevelDecl d in module.TopLevelDecls) {
- if (!HasBodyTokens(d) && !(d is Dafny.ClassDecl)) {
- continue;
- }
- if (d is Dafny.ArbitraryTypeDecl) {
- newRegions.Add(new ORegion(d, "type"));
- } else if (d is Dafny.CoDatatypeDecl) {
- newRegions.Add(new ORegion(d, "codatatype"));
- } else if (d is Dafny.DatatypeDecl) {
- newRegions.Add(new ORegion(d, "datatype"));
- } else if (d is Dafny.ModuleDecl) {
- // do nothing here, since the outer loop handles modules
- } else {
- Dafny.ClassDecl cl = (Dafny.ClassDecl)d;
- if (!cl.IsDefaultClass) {
- newRegions.Add(new ORegion(cl, "class"));
- }
- // do the class members (in particular, functions and methods)
- foreach (Dafny.MemberDecl m in cl.Members) {
- if (!HasBodyTokens(m)) {
- continue;
- }
- if (m is Dafny.Function && ((Dafny.Function)m).Body != null) {
- newRegions.Add(new ORegion(m, m is Dafny.CoPredicate ? "copredicate" : m is Dafny.Predicate ? "predicate" : "function"));
- } else if (m is Dafny.Method && ((Dafny.Method)m).Body != null) {
- newRegions.Add(new ORegion(m, m is Dafny.Constructor ? "constructor" : "method"));
- }
- }
- }
- }
- }
- _snapshot = snapshot;
- _regions = newRegions;
- _program = program;
- return true;
- }
-
- bool HasBodyTokens(Dafny.Declaration decl) {
- Contract.Requires(decl != null);
- return decl.BodyStartTok != Bpl.Token.NoToken && decl.BodyEndTok != Bpl.Token.NoToken;
- }
-
- class ORegion
- {
- public readonly int Start;
- public readonly int Length;
- public readonly string HoverText;
- public ORegion(Dafny.Declaration decl, string kind) {
- int startPosition = decl.BodyStartTok.pos + 1; // skip the open-curly brace itself
- int length = decl.BodyEndTok.pos - startPosition;
- Start = startPosition;
- Length = length;
- HoverText = string.Format("body of {0} {1}", kind, decl.Name);
- }
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/ProgressMargin.cs b/Util/VS2010/DafnyExtension/DafnyExtension/ProgressMargin.cs
deleted file mode 100644
index 7fdf38a6..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/ProgressMargin.cs
+++ /dev/null
@@ -1,260 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Windows.Threading;
-using System.Windows;
-using System.Windows.Shapes;
-using System.Windows.Media;
-using System.Windows.Controls;
-using System.ComponentModel.Composition;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Formatting;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Utilities;
-using System.Diagnostics.Contracts;
-using Dafny = Microsoft.Dafny;
-using Bpl = Microsoft.Boogie;
-
-
-namespace DafnyLanguage
-{
- #region UI stuff
- internal class ProgressMarginGlyphFactory : IGlyphFactory
- {
- public UIElement GenerateGlyph(IWpfTextViewLine line, IGlyphTag tag) {
- var dtag = tag as ProgressGlyphTag;
- if (dtag == null) {
- return null;
- }
-
- System.Windows.Shapes.Rectangle sh = new Rectangle() {
- Fill = dtag.Val == 0 ? Brushes.Violet : Brushes.DarkOrange,
- Height = 18.0,
- Width = 3.0
- };
- return sh;
- }
- }
-
- [Export(typeof(IGlyphFactoryProvider))]
- [Name("ProgressMarginGlyph")]
- [Order(After = "TokenTagger")]
- [ContentType("dafny")]
- [TagType(typeof(ProgressGlyphTag))]
- internal sealed class ProgressMarginGlyphFactoryProvider : IGlyphFactoryProvider
- {
- public IGlyphFactory GetGlyphFactory(IWpfTextView view, IWpfTextViewMargin margin) {
- return new ProgressMarginGlyphFactory();
- }
- }
-
- internal class ProgressGlyphTag : IGlyphTag
- {
- public readonly int Val;
- public ProgressGlyphTag(int val) {
- Val = val;
- }
- }
- #endregion
-
- [Export(typeof(ITaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(ProgressGlyphTag))]
- class ProgressTaggerProvider : ITaggerProvider
- {
- [Import]
- internal IBufferTagAggregatorFactoryService AggregatorFactory = null;
-
- [Import(typeof(Microsoft.VisualStudio.Shell.SVsServiceProvider))]
- internal IServiceProvider _serviceProvider = null;
-
- public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
- ITagAggregator<DafnyResolverTag> tagAggregator = AggregatorFactory.CreateTagAggregator<DafnyResolverTag>(buffer);
- // create a single tagger for each buffer.
- Func<ITagger<T>> sc = delegate() { return new ProgressTagger(buffer, _serviceProvider, tagAggregator) as ITagger<T>; };
- return buffer.Properties.GetOrCreateSingletonProperty<ITagger<T>>(sc);
- }
- }
-
- internal class ProgressTagger : ITagger<ProgressGlyphTag>
- {
- ErrorListProvider _errorProvider;
- ITextBuffer _buffer;
-
- readonly DispatcherTimer timer;
-
- public ProgressTagger(ITextBuffer buffer, IServiceProvider serviceProvider, ITagAggregator<DafnyResolverTag> tagAggregator) {
- _buffer = buffer;
- _errorProvider = new ErrorListProvider(serviceProvider);
-
- timer = new DispatcherTimer(DispatcherPriority.ApplicationIdle);
- timer.Interval = TimeSpan.FromMilliseconds(500);
- timer.Tick += new EventHandler(UponIdle);
-
- tagAggregator.TagsChanged += new EventHandler<TagsChangedEventArgs>(_aggregator_TagsChanged);
- buffer.Changed += new EventHandler<TextContentChangedEventArgs>(buffer_Changed);
- bufferChangesPostVerificationStart.Add(new SnapshotSpan(buffer.CurrentSnapshot, 0, buffer.CurrentSnapshot.Length));
- }
-
- public void Dispose() {
- }
-
- // The following fields and the contents of the following two lists are protected by the lock "this".
- List<SnapshotSpan> bufferChangesPreVerificationStart = new List<SnapshotSpan>(); // buffer changes after the last completed verification and before the currently running verification
- List<SnapshotSpan> bufferChangesPostVerificationStart = new List<SnapshotSpan>(); // buffer changes since the start of the currently running verification
-
- void buffer_Changed(object sender, TextContentChangedEventArgs e) {
- lock (this) {
- foreach (var change in e.Changes) {
- var startLine = e.After.GetLineFromPosition(change.NewPosition);
- var endLine = e.After.GetLineFromPosition(change.NewEnd);
- bufferChangesPostVerificationStart.Add(new SnapshotSpan(startLine.Start, endLine.End));
- }
- }
- }
-
- // The next field is protected by "this"
- ResolverTagger resolver;
- // Keep track of the most recent resolution results.
- void _aggregator_TagsChanged(object sender, TagsChangedEventArgs e) {
- var r = sender as ResolverTagger;
- if (r != null) {
- lock (this) {
- resolver = r;
- }
- timer.Stop();
- timer.Start();
- }
- }
-
- bool verificationInProgress; // this field is protected by "this". Invariant: !verificationInProgress ==> bufferChangesPreVerificationStart.Count == 0
- /// <summary>
- /// This method is invoked when the user has been idle for a little while.
- /// Note, "sender" and "args" are allowed to be passed in as null--they are not used by this method.
- /// </summary>
- public void UponIdle(object sender, EventArgs args) {
- Dafny.Program prog;
- ITextSnapshot snap;
- ResolverTagger r;
- lock (this) {
- if (verificationInProgress) {
- // This UponIdle message came at an inopportune time--we've already kicked off a verification.
- // Just back off.
- return;
- }
-
- if (resolver == null) return;
- lock (resolver) {
- prog = resolver._program;
- snap = resolver._snapshot;
- }
- r = resolver;
- resolver = null;
- if (prog == null) return;
- // We have a successfully resolved program to verify
-
- var resolvedVersion = snap.Version.VersionNumber;
- if (bufferChangesPostVerificationStart.Count == 0) {
- // Nothing new to verify. No reason to start a new verification.
- return;
- } else if (!bufferChangesPostVerificationStart.TrueForAll(span => span.Snapshot.Version.VersionNumber <= resolvedVersion)) {
- // There have been buffer changes since the program that was resolved. Do nothing here,
- // and instead just await the next resolved program.
- return;
- }
-
- // at this time, we're committed to running the verifier
- verificationInProgress = true;
-
- // Change orange progress markers into yellow ones
- Contract.Assert(bufferChangesPreVerificationStart.Count == 0); // follows from monitor invariant
- var empty = bufferChangesPreVerificationStart;
- bufferChangesPreVerificationStart = bufferChangesPostVerificationStart;
- bufferChangesPostVerificationStart = empty;
- // Notify to-whom-it-may-concern about the changes we just made
- var chng = TagsChanged;
- if (chng != null) {
- chng(this, new SnapshotSpanEventArgs(new SnapshotSpan(snap, 0, snap.Length)));
- }
-
- }
- new Thread(() => VerificationWorker(prog, snap, r)).Start();
- }
-
- /// <summary>
- /// Thread entry point.
- /// </summary>
- void VerificationWorker(Dafny.Program program, ITextSnapshot snapshot, ResolverTagger errorListHolder) {
- Contract.Requires(program != null);
- Contract.Requires(snapshot != null);
- Contract.Requires(errorListHolder != null);
-
- // Run the verifier
- var newErrors = new List<DafnyError>();
- try {
- bool success = DafnyDriver.Verify(program, errorInfo => {
- newErrors.Add(new DafnyError(errorInfo.Tok.line - 1, errorInfo.Tok.col - 1, ErrorCategory.VerificationError, errorInfo.Msg));
- foreach (var aux in errorInfo.Aux) {
- newErrors.Add(new DafnyError(aux.Tok.line - 1, aux.Tok.col - 1, ErrorCategory.AuxInformation, aux.Msg));
- }
- });
- if (!success) {
- newErrors.Add(new DafnyError(0, 0, ErrorCategory.InternalError, "verification process error"));
- }
- } catch (Exception e) {
- newErrors.Add(new DafnyError(0, 0, ErrorCategory.InternalError, "verification process error: " + e.Message));
- }
- errorListHolder.PopulateErrorList(newErrors, true, snapshot);
-
- lock (this) {
- bufferChangesPreVerificationStart.Clear();
- verificationInProgress = false;
- }
- // Notify to-whom-it-may-concern about the cleared pre-verification changes
- var chng = TagsChanged;
- if (chng != null) {
- chng(this, new SnapshotSpanEventArgs(new SnapshotSpan(snapshot, 0, snapshot.Length)));
- }
-
- // If new changes took place since we started the verification, we may need to kick off another verification
- // immediately.
- UponIdle(null, null);
- }
-
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
- IEnumerable<ITagSpan<ProgressGlyphTag>> ITagger<ProgressGlyphTag>.GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0) yield break;
- var targetSnapshot = spans[0].Snapshot;
-
- List<SnapshotSpan> pre;
- List<SnapshotSpan> post;
- lock (this) {
- pre = bufferChangesPreVerificationStart;
- post = bufferChangesPostVerificationStart;
- }
-
- // If the requested snapshot isn't the same as the one our words are on, translate our spans to the expected snapshot
- NormalizedSnapshotSpanCollection chs;
- chs = new NormalizedSnapshotSpanCollection(Map(pre, span => span.TranslateTo(targetSnapshot, SpanTrackingMode.EdgeExclusive)));
- foreach (SnapshotSpan span in NormalizedSnapshotSpanCollection.Overlap(spans, chs)) {
- yield return new TagSpan<ProgressGlyphTag>(span, new ProgressGlyphTag(0));
- }
- chs = new NormalizedSnapshotSpanCollection(Map(post, span => span.TranslateTo(targetSnapshot, SpanTrackingMode.EdgeExclusive)));
- foreach (SnapshotSpan span in NormalizedSnapshotSpanCollection.Overlap(spans, chs)) {
- yield return new TagSpan<ProgressGlyphTag>(span, new ProgressGlyphTag(1));
- }
- }
-
- /// <summary>
- /// (Why the firetruck isn't an extension method like this already in the standard library?)
- /// </summary>
- public static IEnumerable<TOut> Map<TIn, TOut>(IEnumerable<TIn> coll, System.Func<TIn, TOut> fn) {
- foreach (var e in coll) {
- yield return fn(e);
- }
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/Properties/AssemblyInfo.cs b/Util/VS2010/DafnyExtension/DafnyExtension/Properties/AssemblyInfo.cs
deleted file mode 100644
index b73b8410..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("EditorClassifier1")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("EditorClassifier1")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/ResolverTagger.cs b/Util/VS2010/DafnyExtension/DafnyExtension/ResolverTagger.cs
deleted file mode 100644
index d1af6878..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/ResolverTagger.cs
+++ /dev/null
@@ -1,321 +0,0 @@
-//***************************************************************************
-// Copyright © 2010 Microsoft Corporation. All Rights Reserved.
-// This code released under the terms of the
-// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
-//***************************************************************************
-using EnvDTE;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.ComponentModel.Composition;
-using System.Windows.Threading;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Text.Projection;
-using Microsoft.VisualStudio.TextManager.Interop;
-using Microsoft.VisualStudio.Utilities;
-using System.Diagnostics.Contracts;
-using Dafny = Microsoft.Dafny;
-
-namespace DafnyLanguage
-{
- [Export(typeof(ITaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(DafnyResolverTag))]
- internal sealed class ResolverTaggerProvider : ITaggerProvider
- {
- [Import(typeof(Microsoft.VisualStudio.Shell.SVsServiceProvider))]
- internal IServiceProvider _serviceProvider = null;
-
- [Import]
- ITextDocumentFactoryService _textDocumentFactory = null;
-
- public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
- // create a single tagger for each buffer.
- Func<ITagger<T>> sc = delegate() { return new ResolverTagger(buffer, _serviceProvider, _textDocumentFactory) as ITagger<T>; };
- return buffer.Properties.GetOrCreateSingletonProperty<ITagger<T>>(sc);
- }
- }
-
- public abstract class DafnyResolverTag : ITag
- {
- }
- public class DafnyErrorResolverTag : DafnyResolverTag
- {
- public readonly string Typ;
- public readonly string Msg;
- public DafnyErrorResolverTag(string typ, string msg) {
- Typ = typ;
- Msg = msg;
- }
- }
- public class DafnySuccessResolverTag : DafnyResolverTag
- {
- public readonly Dafny.Program Program;
- public DafnySuccessResolverTag(Dafny.Program program) {
- Program = program;
- }
- }
-
- /// <summary>
- /// Translate PkgDefTokenTags into ErrorTags and Error List items
- /// </summary>
- internal sealed class ResolverTagger : ITagger<DafnyResolverTag>, IDisposable
- {
- ITextBuffer _buffer;
- ITextDocument _document;
- // The _snapshot and _program fields should be updated and read together, so they are protected by "this"
- public ITextSnapshot _snapshot; // may be null
- public Dafny.Program _program; // non-null only if the snapshot contains a Dafny program that type checks
- List<DafnyError> _resolutionErrors = new List<DafnyError>(); // if nonempty, then _snapshot is the snapshot from which the errors were produced
- List<DafnyError> _verificationErrors = new List<DafnyError>();
- ErrorListProvider _errorProvider;
-
- internal ResolverTagger(ITextBuffer buffer, IServiceProvider serviceProvider, ITextDocumentFactoryService textDocumentFactory) {
- _buffer = buffer;
- if (!textDocumentFactory.TryGetTextDocument(_buffer, out _document))
- _document = null;
- _snapshot = null; // this makes sure the next snapshot will look different
- _errorProvider = new ErrorListProvider(serviceProvider);
-
- BufferIdleEventUtil.AddBufferIdleEventListener(_buffer, ResolveBuffer);
- }
-
- public void Dispose() {
- if (_errorProvider != null) {
- try {
- _errorProvider.Tasks.Clear();
- } catch (InvalidOperationException) {
- // this may occur if the SVsServiceProvider somehow has been uninstalled before our Dispose method is called
- }
- _errorProvider.Dispose();
- }
- BufferIdleEventUtil.RemoveBufferIdleEventListener(_buffer, ResolveBuffer);
- }
-
- public IEnumerable<DafnyError> AllErrors() {
- foreach (var err in _resolutionErrors) {
- yield return err;
- }
- if (_resolutionErrors.Count != 0) {
- // we're done
- yield break;
- }
- foreach (var err in _verificationErrors) {
- yield return err;
- }
- }
-
- /// <summary>
- /// Find the Error tokens in the set of all tokens and create an ErrorTag for each
- /// </summary>
- public IEnumerable<ITagSpan<DafnyResolverTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0) yield break;
- var currentSnapshot = spans[0].Snapshot;
- foreach (var err in AllErrors()) {
- if (err.Category != ErrorCategory.ProcessError) {
- var span = err.Span().TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive);
- string ty; // the COLORs below indicate what I see on my machine
- switch (err.Category) {
- default: // unexpected category
- case ErrorCategory.ParseError:
- case ErrorCategory.ParseWarning:
- ty = "syntax error"; break; // COLOR: red
- case ErrorCategory.ResolveError:
- ty = "compiler error"; break; // COLOR: blue
- case ErrorCategory.VerificationError:
- ty = "error"; break; // COLOR: red
- case ErrorCategory.AuxInformation:
- ty = "other error"; break; // COLOR: purple red
- case ErrorCategory.InternalError:
- ty = "error"; break; // COLOR: red
- }
- yield return new TagSpan<DafnyResolverTag>(span, new DafnyErrorResolverTag(ty, err.Message));
- }
- }
-
- ITextSnapshot snap;
- Dafny.Program prog;
- lock (this) {
- snap = _snapshot;
- prog = _program;
- }
- if (prog != null) {
- yield return new TagSpan<DafnyResolverTag>(new SnapshotSpan(snap, 0, snap.Length), new DafnySuccessResolverTag(prog));
- }
- }
-
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- /// <summary>
- /// Calls the Dafny parser/resolver/type checker on the contents of the buffer, updates the Error List accordingly.
- /// </summary>
- void ResolveBuffer(object sender, EventArgs args) {
- ITextSnapshot snapshot = _buffer.CurrentSnapshot;
- if (snapshot == _snapshot)
- return; // we've already done this snapshot
- NormalizedSnapshotSpanCollection spans = new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length));
-
- var driver = new DafnyDriver(snapshot.GetText(), _document != null ? _document.FilePath : "<program>");
- List<DafnyError> newErrors;
- Dafny.Program program;
- try {
- program = driver.ProcessResolution();
- newErrors = driver.Errors;
- } catch (Exception e) {
- newErrors = new List<DafnyError>();
- newErrors.Add(new DafnyError(0, 0, ErrorCategory.InternalError, "internal Dafny error: " + e.Message));
- program = null;
- }
-
- lock (this) {
- _snapshot = snapshot;
- _program = program;
- }
- PopulateErrorList(newErrors, false, snapshot);
- }
-
- public void PopulateErrorList(List<DafnyError> newErrors, bool verificationErrors, ITextSnapshot snapshot) {
- Contract.Requires(newErrors != null);
- foreach (var err in newErrors) {
- err.FillInSnapshot(snapshot);
- }
- if (verificationErrors) {
- _verificationErrors = newErrors;
- } else {
- _resolutionErrors = newErrors;
- }
-
- _errorProvider.SuspendRefresh(); // reduce flickering
- _errorProvider.Tasks.Clear();
- foreach (var err in AllErrors()) {
- ErrorTask task = new ErrorTask() {
- Category = TaskCategory.BuildCompile,
- ErrorCategory = CategoryConversion(err.Category),
- Text = err.Message,
- Line = err.Line,
- Column = err.Column
- };
- if (_document != null) {
- task.Document = _document.FilePath;
- }
- if (err.Category != ErrorCategory.ProcessError && err.Category != ErrorCategory.InternalError) {
- task.Navigate += new EventHandler(NavigateHandler);
- }
- _errorProvider.Tasks.Add(task);
- }
- _errorProvider.ResumeRefresh();
- var chng = TagsChanged;
- if (chng != null)
- chng(this, new SnapshotSpanEventArgs(new SnapshotSpan(snapshot, 0, snapshot.Length)));
- }
-
- TaskErrorCategory CategoryConversion(ErrorCategory cat) {
- switch (cat) {
- case ErrorCategory.ParseError:
- case ErrorCategory.ResolveError:
- case ErrorCategory.VerificationError:
- case ErrorCategory.InternalError:
- return TaskErrorCategory.Error;
- case ErrorCategory.ParseWarning:
- return TaskErrorCategory.Warning;
- case ErrorCategory.AuxInformation:
- return TaskErrorCategory.Message;
- default:
- Contract.Assert(false); // unexpected category
- return TaskErrorCategory.Error; // please compiler
- }
- }
-
- void NavigateHandler(object sender, EventArgs arguments) {
- var task = sender as ErrorTask;
- if (task == null || task.Document == null)
- return;
-
- // This would have been the simple way of doing things:
- // _errorProvider.Navigate(error, new Guid(EnvDTE.Constants.vsViewKindCode));
- // Unfortunately, it doesn't work--it seems to ignore the column position. (Moreover, it wants 1-based
- // line/column numbers, whereas the Error Task pane wants 0-based line/column numbers.)
- // So, instead we do all the things that follow:
-
- var openDoc = Package.GetGlobalService(typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument;
- if (openDoc == null)
- return;
-
- IVsWindowFrame frame;
- Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp;
- IVsUIHierarchy hier;
- uint itemid;
- Guid logicalView = VSConstants.LOGVIEWID_Code;
- if (Microsoft.VisualStudio.ErrorHandler.Failed(openDoc.OpenDocumentViaProject(task.Document, ref logicalView, out sp, out hier, out itemid, out frame)) || frame == null)
- return;
-
- object docData;
- Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out docData));
-
- // Get the VsTextBuffer
- VsTextBuffer buffer = docData as VsTextBuffer;
- if (buffer == null) {
- IVsTextBufferProvider bufferProvider = docData as IVsTextBufferProvider;
- if (bufferProvider != null) {
- IVsTextLines lines;
- Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(bufferProvider.GetTextBuffer(out lines));
- buffer = lines as VsTextBuffer;
- if (buffer == null)
- return;
- }
- }
-
- VsTextManager textManager = Package.GetGlobalService(typeof(VsTextManagerClass)) as VsTextManager;
- if (textManager == null)
- return;
-
- // Finally, move the cursor
- Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(textManager.NavigateToLineAndColumn(buffer, ref logicalView, task.Line, task.Column, task.Line, task.Column));
- }
-
- }
-
- public enum ErrorCategory
- {
- ProcessError, ParseWarning, ParseError, ResolveError, VerificationError, AuxInformation, InternalError
- }
-
- internal class DafnyError
- {
- public readonly int Line; // 0 based
- public readonly int Column; // 0 based
- ITextSnapshot Snapshot; // filled in during the FillInSnapshot call
- public readonly ErrorCategory Category;
- public readonly string Message;
- /// <summary>
- /// "line" and "col" are expected to be 0-based
- /// </summary>
- public DafnyError(int line, int col, ErrorCategory cat, string msg) {
- Contract.Requires(0 <= line);
- Contract.Requires(0 <= col);
- Line = line;
- Column = col;
- Category = cat;
- Message = msg;
- }
-
- public void FillInSnapshot(ITextSnapshot snapshot) {
- Contract.Requires(snapshot != null);
- Snapshot = snapshot;
- }
- public SnapshotSpan Span() {
- Contract.Requires(Snapshot != null); // requires that Snapshot has been filled in
- var line = Snapshot.GetLineFromLineNumber(Line);
- Contract.Assume(Column <= line.Length); // this is really a precondition of the constructor + FillInSnapshot
- var length = Math.Min(line.Length - Column, 5);
- return new SnapshotSpan(line.Start + Column, length);
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs b/Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs
deleted file mode 100644
index 2f295429..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs
+++ /dev/null
@@ -1,342 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.ComponentModel.Composition;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Utilities;
-using Dafny = Microsoft.Dafny;
-
-namespace DafnyLanguage
-{
- [Export(typeof(ITaggerProvider))]
- [ContentType("dafny")]
- [TagType(typeof(DafnyTokenTag))]
- internal sealed class DafnyTokenTagProvider : ITaggerProvider
- {
- public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
- return new DafnyTokenTagger(buffer) as ITagger<T>;
- }
- }
-
- public enum DafnyTokenKinds
- {
- Keyword, Number, String, Comment,
- VariableIdentifier, VariableIdentifierDefinition
- }
-
- public class DafnyTokenTag : ITag
- {
- public DafnyTokenKinds Kind { get; private set; }
- public string HoverText { get; private set; }
-
- public DafnyTokenTag(DafnyTokenKinds kind) {
- this.Kind = kind;
- }
-
- public DafnyTokenTag(DafnyTokenKinds kind, string hoverText) {
- this.Kind = kind;
- this.HoverText = hoverText;
- }
- }
-
- internal sealed class DafnyTokenTagger : ITagger<DafnyTokenTag>
- {
- ITextBuffer _buffer;
- ITextSnapshot _snapshot;
- List<DRegion> _regions;
-
- internal DafnyTokenTagger(ITextBuffer buffer) {
- _buffer = buffer;
- _snapshot = buffer.CurrentSnapshot;
- _regions = Rescan(_snapshot);
-
- _buffer.Changed += new EventHandler<TextContentChangedEventArgs>(ReparseFile);
- }
-
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- public IEnumerable<ITagSpan<DafnyTokenTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (spans.Count == 0)
- yield break;
-
- List<DRegion> currentRegions = _regions;
- ITextSnapshot currentSnapshot = _snapshot;
-
- // create a new SnapshotSpan for the entire region encompassed by the span collection
- SnapshotSpan entire = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End).TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive);
-
- // return tags for any regions that fall within that span
- // BUGBUG: depending on how GetTags gets called (e.g., once for each line in the buffer), this may produce quadratic behavior
- foreach (var region in currentRegions) {
- if (entire.IntersectsWith(region.Span)) {
- yield return new TagSpan<DafnyTokenTag>(new SnapshotSpan(region.Start, region.End), new DafnyTokenTag(region.Kind));
- }
- }
- }
-
- /// <summary>
- /// Find all of the tag regions in the document (snapshot) and notify
- /// listeners of any that changed
- /// </summary>
- void ReparseFile(object sender, TextContentChangedEventArgs args) {
- ITextSnapshot snapshot = _buffer.CurrentSnapshot;
- if (snapshot == _snapshot)
- return; // we've already computed the regions for this snapshot
-
- // get all of the outline regions in the snapshot
- List<DRegion> newRegions = Rescan(snapshot);
-
- // determine the changed span, and send a changed event with the new spans
- List<SnapshotSpan> oldSpans = new List<SnapshotSpan>(_regions.Select(r =>
- r.Span.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive)));
-
- List<SnapshotSpan> newSpans = new List<SnapshotSpan>(newRegions.Select(r => r.Span));
-
- NormalizedSnapshotSpanCollection oldSpanCollection = new NormalizedSnapshotSpanCollection(oldSpans);
- NormalizedSnapshotSpanCollection newSpanCollection = new NormalizedSnapshotSpanCollection(newSpans);
-
- NormalizedSnapshotSpanCollection difference = SymmetricDifference(oldSpanCollection, newSpanCollection);
-
- // save the new baseline
- _snapshot = snapshot;
- _regions = newRegions;
-
- var chng = TagsChanged;
- if (chng != null) {
- foreach (var span in difference) {
- chng(this, new SnapshotSpanEventArgs(span));
- }
- }
- }
-
- NormalizedSnapshotSpanCollection SymmetricDifference(NormalizedSnapshotSpanCollection first, NormalizedSnapshotSpanCollection second) {
- return NormalizedSnapshotSpanCollection.Union(
- NormalizedSnapshotSpanCollection.Difference(first, second),
- NormalizedSnapshotSpanCollection.Difference(second, first));
- }
-
- private static List<DRegion> Rescan(ITextSnapshot newSnapshot) {
- List<DRegion> newRegions = new List<DRegion>();
-
- bool stillScanningLongComment = false;
- SnapshotPoint commentStart = new SnapshotPoint(); // used only when stillScanningLongComment
- SnapshotPoint commentEndAsWeKnowIt = new SnapshotPoint(); // used only when stillScanningLongComment
- foreach (ITextSnapshotLine line in newSnapshot.Lines) {
- string txt = line.GetText(); // the current line (without linebreak characters)
- int N = txt.Length; // length of the current line
- int cur = 0; // offset into the current line
-
- if (stillScanningLongComment) {
- if (ScanForEndOfComment(txt, ref cur)) {
- newRegions.Add(new DRegion(commentStart, new SnapshotPoint(newSnapshot, line.Start + cur), DafnyTokenKinds.Comment));
- stillScanningLongComment = false;
- } else {
- commentEndAsWeKnowIt = new SnapshotPoint(newSnapshot, line.Start + cur);
- }
- }
-
- // repeatedly get the remaining tokens from this line
- int end; // offset into the current line
- for (; ; cur = end) {
- // advance to the first character of a keyword or token
- DafnyTokenKinds ty = DafnyTokenKinds.Keyword;
- for (; ; cur++) {
- if (N <= cur) {
- // we've looked at everything in this line
- goto OUTER_CONTINUE;
- }
- char ch = txt[cur];
- if ('a' <= ch && ch <= 'z') break;
- if ('A' <= ch && ch <= 'Z') break;
- if ('0' <= ch && ch <= '9') { ty = DafnyTokenKinds.Number; break; }
- if (ch == '"') { ty = DafnyTokenKinds.String; break; }
- if (ch == '/') { ty = DafnyTokenKinds.Comment; break; }
- if (ch == '\'' || ch == '_' || ch == '?' || ch == '\\') break; // parts of identifiers
- }
-
- // advance to the end of the token
- end = cur + 1; // offset into the current line
- if (ty == DafnyTokenKinds.Number) {
- // scan the rest of this number
- for (; end < N; end++) {
- char ch = txt[end];
- if ('0' <= ch && ch <= '9') {
- } else break;
- }
- } else if (ty == DafnyTokenKinds.String) {
- // scan the rest of this string, but not past the end-of-line
- for (; end < N; end++) {
- char ch = txt[end];
- if (ch == '"') {
- end++; break;
- } else if (ch == '\\') {
- // escape sequence
- end++;
- if (end == N) { break; }
- ch = txt[end];
- if (ch == 'u') {
- end += 4;
- if (N <= end) { end = N; break; }
- }
- }
- }
- } else if (ty == DafnyTokenKinds.Comment) {
- if (end == N) continue; // this was not the start of a comment
- char ch = txt[end];
- if (ch == '/') {
- // a short comment
- end = N;
- } else if (ch == '*') {
- // a long comment; find the matching "*/"
- end++;
- commentStart = new SnapshotPoint(newSnapshot, line.Start + cur);
- if (ScanForEndOfComment(txt, ref end)) {
- newRegions.Add(new DRegion(commentStart, new SnapshotPoint(newSnapshot, line.Start + end), DafnyTokenKinds.Comment));
- } else {
- stillScanningLongComment = true;
- commentEndAsWeKnowIt = new SnapshotPoint(newSnapshot, line.Start + end);
- }
- continue;
- } else {
- // not a comment
- continue;
- }
- } else {
- int trailingDigits = 0;
- for (; end < N; end++) {
- char ch = txt[end];
- if ('a' <= ch && ch <= 'z') {
- trailingDigits = 0;
- } else if ('A' <= ch && ch <= 'Z') {
- trailingDigits = 0;
- } else if ('0' <= ch && ch <= '9') {
- trailingDigits++;
- } else if (ch == '\'' || ch == '_' || ch == '?' || ch == '\\') {
- trailingDigits = 0;
- } else break;
- }
- // we have a keyword or an identifier
- string s = txt.Substring(cur, end - cur);
- if (0 < trailingDigits && s.Length == 5 + trailingDigits && s.StartsWith("array") && s[5] != '0' && (trailingDigits != 1 || s[5] != '1')) {
- // this is a keyword (array2, array3, ...)
- } else {
- switch (s) {
- #region keywords
- case "allocated":
- case "array":
- case "as":
- case "assert":
- case "assume":
- case "bool":
- case "break":
- case "calc":
- case "case":
- case "choose":
- case "class":
- case "codatatype":
- case "constructor":
- case "copredicate":
- case "datatype":
- case "decreases":
- case "else":
- case "ensures":
- case "exists":
- case "false":
- case "forall":
- case "free":
- case "fresh":
- case "function":
- case "ghost":
- case "if":
- case "import":
- case "in":
- case "int":
- case "invariant":
- case "iterator":
- case "label":
- case "match":
- case "method":
- case "modifies":
- case "module":
- case "multiset":
- case "nat":
- case "new":
- case "null":
- case "object":
- case "old":
- case "opened":
- case "parallel":
- case "predicate":
- case "print":
- case "reads":
- case "refines":
- case "requires":
- case "result":
- case "return":
- case "returns":
- case "seq":
- case "set":
- case "static":
- case "then":
- case "this":
- case "true":
- case "type":
- case "var":
- case "while":
- case "yield":
- case "yields":
- #endregion
- break;
- default:
- continue; // it was an identifier
- }
- }
- }
-
- newRegions.Add(new DRegion(new SnapshotPoint(newSnapshot, line.Start + cur), new SnapshotPoint(newSnapshot, line.Start + end), ty));
- }
- OUTER_CONTINUE: ;
- }
-
- if (stillScanningLongComment) {
- newRegions.Add(new DRegion(commentStart, commentEndAsWeKnowIt, DafnyTokenKinds.Comment));
- }
-
- return newRegions;
- }
-
- private static bool ScanForEndOfComment(string txt, ref int end) {
- int N = txt.Length;
- for (; end < N; end++) {
- char ch = txt[end];
- if (ch == '*' && end + 1 < N) {
- ch = txt[end + 1];
- if (ch == '/') {
- end += 2;
- return true;
- }
- }
- }
- return false; // hit end-of-line without finding end-of-comment
- }
- }
-
- internal class DRegion
- {
- public SnapshotPoint Start { get; private set; }
- public SnapshotPoint End { get; private set; }
- public SnapshotSpan Span {
- get { return new SnapshotSpan(Start, End); }
- }
- public DafnyTokenKinds Kind { get; private set; }
-
- public DRegion(SnapshotPoint start, SnapshotPoint end, DafnyTokenKinds kind) {
- Start = start;
- End = end;
- Kind = kind;
- }
- }
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/WordHighlighter.cs b/Util/VS2010/DafnyExtension/DafnyExtension/WordHighlighter.cs
deleted file mode 100644
index 03456c85..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/WordHighlighter.cs
+++ /dev/null
@@ -1,211 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.Linq;
-using System.Threading;
-using System.Windows.Media;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Classification;
-using Microsoft.VisualStudio.Text.Editor;
-using Microsoft.VisualStudio.Text.Operations;
-using Microsoft.VisualStudio.Text.Tagging;
-using Microsoft.VisualStudio.Utilities;
-
-namespace DafnyLanguage
-{
-#if LATER_MAYBE
- #region // (the current annoying) word highligher
- internal class HighlightWordTagger : ITagger<HighlightWordTag>
- {
- ITextView View { get; set; }
- ITextBuffer SourceBuffer { get; set; }
- ITextSearchService TextSearchService { get; set; }
- ITextStructureNavigator TextStructureNavigator { get; set; }
- NormalizedSnapshotSpanCollection WordSpans { get; set; }
- SnapshotSpan? CurrentWord { get; set; }
- SnapshotPoint RequestedPoint { get; set; }
- object updateLock = new object();
-
- public HighlightWordTagger(ITextView view, ITextBuffer sourceBuffer, ITextSearchService textSearchService,
- ITextStructureNavigator textStructureNavigator) {
- this.View = view;
- this.SourceBuffer = sourceBuffer;
- this.TextSearchService = textSearchService;
- this.TextStructureNavigator = textStructureNavigator;
- this.WordSpans = new NormalizedSnapshotSpanCollection();
- this.CurrentWord = null;
- this.View.Caret.PositionChanged += CaretPositionChanged;
- this.View.LayoutChanged += ViewLayoutChanged;
- }
-
- void ViewLayoutChanged(object sender, TextViewLayoutChangedEventArgs e) {
- // If a new snapshot wasn't generated, then skip this layout
- if (e.NewSnapshot != e.OldSnapshot) {
- UpdateAtCaretPosition(View.Caret.Position);
- }
- }
-
- void CaretPositionChanged(object sender, CaretPositionChangedEventArgs e) {
- UpdateAtCaretPosition(e.NewPosition);
- }
-
- public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
- void UpdateAtCaretPosition(CaretPosition caretPosition) {
- SnapshotPoint? point = caretPosition.Point.GetPoint(SourceBuffer, caretPosition.Affinity);
-
- if (!point.HasValue)
- return;
-
- // If the new caret position is still within the current word (and on the same snapshot), we don't need to check it
- if (CurrentWord.HasValue
- && CurrentWord.Value.Snapshot == View.TextSnapshot
- && CurrentWord.Value.Start <= point.Value && point.Value <= CurrentWord.Value.End) {
- return;
- }
-
- RequestedPoint = point.Value;
- UpdateWordAdornments();
- }
-
- void UpdateWordAdornments() {
- SnapshotPoint currentRequest = RequestedPoint;
- List<SnapshotSpan> wordSpans = new List<SnapshotSpan>();
- //Find all words in the buffer like the one the caret is on
- TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest);
- bool foundWord = true;
- //If we've selected something not worth highlighting, we might have missed a "word" by a little bit
- if (!WordExtentIsValid(currentRequest, word)) {
- //Before we retry, make sure it is worthwhile
- if (word.Span.Start != currentRequest
- || currentRequest == currentRequest.GetContainingLine().Start
- || char.IsWhiteSpace((currentRequest - 1).GetChar())) {
- foundWord = false;
- } else {
- // Try again, one character previous.
- //If the caret is at the end of a word, pick up the word.
- word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1);
-
- //If the word still isn't valid, we're done
- if (!WordExtentIsValid(currentRequest, word))
- foundWord = false;
- }
- }
-
- if (!foundWord) {
- //If we couldn't find a word, clear out the existing markers
- SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null);
- return;
- }
-
- SnapshotSpan currentWord = word.Span;
- //If this is the current word, and the caret moved within a word, we're done.
- if (CurrentWord.HasValue && currentWord == CurrentWord)
- return;
-
- //Find the new spans
- FindData findData = new FindData(currentWord.GetText(), currentWord.Snapshot);
- findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase;
-
- wordSpans.AddRange(TextSearchService.FindAll(findData));
-
- //If another change hasn't happened, do a real update
- if (currentRequest == RequestedPoint)
- SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord);
- }
-
- static bool WordExtentIsValid(SnapshotPoint currentRequest, TextExtent word) {
- return word.IsSignificant
- && currentRequest.Snapshot.GetText(word.Span).Any(c => char.IsLetter(c));
- }
-
- void SynchronousUpdate(SnapshotPoint currentRequest, NormalizedSnapshotSpanCollection newSpans, SnapshotSpan? newCurrentWord) {
- lock (updateLock) {
- if (currentRequest != RequestedPoint)
- return;
-
- WordSpans = newSpans;
- CurrentWord = newCurrentWord;
-
- var chngd = TagsChanged;
- if (chngd != null)
- chngd(this, new SnapshotSpanEventArgs(new SnapshotSpan(SourceBuffer.CurrentSnapshot, 0, SourceBuffer.CurrentSnapshot.Length)));
- }
- }
-
- public IEnumerable<ITagSpan<HighlightWordTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
- if (CurrentWord == null)
- yield break;
-
- // Hold on to a "snapshot" of the word spans and current word, so that we maintain the same
- // collection throughout
- SnapshotSpan currentWord = CurrentWord.Value;
- NormalizedSnapshotSpanCollection wordSpans = WordSpans;
-
- if (spans.Count == 0 || WordSpans.Count == 0)
- yield break;
-
- // If the requested snapshot isn't the same as the one our words are on, translate our spans to the expected snapshot
- if (spans[0].Snapshot != wordSpans[0].Snapshot) {
- wordSpans = new NormalizedSnapshotSpanCollection(
- wordSpans.Select(span => span.TranslateTo(spans[0].Snapshot, SpanTrackingMode.EdgeExclusive)));
-
- currentWord = currentWord.TranslateTo(spans[0].Snapshot, SpanTrackingMode.EdgeExclusive);
- }
-
- // First, yield back the word the cursor is under (if it overlaps)
- // Note that we'll yield back the same word again in the wordspans collection;
- // the duplication here is expected.
- if (spans.OverlapsWith(new NormalizedSnapshotSpanCollection(currentWord)))
- yield return new TagSpan<HighlightWordTag>(currentWord, new HighlightWordTag());
-
- // Second, yield all the other words in the file
- foreach (SnapshotSpan span in NormalizedSnapshotSpanCollection.Overlap(spans, wordSpans)) {
- yield return new TagSpan<HighlightWordTag>(span, new HighlightWordTag());
- }
- }
- }
-
- internal class HighlightWordTag : TextMarkerTag
- {
- public HighlightWordTag() : base("MarkerFormatDefinition/HighlightWordFormatDefinition") { }
- }
-
- [Export(typeof(EditorFormatDefinition))]
- [Name("MarkerFormatDefinition/HighlightWordFormatDefinition")]
- [UserVisible(true)]
- internal class HighlightWordFormatDefinition : MarkerFormatDefinition
- {
- public HighlightWordFormatDefinition() {
- this.BackgroundColor = Colors.LightBlue;
- this.ForegroundColor = Colors.DarkBlue;
- this.DisplayName = "Highlight Word";
- this.ZOrder = 5;
- }
- }
-
- [Export(typeof(IViewTaggerProvider))]
- [ContentType("text")]
- [TagType(typeof(TextMarkerTag))]
- internal class HighlightWordTaggerProvider : IViewTaggerProvider
- {
- [Import]
- internal ITextSearchService TextSearchService { get; set; }
-
- [Import]
- internal ITextStructureNavigatorSelectorService TextStructureNavigatorSelector { get; set; }
-
- public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag {
- //provide highlighting only on the top buffer
- if (textView.TextBuffer != buffer)
- return null;
-
- ITextStructureNavigator textStructureNavigator =
- TextStructureNavigatorSelector.GetTextStructureNavigator(buffer);
-
- return new HighlightWordTagger(textView, buffer, TextSearchService, textStructureNavigator) as ITagger<T>;
- }
- }
-#endregion
-#endif
-}
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/source.extension.vsixmanifest b/Util/VS2010/DafnyExtension/DafnyExtension/source.extension.vsixmanifest
deleted file mode 100644
index ef5c1cf5..00000000
--- a/Util/VS2010/DafnyExtension/DafnyExtension/source.extension.vsixmanifest
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Vsix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
- <Identifier Id="DafnyLanguageMode.Microsoft.6c7ed99a-206a-4937-9e08-b389de175f68">
- <Name>DafnyLanguageMode</Name>
- <Author>Microsoft Research</Author>
- <Version>1.0</Version>
- <Description xml:space="preserve">This is a language mode for using the Dafny language inside Visual Studio.</Description>
- <Locale>1033</Locale>
- <SupportedProducts>
- <VisualStudio Version="10.0">
- <Edition>Pro</Edition>
- </VisualStudio>
- <VisualStudio Version="11.0">
- <Edition>Pro</Edition>
- </VisualStudio>
- </SupportedProducts>
- <SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.0" />
- </Identifier>
- <References />
- <Content>
- <MefComponent>|%CurrentProject%|</MefComponent>
- <CustomExtension Type="Boogie">DafnyPrelude.bpl</CustomExtension>
- <CustomExtension Type="SMTLib 2">UnivBackPred2.smt2</CustomExtension>
- </Content>
-</Vsix>
diff --git a/Util/latex/chalice.sty b/Util/latex/chalice.sty
deleted file mode 100644
index a04d6f23..00000000
--- a/Util/latex/chalice.sty
+++ /dev/null
@@ -1,63 +0,0 @@
-\usepackage{listings}
-%\lstloadlanguages{C}
-\lstdefinestyle{chalice}{%
- numbers=none,
- firstnumber=0,
- numberstyle=\tiny,
- stepnumber=5,
-% basicstyle=\scriptsize\sffamily,%
-% commentstyle=\itshape,%
-% keywordstyle=\bfseries,%
-% ndkeywordstyle=\bfseries,%
-% language=[Sharp]C,
- morekeywords={%
- above,acc,acquire,and,assert,assigned,assume,%
- below,between,bool,%
- call,class,const,%
- downgrade,%
- else,ensures,eval,exists,%
- false,fold,forall,fork,free,function,%
- ghost,%
- holds,%
- if,in,int,invariant,ite,%
- join,%
- lock,lockbottom,lockchange,%
- method,module,%
- new,nil,null,%
- old,%
- predicate,%
- rd,reorder,release,requires,result,returns,%
- seq,share,string,%
- this,token,true,%
- unfold,unfolding,unshare,%
- var,%
- waitlevel,while},
- literate=%
- {=}{{=~}}1%
- {+=}{{+}{=}~}3%
- {-=}{{-}{=}~}3%
- {*=}{{*}{=}~}3%
- {++}{{+}{+}}2%
- {--}{{-}{-}}2%
- {==}{==}2%
- {<=}{<=}2%
- {=>}{=>}2%
- {==>}{==>}3 %
- {<==>}{<==>}4 %
-%% % {!}{$\lnot$}1% don't do this if ! is also used to indicate non-null types
- {!=}{!=}2%
-}%
-\lstnewenvironment{chalice}[1][]{%
- \lstset{style=chalice,
- floatplacement={tbp},showstringspaces=false,captionpos=b,
- frame=lines,xleftmargin=8pt,xrightmargin=8pt,basicstyle=\ttfamily,#1}}{}%
-\lstnewenvironment{chaliceNoLines}[1][]{%
- \lstset{style=chalice,
- floatplacement={tbp},showstringspaces=false,captionpos=b,
- xleftmargin=8pt,xrightmargin=8pt,basicstyle=\ttfamily,#1}}{}%
-\def\S{%
- \lstinline[style=chalice,basicstyle=\ttfamily,columns=fixed]}
-\newcommand{\lstfile}[1]{
- \lstinputlisting[style=chalice,%
- frame=lines,xleftmargin=8pt,xrightmargin=8pt,basicstyle=\ttfamily,columns=fixed]{#1}
-}
diff --git a/Util/latex/dafny.sty b/Util/latex/dafny.sty
deleted file mode 100644
index 879b90cb..00000000
--- a/Util/latex/dafny.sty
+++ /dev/null
@@ -1,110 +0,0 @@
-% dafny.sty
-% Dafny mode for the LaTeX listings package.
-% Rustan Leino, 22 June 2008.
-
-\usepackage{listings}
-
-\lstdefinelanguage{dafny}{
- morekeywords={class,datatype,codatatype,type,iterator,
- bool,nat,int,object,set,multiset,seq,array,array2,array3,map,
- function,predicate,copredicate,
- ghost,var,static,refines,
- method,constructor,returns,yields,module,import,default,opened,as,in,
- requires,modifies,ensures,reads,decreases,free,
- % expressions
- match,case,false,true,null,old,fresh,choose,this,
- % statements
- assert,assume,print,new,if,then,else,while,invariant,break,label,return,yield,
- parallel,where,calc
- },
- literate=%
- {:}{$\colon$}1
- {::}{$\bullet$}2
- {:=}{$:$$=$}2
- {!}{$\lnot$}1
- {!!}{$\not\cap$}1
- {==}{$=$}1
- {!=}{$\neq$}1
- {&&}{$\land$}1
- {||}{$\lor$}1
- {<=}{$\le$}1
- {>=}{$\ge$}1
- % the following isn't actually Dafny, but it gives the option to produce nicer latex
- {|=>}{$\Rightarrow$}2
- {<=set}{$\subseteq$}1
- {+set}{$\cup$}1
- {*set}{$\cap$}1
- {==>}{$\Longrightarrow$}3
- {=>}{$\Rightarrow$}2
- {<==>}{$\Longleftrightarrow$}4
- {forall}{$\forall$}1
- {exists}{$\exists$}1
- {!in}{$\not\in$}1
- {\\in}{$\in$}1
- % the following isn't actually Dafny, but it gives the option to produce nicer latex
- {<<}{$\langle$}1
- {>>}{$\rangle$}1
- {(==)}{${}^{(=)}$}2
- {...}{$\ldots$}1
- {\\alpha}{$\alpha$}1
- {\\beta}{$\beta$}1
- {\\gamma}{$\gamma$}1
- {\\delta}{$\delta$}1
- {\\epsilon}{$\epsilon$}1
- {\\zeta}{$\zeta$}1
- {\\eta}{$\eta$}1
- {\\theta}{$\theta$}1
- {\\iota}{$\iota$}1
- {\\kappa}{$\kappa$}1
- {\\lambda}{$\lambda$}1
- {\\mu}{$\mu$}1
- {\\nu}{$\nu$}1
- {\\xi}{$\xi$}1
- {\\pi}{$\pi$}1
- {\\rho}{$\rho$}1
- {\\sigma}{$\sigma$}1
- {\\tau}{$\tau$}1
- {\\upsilon}{$\upsilon$}1
- {\\phi}{$\phi$}1
- {\\chi}{$\chi$}1
- {\\psi}{$\psi$}1
- {\\omega}{$\omega$}1
- {\\Gamma}{$\Gamma$}1
- {\\Delta}{$\Delta$}1
- {\\Theta}{$\Theta$}1
- {\\Lambda}{$\Lambda$}1
- {\\Xi}{$\Xi$}1
- {\\Pi}{$\Pi$}1
- {\\Sigma}{$\Sigma$}1
- {\\Upsilon}{$\Upsilon$}1
- {\\Phi}{$\Phi$}1
- {\\Psi}{$\Psi$}1
- {\\Omega}{$\Omega$}1
- ,
- sensitive=true, % case sensitive
- morecomment=[l]{//},
- morecomment=[s]{/*}{*/},
- morestring=[b]",
- numbers=none,
- firstnumber=0,
- numberstyle=\tiny,
- stepnumber=5,
- basicstyle=\scriptsize\sffamily,
- commentstyle=\itshape,
- keywordstyle=\bfseries,
- ndkeywordstyle=\bfseries,
-}
-\lstnewenvironment{dafny}[1][]{%
- \lstset{language=dafny,
- floatplacement={tbp},captionpos=b,
- frame=lines,xleftmargin=8pt,xrightmargin=8pt,basicstyle=\ttfamily,#1}}{}
-\lstnewenvironment{dafnyNoLines}[1][]{%
- \lstset{language=dafny,
- floatplacement={tbp},captionpos=b,
- xleftmargin=8pt,xrightmargin=8pt,basicstyle=\ttfamily,#1}}{}
-\def\inlinedafny{%
- \lstinline[language=dafny,basicstyle=\ttfamily,columns=fixed]}
-\newcommand{\lstfile}[1]{
- \lstinputlisting[language=dafny,%
- frame=lines,xleftmargin=8pt,xrightmargin=8pt,basicstyle=\ttfamily,columns=fixed]{#1}
-}
diff --git a/Util/vim/syntax/chalice.vim b/Util/vim/syntax/chalice.vim
deleted file mode 100644
index 86b65d74..00000000
--- a/Util/vim/syntax/chalice.vim
+++ /dev/null
@@ -1,44 +0,0 @@
-" Vim syntax file
-" Language: Chalice
-" Author: Kuat Yessenov
-" Date: 7/14/2010
-
-syntax clear
-syntax case match
-syntax keyword chaliceFunction function method predicate
-syntax keyword chaliceTypeDef class channel module
-syntax keyword chaliceConditional if then else
-syntax keyword chaliceRepeat foreach while
-syntax keyword chaliceStatement assert assume call reorder share unshare acquire release lock rd downgrade free fold unfold fork join wait signal send receive
-syntax keyword chaliceKeyword external var ghost returns where const new between and above below waitlevel lockbottom this result holds refines replaces spec by transforms
-syntax keyword chaliceType int bool string seq token
-syntax keyword chaliceLogic invariant requires ensures lockchange
-syntax keyword chaliceOperator forall exists old fresh old credit acc unfolding in eval ite rd
-syntax keyword chaliceBoolean true false
-
-syntax region chaliceString start=/"/ skip=/\\"/ end=/"/
-
-syntax match chaliceComment /\/\/.*/
-syntax region chaliceComment start="/\*" end="\*/"
-
-syntax match chaliceNumber /\d\+\>/
-syntax match chaliceIdentifier /\<\w\+\>/
-
-syntax match chaliceOperator "==>"
-syntax match chaliceOperator "<==>"
-syntax match chaliceOperator ":="
-syntax match chaliceOperator "<<"
-
-highlight link chaliceFunction Function
-highlight link chaliceTypeDef Typedef
-highlight link chaliceConditional Conditional
-highlight link chaliceRepeat Repeat
-highlight link chaliceKeyword Keyword
-highlight link chaliceType Type
-highlight link chaliceLogic Debug
-highlight link chaliceComment Comment
-highlight link chaliceString String
-highlight link chaliceNumber Number
-highlight link chaliceOperator Operator
-highlight link chaliceStatement Statement
-highlight link chaliceBoolean Boolean
diff --git a/Util/vim/syntax/dafny.vim b/Util/vim/syntax/dafny.vim
deleted file mode 100644
index 45afbcf0..00000000
--- a/Util/vim/syntax/dafny.vim
+++ /dev/null
@@ -1,44 +0,0 @@
-" Vim syntax file
-" Language: Dafny
-" Author: Kuat Yessenov
-" Date: 6/24/2010
-
-syntax clear
-syntax case match
-syntax keyword dafnyFunction function predicate copredicate method constructor
-syntax keyword dafnyTypeDef class datatype codatatype type iterator
-syntax keyword module import opened as default
-syntax keyword dafnyConditional if then else match case
-syntax keyword dafnyRepeat while parallel
-syntax keyword dafnyStatement assume assert return yield new print break label where calc
-syntax keyword dafnyKeyword var ghost returns yields null static this refines
-syntax keyword dafnyType bool nat int seq set multiset object array array2 array3 map
-syntax keyword dafnyLogic requires ensures modifies reads decreases invariant
-syntax keyword dafnyOperator forall exists old fresh choose
-syntax keyword dafnyBoolean true false
-
-syntax region dafnyString start=/"/ skip=/\\"/ end=/"/
-
-syntax match dafnyComment /\/\/.*/
-syntax region dafnyComment start="/\*" end="\*/"
-
-syntax match dafnyNumber /\d\+\>/
-syntax match dafnyIdentifier /\<\w\+\>/
-
-syntax match dafnyOperator "==>"
-syntax match dafnyOperator "<==>"
-syntax match dafnyOperator "::"
-
-highlight link dafnyFunction Function
-highlight link dafnyTypeDef Typedef
-highlight link dafnyConditional Conditional
-highlight link dafnyRepeat Repeat
-highlight link dafnyKeyword Keyword
-highlight link dafnyType Type
-highlight link dafnyLogic Debug
-highlight link dafnyComment Comment
-highlight link dafnyString String
-highlight link dafnyNumber Number
-highlight link dafnyOperator Operator
-highlight link dafnyStatement Statement
-highlight link dafnyBoolean Boolean
diff --git a/_admin/Chalice/aste/summary.log b/_admin/Chalice/aste/summary.log
deleted file mode 100644
index 9ea40ad3..00000000
--- a/_admin/Chalice/aste/summary.log
+++ /dev/null
@@ -1,16 +0,0 @@
-# Aste started: 2012-11-20 07:04:30
-# Host id: Boogiebox
-# Configuration: chalice.cfg
-# Task: aste.tasks.chalice.FullBuild
-# [2012-11-20 07:05:20] Chalice revision: f3679623d3eb
-[2012-11-20 07:08:40] cmd /c "(set JAVA_OPTS=-Dsbt.ivy.home=D:\temp\.ivy2\) && (sbt.bat clean compile)"
-
- [warn] D:\temp\aste\Boogie\Chalice\src\main\scala\Ast.scala:77: case class `class SeqClass' has case ancestor `class Class'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.
- [warn] D:\temp\aste\Boogie\Chalice\src\main\scala\Ast.scala:111: case class `class TokenClass' has case ancestor `class Class'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.
- [warn] D:\temp\aste\Boogie\Chalice\src\main\scala\Ast.scala:121: case class `class ChannelClass' has case ancestor `class Class'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.
- [warn] D:\temp\aste\Boogie\Chalice\src\main\scala\Ast.scala:141: case class `class TokenType' has case ancestor `class Type'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.
- [warn] D:\temp\aste\Boogie\Chalice\src\main\scala\Ast.scala:168: case class `class SpecialField' has case ancestor `class Field'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.
- [warn] D:\temp\aste\Boogie\Chalice\src\main\scala\Ast.scala:233: case class `class SpecialVariable' has case ancestor `class Variable'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.
-[2012-11-20 07:12:48] 87 out of 99 test(s) failed
-['AssociationList.chalice (5.317 seconds)\r', 'AVLTree.iterative.chalice (5.476 seconds)\r', 'AVLTree.nokeys.chalice (9.281 seconds)\r', 'BackgroundComputation.chalice (1.408 seconds)\r', 'cell.chalice (1.843 seconds)\r', 'CopyLessMessagePassing-with-ack.chalice (1.659 seconds)\r', 'CopyLessMessagePassing-with-ack2.chalice (1.706 seconds)\r', 'CopyLessMessagePassing.chalice (1.683 seconds)\r', 'dining-philosophers.chalice (1.811 seconds)\r', 'FictionallyDisjointCells.chalice (1.677 seconds)\r', 'ForkJoin.chalice (1.508 seconds)\r', 'HandOverHand.chalice (2.658 seconds)\r', 'iterator.chalice (2.257 seconds)\r', 'iterator2.chalice (1.952 seconds)\r', 'linkedlist.chalice (1.723 seconds)\r', 'list-reverse.chalice (1.496 seconds)\r', 'lseg.chalice (1.750 seconds)\r', 'OwickiGries.chalice (1.458 seconds)\r', 'PetersonsAlgorithm.chalice (3.282 seconds)\r', 'ProdConsChannel.chalice (1.492 seconds)\r', 'producer-consumer.chalice (2.456 seconds)\r', 'RockBand.chalice (1.575 seconds)\r', 'Sieve.chalice (1.571 seconds)\r', 'Solver.chalice (1.543 seconds)\r', 'swap.chalice (1.266 seconds)\r', 'TreeOfWorker.chalice (1.438 seconds)\r', 'UnboundedThreads.chalice (1.667 seconds)\r', 'basic.chalice (1.716 seconds)\r', 'channels.chalice (1.417 seconds)\r', 'locks.chalice (1.654 seconds)\r', 'peculiar.chalice (1.415 seconds)\r', 'permission_arithmetic.chalice (1.904 seconds)\r', 'predicates.chalice (1.481 seconds)\r', 'scaling.chalice (1.385 seconds)\r', 'sequences.chalice (1.578 seconds)\r', 'cell-defaults.chalice (1.879 seconds)\r', 'counter.chalice (1.715 seconds)\r', 'ImplicitLocals.chalice (1.390 seconds)\r', 'll-lastnode.chalice (1.821 seconds)\r', 'LoopLockChange.chalice (1.532 seconds)\r', 'nestedPredicates.chalice (1.811 seconds)\r', 'prog1.chalice (1.497 seconds)\r', 'prog2.chalice (1.443 seconds)\r', 'prog3.chalice (2.166 seconds)\r', 'prog4.chalice (1.433 seconds)\r', 'quantifiers.chalice (1.548 seconds)\r', 'RockBand-automagic.chalice (1.584 seconds)\r', 'SmokeTestTest.chalice (1.581 seconds)\r', 'triggers.chalice (1.591 seconds)\r', 'internal-bug-1.chalice (1.160 seconds)\r', 'internal-bug-2.chalice (1.257 seconds)\r', 'internal-bug-5.chalice (1.416 seconds)\r', 'internal-bug-6.chalice (1.299 seconds)\r', 'internal-bug-7.chalice (1.440 seconds)\r', 'workitem-10189.chalice (1.263 seconds)\r', 'workitem-10190.chalice (0.965 seconds)\r', 'workitem-10192.chalice (1.351 seconds)\r', 'workitem-10194.chalice (1.424 seconds)\r', 'workitem-10195.chalice (1.463 seconds)\r', 'workitem-10196.chalice (1.287 seconds)\r', 'workitem-10197.chalice (1.253 seconds)\r', 'workitem-10198.chalice (1.283 seconds)\r', 'workitem-10199.chalice (1.257 seconds)\r', 'workitem-10200.chalice (1.444 seconds)\r', 'workitem-10208.chalice (1.348 seconds)\r', 'workitem-10221.chalice (1.802 seconds)\r', 'workitem-10223.chalice (1.146 seconds)\r', 'workitem-8234.chalice (1.230 seconds)\r', 'workitem-8236.chalice (1.278 seconds)\r', 'workitem-9978.chalice (1.231 seconds)\r', 'aux-info.chalice (1.328 seconds)\r', 'FoldUnfoldExperiments.chalice (1.386 seconds)\r', 'framing-fields.chalice (1.391 seconds)\r', 'framing-functions.chalice (1.424 seconds)\r', 'LinkedList-various.chalice (2.141 seconds)\r', 'list-reverse-extra-unfold-fold.chalice (1.590 seconds)\r', 'mutual-dependence.chalice (1.358 seconds)\r', 'setset.chalice (1.599 seconds)\r', 'test.chalice (1.387 seconds)\r', 'test1.chalice (1.543 seconds)\r', 'test10.chalice (1.327 seconds)\r', 'test2.chalice (1.540 seconds)\r', 'test3.chalice (1.379 seconds)\r', 'test4.chalice (1.556 seconds)\r', 'test7.chalice (1.594 seconds)\r', 'test8.chalice (1.446 seconds)\r', 'unfolding.chalice (1.351 seconds)\r']
-# [2012-11-20 07:13:33] Released nightly of Chalice