diff options
Diffstat (limited to 'Source')
55 files changed, 2894 insertions, 2315 deletions
diff --git a/Source/AbsInt/AbsInt.csproj b/Source/AbsInt/AbsInt.csproj index 93d304d7..9ccd0ffe 100644 --- a/Source/AbsInt/AbsInt.csproj +++ b/Source/AbsInt/AbsInt.csproj @@ -141,6 +141,67 @@ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\AbsInt.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+ <OutputPath>bin\x86\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Release\AbsInt.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'z3apidebug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\z3apidebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>bin\z3apidebug\AbsInt.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>Migrated rules for AbsInt.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Checked\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\AbsInt.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
diff --git a/Source/Boogie.sln b/Source/Boogie.sln index 955dfb46..1e733880 100644 --- a/Source/Boogie.sln +++ b/Source/Boogie.sln @@ -79,7 +79,8 @@ Global {DAB6BAA4-7AF7-449F-96AB-F58F34D03A7A}.z3apidebug|Any CPU.Build.0 = z3apidebug|Any CPU
{DAB6BAA4-7AF7-449F-96AB-F58F34D03A7A}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DAB6BAA4-7AF7-449F-96AB-F58F34D03A7A}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {DAB6BAA4-7AF7-449F-96AB-F58F34D03A7A}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {DAB6BAA4-7AF7-449F-96AB-F58F34D03A7A}.z3apidebug|x86.ActiveCfg = z3apidebug|x86
+ {DAB6BAA4-7AF7-449F-96AB-F58F34D03A7A}.z3apidebug|x86.Build.0 = z3apidebug|x86
{435D5BD0-6F62-49F8-BB24-33E2257519AD}.Checked|.NET.ActiveCfg = Checked|Any CPU
{435D5BD0-6F62-49F8-BB24-33E2257519AD}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{435D5BD0-6F62-49F8-BB24-33E2257519AD}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -105,6 +106,7 @@ Global {435D5BD0-6F62-49F8-BB24-33E2257519AD}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{435D5BD0-6F62-49F8-BB24-33E2257519AD}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{435D5BD0-6F62-49F8-BB24-33E2257519AD}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {435D5BD0-6F62-49F8-BB24-33E2257519AD}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.Checked|.NET.ActiveCfg = Checked|Any CPU
{0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -129,7 +131,8 @@ Global {0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.z3apidebug|Any CPU.Build.0 = z3apidebug|Any CPU
{0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
- {0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.z3apidebug|x86.ActiveCfg = z3apidebug|x86
+ {0EFA3E43-690B-48DC-A72C-384A3EA7F31F}.z3apidebug|x86.Build.0 = z3apidebug|x86
{9B163AA3-36BC-4AFB-88AB-79BC9E97E401}.Checked|.NET.ActiveCfg = Checked|Any CPU
{9B163AA3-36BC-4AFB-88AB-79BC9E97E401}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{9B163AA3-36BC-4AFB-88AB-79BC9E97E401}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -155,6 +158,7 @@ Global {9B163AA3-36BC-4AFB-88AB-79BC9E97E401}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9B163AA3-36BC-4AFB-88AB-79BC9E97E401}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{9B163AA3-36BC-4AFB-88AB-79BC9E97E401}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {9B163AA3-36BC-4AFB-88AB-79BC9E97E401}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{E1F10180-C7B9-4147-B51F-FA1B701966DC}.Checked|.NET.ActiveCfg = Checked|Any CPU
{E1F10180-C7B9-4147-B51F-FA1B701966DC}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{E1F10180-C7B9-4147-B51F-FA1B701966DC}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -180,6 +184,7 @@ Global {E1F10180-C7B9-4147-B51F-FA1B701966DC}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E1F10180-C7B9-4147-B51F-FA1B701966DC}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{E1F10180-C7B9-4147-B51F-FA1B701966DC}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {E1F10180-C7B9-4147-B51F-FA1B701966DC}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}.Checked|.NET.ActiveCfg = Checked|Any CPU
{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -204,6 +209,7 @@ Global {56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {56FFDBCA-7D14-43B8-A6CA-22A20E417EE1}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{B230A69C-C466-4065-B9C1-84D80E76D802}.Checked|.NET.ActiveCfg = Checked|Any CPU
{B230A69C-C466-4065-B9C1-84D80E76D802}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{B230A69C-C466-4065-B9C1-84D80E76D802}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -228,6 +234,7 @@ Global {B230A69C-C466-4065-B9C1-84D80E76D802}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{B230A69C-C466-4065-B9C1-84D80E76D802}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{B230A69C-C466-4065-B9C1-84D80E76D802}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {B230A69C-C466-4065-B9C1-84D80E76D802}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{966DD87B-A29D-4F3C-9406-F680A61DC0E0}.Checked|.NET.ActiveCfg = Checked|Any CPU
{966DD87B-A29D-4F3C-9406-F680A61DC0E0}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{966DD87B-A29D-4F3C-9406-F680A61DC0E0}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -249,6 +256,7 @@ Global {966DD87B-A29D-4F3C-9406-F680A61DC0E0}.z3apidebug|Mixed Platforms.ActiveCfg = z3apidebug|Any CPU
{966DD87B-A29D-4F3C-9406-F680A61DC0E0}.z3apidebug|Mixed Platforms.Build.0 = z3apidebug|Any CPU
{966DD87B-A29D-4F3C-9406-F680A61DC0E0}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {966DD87B-A29D-4F3C-9406-F680A61DC0E0}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{39B0658D-C955-41C5-9A43-48C97A1EF5FD}.Checked|.NET.ActiveCfg = Checked|Any CPU
{39B0658D-C955-41C5-9A43-48C97A1EF5FD}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{39B0658D-C955-41C5-9A43-48C97A1EF5FD}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -273,6 +281,7 @@ Global {39B0658D-C955-41C5-9A43-48C97A1EF5FD}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{39B0658D-C955-41C5-9A43-48C97A1EF5FD}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{39B0658D-C955-41C5-9A43-48C97A1EF5FD}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {39B0658D-C955-41C5-9A43-48C97A1EF5FD}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}.Checked|.NET.ActiveCfg = Checked|Any CPU
{69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -297,6 +306,7 @@ Global {69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {69A2B0B8-BCAC-4101-AE7A-556FCC58C06E}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}.Checked|.NET.ActiveCfg = Checked|Any CPU
{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -321,6 +331,7 @@ Global {43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {43DFAD18-3E35-4558-9BE2-CAFF6B5BA8A0}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}.Checked|.NET.ActiveCfg = Checked|Any CPU
{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -345,6 +356,7 @@ Global {ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}.z3apidebug|x86.ActiveCfg = z3apidebug|Any CPU
+ {ACCC0156-0921-43ED-8F67-AD8BDC8CDE31}.z3apidebug|x86.Build.0 = z3apidebug|Any CPU
{A678C6EB-B329-46A9-BBFC-7585F01ACD7C}.Checked|.NET.ActiveCfg = Checked|x86
{A678C6EB-B329-46A9-BBFC-7585F01ACD7C}.Checked|Any CPU.ActiveCfg = Checked|x86
{A678C6EB-B329-46A9-BBFC-7585F01ACD7C}.Checked|Mixed Platforms.ActiveCfg = Checked|x86
@@ -393,6 +405,7 @@ Global {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.z3apidebug|Mixed Platforms.ActiveCfg = Release|Any CPU
{ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.z3apidebug|Mixed Platforms.Build.0 = Release|Any CPU
{ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.z3apidebug|x86.ActiveCfg = Release|Any CPU
+ {ACEF88D5-DADD-46DA-BAE1-2144D63F4C83}.z3apidebug|x86.Build.0 = Release|Any CPU
{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}.Checked|.NET.ActiveCfg = Checked|Any CPU
{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}.Checked|Any CPU.ActiveCfg = Checked|Any CPU
{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}.Checked|Any CPU.Build.0 = Checked|Any CPU
@@ -417,6 +430,7 @@ Global {FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}.z3apidebug|Mixed Platforms.ActiveCfg = Release|Any CPU
{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}.z3apidebug|Mixed Platforms.Build.0 = Release|Any CPU
{FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}.z3apidebug|x86.ActiveCfg = Release|Any CPU
+ {FCD3AC7F-9DFD-46C8-AB1E-09F0B0F16DC5}.z3apidebug|x86.Build.0 = Release|Any CPU
{CF41E903-78EB-43BA-A355-E5FEB5ECECD4}.Checked|.NET.ActiveCfg = Release|Any CPU
{CF41E903-78EB-43BA-A355-E5FEB5ECECD4}.Checked|Any CPU.ActiveCfg = Release|Any CPU
{CF41E903-78EB-43BA-A355-E5FEB5ECECD4}.Checked|Any CPU.Build.0 = Release|Any CPU
@@ -441,6 +455,7 @@ Global {CF41E903-78EB-43BA-A355-E5FEB5ECECD4}.z3apidebug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{CF41E903-78EB-43BA-A355-E5FEB5ECECD4}.z3apidebug|Mixed Platforms.Build.0 = Debug|Any CPU
{CF41E903-78EB-43BA-A355-E5FEB5ECECD4}.z3apidebug|x86.ActiveCfg = Release|Any CPU
+ {CF41E903-78EB-43BA-A355-E5FEB5ECECD4}.z3apidebug|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Source/BoogieDriver/BoogieDriver.cs b/Source/BoogieDriver/BoogieDriver.cs index 44adce15..ae26d8db 100644 --- a/Source/BoogieDriver/BoogieDriver.cs +++ b/Source/BoogieDriver/BoogieDriver.cs @@ -18,6 +18,7 @@ namespace Microsoft.Boogie { using Microsoft.Boogie.AbstractInterpretation;
using System.Diagnostics.Contracts;
using System.Diagnostics;
+ using System.Linq;
using VC;
using AI = Microsoft.AbstractInterpretationFramework;
using BoogiePL = Microsoft.Boogie;
@@ -178,6 +179,14 @@ namespace Microsoft.Boogie { return;
}
+ if (CommandLineOptions.Clo.PrintCFGPrefix != null) {
+ foreach (var impl in program.TopLevelDeclarations.OfType<Implementation>()) {
+ using (StreamWriter sw = new StreamWriter(CommandLineOptions.Clo.PrintCFGPrefix + "." + impl.Name + ".dot")) {
+ sw.Write(program.ProcessLoops(impl).ToDot());
+ }
+ }
+ }
+
EliminateDeadVariablesAndInline(program);
int errorCount, verified, inconclusives, timeOuts, outOfMemories;
diff --git a/Source/BoogieDriver/BoogieDriver.csproj b/Source/BoogieDriver/BoogieDriver.csproj index 9b6e329b..57aeb4d9 100644 --- a/Source/BoogieDriver/BoogieDriver.csproj +++ b/Source/BoogieDriver/BoogieDriver.csproj @@ -86,10 +86,10 @@ </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'z3apidebug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\z3apidebug\</OutputPath>
+ <OutputPath>..\Provers\Z3api\bin\z3apidebug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
+ <PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleAssemblies>
</CodeAnalysisRuleAssemblies>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
@@ -138,6 +138,68 @@ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>..\..\Binaries\Boogie.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+ <OutputPath>bin\x86\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Release\Boogie.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'z3apidebug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\z3apidebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>bin\z3apidebug\Boogie.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>Migrated rules for BoogieDriver.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Checked|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Checked\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>..\..\Binaries\Boogie.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
diff --git a/Source/Core/Absy.cs b/Source/Core/Absy.cs index 148a739d..c4b5d7a9 100644 --- a/Source/Core/Absy.cs +++ b/Source/Core/Absy.cs @@ -545,6 +545,8 @@ namespace Microsoft.Boogie { // header_last block that was created because of splitting header.
Dictionary<Block, Block> newBlocksCreated = new Dictionary<Block, Block>();
+ bool headRecursion = false; // testing an option to put recursive call before loop body
+
IEnumerable<Block> sortedHeaders = g.SortHeadersByDominance();
foreach (Block/*!*/ header in sortedHeaders)
{
@@ -565,7 +567,17 @@ namespace Microsoft.Boogie { continue;
Block newBlock = new Block();
newBlock.Label = block.Label;
- newBlock.Cmds = codeCopier.CopyCmdSeq(block.Cmds);
+ if (headRecursion && block == header)
+ {
+ CallCmd callCmd = (CallCmd)(loopHeaderToCallCmd2[header]).Clone();
+ addUniqueCallAttr(si_unique_loc, callCmd);
+ si_unique_loc++;
+ newBlock.Cmds.Add(callCmd); // add the recursive call at head of loop
+ var rest = codeCopier.CopyCmdSeq(block.Cmds);
+ newBlock.Cmds.AddRange(rest);
+ }
+ else
+ newBlock.Cmds = codeCopier.CopyCmdSeq(block.Cmds);
blockMap[block] = newBlock;
if (newBlocksCreated.ContainsKey(block))
{
@@ -616,14 +628,21 @@ namespace Microsoft.Boogie { }
}
- CallCmd callCmd = (CallCmd) (loopHeaderToCallCmd2[header]).Clone();
- addUniqueCallAttr(si_unique_loc, callCmd);
- si_unique_loc++;
+ CmdSeq cmdSeq;
+ if (headRecursion)
+ cmdSeq = new CmdSeq();
+ else
+ {
+ CallCmd callCmd = (CallCmd)(loopHeaderToCallCmd2[header]).Clone();
+ addUniqueCallAttr(si_unique_loc, callCmd);
+ si_unique_loc++;
+ cmdSeq = new CmdSeq(callCmd);
+ }
Block/*!*/ block1 = new Block(Token.NoToken, source.Label + "_dummy",
new CmdSeq(new AssumeCmd(Token.NoToken, Expr.False)), new ReturnCmd(Token.NoToken));
Block/*!*/ block2 = new Block(Token.NoToken, block1.Label,
- new CmdSeq(callCmd), new ReturnCmd(Token.NoToken));
+ cmdSeq, new ReturnCmd(Token.NoToken));
impl.Blocks.Add(block1);
dummyBlocks.Add(block1.Label);
@@ -2038,6 +2057,11 @@ namespace Microsoft.Boogie { }
}
+ public class Macro : Function {
+ public Macro(IToken tok, string name, VariableSeq args, Variable result)
+ : base(tok, name, args, result) { }
+ }
+
public class Requires : Absy, IPotentialErrorNode {
public readonly bool Free;
public Expr/*!*/ Condition;
diff --git a/Source/Core/CommandLineOptions.cs b/Source/Core/CommandLineOptions.cs index c28d8c8a..7d55e177 100644 --- a/Source/Core/CommandLineOptions.cs +++ b/Source/Core/CommandLineOptions.cs @@ -450,6 +450,7 @@ namespace Microsoft.Boogie { public string PrintErrorModelFile = null;
public string/*?*/ ModelViewFile = null;
public int EnhancedErrorMessages = 0;
+ public string PrintCFGPrefix = null;
public bool ForceBplErrors = false; // if true, boogie error is shown even if "msg" attribute is present
public bool UseArrayTheory = false;
public bool UseLabels = true;
@@ -834,6 +835,12 @@ namespace Microsoft.Boogie { ps.GetNumericArgument(ref EnhancedErrorMessages, 2);
return true;
+ case "printCFG":
+ if (ps.ConfirmArgumentCount(1)) {
+ PrintCFGPrefix = args[ps.i];
+ }
+ return true;
+
case "inlineDepth":
ps.GetNumericArgument(ref InlineDepth);
return true;
@@ -1449,6 +1456,10 @@ namespace Microsoft.Boogie { 0 (default) - no enhanced error messages
1 - Z3 error model enhanced error messages
+ /printCFG:<prefix> : print control flow graph of each implementation in
+ Graphviz format to files named:
+ <prefix>.<procedure name>.dot
+
---- Inference options -----------------------------------------------------
/infer:<flags>
diff --git a/Source/Core/Inline.cs b/Source/Core/Inline.cs index 88512025..63103399 100644 --- a/Source/Core/Inline.cs +++ b/Source/Core/Inline.cs @@ -384,7 +384,7 @@ namespace Microsoft.Boogie { codeCopier.OldSubst = null;
}
- private Cmd InlinedRequires(Implementation impl, CallCmd callCmd, Requires req) {
+ private Cmd InlinedRequires(CallCmd callCmd, Requires req) {
Requires/*!*/ reqCopy = (Requires/*!*/)cce.NonNull(req.Clone());
if (req.Free)
reqCopy.Condition = Expr.True;
@@ -395,16 +395,16 @@ namespace Microsoft.Boogie { return a;
}
- private Cmd InlinedEnsures(Implementation impl, CallCmd callCmd, Ensures ens) {
- if (impl.FindExprAttribute("inline") != null && !ens.Free) {
+ private Cmd InlinedEnsures(CallCmd callCmd, Ensures ens) {
+ if (QKeyValue.FindBoolAttribute(ens.Attributes, "assume")) {
+ return new AssumeCmd(ens.tok, codeCopier.CopyExpr(ens.Condition));
+ } else if (ens.Free) {
+ return new AssumeCmd(ens.tok, Expr.True);
+ } else {
Ensures/*!*/ ensCopy = (Ensures/*!*/)cce.NonNull(ens.Clone());
ensCopy.Condition = codeCopier.CopyExpr(ens.Condition);
return new AssertEnsuresCmd(ensCopy);
}
- else {
- //return new AssumeCmd(ens.tok, codeCopier.CopyExpr(ens.Condition));
- return new AssumeCmd(ens.tok, Expr.True);
- }
}
private CmdSeq RemoveAsserts(CmdSeq cmds) {
@@ -449,7 +449,7 @@ namespace Microsoft.Boogie { // inject requires
for (int i = 0; i < proc.Requires.Length; i++) {
Requires/*!*/ req = cce.NonNull(proc.Requires[i]);
- inCmds.Add(InlinedRequires(impl, callCmd, req));
+ inCmds.Add(InlinedRequires(callCmd, req));
}
VariableSeq locVars = cce.NonNull(impl.OriginalLocVars);
@@ -510,7 +510,7 @@ namespace Microsoft.Boogie { // inject ensures
for (int i = 0; i < proc.Ensures.Length; i++) {
Ensures/*!*/ ens = cce.NonNull(proc.Ensures[i]);
- outCmds.Add(InlinedEnsures(impl, callCmd, ens));
+ outCmds.Add(InlinedEnsures(callCmd, ens));
}
// assign out params
diff --git a/Source/Core/Util.cs b/Source/Core/Util.cs index f45e2995..a8e12f63 100644 --- a/Source/Core/Util.cs +++ b/Source/Core/Util.cs @@ -61,6 +61,11 @@ namespace Microsoft.Boogie { {
foreach (var e in coll) fn(e);
}
+
+ public static IEnumerable<Tuple<TSource1, TSource2>> Zip<TSource1, TSource2>(this IEnumerable<TSource1> source1, IEnumerable<TSource2> source2)
+ {
+ return source1.Zip(source2, (e1, e2) => new Tuple<TSource1, TSource2>(e1, e2));
+ }
}
public class TokenTextWriter : IDisposable {
diff --git a/Source/Dafny/Compiler.cs b/Source/Dafny/Compiler.cs index afab0c1f..fa8ea6da 100644 --- a/Source/Dafny/Compiler.cs +++ b/Source/Dafny/Compiler.cs @@ -74,18 +74,18 @@ namespace Microsoft.Dafny { }
int indent = 0;
if (!m.IsDefaultModule) {
- wr.WriteLine("namespace @{0} {{", m.Name);
+ 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.Name);
+ 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.Name);
+ wr.Write("public abstract class Base_{0}", dt.CompileName);
if (dt.TypeArgs.Count != 0) {
wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
}
@@ -95,7 +95,7 @@ namespace Microsoft.Dafny { } else {
ClassDecl cl = (ClassDecl)d;
Indent(indent);
- wr.Write("public class @{0}", cl.Name);
+ wr.Write("public class @{0}", cl.CompileName);
if (cl.TypeArgs.Count != 0) {
wr.Write("<{0}>", TypeParameters(cl.TypeArgs));
}
@@ -105,7 +105,7 @@ namespace Microsoft.Dafny { }
}
if (!m.IsDefaultModule) {
- wr.WriteLine("}} // end of namespace {0}", m.Name);
+ wr.WriteLine("}} // end of namespace {0}", m.CompileName);
}
}
}
@@ -200,18 +200,18 @@ namespace Microsoft.Dafny { // public Base_Dt<T> Get() { return c(); }
// }
Indent(indent);
- wr.WriteLine("public class {0}__Lazy{1} : Base_{0}{1} {{", dt.Name, typeParams);
+ 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.Name, typeParams);
+ 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.Name);
+ wr.WriteLine("public {0}__Lazy(Computer c) {{ this.c = c; }}", dt.CompileName);
Indent(ind);
- wr.WriteLine("public Base_{0}{1} Get() {{ return c(); }}", dt.Name, typeParams);
+ wr.WriteLine("public Base_{0}{1} Get() {{ return c(); }}", dt.CompileName, typeParams);
Indent(indent);
wr.WriteLine("}");
}
@@ -235,7 +235,7 @@ namespace Microsoft.Dafny { // }
Indent(indent);
wr.Write("public class {0}", DtCtorName(ctor, dt.TypeArgs));
- wr.WriteLine(" : Base_{0}{1} {{", dt.Name, typeParams);
+ wr.WriteLine(" : Base_{0}{1} {{", dt.CompileName, typeParams);
int ind = indent + IndentAmount;
int i = 0;
@@ -290,7 +290,7 @@ namespace Microsoft.Dafny { if (dt is IndDatatypeDecl) {
Indent(ind); wr.WriteLine("public override string ToString() {");
- string nm = (dt.Module.IsDefaultModule ? "" : dt.Module.Name + ".") + dt.Name + "." + ctor.Name;
+ 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 += \"(\";");
@@ -345,13 +345,13 @@ namespace Microsoft.Dafny { // public override int GetHashCode() { return _D.GetHashCode(); }
// public override string ToString() { return _D.ToString(); } // only for inductive datatypes
//
- // public bool _Ctor0 { get { return _D is Dt_Ctor0; } }
+ // public bool is_Ctor0 { get { return _D is Dt_Ctor0; } }
// ...
//
// public T0 dtor_Dtor0 { get { return ((DT_Ctor)_D).@Dtor0; } }
// ...
// }
- string DtT = dt.Name;
+ string DtT = dt.CompileName;
string DtT_TypeArgs = "";
if (dt.TypeArgs.Count != 0) {
DtT_TypeArgs = "<" + TypeParameters(dt.TypeArgs) + ">";
@@ -376,9 +376,9 @@ namespace Microsoft.Dafny { 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.Name, typeParams);
+ 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.Name, typeParams);
+ 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;");
@@ -386,7 +386,7 @@ namespace Microsoft.Dafny { Indent(ind); wr.WriteLine("}");
Indent(ind);
- wr.WriteLine("public @{0}(Base_{1} d) {{ this.d = d; }}", dt.Name, DtT);
+ wr.WriteLine("public @{0}(Base_{1} d) {{ this.d = d; }}", dt.CompileName, DtT);
Indent(ind);
wr.WriteLine("static Base_{0} theDefault;", DtT);
@@ -440,9 +440,9 @@ namespace Microsoft.Dafny { // query properties
foreach (var ctor in dt.Ctors) {
- // public bool _Ctor0 { get { return _D is Dt_Ctor0; } }
+ // public bool is_Ctor0 { get { return _D is Dt_Ctor0; } }
Indent(ind);
- wr.WriteLine("public bool _{0} {{ get {{ return _D is {1}_{0}{2}; }} }}", ctor.Name, dt.Name, DtT_TypeArgs);
+ wr.WriteLine("public bool is_{0} {{ get {{ return _D is {1}_{0}{2}; }} }}", ctor.CompileName, dt.CompileName, DtT_TypeArgs);
}
// destructors
@@ -451,7 +451,7 @@ namespace Microsoft.Dafny { 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.Name, dt.Name, ctor.Name, DtT_TypeArgs);
+ wr.WriteLine("public {0} dtor_{1} {{ get {{ return (({2}_{3}{4})_D).@{1}; }} }}", TypeName(arg.Type), arg.CompileName, dt.CompileName, ctor.CompileName, DtT_TypeArgs);
}
}
}
@@ -480,14 +480,14 @@ namespace Microsoft.Dafny { Contract.Requires(formal != null);
Contract.Ensures(Contract.Result<string>() != null);
- return formal.HasName ? formal.Name : "_a" + i;
+ return formal.HasName ? formal.CompileName : "_a" + i;
}
string DtCtorName(DatatypeCtor ctor) {
Contract.Requires(ctor != null);
Contract.Ensures(Contract.Result<string>() != null);
- return cce.NonNull(ctor.EnclosingDatatype).Name + "_" + ctor.Name;
+ return cce.NonNull(ctor.EnclosingDatatype).CompileName + "_" + ctor.CompileName;
}
string DtCtorName(DatatypeCtor ctor, List<TypeParameter> typeParams) {
@@ -539,7 +539,7 @@ namespace Microsoft.Dafny { Field f = (Field)member;
if (!f.IsGhost) {
Indent(indent);
- wr.WriteLine("public {0} @{1} = {2};", TypeName(f.Type), f.Name, DefaultValue(f.Type));
+ wr.WriteLine("public {0} @{1} = {2};", TypeName(f.Type), f.CompileName, DefaultValue(f.Type));
}
} else if (member is Function) {
@@ -550,7 +550,7 @@ namespace Microsoft.Dafny { Error("Function {0} has no body", f.FullName);
} else {
Indent(indent);
- wr.Write("public {0}{1} @{2}", f.IsStatic ? "static " : "", TypeName(f.ResultType), f.Name);
+ 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));
}
@@ -565,7 +565,7 @@ namespace Microsoft.Dafny { Method m = (Method)member;
if (!m.IsGhost) {
Indent(indent);
- wr.Write("public {0}void @{1}", m.IsStatic ? "static " : "", m.Name);
+ wr.Write("public {0}void @{1}", m.IsStatic ? "static " : "", m.CompileName);
if (m.TypeArgs.Count != 0) {
wr.Write("<{0}>", TypeParameters(m.TypeArgs));
}
@@ -579,7 +579,7 @@ namespace Microsoft.Dafny { foreach (Formal p in m.Outs) {
if (!p.IsGhost) {
Indent(indent + IndentAmount);
- wr.WriteLine("@{0} = {1};", p.Name, DefaultValue(p.Type));
+ wr.WriteLine("@{0} = {1};", p.CompileName, DefaultValue(p.Type));
}
}
if (m.Body == null) {
@@ -595,7 +595,7 @@ namespace Microsoft.Dafny { wr.WriteLine("public static void Main(string[] args) {");
Contract.Assert(m.EnclosingClass == c);
Indent(indent + IndentAmount);
- wr.Write("@{0} b = new @{0}", c.Name);
+ wr.Write("@{0} b = new @{0}", c.CompileName);
if (c.TypeArgs.Count != 0) {
// instantiate every parameter, it doesn't particularly matter how
wr.Write("<");
@@ -623,7 +623,7 @@ namespace Microsoft.Dafny { if (body is MatchExpr) {
MatchExpr me = (MatchExpr)body;
// Type source = e;
- // if (source._Ctor0) {
+ // if (source.is_Ctor0) {
// FormalType f0 = ((Dt_Ctor0)source._D).a0;
// ...
// return Body0;
@@ -675,7 +675,7 @@ namespace Microsoft.Dafny { var e = (LetExpr)expr;
foreach (var v in e.Vars) {
Indent(indent);
- wr.WriteLine("{0} @{1};", TypeName(v.Type), v.Name);
+ wr.WriteLine("{0} @{1};", TypeName(v.Type), v.CompileName);
}
}
foreach (var ee in expr.SubExpressions) {
@@ -724,7 +724,7 @@ namespace Microsoft.Dafny { return name + "]";
} else if (type is UserDefinedType) {
UserDefinedType udt = (UserDefinedType)type;
- string s = "@" + udt.FullName;
+ 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");
@@ -782,7 +782,7 @@ namespace Microsoft.Dafny { string s = "";
string sep = "";
foreach (TypeParameter tp in targs) {
- s += sep + "@" + tp.Name;
+ s += sep + "@" + tp.CompileName;
sep = ",";
}
return s;
@@ -813,14 +813,14 @@ namespace Microsoft.Dafny { return string.Format("({0})null", TypeName(type));
} else if (type.IsDatatype) {
UserDefinedType udt = (UserDefinedType)type;
- string s = "@" + udt.Name;
+ 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.Name + ")";
+ return "default(@" + udt.FullCompileName + ")";
} else if (type is SetType) {
return DafnySetClass + "<" + TypeName(((SetType)type).Arg) + ">.Empty";
} else if (type is MultiSetType) {
@@ -841,7 +841,10 @@ namespace Microsoft.Dafny { if (stmt is AssumeStmt) {
Error("an assume statement cannot be compiled (line {0})", stmt.Tok.line);
} else if (stmt is AssignSuchThatStmt) {
- Error("an assign-such-that statement cannot be compiled (line {0})", stmt.Tok.line);
+ 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);
@@ -882,7 +885,7 @@ namespace Microsoft.Dafny { } else if (stmt is BreakStmt) {
var s = (BreakStmt)stmt;
Indent(indent);
- wr.WriteLine("goto after_{0};", s.TargetStmt.Labels.UniqueId);
+ wr.WriteLine("goto after_{0};", s.TargetStmt.Labels.Data.UniqueId);
} else if (stmt is ReturnStmt) {
var s = (ReturnStmt)stmt;
if (s.hiddenUpdate != null)
@@ -925,6 +928,16 @@ namespace Microsoft.Dafny { 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);
@@ -1099,7 +1112,7 @@ namespace Microsoft.Dafny { // declare and construct "ingredients"
Indent(indent);
- wr.WriteLine("var {0} = new List<System.Tuple<{1}>>();", ingredients, tupleTypeArgs);
+ 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);
@@ -1109,29 +1122,29 @@ namespace Microsoft.Dafny { var bv = s.BoundVars[i];
if (bound is QuantifierExpr.BoolBoundedPool) {
Indent(ind);
- wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.Name);
+ wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
} else if (bound is QuantifierExpr.IntBoundedPool) {
var b = (QuantifierExpr.IntBoundedPool)bound;
SpillLetVariableDecls(b.LowerBound, ind);
SpillLetVariableDecls(b.UpperBound, ind);
Indent(ind);
- wr.Write("for (var @{0} = ", bv.Name);
+ wr.Write("for (var @{0} = ", bv.CompileName);
TrExpr(b.LowerBound);
- wr.Write("; @{0} < ", bv.Name);
+ wr.Write("; @{0} < ", bv.CompileName);
TrExpr(b.UpperBound);
- wr.Write("; @{0}++) {{ ", bv.Name);
+ wr.Write("; @{0}++) {{ ", bv.CompileName);
} else if (bound is QuantifierExpr.SetBoundedPool) {
var b = (QuantifierExpr.SetBoundedPool)bound;
SpillLetVariableDecls(b.Set, ind);
Indent(ind);
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Set);
wr.Write(").Elements) { ");
} else if (bound is QuantifierExpr.SeqBoundedPool) {
var b = (QuantifierExpr.SeqBoundedPool)bound;
SpillLetVariableDecls(b.Seq, ind);
Indent(ind);
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Seq);
wr.Write(").UniqueElements) { ");
} else {
@@ -1213,7 +1226,7 @@ namespace Microsoft.Dafny { } else if (stmt is MatchStmt) {
MatchStmt s = (MatchStmt)stmt;
// Type source = e;
- // if (source._Ctor0) {
+ // if (source.is_Ctor0) {
// FormalType f0 = ((Dt_Ctor0)source._D).a0;
// ...
// Body0;
@@ -1258,7 +1271,7 @@ namespace Microsoft.Dafny { SpillLetVariableDecls(lhs, indent);
if (lhs is IdentifierExpr) {
var ll = (IdentifierExpr)lhs;
- return "@" + ll.Var.Name;
+ return "@" + ll.Var.CompileName;
} else if (lhs is FieldSelectExpr) {
var ll = (FieldSelectExpr)lhs;
string obj = "_obj" + tmpVarCount;
@@ -1267,7 +1280,7 @@ namespace Microsoft.Dafny { wr.Write("var {0} = ", obj);
TrExpr(ll.Obj);
wr.WriteLine(";");
- return string.Format("{0}.@{1}", obj, ll.Field.Name);
+ return string.Format("{0}.@{1}", obj, ll.Field.CompileName);
} else if (lhs is SeqSelectExpr) {
var ll = (SeqSelectExpr)lhs;
string arr = "_arr" + tmpVarCount;
@@ -1390,7 +1403,7 @@ namespace Microsoft.Dafny { Indent(indent);
TrParenExpr(s.Receiver);
}
- wr.Write(".@{0}(", s.Method.Name);
+ wr.Write(".@{0}(", s.Method.CompileName);
string sep = "";
for (int i = 0; i < s.Method.Ins.Count; i++) {
@@ -1462,7 +1475,7 @@ namespace Microsoft.Dafny { 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.UniqueId);
+ wr.WriteLine("after_{0}: ;", ss.Labels.Data.UniqueId);
}
}
}
@@ -1475,7 +1488,7 @@ namespace Microsoft.Dafny { }
Indent(indent);
- wr.Write("{0} @{1}", TypeName(s.Type), s.Name);
+ wr.Write("{0} @{1}", TypeName(s.Type), s.CompileName);
if (alwaysInitialize) {
// produce a default value
wr.WriteLine(" = {0};", DefaultValue(s.Type));
@@ -1489,7 +1502,7 @@ namespace Microsoft.Dafny { Contract.Requires(sourceType != null);
Contract.Requires(ctor != null);
Contract.Requires(cce.NonNullElements(arguments));
- // if (source._Ctor0) {
+ // if (source.is_Ctor0) {
// FormalType f0 = ((Dt_Ctor0)source._D).a0;
// ...
Indent(indent);
@@ -1497,7 +1510,7 @@ namespace Microsoft.Dafny { if (caseIndex == caseCount - 1) {
wr.Write("true");
} else {
- wr.Write("{0}._{1}", source, ctor.Name);
+ wr.Write("{0}.is_{1}", source, ctor.CompileName);
}
wr.WriteLine(") {");
@@ -1509,7 +1522,7 @@ namespace Microsoft.Dafny { // FormalType f0 = ((Dt_Ctor0)source._D).a0;
Indent(indent + IndentAmount);
wr.WriteLine("{0} @{1} = (({2}){3}._D).@{4};",
- TypeName(bv.Type), bv.Name, DtCtorName(ctor, sourceType.TypeArgs), source, FormalName(arg, k));
+ TypeName(bv.Type), bv.CompileName, DtCtorName(ctor, sourceType.TypeArgs), source, FormalName(arg, k));
k++;
}
}
@@ -1599,7 +1612,7 @@ namespace Microsoft.Dafny { } else if (expr is IdentifierExpr) {
IdentifierExpr e = (IdentifierExpr)expr;
- wr.Write("@" + e.Var.Name);
+ wr.Write("@" + e.Var.CompileName);
} else if (expr is SetDisplayExpr) {
SetDisplayExpr e = (SetDisplayExpr)expr;
@@ -1634,7 +1647,7 @@ namespace Microsoft.Dafny { wr.Write(sf.PostString);
} else {
TrParenExpr(e.Obj);
- wr.Write(".@{0}", e.Field.Name);
+ wr.Write(".@{0}", e.Field.CompileName);
}
} else if (expr is SeqSelectExpr) {
@@ -1800,7 +1813,7 @@ namespace Microsoft.Dafny { wr.Write(".Length)");
} else {
TrParenExpr(e.E);
- wr.Write(".Length");
+ wr.Write(".Length");
}
break;
default:
@@ -1827,6 +1840,11 @@ namespace Microsoft.Dafny { 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 = "==";
}
@@ -1837,6 +1855,11 @@ namespace Microsoft.Dafny { 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 = "!=";
}
@@ -1969,7 +1992,7 @@ namespace Microsoft.Dafny { // 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].Name);
+ wr.Write("Dafny.Helpers.ExpressionSequence(@{0} = ", e.Vars[i].CompileName);
TrExpr(e.RHSs[i]);
wr.Write(", ");
}
@@ -2015,7 +2038,7 @@ namespace Microsoft.Dafny { Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
}
wr.Write("{0}, ", expr is ForallExpr ? "true" : "false");
- wr.Write("@{0} => ", bv.Name);
+ wr.Write("@{0} => ", bv.CompileName);
}
TrExpr(e.LogicalBody());
for (int i = 0; i < n; i++) {
@@ -2050,27 +2073,27 @@ namespace Microsoft.Dafny { var bound = e.Bounds[i];
var bv = e.BoundVars[i];
if (bound is QuantifierExpr.BoolBoundedPool) {
- wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.Name);
+ wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
} else if (bound is QuantifierExpr.IntBoundedPool) {
var b = (QuantifierExpr.IntBoundedPool)bound;
- wr.Write("for (var @{0} = ", bv.Name);
+ wr.Write("for (var @{0} = ", bv.CompileName);
TrExpr(b.LowerBound);
- wr.Write("; @{0} < ", bv.Name);
+ wr.Write("; @{0} < ", bv.CompileName);
TrExpr(b.UpperBound);
- wr.Write("; @{0}++) {{ ", bv.Name);
+ wr.Write("; @{0}++) {{ ", bv.CompileName);
} else if (bound is QuantifierExpr.SetBoundedPool) {
var b = (QuantifierExpr.SetBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Set);
wr.Write(").Elements) { ");
} else if (bound is QuantifierExpr.MapBoundedPool) {
var b = (QuantifierExpr.MapBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Map);
wr.Write(").Domain) { ");
} else if (bound is QuantifierExpr.SeqBoundedPool) {
var b = (QuantifierExpr.SeqBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Seq);
wr.Write(").Elements) { ");
} else {
@@ -2116,27 +2139,27 @@ namespace Microsoft.Dafny { var bound = e.Bounds[0];
var bv = e.BoundVars[0];
if (bound is QuantifierExpr.BoolBoundedPool) {
- wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.Name);
+ wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
} else if (bound is QuantifierExpr.IntBoundedPool) {
var b = (QuantifierExpr.IntBoundedPool)bound;
- wr.Write("for (var @{0} = ", bv.Name);
+ wr.Write("for (var @{0} = ", bv.CompileName);
TrExpr(b.LowerBound);
- wr.Write("; @{0} < ", bv.Name);
+ wr.Write("; @{0} < ", bv.CompileName);
TrExpr(b.UpperBound);
- wr.Write("; @{0}++) {{ ", bv.Name);
+ wr.Write("; @{0}++) {{ ", bv.CompileName);
} else if (bound is QuantifierExpr.SetBoundedPool) {
var b = (QuantifierExpr.SetBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Set);
wr.Write(").Elements) { ");
} else if (bound is QuantifierExpr.MapBoundedPool) {
var b = (QuantifierExpr.MapBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Map);
wr.Write(").Domain) { ");
} else if (bound is QuantifierExpr.SeqBoundedPool) {
var b = (QuantifierExpr.SeqBoundedPool)bound;
- wr.Write("foreach (var @{0} in (", bv.Name);
+ wr.Write("foreach (var @{0} in (", bv.CompileName);
TrExpr(b.Seq);
wr.Write(").Elements) { ");
} else {
@@ -2145,7 +2168,7 @@ namespace Microsoft.Dafny { wr.Write("if (");
TrExpr(e.Range);
wr.Write(") { ");
- wr.Write("_coll.Add(new Dafny.Pair<{0},{1}>(@{2},", domtypeName, rantypeName, bv.Name);
+ wr.Write("_coll.Add(new Dafny.Pair<{0},{1}>(@{2},", domtypeName, rantypeName, bv.CompileName);
TrExpr(e.Term);
wr.Write(")); }");
wr.Write("}");
@@ -2186,7 +2209,7 @@ namespace Microsoft.Dafny { tr(e.Receiver);
twr.Write(")");
}
- twr.Write(".@{0}", f.Name);
+ twr.Write(".@{0}", f.CompileName);
twr.Write("(");
string sep = "";
for (int i = 0; i < e.Args.Count; i++) {
diff --git a/Source/Dafny/Dafny.atg b/Source/Dafny/Dafny.atg index 97da97e3..13f6c245 100644 --- a/Source/Dafny/Dafny.atg +++ b/Source/Dafny/Dafny.atg @@ -24,7 +24,6 @@ static int anonymousIds = 0; struct MemberModifiers {
public bool IsGhost;
public bool IsStatic;
- public bool IsUnlimited;
}
// helper routine for parsing call statements
///<summary>
@@ -226,7 +225,6 @@ ClassMemberDecl<.List<MemberDecl/*!*/>/*!*/ mm, bool isAlreadyGhost, bool allowC .)
{ "ghost" (. mmod.IsGhost = true; .)
| "static" (. mmod.IsStatic = true; .)
- | "unlimited" (. mmod.IsUnlimited = true; .)
}
( FieldDecl<mmod, mm>
| FunctionDecl<mmod, out f> (. mm.Add(f); .)
@@ -281,8 +279,7 @@ FieldDecl<.MemberModifiers mmod, List<MemberDecl/*!*/>/*!*/ mm.> .)
SYNC
"var"
- (. if (mmod.IsUnlimited) { SemErr(t, "fields cannot be declared 'unlimited'"); }
- if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
+ (. if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
.)
{ Attribute<ref attrs> }
IdentType<out id, out ty> (. mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs)); .)
@@ -396,8 +393,7 @@ MethodDecl<MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m> }
.)
)
- (. if (mmod.IsUnlimited) { SemErr(t, "methods cannot be declared 'unlimited'"); }
- if (isConstructor) {
+ (. if (isConstructor) {
if (mmod.IsGhost) {
SemErr(t, "constructors cannot be declared 'ghost'");
}
@@ -503,7 +499,7 @@ TypeAndToken<out IToken/*!*/ tok, out Type/*!*/ ty> GenericInstantiation<gt> (. if (gt.Count != 2) {
SemErr("map type expects exactly two type arguments");
}
- ty = new MapType(gt[0], gt[1]);
+ else { ty = new MapType(gt[0], gt[1]); }
.)
| ReferenceType<out tok, out ty>
)
@@ -511,6 +507,7 @@ TypeAndToken<out IToken/*!*/ tok, out Type/*!*/ 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*/
+ IToken moduleName = null;
List<Type/*!*/>/*!*/ gt;
.)
( "object" (. tok = t; ty = new ObjectType(); .)
@@ -525,7 +522,10 @@ ReferenceType<out IToken/*!*/ tok, out Type/*!*/ ty> ty = theBuiltIns.ArrayType(tok, dims, gt[0], true);
.)
| Ident<out tok> (. gt = new List<Type/*!*/>(); .)
- [ GenericInstantiation<gt> ] (. ty = new UserDefinedType(tok, tok.val, gt); .)
+ [ (. moduleName = tok; .)
+ "." Ident<out tok>
+ ]
+ [ GenericInstantiation<gt> ] (. ty = new UserDefinedType(tok, tok.val, gt, moduleName); .)
)
.
GenericInstantiation<.List<Type/*!*/>/*!*/ gt.>
@@ -596,10 +596,10 @@ FunctionDecl<MemberModifiers mmod, out Function/*!*/ f> [ FunctionBody<out body, out bodyStart, out bodyEnd>
]
(. if (isPredicate) {
- f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, mmod.IsUnlimited, typeArgs, openParen, formals,
+ f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals,
reqs, reads, ens, new Specification<Expression>(decreases, null), body, false, attrs, signatureOmitted);
} else {
- f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, mmod.IsUnlimited, typeArgs, openParen, formals, returnType,
+ 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;
@@ -691,7 +691,7 @@ OneStmt<out Statement/*!*/ s> | ParallelStmt<out s>
| "label" (. x = t; .)
Ident<out id> ":"
- OneStmt<out s> (. s.Labels = new LabelNode(x, id.val, s.Labels); .)
+ OneStmt<out s> (. s.Labels = new LList<Label>(new Label(x, id.val), s.Labels); .)
| "break" (. x = t; breakCount = 1; label = null; .)
( Ident<out id> (. label = id.val; .)
| { "break" (. breakCount++; .)
@@ -725,6 +725,7 @@ UpdateStmt<out Statement/*!*/ s> Expression lhs0;
IToken x;
Attributes attrs = null;
+ IToken suchThatAssume = null;
Expression suchThat = null;
.)
Lhs<out e> (. x = e.tok; .)
@@ -738,13 +739,15 @@ UpdateStmt<out Statement/*!*/ s> { "," 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);
+ s = new AssignSuchThatStmt(x, lhss, suchThat, suchThatAssume);
} else {
s = new UpdateStmt(x, lhss, rhss);
}
@@ -769,8 +772,23 @@ Rhs<out AssignmentRhs r, Expression receiverForInitCall> | "." Ident<out x>
"(" (. args = new List<Expression/*!*/>(); .)
[ Expressions<args> ]
- ")" (. initCall = new CallStmt(x, new List<Expression>(),
- receiverForInitCall, x.val, args); .)
+ ")" (. initCall = new CallStmt(x, new List<Expression>(), receiverForInitCall, x.val, args); .)
+ | "(" (. var udf = ty as UserDefinedType;
+ if (udf != null && udf.ModuleName != null && udf.TypeArgs.Count == 0) {
+ // The parsed name had the form "A.B", so treat "A" as the name of the type and "B" as
+ // the name of the constructor that's being invoked.
+ x = udf.tok;
+ ty = new UserDefinedType(udf.ModuleName, udf.ModuleName.val, new List<Type>(), null);
+ } 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);
@@ -784,7 +802,7 @@ Rhs<out AssignmentRhs r, Expression receiverForInitCall> | "*" (. r = new HavocRhs(t); .)
| Expression<out e> (. r = new ExprRhs(e); .)
)
- { Attribute<ref attrs> } (. r.Attributes = attrs; .)
+ { Attribute<ref attrs> } (. if (r != null) r.Attributes = attrs; .)
.
VarDeclStatement<.out Statement/*!*/ s.>
= (. IToken x = null, assignTok = null; bool isGhost = false;
@@ -792,6 +810,7 @@ VarDeclStatement<.out Statement/*!*/ s.> 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; .)
@@ -809,6 +828,8 @@ VarDeclStatement<.out Statement/*!*/ s.> { "," Rhs<out r, lhs0> (. rhss.Add(r); .)
}
| ":|" (. assignTok = t; .)
+ [ "assume" (. suchThatAssume = t; .)
+ ]
Expression<out suchThat>
]
";"
@@ -818,7 +839,7 @@ VarDeclStatement<.out Statement/*!*/ s.> foreach (var lhs in lhss) {
ies.Add(new IdentifierExpr(lhs.Tok, lhs.Name));
}
- update = new AssignSuchThatStmt(assignTok, ies, suchThat);
+ update = new AssignSuchThatStmt(assignTok, ies, suchThat, suchThatAssume);
} else if (rhss.Count == 0) {
update = null;
} else {
diff --git a/Source/Dafny/DafnyAst.cs b/Source/Dafny/DafnyAst.cs index 5fd34e65..a57ef79d 100644 --- a/Source/Dafny/DafnyAst.cs +++ b/Source/Dafny/DafnyAst.cs @@ -54,7 +54,7 @@ namespace Microsoft.Dafny { List<Type/*!*/> typeArgs = new List<Type/*!*/>();
typeArgs.Add(arg);
- UserDefinedType udt = new UserDefinedType(tok, ArrayClassName(dims), typeArgs);
+ 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++) {
@@ -393,7 +393,8 @@ namespace Microsoft.Dafny { Contract.Invariant(cce.NonNullElements(TypeArgs));
}
- public readonly IToken tok;
+ public readonly IToken ModuleName; // may be null
+ public readonly IToken tok; // token of the Name
public readonly string Name;
[Rep]
public readonly List<Type/*!*/>/*!*/ TypeArgs;
@@ -408,13 +409,33 @@ namespace Microsoft.Dafny { }
}
+ 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 and TypeArgs match the type parameters of that class/datatype
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) {
+ public UserDefinedType(IToken/*!*/ tok, string/*!*/ name, [Captured] List<Type/*!*/>/*!*/ typeArgs, IToken moduleName) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(cce.NonNullElements(typeArgs));
+ this.ModuleName = moduleName;
this.tok = tok;
this.Name = name;
this.TypeArgs = typeArgs;
@@ -480,6 +501,9 @@ namespace Microsoft.Dafny { Contract.Ensures(Contract.Result<string>() != null);
string s = Name;
+ if (ModuleName != null) {
+ s = ModuleName.val + "." + s;
+ }
if (TypeArgs.Count != 0) {
string sep = "<";
foreach (Type t in TypeArgs) {
@@ -652,6 +676,15 @@ namespace Microsoft.Dafny { public IToken BodyStartTok = Token.NoToken;
public IToken BodyEndTok = Token.NoToken;
public readonly string/*!*/ Name;
+ string compileName;
+ public string CompileName {
+ get {
+ if (compileName == null) {
+ compileName = NonglobalVariable.CompilerizeName(Name);
+ }
+ return compileName;
+ }
+ }
public readonly Attributes Attributes;
public Declaration(IToken tok, string name, Attributes attributes) {
@@ -770,6 +803,11 @@ namespace Microsoft.Dafny { return Module.Name + "." + Name;
}
}
+ public string FullCompileName {
+ get {
+ return Module.CompileName + "." + CompileName;
+ }
+ }
}
public class ClassDecl : TopLevelDecl {
@@ -934,6 +972,14 @@ namespace Microsoft.Dafny { return EnclosingClass.FullName + "." + Name;
}
}
+ public string FullCompileName {
+ get {
+ Contract.Requires(EnclosingClass != null);
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ return EnclosingClass.FullCompileName + "." + CompileName;
+ }
+ }
}
public class Field : MemberDecl {
@@ -1019,6 +1065,9 @@ namespace Microsoft.Dafny { string/*!*/ UniqueName {
get;
}
+ string/*!*/ CompileName {
+ get;
+ }
Type/*!*/ Type {
get;
}
@@ -1043,6 +1092,12 @@ namespace Microsoft.Dafny { throw new NotImplementedException();
}
}
+ public string CompileName {
+ get {
+ Contract.Ensures(Contract.Result<string>() != null);
+ throw new NotImplementedException();
+ }
+ }
public Type Type {
get {
Contract.Ensures(Contract.Result<Type>() != null);
@@ -1085,6 +1140,46 @@ namespace Microsoft.Dafny { 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);
+ 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 {
@@ -1140,6 +1235,14 @@ namespace Microsoft.Dafny { return !Name.StartsWith("#");
}
}
+ public override string CompileName {
+ get {
+ if (compileName == null) {
+ compileName = CompilerizeName(Name);
+ }
+ return compileName;
+ }
+ }
}
/// <summary>
@@ -1172,7 +1275,6 @@ namespace Microsoft.Dafny { public class Function : MemberDecl, TypeParameter.ParentType {
public readonly bool IsGhost; // functions are "ghost" by default; a non-ghost function is called a "function method"
- public readonly bool IsUnlimited;
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
@@ -1195,7 +1297,7 @@ namespace Microsoft.Dafny { Contract.Invariant(Decreases != null);
}
- public Function(IToken tok, string name, bool isStatic, bool isGhost, bool isUnlimited,
+ 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)
@@ -1211,7 +1313,6 @@ namespace Microsoft.Dafny { Contract.Requires(cce.NonNullElements(ens));
Contract.Requires(decreases != null);
this.IsGhost = isGhost;
- this.IsUnlimited = isUnlimited;
this.TypeArgs = typeArgs;
this.OpenParen = openParen;
this.Formals = formals;
@@ -1228,11 +1329,11 @@ namespace Microsoft.Dafny { public class Predicate : Function
{
public readonly bool BodyIsExtended; // says that this predicate definition is a refinement extension of a predicate definition is a refining module
- public Predicate(IToken tok, string name, bool isStatic, bool isGhost, bool isUnlimited,
+ 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, bool bodyIsExtended, Attributes attributes, bool signatureOmitted)
- : base(tok, name, isStatic, isGhost, isUnlimited, typeArgs, openParen, formals, new BoolType(), req, reads, ens, decreases, body, attributes, signatureOmitted) {
+ : base(tok, name, isStatic, isGhost, typeArgs, openParen, formals, new BoolType(), req, reads, ens, decreases, body, attributes, signatureOmitted) {
Contract.Requires(!bodyIsExtended || body != null);
BodyIsExtended = bodyIsExtended;
}
@@ -1320,7 +1421,7 @@ namespace Microsoft.Dafny { public abstract class Statement {
public readonly IToken Tok;
- public LabelNode Labels; // mutable during resolution
+ public LList<Label> Labels; // mutable during resolution
private Attributes attributes;
public Attributes Attributes {
@@ -1363,19 +1464,43 @@ namespace Microsoft.Dafny { }
}
- public class LabelNode
+ 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 Label;
+ public readonly string Name;
public readonly int UniqueId;
- public readonly LabelNode Next;
static int nodes = 0;
- public LabelNode(IToken tok, string label, LabelNode next) {
+ public Label(IToken tok, string label) {
Contract.Requires(tok != null);
Tok = tok;
- Label = label;
- Next = next;
+ Name = label;
UniqueId = nodes++;
}
}
@@ -1676,14 +1801,22 @@ namespace Microsoft.Dafny { public class AssignSuchThatStmt : ConcreteUpdateStatement
{
- public readonly AssumeStmt Assume;
- public AssignSuchThatStmt(IToken tok, List<Expression> lhss, Expression expr)
+ 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);
- Assume = new AssumeStmt(tok, expr);
+ Expr = expr;
+ if (assumeToken != null) {
+ AssumeToken = assumeToken;
+ }
}
}
@@ -1744,6 +1877,24 @@ namespace Microsoft.Dafny { }
}
}
+
+ /// <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 {
@@ -1778,6 +1929,15 @@ namespace Microsoft.Dafny { 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)]
diff --git a/Source/Dafny/Parser.cs b/Source/Dafny/Parser.cs index fe4d58a9..9a439914 100644 --- a/Source/Dafny/Parser.cs +++ b/Source/Dafny/Parser.cs @@ -21,7 +21,7 @@ public class Parser { public const int _colon = 5;
public const int _lbrace = 6;
public const int _rbrace = 7;
- public const int maxT = 108;
+ public const int maxT = 107;
const bool T = true;
const bool x = false;
@@ -44,7 +44,6 @@ static int anonymousIds = 0; struct MemberModifiers {
public bool IsGhost;
public bool IsStatic;
- public bool IsUnlimited;
}
// helper routine for parsing call statements
///<summary>
@@ -231,10 +230,10 @@ bool IsAttribute() { if (la.kind == 12) {
ClassDecl(module, out c);
module.TopLevelDecls.Add(c);
- } else if (la.kind == 15 || la.kind == 16) {
+ } else if (la.kind == 14 || la.kind == 15) {
DatatypeDecl(module, out dt);
module.TopLevelDecls.Add(dt);
- } else if (la.kind == 22) {
+ } else if (la.kind == 21) {
ArbitraryTypeDecl(module, out at);
module.TopLevelDecls.Add(at);
} else {
@@ -249,17 +248,17 @@ bool IsAttribute() { if (isGhost) { SemErr(t, "a class is not allowed to be declared as 'ghost'"); }
ClassDecl(defaultModule, out c);
defaultModule.TopLevelDecls.Add(c);
- } else if (la.kind == 15 || la.kind == 16) {
+ } else if (la.kind == 14 || la.kind == 15) {
if (isGhost) { SemErr(t, "a datatype/codatatype is not allowed to be declared as 'ghost'"); }
DatatypeDecl(defaultModule, out dt);
defaultModule.TopLevelDecls.Add(dt);
- } else if (la.kind == 22) {
+ } else if (la.kind == 21) {
if (isGhost) { SemErr(t, "a type is not allowed to be declared as 'ghost'"); }
ArbitraryTypeDecl(defaultModule, out at);
defaultModule.TopLevelDecls.Add(at);
} else if (StartOf(3)) {
ClassMemberDecl(membersDefaultClass, isGhost, false);
- } else SynErr(109);
+ } else SynErr(108);
}
if (defaultModuleCreatedHere) {
defaultModule.TopLevelDecls.Add(new DefaultClassDecl(defaultModule, membersDefaultClass));
@@ -294,7 +293,7 @@ bool IsAttribute() { IToken/*!*/ id;
Ident(out id);
ids.Add(id.val);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Ident(out id);
ids.Add(id.val);
@@ -310,13 +309,13 @@ bool IsAttribute() { List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
IToken bodyStart;
- while (!(la.kind == 0 || la.kind == 12)) {SynErr(110); Get();}
+ while (!(la.kind == 0 || la.kind == 12)) {SynErr(109); Get();}
Expect(12);
while (la.kind == 6) {
Attribute(ref attrs);
}
Ident(out id);
- if (la.kind == 23) {
+ if (la.kind == 22) {
GenericParameters(typeArgs);
}
Expect(6);
@@ -341,29 +340,29 @@ bool IsAttribute() { IToken bodyStart = Token.NoToken; // dummy assignment
bool co = false;
- while (!(la.kind == 0 || la.kind == 15 || la.kind == 16)) {SynErr(111); Get();}
- if (la.kind == 15) {
+ while (!(la.kind == 0 || la.kind == 14 || la.kind == 15)) {SynErr(110); Get();}
+ if (la.kind == 14) {
Get();
- } else if (la.kind == 16) {
+ } else if (la.kind == 15) {
Get();
co = true;
- } else SynErr(112);
+ } else SynErr(111);
while (la.kind == 6) {
Attribute(ref attrs);
}
Ident(out id);
- if (la.kind == 23) {
+ if (la.kind == 22) {
GenericParameters(typeArgs);
}
- Expect(17);
+ Expect(16);
bodyStart = t;
DatatypeMemberDecl(ctors);
- while (la.kind == 18) {
+ while (la.kind == 17) {
Get();
DatatypeMemberDecl(ctors);
}
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(113); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(112); Get();}
+ Expect(18);
if (co) {
dt = new CoDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
} else {
@@ -378,14 +377,14 @@ bool IsAttribute() { IToken/*!*/ id;
Attributes attrs = null;
- Expect(22);
+ Expect(21);
while (la.kind == 6) {
Attribute(ref attrs);
}
Ident(out id);
at = new ArbitraryTypeDecl(id, id.val, module, attrs);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(114); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(113); Get();}
+ Expect(18);
}
void ClassMemberDecl(List<MemberDecl/*!*/>/*!*/ mm, bool isAlreadyGhost, bool allowConstructors) {
@@ -395,41 +394,38 @@ bool IsAttribute() { MemberModifiers mmod = new MemberModifiers();
mmod.IsGhost = isAlreadyGhost;
- while (la.kind == 8 || la.kind == 13 || la.kind == 14) {
+ while (la.kind == 8 || la.kind == 13) {
if (la.kind == 8) {
Get();
mmod.IsGhost = true;
- } else if (la.kind == 13) {
- Get();
- mmod.IsStatic = true;
} else {
Get();
- mmod.IsUnlimited = true;
+ mmod.IsStatic = true;
}
}
- if (la.kind == 20) {
+ if (la.kind == 19) {
FieldDecl(mmod, mm);
} else if (la.kind == 44 || la.kind == 45) {
FunctionDecl(mmod, out f);
mm.Add(f);
- } else if (la.kind == 25 || la.kind == 26) {
+ } else if (la.kind == 24 || la.kind == 25) {
MethodDecl(mmod, allowConstructors, out m);
mm.Add(m);
- } else SynErr(115);
+ } else SynErr(114);
}
void GenericParameters(List<TypeParameter/*!*/>/*!*/ typeArgs) {
Contract.Requires(cce.NonNullElements(typeArgs));
IToken/*!*/ id;
- Expect(23);
+ Expect(22);
Ident(out id);
typeArgs.Add(new TypeParameter(id, id.val));
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Ident(out id);
typeArgs.Add(new TypeParameter(id, id.val));
}
- Expect(24);
+ Expect(23);
}
void FieldDecl(MemberModifiers mmod, List<MemberDecl/*!*/>/*!*/ mm) {
@@ -437,9 +433,8 @@ bool IsAttribute() { Attributes attrs = null;
IToken/*!*/ id; Type/*!*/ ty;
- while (!(la.kind == 0 || la.kind == 20)) {SynErr(116); Get();}
- Expect(20);
- if (mmod.IsUnlimited) { SemErr(t, "fields cannot be declared 'unlimited'"); }
+ while (!(la.kind == 0 || la.kind == 19)) {SynErr(115); Get();}
+ Expect(19);
if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
while (la.kind == 6) {
@@ -447,13 +442,13 @@ bool IsAttribute() { }
IdentType(out id, out ty);
mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
IdentType(out id, out ty);
mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
}
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(117); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(116); Get();}
+ Expect(18);
}
void FunctionDecl(MemberModifiers mmod, out Function/*!*/ f) {
@@ -477,7 +472,7 @@ bool IsAttribute() { if (la.kind == 44) {
Get();
- if (la.kind == 25) {
+ if (la.kind == 24) {
Get();
isFunctionMethod = true;
}
@@ -487,22 +482,22 @@ bool IsAttribute() { Attribute(ref attrs);
}
Ident(out id);
- if (la.kind == 23 || la.kind == 34) {
- if (la.kind == 23) {
+ if (la.kind == 22 || la.kind == 33) {
+ if (la.kind == 22) {
GenericParameters(typeArgs);
}
Formals(true, isFunctionMethod, formals, out openParen);
Expect(5);
Type(out returnType);
- } else if (la.kind == 28) {
+ } else if (la.kind == 27) {
Get();
signatureOmitted = true;
openParen = Token.NoToken;
- } else SynErr(118);
+ } else SynErr(117);
} else if (la.kind == 45) {
Get();
isPredicate = true;
- if (la.kind == 25) {
+ if (la.kind == 24) {
Get();
isFunctionMethod = true;
}
@@ -513,22 +508,22 @@ bool IsAttribute() { }
Ident(out id);
if (StartOf(4)) {
- if (la.kind == 23) {
+ if (la.kind == 22) {
GenericParameters(typeArgs);
}
- if (la.kind == 34) {
+ if (la.kind == 33) {
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 == 28) {
+ } else if (la.kind == 27) {
Get();
signatureOmitted = true;
openParen = Token.NoToken;
- } else SynErr(119);
- } else SynErr(120);
+ } else SynErr(118);
+ } else SynErr(119);
while (StartOf(5)) {
FunctionSpec(reqs, reads, ens, decreases);
}
@@ -536,10 +531,10 @@ bool IsAttribute() { FunctionBody(out body, out bodyStart, out bodyEnd);
}
if (isPredicate) {
- f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, mmod.IsUnlimited, typeArgs, openParen, formals,
+ f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals,
reqs, reads, ens, new Specification<Expression>(decreases, null), body, false, attrs, signatureOmitted);
} else {
- f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, mmod.IsUnlimited, typeArgs, openParen, formals, returnType,
+ 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;
@@ -567,10 +562,10 @@ bool IsAttribute() { IToken bodyStart = Token.NoToken;
IToken bodyEnd = Token.NoToken;
- while (!(la.kind == 0 || la.kind == 25 || la.kind == 26)) {SynErr(121); Get();}
- if (la.kind == 25) {
+ while (!(la.kind == 0 || la.kind == 24 || la.kind == 25)) {SynErr(120); Get();}
+ if (la.kind == 24) {
Get();
- } else if (la.kind == 26) {
+ } else if (la.kind == 25) {
Get();
if (allowConstructor) {
isConstructor = true;
@@ -578,8 +573,7 @@ bool IsAttribute() { SemErr(t, "constructors are only allowed in classes");
}
- } else SynErr(122);
- if (mmod.IsUnlimited) { SemErr(t, "methods cannot be declared 'unlimited'"); }
+ } else SynErr(121);
if (isConstructor) {
if (mmod.IsGhost) {
SemErr(t, "constructors cannot be declared 'ghost'");
@@ -593,20 +587,20 @@ bool IsAttribute() { Attribute(ref attrs);
}
Ident(out id);
- if (la.kind == 23 || la.kind == 34) {
- if (la.kind == 23) {
+ if (la.kind == 22 || la.kind == 33) {
+ if (la.kind == 22) {
GenericParameters(typeArgs);
}
Formals(true, !mmod.IsGhost, ins, out openParen);
- if (la.kind == 27) {
+ if (la.kind == 26) {
Get();
if (isConstructor) { SemErr(t, "constructors cannot have out-parameters"); }
Formals(false, !mmod.IsGhost, outs, out openParen);
}
- } else if (la.kind == 28) {
+ } else if (la.kind == 27) {
Get();
signatureOmitted = true; openParen = Token.NoToken;
- } else SynErr(123);
+ } else SynErr(122);
while (StartOf(6)) {
MethodSpec(req, mod, ens, dec, ref decAttrs, ref modAttrs);
}
@@ -635,7 +629,7 @@ bool IsAttribute() { Attribute(ref attrs);
}
Ident(out id);
- if (la.kind == 34) {
+ if (la.kind == 33) {
FormalsOptionalIds(formals);
}
ctors.Add(new DatatypeCtor(id, id.val, formals, attrs));
@@ -643,17 +637,17 @@ bool IsAttribute() { void FormalsOptionalIds(List<Formal/*!*/>/*!*/ formals) {
Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; string/*!*/ name; bool isGhost;
- Expect(34);
+ Expect(33);
if (StartOf(7)) {
TypeIdentOptional(out id, out name, out ty, out isGhost);
formals.Add(new Formal(id, name, ty, true, isGhost));
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
TypeIdentOptional(out id, out name, out ty, out isGhost);
formals.Add(new Formal(id, name, ty, true, isGhost));
}
}
- Expect(35);
+ Expect(34);
}
void IdentType(out IToken/*!*/ id, out Type/*!*/ ty) {
@@ -737,22 +731,22 @@ bool IsAttribute() { List<Type/*!*/>/*!*/ gt;
switch (la.kind) {
- case 36: {
+ case 35: {
Get();
tok = t;
break;
}
- case 37: {
+ case 36: {
Get();
tok = t; ty = new NatType();
break;
}
- case 38: {
+ case 37: {
Get();
tok = t; ty = new IntType();
break;
}
- case 39: {
+ case 38: {
Get();
tok = t; gt = new List<Type/*!*/>();
GenericInstantiation(gt);
@@ -763,7 +757,7 @@ bool IsAttribute() { break;
}
- case 40: {
+ case 39: {
Get();
tok = t; gt = new List<Type/*!*/>();
GenericInstantiation(gt);
@@ -774,7 +768,7 @@ bool IsAttribute() { break;
}
- case 41: {
+ case 40: {
Get();
tok = t; gt = new List<Type/*!*/>();
GenericInstantiation(gt);
@@ -785,39 +779,39 @@ bool IsAttribute() { break;
}
- case 42: {
+ case 41: {
Get();
tok = t; gt = new List<Type/*!*/>();
GenericInstantiation(gt);
if (gt.Count != 2) {
SemErr("map type expects exactly two type arguments");
}
- ty = new MapType(gt[0], gt[1]);
+ else { ty = new MapType(gt[0], gt[1]); }
break;
}
- case 1: case 3: case 43: {
+ case 1: case 3: case 42: {
ReferenceType(out tok, out ty);
break;
}
- default: SynErr(124); break;
+ default: SynErr(123); 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(34);
+ Expect(33);
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 == 21) {
+ while (la.kind == 20) {
Get();
GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
}
}
- Expect(35);
+ Expect(34);
}
void MethodSpec(List<MaybeFreeExpression/*!*/>/*!*/ req, List<FrameExpression/*!*/>/*!*/ mod, List<MaybeFreeExpression/*!*/>/*!*/ ens,
@@ -825,8 +819,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo 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(8))) {SynErr(125); Get();}
- if (la.kind == 29) {
+ while (!(StartOf(8))) {SynErr(124); Get();}
+ if (la.kind == 28) {
Get();
while (IsAttribute()) {
Attribute(ref modAttrs);
@@ -834,44 +828,44 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (StartOf(9)) {
FrameExpression(out fe);
mod.Add(fe);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
FrameExpression(out fe);
mod.Add(fe);
}
}
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(126); Get();}
- Expect(19);
- } else if (la.kind == 30 || la.kind == 31 || la.kind == 32) {
- if (la.kind == 30) {
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(125); Get();}
+ Expect(18);
+ } else if (la.kind == 29 || la.kind == 30 || la.kind == 31) {
+ if (la.kind == 29) {
Get();
isFree = true;
}
- if (la.kind == 31) {
+ if (la.kind == 30) {
Get();
Expression(out e);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(127); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(126); Get();}
+ Expect(18);
req.Add(new MaybeFreeExpression(e, isFree));
- } else if (la.kind == 32) {
+ } else if (la.kind == 31) {
Get();
while (IsAttribute()) {
Attribute(ref ensAttrs);
}
Expression(out e);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(128); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(127); Get();}
+ Expect(18);
ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
- } else SynErr(129);
- } else if (la.kind == 33) {
+ } else SynErr(128);
+ } else if (la.kind == 32) {
Get();
while (IsAttribute()) {
Attribute(ref decAttrs);
}
DecreasesList(decreases, false);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(130); Get();}
- Expect(19);
- } else SynErr(131);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(129); Get();}
+ Expect(18);
+ } else SynErr(130);
}
void BlockStmt(out BlockStmt/*!*/ block, out IToken bodyStart, out IToken bodyEnd) {
@@ -912,7 +906,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo decreases.Add(e);
}
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
PossiblyWildExpression(out e);
if (!allowWildcard && e is WildcardExpr) {
@@ -926,23 +920,24 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo void GenericInstantiation(List<Type/*!*/>/*!*/ gt) {
Contract.Requires(cce.NonNullElements(gt)); Type/*!*/ ty;
- Expect(23);
+ Expect(22);
Type(out ty);
gt.Add(ty);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Type(out ty);
gt.Add(ty);
}
- Expect(24);
+ Expect(23);
}
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*/
+ IToken moduleName = null;
List<Type/*!*/>/*!*/ gt;
- if (la.kind == 43) {
+ if (la.kind == 42) {
Get();
tok = t; ty = new ObjectType();
} else if (la.kind == 3) {
@@ -961,48 +956,53 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo } else if (la.kind == 1) {
Ident(out tok);
gt = new List<Type/*!*/>();
- if (la.kind == 23) {
+ if (la.kind == 43) {
+ moduleName = tok;
+ Get();
+ Ident(out tok);
+ }
+ if (la.kind == 22) {
GenericInstantiation(gt);
}
- ty = new UserDefinedType(tok, tok.val, gt);
- } else SynErr(132);
+ ty = new UserDefinedType(tok, tok.val, gt, moduleName);
+ } else SynErr(131);
}
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(cce.NonNullElements(decreases));
Expression/*!*/ e; FrameExpression/*!*/ fe;
- if (la.kind == 31) {
- while (!(la.kind == 0 || la.kind == 31)) {SynErr(133); Get();}
+ if (la.kind == 30) {
+ while (!(la.kind == 0 || la.kind == 30)) {SynErr(132); Get();}
Get();
Expression(out e);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(134); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(133); Get();}
+ Expect(18);
reqs.Add(e);
} else if (la.kind == 46) {
Get();
if (StartOf(11)) {
PossiblyWildFrameExpression(out fe);
reads.Add(fe);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
PossiblyWildFrameExpression(out fe);
reads.Add(fe);
}
}
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(135); Get();}
- Expect(19);
- } else if (la.kind == 32) {
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(134); Get();}
+ Expect(18);
+ } else if (la.kind == 31) {
Get();
Expression(out e);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(136); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(135); Get();}
+ Expect(18);
ens.Add(e);
- } else if (la.kind == 33) {
+ } else if (la.kind == 32) {
Get();
DecreasesList(decreases, false);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(137); Get();}
- Expect(19);
- } else SynErr(138);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(136); Get();}
+ Expect(18);
+ } else SynErr(137);
}
void FunctionBody(out Expression/*!*/ e, out IToken bodyStart, out IToken bodyEnd) {
@@ -1021,7 +1021,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo fe = new FrameExpression(new WildcardExpr(t), null);
} else if (StartOf(9)) {
FrameExpression(out fe);
- } else SynErr(139);
+ } else SynErr(138);
}
void PossiblyWildExpression(out Expression/*!*/ e) {
@@ -1032,7 +1032,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo e = new WildcardExpr(t);
} else if (StartOf(9)) {
Expression(out e);
- } else SynErr(140);
+ } else SynErr(139);
}
void Stmt(List<Statement/*!*/>/*!*/ ss) {
@@ -1049,7 +1049,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo IToken bodyStart, bodyEnd;
int breakCount;
- while (!(StartOf(12))) {SynErr(141); Get();}
+ while (!(StartOf(12))) {SynErr(140); Get();}
switch (la.kind) {
case 6: {
BlockStmt(out bs, out bodyStart, out bodyEnd);
@@ -1060,19 +1060,19 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo AssertStmt(out s);
break;
}
- case 67: {
+ case 54: {
AssumeStmt(out s);
break;
}
- case 68: {
+ case 67: {
PrintStmt(out s);
break;
}
- case 1: case 2: case 18: case 34: case 93: case 94: case 95: case 96: case 97: case 98: case 99: {
+ case 1: case 2: case 17: case 33: case 92: case 93: case 94: case 95: case 96: case 97: case 98: {
UpdateStmt(out s);
break;
}
- case 8: case 20: {
+ case 8: case 19: {
VarDeclStatement(out s);
break;
}
@@ -1088,7 +1088,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo MatchStmt(out s);
break;
}
- case 69: {
+ case 68: {
ParallelStmt(out s);
break;
}
@@ -1098,7 +1098,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Ident(out id);
Expect(5);
OneStmt(out s);
- s.Labels = new LabelNode(x, id.val, s.Labels);
+ s.Labels = new LList<Label>(new Label(x, id.val), s.Labels);
break;
}
case 50: {
@@ -1107,14 +1107,14 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (la.kind == 1) {
Ident(out id);
label = id.val;
- } else if (la.kind == 19 || la.kind == 50) {
+ } else if (la.kind == 18 || la.kind == 50) {
while (la.kind == 50) {
Get();
breakCount++;
}
- } else SynErr(142);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(143); Get();}
- Expect(19);
+ } else SynErr(141);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(142); Get();}
+ Expect(18);
s = label != null ? new BreakStmt(x, label) : new BreakStmt(x, breakCount);
break;
}
@@ -1122,13 +1122,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo ReturnStmt(out s);
break;
}
- case 28: {
+ case 27: {
Get();
s = new SkeletonStatement(t);
- Expect(19);
+ Expect(18);
break;
}
- default: SynErr(144); break;
+ default: SynErr(143); break;
}
}
@@ -1143,10 +1143,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
if (StartOf(9)) {
Expression(out e);
- } else if (la.kind == 28) {
+ } else if (la.kind == 27) {
Get();
- } else SynErr(145);
- Expect(19);
+ } else SynErr(144);
+ Expect(18);
if (e == null) {
s = new SkeletonStatement(new AssertStmt(x, new LiteralExpr(x, true), attrs), true, false);
} else {
@@ -1157,10 +1157,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo void AssumeStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e;
- Expect(67);
+ Expect(54);
x = t;
Expression(out e);
- Expect(19);
+ Expect(18);
s = new AssumeStmt(x, e);
}
@@ -1168,16 +1168,16 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Attributes.Argument/*!*/ arg;
List<Attributes.Argument/*!*/> args = new List<Attributes.Argument/*!*/>();
- Expect(68);
+ Expect(67);
x = t;
AttributeArg(out arg);
args.Add(arg);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
AttributeArg(out arg);
args.Add(arg);
}
- Expect(19);
+ Expect(18);
s = new PrintStmt(x, args);
}
@@ -1188,19 +1188,20 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo 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 == 19) {
+ if (la.kind == 6 || la.kind == 18) {
while (la.kind == 6) {
Attribute(ref attrs);
}
- Expect(19);
+ Expect(18);
rhss.Add(new ExprRhs(e, attrs));
- } else if (la.kind == 21 || la.kind == 52 || la.kind == 53) {
+ } else if (la.kind == 20 || la.kind == 52 || la.kind == 53) {
lhss.Add(e); lhs0 = e;
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Lhs(out e);
lhss.Add(e);
@@ -1210,7 +1211,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo x = t;
Rhs(out r, lhs0);
rhss.Add(r);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Rhs(out r, lhs0);
rhss.Add(r);
@@ -1218,15 +1219,19 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo } else if (la.kind == 53) {
Get();
x = t;
+ if (la.kind == 54) {
+ Get();
+ suchThatAssume = t;
+ }
Expression(out suchThat);
- } else SynErr(146);
- Expect(19);
+ } else SynErr(145);
+ Expect(18);
} else if (la.kind == 5) {
Get();
SemErr(t, "invalid statement (did you forget the 'label' keyword?)");
- } else SynErr(147);
+ } else SynErr(146);
if (suchThat != null) {
- s = new AssignSuchThatStmt(x, lhss, suchThat);
+ s = new AssignSuchThatStmt(x, lhss, suchThat, suchThatAssume);
} else {
s = new UpdateStmt(x, lhss, rhss);
}
@@ -1239,17 +1244,18 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo 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(20);
+ Expect(19);
if (!isGhost) { x = t; }
LocalIdentTypeOptional(out d, isGhost);
lhss.Add(d);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
LocalIdentTypeOptional(out d, isGhost);
lhss.Add(d);
@@ -1263,7 +1269,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Rhs(out r, lhs0);
rhss.Add(r);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Rhs(out r, lhs0);
rhss.Add(r);
@@ -1271,17 +1277,21 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo } else {
Get();
assignTok = t;
+ if (la.kind == 54) {
+ Get();
+ suchThatAssume = t;
+ }
Expression(out suchThat);
}
}
- Expect(19);
+ Expect(18);
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);
+ update = new AssignSuchThatStmt(assignTok, ies, suchThat, suchThatAssume);
} else if (rhss.Count == 0) {
update = null;
} else {
@@ -1308,8 +1318,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expect(59);
x = t;
- if (la.kind == 28 || la.kind == 34) {
- if (la.kind == 34) {
+ if (la.kind == 27 || la.kind == 33) {
+ if (la.kind == 33) {
Guard(out guard);
} else {
Get();
@@ -1324,7 +1334,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo } else if (la.kind == 6) {
BlockStmt(out bs, out bodyStart, out bodyEnd);
els = bs;
- } else SynErr(148);
+ } else SynErr(147);
}
if (guardOmitted) {
ifStmt = new SkeletonStatement(new IfStmt(x, guard, thn, els), true, false);
@@ -1335,7 +1345,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo } else if (la.kind == 6) {
AlternativeBlock(out alternatives);
ifStmt = new AlternativeStmt(x, alternatives);
- } else SynErr(149);
+ } else SynErr(148);
}
void WhileStmt(out Statement/*!*/ stmt) {
@@ -1353,8 +1363,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expect(63);
x = t;
- if (la.kind == 28 || la.kind == 34) {
- if (la.kind == 34) {
+ if (la.kind == 27 || la.kind == 33) {
+ if (la.kind == 33) {
Guard(out guard);
Contract.Assume(guard == null || cce.Owner.None(guard));
} else {
@@ -1364,10 +1374,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo 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 == 28) {
+ } else if (la.kind == 27) {
Get();
bodyOmitted = true;
- } else SynErr(150);
+ } else SynErr(149);
if (guardOmitted || bodyOmitted) {
if (decreases.Count != 0) {
SemErr(decreases[0].tok, "'decreases' clauses are not allowed on refining loops");
@@ -1388,7 +1398,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo 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(151);
+ } else SynErr(150);
}
void MatchStmt(out Statement/*!*/ s) {
@@ -1419,9 +1429,9 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo BlockStmt/*!*/ block;
IToken bodyStart, bodyEnd;
- Expect(69);
+ Expect(68);
x = t;
- Expect(34);
+ Expect(33);
if (la.kind == 1) {
List<BoundVar/*!*/> bvarsX; Attributes attrsX; Expression rangeX;
QuantifierDomain(out bvarsX, out attrsX, out rangeX);
@@ -1431,16 +1441,16 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (bvars == null) { bvars = new List<BoundVar>(); }
if (range == null) { range = new LiteralExpr(x, true); }
- Expect(35);
- while (la.kind == 30 || la.kind == 32) {
+ Expect(34);
+ while (la.kind == 29 || la.kind == 31) {
isFree = false;
- if (la.kind == 30) {
+ if (la.kind == 29) {
Get();
isFree = true;
}
- Expect(32);
+ Expect(31);
Expression(out e);
- Expect(19);
+ Expect(18);
ens.Add(new MaybeFreeExpression(e, isFree));
}
BlockStmt(out block, out bodyStart, out bodyEnd);
@@ -1457,13 +1467,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (StartOf(14)) {
Rhs(out r, null);
rhss = new List<AssignmentRhs>(); rhss.Add(r);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Rhs(out r, null);
rhss.Add(r);
}
}
- Expect(19);
+ Expect(18);
s = new ReturnStmt(returnTok, rhss);
}
@@ -1476,29 +1486,49 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo r = null; // to please compiler
Attributes attrs = null;
- if (la.kind == 54) {
+ if (la.kind == 55) {
Get();
newToken = t;
TypeAndToken(out x, out ty);
- if (la.kind == 55 || la.kind == 57) {
- if (la.kind == 55) {
+ if (la.kind == 33 || la.kind == 43 || la.kind == 56) {
+ if (la.kind == 56) {
Get();
ee = new List<Expression>();
Expressions(ee);
- Expect(56);
+ Expect(57);
UserDefinedType tmp = theBuiltIns.ArrayType(x, ee.Count, new IntType(), true);
- } else {
+ } else if (la.kind == 43) {
Get();
Ident(out x);
+ Expect(33);
+ args = new List<Expression/*!*/>();
+ if (StartOf(9)) {
+ Expressions(args);
+ }
Expect(34);
+ initCall = new CallStmt(x, new List<Expression>(), receiverForInitCall, x.val, args);
+ } else {
+ Get();
+ var udf = ty as UserDefinedType;
+ if (udf != null && udf.ModuleName != null && udf.TypeArgs.Count == 0) {
+ // The parsed name had the form "A.B", so treat "A" as the name of the type and "B" as
+ // the name of the constructor that's being invoked.
+ x = udf.tok;
+ ty = new UserDefinedType(udf.ModuleName, udf.ModuleName.val, new List<Type>(), null);
+ } else {
+ SemErr(t, "expected '.'");
+ x = null;
+ }
args = new List<Expression/*!*/>();
if (StartOf(9)) {
Expressions(args);
}
- Expect(35);
- initCall = new CallStmt(x, new List<Expression>(),
- receiverForInitCall, x.val, args);
+ Expect(34);
+ if (x != null) {
+ initCall = new CallStmt(x, new List<Expression>(), receiverForInitCall, x.val, args);
+ }
+
}
}
if (ee != null) {
@@ -1518,11 +1548,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo } else if (StartOf(9)) {
Expression(out e);
r = new ExprRhs(e);
- } else SynErr(152);
+ } else SynErr(151);
while (la.kind == 6) {
Attribute(ref attrs);
}
- r.Attributes = attrs;
+ if (r != null) r.Attributes = attrs;
}
void Lhs(out Expression e) {
@@ -1530,23 +1560,23 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (la.kind == 1) {
DottedIdentifiersAndFunction(out e);
- while (la.kind == 55 || la.kind == 57) {
+ while (la.kind == 43 || la.kind == 56) {
Suffix(ref e);
}
} else if (StartOf(15)) {
ConstAtomExpression(out e);
Suffix(ref e);
- while (la.kind == 55 || la.kind == 57) {
+ while (la.kind == 43 || la.kind == 56) {
Suffix(ref e);
}
- } else SynErr(153);
+ } else SynErr(152);
}
void Expressions(List<Expression/*!*/>/*!*/ args) {
Contract.Requires(cce.NonNullElements(args)); Expression/*!*/ e;
Expression(out e);
args.Add(e);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Expression(out e);
args.Add(e);
@@ -1555,15 +1585,15 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo void Guard(out Expression e) {
Expression/*!*/ ee; e = null;
- Expect(34);
+ Expect(33);
if (la.kind == 47) {
Get();
e = null;
} else if (StartOf(9)) {
Expression(out ee);
e = ee;
- } else SynErr(154);
- Expect(35);
+ } else SynErr(153);
+ Expect(34);
}
void AlternativeBlock(out List<GuardedAlternative> alternatives) {
@@ -1595,22 +1625,22 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo mod = null;
while (StartOf(16)) {
- if (la.kind == 30 || la.kind == 64) {
+ if (la.kind == 29 || la.kind == 64) {
Invariant(out invariant);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(155); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(154); Get();}
+ Expect(18);
invariants.Add(invariant);
- } else if (la.kind == 33) {
- while (!(la.kind == 0 || la.kind == 33)) {SynErr(156); Get();}
+ } else if (la.kind == 32) {
+ while (!(la.kind == 0 || la.kind == 32)) {SynErr(155); Get();}
Get();
while (IsAttribute()) {
Attribute(ref decAttrs);
}
DecreasesList(decreases, true);
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(157); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(156); Get();}
+ Expect(18);
} else {
- while (!(la.kind == 0 || la.kind == 29)) {SynErr(158); Get();}
+ while (!(la.kind == 0 || la.kind == 28)) {SynErr(157); Get();}
Get();
while (IsAttribute()) {
Attribute(ref modAttrs);
@@ -1619,22 +1649,22 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (StartOf(9)) {
FrameExpression(out fe);
mod.Add(fe);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
FrameExpression(out fe);
mod.Add(fe);
}
}
- while (!(la.kind == 0 || la.kind == 19)) {SynErr(159); Get();}
- Expect(19);
+ while (!(la.kind == 0 || la.kind == 18)) {SynErr(158); Get();}
+ Expect(18);
}
}
}
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 == 30 || la.kind == 64)) {SynErr(160); Get();}
- if (la.kind == 30) {
+ while (!(la.kind == 0 || la.kind == 29 || la.kind == 64)) {SynErr(159); Get();}
+ if (la.kind == 29) {
Get();
isFree = true;
}
@@ -1656,16 +1686,16 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expect(61);
x = t;
Ident(out id);
- if (la.kind == 34) {
+ if (la.kind == 33) {
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
}
- Expect(35);
+ Expect(34);
}
Expect(62);
while (StartOf(10)) {
@@ -1682,7 +1712,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo } else if (StartOf(9)) {
Expression(out e);
arg = new Attributes.Argument(t, e);
- } else SynErr(161);
+ } else SynErr(160);
}
void QuantifierDomain(out List<BoundVar/*!*/> bvars, out Attributes attrs, out Expression range) {
@@ -1693,7 +1723,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo IdentTypeOptional(out bv);
bvars.Add(bv);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
IdentTypeOptional(out bv);
bvars.Add(bv);
@@ -1701,7 +1731,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo while (la.kind == 6) {
Attribute(ref attrs);
}
- if (la.kind == 18) {
+ if (la.kind == 17) {
Get();
Expression(out range);
}
@@ -1710,7 +1740,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo void EquivExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
ImpliesExpression(out e0);
- while (la.kind == 70 || la.kind == 71) {
+ while (la.kind == 69 || la.kind == 70) {
EquivOp();
x = t;
ImpliesExpression(out e1);
@@ -1721,7 +1751,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo void ImpliesExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
LogicalExpression(out e0);
- if (la.kind == 72 || la.kind == 73) {
+ if (la.kind == 71 || la.kind == 72) {
ImpliesOp();
x = t;
ImpliesExpression(out e1);
@@ -1730,23 +1760,23 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
void EquivOp() {
- if (la.kind == 70) {
+ if (la.kind == 69) {
Get();
- } else if (la.kind == 71) {
+ } else if (la.kind == 70) {
Get();
- } else SynErr(162);
+ } else SynErr(161);
}
void LogicalExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
RelationalExpression(out e0);
if (StartOf(17)) {
- if (la.kind == 74 || la.kind == 75) {
+ if (la.kind == 73 || la.kind == 74) {
AndOp();
x = t;
RelationalExpression(out e1);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1);
- while (la.kind == 74 || la.kind == 75) {
+ while (la.kind == 73 || la.kind == 74) {
AndOp();
x = t;
RelationalExpression(out e1);
@@ -1757,7 +1787,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo x = t;
RelationalExpression(out e1);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1);
- while (la.kind == 76 || la.kind == 77) {
+ while (la.kind == 75 || la.kind == 76) {
OrOp();
x = t;
RelationalExpression(out e1);
@@ -1768,11 +1798,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
void ImpliesOp() {
- if (la.kind == 72) {
+ if (la.kind == 71) {
Get();
- } else if (la.kind == 73) {
+ } else if (la.kind == 72) {
Get();
- } else SynErr(163);
+ } else SynErr(162);
}
void RelationalExpression(out Expression/*!*/ e) {
@@ -1866,25 +1896,25 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
void AndOp() {
- if (la.kind == 74) {
+ if (la.kind == 73) {
Get();
- } else if (la.kind == 75) {
+ } else if (la.kind == 74) {
Get();
- } else SynErr(164);
+ } else SynErr(163);
}
void OrOp() {
- if (la.kind == 76) {
+ if (la.kind == 75) {
Get();
- } else if (la.kind == 77) {
+ } else if (la.kind == 76) {
Get();
- } else SynErr(165);
+ } else SynErr(164);
}
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 == 88 || la.kind == 89) {
+ while (la.kind == 87 || la.kind == 88) {
AddOp(out x, out op);
Factor(out e1);
e0 = new BinaryExpr(x, op, e0, e1);
@@ -1897,50 +1927,50 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo IToken y;
switch (la.kind) {
- case 78: {
+ case 77: {
Get();
x = t; op = BinaryExpr.Opcode.Eq;
break;
}
- case 23: {
+ case 22: {
Get();
x = t; op = BinaryExpr.Opcode.Lt;
break;
}
- case 24: {
+ case 23: {
Get();
x = t; op = BinaryExpr.Opcode.Gt;
break;
}
- case 79: {
+ case 78: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 80: {
+ case 79: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- case 81: {
+ case 80: {
Get();
x = t; op = BinaryExpr.Opcode.Neq;
break;
}
- case 82: {
+ case 81: {
Get();
x = t; op = BinaryExpr.Opcode.Disjoint;
break;
}
- case 83: {
+ case 82: {
Get();
x = t; op = BinaryExpr.Opcode.In;
break;
}
- case 84: {
+ case 83: {
Get();
x = t; y = Token.NoToken;
- if (la.kind == 83) {
+ if (la.kind == 82) {
Get();
y = t;
}
@@ -1955,29 +1985,29 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo break;
}
- case 85: {
+ case 84: {
Get();
x = t; op = BinaryExpr.Opcode.Neq;
break;
}
- case 86: {
+ case 85: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 87: {
+ case 86: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- default: SynErr(166); break;
+ default: SynErr(165); 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 == 47 || la.kind == 90 || la.kind == 91) {
+ while (la.kind == 47 || la.kind == 89 || la.kind == 90) {
MulOp(out x, out op);
UnaryExpression(out e1);
e0 = new BinaryExpr(x, op, e0, e1);
@@ -1986,63 +2016,63 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo 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 == 88) {
+ if (la.kind == 87) {
Get();
x = t; op = BinaryExpr.Opcode.Add;
- } else if (la.kind == 89) {
+ } else if (la.kind == 88) {
Get();
x = t; op = BinaryExpr.Opcode.Sub;
- } else SynErr(167);
+ } else SynErr(166);
}
void UnaryExpression(out Expression/*!*/ e) {
Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr;
switch (la.kind) {
- case 89: {
+ case 88: {
Get();
x = t;
UnaryExpression(out e);
e = new BinaryExpr(x, BinaryExpr.Opcode.Sub, new LiteralExpr(x, 0), e);
break;
}
- case 84: case 92: {
+ case 83: case 91: {
NegOp();
x = t;
UnaryExpression(out e);
e = new UnaryExpr(x, UnaryExpr.Opcode.Not, e);
break;
}
- case 20: case 39: case 59: case 65: case 66: case 67: case 102: case 103: case 104: case 105: {
+ case 19: case 38: case 54: case 59: case 65: case 66: case 101: case 102: case 103: case 104: {
EndlessExpression(out e);
break;
}
case 1: {
DottedIdentifiersAndFunction(out e);
- while (la.kind == 55 || la.kind == 57) {
+ while (la.kind == 43 || la.kind == 56) {
Suffix(ref e);
}
break;
}
- case 6: case 55: {
+ case 6: case 56: {
DisplayExpr(out e);
break;
}
- case 40: {
+ case 39: {
MultiSetExpr(out e);
break;
}
- case 42: {
+ case 41: {
MapExpr(out e);
break;
}
- case 2: case 18: case 34: case 93: case 94: case 95: case 96: case 97: case 98: case 99: {
+ case 2: case 17: case 33: case 92: case 93: case 94: case 95: case 96: case 97: case 98: {
ConstAtomExpression(out e);
- while (la.kind == 55 || la.kind == 57) {
+ while (la.kind == 43 || la.kind == 56) {
Suffix(ref e);
}
break;
}
- default: SynErr(168); break;
+ default: SynErr(167); break;
}
}
@@ -2051,21 +2081,21 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (la.kind == 47) {
Get();
x = t; op = BinaryExpr.Opcode.Mul;
- } else if (la.kind == 90) {
+ } else if (la.kind == 89) {
Get();
x = t; op = BinaryExpr.Opcode.Div;
- } else if (la.kind == 91) {
+ } else if (la.kind == 90) {
Get();
x = t; op = BinaryExpr.Opcode.Mod;
- } else SynErr(169);
+ } else SynErr(168);
}
void NegOp() {
- if (la.kind == 84) {
+ if (la.kind == 83) {
Get();
- } else if (la.kind == 92) {
+ } else if (la.kind == 91) {
Get();
- } else SynErr(170);
+ } else SynErr(169);
}
void EndlessExpression(out Expression e) {
@@ -2080,7 +2110,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Get();
x = t;
Expression(out e);
- Expect(100);
+ Expect(99);
Expression(out e0);
Expect(60);
Expression(out e1);
@@ -2091,11 +2121,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo MatchExpression(out e);
break;
}
- case 102: case 103: case 104: case 105: {
+ case 101: case 102: case 103: case 104: {
QuantifierGuts(out e);
break;
}
- case 39: {
+ case 38: {
ComprehensionExpr(out e);
break;
}
@@ -2103,28 +2133,28 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Get();
x = t;
Expression(out e0);
- Expect(19);
+ Expect(18);
Expression(out e1);
e = new AssertExpr(x, e0, e1);
break;
}
- case 67: {
+ case 54: {
Get();
x = t;
Expression(out e0);
- Expect(19);
+ Expect(18);
Expression(out e1);
e = new AssumeExpr(x, e0, e1);
break;
}
- case 20: {
+ case 19: {
Get();
x = t;
letVars = new List<BoundVar>();
letRHSs = new List<Expression>();
IdentTypeOptional(out d);
letVars.Add(d);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
IdentTypeOptional(out d);
letVars.Add(d);
@@ -2132,17 +2162,17 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expect(52);
Expression(out e);
letRHSs.Add(e);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Expression(out e);
letRHSs.Add(e);
}
- Expect(19);
+ Expect(18);
Expression(out e);
e = new LetExpr(x, letVars, letRHSs, e);
break;
}
- default: SynErr(171); break;
+ default: SynErr(170); break;
}
}
@@ -2153,18 +2183,18 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Ident(out id);
idents.Add(id);
- while (la.kind == 57) {
+ while (la.kind == 43) {
Get();
Ident(out id);
idents.Add(id);
}
- if (la.kind == 34) {
+ if (la.kind == 33) {
Get();
openParen = t; args = new List<Expression>();
if (StartOf(9)) {
Expressions(args);
}
- Expect(35);
+ Expect(34);
}
e = new IdentifierSequence(idents, openParen, args);
}
@@ -2175,26 +2205,26 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo List<Expression> multipleIndices = null;
bool func = false;
- if (la.kind == 57) {
+ if (la.kind == 43) {
Get();
Ident(out id);
- if (la.kind == 34) {
+ if (la.kind == 33) {
Get();
IToken openParen = t; args = new List<Expression/*!*/>(); func = true;
if (StartOf(9)) {
Expressions(args);
}
- Expect(35);
+ Expect(34);
e = new FunctionCallExpr(id, id.val, e, openParen, args);
}
if (!func) { e = new ExprDotName(id, e, id.val); }
- } else if (la.kind == 55) {
+ } else if (la.kind == 56) {
Get();
x = t;
if (StartOf(9)) {
Expression(out ee);
e0 = ee;
- if (la.kind == 101) {
+ if (la.kind == 100) {
Get();
anyDots = true;
if (StartOf(9)) {
@@ -2205,8 +2235,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Get();
Expression(out ee);
e1 = ee;
- } else if (la.kind == 21 || la.kind == 56) {
- while (la.kind == 21) {
+ } else if (la.kind == 20 || la.kind == 57) {
+ while (la.kind == 20) {
Get();
Expression(out ee);
if (multipleIndices == null) {
@@ -2216,15 +2246,15 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo multipleIndices.Add(ee);
}
- } else SynErr(172);
- } else if (la.kind == 101) {
+ } else SynErr(171);
+ } else if (la.kind == 100) {
Get();
anyDots = true;
if (StartOf(9)) {
Expression(out ee);
e1 = ee;
}
- } else SynErr(173);
+ } else SynErr(172);
if (multipleIndices != null) {
e = new MultiSelectExpr(x, e, multipleIndices);
// make sure an array class with this dimensionality exists
@@ -2247,8 +2277,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
}
- Expect(56);
- } else SynErr(174);
+ Expect(57);
+ } else SynErr(173);
}
void DisplayExpr(out Expression e) {
@@ -2264,15 +2294,15 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
e = new SetDisplayExpr(x, elements);
Expect(7);
- } else if (la.kind == 55) {
+ } else if (la.kind == 56) {
Get();
x = t; elements = new List<Expression/*!*/>();
if (StartOf(9)) {
Expressions(elements);
}
e = new SeqDisplayExpr(x, elements);
- Expect(56);
- } else SynErr(175);
+ Expect(57);
+ } else SynErr(174);
}
void MultiSetExpr(out Expression e) {
@@ -2280,7 +2310,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo IToken/*!*/ x = null; List<Expression/*!*/>/*!*/ elements;
e = dummyExpr;
- Expect(40);
+ Expect(39);
x = t;
if (la.kind == 6) {
Get();
@@ -2290,15 +2320,15 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
e = new MultiSetDisplayExpr(x, elements);
Expect(7);
- } else if (la.kind == 34) {
+ } else if (la.kind == 33) {
Get();
x = t; elements = new List<Expression/*!*/>();
Expression(out e);
e = new MultiSetFormingExpr(x, e);
- Expect(35);
+ Expect(34);
} else if (StartOf(19)) {
SemErr("multiset must be followed by multiset literal or expression to coerce in parentheses.");
- } else SynErr(176);
+ } else SynErr(175);
}
void MapExpr(out Expression e) {
@@ -2307,16 +2337,16 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo List<ExpressionPair/*!*/>/*!*/ elements;
e = dummyExpr;
- Expect(42);
+ Expect(41);
x = t;
- if (la.kind == 55) {
+ if (la.kind == 56) {
Get();
elements = new List<ExpressionPair/*!*/>();
if (StartOf(9)) {
MapLiteralExpressions(out elements);
}
e = new MapDisplayExpr(x, elements);
- Expect(56);
+ Expect(57);
} else if (la.kind == 1) {
BoundVar/*!*/ bv;
List<BoundVar/*!*/> bvars = new List<BoundVar/*!*/>();
@@ -2325,14 +2355,14 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo IdentTypeOptional(out bv);
bvars.Add(bv);
- Expect(18);
+ Expect(17);
Expression(out range);
QSep();
Expression(out body);
e = new MapComprehension(x, bvars, range, body);
} else if (StartOf(19)) {
SemErr("map must be followed by literal in brackets or comprehension.");
- } else SynErr(177);
+ } else SynErr(176);
}
void ConstAtomExpression(out Expression/*!*/ e) {
@@ -2341,17 +2371,17 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo e = dummyExpr;
switch (la.kind) {
- case 93: {
+ case 92: {
Get();
e = new LiteralExpr(t, false);
break;
}
- case 94: {
+ case 93: {
Get();
e = new LiteralExpr(t, true);
break;
}
- case 95: {
+ case 94: {
Get();
e = new LiteralExpr(t);
break;
@@ -2361,55 +2391,55 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo e = new LiteralExpr(t, n);
break;
}
- case 96: {
+ case 95: {
Get();
e = new ThisExpr(t);
break;
}
- case 97: {
+ case 96: {
Get();
x = t;
- Expect(34);
+ Expect(33);
Expression(out e);
- Expect(35);
+ Expect(34);
e = new FreshExpr(x, e);
break;
}
- case 98: {
+ case 97: {
Get();
x = t;
- Expect(34);
+ Expect(33);
Expression(out e);
- Expect(35);
+ Expect(34);
e = new AllocatedExpr(x, e);
break;
}
- case 99: {
+ case 98: {
Get();
x = t;
- Expect(34);
+ Expect(33);
Expression(out e);
- Expect(35);
+ Expect(34);
e = new OldExpr(x, e);
break;
}
- case 18: {
+ case 17: {
Get();
x = t;
Expression(out e);
e = new UnaryExpr(x, UnaryExpr.Opcode.SeqLength, e);
- Expect(18);
+ Expect(17);
break;
}
- case 34: {
+ case 33: {
Get();
x = t;
Expression(out e);
e = new ParensExpression(x, e);
- Expect(35);
+ Expect(34);
break;
}
- default: SynErr(178); break;
+ default: SynErr(177); break;
}
}
@@ -2431,7 +2461,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expect(52);
Expression(out r);
elements.Add(new ExpressionPair(d,r));
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
Expression(out d);
Expect(52);
@@ -2441,11 +2471,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
void QSep() {
- if (la.kind == 106) {
+ if (la.kind == 105) {
Get();
- } else if (la.kind == 107) {
+ } else if (la.kind == 106) {
Get();
- } else SynErr(179);
+ } else SynErr(178);
}
void MatchExpression(out Expression/*!*/ e) {
@@ -2470,13 +2500,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expression range;
Expression/*!*/ body;
- if (la.kind == 102 || la.kind == 103) {
+ if (la.kind == 101 || la.kind == 102) {
Forall();
x = t; univ = true;
- } else if (la.kind == 104 || la.kind == 105) {
+ } else if (la.kind == 103 || la.kind == 104) {
Exists();
x = t;
- } else SynErr(180);
+ } else SynErr(179);
QuantifierDomain(out bvars, out attrs, out range);
QSep();
Expression(out body);
@@ -2496,18 +2526,18 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expression/*!*/ range;
Expression body = null;
- Expect(39);
+ Expect(38);
x = t;
IdentTypeOptional(out bv);
bvars.Add(bv);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
IdentTypeOptional(out bv);
bvars.Add(bv);
}
- Expect(18);
+ Expect(17);
Expression(out range);
- if (la.kind == 106 || la.kind == 107) {
+ if (la.kind == 105 || la.kind == 106) {
QSep();
Expression(out body);
}
@@ -2525,16 +2555,16 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo Expect(61);
x = t;
Ident(out id);
- if (la.kind == 34) {
+ if (la.kind == 33) {
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
}
- Expect(35);
+ Expect(34);
}
Expect(62);
Expression(out body);
@@ -2542,19 +2572,19 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
void Forall() {
- if (la.kind == 102) {
+ if (la.kind == 101) {
Get();
- } else if (la.kind == 103) {
+ } else if (la.kind == 102) {
Get();
- } else SynErr(181);
+ } else SynErr(180);
}
void Exists() {
- if (la.kind == 104) {
+ if (la.kind == 103) {
Get();
- } else if (la.kind == 105) {
+ } else if (la.kind == 104) {
Get();
- } else SynErr(182);
+ } else SynErr(181);
}
void AttributeBody(ref Attributes attrs) {
@@ -2568,7 +2598,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo if (StartOf(20)) {
AttributeArg(out aArg);
aArgs.Add(aArg);
- while (la.kind == 21) {
+ while (la.kind == 20) {
Get();
AttributeArg(out aArg);
aArgs.Add(aArg);
@@ -2590,27 +2620,27 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo }
static readonly bool[,]/*!*/ set = {
- {T,T,T,x, x,x,T,x, T,x,x,x, T,x,x,T, T,x,T,T, T,x,x,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, x,T,T,T, x,x,x,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, 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, T,T,x,x, T,T,T,T, T,x,x,x, T,x,T,x, x,T,T,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,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, T,T,T,T, T,x,x,x, T,x,T,x, x,T,T,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,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, T,x,x,x, x,T,T,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,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,x, T,T,T,T, T,x,x,x, T,x,T,T, x,T,T,x, 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,T, T,T,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,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},
- {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, 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,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,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},
- {x,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,T, T,x,T,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, T,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, T,x,x,x, x,x,x,x, x,x,T,x, T,x,x,x, x,x,x,x, T,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, x,x,x,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, x,T,T,T, T,T,T,T, 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,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,T, T,x,T,x, x,x,x,T, x,x,x,x, x,x,x,T, x,x,x,T, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, T,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,T,x, T,x,x,x, x,x,x,x, T,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, x,x,x,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, x,T,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,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, 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,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,T, T,x,T,x, x,x,x,T, x,x,x,x, x,x,T,T, x,x,T,T, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, T,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,T,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,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,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, 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,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,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,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,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,T,x,T, T,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, T,x,x,x, T,x,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,T, x,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,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,T, T,x,T,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, T,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, T,x,T,T, x,T,T,T, x,x,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,x, x,T,T,T, x,x,T,x, x,x,x,T, 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, 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, T,T,x,x, T,T,T,T, x,x,x,T, x,T,x,x, T,T,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,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, T,T,T,T, x,x,x,T, x,T,x,x, T,T,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,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,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, 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},
+ {T,x,x,x, x,x,T,T, T,T,x,x, T,T,T,T, x,x,x,T, x,T,T,x, T,T,x,x, x,x,T,T, T,T,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,T,T, T,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, 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},
+ {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,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, 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, 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},
+ {x,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,T, x,T,x,x, x,x,x,x, x,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,T, x,x,x,x, T,x,x,T, 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, T,x,x,x, x,x,x,x, x,T,x,T, x,x,x,x, x,x,x,T, x,x,x,x, x,T,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,T, x,x,x,T, 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, T,T,T,T, T,T,T,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,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,T, x,T,x,x, x,x,x,T, x,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,T, x,x,x,x, T,x,x,T, 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,T,x,T, x,x,x,x, x,x,x,T, x,x,x,x, x,T,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,T, x,x,x,T, 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, T,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, 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,T,T,x, x,x,T,x, x,x,x,x, x,x,x,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,T, x,T,x,x, x,x,x,T, x,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,T, x,x,x,x, T,x,x,T, 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,T,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, 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, 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,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,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,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,T,T, x,x,x,x, x,x,x,x, x,T,T,x, T,x,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,T, T,x,x,x, T,x,x,x, x,T,x,x, T,T,T,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,T,x, 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,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,T, x,T,x,x, x,x,x,x, x,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,T, x,x,x,x, T,x,x,T, T,T,T,T, T,T,T,x, x,T,T,T, T,x,x,x, x}
};
} // end Parser
@@ -2649,36 +2679,36 @@ public class Errors { case 11: s = "\"imports\" expected"; break;
case 12: s = "\"class\" expected"; break;
case 13: s = "\"static\" expected"; break;
- case 14: s = "\"unlimited\" expected"; break;
- case 15: s = "\"datatype\" expected"; break;
- case 16: s = "\"codatatype\" expected"; break;
- case 17: s = "\"=\" expected"; break;
- case 18: s = "\"|\" expected"; break;
- case 19: s = "\";\" expected"; break;
- case 20: s = "\"var\" expected"; break;
- case 21: s = "\",\" expected"; break;
- case 22: s = "\"type\" expected"; break;
- case 23: s = "\"<\" expected"; break;
- case 24: s = "\">\" expected"; break;
- case 25: s = "\"method\" expected"; break;
- case 26: s = "\"constructor\" expected"; break;
- case 27: s = "\"returns\" expected"; break;
- case 28: s = "\"...\" expected"; break;
- case 29: s = "\"modifies\" expected"; break;
- case 30: s = "\"free\" expected"; break;
- case 31: s = "\"requires\" expected"; break;
- case 32: s = "\"ensures\" expected"; break;
- case 33: s = "\"decreases\" expected"; break;
- case 34: s = "\"(\" expected"; break;
- case 35: s = "\")\" expected"; break;
- case 36: s = "\"bool\" expected"; break;
- case 37: s = "\"nat\" expected"; break;
- case 38: s = "\"int\" expected"; break;
- case 39: s = "\"set\" expected"; break;
- case 40: s = "\"multiset\" expected"; break;
- case 41: s = "\"seq\" expected"; break;
- case 42: s = "\"map\" expected"; break;
- case 43: s = "\"object\" expected"; break;
+ case 14: s = "\"datatype\" expected"; break;
+ case 15: s = "\"codatatype\" expected"; break;
+ case 16: s = "\"=\" expected"; break;
+ case 17: s = "\"|\" expected"; break;
+ case 18: s = "\";\" expected"; break;
+ case 19: s = "\"var\" expected"; break;
+ case 20: s = "\",\" expected"; break;
+ case 21: s = "\"type\" expected"; break;
+ case 22: s = "\"<\" expected"; break;
+ case 23: s = "\">\" expected"; break;
+ case 24: s = "\"method\" expected"; break;
+ case 25: s = "\"constructor\" expected"; break;
+ case 26: s = "\"returns\" expected"; break;
+ case 27: s = "\"...\" expected"; break;
+ case 28: s = "\"modifies\" expected"; break;
+ case 29: s = "\"free\" expected"; break;
+ case 30: s = "\"requires\" expected"; break;
+ case 31: s = "\"ensures\" expected"; break;
+ case 32: s = "\"decreases\" expected"; break;
+ case 33: s = "\"(\" expected"; break;
+ case 34: s = "\")\" expected"; break;
+ case 35: s = "\"bool\" expected"; break;
+ case 36: s = "\"nat\" expected"; break;
+ case 37: s = "\"int\" expected"; break;
+ case 38: s = "\"set\" expected"; break;
+ case 39: s = "\"multiset\" expected"; break;
+ case 40: s = "\"seq\" expected"; break;
+ case 41: s = "\"map\" expected"; break;
+ case 42: s = "\"object\" expected"; break;
+ case 43: s = "\".\" expected"; break;
case 44: s = "\"function\" expected"; break;
case 45: s = "\"predicate\" expected"; break;
case 46: s = "\"reads\" expected"; break;
@@ -2689,10 +2719,10 @@ public class Errors { case 51: s = "\"return\" expected"; break;
case 52: s = "\":=\" expected"; break;
case 53: s = "\":|\" expected"; break;
- case 54: s = "\"new\" expected"; break;
- case 55: s = "\"[\" expected"; break;
- case 56: s = "\"]\" expected"; break;
- case 57: s = "\".\" expected"; break;
+ case 54: s = "\"assume\" expected"; break;
+ case 55: s = "\"new\" expected"; break;
+ case 56: s = "\"[\" expected"; break;
+ case 57: s = "\"]\" expected"; break;
case 58: s = "\"choose\" expected"; break;
case 59: s = "\"if\" expected"; break;
case 60: s = "\"else\" expected"; break;
@@ -2702,122 +2732,121 @@ public class Errors { case 64: s = "\"invariant\" expected"; break;
case 65: s = "\"match\" expected"; break;
case 66: s = "\"assert\" expected"; break;
- case 67: s = "\"assume\" expected"; break;
- case 68: s = "\"print\" expected"; break;
- case 69: s = "\"parallel\" expected"; break;
- case 70: s = "\"<==>\" expected"; break;
- case 71: s = "\"\\u21d4\" expected"; break;
- case 72: s = "\"==>\" expected"; break;
- case 73: s = "\"\\u21d2\" expected"; break;
- case 74: s = "\"&&\" expected"; break;
- case 75: s = "\"\\u2227\" expected"; break;
- case 76: s = "\"||\" expected"; break;
- case 77: s = "\"\\u2228\" expected"; break;
- case 78: s = "\"==\" expected"; break;
- case 79: s = "\"<=\" expected"; break;
- case 80: s = "\">=\" expected"; break;
- case 81: s = "\"!=\" expected"; break;
- case 82: s = "\"!!\" expected"; break;
- case 83: s = "\"in\" expected"; break;
- case 84: s = "\"!\" expected"; break;
- case 85: s = "\"\\u2260\" expected"; break;
- case 86: s = "\"\\u2264\" expected"; break;
- case 87: s = "\"\\u2265\" expected"; break;
- case 88: s = "\"+\" expected"; break;
- case 89: s = "\"-\" expected"; break;
- case 90: s = "\"/\" expected"; break;
- case 91: s = "\"%\" expected"; break;
- case 92: s = "\"\\u00ac\" expected"; break;
- case 93: s = "\"false\" expected"; break;
- case 94: s = "\"true\" expected"; break;
- case 95: s = "\"null\" expected"; break;
- case 96: s = "\"this\" expected"; break;
- case 97: s = "\"fresh\" expected"; break;
- case 98: s = "\"allocated\" expected"; break;
- case 99: s = "\"old\" expected"; break;
- case 100: s = "\"then\" expected"; break;
- case 101: s = "\"..\" expected"; break;
- case 102: s = "\"forall\" expected"; break;
- case 103: s = "\"\\u2200\" expected"; break;
- case 104: s = "\"exists\" expected"; break;
- case 105: s = "\"\\u2203\" expected"; break;
- case 106: s = "\"::\" expected"; break;
- case 107: s = "\"\\u2022\" expected"; break;
- case 108: s = "??? expected"; break;
- case 109: s = "invalid Dafny"; break;
- case 110: s = "this symbol not expected in ClassDecl"; break;
- case 111: s = "this symbol not expected in DatatypeDecl"; break;
- case 112: s = "invalid DatatypeDecl"; break;
- case 113: s = "this symbol not expected in DatatypeDecl"; break;
- case 114: s = "this symbol not expected in ArbitraryTypeDecl"; break;
- case 115: s = "invalid ClassMemberDecl"; break;
+ case 67: s = "\"print\" expected"; break;
+ case 68: s = "\"parallel\" expected"; break;
+ case 69: s = "\"<==>\" expected"; break;
+ case 70: s = "\"\\u21d4\" expected"; break;
+ case 71: s = "\"==>\" expected"; break;
+ case 72: s = "\"\\u21d2\" expected"; break;
+ case 73: s = "\"&&\" expected"; break;
+ case 74: s = "\"\\u2227\" expected"; break;
+ case 75: s = "\"||\" expected"; break;
+ case 76: s = "\"\\u2228\" expected"; break;
+ case 77: s = "\"==\" expected"; break;
+ case 78: s = "\"<=\" expected"; break;
+ case 79: s = "\">=\" expected"; break;
+ case 80: s = "\"!=\" expected"; break;
+ case 81: s = "\"!!\" expected"; break;
+ case 82: s = "\"in\" expected"; break;
+ case 83: s = "\"!\" expected"; break;
+ case 84: s = "\"\\u2260\" expected"; break;
+ case 85: s = "\"\\u2264\" expected"; break;
+ case 86: s = "\"\\u2265\" expected"; break;
+ case 87: s = "\"+\" expected"; break;
+ case 88: s = "\"-\" expected"; break;
+ case 89: s = "\"/\" expected"; break;
+ case 90: s = "\"%\" expected"; break;
+ case 91: s = "\"\\u00ac\" expected"; break;
+ case 92: s = "\"false\" expected"; break;
+ case 93: s = "\"true\" expected"; break;
+ case 94: s = "\"null\" expected"; break;
+ case 95: s = "\"this\" expected"; break;
+ case 96: s = "\"fresh\" expected"; break;
+ case 97: s = "\"allocated\" expected"; break;
+ case 98: s = "\"old\" expected"; break;
+ case 99: s = "\"then\" expected"; break;
+ case 100: s = "\"..\" expected"; break;
+ case 101: s = "\"forall\" expected"; break;
+ case 102: s = "\"\\u2200\" expected"; break;
+ case 103: s = "\"exists\" expected"; break;
+ case 104: s = "\"\\u2203\" expected"; break;
+ case 105: s = "\"::\" expected"; break;
+ case 106: s = "\"\\u2022\" expected"; break;
+ case 107: s = "??? expected"; break;
+ case 108: s = "invalid Dafny"; break;
+ case 109: s = "this symbol not expected in ClassDecl"; break;
+ case 110: s = "this symbol not expected in DatatypeDecl"; break;
+ case 111: s = "invalid DatatypeDecl"; break;
+ case 112: s = "this symbol not expected in DatatypeDecl"; break;
+ case 113: s = "this symbol not expected in ArbitraryTypeDecl"; break;
+ case 114: s = "invalid ClassMemberDecl"; break;
+ case 115: s = "this symbol not expected in FieldDecl"; break;
case 116: s = "this symbol not expected in FieldDecl"; break;
- case 117: s = "this symbol not expected in FieldDecl"; break;
+ case 117: s = "invalid FunctionDecl"; break;
case 118: s = "invalid FunctionDecl"; break;
case 119: s = "invalid FunctionDecl"; break;
- case 120: s = "invalid FunctionDecl"; break;
- case 121: s = "this symbol not expected in MethodDecl"; break;
+ case 120: s = "this symbol not expected in MethodDecl"; break;
+ case 121: s = "invalid MethodDecl"; break;
case 122: s = "invalid MethodDecl"; break;
- case 123: s = "invalid MethodDecl"; break;
- case 124: s = "invalid TypeAndToken"; break;
+ case 123: s = "invalid TypeAndToken"; break;
+ case 124: s = "this symbol not expected in MethodSpec"; break;
case 125: s = "this symbol not expected in MethodSpec"; break;
case 126: s = "this symbol not expected in MethodSpec"; break;
case 127: s = "this symbol not expected in MethodSpec"; break;
- case 128: s = "this symbol not expected in MethodSpec"; break;
- case 129: s = "invalid MethodSpec"; break;
- case 130: s = "this symbol not expected in MethodSpec"; break;
- case 131: s = "invalid MethodSpec"; break;
- case 132: s = "invalid ReferenceType"; break;
+ case 128: s = "invalid MethodSpec"; break;
+ case 129: s = "this symbol not expected in MethodSpec"; break;
+ case 130: s = "invalid MethodSpec"; break;
+ case 131: s = "invalid ReferenceType"; break;
+ case 132: s = "this symbol not expected in FunctionSpec"; break;
case 133: s = "this symbol not expected in FunctionSpec"; break;
case 134: s = "this symbol not expected in FunctionSpec"; break;
case 135: s = "this symbol not expected in FunctionSpec"; break;
case 136: s = "this symbol not expected in FunctionSpec"; break;
- case 137: s = "this symbol not expected in FunctionSpec"; break;
- case 138: s = "invalid FunctionSpec"; break;
- case 139: s = "invalid PossiblyWildFrameExpression"; break;
- case 140: s = "invalid PossiblyWildExpression"; break;
- case 141: s = "this symbol not expected in OneStmt"; break;
- case 142: s = "invalid OneStmt"; break;
- case 143: s = "this symbol not expected in OneStmt"; break;
- case 144: s = "invalid OneStmt"; break;
- case 145: s = "invalid AssertStmt"; break;
+ case 137: s = "invalid FunctionSpec"; break;
+ case 138: s = "invalid PossiblyWildFrameExpression"; break;
+ case 139: s = "invalid PossiblyWildExpression"; break;
+ case 140: s = "this symbol not expected in OneStmt"; break;
+ case 141: s = "invalid OneStmt"; break;
+ case 142: s = "this symbol not expected in OneStmt"; break;
+ case 143: s = "invalid OneStmt"; break;
+ case 144: s = "invalid AssertStmt"; break;
+ case 145: s = "invalid UpdateStmt"; break;
case 146: s = "invalid UpdateStmt"; break;
- case 147: s = "invalid UpdateStmt"; break;
+ case 147: s = "invalid IfStmt"; break;
case 148: s = "invalid IfStmt"; break;
- case 149: s = "invalid IfStmt"; break;
+ case 149: s = "invalid WhileStmt"; break;
case 150: s = "invalid WhileStmt"; break;
- case 151: s = "invalid WhileStmt"; break;
- case 152: s = "invalid Rhs"; break;
- case 153: s = "invalid Lhs"; break;
- case 154: s = "invalid Guard"; break;
+ case 151: s = "invalid Rhs"; break;
+ case 152: s = "invalid Lhs"; break;
+ case 153: s = "invalid Guard"; break;
+ case 154: s = "this symbol not expected in LoopSpec"; break;
case 155: s = "this symbol not expected in LoopSpec"; break;
case 156: s = "this symbol not expected in LoopSpec"; break;
case 157: s = "this symbol not expected in LoopSpec"; break;
case 158: s = "this symbol not expected in LoopSpec"; break;
- case 159: s = "this symbol not expected in LoopSpec"; break;
- case 160: s = "this symbol not expected in Invariant"; break;
- case 161: s = "invalid AttributeArg"; break;
- case 162: s = "invalid EquivOp"; break;
- case 163: s = "invalid ImpliesOp"; break;
- case 164: s = "invalid AndOp"; break;
- case 165: s = "invalid OrOp"; break;
- case 166: s = "invalid RelOp"; break;
- case 167: s = "invalid AddOp"; break;
- case 168: s = "invalid UnaryExpression"; break;
- case 169: s = "invalid MulOp"; break;
- case 170: s = "invalid NegOp"; break;
- case 171: s = "invalid EndlessExpression"; break;
+ case 159: s = "this symbol not expected in Invariant"; break;
+ case 160: s = "invalid AttributeArg"; break;
+ case 161: s = "invalid EquivOp"; break;
+ case 162: s = "invalid ImpliesOp"; break;
+ case 163: s = "invalid AndOp"; break;
+ case 164: s = "invalid OrOp"; break;
+ case 165: s = "invalid RelOp"; break;
+ case 166: s = "invalid AddOp"; break;
+ case 167: s = "invalid UnaryExpression"; break;
+ case 168: s = "invalid MulOp"; break;
+ case 169: s = "invalid NegOp"; break;
+ case 170: s = "invalid EndlessExpression"; break;
+ case 171: s = "invalid Suffix"; break;
case 172: s = "invalid Suffix"; break;
case 173: s = "invalid Suffix"; break;
- case 174: s = "invalid Suffix"; break;
- case 175: s = "invalid DisplayExpr"; break;
- case 176: s = "invalid MultiSetExpr"; break;
- case 177: s = "invalid MapExpr"; break;
- case 178: s = "invalid ConstAtomExpression"; break;
- case 179: s = "invalid QSep"; break;
- case 180: s = "invalid QuantifierGuts"; break;
- case 181: s = "invalid Forall"; break;
- case 182: s = "invalid Exists"; break;
+ case 174: s = "invalid DisplayExpr"; break;
+ case 175: s = "invalid MultiSetExpr"; break;
+ case 176: s = "invalid MapExpr"; break;
+ case 177: s = "invalid ConstAtomExpression"; break;
+ case 178: s = "invalid QSep"; break;
+ case 179: s = "invalid QuantifierGuts"; break;
+ case 180: s = "invalid Forall"; break;
+ case 181: s = "invalid Exists"; break;
default: s = "error " + n; break;
}
diff --git a/Source/Dafny/Printer.cs b/Source/Dafny/Printer.cs index 6cf71fa1..fb46ba4b 100644 --- a/Source/Dafny/Printer.cs +++ b/Source/Dafny/Printer.cs @@ -222,7 +222,6 @@ namespace Microsoft.Dafny { var isPredicate = f is Predicate;
Indent(indent);
string k = isPredicate ? "predicate" : "function";
- if (f.IsUnlimited) { k = "unlimited " + k; }
if (f.IsStatic) { k = "static " + k; }
if (!f.IsGhost) { k += " method"; }
PrintClassMethodHelper(k, f.Attributes, f.Name, f.TypeArgs);
@@ -421,9 +420,9 @@ namespace Microsoft.Dafny { /// </summary>
public void PrintStatement(Statement stmt, int indent) {
Contract.Requires(stmt != null);
- for (LabelNode label = stmt.Labels; label != null; label = label.Next) {
- if (label.Label != null) {
- wr.WriteLine("label {0}:", label.Label);
+ 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);
}
}
@@ -662,7 +661,10 @@ namespace Microsoft.Dafny { } else if (s is AssignSuchThatStmt) {
var update = (AssignSuchThatStmt)s;
wr.Write(" :| ");
- PrintExpression(update.Assume.Expr);
+ if (update.AssumeToken != null) {
+ wr.Write("assume ");
+ }
+ PrintExpression(update.Expr);
} else {
Contract.Assert(s == null); // otherwise, unknown type
}
diff --git a/Source/Dafny/RefinementTransformer.cs b/Source/Dafny/RefinementTransformer.cs index d966a76f..51b22443 100644 --- a/Source/Dafny/RefinementTransformer.cs +++ b/Source/Dafny/RefinementTransformer.cs @@ -186,19 +186,19 @@ namespace Microsoft.Dafny { return t;
} else if (t is SetType) {
var tt = (SetType)t;
- return new SetType(tt.Arg);
+ return new SetType(CloneType(tt.Arg));
} else if (t is SeqType) {
var tt = (SeqType)t;
- return new SeqType(tt.Arg);
+ return new SeqType(CloneType(tt.Arg));
} else if (t is MultiSetType) {
var tt = (MultiSetType)t;
- return new MultiSetType(tt.Arg);
+ return new MultiSetType(CloneType(tt.Arg));
} else if (t is MapType) {
var tt = (MapType)t;
- return new MapType(tt.Domain, tt.Range);
+ 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));
+ return new UserDefinedType(Tok(tt.tok), tt.Name, tt.TypeArgs.ConvertAll(CloneType), tt.ModuleName == null ? null : Tok(tt.ModuleName));
} else if (t is InferredTypeProxy) {
return new InferredTypeProxy();
} else {
@@ -493,7 +493,7 @@ namespace Microsoft.Dafny { } else if (stmt is AssignSuchThatStmt) {
var s = (AssignSuchThatStmt)stmt;
- r = new AssignSuchThatStmt(Tok(s.Tok), s.Lhss.ConvertAll(CloneExpr), CloneExpr(s.Assume.Expr));
+ 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;
@@ -513,13 +513,13 @@ namespace Microsoft.Dafny { return r;
}
- void AddStmtLabels(Statement s, LabelNode node) {
+ void AddStmtLabels(Statement s, LList<Label> node) {
if (node != null) {
AddStmtLabels(s, node.Next);
- if (node.Label == null) {
+ if (node.Data.Name == null) {
// this indicates an implicit-target break statement that has been resolved; don't add it
} else {
- s.Labels = new LabelNode(Tok(node.Tok), node.Label, s.Labels);
+ s.Labels = new LList<Label>(new Label(Tok(node.Data.Tok), node.Data.Name), s.Labels);
}
}
}
@@ -560,10 +560,10 @@ namespace Microsoft.Dafny { }
if (f is Predicate) {
- return new Predicate(tok, f.Name, f.IsStatic, isGhost, f.IsUnlimited, tps, f.OpenParen, formals,
+ return new Predicate(tok, f.Name, f.IsStatic, isGhost, tps, f.OpenParen, formals,
req, reads, ens, decreases, body, moreBody != null, null, false);
} else {
- return new Function(tok, f.Name, f.IsStatic, isGhost, f.IsUnlimited, tps, f.OpenParen, formals, CloneType(f.ResultType),
+ return new Function(tok, f.Name, f.IsStatic, isGhost, tps, f.OpenParen, formals, CloneType(f.ResultType),
req, reads, ens, decreases, body, null, false);
}
}
@@ -638,9 +638,6 @@ namespace Microsoft.Dafny { 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.IsUnlimited != f.IsUnlimited) {
- reporter.Error(f, "a function in a refining module cannot be changed from unlimited to limited 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) {
@@ -917,7 +914,7 @@ namespace Microsoft.Dafny { doMerge = true;
} else if (cOld.Update is AssignSuchThatStmt) {
doMerge = true;
- addedAssert = CloneExpr(((AssignSuchThatStmt)cOld.Update).Assume.Expr);
+ addedAssert = CloneExpr(((AssignSuchThatStmt)cOld.Update).Expr);
} else {
var updateOld = (UpdateStmt)cOld.Update; // if cast fails, there are more ConcreteUpdateStatement subclasses than expected
if (updateOld.Rhss.Count == 1 && updateOld.Rhss[0] is HavocRhs) {
@@ -1090,8 +1087,8 @@ namespace Microsoft.Dafny { Contract.Requires(labels != null);
Contract.Requires(0 <= loopLevels);
- for (LabelNode n = s.Labels; n != null; n = n.Next) {
- labels.Push(n.Label);
+ for (LList<Label> n = s.Labels; n != null; n = n.Next) {
+ labels.Push(n.Data.Name);
}
if (s is SkeletonStatement) {
@@ -1116,7 +1113,7 @@ namespace Microsoft.Dafny { }
}
- for (LabelNode n = s.Labels; n != null; n = n.Next) {
+ for (LList<Label> n = s.Labels; n != null; n = n.Next) {
labels.Pop();
}
}
diff --git a/Source/Dafny/Resolver.cs b/Source/Dafny/Resolver.cs index 7be3fca2..f0990aa0 100644 --- a/Source/Dafny/Resolver.cs +++ b/Source/Dafny/Resolver.cs @@ -322,7 +322,7 @@ namespace Microsoft.Dafny { // create and add the query "method" (field, really)
string queryName = ctor.Name + "?";
- var query = new SpecialField(ctor.tok, queryName, "_" + ctor.Name, "", "", false, false, Type.Bool, null);
+ var query = new SpecialField(ctor.tok, queryName, "is_" + ctor.CompileName, "", "", false, false, Type.Bool, null);
query.EnclosingClass = dt; // resolve here
members.Add(queryName, query);
ctor.QueryField = query;
@@ -937,7 +937,7 @@ namespace Microsoft.Dafny { Error(t.tok, "sorry, cannot instantiate type parameter with a subrange type");
}
}
- TypeParameter tp = allTypeParameters.Find(t.Name);
+ TypeParameter tp = t.ModuleName == null ? allTypeParameters.Find(t.Name) : null;
if (tp != null) {
if (t.TypeArgs.Count == 0) {
t.ResolvedParam = tp;
@@ -945,11 +945,32 @@ namespace Microsoft.Dafny { 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;
- if (!classes.TryGetValue(t.Name, out d)) {
+ TopLevelDecl d = null;
+ if (t.ModuleName != null) {
+ foreach (var imp in currentClass.Module.Imports) {
+ if (imp.Name == t.ModuleName.val) {
+ // now search among the types declared in module "imp"
+ foreach (var tld in imp.TopLevelDecls) { // this search is slow, but oh well
+ if (tld.Name == t.Name) {
+ // found the class
+ d = tld;
+ goto DONE_WITH_QUALIFIED_NAME;
+ }
+ }
+ Error(t.tok, "Undeclared class name {0} in module {1}", t.Name, t.ModuleName.val);
+ goto DONE_WITH_QUALIFIED_NAME;
+ }
+ }
+ Error(t.ModuleName, "Undeclared module name: {0} (did you forget a module import?)", t.ModuleName.val);
+ DONE_WITH_QUALIFIED_NAME: ;
+ } else if (!classes.TryGetValue(t.Name, out d)) {
Error(t.tok, "Undeclared top-level type or type parameter: {0} (did you forget a module import?)", t.Name);
+ }
+
+ 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}", t.Name, ((AmbiguousTopLevelDecl)d).ModuleNames());
+ 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 {
@@ -973,7 +994,7 @@ namespace Microsoft.Dafny { 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>());
+ var typeArg = new UserDefinedType(t.tok, defaultTypeArguments[i].Name, new List<Type>(), null);
typeArg.ResolvedParam = defaultTypeArguments[i]; // resolve "typeArg" here
t.TypeArgs.Add(typeArg);
}
@@ -1355,7 +1376,7 @@ namespace Microsoft.Dafny { 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 LabelNode(target.Tok, null, null);
+ target.Labels = new LList<Label>(new Label(target.Tok, null), null);
}
s.TargetStmt = target;
if (specContextOnly && !target.IsGhost && !inSpecOnlyContext[target]) {
@@ -1818,13 +1839,15 @@ namespace Microsoft.Dafny { Contract.Assert(false); throw new cce.UnreachableException();
}
}
-
private void ResolveUpdateStmt(ConcreteUpdateStatement s, bool specContextOnly, Method method)
{
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);
@@ -1834,14 +1857,34 @@ namespace Microsoft.Dafny { } 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;
- var update = s as UpdateStmt;
// Resolve RHSs
if (update == null) {
var suchThat = (AssignSuchThatStmt)s; // this is the other possible subclass
- s.ResolvedStatements.Add(suchThat.Assume);
+ 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;
@@ -1877,13 +1920,14 @@ namespace Microsoft.Dafny { var ie = lhs.Resolved as IdentifierExpr;
if (ie != null) {
if (lhsNameSet.ContainsKey(ie.Name)) {
- Error(s, "Duplicate variable in left-hand side of {1} statement: {0}", ie.Name, callRhs != null ? "call" : "assignment");
+ 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) {
@@ -2158,17 +2202,18 @@ namespace Microsoft.Dafny { foreach (Statement ss in blockStmt.Body) {
labeledStatements.PushMarker();
// push labels
- for (var lnode = ss.Labels; lnode != null; lnode = lnode.Next) {
- Contract.Assert(lnode.Label != 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.Label);
+ 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.Label, ss);
+ bool b = labeledStatements.Push(lnode.Name, ss);
Contract.Assert(b); // since we just checked for duplicates, we expect the Push to succeed
- if (lnode == ss.Labels) { // add it only once
+ if (l == ss.Labels) { // add it only once
inSpecOnlyContext.Add(ss, specContextOnly);
}
}
@@ -2338,7 +2383,7 @@ namespace Microsoft.Dafny { }
if (!callsConstructor && rr.EType is UserDefinedType) {
var udt = (UserDefinedType)rr.EType;
- var cl = (ClassDecl)udt.ResolvedClass; // cast is guarantted by the call to rr.EType.IsRefType above, together with the "rr.EType is UserDefinedType" test
+ 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);
}
@@ -2594,7 +2639,7 @@ namespace Microsoft.Dafny { dtv.InferredTypeArgs.Add(t);
subst.Add(dt.TypeArgs[i], t);
}
- expr.Type = new UserDefinedType(dtv.tok, dtv.DatatypeName, gt);
+ expr.Type = new UserDefinedType(dtv.tok, dtv.DatatypeName, gt, null);
ResolveType(expr.tok, expr.Type, null, true);
DatatypeCtor ctor;
@@ -2855,8 +2900,10 @@ namespace Microsoft.Dafny { case BinaryExpr.Opcode.Eq:
case BinaryExpr.Opcode.Neq:
- 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 (!CouldPossiblyBeSameType(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;
@@ -3248,6 +3295,35 @@ namespace Microsoft.Dafny { }
}
+ 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.
diff --git a/Source/Dafny/Scanner.cs b/Source/Dafny/Scanner.cs index 0c91c68c..d35fc22f 100644 --- a/Source/Dafny/Scanner.cs +++ b/Source/Dafny/Scanner.cs @@ -211,8 +211,8 @@ public class UTF8Buffer: Buffer { public class Scanner {
const char EOL = '\n';
const int eofSym = 0; /* pdt */
- const int maxT = 108;
- const int noSym = 108;
+ const int maxT = 107;
+ const int noSym = 107;
[ContractInvariantMethod]
@@ -494,34 +494,34 @@ public class Scanner { case "imports": t.kind = 11; break;
case "class": t.kind = 12; break;
case "static": t.kind = 13; break;
- case "unlimited": t.kind = 14; break;
- case "datatype": t.kind = 15; break;
- case "codatatype": t.kind = 16; break;
- case "var": t.kind = 20; break;
- case "type": t.kind = 22; break;
- case "method": t.kind = 25; break;
- case "constructor": t.kind = 26; break;
- case "returns": t.kind = 27; break;
- case "modifies": t.kind = 29; break;
- case "free": t.kind = 30; break;
- case "requires": t.kind = 31; break;
- case "ensures": t.kind = 32; break;
- case "decreases": t.kind = 33; break;
- case "bool": t.kind = 36; break;
- case "nat": t.kind = 37; break;
- case "int": t.kind = 38; break;
- case "set": t.kind = 39; break;
- case "multiset": t.kind = 40; break;
- case "seq": t.kind = 41; break;
- case "map": t.kind = 42; break;
- case "object": t.kind = 43; break;
+ case "datatype": t.kind = 14; break;
+ case "codatatype": t.kind = 15; break;
+ case "var": t.kind = 19; break;
+ case "type": t.kind = 21; break;
+ case "method": t.kind = 24; break;
+ case "constructor": t.kind = 25; break;
+ case "returns": t.kind = 26; break;
+ case "modifies": t.kind = 28; break;
+ case "free": t.kind = 29; break;
+ case "requires": t.kind = 30; break;
+ case "ensures": t.kind = 31; break;
+ case "decreases": t.kind = 32; break;
+ case "bool": t.kind = 35; break;
+ case "nat": t.kind = 36; break;
+ case "int": t.kind = 37; break;
+ case "set": t.kind = 38; break;
+ case "multiset": t.kind = 39; break;
+ case "seq": t.kind = 40; break;
+ case "map": t.kind = 41; break;
+ case "object": t.kind = 42; break;
case "function": t.kind = 44; break;
case "predicate": t.kind = 45; break;
case "reads": t.kind = 46; break;
case "label": t.kind = 49; break;
case "break": t.kind = 50; break;
case "return": t.kind = 51; break;
- case "new": t.kind = 54; break;
+ case "assume": t.kind = 54; break;
+ case "new": t.kind = 55; break;
case "choose": t.kind = 58; break;
case "if": t.kind = 59; break;
case "else": t.kind = 60; break;
@@ -530,20 +530,19 @@ public class Scanner { case "invariant": t.kind = 64; break;
case "match": t.kind = 65; break;
case "assert": t.kind = 66; break;
- case "assume": t.kind = 67; break;
- case "print": t.kind = 68; break;
- case "parallel": t.kind = 69; break;
- case "in": t.kind = 83; break;
- case "false": t.kind = 93; break;
- case "true": t.kind = 94; break;
- case "null": t.kind = 95; break;
- case "this": t.kind = 96; break;
- case "fresh": t.kind = 97; break;
- case "allocated": t.kind = 98; break;
- case "old": t.kind = 99; break;
- case "then": t.kind = 100; break;
- case "forall": t.kind = 102; break;
- case "exists": t.kind = 104; break;
+ case "print": t.kind = 67; break;
+ case "parallel": t.kind = 68; break;
+ case "in": t.kind = 82; break;
+ case "false": t.kind = 92; break;
+ case "true": t.kind = 93; break;
+ case "null": t.kind = 94; break;
+ case "this": t.kind = 95; break;
+ case "fresh": t.kind = 96; break;
+ case "allocated": t.kind = 97; break;
+ case "old": t.kind = 98; break;
+ case "then": t.kind = 99; break;
+ case "forall": t.kind = 101; break;
+ case "exists": t.kind = 103; break;
default: break;
}
}
@@ -649,15 +648,15 @@ public class Scanner { else if (ch >= '0' && ch <= '9') {AddCh(); goto case 18;}
else {t.kind = 3; break;}
case 19:
- {t.kind = 19; break;}
+ {t.kind = 18; break;}
case 20:
- {t.kind = 21; break;}
+ {t.kind = 20; break;}
case 21:
- {t.kind = 28; break;}
+ {t.kind = 27; break;}
case 22:
- {t.kind = 34; break;}
+ {t.kind = 33; break;}
case 23:
- {t.kind = 35; break;}
+ {t.kind = 34; break;}
case 24:
{t.kind = 47; break;}
case 25:
@@ -667,63 +666,63 @@ public class Scanner { case 27:
{t.kind = 53; break;}
case 28:
- {t.kind = 55; break;}
- case 29:
{t.kind = 56; break;}
+ case 29:
+ {t.kind = 57; break;}
case 30:
{t.kind = 62; break;}
case 31:
if (ch == '>') {AddCh(); goto case 32;}
else {goto case 0;}
case 32:
- {t.kind = 70; break;}
+ {t.kind = 69; break;}
case 33:
- {t.kind = 71; break;}
+ {t.kind = 70; break;}
case 34:
- {t.kind = 72; break;}
+ {t.kind = 71; break;}
case 35:
- {t.kind = 73; break;}
+ {t.kind = 72; break;}
case 36:
if (ch == '&') {AddCh(); goto case 37;}
else {goto case 0;}
case 37:
- {t.kind = 74; break;}
+ {t.kind = 73; break;}
case 38:
- {t.kind = 75; break;}
+ {t.kind = 74; break;}
case 39:
- {t.kind = 76; break;}
+ {t.kind = 75; break;}
case 40:
- {t.kind = 77; break;}
+ {t.kind = 76; break;}
case 41:
- {t.kind = 80; break;}
+ {t.kind = 79; break;}
case 42:
- {t.kind = 81; break;}
+ {t.kind = 80; break;}
case 43:
- {t.kind = 82; break;}
+ {t.kind = 81; break;}
case 44:
- {t.kind = 85; break;}
+ {t.kind = 84; break;}
case 45:
- {t.kind = 86; break;}
+ {t.kind = 85; break;}
case 46:
- {t.kind = 87; break;}
+ {t.kind = 86; break;}
case 47:
- {t.kind = 88; break;}
+ {t.kind = 87; break;}
case 48:
- {t.kind = 89; break;}
+ {t.kind = 88; break;}
case 49:
- {t.kind = 90; break;}
+ {t.kind = 89; break;}
case 50:
- {t.kind = 91; break;}
+ {t.kind = 90; break;}
case 51:
- {t.kind = 92; break;}
+ {t.kind = 91; break;}
case 52:
- {t.kind = 103; break;}
+ {t.kind = 102; break;}
case 53:
- {t.kind = 105; break;}
+ {t.kind = 104; break;}
case 54:
- {t.kind = 106; break;}
+ {t.kind = 105; break;}
case 55:
- {t.kind = 107; break;}
+ {t.kind = 106; break;}
case 56:
recEnd = pos; recKind = 5;
if (ch == '=') {AddCh(); goto case 26;}
@@ -731,43 +730,43 @@ public class Scanner { else if (ch == ':') {AddCh(); goto case 54;}
else {t.kind = 5; break;}
case 57:
- recEnd = pos; recKind = 17;
+ recEnd = pos; recKind = 16;
if (ch == '>') {AddCh(); goto case 30;}
else if (ch == '=') {AddCh(); goto case 63;}
- else {t.kind = 17; break;}
+ else {t.kind = 16; break;}
case 58:
- recEnd = pos; recKind = 18;
+ recEnd = pos; recKind = 17;
if (ch == '|') {AddCh(); goto case 39;}
- else {t.kind = 18; break;}
+ else {t.kind = 17; break;}
case 59:
- recEnd = pos; recKind = 23;
+ recEnd = pos; recKind = 22;
if (ch == '=') {AddCh(); goto case 64;}
- else {t.kind = 23; break;}
+ else {t.kind = 22; break;}
case 60:
- recEnd = pos; recKind = 24;
+ recEnd = pos; recKind = 23;
if (ch == '=') {AddCh(); goto case 41;}
- else {t.kind = 24; break;}
+ else {t.kind = 23; break;}
case 61:
- recEnd = pos; recKind = 57;
+ recEnd = pos; recKind = 43;
if (ch == '.') {AddCh(); goto case 65;}
- else {t.kind = 57; break;}
+ else {t.kind = 43; break;}
case 62:
- recEnd = pos; recKind = 84;
+ recEnd = pos; recKind = 83;
if (ch == '=') {AddCh(); goto case 42;}
else if (ch == '!') {AddCh(); goto case 43;}
- else {t.kind = 84; break;}
+ else {t.kind = 83; break;}
case 63:
- recEnd = pos; recKind = 78;
+ recEnd = pos; recKind = 77;
if (ch == '>') {AddCh(); goto case 34;}
- else {t.kind = 78; break;}
+ else {t.kind = 77; break;}
case 64:
- recEnd = pos; recKind = 79;
+ recEnd = pos; recKind = 78;
if (ch == '=') {AddCh(); goto case 31;}
- else {t.kind = 79; break;}
+ else {t.kind = 78; break;}
case 65:
- recEnd = pos; recKind = 101;
+ recEnd = pos; recKind = 100;
if (ch == '.') {AddCh(); goto case 21;}
- else {t.kind = 101; break;}
+ else {t.kind = 100; break;}
}
t.val = new String(tval, 0, tlen);
diff --git a/Source/Dafny/Translator.cs b/Source/Dafny/Translator.cs index 0189c11b..c05d9a38 100644 --- a/Source/Dafny/Translator.cs +++ b/Source/Dafny/Translator.cs @@ -574,7 +574,7 @@ namespace Microsoft.Dafny { } else if (member is Function) {
Function f = (Function)member;
AddFunction(f);
- if (f.IsRecursive && !f.IsUnlimited) {
+ if (f.IsRecursive) {
AddLimitedAxioms(f, 2);
AddLimitedAxioms(f, 1);
}
@@ -586,7 +586,7 @@ namespace Microsoft.Dafny { } else {
AddFunctionAxiom(f, body, f.Ens, null, layerOffset);
}
- if (!f.IsRecursive || f.IsUnlimited) { break; }
+ if (!f.IsRecursive) { break; }
}
AddFrameAxiom(f);
AddWellformednessCheck(f);
@@ -666,7 +666,7 @@ namespace Microsoft.Dafny { // 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*/);
+ 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);
@@ -716,7 +716,7 @@ namespace Microsoft.Dafny { 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 && !f.IsUnlimited));
+ Contract.Requires(layerOffset == 0 || (layerOffset == 1 && f.IsRecursive));
Contract.Requires(predef != null);
Contract.Requires(f.EnclosingClass != null);
@@ -895,7 +895,7 @@ namespace Microsoft.Dafny { void AddLimitedAxioms(Function f, int fromLayer) {
Contract.Requires(f != null);
- Contract.Requires(f.IsRecursive && !f.IsUnlimited);
+ Contract.Requires(f.IsRecursive);
Contract.Requires(fromLayer == 1 || fromLayer == 2);
Contract.Requires(sink != null && predef != null);
// With fromLayer==1, generate:
@@ -1380,7 +1380,7 @@ namespace Microsoft.Dafny { /// F(h0,formals) == F(h1,formals)
/// );
///
- /// If the function is a recursive, non-unlimited function, then the same axiom is also produced for "F#limited" instead of "F".
+ /// 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)
{
@@ -1459,7 +1459,7 @@ namespace Microsoft.Dafny { 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 && !f.IsUnlimited) {
+ 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 {
@@ -2933,7 +2933,7 @@ namespace Microsoft.Dafny { Bpl.Function func = new Bpl.Function(f.tok, f.FullName, typeParams, args, res);
sink.TopLevelDeclarations.Add(func);
- if (f.IsRecursive && !f.IsUnlimited) {
+ 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));
}
@@ -3403,7 +3403,7 @@ namespace Microsoft.Dafny { } 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.UniqueId)));
+ 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");
@@ -3414,7 +3414,11 @@ namespace Microsoft.Dafny { } else if (stmt is AssignSuchThatStmt) {
var s = (AssignSuchThatStmt)stmt;
AddComment(builder, s, "assign-such-that statement");
- // treat like a parallel havoc, followed by an assume
+ // 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>();
@@ -3424,10 +3428,40 @@ namespace Microsoft.Dafny { }
List<AssignToLhs> lhsBuilder;
List<Bpl.IdentifierExpr> bLhss;
- ProcessLhss(lhss, false, builder, locals, etran, out lhsBuilder, out 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
+ }
+ }
+ var bvs = new VariableSeq();
+ var typeAntecedent = etran.TrBoundVariables(bvars, bvs);
+ var substE = etran.TrExpr(Substitute(s.Expr, null, substMap));
+ var ex = new Bpl.ExistsExpr(s.Tok, bvs, BplAnd(typeAntecedent, substE));
+ builder.Add(Assert(s.Tok, ex, "cannot establish the existence of LHS values that satisfy the such-that predicate"));
+ }
// End by doing the assume
- TrStmt(s.Assume, builder, locals, etran);
+ 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) {
@@ -3443,11 +3477,28 @@ namespace Microsoft.Dafny { foreach (var lhs in s.Lhss) {
lhss.Add(lhs.Resolved);
}
- bool rhssCanAffectPreviouslyKnownExpressions = s.Rhss.Exists(rhs => rhs.CanAffectPreviouslyKnownExpressions);
List<AssignToLhs> lhsBuilder;
List<Bpl.IdentifierExpr> bLhss;
- ProcessLhss(lhss, rhssCanAffectPreviouslyKnownExpressions, builder, locals, etran, out lhsBuilder, out bLhss);
- ProcessRhss(lhsBuilder, bLhss, lhss, s.Rhss, builder, locals, etran);
+ // 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));
}
@@ -3471,7 +3522,7 @@ namespace Microsoft.Dafny { foreach (Statement ss in ((BlockStmt)stmt).Body) {
TrStmt(ss, builder, locals, etran);
if (ss.Labels != null) {
- builder.AddLabelCmd("after_" + ss.Labels.UniqueId);
+ builder.AddLabelCmd("after_" + ss.Labels.Data.UniqueId);
}
}
} else if (stmt is IfStmt) {
@@ -4235,7 +4286,9 @@ namespace Microsoft.Dafny { void TrCallStmt(CallStmt s, Bpl.StmtListBuilder builder, Bpl.VariableSeq locals, ExpressionTranslator etran, Bpl.Expr actualReceiver) {
List<AssignToLhs> lhsBuilders;
List<Bpl.IdentifierExpr> bLhss;
- ProcessLhss(s.Lhs, true, builder, locals, etran, out lhsBuilders, out 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>();
@@ -4869,8 +4922,10 @@ namespace Microsoft.Dafny { List<AssignToLhs> lhsBuilder;
List<Bpl.IdentifierExpr> bLhss;
var lhss = new List<Expression>() { lhs };
- ProcessLhss(lhss, rhs.CanAffectPreviouslyKnownExpressions, builder, locals, etran,
- out lhsBuilder, out bLhss);
+ 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 };
@@ -4919,16 +4974,104 @@ namespace Microsoft.Dafny { }
}
+ 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, denote different locations,
+ /// 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,
+ 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 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);
@@ -4943,17 +5086,31 @@ namespace Microsoft.Dafny { // for each Dafny LHS, build a protected Boogie LHS for the eventual assignment
lhsBuilders = new List<AssignToLhs>();
bLhss = new List<Bpl.IdentifierExpr>();
- var prevObj = new Bpl.Expr[lhss.Count];
- var prevIndex = new Bpl.Expr[lhss.Count];
+ 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?
- // Note, the resolver checks for duplicate IdentifierExpr's in LHSs
bLhss.Add(rhsCanAffectPreviouslyKnownExpressions ? null : bLhs);
lhsBuilders.Add(delegate(Bpl.Expr rhs, Bpl.StmtListBuilder bldr, ExpressionTranslator et) {
builder.Add(Bpl.Cmd.SimpleAssign(tok, bLhs, rhs));
@@ -4968,11 +5125,13 @@ namespace Microsoft.Dafny { // 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"));
- // 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)));
+ 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)));
+ }
}
}
@@ -4999,16 +5158,17 @@ namespace Microsoft.Dafny { // 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"));
- // 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)));
+ 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?
@@ -5030,16 +5190,17 @@ namespace Microsoft.Dafny { 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"));
- // 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)));
+ 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?
@@ -5097,7 +5258,10 @@ namespace Microsoft.Dafny { } 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;
@@ -5535,12 +5699,12 @@ namespace Microsoft.Dafny { } else if (expr is FunctionCallExpr) {
FunctionCallExpr e = (FunctionCallExpr)expr;
- int offsetToUse = e.Function.IsRecursive && !e.Function.IsUnlimited ? this.layerOffset : 0;
- if (e.Function.IsRecursive && !e.Function.IsUnlimited) {
+ 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 && !e.Function.IsUnlimited) {
+ if (this.applyLimited_CurrentFunction != null && e.Function.IsRecursive) {
ModuleDecl 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)) {
diff --git a/Source/GPUVerify/ArrayControlFlowAnalyser.cs b/Source/GPUVerify/ArrayControlFlowAnalyser.cs index 20036abe..f1ce9f1e 100644 --- a/Source/GPUVerify/ArrayControlFlowAnalyser.cs +++ b/Source/GPUVerify/ArrayControlFlowAnalyser.cs @@ -99,7 +99,11 @@ namespace GPUVerify private void Analyse(Implementation Impl)
{
- Analyse(Impl, Impl.StructuredStmts);
+ if (CommandLineOptions.Unstructured)
+ foreach (var b in Impl.Blocks)
+ Analyse(Impl, b.Cmds);
+ else
+ Analyse(Impl, Impl.StructuredStmts);
}
private void Analyse(Implementation impl, StmtList stmtList)
@@ -110,9 +114,29 @@ namespace GPUVerify }
}
- private void Analyse(Implementation impl, BigBlock bb)
+ private void ExprMayAffectControlFlow(Implementation impl, Expr e)
{
- foreach (Cmd c in bb.simpleCmds)
+ var visitor = new VariablesOccurringInExpressionVisitor();
+ visitor.VisitExpr(e);
+ foreach (Variable v in visitor.GetVariables())
+ {
+ if (!mayBeDerivedFrom[impl.Name].ContainsKey(v.Name))
+ {
+ continue;
+ }
+ foreach (string s in mayBeDerivedFrom[impl.Name][v.Name])
+ {
+ if (!arraysWhichMayAffectControlFlow.Contains(s))
+ {
+ SetArrayMayAffectControlFlow(s);
+ }
+ }
+ }
+ }
+
+ private void Analyse(Implementation impl, CmdSeq cs)
+ {
+ foreach (var c in cs)
{
if (c is AssignCmd)
{
@@ -189,28 +213,23 @@ namespace GPUVerify }
}
+ else if (c is AssumeCmd)
+ {
+ var assumeCmd = c as AssumeCmd;
+ ExprMayAffectControlFlow(impl, assumeCmd.Expr);
+ }
}
+ }
+
+ private void Analyse(Implementation impl, BigBlock bb)
+ {
+ Analyse(impl, bb.simpleCmds);
if (bb.ec is WhileCmd)
{
WhileCmd wc = bb.ec as WhileCmd;
- VariablesOccurringInExpressionVisitor visitor = new VariablesOccurringInExpressionVisitor();
- visitor.VisitExpr(wc.Guard);
- foreach (Variable v in visitor.GetVariables())
- {
- if (!mayBeDerivedFrom[impl.Name].ContainsKey(v.Name))
- {
- continue;
- }
- foreach (string s in mayBeDerivedFrom[impl.Name][v.Name])
- {
- if (!arraysWhichMayAffectControlFlow.Contains(s))
- {
- SetArrayMayAffectControlFlow(s);
- }
- }
- }
+ ExprMayAffectControlFlow(impl, wc.Guard);
Analyse(impl, wc.Body);
}
@@ -218,22 +237,7 @@ namespace GPUVerify {
IfCmd ifCmd = bb.ec as IfCmd;
- VariablesOccurringInExpressionVisitor visitor = new VariablesOccurringInExpressionVisitor();
- visitor.VisitExpr(ifCmd.Guard);
- foreach (Variable v in visitor.GetVariables())
- {
- if (!mayBeDerivedFrom[impl.Name].ContainsKey(v.Name))
- {
- continue;
- }
- foreach (string s in mayBeDerivedFrom[impl.Name][v.Name])
- {
- if (!arraysWhichMayAffectControlFlow.Contains(s))
- {
- SetArrayMayAffectControlFlow(s);
- }
- }
- }
+ ExprMayAffectControlFlow(impl, ifCmd.Guard);
Analyse(impl, ifCmd.thn);
if (ifCmd.elseBlock != null)
diff --git a/Source/GPUVerify/BlockPredicator.cs b/Source/GPUVerify/BlockPredicator.cs index 6521960c..a006bde6 100644 --- a/Source/GPUVerify/BlockPredicator.cs +++ b/Source/GPUVerify/BlockPredicator.cs @@ -9,6 +9,7 @@ namespace GPUVerify { class BlockPredicator { + GPUVerifier verifier; Program prog; Implementation impl; Graph<Block> blockGraph; @@ -16,14 +17,15 @@ class BlockPredicator { Expr returnBlockId; LocalVariable curVar, pVar; - IdentifierExpr cur, p; + IdentifierExpr cur, p, fp; Expr pExpr; Dictionary<Microsoft.Boogie.Type, IdentifierExpr> havocVars = new Dictionary<Microsoft.Boogie.Type, IdentifierExpr>(); Dictionary<Block, Expr> blockIds = new Dictionary<Block, Expr>(); HashSet<Block> doneBlocks = new HashSet<Block>(); - BlockPredicator(Program p, Implementation i) { + BlockPredicator(GPUVerifier v, Program p, Implementation i) { + verifier = v; prog = p; impl = i; } @@ -145,7 +147,7 @@ class BlockPredicator { var newBlocks = new List<Block>(); - var fp = Expr.Ident(impl.InParams[0]); + fp = Expr.Ident(impl.InParams[0]); Block entryBlock = new Block(); entryBlock.Label = "entry"; entryBlock.Cmds = new CmdSeq(Cmd.SimpleAssign(Token.NoToken, cur, @@ -158,6 +160,16 @@ class BlockPredicator { var prevBlock = entryBlock; foreach (var n in sortedBlocks) { if (n.Item2) { + var backedgeBlock = new Block(); + newBlocks.Add(backedgeBlock); + + backedgeBlock.Label = n.Item1.Label + ".backedge"; + backedgeBlock.Cmds = new CmdSeq(new AssumeCmd(Token.NoToken, + Expr.Eq(cur, blockIds[n.Item1]), + new QKeyValue(Token.NoToken, "backedge", new List<object>(), null))); + backedgeBlock.TransferCmd = new GotoCmd(Token.NoToken, + new BlockSeq(n.Item1)); + var tailBlock = new Block(); newBlocks.Add(tailBlock); @@ -166,7 +178,7 @@ class BlockPredicator { Expr.Neq(cur, blockIds[n.Item1]))); prevBlock.TransferCmd = new GotoCmd(Token.NoToken, - new BlockSeq(tailBlock, n.Item1)); + new BlockSeq(backedgeBlock, tailBlock)); prevBlock = tailBlock; } else { var runBlock = n.Item1; @@ -174,6 +186,10 @@ class BlockPredicator { pExpr = Expr.Eq(cur, blockIds[runBlock]); CmdSeq newCmdSeq = new CmdSeq(); + if (CommandLineOptions.Inference && blockGraph.Headers.Contains(runBlock)) { + AddUniformCandidateInvariant(newCmdSeq, runBlock); + AddNonUniformCandidateInvariant(newCmdSeq, runBlock); + } newCmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, p, pExpr)); foreach (Cmd cmd in runBlock.Cmds) PredicateCmd(newCmdSeq, cmd); @@ -191,12 +207,43 @@ class BlockPredicator { impl.Blocks = newBlocks; } - public static void Predicate(Program p) { - foreach (var decl in p.TopLevelDeclarations) { + private void AddUniformCandidateInvariant(CmdSeq cs, Block header) { + cs.Add(verifier.CreateCandidateInvariant(Expr.Eq(cur, + new NAryExpr(Token.NoToken, + new IfThenElse(Token.NoToken), + new ExprSeq(fp, blockIds[header], returnBlockId))), + "uniform loop")); + } + + private void AddNonUniformCandidateInvariant(CmdSeq cs, Block header) { + var loopNodes = new HashSet<Block>(); + foreach (var b in blockGraph.BackEdgeNodes(header)) + loopNodes.UnionWith(blockGraph.NaturalLoops(header, b)); + var exits = new HashSet<Expr>(); + foreach (var ln in loopNodes) { + if (ln.TransferCmd is GotoCmd) { + var gCmd = (GotoCmd) ln.TransferCmd; + foreach (var exit in gCmd.labelTargets.Cast<Block>() + .Where(b => !loopNodes.Contains(b))) + exits.Add(blockIds[exit]); + } + if (ln.TransferCmd is ReturnCmd) + exits.Add(returnBlockId); + } + var curIsHeaderOrExit = exits.Aggregate((Expr)Expr.Eq(cur, blockIds[header]), + (e, exit) => Expr.Or(e, Expr.Eq(cur, exit))); + cs.Add(verifier.CreateCandidateInvariant(new NAryExpr(Token.NoToken, + new IfThenElse(Token.NoToken), + new ExprSeq(fp, curIsHeaderOrExit, Expr.Eq(cur, returnBlockId))), + "non-uniform loop")); + } + + public static void Predicate(GPUVerifier v, Program p) { + foreach (var decl in p.TopLevelDeclarations.ToList()) { if (decl is DeclWithFormals && !(decl is Function)) { var dwf = (DeclWithFormals)decl; var fpVar = new Formal(Token.NoToken, - new TypedIdent(Token.NoToken, "fp", + new TypedIdent(Token.NoToken, "_P", Microsoft.Boogie.Type.Bool), /*incoming=*/true); dwf.InParams = new VariableSeq( @@ -205,7 +252,7 @@ class BlockPredicator { } var impl = decl as Implementation; if (impl != null) - new BlockPredicator(p, impl).PredicateImplementation(); + new BlockPredicator(v, p, impl).PredicateImplementation(); } } diff --git a/Source/GPUVerify/CommandLineOptions.cs b/Source/GPUVerify/CommandLineOptions.cs index 7e6324b2..966f98eb 100644 --- a/Source/GPUVerify/CommandLineOptions.cs +++ b/Source/GPUVerify/CommandLineOptions.cs @@ -42,6 +42,8 @@ namespace GPUVerify public static bool Unstructured = false;
+ public static bool InterGroupRaceChecking = false;
+
public static int Parse(string[] args)
{
for (int i = 0; i < args.Length; i++)
@@ -184,6 +186,11 @@ namespace GPUVerify Unstructured = true;
break;
+ case "-interGroupRaceChecking":
+ case "/interGroupRaceChecking":
+ InterGroupRaceChecking = true;
+ break;
+
default:
inputFiles.Add(args[i]);
break;
diff --git a/Source/GPUVerify/ElementEncodingRaceInstrumenter.cs b/Source/GPUVerify/ElementEncodingRaceInstrumenter.cs index 7b78f0f1..cb880767 100644 --- a/Source/GPUVerify/ElementEncodingRaceInstrumenter.cs +++ b/Source/GPUVerify/ElementEncodingRaceInstrumenter.cs @@ -65,6 +65,12 @@ namespace GPUVerify MakeAccessedIndex(v, new IdentifierExpr(Token.NoToken, VariableForThread(2, OffsetParameter)), 2, "READ")
));
}
+
+ if (verifier.NonLocalState.getGroupSharedVariables().Contains(v) && CommandLineOptions.InterGroupRaceChecking)
+ {
+ WriteReadGuard = Expr.And(WriteReadGuard, verifier.ThreadsInSameGroup());
+ }
+
WriteReadGuard = Expr.Not(WriteReadGuard);
simpleCmds.Add(new AssertCmd(Token.NoToken, WriteReadGuard));
}
@@ -87,6 +93,12 @@ namespace GPUVerify MakeAccessedIndex(v, new IdentifierExpr(Token.NoToken, VariableForThread(2, OffsetParameter)), 2, "WRITE")
));
}
+
+ if (verifier.NonLocalState.getGroupSharedVariables().Contains(v) && CommandLineOptions.InterGroupRaceChecking)
+ {
+ WriteWriteGuard = Expr.And(WriteWriteGuard, verifier.ThreadsInSameGroup());
+ }
+
WriteWriteGuard = Expr.Not(WriteWriteGuard);
simpleCmds.Add(new AssertCmd(Token.NoToken, WriteWriteGuard));
@@ -105,6 +117,12 @@ namespace GPUVerify MakeAccessedIndex(v, new IdentifierExpr(Token.NoToken, VariableForThread(2, OffsetParameter)), 2, "READ")
));
}
+
+ if (verifier.NonLocalState.getGroupSharedVariables().Contains(v) && CommandLineOptions.InterGroupRaceChecking)
+ {
+ ReadWriteGuard = Expr.And(ReadWriteGuard, verifier.ThreadsInSameGroup());
+ }
+
ReadWriteGuard = Expr.Not(ReadWriteGuard);
simpleCmds.Add(new AssertCmd(Token.NoToken, ReadWriteGuard));
@@ -156,14 +174,6 @@ namespace GPUVerify return new AssignCmd(lhs.tok, lhss, rhss);
}
- protected override void SetNoAccessOccurred(IToken tok, BigBlock bb, Variable v, string AccessType)
- {
- IdentifierExpr AccessOccurred1 = new IdentifierExpr(tok,
- new VariableDualiser(1, null, null).VisitVariable(GPUVerifier.MakeAccessHasOccurredVariable(v.Name, AccessType)));
-
- bb.simpleCmds.Add(new AssumeCmd(Token.NoToken, Expr.Not(AccessOccurred1)));
- }
-
private Expr MakeAccessedIndex(Variable v, Expr offsetExpr, int Thread, string AccessType)
{
Expr result = new IdentifierExpr(v.tok, new VariableDualiser(Thread, null, null).VisitVariable(v.Clone() as Variable));
@@ -195,16 +205,16 @@ namespace GPUVerify }
- protected override void AddAccessedOffsetIsThreadGlobalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite)
+ protected override void AddAccessedOffsetsAreConstantCandidateInvariant(IRegion region, Variable v, IEnumerable<Expr> offsets, string ReadOrWrite)
{
- Expr expr = AccessedOffsetIsThreadGlobalIdExpr(v, ReadOrWrite, 1);
- verifier.AddCandidateInvariant(wc, expr, "accessed offset is global id");
+ Expr expr = AccessedOffsetsAreConstantExpr(v, offsets, ReadOrWrite, 1);
+ verifier.AddCandidateInvariant(region, expr, "accessed offsets are constant");
}
- protected override void AddAccessedOffsetIsThreadLocalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite)
- {
- Expr expr = AccessedOffsetIsThreadLocalIdExpr(v, ReadOrWrite, 1);
- verifier.AddCandidateInvariant(wc, expr, "accessed offset is local id");
+ private Expr AccessedOffsetsAreConstantExpr(Variable v, IEnumerable<Expr> offsets, string ReadOrWrite, int Thread) {
+ return Expr.Imp(
+ new IdentifierExpr(Token.NoToken, new VariableDualiser(Thread, null, null).VisitVariable(GPUVerifier.MakeAccessHasOccurredVariable(v.Name, ReadOrWrite))),
+ offsets.Select(ofs => (Expr)Expr.Eq(new IdentifierExpr(Token.NoToken, new VariableDualiser(Thread, null, null).VisitVariable(GPUVerifier.MakeOffsetXVariable(v, ReadOrWrite))), ofs)).Aggregate(Expr.Or));
}
private Expr AccessedOffsetIsThreadLocalIdExpr(Variable v, string ReadOrWrite, int Thread)
@@ -240,65 +250,10 @@ namespace GPUVerify return new VariableDualiser(Thread, null, null).VisitExpr(verifier.GlobalIdExpr(dimension).Clone() as Expr);
}
- private Expr GlobalSizeExpr(string dimension)
- {
- return GPUVerifier.MakeBitVectorBinaryBitVector("BV32_MUL",
- new IdentifierExpr(Token.NoToken, verifier.GetNumGroups(dimension)),
- new IdentifierExpr(Token.NoToken, verifier.GetGroupSize(dimension)));
- }
-
- protected override void AddAccessedOffsetIsThreadFlattened2DLocalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite)
- {
- Expr expr = AccessedOffsetIsThreadFlattened2DLocalIdExpr(v, ReadOrWrite, 1);
- verifier.AddCandidateInvariant(wc, expr, "accessed offset is flattened 2D local id");
- }
-
- private Expr AccessedOffsetIsThreadFlattened2DLocalIdExpr(Variable v, string ReadOrWrite, int Thread)
- {
- Expr expr = null;
- if (GPUVerifier.HasXDimension(v) && GPUVerifier.IndexTypeOfXDimension(v).Equals(verifier.GetTypeOfIdX()))
- {
- expr = Expr.Imp(
- AccessHasOccurred(v, ReadOrWrite, Thread),
- Expr.Eq(
- new IdentifierExpr(v.tok, new VariableDualiser(Thread, null, null).VisitVariable(GPUVerifier.MakeOffsetXVariable(v, ReadOrWrite))),
- GPUVerifier.MakeBitVectorBinaryBitVector("BV32_ADD", GPUVerifier.MakeBitVectorBinaryBitVector("BV32_MUL",
- new IdentifierExpr(v.tok, verifier.MakeThreadId(v.tok, "Y", Thread)), new IdentifierExpr(v.tok, verifier.GetGroupSize("X"))),
- new IdentifierExpr(v.tok, verifier.MakeThreadId(v.tok, "X", Thread)))
- )
- );
- }
- return expr;
- }
-
- protected override void AddAccessedOffsetIsThreadFlattened2DGlobalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite)
- {
- Expr expr = AccessedOffsetIsThreadFlattened2DGlobalIdExpr(v, ReadOrWrite, 1);
- verifier.AddCandidateInvariant(wc, expr, "accessed offset is flattened 2D global id");
- }
-
- private Expr AccessedOffsetIsThreadFlattened2DGlobalIdExpr(Variable v, string ReadOrWrite, int Thread)
- {
- Expr expr = null;
- if (GPUVerifier.HasXDimension(v) && GPUVerifier.IndexTypeOfXDimension(v).Equals(verifier.GetTypeOfIdX()))
- {
- expr = Expr.Imp(
- AccessHasOccurred(v, ReadOrWrite, Thread),
- Expr.Eq(
- new IdentifierExpr(v.tok, new VariableDualiser(Thread, null, null).VisitVariable(GPUVerifier.MakeOffsetXVariable(v, ReadOrWrite))),
- GPUVerifier.MakeBitVectorBinaryBitVector("BV32_ADD", GPUVerifier.MakeBitVectorBinaryBitVector("BV32_MUL",
- GlobalIdExpr("Y", Thread), GlobalSizeExpr("X")),
- GlobalIdExpr("X", Thread))
- )
- );
- }
- return expr;
- }
-
- protected override void AddAccessedOffsetInRangeCTimesLocalIdToCTimesLocalIdPlusC(WhileCmd wc, Variable v, Expr constant, string ReadOrWrite)
+ protected override void AddAccessedOffsetInRangeCTimesLocalIdToCTimesLocalIdPlusC(IRegion region, Variable v, Expr constant, string ReadOrWrite)
{
Expr expr = MakeCTimesLocalIdRangeExpression(v, constant, ReadOrWrite, 1);
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
expr, "accessed offset in range [ C*local_id, (C+1)*local_id )");
}
@@ -329,10 +284,10 @@ namespace GPUVerify return new IdentifierExpr(v.tok, new VariableDualiser(Thread, null, null).VisitVariable(GPUVerifier.MakeOffsetXVariable(v, ReadOrWrite)));
}
- protected override void AddAccessedOffsetInRangeCTimesGlobalIdToCTimesGlobalIdPlusC(WhileCmd wc, Variable v, Expr constant, string ReadOrWrite)
+ protected override void AddAccessedOffsetInRangeCTimesGlobalIdToCTimesGlobalIdPlusC(IRegion region, Variable v, Expr constant, string ReadOrWrite)
{
Expr expr = MakeCTimesGloalIdRangeExpr(v, constant, ReadOrWrite, 1);
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
expr, "accessed offset in range [ C*global_id, (C+1)*global_id )");
}
diff --git a/Source/GPUVerify/GPUVerifier.cs b/Source/GPUVerify/GPUVerifier.cs index 4e30951e..1839b138 100644 --- a/Source/GPUVerify/GPUVerifier.cs +++ b/Source/GPUVerify/GPUVerifier.cs @@ -25,7 +25,7 @@ namespace GPUVerify private HashSet<string> ReservedNames = new HashSet<string>();
private int TempCounter = 0;
- private int invariantGenerationCounter;
+ private int invariantGenerationCounter = 0;
internal const string LOCAL_ID_X_STRING = "local_id_x";
internal const string LOCAL_ID_Y_STRING = "local_id_y";
@@ -64,13 +64,12 @@ namespace GPUVerify public UniformityAnalyser uniformityAnalyser;
public MayBeThreadConfigurationVariableAnalyser mayBeTidAnalyser;
public MayBeGidAnalyser mayBeGidAnalyser;
- public MayBeGlobalSizeAnalyser mayBeGlobalSizeAnalyser;
- public MayBeFlattened2DTidOrGidAnalyser mayBeFlattened2DTidOrGidAnalyser;
public MayBeLocalIdPlusConstantAnalyser mayBeTidPlusConstantAnalyser;
public MayBeGlobalIdPlusConstantAnalyser mayBeGidPlusConstantAnalyser;
public MayBePowerOfTwoAnalyser mayBePowerOfTwoAnalyser;
public LiveVariableAnalyser liveVariableAnalyser;
public ArrayControlFlowAnalyser arrayControlFlowAnalyser;
+ public Dictionary<Implementation, VariableDefinitionAnalysis> varDefAnalyses;
public GPUVerifier(string filename, Program program, ResolutionContext rc, IRaceInstrumenter raceInstrumenter) : this(filename, program, rc, raceInstrumenter, false)
{
@@ -124,6 +123,7 @@ namespace GPUVerify new EnsuresSeq(),
new QKeyValue(Token.NoToken, "barrier", new List<object>(), null));
Program.TopLevelDeclarations.Add(p);
+ ResContext.AddProcedure(p);
}
return p;
}
@@ -370,6 +370,8 @@ namespace GPUVerify DoArrayControlFlowAnalysis();
+ DoVariableDefinitionAnalysis();
+
if (CommandLineOptions.ShowStages)
{
emitProgram(outputFilename + "_preprocessed");
@@ -489,12 +491,6 @@ namespace GPUVerify mayBeGidAnalyser = new MayBeGidAnalyser(this);
mayBeGidAnalyser.Analyse();
-
- mayBeGlobalSizeAnalyser = new MayBeGlobalSizeAnalyser(this);
- mayBeGlobalSizeAnalyser.Analyse();
-
- mayBeFlattened2DTidOrGidAnalyser = new MayBeFlattened2DTidOrGidAnalyser(this);
- mayBeFlattened2DTidOrGidAnalyser.Analyse();
}
private void DoMayBeIdPlusConstantAnalysis()
@@ -523,6 +519,12 @@ namespace GPUVerify liveVariableAnalyser.Analyse();
}
+ private void DoVariableDefinitionAnalysis()
+ {
+ varDefAnalyses = Program.TopLevelDeclarations
+ .OfType<Implementation>()
+ .ToDictionary(i => i, i => VariableDefinitionAnalysis.Analyse(this, i));
+ }
private void ProcessAccessInvariants()
{
@@ -654,9 +656,6 @@ namespace GPUVerify private void ComputeInvariant()
{
-
- invariantGenerationCounter = 0;
-
for (int i = 0; i < Program.TopLevelDeclarations.Count; i++)
{
if (Program.TopLevelDeclarations[i] is Implementation)
@@ -1056,7 +1055,7 @@ namespace GPUVerify {
if (p.Contains("$"))
{
- return p.Substring(0, p.IndexOf("$"));
+ return p.Substring(0, p.LastIndexOf("$"));
}
return p;
}
@@ -1083,64 +1082,78 @@ namespace GPUVerify {
RaceInstrumenter.AddKernelPrecondition();
- Expr AssumeDistinctThreads = null;
- Expr AssumeThreadIdsInRange = null;
IToken tok = KernelImplementation.tok;
- GeneratePreconditionsForDimension(ref AssumeDistinctThreads, ref AssumeThreadIdsInRange, tok, "X");
- GeneratePreconditionsForDimension(ref AssumeDistinctThreads, ref AssumeThreadIdsInRange, tok, "Y");
- GeneratePreconditionsForDimension(ref AssumeDistinctThreads, ref AssumeThreadIdsInRange, tok, "Z");
+ GeneratePreconditionsForDimension(tok, "X");
+ GeneratePreconditionsForDimension(tok, "Y");
+ GeneratePreconditionsForDimension(tok, "Z");
- if (AssumeDistinctThreads != null)
+ foreach (Declaration D in Program.TopLevelDeclarations)
{
- Debug.Assert(AssumeThreadIdsInRange != null);
+ if (!(D is Procedure))
+ {
+ continue;
+ }
+ Procedure Proc = D as Procedure;
+ if (QKeyValue.FindIntAttribute(Proc.Attributes, "inline", -1) == 1)
+ {
+ continue;
+ }
+
+ Expr DistinctLocalIds =
+ Expr.Or(
+ Expr.Or(
+ Expr.Neq(
+ new IdentifierExpr(tok, MakeThreadId(tok, "X", 1)),
+ new IdentifierExpr(tok, MakeThreadId(tok, "X", 2))
+ ),
+ Expr.Neq(
+ new IdentifierExpr(tok, MakeThreadId(tok, "Y", 1)),
+ new IdentifierExpr(tok, MakeThreadId(tok, "Y", 2))
+ )
+ ),
+ Expr.Neq(
+ new IdentifierExpr(tok, MakeThreadId(tok, "Z", 1)),
+ new IdentifierExpr(tok, MakeThreadId(tok, "Z", 2))
+ )
+ );
- foreach (Declaration D in Program.TopLevelDeclarations)
+ if (CommandLineOptions.InterGroupRaceChecking)
{
- if (!(D is Procedure))
- {
- continue;
- }
- Procedure Proc = D as Procedure;
- if (QKeyValue.FindIntAttribute(Proc.Attributes, "inline", -1) == 1)
- {
- continue;
- }
+ Proc.Requires.Add(new Requires(false, Expr.Imp(ThreadsInSameGroup(), DistinctLocalIds)));
- Proc.Requires.Add(new Requires(false, AssumeDistinctThreads));
- Proc.Requires.Add(new Requires(false, AssumeThreadIdsInRange));
+ }
+ else
+ {
+ Proc.Requires.Add(new Requires(false, DistinctLocalIds));
+ }
- if (Proc == KernelProcedure)
+ if (Proc == KernelProcedure)
+ {
+ bool foundNonUniform = false;
+ int indexOfFirstNonUniformParameter;
+ for (indexOfFirstNonUniformParameter = 0; indexOfFirstNonUniformParameter < Proc.InParams.Length; indexOfFirstNonUniformParameter++)
{
- bool foundNonUniform = false;
- int indexOfFirstNonUniformParameter;
- for (indexOfFirstNonUniformParameter = 0; indexOfFirstNonUniformParameter < Proc.InParams.Length; indexOfFirstNonUniformParameter++)
+ if (!uniformityAnalyser.IsUniform(Proc.Name, StripThreadIdentifier(Proc.InParams[indexOfFirstNonUniformParameter].Name)))
{
- if (!uniformityAnalyser.IsUniform(Proc.Name, StripThreadIdentifier(Proc.InParams[indexOfFirstNonUniformParameter].Name)))
- {
- foundNonUniform = true;
- break;
- }
+ foundNonUniform = true;
+ break;
}
+ }
- if (foundNonUniform)
+ if (foundNonUniform)
+ {
+ // I have a feeling this will never be reachable!!!
+ int numberOfNonUniformParameters = (Proc.InParams.Length - indexOfFirstNonUniformParameter) / 2;
+ for (int i = indexOfFirstNonUniformParameter; i < numberOfNonUniformParameters; i++)
{
- // I have a feeling this will never be reachable!!!
- int numberOfNonUniformParameters = (Proc.InParams.Length - indexOfFirstNonUniformParameter) / 2;
- for (int i = indexOfFirstNonUniformParameter; i < numberOfNonUniformParameters; i++)
- {
- Proc.Requires.Add(new Requires(false,
- Expr.Eq(new IdentifierExpr(Proc.InParams[i].tok, Proc.InParams[i]),
- new IdentifierExpr(Proc.InParams[i + numberOfNonUniformParameters].tok, Proc.InParams[i + numberOfNonUniformParameters]))));
- }
+ Proc.Requires.Add(new Requires(false,
+ Expr.Eq(new IdentifierExpr(Proc.InParams[i].tok, Proc.InParams[i]),
+ new IdentifierExpr(Proc.InParams[i + numberOfNonUniformParameters].tok, Proc.InParams[i + numberOfNonUniformParameters]))));
}
}
-
}
- }
- else
- {
- Debug.Assert(AssumeThreadIdsInRange == null);
+
}
foreach (Declaration D in Program.TopLevelDeclarations)
@@ -1166,6 +1179,26 @@ namespace GPUVerify }
+ internal Expr ThreadsInSameGroup()
+ {
+ return Expr.And(
+ Expr.And(
+ Expr.Eq(
+ new IdentifierExpr(Token.NoToken, MakeGroupId("X", 1)),
+ new IdentifierExpr(Token.NoToken, MakeGroupId("X", 2))
+ ),
+ Expr.Eq(
+ new IdentifierExpr(Token.NoToken, MakeGroupId("Y", 1)),
+ new IdentifierExpr(Token.NoToken, MakeGroupId("Y", 2))
+ )
+ ),
+ Expr.Eq(
+ new IdentifierExpr(Token.NoToken, MakeGroupId("Z", 1)),
+ new IdentifierExpr(Token.NoToken, MakeGroupId("Z", 2))
+ )
+ );
+ }
+
internal static void AddInvariantToAllLoops(Expr Invariant, StmtList stmtList)
{
foreach (BigBlock bb in stmtList.BigBlocks)
@@ -1190,7 +1223,7 @@ namespace GPUVerify return Int32.Parse(p.Substring(p.IndexOf("$") + 1, p.Length - (p.IndexOf("$") + 1)));
}
- private void GeneratePreconditionsForDimension(ref Expr AssumeDistinctThreads, ref Expr AssumeThreadIdsInRange, IToken tok, String dimension)
+ private void GeneratePreconditionsForDimension(IToken tok, String dimension)
{
foreach (Declaration D in Program.TopLevelDeclarations.ToList())
{
@@ -1204,53 +1237,59 @@ namespace GPUVerify continue;
}
+ Expr GroupSizePositive;
+ Expr NumGroupsPositive;
+ Expr GroupIdNonNegative;
+ Expr GroupIdLessThanNumGroups;
+
if (GetTypeOfId(dimension).Equals(Microsoft.Boogie.Type.GetBvType(32)))
{
- Proc.Requires.Add(new Requires(false, MakeBVSgt(new IdentifierExpr(tok, GetGroupSize(dimension)), ZeroBV(tok))));
- Proc.Requires.Add(new Requires(false, MakeBVSgt(new IdentifierExpr(tok, GetNumGroups(dimension)), ZeroBV(tok))));
- Proc.Requires.Add(new Requires(false, MakeBVSge(new IdentifierExpr(tok, GetGroupId(dimension)), ZeroBV(tok))));
- Proc.Requires.Add(new Requires(false, MakeBVSlt(new IdentifierExpr(tok, GetGroupId(dimension)), new IdentifierExpr(tok, GetNumGroups(dimension)))));
+ GroupSizePositive = MakeBVSgt(new IdentifierExpr(tok, GetGroupSize(dimension)), ZeroBV(tok));
+ NumGroupsPositive = MakeBVSgt(new IdentifierExpr(tok, GetNumGroups(dimension)), ZeroBV(tok));
+ GroupIdNonNegative = MakeBVSge(new IdentifierExpr(tok, GetGroupId(dimension)), ZeroBV(tok));
+ GroupIdLessThanNumGroups = MakeBVSlt(new IdentifierExpr(tok, GetGroupId(dimension)), new IdentifierExpr(tok, GetNumGroups(dimension)));
}
else
{
- Proc.Requires.Add(new Requires(false, Expr.Gt(new IdentifierExpr(tok, GetGroupSize(dimension)), Zero(tok))));
- Proc.Requires.Add(new Requires(false, Expr.Gt(new IdentifierExpr(tok, GetNumGroups(dimension)), Zero(tok))));
- Proc.Requires.Add(new Requires(false, Expr.Ge(new IdentifierExpr(tok, GetGroupId(dimension)), Zero(tok))));
- Proc.Requires.Add(new Requires(false, Expr.Lt(new IdentifierExpr(tok, GetGroupId(dimension)), new IdentifierExpr(tok, GetNumGroups(dimension)))));
+ GroupSizePositive = Expr.Gt(new IdentifierExpr(tok, GetGroupSize(dimension)), Zero(tok));
+ NumGroupsPositive = Expr.Gt(new IdentifierExpr(tok, GetNumGroups(dimension)), Zero(tok));
+ GroupIdNonNegative = Expr.Ge(new IdentifierExpr(tok, GetGroupId(dimension)), Zero(tok));
+ GroupIdLessThanNumGroups = Expr.Lt(new IdentifierExpr(tok, GetGroupId(dimension)), new IdentifierExpr(tok, GetNumGroups(dimension)));
}
- }
- Expr AssumeThreadsDistinctInDimension =
- Expr.Neq(
- new IdentifierExpr(tok, MakeThreadId(tok, dimension, 1)),
- new IdentifierExpr(tok, MakeThreadId(tok, dimension, 2))
- );
+ Proc.Requires.Add(new Requires(false, GroupSizePositive));
+ Proc.Requires.Add(new Requires(false, NumGroupsPositive));
+ if (CommandLineOptions.InterGroupRaceChecking)
+ {
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(1, null, null).VisitExpr(GroupIdNonNegative)));
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(2, null, null).VisitExpr(GroupIdNonNegative)));
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(1, null, null).VisitExpr(GroupIdLessThanNumGroups)));
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(2, null, null).VisitExpr(GroupIdLessThanNumGroups)));
+ }
+ else
+ {
+ Proc.Requires.Add(new Requires(false, GroupIdNonNegative));
+ Proc.Requires.Add(new Requires(false, GroupIdLessThanNumGroups));
+ }
- AssumeDistinctThreads = (null == AssumeDistinctThreads) ? AssumeThreadsDistinctInDimension : Expr.Or(AssumeDistinctThreads, AssumeThreadsDistinctInDimension);
+ Expr ThreadIdNonNegative =
+ GetTypeOfId(dimension).Equals(Microsoft.Boogie.Type.GetBvType(32)) ?
+ MakeBVSge(new IdentifierExpr(tok, MakeThreadId(tok, dimension)), ZeroBV(tok))
+ :
+ Expr.Ge(new IdentifierExpr(tok, MakeThreadId(tok, dimension)), Zero(tok));
+ Expr ThreadIdLessThanGroupSize =
+ GetTypeOfId(dimension).Equals(Microsoft.Boogie.Type.GetBvType(32)) ?
+ MakeBVSlt(new IdentifierExpr(tok, MakeThreadId(tok, dimension)), new IdentifierExpr(tok, GetGroupSize(dimension)))
+ :
+ Expr.Lt(new IdentifierExpr(tok, MakeThreadId(tok, dimension)), new IdentifierExpr(tok, GetGroupSize(dimension)));
- Expr AssumeThreadIdsInRangeInDimension =
- GetTypeOfId(dimension).Equals(Microsoft.Boogie.Type.GetBvType(32)) ?
- Expr.And(
- Expr.And(
- MakeBVSge(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 1)), ZeroBV(tok)),
- MakeBVSge(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 2)), ZeroBV(tok))
- ),
- Expr.And(
- MakeBVSlt(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 1)), new IdentifierExpr(tok, GetGroupSize(dimension))),
- MakeBVSlt(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 2)), new IdentifierExpr(tok, GetGroupSize(dimension)))
- ))
- :
- Expr.And(
- Expr.And(
- Expr.Ge(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 1)), Zero(tok)),
- Expr.Ge(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 2)), Zero(tok))
- ),
- Expr.And(
- Expr.Lt(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 1)), new IdentifierExpr(tok, GetGroupSize(dimension))),
- Expr.Lt(new IdentifierExpr(tok, MakeThreadId(tok, dimension, 2)), new IdentifierExpr(tok, GetGroupSize(dimension)))
- ));
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(1, null, null).VisitExpr(ThreadIdNonNegative)));
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(2, null, null).VisitExpr(ThreadIdNonNegative)));
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(1, null, null).VisitExpr(ThreadIdLessThanGroupSize)));
+ Proc.Requires.Add(new Requires(false, new VariableDualiser(2, null, null).VisitExpr(ThreadIdLessThanGroupSize)));
+
+ }
- AssumeThreadIdsInRange = (null == AssumeThreadIdsInRange) ? AssumeThreadIdsInRangeInDimension : Expr.And(AssumeThreadIdsInRange, AssumeThreadIdsInRangeInDimension);
}
private Function GetOrCreateBVFunction(string functionName, string smtName, Microsoft.Boogie.Type resultType, params Microsoft.Boogie.Type[] argTypes)
@@ -1351,6 +1390,12 @@ namespace GPUVerify return null;
}
+ internal Constant MakeGroupId(string dimension, int number)
+ {
+ Constant resultWithoutThreadId = GetGroupId(dimension);
+ return new Constant(Token.NoToken, new TypedIdent(Token.NoToken, resultWithoutThreadId.Name + "$" + number, GetTypeOfId(dimension)));
+ }
+
private static LiteralExpr Zero(IToken tok)
{
return new LiteralExpr(tok, BigNum.FromInt(0));
@@ -1374,8 +1419,13 @@ namespace GPUVerify IdentifierExpr P1 = new IdentifierExpr(tok, new LocalVariable(tok, BarrierProcedure.InParams[0].TypedIdent));
IdentifierExpr P2 = new IdentifierExpr(tok, new LocalVariable(tok, BarrierProcedure.InParams[1].TypedIdent));
- if (!CommandLineOptions.Unstructured)
- checkNonDivergence.simpleCmds.Add(new AssertCmd(tok, Expr.Eq(P1, P2)));
+ Expr DivergenceCondition = Expr.Eq(P1, P2);
+ if (CommandLineOptions.InterGroupRaceChecking)
+ {
+ DivergenceCondition = Expr.Imp(ThreadsInSameGroup(), DivergenceCondition);
+ }
+
+ checkNonDivergence.simpleCmds.Add(new AssertCmd(tok, DivergenceCondition));
if (!CommandLineOptions.OnlyDivergence)
{
@@ -1388,15 +1438,32 @@ namespace GPUVerify checkNonDivergence.ec = new IfCmd(tok, Expr.Or(Expr.Not(P1), Expr.Not(P2)), returnstatement, null, null);
}
- bigblocks.Add(RaceInstrumenter.MakeResetReadWriteSetsStatements(tok));
+ if (CommandLineOptions.InterGroupRaceChecking)
+ {
+ bigblocks.Add(new BigBlock(Token.NoToken, null, new CmdSeq(),
+ new IfCmd(Token.NoToken, P1, new StmtList(MakeResetAndHavocBlocks(1), Token.NoToken), null, null),
+ null));
+ bigblocks.Add(new BigBlock(Token.NoToken, null, new CmdSeq(),
+ new IfCmd(Token.NoToken, P2, new StmtList(MakeResetAndHavocBlocks(2), Token.NoToken), null, null),
+ null));
+ }
+ else
+ {
+ foreach (BigBlock bb in MakeResetAndHavocBlocks(1))
+ {
+ bigblocks.Add(bb);
+ }
+ foreach (BigBlock bb in MakeResetAndHavocBlocks(2))
+ {
+ bigblocks.Add(bb);
+ }
+ }
- BigBlock havocSharedState = new BigBlock(tok, "__HavocSharedState", new CmdSeq(), null, null);
- bigblocks.Add(havocSharedState);
foreach (Variable v in NonLocalState.getAllNonLocalVariables())
{
if (!ArrayModelledAdversarially(v))
{
- HavocAndAssumeEquality(tok, havocSharedState, v);
+ bigblocks.Add(AssumeEqualityBetweenSharedArrays(v, P1, P2));
}
}
@@ -1414,6 +1481,20 @@ namespace GPUVerify Program.TopLevelDeclarations.Add(BarrierImplementation);
}
+ private List<BigBlock> MakeResetAndHavocBlocks(int Thread)
+ {
+ List<BigBlock> ResetAndHavocBlocks = new List<BigBlock>();
+ foreach (Variable v in NonLocalState.getAllNonLocalVariables())
+ {
+ ResetAndHavocBlocks.Add(RaceInstrumenter.MakeResetReadWriteSetStatements(v, Thread));
+ if (!ArrayModelledAdversarially(v))
+ {
+ ResetAndHavocBlocks.Add(HavocSharedArray(v, Thread));
+ }
+ }
+ return ResetAndHavocBlocks;
+ }
+
public static bool HasZDimension(Variable v)
{
@@ -1444,17 +1525,28 @@ namespace GPUVerify return v.TypedIdent.Type is MapType;
}
- private void HavocAndAssumeEquality(IToken tok, BigBlock bb, Variable v)
+ private BigBlock HavocSharedArray(Variable v, int thread)
{
- IdentifierExpr v1 = new IdentifierExpr(tok, new VariableDualiser(1, null, null).VisitVariable(v.Clone() as Variable));
- IdentifierExpr v2 = new IdentifierExpr(tok, new VariableDualiser(2, null, null).VisitVariable(v.Clone() as Variable));
+ IdentifierExpr vForThread = new IdentifierExpr(Token.NoToken, new VariableDualiser(thread, null, null).VisitVariable(v.Clone() as Variable));
+ return new BigBlock(Token.NoToken, null, new CmdSeq(new Cmd[] { new HavocCmd(Token.NoToken, new IdentifierExprSeq(new IdentifierExpr[] { vForThread })) }), null, null);
+ }
- IdentifierExprSeq ModifiedVars = new IdentifierExprSeq(new IdentifierExpr[] { v1, v2 });
- bb.simpleCmds.Add(new HavocCmd(tok, ModifiedVars));
- bb.simpleCmds.Add(new AssumeCmd(tok, Expr.Eq(v1, v2)));
+ private BigBlock AssumeEqualityBetweenSharedArrays(Variable v, Expr P1, Expr P2)
+ {
+ IdentifierExpr v1 = new IdentifierExpr(Token.NoToken, new VariableDualiser(1, null, null).VisitVariable(v.Clone() as Variable));
+ IdentifierExpr v2 = new IdentifierExpr(Token.NoToken, new VariableDualiser(2, null, null).VisitVariable(v.Clone() as Variable));
+ Expr AssumeGuard = Expr.Eq(v1, v2);
+
+ if (CommandLineOptions.InterGroupRaceChecking)
+ {
+ AssumeGuard = Expr.Imp(ThreadsInSameGroup(), AssumeGuard);
+ }
+
+ return new BigBlock(Token.NoToken, null, new CmdSeq(new Cmd[] { new AssumeCmd(Token.NoToken, AssumeGuard) }), null, null);
}
+
internal static bool ModifiesSetContains(IdentifierExprSeq Modifies, IdentifierExpr v)
{
foreach (IdentifierExpr ie in Modifies)
@@ -2040,7 +2132,8 @@ namespace GPUVerify }
- if (d is Variable && ((d as Variable).IsMutable || IsThreadLocalIdConstant(d as Variable)))
+ if (d is Variable && ((d as Variable).IsMutable || IsThreadLocalIdConstant(d as Variable)
+ || (CommandLineOptions.InterGroupRaceChecking && IsGroupIdConstant(d as Variable) ) ))
{
NewTopLevelDeclarations.Add(new VariableDualiser(1, null, null).VisitVariable((Variable)d.Clone()));
NewTopLevelDeclarations.Add(new VariableDualiser(2, null, null).VisitVariable((Variable)d.Clone()));
@@ -2060,7 +2153,7 @@ namespace GPUVerify {
if (CommandLineOptions.Unstructured)
{
- BlockPredicator.Predicate(Program);
+ BlockPredicator.Predicate(this, Program);
return;
}
@@ -2157,16 +2250,26 @@ namespace GPUVerify return variable.Name.Equals(_X.Name) || variable.Name.Equals(_Y.Name) || variable.Name.Equals(_Z.Name);
}
- internal void AddCandidateInvariant(WhileCmd wc, Expr e, string tag)
+ public static bool IsGroupIdConstant(Variable variable)
+ {
+ return variable.Name.Equals(_GROUP_X.Name) || variable.Name.Equals(_GROUP_Y.Name) || variable.Name.Equals(_GROUP_Z.Name);
+ }
+
+ internal void AddCandidateInvariant(IRegion region, Expr e, string tag)
+ {
+ region.AddInvariant(CreateCandidateInvariant(e, tag));
+ }
+
+ internal PredicateCmd CreateCandidateInvariant(Expr e, string tag)
{
- Constant ExistentialBooleanConstant = MakeExistentialBoolean(wc.tok);
- IdentifierExpr ExistentialBoolean = new IdentifierExpr(wc.tok, ExistentialBooleanConstant);
- PredicateCmd invariant = new AssertCmd(wc.tok, Expr.Imp(ExistentialBoolean, e));
+ Constant ExistentialBooleanConstant = MakeExistentialBoolean(Token.NoToken);
+ IdentifierExpr ExistentialBoolean = new IdentifierExpr(Token.NoToken, ExistentialBooleanConstant);
+ PredicateCmd invariant = new AssertCmd(Token.NoToken, Expr.Imp(ExistentialBoolean, e));
invariant.Attributes = new QKeyValue(Token.NoToken, "tag", new List<object>(new object[] { tag }), null);
- wc.Invariants.Add(invariant);
Program.TopLevelDeclarations.Add(ExistentialBooleanConstant);
+ return invariant;
}
-
+
internal Implementation GetImplementation(string procedureName)
{
foreach (Declaration D in Program.TopLevelDeclarations)
@@ -2181,21 +2284,9 @@ namespace GPUVerify }
- internal bool ContainsBarrierCall(StmtList stmtList)
+ internal bool ContainsBarrierCall(IRegion loop)
{
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- if (ContainsBarrierCall(bb))
- {
- return true;
- }
- }
- return false;
- }
-
- private bool ContainsBarrierCall(BigBlock bb)
- {
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in loop.Cmds())
{
if (c is CallCmd && ((c as CallCmd).Proc == BarrierProcedure))
{
@@ -2203,21 +2294,6 @@ namespace GPUVerify }
}
- if (bb.ec is WhileCmd)
- {
- return ContainsBarrierCall((bb.ec as WhileCmd).Body);
- }
-
- if (bb.ec is IfCmd)
- {
- Debug.Assert((bb.ec as IfCmd).elseIf == null);
- if (ContainsBarrierCall((bb.ec as IfCmd).thn))
- {
- return true;
- }
- return (bb.ec as IfCmd).elseBlock != null && ContainsBarrierCall((bb.ec as IfCmd).elseBlock);
- }
-
return false;
}
@@ -2247,6 +2323,14 @@ namespace GPUVerify new IdentifierExpr(Token.NoToken, GetGroupId(dimension)), new IdentifierExpr(Token.NoToken, GetGroupSize(dimension))),
new IdentifierExpr(Token.NoToken, MakeThreadId(Token.NoToken, dimension)));
}
+
+ internal IRegion RootRegion(Implementation Impl)
+ {
+ if (CommandLineOptions.Unstructured)
+ return new UnstructuredRegion(Program, Impl);
+ else
+ return new StructuredRegion(Impl);
+ }
}
class ThreadIdentifierStripper : StandardVisitor
diff --git a/Source/GPUVerify/GPUVerify.csproj b/Source/GPUVerify/GPUVerify.csproj index 27b9abe5..0c87587f 100644 --- a/Source/GPUVerify/GPUVerify.csproj +++ b/Source/GPUVerify/GPUVerify.csproj @@ -109,12 +109,12 @@ <Compile Include="ArrayControlFlowAnalyser.cs" />
<Compile Include="AsymmetricExpressionFinder.cs" />
<Compile Include="BlockPredicator.cs" />
+ <Compile Include="UnstructuredRegion.cs" />
+ <Compile Include="IRegion.cs" />
<Compile Include="GraphAlgorithms.cs" />
<Compile Include="InvariantGenerationRules\LoopVariableBoundsInvariantGenerator.cs" />
<Compile Include="InvariantGenerationRules\InvariantGenerationRule.cs" />
<Compile Include="InvariantGenerationRules\PowerOfTwoInvariantGenerator.cs" />
- <Compile Include="MayBeGlobalSizeAnalyser.cs" />
- <Compile Include="MayBeFlattened2DTidOrGidAnalyser.cs" />
<Compile Include="MayBeGidAnalyser.cs" />
<Compile Include="EnsureDisabledThreadHasNoEffectInstrumenter.cs" />
<Compile Include="KernelDualiser.cs" />
@@ -145,6 +145,8 @@ <Compile Include="UniformityAnalyser.cs" />
<Compile Include="VariableDualiser.cs" />
<Compile Include="VariablesOccurringInExpressionVisitor.cs" />
+ <Compile Include="VariableDefinitionAnalysis.cs" />
+ <Compile Include="StructuredRegion.cs" />
<Compile Include="WriteCollector.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/Source/GPUVerify/IRaceInstrumenter.cs b/Source/GPUVerify/IRaceInstrumenter.cs index 65d2cc1b..63b1ea1a 100644 --- a/Source/GPUVerify/IRaceInstrumenter.cs +++ b/Source/GPUVerify/IRaceInstrumenter.cs @@ -8,7 +8,7 @@ namespace GPUVerify {
interface IRaceInstrumenter
{
- void AddRaceCheckingCandidateInvariants(Implementation impl, WhileCmd wc);
+ void AddRaceCheckingCandidateInvariants(Implementation impl, IRegion region);
void AddKernelPrecondition();
// Summary:
@@ -20,7 +20,7 @@ namespace GPUVerify void AddRaceCheckingDeclarations();
- BigBlock MakeResetReadWriteSetsStatements(IToken tok);
+ BigBlock MakeResetReadWriteSetStatements(Variable v, int thread);
void AddRaceCheckingCandidateRequires(Procedure Proc);
diff --git a/Source/GPUVerify/IRegion.cs b/Source/GPUVerify/IRegion.cs new file mode 100644 index 00000000..c6655b06 --- /dev/null +++ b/Source/GPUVerify/IRegion.cs @@ -0,0 +1,18 @@ +using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Boogie;
+
+namespace GPUVerify {
+
+interface IRegion {
+ object Identifier();
+ IEnumerable<Cmd> Cmds();
+ IEnumerable<object> CmdsChildRegions();
+ IEnumerable<IRegion> SubRegions();
+ Expr Guard();
+ void AddInvariant(PredicateCmd pc);
+}
+
+}
diff --git a/Source/GPUVerify/InvariantGenerationRules/InvariantGenerationRule.cs b/Source/GPUVerify/InvariantGenerationRules/InvariantGenerationRule.cs index 1bd66785..cb2a9f41 100644 --- a/Source/GPUVerify/InvariantGenerationRules/InvariantGenerationRule.cs +++ b/Source/GPUVerify/InvariantGenerationRules/InvariantGenerationRule.cs @@ -16,7 +16,7 @@ namespace GPUVerify.InvariantGenerationRules this.verifier = verifier;
}
- public abstract void GenerateCandidates(Implementation Impl, WhileCmd wc);
+ public abstract void GenerateCandidates(Implementation Impl, IRegion region);
}
}
diff --git a/Source/GPUVerify/InvariantGenerationRules/LoopVariableBoundsInvariantGenerator.cs b/Source/GPUVerify/InvariantGenerationRules/LoopVariableBoundsInvariantGenerator.cs index af5f8d71..f73bddb6 100644 --- a/Source/GPUVerify/InvariantGenerationRules/LoopVariableBoundsInvariantGenerator.cs +++ b/Source/GPUVerify/InvariantGenerationRules/LoopVariableBoundsInvariantGenerator.cs @@ -17,15 +17,15 @@ namespace GPUVerify.InvariantGenerationRules }
- public override void GenerateCandidates(Implementation Impl, WhileCmd wc)
+ public override void GenerateCandidates(Implementation Impl, IRegion region)
{
- if (verifier.uniformityAnalyser.IsUniform(Impl.Name, wc.Guard))
+ if (verifier.uniformityAnalyser.IsUniform(Impl.Name, region.Guard()))
{
VariablesOccurringInExpressionVisitor visitor = new VariablesOccurringInExpressionVisitor();
- visitor.VisitExpr(wc.Guard);
+ visitor.VisitExpr(region.Guard());
foreach (Variable v in visitor.GetVariables())
{
- if (!verifier.ContainsNamedVariable(LoopInvariantGenerator.GetModifiedVariables(wc.Body), v.Name))
+ if (!verifier.ContainsNamedVariable(LoopInvariantGenerator.GetModifiedVariables(region), v.Name))
{
continue;
}
@@ -34,7 +34,7 @@ namespace GPUVerify.InvariantGenerationRules {
int BVWidth = (v.TypedIdent.Type as BvType).Bits;
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
verifier.MakeBVSge(
new IdentifierExpr(v.tok, v),
new LiteralExpr(v.tok, BigNum.FromInt(0), BVWidth)), "loop guard variable non-negative");
diff --git a/Source/GPUVerify/InvariantGenerationRules/PowerOfTwoInvariantGenerator.cs b/Source/GPUVerify/InvariantGenerationRules/PowerOfTwoInvariantGenerator.cs index 6b2bdc56..8b24bb0a 100644 --- a/Source/GPUVerify/InvariantGenerationRules/PowerOfTwoInvariantGenerator.cs +++ b/Source/GPUVerify/InvariantGenerationRules/PowerOfTwoInvariantGenerator.cs @@ -17,7 +17,7 @@ namespace GPUVerify.InvariantGenerationRules }
- public override void GenerateCandidates(Implementation Impl, WhileCmd wc)
+ public override void GenerateCandidates(Implementation Impl, IRegion region)
{
foreach (Variable v in Impl.LocVars)
{
@@ -26,17 +26,17 @@ namespace GPUVerify.InvariantGenerationRules {
if (verifier.mayBePowerOfTwoAnalyser.MayBePowerOfTwo(Impl.Name, basicName))
{
- if (verifier.ContainsNamedVariable(LoopInvariantGenerator.GetModifiedVariables(wc.Body), basicName))
+ if (verifier.ContainsNamedVariable(LoopInvariantGenerator.GetModifiedVariables(region), basicName))
{
- verifier.AddCandidateInvariant(wc, MakePowerOfTwoExpr(v), "pow2 disjunction");
+ verifier.AddCandidateInvariant(region, MakePowerOfTwoExpr(v), "pow2 disjunction");
for (int i = (1 << 15); i > 0; i >>= 1)
{
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
GPUVerifier.MakeBitVectorBinaryBoolean("BV32_LT",
new IdentifierExpr(v.tok, v),
new LiteralExpr(v.tok, BigNum.FromInt(i), 32)), "pow2 less than " + i);
}
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
Expr.Neq(new IdentifierExpr(v.tok, v),
new LiteralExpr(v.tok, BigNum.FromInt(0), 32)), "pow2 not zero");
}
diff --git a/Source/GPUVerify/KernelDualiser.cs b/Source/GPUVerify/KernelDualiser.cs index 49b04251..967b69ef 100644 --- a/Source/GPUVerify/KernelDualiser.cs +++ b/Source/GPUVerify/KernelDualiser.cs @@ -186,27 +186,27 @@ namespace GPUVerify else if (c is AssertCmd)
{
AssertCmd ass = c as AssertCmd;
- if (ContainsAsymmetricExpression(ass.Expr))
+ cs.Add(new AssertCmd(c.tok, new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr), ass.Attributes));
+ if (!ContainsAsymmetricExpression(ass.Expr))
{
- cs.Add(new AssertCmd(c.tok, new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr)));
- }
- else
- {
- cs.Add(new AssertCmd(c.tok, Expr.And(new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr),
- new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr))));
+ cs.Add(new AssertCmd(c.tok, new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr), ass.Attributes));
}
}
else if (c is AssumeCmd)
{
AssumeCmd ass = c as AssumeCmd;
- if (ContainsAsymmetricExpression(ass.Expr))
+ if (QKeyValue.FindBoolAttribute(ass.Attributes, "backedge"))
{
- cs.Add(new AssumeCmd(c.tok, new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr)));
+ cs.Add(new AssumeCmd(c.tok, Expr.Or(new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr),
+ new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr))));
}
else
{
- cs.Add(new AssumeCmd(c.tok, Expr.And(new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr),
- new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr))));
+ cs.Add(new AssumeCmd(c.tok, new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr)));
+ if (!ContainsAsymmetricExpression(ass.Expr))
+ {
+ cs.Add(new AssumeCmd(c.tok, new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr)));
+ }
}
}
else
@@ -268,12 +268,13 @@ namespace GPUVerify private Block MakeDual(Block b)
{
- Block result = new Block(b.tok, b.Label, new CmdSeq(), b.TransferCmd);
+ var newCmds = new CmdSeq();
foreach (Cmd c in b.Cmds)
{
- MakeDual(result.Cmds, c);
+ MakeDual(newCmds, c);
}
- return result;
+ b.Cmds = newCmds;
+ return b;
}
private List<PredicateCmd> MakeDualInvariants(List<PredicateCmd> originalInvariants)
diff --git a/Source/GPUVerify/LoopInvariantGenerator.cs b/Source/GPUVerify/LoopInvariantGenerator.cs index ead78917..936d1c44 100644 --- a/Source/GPUVerify/LoopInvariantGenerator.cs +++ b/Source/GPUVerify/LoopInvariantGenerator.cs @@ -43,153 +43,131 @@ namespace GPUVerify LocalVars.Add(v);
}
- AddCandidateInvariants(Impl.StructuredStmts, LocalVars, UserSuppliedInvariants, Impl);
+ AddCandidateInvariants(verifier.RootRegion(Impl), LocalVars, UserSuppliedInvariants, Impl);
}
- private void AddEqualityCandidateInvariant(WhileCmd wc, string LoopPredicate, Variable v)
+ private void AddEqualityCandidateInvariant(IRegion region, string LoopPredicate, Variable v)
{
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
Expr.Eq(
- new IdentifierExpr(wc.tok, new VariableDualiser(1, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable)),
- new IdentifierExpr(wc.tok, new VariableDualiser(2, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable))
+ new IdentifierExpr(Token.NoToken, new VariableDualiser(1, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable)),
+ new IdentifierExpr(Token.NoToken, new VariableDualiser(2, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable))
), "equality");
}
- private void AddPredicatedEqualityCandidateInvariant(WhileCmd wc, string LoopPredicate, Variable v)
+ private void AddPredicatedEqualityCandidateInvariant(IRegion region, string LoopPredicate, Variable v)
{
- verifier.AddCandidateInvariant(wc, Expr.Imp(
+ verifier.AddCandidateInvariant(region, Expr.Imp(
Expr.And(
- new IdentifierExpr(wc.tok, new LocalVariable(wc.tok, new TypedIdent(wc.tok, LoopPredicate + "$1", Microsoft.Boogie.Type.Int))),
- new IdentifierExpr(wc.tok, new LocalVariable(wc.tok, new TypedIdent(wc.tok, LoopPredicate + "$2", Microsoft.Boogie.Type.Int)))
+ new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, LoopPredicate + "$1", Microsoft.Boogie.Type.Int))),
+ new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, LoopPredicate + "$2", Microsoft.Boogie.Type.Int)))
),
Expr.Eq(
- new IdentifierExpr(wc.tok, new VariableDualiser(1, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable)),
- new IdentifierExpr(wc.tok, new VariableDualiser(2, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable))
+ new IdentifierExpr(Token.NoToken, new VariableDualiser(1, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable)),
+ new IdentifierExpr(Token.NoToken, new VariableDualiser(2, verifier.uniformityAnalyser, Impl.Name).VisitVariable(v.Clone() as Variable))
)), "predicated equality");
}
- private void AddBarrierDivergenceCandidates(HashSet<Variable> LocalVars, Implementation Impl, WhileCmd wc)
+ private void AddBarrierDivergenceCandidates(HashSet<Variable> LocalVars, Implementation Impl, IRegion region)
{
if (CommandLineOptions.AddDivergenceCandidatesOnlyToBarrierLoops)
{
- if (!verifier.ContainsBarrierCall(wc.Body))
+ if (!verifier.ContainsBarrierCall(region))
{
return;
}
}
- if (verifier.uniformityAnalyser.IsUniform(Impl.Name, wc.Guard))
+ Expr guard = region.Guard();
+ if (verifier.uniformityAnalyser.IsUniform(Impl.Name, guard))
{
return;
}
- Debug.Assert(wc.Guard is NAryExpr);
- Debug.Assert((wc.Guard as NAryExpr).Args.Length == 2);
- Debug.Assert((wc.Guard as NAryExpr).Args[0] is IdentifierExpr);
- string LoopPredicate = ((wc.Guard as NAryExpr).Args[0] as IdentifierExpr).Name;
-
- LoopPredicate = LoopPredicate.Substring(0, LoopPredicate.IndexOf('$'));
+ if (guard is NAryExpr &&
+ (guard as NAryExpr).Args.Length == 2 &&
+ (guard as NAryExpr).Args[0] is IdentifierExpr)
+ {
+ string LoopPredicate = ((guard as NAryExpr).Args[0] as IdentifierExpr).Name;
- verifier.AddCandidateInvariant(wc, Expr.Eq(
- // Int type used here, but it doesn't matter as we will print and then re-parse the program
- new IdentifierExpr(wc.tok, new LocalVariable(wc.tok, new TypedIdent(wc.tok, LoopPredicate + "$1", Microsoft.Boogie.Type.Int))),
- new IdentifierExpr(wc.tok, new LocalVariable(wc.tok, new TypedIdent(wc.tok, LoopPredicate + "$2", Microsoft.Boogie.Type.Int)))
- ), "loop predicate equality");
+ LoopPredicate = LoopPredicate.Substring(0, LoopPredicate.IndexOf('$'));
- foreach (Variable v in LocalVars)
- {
+ verifier.AddCandidateInvariant(region, Expr.Eq(
+ // Int type used here, but it doesn't matter as we will print and then re-parse the program
+ new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, LoopPredicate + "$1", Microsoft.Boogie.Type.Int))),
+ new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, LoopPredicate + "$2", Microsoft.Boogie.Type.Int)))
+ ), "loop predicate equality");
- if (verifier.uniformityAnalyser.IsUniform(Impl.Name, v.Name))
+ foreach (Variable v in LocalVars)
{
- continue;
- }
- string lv = GPUVerifier.StripThreadIdentifier(v.Name);
+ if (verifier.uniformityAnalyser.IsUniform(Impl.Name, v.Name))
+ {
+ continue;
+ }
- if (GPUVerifier.IsPredicateOrTemp(lv))
- {
- continue;
- }
+ string lv = GPUVerifier.StripThreadIdentifier(v.Name);
- if (CommandLineOptions.AddDivergenceCandidatesOnlyIfModified)
- {
- if (!verifier.ContainsNamedVariable(GetModifiedVariables(wc.Body),
- GPUVerifier.StripThreadIdentifier(v.Name)))
+ if (GPUVerifier.IsPredicateOrTemp(lv))
{
continue;
}
- }
- AddEqualityCandidateInvariant(wc, LoopPredicate, new LocalVariable(wc.tok, new TypedIdent(wc.tok, lv, Microsoft.Boogie.Type.Int)));
+ if (CommandLineOptions.AddDivergenceCandidatesOnlyIfModified)
+ {
+ if (!verifier.ContainsNamedVariable(GetModifiedVariables(region),
+ GPUVerifier.StripThreadIdentifier(v.Name)))
+ {
+ continue;
+ }
+ }
+
+ AddEqualityCandidateInvariant(region, LoopPredicate, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, lv, Microsoft.Boogie.Type.Int)));
- if (Impl != verifier.KernelImplementation)
- {
- AddPredicatedEqualityCandidateInvariant(wc, LoopPredicate, new LocalVariable(wc.tok, new TypedIdent(wc.tok, lv, Microsoft.Boogie.Type.Int)));
+ if (Impl != verifier.KernelImplementation)
+ {
+ AddPredicatedEqualityCandidateInvariant(region, LoopPredicate, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, lv, Microsoft.Boogie.Type.Int)));
+ }
}
- }
- if (CommandLineOptions.ArrayEqualities)
- {
- foreach (Variable v in verifier.NonLocalState.getAllNonLocalVariables())
+ if (CommandLineOptions.ArrayEqualities)
{
- if (!verifier.ArrayModelledAdversarially(v))
+ foreach (Variable v in verifier.NonLocalState.getAllNonLocalVariables())
{
- AddEqualityCandidateInvariant(wc, LoopPredicate, v);
+ if (!verifier.ArrayModelledAdversarially(v))
+ {
+ AddEqualityCandidateInvariant(region, LoopPredicate, v);
+ }
}
}
}
}
- private void AddCandidateInvariants(StmtList stmtList, HashSet<Variable> LocalVars, List<Expr> UserSuppliedInvariants, Implementation Impl)
- {
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- AddCandidateInvariants(bb, LocalVars, UserSuppliedInvariants, Impl);
- }
- }
-
- private void AddCandidateInvariants(BigBlock bb, HashSet<Variable> LocalVars, List<Expr> UserSuppliedInvariants, Implementation Impl)
+ private void AddCandidateInvariants(IRegion region, HashSet<Variable> LocalVars, List<Expr> UserSuppliedInvariants, Implementation Impl)
{
- if (bb.ec is WhileCmd)
+ foreach (IRegion subregion in region.SubRegions())
{
- WhileCmd wc = bb.ec as WhileCmd;
-
foreach (InvariantGenerationRule r in invariantGenerationRules)
{
- r.GenerateCandidates(Impl, wc);
+ r.GenerateCandidates(Impl, subregion);
}
- AddBarrierDivergenceCandidates(LocalVars, Impl, wc);
-
- verifier.RaceInstrumenter.AddRaceCheckingCandidateInvariants(Impl, wc);
+ AddBarrierDivergenceCandidates(LocalVars, Impl, subregion);
- AddUserSuppliedInvariants(wc, UserSuppliedInvariants, Impl);
-
- AddCandidateInvariants(wc.Body, LocalVars, UserSuppliedInvariants, Impl);
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
- AddCandidateInvariants(ifCmd.thn, LocalVars, UserSuppliedInvariants, Impl);
- if (ifCmd.elseBlock != null)
- {
- AddCandidateInvariants(ifCmd.elseBlock, LocalVars, UserSuppliedInvariants, Impl);
- }
+ verifier.RaceInstrumenter.AddRaceCheckingCandidateInvariants(Impl, subregion);
- }
- else
- {
- Debug.Assert(bb.ec == null);
+ AddUserSuppliedInvariants(subregion, UserSuppliedInvariants, Impl);
}
}
- private void AddUserSuppliedInvariants(WhileCmd wc, List<Expr> UserSuppliedInvariants, Implementation Impl)
+ private void AddUserSuppliedInvariants(IRegion region, List<Expr> UserSuppliedInvariants, Implementation Impl)
{
foreach (Expr e in UserSuppliedInvariants)
{
+ /*
wc.Invariants.Add(new AssertCmd(wc.tok, e));
bool OK = verifier.ProgramIsOK(Impl);
wc.Invariants.RemoveAt(wc.Invariants.Count - 1);
@@ -197,30 +175,16 @@ namespace GPUVerify {
verifier.AddCandidateInvariant(wc, e, "user supplied");
}
+ */
+ verifier.AddCandidateInvariant(region, e, "user supplied");
}
}
- internal static HashSet<Variable> GetModifiedVariables(StmtList stmtList)
- {
- HashSet<Variable> result = new HashSet<Variable>();
-
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- HashSet<Variable> resultForBlock = GetModifiedVariables(bb);
- foreach (Variable v in resultForBlock)
- {
- result.Add(v);
- }
- }
-
- return result;
- }
-
- private static HashSet<Variable> GetModifiedVariables(BigBlock bb)
+ internal static HashSet<Variable> GetModifiedVariables(IRegion region)
{
HashSet<Variable> result = new HashSet<Variable>();
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in region.Cmds())
{
VariableSeq vars = new VariableSeq();
c.AddAssignedVariables(vars);
@@ -230,34 +194,6 @@ namespace GPUVerify }
}
- if (bb.ec is WhileCmd)
- {
- HashSet<Variable> modifiedByLoop = GetModifiedVariables((bb.ec as WhileCmd).Body);
- foreach (Variable v in modifiedByLoop)
- {
- result.Add(v);
- }
- }
- else if (bb.ec is IfCmd)
- {
- HashSet<Variable> modifiedByThen = GetModifiedVariables((bb.ec as IfCmd).thn);
- foreach (Variable v in modifiedByThen)
- {
- result.Add(v);
- }
-
- if ((bb.ec as IfCmd).elseBlock != null)
- {
- HashSet<Variable> modifiedByElse = GetModifiedVariables((bb.ec as IfCmd).elseBlock);
- foreach (Variable v in modifiedByElse)
- {
- result.Add(v);
- }
- }
-
- Debug.Assert((bb.ec as IfCmd).elseIf == null);
- }
-
return result;
}
diff --git a/Source/GPUVerify/Main.cs b/Source/GPUVerify/Main.cs index c8d29282..d1fcca9e 100644 --- a/Source/GPUVerify/Main.cs +++ b/Source/GPUVerify/Main.cs @@ -129,6 +129,12 @@ namespace GPUVerify {
fn = CommandLineOptions.outputFile;
}
+ else if (CommandLineOptions.inputFiles.Count == 1)
+ {
+ var inputFile = CommandLineOptions.inputFiles[0];
+ if (Path.GetExtension(inputFile).ToLower() != ".bpl")
+ fn = Path.GetFileNameWithoutExtension(inputFile);
+ }
ResolutionContext rc;
Program program = parse(out rc);
IList<GPUVerifier> result = new List<GPUVerifier>();
diff --git a/Source/GPUVerify/MayBeFlattened2DTidOrGidAnalyser.cs b/Source/GPUVerify/MayBeFlattened2DTidOrGidAnalyser.cs deleted file mode 100644 index 3d65ec61..00000000 --- a/Source/GPUVerify/MayBeFlattened2DTidOrGidAnalyser.cs +++ /dev/null @@ -1,347 +0,0 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-using Microsoft.Boogie;
-
-namespace GPUVerify
-{
- class MayBeFlattened2DTidOrGidAnalyser
- {
- private static string[] cases = { "local", "global" };
-
- private GPUVerifier verifier;
-
- private bool ProcedureChanged;
-
- private Dictionary<string, Dictionary<string, Dictionary<string, bool>>> mayBeInfo;
-
- public MayBeFlattened2DTidOrGidAnalyser(GPUVerifier verifier)
- {
- this.verifier = verifier;
-
- mayBeInfo = new Dictionary<string,Dictionary<string,Dictionary<string,bool>>>();
- foreach (string s in cases)
- {
- mayBeInfo[s] = new Dictionary<string, Dictionary<string, bool>>();
- }
-
- }
-
- internal void Analyse()
- {
- foreach (Declaration D in verifier.Program.TopLevelDeclarations)
- {
- if(D is Implementation)
- {
- Implementation Impl = D as Implementation;
-
- foreach (string s in cases)
- {
- mayBeInfo[s][Impl.Name] = new Dictionary<string, bool>();
- }
-
- foreach (Variable v in Impl.LocVars)
- {
- foreach (string s in cases)
- {
- SetMayBe(s, Impl.Name, v.Name);
- }
- }
-
- foreach (Variable v in Impl.InParams)
- {
- foreach (string s in cases)
- {
- SetMayBe(s, Impl.Name, v.Name);
- }
- }
-
- foreach (Variable v in Impl.OutParams)
- {
- foreach (string s in cases)
- {
- SetMayBe(s, Impl.Name, v.Name);
- }
- }
-
- ProcedureChanged = true;
- }
- }
-
- while (ProcedureChanged)
- {
- ProcedureChanged = false;
-
- foreach (Declaration D in verifier.Program.TopLevelDeclarations)
- {
- if (D is Implementation)
- {
- Implementation Impl = D as Implementation;
- Analyse(Impl);
- }
- }
- }
-
- if (CommandLineOptions.ShowMayBeThreadConfigurationVariableAnalysis)
- {
- dump();
- }
- }
-
- private void Analyse(Implementation Impl)
- {
- Analyse(Impl, Impl.StructuredStmts);
- }
-
- private void Analyse(Implementation impl, StmtList stmtList)
- {
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- Analyse(impl, bb);
- }
- }
-
- private void Analyse(Implementation impl, BigBlock bb)
- {
- foreach (Cmd c in bb.simpleCmds)
- {
- if (c is AssignCmd)
- {
- foreach (string s in cases)
- {
- TransferAssign(impl, c as AssignCmd, s);
- }
- }
- else if (c is CallCmd)
- {
- foreach (string s in cases)
- {
- TransferCall(impl, c as CallCmd, s);
- }
- }
- else if (c is HavocCmd)
- {
- foreach (string s in cases)
- {
- TransferHavoc(impl, c as HavocCmd, s);
- }
- }
- }
-
- if (bb.ec is WhileCmd)
- {
- WhileCmd wc = bb.ec as WhileCmd;
- Analyse(impl, wc.Body);
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
- Analyse(impl, ifCmd.thn);
- if (ifCmd.elseBlock != null)
- {
- Analyse(impl, ifCmd.elseBlock);
- }
- Debug.Assert(ifCmd.elseIf == null);
- }
-
- }
-
- private void TransferHavoc(Implementation impl, HavocCmd havoc, string component)
- {
- Debug.Assert(havoc.Vars.Length == 1);
- if (MayBe(component, impl.Name, havoc.Vars[0].Decl.Name))
- {
- SetNot(component, impl.Name, havoc.Vars[0].Decl.Name);
- }
- }
-
- private void TransferCall(Implementation impl, CallCmd callCmd, string component)
- {
- if (callCmd.callee != verifier.BarrierProcedure.Name)
- {
-
- Implementation CalleeImplementation = verifier.GetImplementation(callCmd.callee);
- for (int i = 0; i < CalleeImplementation.InParams.Length; i++)
- {
- if (MayBe(component, callCmd.callee, CalleeImplementation.InParams[i].Name)
- && !MayBe(component, impl.Name, callCmd.Ins[i]))
- {
- SetNot(component, callCmd.callee, CalleeImplementation.InParams[i].Name);
- }
- }
-
- for (int i = 0; i < CalleeImplementation.OutParams.Length; i++)
- {
- if (MayBe(component, impl.Name, callCmd.Outs[i].Name)
- && !MayBe(component, callCmd.callee, CalleeImplementation.OutParams[i].Name))
- {
- SetNot(component, impl.Name, callCmd.Outs[i].Name);
- }
- }
-
- }
- }
-
- private void TransferAssign(Implementation impl, AssignCmd assignCmd, string component)
- {
- for (int i = 0; i != assignCmd.Lhss.Count; ++i)
- {
- if (assignCmd.Lhss[i] is SimpleAssignLhs)
- {
- SimpleAssignLhs lhs = assignCmd.Lhss[i] as SimpleAssignLhs;
- Expr rhs = assignCmd.Rhss[i];
-
- if (MayBe(component, impl.Name, lhs.AssignedVariable.Name)
- && !MayBe(component, impl.Name, rhs))
- {
- SetNot(component, impl.Name, lhs.AssignedVariable.Name);
- }
- }
- }
- }
-
- private void SetNot(string component, string proc, string v)
- {
- mayBeInfo[component][proc][v] = false;
- ProcedureChanged = true;
- }
-
- private void SetMayBe(string component, string proc, string v)
- {
- mayBeInfo[component][proc][v] = true;
- }
-
- internal bool MayBe(string component, string proc, string v)
- {
- if (!mayBeInfo[component].ContainsKey(proc))
- {
- return false;
- }
-
- if (!mayBeInfo[component][proc].ContainsKey(v))
- {
- return false;
- }
-
- return mayBeInfo[component][proc][v];
- }
-
- internal bool MayBe(string component, string proc, Expr e)
- {
- if (e is IdentifierExpr)
- {
- return MayBe(component, proc, (e as IdentifierExpr).Decl.Name);
- }
-
- if (e is NAryExpr && (e as NAryExpr).Fun.FunctionName.Equals("BV32_ADD"))
- {
- NAryExpr nary = e as NAryExpr;
-
- if (component.Equals("local"))
- {
- if (verifier.mayBeTidAnalyser.MayBe(GPUVerifier.LOCAL_ID_X_STRING, proc, nary.Args[1]))
- {
- return IsLocalIdYTimesGroupSizeX(proc, nary.Args[0]);
- }
-
- if (verifier.mayBeTidAnalyser.MayBe(GPUVerifier.LOCAL_ID_X_STRING, proc, nary.Args[0]))
- {
- return IsLocalIdYTimesGroupSizeX(proc, nary.Args[1]);
- }
- }
- else
- {
- Debug.Assert(component.Equals("global"));
- if (verifier.mayBeGidAnalyser.MayBe("x", proc, nary.Args[1]))
- {
- return IsGlobalIdYTimesGlobalSizeX(proc, nary.Args[0]);
- }
-
- if (verifier.mayBeGidAnalyser.MayBe("x", proc, nary.Args[0]))
- {
- return IsGlobalIdYTimesGlobalSizeX(proc, nary.Args[1]);
- }
- }
- }
-
- return false;
- }
-
- private bool IsLocalIdYTimesGroupSizeX(string proc, Expr expr)
- {
- if (expr is NAryExpr && (expr as NAryExpr).Fun.FunctionName.Equals("BV32_MUL"))
- {
- NAryExpr innerNary = expr as NAryExpr;
-
- if (IsLocalIdYAndGroupSizeX(proc, innerNary.Args[0], innerNary.Args[1]))
- {
- return true;
- }
-
- if (IsLocalIdYAndGroupSizeX(proc, innerNary.Args[1], innerNary.Args[0]))
- {
- return true;
- }
- }
- return false;
- }
-
- private bool IsLocalIdYAndGroupSizeX(string proc, Expr maybeLocalIdY, Expr maybeGroupSizeX)
- {
- return verifier.mayBeTidAnalyser.MayBe(GPUVerifier.LOCAL_ID_Y_STRING, proc, maybeLocalIdY) &&
- verifier.mayBeTidAnalyser.MayBe(GPUVerifier.GROUP_SIZE_X_STRING, proc, maybeGroupSizeX);
- }
-
-
- private bool IsGlobalIdYTimesGlobalSizeX(string proc, Expr expr)
- {
- if (expr is NAryExpr && (expr as NAryExpr).Fun.FunctionName.Equals("BV32_MUL"))
- {
- NAryExpr innerNary = expr as NAryExpr;
-
- if (IsGlobalIdYAndGlobalSizeX(proc, innerNary.Args[0], innerNary.Args[1]))
- {
- return true;
- }
-
- if (IsGlobalIdYAndGlobalSizeX(proc, innerNary.Args[1], innerNary.Args[0]))
- {
- return true;
- }
- }
- return false;
- }
-
- private bool IsGlobalIdYAndGlobalSizeX(string proc, Expr maybeGlobalIdY, Expr maybeGlobalSizeX)
- {
- return verifier.mayBeGidAnalyser.MayBe("y", proc, maybeGlobalIdY) &&
- verifier.mayBeGlobalSizeAnalyser.MayBe("x", proc, maybeGlobalSizeX);
- }
-
-
- private void dump()
- {
- foreach (string s in cases)
- {
- Console.WriteLine("*** flattened " + s + " id ***");
-
- foreach (string p in mayBeInfo[s].Keys)
- {
- Console.WriteLine(" Procedure " + p);
-
- foreach (string v in mayBeInfo[s][p].Keys)
- {
- if (mayBeInfo[s][p][v])
- {
- Console.WriteLine(" " + v + ": may be flattened " + s + " id");
- }
- }
- }
- }
-
- }
-
- }
-}
diff --git a/Source/GPUVerify/MayBeGidAnalyser.cs b/Source/GPUVerify/MayBeGidAnalyser.cs index 969e8935..f7d8c973 100644 --- a/Source/GPUVerify/MayBeGidAnalyser.cs +++ b/Source/GPUVerify/MayBeGidAnalyser.cs @@ -92,20 +92,12 @@ namespace GPUVerify private void Analyse(Implementation Impl)
{
- Analyse(Impl, Impl.StructuredStmts);
+ Analyse(Impl, verifier.RootRegion(Impl));
}
- private void Analyse(Implementation impl, StmtList stmtList)
+ private void Analyse(Implementation impl, IRegion region)
{
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- Analyse(impl, bb);
- }
- }
-
- private void Analyse(Implementation impl, BigBlock bb)
- {
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in region.Cmds())
{
if (c is AssignCmd)
{
@@ -129,23 +121,6 @@ namespace GPUVerify }
}
}
-
- if (bb.ec is WhileCmd)
- {
- WhileCmd wc = bb.ec as WhileCmd;
- Analyse(impl, wc.Body);
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
- Analyse(impl, ifCmd.thn);
- if (ifCmd.elseBlock != null)
- {
- Analyse(impl, ifCmd.elseBlock);
- }
- Debug.Assert(ifCmd.elseIf == null);
- }
-
}
private void TransferHavoc(Implementation impl, HavocCmd havoc, string component)
diff --git a/Source/GPUVerify/MayBeGlobalSizeAnalyser.cs b/Source/GPUVerify/MayBeGlobalSizeAnalyser.cs deleted file mode 100644 index 579f6805..00000000 --- a/Source/GPUVerify/MayBeGlobalSizeAnalyser.cs +++ /dev/null @@ -1,312 +0,0 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-using Microsoft.Boogie;
-
-namespace GPUVerify
-{
- class MayBeGlobalSizeAnalyser
- {
- private static string[] dimensions = { "x", "y", "z" };
-
- private GPUVerifier verifier;
-
- private bool ProcedureChanged;
-
- private Dictionary<string, Dictionary<string, Dictionary<string, bool>>> mayBeInfo;
-
- public MayBeGlobalSizeAnalyser(GPUVerifier verifier)
- {
- this.verifier = verifier;
-
- mayBeInfo = new Dictionary<string,Dictionary<string,Dictionary<string,bool>>>();
- foreach (string s in dimensions)
- {
- mayBeInfo[s] = new Dictionary<string, Dictionary<string, bool>>();
- }
-
- }
-
- internal void Analyse()
- {
- foreach (Declaration D in verifier.Program.TopLevelDeclarations)
- {
- if(D is Implementation)
- {
- Implementation Impl = D as Implementation;
-
- foreach (string s in dimensions)
- {
- mayBeInfo[s][Impl.Name] = new Dictionary<string, bool>();
- }
-
- foreach (Variable v in Impl.LocVars)
- {
- foreach (string s in dimensions)
- {
- SetMayBe(s, Impl.Name, v.Name);
- }
- }
-
- foreach (Variable v in Impl.InParams)
- {
- foreach (string s in dimensions)
- {
- SetMayBe(s, Impl.Name, v.Name);
- }
- }
-
- foreach (Variable v in Impl.OutParams)
- {
- foreach (string s in dimensions)
- {
- SetMayBe(s, Impl.Name, v.Name);
- }
- }
-
- ProcedureChanged = true;
- }
- }
-
- while (ProcedureChanged)
- {
- ProcedureChanged = false;
-
- foreach (Declaration D in verifier.Program.TopLevelDeclarations)
- {
- if (D is Implementation)
- {
- Implementation Impl = D as Implementation;
- Analyse(Impl);
- }
- }
- }
-
- if (CommandLineOptions.ShowMayBeThreadConfigurationVariableAnalysis)
- {
- dump();
- }
- }
-
- private void Analyse(Implementation Impl)
- {
- Analyse(Impl, Impl.StructuredStmts);
- }
-
- private void Analyse(Implementation impl, StmtList stmtList)
- {
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- Analyse(impl, bb);
- }
- }
-
- private void Analyse(Implementation impl, BigBlock bb)
- {
- foreach (Cmd c in bb.simpleCmds)
- {
- if (c is AssignCmd)
- {
- foreach (string s in dimensions)
- {
- TransferAssign(impl, c as AssignCmd, s);
- }
- }
- else if (c is CallCmd)
- {
- foreach (string s in dimensions)
- {
- TransferCall(impl, c as CallCmd, s);
- }
- }
- else if (c is HavocCmd)
- {
- foreach (string s in dimensions)
- {
- TransferHavoc(impl, c as HavocCmd, s);
- }
- }
- }
-
- if (bb.ec is WhileCmd)
- {
- WhileCmd wc = bb.ec as WhileCmd;
- Analyse(impl, wc.Body);
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
- Analyse(impl, ifCmd.thn);
- if (ifCmd.elseBlock != null)
- {
- Analyse(impl, ifCmd.elseBlock);
- }
- Debug.Assert(ifCmd.elseIf == null);
- }
-
- }
-
- private void TransferHavoc(Implementation impl, HavocCmd havoc, string component)
- {
- Debug.Assert(havoc.Vars.Length == 1);
- if (MayBe(component, impl.Name, havoc.Vars[0].Decl.Name))
- {
- SetNot(component, impl.Name, havoc.Vars[0].Decl.Name);
- }
- }
-
- private void TransferCall(Implementation impl, CallCmd callCmd, string component)
- {
- if (callCmd.callee != verifier.BarrierProcedure.Name)
- {
-
- Implementation CalleeImplementation = verifier.GetImplementation(callCmd.callee);
- for (int i = 0; i < CalleeImplementation.InParams.Length; i++)
- {
- if (MayBe(component, callCmd.callee, CalleeImplementation.InParams[i].Name)
- && !MayBe(component, impl.Name, callCmd.Ins[i]))
- {
- SetNot(component, callCmd.callee, CalleeImplementation.InParams[i].Name);
- }
- }
-
- for (int i = 0; i < CalleeImplementation.OutParams.Length; i++)
- {
- if (MayBe(component, impl.Name, callCmd.Outs[i].Name)
- && !MayBe(component, callCmd.callee, CalleeImplementation.OutParams[i].Name))
- {
- SetNot(component, impl.Name, callCmd.Outs[i].Name);
- }
- }
-
- }
- }
-
- private void TransferAssign(Implementation impl, AssignCmd assignCmd, string component)
- {
- for (int i = 0; i != assignCmd.Lhss.Count; ++i)
- {
- if (assignCmd.Lhss[i] is SimpleAssignLhs)
- {
- SimpleAssignLhs lhs = assignCmd.Lhss[i] as SimpleAssignLhs;
- Expr rhs = assignCmd.Rhss[i];
-
- if (MayBe(component, impl.Name, lhs.AssignedVariable.Name)
- && !MayBe(component, impl.Name, rhs))
- {
- SetNot(component, impl.Name, lhs.AssignedVariable.Name);
- }
- }
- }
- }
-
- private void SetNot(string component, string proc, string v)
- {
- mayBeInfo[component][proc][v] = false;
- ProcedureChanged = true;
- }
-
- private void SetMayBe(string component, string proc, string v)
- {
- mayBeInfo[component][proc][v] = true;
- }
-
- internal bool MayBe(string component, string proc, string v)
- {
- if (!mayBeInfo[component].ContainsKey(proc))
- {
- return false;
- }
-
- if (!mayBeInfo[component][proc].ContainsKey(v))
- {
- return false;
- }
-
- return mayBeInfo[component][proc][v];
- }
-
- internal bool MayBe(string component, string proc, Expr e)
- {
- if (e is IdentifierExpr)
- {
- return MayBe(component, proc, (e as IdentifierExpr).Decl.Name);
- }
-
- return IsNumGroupsTimesGroupSize(component, proc, e);
-
- }
-
- private bool IsNumGroupsTimesGroupSize(string component, string proc, Expr expr)
- {
- if (expr is NAryExpr && (expr as NAryExpr).Fun.FunctionName.Equals("BV32_MUL"))
- {
- NAryExpr innerNary = expr as NAryExpr;
-
- if (IsNumGroupsAndGroupSize(component, proc, innerNary.Args[0], innerNary.Args[1]))
- {
- return true;
- }
-
- if (IsNumGroupsAndGroupSize(component, proc, innerNary.Args[1], innerNary.Args[0]))
- {
- return true;
- }
- }
- return false;
- }
-
- private bool IsNumGroupsAndGroupSize(string component, string proc, Expr maybeNumGroups, Expr maybeGroupSize)
- {
- string numGroupsString = null;
- string groupSizeString = null;
- if (component.Equals("x"))
- {
- numGroupsString = GPUVerifier.NUM_GROUPS_X_STRING;
- groupSizeString = GPUVerifier.GROUP_SIZE_X_STRING;
- }
- else if (component.Equals("y"))
- {
- numGroupsString = GPUVerifier.NUM_GROUPS_Y_STRING;
- groupSizeString = GPUVerifier.GROUP_SIZE_Y_STRING;
- }
- else if (component.Equals("z"))
- {
- numGroupsString = GPUVerifier.NUM_GROUPS_Z_STRING;
- groupSizeString = GPUVerifier.GROUP_SIZE_Z_STRING;
- }
- else
- {
- Debug.Assert(false);
- }
-
- return verifier.mayBeTidAnalyser.MayBe(numGroupsString, proc, maybeNumGroups) &&
- verifier.mayBeTidAnalyser.MayBe(groupSizeString, proc, maybeGroupSize);
- }
-
- private void dump()
- {
- foreach (string s in dimensions)
- {
- Console.WriteLine("*** global_size_" + s + " ***");
-
- foreach (string p in mayBeInfo[s].Keys)
- {
- Console.WriteLine(" Procedure " + p);
-
- foreach (string v in mayBeInfo[s][p].Keys)
- {
- if (mayBeInfo[s][p][v])
- {
- Console.WriteLine(" " + v + ": may be global_size_" + s);
- }
- }
- }
- }
-
- }
-
- }
-}
diff --git a/Source/GPUVerify/MayBeIdPlusConstantAnalyser.cs b/Source/GPUVerify/MayBeIdPlusConstantAnalyser.cs index a8563dfa..a57f35ee 100644 --- a/Source/GPUVerify/MayBeIdPlusConstantAnalyser.cs +++ b/Source/GPUVerify/MayBeIdPlusConstantAnalyser.cs @@ -79,21 +79,12 @@ namespace GPUVerify private void Analyse(Implementation Impl)
{
- Analyse(Impl, Impl.StructuredStmts);
+ Analyse(Impl, verifier.RootRegion(Impl));
}
- private void Analyse(Implementation impl, StmtList stmtList)
+ private void Analyse(Implementation impl, IRegion region)
{
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- Analyse(impl, bb);
- }
- }
-
-
- private void Analyse(Implementation impl, BigBlock bb)
- {
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in region.Cmds())
{
if (c is AssignCmd)
{
@@ -135,23 +126,6 @@ namespace GPUVerify }
}
}
-
- if (bb.ec is WhileCmd)
- {
- WhileCmd wc = bb.ec as WhileCmd;
- Analyse(impl, wc.Body);
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
- Analyse(impl, ifCmd.thn);
- if (ifCmd.elseBlock != null)
- {
- Analyse(impl, ifCmd.elseBlock);
- }
- Debug.Assert(ifCmd.elseIf == null);
- }
-
}
private string ConvertToString(Expr constantIncrement)
diff --git a/Source/GPUVerify/MayBePowerOfTwoAnalyser.cs b/Source/GPUVerify/MayBePowerOfTwoAnalyser.cs index 506add7c..c0f00dda 100644 --- a/Source/GPUVerify/MayBePowerOfTwoAnalyser.cs +++ b/Source/GPUVerify/MayBePowerOfTwoAnalyser.cs @@ -67,20 +67,12 @@ namespace GPUVerify private void Analyse(Implementation Impl)
{
- Analyse(Impl, Impl.StructuredStmts);
+ Analyse(Impl, verifier.RootRegion(Impl));
}
- private void Analyse(Implementation impl, StmtList stmtList)
+ private void Analyse(Implementation impl, IRegion region)
{
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- Analyse(impl, bb);
- }
- }
-
- private void Analyse(Implementation impl, BigBlock bb)
- {
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in region.Cmds())
{
if (c is AssignCmd)
{
@@ -102,23 +94,6 @@ namespace GPUVerify }
}
}
-
- if (bb.ec is WhileCmd)
- {
- WhileCmd wc = bb.ec as WhileCmd;
- Analyse(impl, wc.Body);
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
- Analyse(impl, ifCmd.thn);
- if (ifCmd.elseBlock != null)
- {
- Analyse(impl, ifCmd.elseBlock);
- }
- Debug.Assert(ifCmd.elseIf == null);
- }
-
}
private bool isPowerOfTwoOperation(Variable v, Expr expr)
diff --git a/Source/GPUVerify/MayBeThreadConfigurationVariableAnalyser.cs b/Source/GPUVerify/MayBeThreadConfigurationVariableAnalyser.cs index 53efbea8..d445d422 100644 --- a/Source/GPUVerify/MayBeThreadConfigurationVariableAnalyser.cs +++ b/Source/GPUVerify/MayBeThreadConfigurationVariableAnalyser.cs @@ -127,20 +127,12 @@ namespace GPUVerify private void Analyse(Implementation Impl)
{
- Analyse(Impl, Impl.StructuredStmts);
+ Analyse(Impl, verifier.RootRegion(Impl));
}
- private void Analyse(Implementation impl, StmtList stmtList)
+ private void Analyse(Implementation impl, IRegion region)
{
- foreach (BigBlock bb in stmtList.BigBlocks)
- {
- Analyse(impl, bb);
- }
- }
-
- private void Analyse(Implementation impl, BigBlock bb)
- {
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in region.Cmds())
{
if (c is AssignCmd)
{
@@ -164,23 +156,6 @@ namespace GPUVerify }
}
}
-
- if (bb.ec is WhileCmd)
- {
- WhileCmd wc = bb.ec as WhileCmd;
- Analyse(impl, wc.Body);
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
- Analyse(impl, ifCmd.thn);
- if (ifCmd.elseBlock != null)
- {
- Analyse(impl, ifCmd.elseBlock);
- }
- Debug.Assert(ifCmd.elseIf == null);
- }
-
}
private void TransferHavoc(Implementation impl, HavocCmd havoc, string component)
diff --git a/Source/GPUVerify/NullRaceInstrumenter.cs b/Source/GPUVerify/NullRaceInstrumenter.cs index 73f038fb..acba7ca6 100644 --- a/Source/GPUVerify/NullRaceInstrumenter.cs +++ b/Source/GPUVerify/NullRaceInstrumenter.cs @@ -9,7 +9,7 @@ namespace GPUVerify class NullRaceInstrumenter : IRaceInstrumenter
{
- public void AddRaceCheckingCandidateInvariants(Implementation impl, Microsoft.Boogie.WhileCmd wc)
+ public void AddRaceCheckingCandidateInvariants(Implementation impl, IRegion region)
{
}
@@ -24,9 +24,9 @@ namespace GPUVerify return true;
}
- public Microsoft.Boogie.BigBlock MakeResetReadWriteSetsStatements(Microsoft.Boogie.IToken tok)
+ public Microsoft.Boogie.BigBlock MakeResetReadWriteSetStatements(Variable v, int Thread)
{
- return new BigBlock(tok, "__ResetReadWriteSets", new CmdSeq(), null, null);
+ return new BigBlock(Token.NoToken, null, new CmdSeq(), null, null);
}
public void AddRaceCheckingCandidateRequires(Procedure Proc)
diff --git a/Source/GPUVerify/RaceInstrumenterBase.cs b/Source/GPUVerify/RaceInstrumenterBase.cs index a0c4b5f7..5155b192 100644 --- a/Source/GPUVerify/RaceInstrumenterBase.cs +++ b/Source/GPUVerify/RaceInstrumenterBase.cs @@ -48,7 +48,7 @@ namespace GPUVerify protected abstract void AddRequiresNoPendingAccess(Variable v);
- private void AddNoReadOrWriteCandidateInvariants(WhileCmd wc, Variable v)
+ private void AddNoReadOrWriteCandidateInvariants(IRegion region, Variable v)
{
// Reasoning: if READ_HAS_OCCURRED_v is not in the modifies set for the
// loop then there is no point adding an invariant
@@ -63,18 +63,18 @@ namespace GPUVerify //
// The same reasoning applies for WRITE
- if (verifier.ContainsBarrierCall(wc.Body))
+ if (verifier.ContainsBarrierCall(region))
{
if (verifier.ContainsNamedVariable(
- LoopInvariantGenerator.GetModifiedVariables(wc.Body), GPUVerifier.MakeAccessHasOccurredVariableName(v.Name, "READ")))
+ LoopInvariantGenerator.GetModifiedVariables(region), GPUVerifier.MakeAccessHasOccurredVariableName(v.Name, "READ")))
{
- AddNoReadOrWriteCandidateInvariant(wc, v, "READ");
+ AddNoReadOrWriteCandidateInvariant(region, v, "READ");
}
if (verifier.ContainsNamedVariable(
- LoopInvariantGenerator.GetModifiedVariables(wc.Body), GPUVerifier.MakeAccessHasOccurredVariableName(v.Name, "WRITE")))
+ LoopInvariantGenerator.GetModifiedVariables(region), GPUVerifier.MakeAccessHasOccurredVariableName(v.Name, "WRITE")))
{
- AddNoReadOrWriteCandidateInvariant(wc, v, "WRITE");
+ AddNoReadOrWriteCandidateInvariant(region, v, "WRITE");
}
}
}
@@ -91,47 +91,47 @@ namespace GPUVerify AddNoReadOrWriteCandidateEnsures(Proc, v, "WRITE", "1");
}
- private void AddNoReadOrWriteCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite)
+ private void AddNoReadOrWriteCandidateInvariant(IRegion region, Variable v, string ReadOrWrite)
{
Expr candidate = NoReadOrWriteExpr(v, ReadOrWrite, "1");
- verifier.AddCandidateInvariant(wc, candidate, "no " + ReadOrWrite.ToLower());
+ verifier.AddCandidateInvariant(region, candidate, "no " + ReadOrWrite.ToLower());
}
- public void AddRaceCheckingCandidateInvariants(Implementation impl, WhileCmd wc)
+ public void AddRaceCheckingCandidateInvariants(Implementation impl, IRegion region)
{
foreach (Variable v in NonLocalStateToCheck.getAllNonLocalVariables())
{
- AddNoReadOrWriteCandidateInvariants(wc, v);
- AddReadOrWrittenOffsetIsThreadIdCandidateInvariants(impl, wc, v, "READ");
- AddReadOrWrittenOffsetIsThreadIdCandidateInvariants(impl, wc, v, "WRITE");
- AddGroupStrideAccessCandidateInvariants(impl, wc, v, "READ");
- AddGroupStrideAccessCandidateInvariants(impl, wc, v, "WRITE");
+ AddNoReadOrWriteCandidateInvariants(region, v);
+ AddReadOrWrittenOffsetIsThreadIdCandidateInvariants(impl, region, v, "READ");
+ AddReadOrWrittenOffsetIsThreadIdCandidateInvariants(impl, region, v, "WRITE");
+ AddGroupStrideAccessCandidateInvariants(impl, region, v, "READ");
+ AddGroupStrideAccessCandidateInvariants(impl, region, v, "WRITE");
}
}
- private void AddGroupStrideAccessCandidateInvariants(Implementation impl, WhileCmd wc, Variable v, string accessKind)
+ private void AddGroupStrideAccessCandidateInvariants(Implementation impl, IRegion region, Variable v, string accessKind)
{
- foreach (Expr e in GetOffsetsAccessed(wc.Body, v, accessKind))
+ foreach (Expr e in GetOffsetsAccessed(region, v, accessKind))
{
- if (TryGenerateCandidateForDirectStridedAccess(impl, wc, v, e, accessKind))
+ if (TryGenerateCandidateForDirectStridedAccess(impl, region, v, e, accessKind))
{
continue;
}
- if (!TryGenerateCandidateForReducedStrengthStrideVariable(impl, wc, v, e, accessKind))
+ if (!TryGenerateCandidateForReducedStrengthStrideVariable(impl, region, v, e, accessKind))
{
if (e is IdentifierExpr)
{
- foreach(Expr f in GetExpressionsFromWhichVariableIsAssignedInLoop(wc.Body, (e as IdentifierExpr).Decl))
+ foreach(Expr f in GetExpressionsFromWhichVariableIsAssignedInLoop(region, (e as IdentifierExpr).Decl))
{
- TryGenerateCandidateForReducedStrengthStrideVariable(impl, wc, v, f, accessKind);
+ TryGenerateCandidateForReducedStrengthStrideVariable(impl, region, v, f, accessKind);
}
}
}
}
}
- private bool TryGenerateCandidateForDirectStridedAccess(Implementation impl, WhileCmd wc, Variable v, Expr e, string accessKind)
+ private bool TryGenerateCandidateForDirectStridedAccess(Implementation impl, IRegion region, Variable v, Expr e, string accessKind)
{
if (!(e is NAryExpr))
{
@@ -157,7 +157,7 @@ namespace GPUVerify new IdentifierExpr(Token.NoToken, GPUVerifier.MakeAccessHasOccurredVariable(v.Name, accessKind)),
modPow2Expr);
- AddAccessRelatedCandidateInvariant(wc, accessKind, candidateInvariantExpr, impl.Name, "direct stride local");
+ AddAccessRelatedCandidateInvariant(region, accessKind, candidateInvariantExpr, impl.Name, "direct stride local");
return true;
}
}
@@ -173,7 +173,7 @@ namespace GPUVerify new IdentifierExpr(Token.NoToken, GPUVerifier.MakeAccessHasOccurredVariable(v.Name, accessKind)),
modPow2Expr);
- AddAccessRelatedCandidateInvariant(wc, accessKind, candidateInvariantExpr, impl.Name, "direct stride global");
+ AddAccessRelatedCandidateInvariant(region, accessKind, candidateInvariantExpr, impl.Name, "direct stride global");
return true;
}
}
@@ -182,10 +182,10 @@ namespace GPUVerify }
- private void AddAccessRelatedCandidateInvariant(WhileCmd wc, string accessKind, Expr candidateInvariantExpr, string procName, string tag)
+ private void AddAccessRelatedCandidateInvariant(IRegion region, string accessKind, Expr candidateInvariantExpr, string procName, string tag)
{
Expr candidate = new VariableDualiser(1, verifier.uniformityAnalyser, procName).VisitExpr(candidateInvariantExpr.Clone() as Expr);
- verifier.AddCandidateInvariant(wc, candidate, tag);
+ verifier.AddCandidateInvariant(region, candidate, tag);
}
private Expr IsIdPlusConstantMultiple(Expr arg1, Expr arg2, bool local, Implementation impl)
@@ -248,20 +248,20 @@ namespace GPUVerify return verifier.mayBeGidAnalyser.MayBe("x", impl.Name, mayBeId);
}
- private bool TryGenerateCandidateForReducedStrengthStrideVariable(Implementation impl, WhileCmd wc, Variable v, Expr e, string accessKind)
+ private bool TryGenerateCandidateForReducedStrengthStrideVariable(Implementation impl, IRegion region, Variable v, Expr e, string accessKind)
{
foreach (string w in
verifier.mayBeTidPlusConstantAnalyser.GetMayBeIdPlusConstantVars(impl.Name))
{
if (!verifier.ContainsNamedVariable(
- LoopInvariantGenerator.GetModifiedVariables(wc.Body), w))
+ LoopInvariantGenerator.GetModifiedVariables(region), w))
{
continue;
}
// Check also live
- if (GenerateModIdInvariants(impl, wc, v, e, accessKind, w, verifier.mayBeTidPlusConstantAnalyser))
+ if (GenerateModIdInvariants(impl, region, v, e, accessKind, w, verifier.mayBeTidPlusConstantAnalyser))
{
return true;
}
@@ -272,14 +272,14 @@ namespace GPUVerify verifier.mayBeGidPlusConstantAnalyser.GetMayBeIdPlusConstantVars(impl.Name))
{
if (!verifier.ContainsNamedVariable(
- LoopInvariantGenerator.GetModifiedVariables(wc.Body), w))
+ LoopInvariantGenerator.GetModifiedVariables(region), w))
{
continue;
}
// Check also live
- if (GenerateModIdInvariants(impl, wc, v, e, accessKind, w, verifier.mayBeGidPlusConstantAnalyser))
+ if (GenerateModIdInvariants(impl, region, v, e, accessKind, w, verifier.mayBeGidPlusConstantAnalyser))
{
return true;
}
@@ -290,7 +290,7 @@ namespace GPUVerify return false;
}
- private bool GenerateModIdInvariants(Implementation impl, WhileCmd wc, Variable v, Expr e, string accessKind,
+ private bool GenerateModIdInvariants(Implementation impl, IRegion region, Variable v, Expr e, string accessKind,
string w, MayBeIdPlusConstantAnalyser mayBeIdPlusConstantAnalyser)
{
if (!IsLinearFunctionOfVariable(e, w))
@@ -300,17 +300,17 @@ namespace GPUVerify Debug.Assert(!verifier.uniformityAnalyser.IsUniform(impl.Name, w));
- Variable wVariable = new LocalVariable(wc.tok, new TypedIdent(wc.tok, w,
+ Variable wVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, w,
Microsoft.Boogie.Type.GetBvType(32)));
Expr indexModPow2EqualsId = ExprModPow2EqualsId(
- new IdentifierExpr(wc.tok, wVariable),
+ new IdentifierExpr(Token.NoToken, wVariable),
mayBeIdPlusConstantAnalyser.GetIncrement(impl.Name, w), mayBeIdPlusConstantAnalyser.MakeIdExpr());
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
new VariableDualiser(1, verifier.uniformityAnalyser, impl.Name).VisitExpr(indexModPow2EqualsId.Clone() as Expr),
"is " + mayBeIdPlusConstantAnalyser.idKind() + " plus constant multiple");
- verifier.AddCandidateInvariant(wc,
+ verifier.AddCandidateInvariant(region,
new VariableDualiser(2, verifier.uniformityAnalyser, impl.Name).VisitExpr(indexModPow2EqualsId.Clone() as Expr),
"is " + mayBeIdPlusConstantAnalyser.idKind() + " plus constant multiple");
@@ -325,29 +325,16 @@ namespace GPUVerify new IdentifierExpr(Token.NoToken, GPUVerifier.MakeAccessHasOccurredVariable(v.Name, accessKind)),
invertedOffsetModPow2EqualsId);
- AddAccessRelatedCandidateInvariant(wc, accessKind, candidateInvariantExpr, impl.Name, "accessed offset is "
+ AddAccessRelatedCandidateInvariant(region, accessKind, candidateInvariantExpr, impl.Name, "accessed offset is "
+ mayBeIdPlusConstantAnalyser.idKind() + " plus constant multiple");
return true;
}
- private HashSet<Expr> GetExpressionsFromWhichVariableIsAssignedInLoop(StmtList stmts, Variable variable)
+ private HashSet<Expr> GetExpressionsFromWhichVariableIsAssignedInLoop(IRegion region, Variable variable)
{
HashSet<Expr> result = new HashSet<Expr>();
- foreach (BigBlock bb in stmts.BigBlocks)
- {
- foreach (Expr e in GetExpressionsFromWhichVariableIsAssignedInLoop(bb, variable))
- {
- result.Add(e);
- }
- }
- return result;
- }
-
- private HashSet<Expr> GetExpressionsFromWhichVariableIsAssignedInLoop(BigBlock bb, Variable variable)
- {
- HashSet<Expr> result = new HashSet<Expr>();
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in region.Cmds())
{
if (c is AssignCmd)
{
@@ -370,34 +357,6 @@ namespace GPUVerify }
}
- if (bb.ec is WhileCmd)
- {
- foreach (Expr e in GetExpressionsFromWhichVariableIsAssignedInLoop((bb.ec as WhileCmd).Body, variable))
- {
- result.Add(e);
- }
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
-
- foreach (Expr e in GetExpressionsFromWhichVariableIsAssignedInLoop(ifCmd.thn, variable))
- {
- result.Add(e);
- }
-
- Debug.Assert(ifCmd.elseIf == null);
-
- if (ifCmd.elseBlock != null)
- {
- foreach (Expr e in GetExpressionsFromWhichVariableIsAssignedInLoop(ifCmd.elseBlock, variable))
- {
- result.Add(e);
- }
- }
-
- }
-
return result;
}
@@ -491,66 +450,34 @@ namespace GPUVerify return !visitor.found;
}
- private void AddReadOrWrittenOffsetIsThreadIdCandidateInvariants(Implementation impl, WhileCmd wc, Variable v, string accessType)
+ private void AddReadOrWrittenOffsetIsThreadIdCandidateInvariants(Implementation impl, IRegion region, Variable v, string accessType)
{
+ var offsets = GetOffsetsAccessed(region, v, accessType)
+ .Select(ofs => verifier.varDefAnalyses[impl].SubstDualisedDefinitions(ofs, 1, impl.Name))
+ .ToList();
- foreach (Expr e in GetOffsetsAccessed(wc.Body, v, accessType))
- {
- if (verifier.mayBeTidAnalyser.MayBe(GPUVerifier.LOCAL_ID_X_STRING, impl.Name, GPUVerifier.StripThreadIdentifiers(e)))
- {
- AddAccessedOffsetIsThreadLocalIdCandidateInvariant(wc, v, accessType);
- // No point adding it multiple times
- break;
- }
- }
-
- foreach (Expr e in GetOffsetsAccessed(wc.Body, v, accessType))
- {
- if (verifier.mayBeGidAnalyser.MayBe("x", impl.Name, GPUVerifier.StripThreadIdentifiers(e)))
- {
- AddAccessedOffsetIsThreadGlobalIdCandidateInvariant(wc, v, accessType);
- // No point adding it multiple times
- break;
- }
- }
-
- foreach (Expr e in GetOffsetsAccessed(wc.Body, v, accessType))
- {
- if (verifier.mayBeFlattened2DTidOrGidAnalyser.MayBe("local", impl.Name, GPUVerifier.StripThreadIdentifiers(e)))
- {
- AddAccessedOffsetIsThreadFlattened2DLocalIdCandidateInvariant(wc, v, accessType);
- // No point adding it multiple times
- break;
- }
- }
-
- foreach (Expr e in GetOffsetsAccessed(wc.Body, v, accessType))
+ if (!offsets.Contains(null))
{
- if (verifier.mayBeFlattened2DTidOrGidAnalyser.MayBe("global", impl.Name, GPUVerifier.StripThreadIdentifiers(e)))
- {
- AddAccessedOffsetIsThreadFlattened2DGlobalIdCandidateInvariant(wc, v, accessType);
- // No point adding it multiple times
- break;
- }
+ AddAccessedOffsetsAreConstantCandidateInvariant(region, v, offsets, accessType);
}
- KeyValuePair<IdentifierExpr, Expr> iLessThanC = GetILessThanC(wc.Guard);
+ KeyValuePair<IdentifierExpr, Expr> iLessThanC = GetILessThanC(region.Guard());
if (iLessThanC.Key != null)
{
- foreach (Expr e in GetOffsetsAccessed(wc.Body, v, accessType))
+ foreach (Expr e in GetOffsetsAccessed(region, v, accessType))
{
if(HasFormIPlusLocalIdTimesC(e, iLessThanC, impl))
{
- AddAccessedOffsetInRangeCTimesLocalIdToCTimesLocalIdPlusC(wc, v, iLessThanC.Value, accessType);
+ AddAccessedOffsetInRangeCTimesLocalIdToCTimesLocalIdPlusC(region, v, iLessThanC.Value, accessType);
break;
}
}
- foreach (Expr e in GetOffsetsAccessed(wc.Body, v, accessType))
+ foreach (Expr e in GetOffsetsAccessed(region, v, accessType))
{
if (HasFormIPlusGlobalIdTimesC(e, iLessThanC, impl))
{
- AddAccessedOffsetInRangeCTimesGlobalIdToCTimesGlobalIdPlusC(wc, v, iLessThanC.Value, accessType);
+ AddAccessedOffsetInRangeCTimesGlobalIdToCTimesGlobalIdPlusC(region, v, iLessThanC.Value, accessType);
break;
}
}
@@ -721,17 +648,11 @@ namespace GPUVerify AddAccessedOffsetIsThreadLocalIdCandidateEnsures(Proc, v, "READ", 1);
}
- protected abstract void AddAccessedOffsetIsThreadLocalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite);
-
- protected abstract void AddAccessedOffsetIsThreadGlobalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite);
+ protected abstract void AddAccessedOffsetInRangeCTimesLocalIdToCTimesLocalIdPlusC(IRegion region, Variable v, Expr constant, string ReadOrWrite);
- protected abstract void AddAccessedOffsetIsThreadFlattened2DLocalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite);
+ protected abstract void AddAccessedOffsetInRangeCTimesGlobalIdToCTimesGlobalIdPlusC(IRegion region, Variable v, Expr constant, string ReadOrWrite);
- protected abstract void AddAccessedOffsetIsThreadFlattened2DGlobalIdCandidateInvariant(WhileCmd wc, Variable v, string ReadOrWrite);
-
- protected abstract void AddAccessedOffsetInRangeCTimesLocalIdToCTimesLocalIdPlusC(WhileCmd wc, Variable v, Expr constant, string ReadOrWrite);
-
- protected abstract void AddAccessedOffsetInRangeCTimesGlobalIdToCTimesGlobalIdPlusC(WhileCmd wc, Variable v, Expr constant, string ReadOrWrite);
+ protected abstract void AddAccessedOffsetsAreConstantCandidateInvariant(IRegion region, Variable v, IEnumerable<Expr> offsets, string ReadOrWrite);
protected abstract void AddAccessedOffsetIsThreadLocalIdCandidateRequires(Procedure Proc, Variable v, string ReadOrWrite, int Thread);
@@ -877,7 +798,7 @@ namespace GPUVerify logAccessCallCmd.Proc = logProcedure;
- cs.Add(logAccessCallCmd);
+ result.Add(logAccessCallCmd);
}
}
@@ -914,7 +835,7 @@ namespace GPUVerify logAccessCallCmd.Proc = logProcedure;
- cs.Add(logAccessCallCmd);
+ result.Add(logAccessCallCmd);
addedLogWrite = true;
@@ -971,25 +892,30 @@ namespace GPUVerify protected abstract void AddLogAccessProcedure(Variable v, string ReadOrWrite);
- public BigBlock MakeResetReadWriteSetsStatements(IToken tok)
+ public BigBlock MakeResetReadWriteSetStatements(Variable v, int Thread)
{
- BigBlock result = new BigBlock(tok, "__ResetReadWriteSets", new CmdSeq(), null, null);
+ BigBlock result = new BigBlock(Token.NoToken, null, new CmdSeq(), null, null);
+ if (Thread == 2)
+ {
+ return result;
+ }
- foreach (Variable v in NonLocalStateToCheck.getAllNonLocalVariables())
+ Expr ResetReadAssumeGuard = Expr.Not(new IdentifierExpr(Token.NoToken,
+ new VariableDualiser(1, null, null).VisitVariable(GPUVerifier.MakeAccessHasOccurredVariable(v.Name, "READ"))));
+ Expr ResetWriteAssumeGuard = Expr.Not(new IdentifierExpr(Token.NoToken,
+ new VariableDualiser(1, null, null).VisitVariable(GPUVerifier.MakeAccessHasOccurredVariable(v.Name, "WRITE"))));
+
+ if (CommandLineOptions.InterGroupRaceChecking && verifier.NonLocalState.getGlobalVariables().Contains(v))
{
- SetNoAccessOccurred(tok, result, v);
+ ResetReadAssumeGuard = Expr.Imp(verifier.ThreadsInSameGroup(), ResetReadAssumeGuard);
+ ResetWriteAssumeGuard = Expr.Imp(verifier.ThreadsInSameGroup(), ResetWriteAssumeGuard);
}
- return result;
- }
- private void SetNoAccessOccurred(IToken tok, BigBlock bb, Variable v)
- {
- SetNoAccessOccurred(tok, bb, v, "READ");
- SetNoAccessOccurred(tok, bb, v, "WRITE");
+ result.simpleCmds.Add(new AssumeCmd(Token.NoToken, ResetReadAssumeGuard));
+ result.simpleCmds.Add(new AssumeCmd(Token.NoToken, ResetWriteAssumeGuard));
+ return result;
}
- protected abstract void SetNoAccessOccurred(IToken tok, BigBlock bb, Variable v, string AccessType);
-
protected Procedure MakeLogAccessProcedureHeader(Variable v, string ReadOrWrite)
{
VariableSeq inParams = new VariableSeq();
@@ -1049,24 +975,11 @@ namespace GPUVerify protected abstract Expr NoReadOrWriteExpr(Variable v, string ReadOrWrite, string OneOrTwo);
- private HashSet<Expr> GetOffsetsAccessed(StmtList stmts, Variable v, string AccessType)
- {
- HashSet<Expr> result = new HashSet<Expr> ();
- foreach (BigBlock bb in stmts.BigBlocks)
- {
- foreach (Expr e in GetOffsetsAccessed(bb, v, AccessType))
- {
- result.Add(e);
- }
- }
- return result;
- }
-
- private HashSet<Expr> GetOffsetsAccessed(BigBlock bb, Variable v, string AccessType)
+ private HashSet<Expr> GetOffsetsAccessed(IRegion region, Variable v, string AccessType)
{
HashSet<Expr> result = new HashSet<Expr>();
- foreach (Cmd c in bb.simpleCmds)
+ foreach (Cmd c in region.Cmds())
{
if (c is CallCmd)
{
@@ -1076,48 +989,27 @@ namespace GPUVerify {
// Ins[0] is thread 1's predicate,
// Ins[1] is the offset to be read
- // Ins[1] has the form BV32_ADD(offset#construct...(P), offset)
- // We are looking for the second parameter to this BV32_ADD
+ // If Ins[1] has the form BV32_ADD(offset#construct...(P), offset),
+ // we are looking for the second parameter to this BV32_ADD
Expr offset = call.Ins[1];
- Debug.Assert(offset is NAryExpr);
- Debug.Assert((offset as NAryExpr).Fun.FunctionName == "BV32_ADD");
- result.Add((offset as NAryExpr).Args[1]);
+ if (offset is NAryExpr)
+ {
+ var nExpr = (NAryExpr)offset;
+ if (nExpr.Fun.FunctionName == "BV32_ADD" &&
+ nExpr.Args[0] is NAryExpr)
+ {
+ var n0Expr = (NAryExpr)nExpr.Args[0];
+ if (n0Expr.Fun.FunctionName.StartsWith("offset#"))
+ offset = nExpr.Args[1];
+ }
+ }
+ result.Add(offset);
}
}
}
- if (bb.ec is WhileCmd)
- {
- HashSet<Expr> bodyResult = GetOffsetsAccessed((bb.ec as WhileCmd).Body, v, AccessType);
- foreach (Expr e in bodyResult)
- {
- result.Add(e);
- }
- }
- else if (bb.ec is IfCmd)
- {
- IfCmd ifCmd = bb.ec as IfCmd;
-
- HashSet<Expr> thenResult = GetOffsetsAccessed(ifCmd.thn, v, AccessType);
- foreach (Expr e in thenResult)
- {
- result.Add(e);
- }
-
- Debug.Assert(ifCmd.elseIf == null);
-
- if(ifCmd.elseBlock != null)
- {
- HashSet<Expr> elseResult = GetOffsetsAccessed(ifCmd.elseBlock, v, AccessType);
- foreach (Expr e in elseResult)
- {
- result.Add(e);
- }
- }
- }
-
return result;
}
diff --git a/Source/GPUVerify/StructuredRegion.cs b/Source/GPUVerify/StructuredRegion.cs new file mode 100644 index 00000000..366682e0 --- /dev/null +++ b/Source/GPUVerify/StructuredRegion.cs @@ -0,0 +1,121 @@ +using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Boogie;
+
+namespace GPUVerify {
+
+class StructuredRegion : IRegion {
+ Implementation impl;
+ WhileCmd cmd;
+
+ public StructuredRegion(Implementation impl) {
+ this.impl = impl;
+ }
+
+ public StructuredRegion(WhileCmd cmd) {
+ this.cmd = cmd;
+ }
+
+ public object Identifier() {
+ if (cmd != null)
+ return cmd;
+ else
+ return impl;
+ }
+
+ private StmtList StmtList() {
+ if (cmd != null)
+ return cmd.Body;
+ else
+ return impl.StructuredStmts;
+ }
+
+ private IEnumerable<Cmd> Cmds(StmtList stmts) {
+ foreach (var bb in stmts.BigBlocks) {
+ foreach (Cmd c in bb.simpleCmds)
+ yield return c;
+
+ if (bb.ec is IfCmd) {
+ var ic = (IfCmd)bb.ec;
+ foreach (var c in Cmds(ic.thn))
+ yield return c;
+
+ if (ic.elseBlock != null)
+ foreach (var c in Cmds(ic.elseBlock))
+ yield return c;
+ } else if (bb.ec is WhileCmd) {
+ var wc = (WhileCmd)bb.ec;
+ foreach (var c in Cmds(wc.Body))
+ yield return c;
+ }
+ }
+ }
+
+ private IEnumerable<object> CmdsChildRegions(StmtList stmts) {
+ foreach (var bb in stmts.BigBlocks) {
+ foreach (Cmd c in bb.simpleCmds)
+ yield return c;
+
+ if (bb.ec is IfCmd) {
+ var ic = (IfCmd)bb.ec;
+ foreach (var c in Cmds(ic.thn))
+ yield return c;
+
+ if (ic.elseBlock != null)
+ foreach (var c in Cmds(ic.elseBlock))
+ yield return c;
+ } else if (bb.ec is WhileCmd) {
+ var wc = (WhileCmd)bb.ec;
+ yield return new StructuredRegion(wc);
+ }
+ }
+ }
+
+ private IEnumerable<IRegion> SubRegions(StmtList stmts) {
+ foreach (var bb in stmts.BigBlocks) {
+ if (bb.ec is IfCmd) {
+ var ic = (IfCmd)bb.ec;
+ foreach (var r in SubRegions(ic.thn))
+ yield return r;
+
+ if (ic.elseBlock != null)
+ foreach (var r in SubRegions(ic.elseBlock))
+ yield return r;
+ } else if (bb.ec is WhileCmd) {
+ var wc = (WhileCmd)bb.ec;
+ yield return new StructuredRegion(wc);
+
+ foreach (var r in SubRegions(wc.Body))
+ yield return r;
+ }
+ }
+ }
+
+ public IEnumerable<Cmd> Cmds() {
+ return Cmds(StmtList());
+ }
+
+ public IEnumerable<object> CmdsChildRegions() {
+ return CmdsChildRegions(StmtList());
+ }
+
+ public IEnumerable<IRegion> SubRegions() {
+ return SubRegions(StmtList());
+ }
+
+ public Expr Guard() {
+ if (cmd != null)
+ return cmd.Guard;
+ else
+ return null;
+ }
+
+ public void AddInvariant(PredicateCmd pc) {
+ if (cmd != null)
+ cmd.Invariants.Add(pc);
+ }
+}
+
+}
diff --git a/Source/GPUVerify/UniformityAnalyser.cs b/Source/GPUVerify/UniformityAnalyser.cs index bd0e3f74..35f297ed 100644 --- a/Source/GPUVerify/UniformityAnalyser.cs +++ b/Source/GPUVerify/UniformityAnalyser.cs @@ -63,6 +63,10 @@ namespace GPUVerify SetNonUniform(Impl.Name, GPUVerifier._Y.Name);
SetNonUniform(Impl.Name, GPUVerifier._Z.Name);
+ SetNonUniform(Impl.Name, GPUVerifier._GROUP_X.Name);
+ SetNonUniform(Impl.Name, GPUVerifier._GROUP_Y.Name);
+ SetNonUniform(Impl.Name, GPUVerifier._GROUP_Z.Name);
+
foreach (Variable v in Impl.LocVars)
{
if (CommandLineOptions.DoUniformityAnalysis)
diff --git a/Source/GPUVerify/UnstructuredRegion.cs b/Source/GPUVerify/UnstructuredRegion.cs new file mode 100644 index 00000000..239f7ca0 --- /dev/null +++ b/Source/GPUVerify/UnstructuredRegion.cs @@ -0,0 +1,97 @@ +using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Boogie;
+using Graphing;
+
+namespace GPUVerify {
+
+class UnstructuredRegion : IRegion {
+ Graph<Block> blockGraph;
+ Block header;
+ Dictionary<Block, HashSet<Block>> loopNodes = new Dictionary<Block, HashSet<Block>>();
+ Dictionary<Block, Block> innermostHeader = new Dictionary<Block, Block>();
+ Expr guard;
+
+ public UnstructuredRegion(Program p, Implementation impl) {
+ blockGraph = p.ProcessLoops(impl);
+ header = null;
+ foreach (var h in blockGraph.SortHeadersByDominance()) {
+ var loopNodes = new HashSet<Block>();
+ foreach (var b in blockGraph.BackEdgeNodes(h))
+ loopNodes.UnionWith(blockGraph.NaturalLoops(h, b));
+ this.loopNodes[h] = loopNodes;
+ foreach (var n in loopNodes)
+ if (n != h)
+ innermostHeader[n] = h;
+ }
+ guard = null;
+ }
+
+ private UnstructuredRegion(UnstructuredRegion r, Block h) {
+ blockGraph = r.blockGraph;
+ header = h;
+ loopNodes = r.loopNodes;
+ innermostHeader = r.innermostHeader;
+ guard = null;
+ }
+
+ public object Identifier() {
+ return header;
+ }
+
+ private HashSet<Block> SubBlocks() {
+ if (header != null) {
+ return loopNodes[header];
+ } else {
+ return blockGraph.Nodes;
+ }
+ }
+
+ public IEnumerable<Cmd> Cmds() {
+ foreach (var b in SubBlocks())
+ foreach (Cmd c in b.Cmds)
+ yield return c;
+ }
+
+ public IEnumerable<object> CmdsChildRegions() {
+ foreach (var b in SubBlocks()) {
+ if (b == header)
+ foreach (Cmd c in b.Cmds)
+ yield return c;
+ else if (innermostHeader[b] == header) {
+ if (loopNodes.ContainsKey(b))
+ yield return new UnstructuredRegion(this, b);
+ else
+ foreach (Cmd c in b.Cmds)
+ yield return c;
+ }
+ }
+ }
+
+ public IEnumerable<IRegion> SubRegions() {
+ return SubBlocks().Intersect(loopNodes.Keys).Select(b => new UnstructuredRegion(this, b));
+ }
+
+ public Expr Guard() {
+ if (header == null)
+ return null;
+ if (guard == null) {
+ var backedges = blockGraph.BackEdgeNodes(header);
+ if (backedges.Count() != 1)
+ return null;
+ var assumes = backedges.Single().Cmds.Cast<Cmd>().OfType<AssumeCmd>();
+ if (assumes.Count() != 1)
+ return null;
+ guard = assumes.Single().Expr;
+ }
+ return guard;
+ }
+
+ public void AddInvariant(PredicateCmd pc) {
+ header.Cmds = new CmdSeq((new Cmd[] {pc}.Concat(header.Cmds.Cast<Cmd>())).ToArray());
+ }
+}
+
+}
diff --git a/Source/GPUVerify/VariableDefinitionAnalysis.cs b/Source/GPUVerify/VariableDefinitionAnalysis.cs new file mode 100644 index 00000000..f55e51e8 --- /dev/null +++ b/Source/GPUVerify/VariableDefinitionAnalysis.cs @@ -0,0 +1,155 @@ +using System;
+using Microsoft.Boogie;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace GPUVerify {
+
+class VariableDefinitionAnalysis {
+ GPUVerifier verifier;
+ Implementation impl;
+
+ Dictionary<Variable, Expr> defMap = new Dictionary<Variable, Expr>();
+ Dictionary<string, Expr> namedDefMap = new Dictionary<string, Expr>();
+ bool changed;
+
+ VariableDefinitionAnalysis(GPUVerifier v, Implementation i) {
+ verifier = v;
+ impl = i;
+ }
+
+ private class IsConstantVisitor : StandardVisitor {
+ private VariableDefinitionAnalysis analysis;
+ public bool isConstant = true;
+
+ public IsConstantVisitor(VariableDefinitionAnalysis a) {
+ analysis = a;
+ }
+
+ public override Expr VisitNAryExpr(NAryExpr expr) {
+ if (expr.Fun is MapSelect) {
+ isConstant = false;
+ return expr;
+ } else
+ return base.VisitNAryExpr(expr);
+ }
+
+ public override Expr VisitIdentifierExpr(IdentifierExpr expr) {
+ if (expr.Decl is Constant)
+ return expr;
+ if (!analysis.defMap.ContainsKey(expr.Decl) || analysis.defMap[expr.Decl] == null)
+ isConstant = false;
+ return expr;
+ }
+ };
+
+ bool IsConstant(Expr e) {
+ var v = new IsConstantVisitor(this);
+ v.Visit(e);
+ return v.isConstant;
+ }
+
+ void UpdateDefMap(Variable v, Expr def) {
+ if (!defMap.ContainsKey(v) || defMap[v] != def) {
+ changed = true;
+ defMap[v] = def;
+ }
+ }
+
+ void AddAssignment(AssignLhs lhs, Expr rhs) {
+ if (lhs is SimpleAssignLhs) {
+ var sLhs = (SimpleAssignLhs)lhs;
+ var theVar = sLhs.DeepAssignedVariable;
+ if ((defMap.ContainsKey(theVar) && defMap[theVar] != rhs) || !IsConstant(rhs)) {
+ UpdateDefMap(theVar, null);
+ } else {
+ UpdateDefMap(theVar, rhs);
+ }
+ }
+ }
+
+ void Analyse() {
+ do {
+ changed = false;
+ foreach (var c in verifier.RootRegion(impl).Cmds()) {
+ if (c is AssignCmd) {
+ var aCmd = (AssignCmd)c;
+ foreach (var a in aCmd.Lhss.Zip(aCmd.Rhss)) {
+ AddAssignment(a.Item1, a.Item2);
+ }
+ }
+ }
+ } while (changed);
+ }
+
+ private class BuildNamedDefVisitor : StandardVisitor {
+ private VariableDefinitionAnalysis analysis;
+
+ public BuildNamedDefVisitor(VariableDefinitionAnalysis a) {
+ analysis = a;
+ }
+
+ public override Expr VisitIdentifierExpr(IdentifierExpr expr) {
+ if (expr.Decl is Constant)
+ return expr;
+ return analysis.BuildNamedDefFor(expr.Decl);
+ }
+ }
+
+ Expr BuildNamedDefFor(Variable v) {
+ Expr def;
+ if (namedDefMap.TryGetValue(v.Name, out def))
+ return def;
+ def = (Expr)new BuildNamedDefVisitor(this).Visit(defMap[v].Clone());
+ namedDefMap[v.Name] = def;
+ return def;
+ }
+
+ void BuildNamedDefMap() {
+ foreach (var v in defMap.Keys)
+ if (defMap[v] != null)
+ BuildNamedDefFor(v);
+ }
+
+ private class SubstDualisedDefVisitor : StandardVisitor {
+ private VariableDefinitionAnalysis analysis;
+ private VariableDualiser dualiser;
+ public bool isSubstitutable = true;
+
+ public SubstDualisedDefVisitor(VariableDefinitionAnalysis a, int id, string procName) {
+ analysis = a;
+ dualiser = new VariableDualiser(id, analysis.verifier.uniformityAnalyser, procName);
+ }
+
+ public override Expr VisitIdentifierExpr(IdentifierExpr expr) {
+ if (expr.Decl is Constant)
+ return dualiser.VisitIdentifierExpr(expr);
+ var varName = GPUVerifier.StripThreadIdentifier(expr.Decl.Name);
+ Expr def;
+ if (!analysis.namedDefMap.TryGetValue(varName, out def)) {
+ isSubstitutable = false;
+ return null;
+ }
+ return (Expr)dualiser.Visit(def.Clone());
+ }
+ }
+
+ public Expr SubstDualisedDefinitions(Expr e, int id, string procName) {
+ var v = new SubstDualisedDefVisitor(this, id, procName);
+ Expr result = (Expr)v.Visit(e.Clone());
+ if (!v.isSubstitutable)
+ return null;
+ return result;
+ }
+
+ public static VariableDefinitionAnalysis Analyse(GPUVerifier verifier, Implementation impl) {
+ var a = new VariableDefinitionAnalysis(verifier, impl);
+ a.Analyse();
+ a.BuildNamedDefMap();
+ a.defMap = null;
+ return a;
+ }
+
+}
+
+}
diff --git a/Source/GPUVerify/VariableDualiser.cs b/Source/GPUVerify/VariableDualiser.cs index 7f637734..63720c13 100644 --- a/Source/GPUVerify/VariableDualiser.cs +++ b/Source/GPUVerify/VariableDualiser.cs @@ -36,6 +36,11 @@ namespace GPUVerify return new IdentifierExpr(node.tok, new Constant(node.tok, DualiseTypedIdent(node.Decl)));
}
+ if (CommandLineOptions.InterGroupRaceChecking && GPUVerifier.IsGroupIdConstant(node.Decl))
+ {
+ return new IdentifierExpr(node.tok, new Constant(node.tok, DualiseTypedIdent(node.Decl)));
+ }
+
return node;
}
@@ -52,7 +57,8 @@ namespace GPUVerify public override Variable VisitVariable(Variable node)
{
- if (!(node is Constant) || GPUVerifier.IsThreadLocalIdConstant(node))
+ if (!(node is Constant) || GPUVerifier.IsThreadLocalIdConstant(node) ||
+ (CommandLineOptions.InterGroupRaceChecking && GPUVerifier.IsGroupIdConstant(node)))
{
node.TypedIdent = DualiseTypedIdent(node);
node.Name = node.Name + "$" + id;
diff --git a/Source/Graph/Graph.cs b/Source/Graph/Graph.cs index e5e8444c..b5590865 100644 --- a/Source/Graph/Graph.cs +++ b/Source/Graph/Graph.cs @@ -843,6 +843,19 @@ namespace Graphing { }
return dag.TopologicalSort();
}
+
+ public string ToDot(Func<Node, string> NodeLabel = null, Func<Node, string> NodeStyle = null) {
+ NodeLabel = NodeLabel ?? (n => n.ToString());
+ NodeStyle = NodeStyle ?? (n => "[shape=box]");
+ var s = new StringBuilder();
+ s.AppendLine("digraph G {");
+ foreach (var n in Nodes)
+ s.AppendLine(" \"" + NodeLabel(n) + "\" " + NodeStyle(n) + ";");
+ foreach (var e in Edges)
+ s.AppendLine(" \"" + NodeLabel(e.Item1) + "\" -> \"" + NodeLabel(e.Item2) + "\";");
+ s.AppendLine("}");
+ return s.ToString();
+ }
} // end: class Graph
public class GraphProgram {
diff --git a/Source/Houdini/Houdini.cs b/Source/Houdini/Houdini.cs index d753762f..ab2fa74f 100644 --- a/Source/Houdini/Houdini.cs +++ b/Source/Houdini/Houdini.cs @@ -279,11 +279,6 @@ namespace Microsoft.Boogie.Houdini { }
}
- public class Macro : Function {
- public Macro(IToken tok, string name, VariableSeq args, Variable result)
- : base(tok, name, args, result) { }
- }
-
public class FreeRequiresVisitor : StandardVisitor {
public override Requires VisitRequires(Requires requires) {
if (requires.Free)
@@ -301,6 +296,13 @@ namespace Microsoft.Boogie.Houdini { }
}
+ public class InlineEnsuresVisitor : StandardVisitor {
+ public override Ensures VisitEnsures(Ensures ensures) {
+ ensures.Attributes = new QKeyValue(Token.NoToken, "assume", new List<object>(), ensures.Attributes);
+ return base.VisitEnsures(ensures);
+ }
+ }
+
public class Houdini : ObservableHoudini {
private Program program;
private HashSet<Variable> houdiniConstants;
@@ -367,6 +369,11 @@ namespace Microsoft.Boogie.Houdini { }
foreach (Implementation impl in callGraph.Nodes) {
+ InlineEnsuresVisitor inlineEnsuresVisitor = new InlineEnsuresVisitor();
+ inlineEnsuresVisitor.Visit(impl);
+ }
+
+ foreach (Implementation impl in callGraph.Nodes) {
impl.OriginalBlocks = impl.Blocks;
impl.OriginalLocVars = impl.LocVars;
}
diff --git a/Source/Model/Model.cs b/Source/Model/Model.cs index 204d130e..325ba03e 100644 --- a/Source/Model/Model.cs +++ b/Source/Model/Model.cs @@ -74,6 +74,14 @@ namespace Microsoft.Boogie }
public abstract ElementKind Kind { get; }
public virtual int AsInt() { throw new NotImplementedException(); }
+
+ public override int GetHashCode() {
+ return Id;
+ }
+
+ public override bool Equals(object obj) {
+ return obj == this;
+ }
}
#region element kinds
@@ -166,6 +174,17 @@ namespace Microsoft.Boogie return string.Format("{0}/{1}", Name, Arity);
}
+ internal void Substitute(Dictionary<Element, Element> mapping) {
+ Element e;
+ if (@else != null && mapping.TryGetValue(@else, out e))
+ @else = e;
+ foreach (var ft in apps) {
+ if (mapping.TryGetValue(ft.Result, out e)) ft.Result = e;
+ for (var i = 0; i < ft.Args.Length; ++i)
+ if (mapping.TryGetValue(ft.Args[i], out e)) ft.Args[i] = e;
+ }
+ }
+
public Element Else
{
get
@@ -322,7 +341,7 @@ namespace Microsoft.Boogie }
return null;
}
-
+
/// <summary>
/// Short for TryEval(args) == (Element)true
/// </summary>
@@ -366,8 +385,9 @@ namespace Microsoft.Boogie {
static readonly Element[] EmptyArgs = new Element[0];
+ // These should be immutable, except when Substituting the entire model
public readonly Func Func;
- public readonly Element Result;
+ public Element Result;
public readonly Element[] Args;
internal FuncTuple(Func func, Element res, Element[] args)
@@ -676,6 +696,10 @@ namespace Microsoft.Boogie wr.WriteLine("*** END_MODEL");
}
+ public void Substitute(Dictionary<Element, Element> mapping) {
+ foreach (var f in functions) f.Substitute(mapping);
+ }
+
class Parser
{
internal System.IO.TextReader rd;
@@ -799,6 +823,8 @@ namespace Microsoft.Boogie internal void Run()
{
+ var selectFunctions = new Dictionary<int, Model.Func>();
+ var storeFunctions = new Dictionary<int, Model.Func>();
for (; ; ) {
var line = ReadLine();
if (line == null) break; // end of model, everything fine
@@ -854,21 +880,38 @@ namespace Microsoft.Boogie if (fn == null)
fn = currModel.MkFunc(funName, 1);
if (tuple0 == "}") break;
- fn.Else = GetElt(tuple[0]);
+ if (fn.Else == null)
+ fn.Else = GetElt(tuple[0]);
continue;
}
string tuplePenultimate = tuple[tuple.Count - 2] as string;
if (tuplePenultimate != "->") BadModel("invalid function tuple definition");
var resultName = tuple[tuple.Count - 1];
if (tuple0 == "else") {
- if (fn != null && !(resultName is string && ((string)resultName) == "#unspecified")) {
+ if (fn != null && !(resultName is string && ((string)resultName) == "#unspecified") && fn.Else == null) {
fn.Else = GetElt(resultName);
}
continue;
}
- if (fn == null)
- fn = currModel.MkFunc(funName, tuple.Count - 2);
+ if (fn == null) {
+ var arity = tuple.Count - 2;
+ if (Regex.IsMatch(funName, "^MapType[0-9]*Select$")) {
+ funName = string.Format("[{0}]", arity);
+ if (!selectFunctions.TryGetValue(arity, out fn)) {
+ fn = currModel.MkFunc(funName, arity);
+ selectFunctions.Add(arity, fn);
+ }
+ } else if (Regex.IsMatch(funName, "^MapType[0-9]*Store$")) {
+ funName = string.Format("[{0}:=]", arity);
+ if (!storeFunctions.TryGetValue(arity, out fn)) {
+ fn = currModel.MkFunc(funName, arity);
+ storeFunctions.Add(arity, fn);
+ }
+ } else {
+ fn = currModel.MkFunc(funName, arity);
+ }
+ }
var args = new Element[fn.Arity];
for (int i = 0; i < fn.Arity; ++i)
args[i] = GetElt(tuple[i]);
diff --git a/Source/ModelViewer/DafnyProvider.cs b/Source/ModelViewer/DafnyProvider.cs index 328bbb26..6e4698d9 100644 --- a/Source/ModelViewer/DafnyProvider.cs +++ b/Source/ModelViewer/DafnyProvider.cs @@ -54,10 +54,10 @@ namespace Microsoft.Boogie.ModelViewer.Dafny // collect the array dimensions from the various array.Length functions, and
// collect all known datatype values
foreach (var fn in m.Functions) {
- if (Regex.IsMatch(fn.Name, "^array[0-9]*.Length[0-9]*$")) {
- int j = fn.Name.IndexOf('.', 5);
- int dims = j == 5 ? 1 : int.Parse(fn.Name.Substring(5, j - 5));
- int idx = j == 5 ? 0 : int.Parse(fn.Name.Substring(j + 7));
+ if (Regex.IsMatch(fn.Name, "^_System.array[0-9]*.Length[0-9]*$")) {
+ int j = fn.Name.IndexOf('.', 13);
+ int dims = j == 13 ? 1 : int.Parse(fn.Name.Substring(13, j - 13));
+ int idx = j == 13 ? 0 : int.Parse(fn.Name.Substring(j + 7));
foreach (var tpl in fn.Apps) {
var elt = tpl.Args[0];
var len = tpl.Result;
diff --git a/Source/Provers/SMTLib/ProverInterface.cs b/Source/Provers/SMTLib/ProverInterface.cs index 65c4e130..31afbdfa 100644 --- a/Source/Provers/SMTLib/ProverInterface.cs +++ b/Source/Provers/SMTLib/ProverInterface.cs @@ -770,12 +770,13 @@ namespace Microsoft.Boogie.SMTLib SendThisVC(a);
}
- public override void DefineMacro(Function fun, VCExpr vc) {
- DeclCollector.AddFunction(fun);
- string name = Namer.GetName(fun, fun.Name);
- string a = "(define-fun " + name + "() Bool " + VCExpr2String(vc, 1) + ")";
+ public override void DefineMacro(Macro f, VCExpr vc) {
+ DeclCollector.AddFunction(f);
+ string printedName = Namer.GetQuotedName(f, f.Name);
+ var argTypes = f.InParams.Cast<Variable>().MapConcat(p => DeclCollector.TypeToStringReg(p.TypedIdent.Type), " ");
+ string decl = "(define-fun " + printedName + " (" + argTypes + ") " + DeclCollector.TypeToStringReg(f.OutParams[0].TypedIdent.Type) + " " + VCExpr2String(vc, 1) + ")";
AssertAxioms();
- SendThisVC(a);
+ SendThisVC(decl);
}
public override void AssertAxioms()
diff --git a/Source/Provers/Z3api/ContextLayer.cs b/Source/Provers/Z3api/ContextLayer.cs index e0fddc63..df40df3d 100644 --- a/Source/Provers/Z3api/ContextLayer.cs +++ b/Source/Provers/Z3api/ContextLayer.cs @@ -20,6 +20,8 @@ namespace Microsoft.Boogie.Z3 { internal BacktrackDictionary<string, Term> constants = new BacktrackDictionary<string, Term>();
internal BacktrackDictionary<string, FuncDecl> functions = new BacktrackDictionary<string, FuncDecl>();
internal BacktrackDictionary<string, Term> labels = new BacktrackDictionary<string, Term>();
+ internal BacktrackDictionary<Term, VCExpr> constants_inv = null;
+ internal BacktrackDictionary<FuncDecl, Function> functions_inv = null;
public Config config;
public Context z3;
@@ -56,7 +58,13 @@ namespace Microsoft.Boogie.Z3 { z3 = new Context(config);
z3.SetPrintMode(PrintMode.Smtlib2Compliant);
if (logFilename != null)
- z3.OpenLog(logFilename);
+ {
+#if true
+ Z3Log.Open(logFilename);
+#else
+ z3.OpenLog(logFilename);
+#endif
+ }
foreach (string tag in debugTraces)
z3.EnableDebugTrace(tag);
@@ -65,6 +73,227 @@ namespace Microsoft.Boogie.Z3 { this.namer = new UniqueNamer();
}
+ public Z3apiProverContext(Context ctx, VCExpressionGenerator gen)
+ : base(gen, new VCGenerationOptions(new List<string>()))
+ {
+ z3 = ctx;
+
+ this.z3log = null;
+ this.tm = new Z3TypeCachedBuilder(this);
+ this.namer = new UniqueNamer();
+
+ // For external
+
+ constants_inv = new BacktrackDictionary<Term, VCExpr>();
+ functions_inv = new BacktrackDictionary<FuncDecl, Function>();
+ }
+
+ public Term VCExprToTerm(VCExpr expr, LineariserOptions linOptions) {
+ Z3apiExprLineariser visitor = new Z3apiExprLineariser(this, namer);
+ return (Term)expr.Accept(visitor, linOptions);
+ }
+
+
+ private class fromZ3
+ {
+ private VCExpressionGenerator gen;
+ private Dictionary<Term, VCExpr> memo;
+ private BacktrackDictionary<Term, VCExpr> constants_inv;
+ private BacktrackDictionary<FuncDecl, Function> functions_inv;
+ private List<VCExprLetBinding> lets;
+ private int let_ctr = 0;
+
+ private VCExpr create_let(Term t, VCExpr u)
+ {
+ var name = "$x" + let_ctr.ToString();
+ let_ctr++;
+ var sym = gen.Variable(name, u.Type);
+ memo.Remove(t);
+ memo.Add(t, sym);
+ lets.Add(gen.LetBinding(sym, u));
+ return sym;
+ }
+
+ public fromZ3(VCExpressionGenerator _gen,
+ BacktrackDictionary<Term, VCExpr> _constants_inv,
+ BacktrackDictionary<FuncDecl, Function> _functions_inv)
+ {
+ gen = _gen;
+ constants_inv = _constants_inv;
+ functions_inv = _functions_inv;
+ memo = new Dictionary<Term, VCExpr>();
+ lets = new List<VCExprLetBinding>();
+ }
+
+ public void clear()
+ {
+ memo.Clear();
+ lets.Clear();
+ }
+ public VCExpr get(Term arg)
+ {
+ if (memo.ContainsKey(arg))
+ return memo[arg];
+ VCExpr res = null;
+ switch (arg.GetKind())
+ {
+ case TermKind.Numeral:
+ var numstr = arg.GetNumeralString();
+ var bignum = Basetypes.BigNum.FromString(numstr);
+ res = gen.Integer(bignum);
+ break;
+ case TermKind.App:
+ var args = arg.GetAppArgs();
+ var vcargs = new VCExpr[args.Length];
+ for (int i = 0; i < args.Length; i++)
+ vcargs[i] = get(args[i]);
+
+ switch (arg.GetAppDecl().GetKind())
+ {
+ case DeclKind.Add:
+ if (vcargs.Length == 0)
+ res = gen.Integer(Basetypes.BigNum.FromInt(0));
+ else
+ {
+ res = vcargs[0];
+ for (int k = 1; k < vcargs.Length; k++)
+ res = gen.Add(res, vcargs[k]);
+ }
+ break;
+ case DeclKind.And:
+ res = VCExpressionGenerator.True;
+ for (int i = 0; i < vcargs.Length; i++)
+ res = gen.AndSimp(res, vcargs[i]);
+ break;
+ case DeclKind.Div:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.DivOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Eq:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Eq(vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.False:
+ res = VCExpressionGenerator.False;
+ break;
+ case DeclKind.Ge:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.GeOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Gt:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Gt(vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.IDiv:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.DivOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Iff:
+ Debug.Assert(vcargs.Length == 2);
+ var l = create_let(args[0], vcargs[0]);
+ var r = create_let(args[1], vcargs[1]);
+ return gen.And(gen.Implies(l, r), gen.Implies(r, l));
+ case DeclKind.Implies:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Implies(vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Ite:
+ Debug.Assert(vcargs.Length == 3);
+ res = gen.Function(VCExpressionGenerator.IfThenElseOp, vcargs[0], vcargs[1], vcargs[2]);
+ break;
+ case DeclKind.Le:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.LeOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Lt:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.LtOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Mod:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.ModOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Mul:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.MulOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Not:
+ Debug.Assert(vcargs.Length == 1);
+ res = gen.Not(vcargs[0]);
+ break;
+ case DeclKind.Or:
+ res = VCExpressionGenerator.False;
+ for (int i = 0; i < vcargs.Length; i++)
+ res = gen.OrSimp(res, vcargs[i]);
+ break;
+ case DeclKind.Select:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Select(vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.Store:
+ Debug.Assert(vcargs.Length == 3);
+ res = gen.Store(vcargs[0], vcargs[1], vcargs[2]);
+ break;
+ case DeclKind.Sub:
+ Debug.Assert(vcargs.Length == 2);
+ res = gen.Function(VCExpressionGenerator.SubOp, vcargs[0], vcargs[1]);
+ break;
+ case DeclKind.True:
+ res = VCExpressionGenerator.True;
+ break;
+ case DeclKind.Uminus:
+ Debug.Assert(vcargs.Length == 1);
+ var bigzero = Basetypes.BigNum.FromInt(0);
+ res = gen.Function(VCExpressionGenerator.SubOp, gen.Integer(bigzero), vcargs[0]);
+ break;
+ case DeclKind.Uninterpreted:
+ var name = arg.GetAppDecl().GetDeclName();
+ if (args.Length == 0)
+ { // a 0-ary constant is a VCExprVar
+ if (!constants_inv.TryGetValue(arg, out res))
+ throw new Exception("Z3 returned unknown constant: " + name);
+ }
+ else
+ {
+ Function f;
+ if (!functions_inv.TryGetValue(arg.GetAppDecl(), out f))
+ throw new Exception("Z3 returned unknown function: " + name);
+ List<VCExpr> vcargsList = new List<VCExpr>(vcargs);
+ res = gen.Function(f, vcargsList);
+ }
+ break;
+ default:
+ throw new Exception("Unknown Z3 operator");
+ }
+ break;
+ default:
+ Debug.Assert(false);
+ throw new Exception("Unknown Z3 AST kind");
+ }
+
+ memo.Add(arg, res);
+ return res;
+ }
+ public VCExpr add_lets(VCExpr e)
+ {
+ foreach (var let in lets)
+ {
+ e = gen.Let(e, let);
+ }
+ return e;
+ }
+ }
+
+ public VCExpr TermToVCExpr(Term t)
+ {
+ var fZ = new fromZ3(gen, constants_inv, functions_inv);
+ return fZ.add_lets(fZ.get(t));
+ }
+
+
+
+
+
public override void DeclareType(TypeCtorDecl t, string attributes) {
base.DeclareType(t, attributes);
log("(declare-sort {0})", t.Name);
@@ -97,6 +326,7 @@ namespace Microsoft.Boogie.Z3 { Sort rangeAst = tm.GetType(range);
FuncDecl constDeclAst = z3.MkFuncDecl(symbolAst, domainAst.ToArray(), rangeAst);
functions.Add(functionName, constDeclAst);
+ if(functions_inv != null)functions_inv.Add(constDeclAst, f);
log("(declare-funs (({0} {1} {2})))", functionName, domainStr, rangeAst);
}
@@ -122,7 +352,11 @@ namespace Microsoft.Boogie.Z3 { }
public void CloseLog() {
- z3.CloseLog();
+#if true
+ Z3Log.Close();
+#else
+ z3.CloseLog();
+#endif
if (z3log != null) {
z3log.Close();
}
@@ -134,6 +368,8 @@ namespace Microsoft.Boogie.Z3 { constants.CreateBacktrackPoint();
functions.CreateBacktrackPoint();
labels.CreateBacktrackPoint();
+ if(constants_inv != null)constants_inv.CreateBacktrackPoint();
+ if(functions_inv != null)functions_inv.CreateBacktrackPoint();
z3.Push();
log("(push)");
}
@@ -144,6 +380,8 @@ namespace Microsoft.Boogie.Z3 { functions.Backtrack();
constants.Backtrack();
symbols.Backtrack();
+ if (constants_inv != null) constants_inv.Backtrack();
+ if (functions_inv != null) functions_inv.Backtrack();
log("(pop)");
}
@@ -368,13 +606,18 @@ namespace Microsoft.Boogie.Z3 { return result;
}
- public Term GetConstant(string constantName, Type constantType) {
+ public Term GetConstant(string constantName, Type constantType, VCExpr node)
+ {
Term typeSafeTerm;
if (!constants.ContainsKey(constantName))
this.DeclareConstant(constantName, constantType);
if (!constants.TryGetValue(constantName, out typeSafeTerm))
throw new Exception("constant " + constantName + " is not defined");
+
+ if (constants_inv != null && !constants_inv.ContainsKey(typeSafeTerm))
+ constants_inv.Add(typeSafeTerm, node);
+
return typeSafeTerm;
}
diff --git a/Source/Provers/Z3api/VCExprVisitor.cs b/Source/Provers/Z3api/VCExprVisitor.cs index 149a23f1..0605a854 100644 --- a/Source/Provers/Z3api/VCExprVisitor.cs +++ b/Source/Provers/Z3api/VCExprVisitor.cs @@ -188,7 +188,7 @@ namespace Microsoft.Boogie.Z3 else
{
string varName = namer.GetName(node, node.Name);
- return cm.GetConstant(varName, node.Type);
+ return cm.GetConstant(varName, node.Type,node);
}
}
@@ -252,7 +252,7 @@ namespace Microsoft.Boogie.Z3 private Term MakeQuantifier(bool isForall, uint weight, string qid, int skolemid, List<string> varNames, List<Type> boogieTypes, List<Pattern> patterns, List<Term> no_patterns, Term body) {
List<Term> bound = new List<Term>();
for (int i = 0; i < varNames.Count; i++) {
- Term t = cm.GetConstant(varNames[i], boogieTypes[i]);
+ Term t = cm.GetConstant(varNames[i], boogieTypes[i], null);
bound.Add(t);
}
diff --git a/Source/Provers/Z3api/Z3api.csproj b/Source/Provers/Z3api/Z3api.csproj index 7c481438..f9511dbd 100644 --- a/Source/Provers/Z3api/Z3api.csproj +++ b/Source/Provers/Z3api/Z3api.csproj @@ -118,9 +118,8 @@ </Target>
-->
<ItemGroup>
- <Reference Include="Microsoft.Z3, Version=2.0.40827.2, Culture=neutral, PublicKeyToken=9c8d792caae602a2, processorArchitecture=x86">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\..\Binaries\Microsoft.Z3.dll</HintPath>
+ <Reference Include="ManagedAPI">
+ <HintPath>..\..\..\..\..\iZ3\win\iZ3\Debug\ManagedAPI.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
diff --git a/Source/VCGeneration/Check.cs b/Source/VCGeneration/Check.cs index a2564be5..e3b1cb2d 100644 --- a/Source/VCGeneration/Check.cs +++ b/Source/VCGeneration/Check.cs @@ -100,8 +100,9 @@ namespace Microsoft.Boogie { /// <summary>
/// Constructor. Initialize a checker with the program and log file.
+ /// Optionally, use prover context provided by parameter "ctx".
/// </summary>
- public Checker(VC.ConditionGeneration vcgen, Program prog, string/*?*/ logFilePath, bool appendLogFile, int timeout) {
+ public Checker(VC.ConditionGeneration vcgen, Program prog, string/*?*/ logFilePath, bool appendLogFile, int timeout, ProverContext ctx = null) {
Contract.Requires(vcgen != null);
Contract.Requires(prog != null);
this.timeout = timeout;
@@ -121,7 +122,6 @@ namespace Microsoft.Boogie { options.Parse(CommandLineOptions.Clo.ProverOptions);
ContextCacheKey key = new ContextCacheKey(prog);
- ProverContext ctx;
ProverInterface prover;
if (vcgen.CheckerCommonState == null) {
@@ -129,12 +129,13 @@ namespace Microsoft.Boogie { }
IDictionary<ContextCacheKey, ProverContext>/*!>!*/ cachedContexts = (IDictionary<ContextCacheKey, ProverContext/*!*/>)vcgen.CheckerCommonState;
- if (cachedContexts.TryGetValue(key, out ctx)) {
+ if (ctx == null && cachedContexts.TryGetValue(key, out ctx))
+ {
ctx = (ProverContext)cce.NonNull(ctx).Clone();
prover = (ProverInterface)
CommandLineOptions.Clo.TheProverFactory.SpawnProver(options, ctx);
} else {
- ctx = (ProverContext)CommandLineOptions.Clo.TheProverFactory.NewProverContext(options);
+ if (ctx == null) ctx = (ProverContext)CommandLineOptions.Clo.TheProverFactory.NewProverContext(options);
// set up the context
foreach (Declaration decl in prog.TopLevelDeclarations) {
@@ -488,7 +489,7 @@ namespace Microsoft.Boogie { get;
}
- public virtual void DefineMacro(Function fun, VCExpr vc) {
+ public virtual void DefineMacro(Macro fun, VCExpr vc) {
throw new NotImplementedException();
}
}
diff --git a/Source/VCGeneration/ConditionGeneration.cs b/Source/VCGeneration/ConditionGeneration.cs index ba58a5de..9837626d 100644 --- a/Source/VCGeneration/ConditionGeneration.cs +++ b/Source/VCGeneration/ConditionGeneration.cs @@ -206,11 +206,23 @@ namespace Microsoft.Boogie { }
}
+ void ApplyRedirections(Model m) {
+ var mapping = new Dictionary<Model.Element, Model.Element>();
+ foreach (var name in new string[] { "U_2_bool", "U_2_int" }) {
+ Model.Func f = m.TryGetFunc(name);
+ if (f != null && f.Arity == 1) {
+ foreach (var ft in f.Apps) mapping[ft.Args[0]] = ft.Result;
+ }
+ }
+ m.Substitute(mapping);
+ }
+
public Model GetModelWithStates()
{
if (Model == null) return null;
Model m = Model;
+ ApplyRedirections(m);
var mvstates = m.TryGetFunc("@MV_state");
if (MvInfo == null || mvstates == null)
diff --git a/Source/VCGeneration/StratifiedVC.cs b/Source/VCGeneration/StratifiedVC.cs index 563cbf40..a2ad1bd3 100644 --- a/Source/VCGeneration/StratifiedVC.cs +++ b/Source/VCGeneration/StratifiedVC.cs @@ -15,7 +15,7 @@ using Microsoft.Boogie.VCExprAST; namespace VC {
using Bpl = Microsoft.Boogie;
-
+
public class StratifiedVC {
public StratifiedInliningInfo info;
public int id;
@@ -23,44 +23,22 @@ namespace VC { public Dictionary<Block, List<StratifiedCallSite>> callSites;
public Dictionary<Block, List<StratifiedCallSite>> recordProcCallSites;
public VCExpr vcexpr;
- public Dictionary<Block, VCExprVar> reachVars;
+
+ // the following three fields are not being used at the moment
+ public VCExprVar entryExprVar;
+ public Dictionary<Block, Macro> reachMacros;
+ public Dictionary<Block, VCExpr> reachMacroDefinitions;
public StratifiedVC(StratifiedInliningInfo siInfo) {
info = siInfo;
info.GenerateVC();
- vcexpr = info.vcexpr;
var vcgen = info.vcgen;
var prover = vcgen.prover;
VCExpressionGenerator gen = prover.VCExprGen;
- var bet = prover.Context.BoogieExprTranslator;
- VCExpr controlFlowVariableExpr = bet.LookupVariable(info.controlFlowVariable);
+ var bet = prover.Context.BoogieExprTranslator;
+
+ vcexpr = info.vcexpr;
id = vcgen.CreateNewId();
- VCExpr eqExpr = gen.Eq(controlFlowVariableExpr, gen.Integer(BigNum.FromInt(id)));
- vcexpr = gen.And(eqExpr, vcexpr);
-
- var impl = info.impl;
- reachVars = new Dictionary<Block, VCExprVar>();
- Dictionary<Block, VCExpr> reachExprs = new Dictionary<Block, VCExpr>();
- foreach (Block b in impl.Blocks) {
- reachVars[b] = vcgen.CreateNewVar(Bpl.Type.Bool);
- reachExprs[b] = VCExpressionGenerator.False;
- }
- foreach (Block currBlock in impl.Blocks) {
- GotoCmd gotoCmd = currBlock.TransferCmd as GotoCmd;
- if (gotoCmd == null) continue;
- foreach (Block successorBlock in gotoCmd.labelTargets) {
- VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(controlFlowVariableExpr, gen.Integer(BigNum.FromInt(currBlock.UniqueId)));
- VCExpr controlTransferExpr = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(successorBlock.UniqueId)));
- reachExprs[successorBlock] = gen.Or(reachExprs[successorBlock], gen.And(reachVars[currBlock], controlTransferExpr));
- }
- }
- // The binding for entry block should be left defined;
- // it will get filled in when the call tree is constructed
- for (int i = 1; i < impl.Blocks.Count; i++) {
- Block b = impl.Blocks[i];
- vcexpr = gen.And(vcexpr, gen.Eq(reachVars[b], reachExprs[b]));
- }
-
interfaceExprVars = new List<VCExprVar>();
Dictionary<VCExprVar, VCExpr> substDict = new Dictionary<VCExprVar, VCExpr>();
foreach (VCExprVar v in info.interfaceExprVars) {
@@ -71,15 +49,35 @@ namespace VC { foreach (VCExprVar v in info.privateExprVars) {
substDict.Add(v, vcgen.CreateNewVar(v.Type));
}
+ substDict.Add(bet.LookupVariable(info.controlFlowVariable), gen.Integer(BigNum.FromInt(id)));
VCExprSubstitution subst = new VCExprSubstitution(substDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>());
SubstitutingVCExprVisitor substVisitor = new SubstitutingVCExprVisitor(prover.VCExprGen);
vcexpr = substVisitor.Mutate(vcexpr, subst);
+ var impl = info.impl;
+ reachMacros = new Dictionary<Block, Macro>();
+ reachMacroDefinitions = new Dictionary<Block, VCExpr>();
+ foreach (Block b in impl.Blocks) {
+ reachMacros[b] = vcgen.CreateNewMacro();
+ reachMacroDefinitions[b] = VCExpressionGenerator.False;
+ }
+ entryExprVar = vcgen.CreateNewVar(Microsoft.Boogie.Type.Bool);
+ reachMacroDefinitions[impl.Blocks[0]] = entryExprVar;
+ foreach (Block currBlock in impl.Blocks) {
+ GotoCmd gotoCmd = currBlock.TransferCmd as GotoCmd;
+ if (gotoCmd == null) continue;
+ foreach (Block successorBlock in gotoCmd.labelTargets) {
+ VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(gen.Integer(BigNum.FromInt(id)), gen.Integer(BigNum.FromInt(currBlock.UniqueId)));
+ VCExpr controlTransferExpr = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(successorBlock.UniqueId)));
+ reachMacroDefinitions[successorBlock] = gen.Or(reachMacroDefinitions[successorBlock], gen.And(gen.Function(reachMacros[currBlock]), controlTransferExpr));
+ }
+ }
+
callSites = new Dictionary<Block, List<StratifiedCallSite>>();
foreach (Block b in info.callSites.Keys) {
callSites[b] = new List<StratifiedCallSite>();
foreach (CallSite cs in info.callSites[b]) {
- callSites[b].Add(new StratifiedCallSite(cs, substVisitor, subst, reachVars));
+ callSites[b].Add(new StratifiedCallSite(cs, substVisitor, subst));
}
}
@@ -87,7 +85,7 @@ namespace VC { foreach (Block b in info.recordProcCallSites.Keys) {
recordProcCallSites[b] = new List<StratifiedCallSite>();
foreach (CallSite cs in info.recordProcCallSites[b]) {
- recordProcCallSites[b].Add(new StratifiedCallSite(cs, substVisitor, subst, reachVars));
+ recordProcCallSites[b].Add(new StratifiedCallSite(cs, substVisitor, subst));
}
}
}
@@ -103,6 +101,18 @@ namespace VC { return ret;
}
}
+
+ public List<StratifiedCallSite> RecordProcCallSites {
+ get {
+ var ret = new List<StratifiedCallSite>();
+ foreach (var b in recordProcCallSites.Keys) {
+ foreach (var cs in recordProcCallSites[b]) {
+ ret.Add(cs);
+ }
+ }
+ return ret;
+ }
+ }
}
public class CallSite {
@@ -110,9 +120,11 @@ namespace VC { public List<VCExpr> interfaceExprs;
public Block block;
public int numInstr; // for TraceLocation
- public CallSite(string callee, List<VCExpr> interfaceExprs, Block block, int numInstr) {
+ public VCExprVar callSiteVar;
+ public CallSite(string callee, List<VCExpr> interfaceExprs, VCExprVar callSiteVar, Block block, int numInstr) {
this.calleeName = callee;
this.interfaceExprs = interfaceExprs;
+ this.callSiteVar = callSiteVar;
this.block = block;
this.numInstr = numInstr;
}
@@ -121,26 +133,47 @@ namespace VC { public class StratifiedCallSite {
public CallSite callSite;
public List<VCExpr> interfaceExprs;
- public VCExprVar reachVar;
+ public VCExpr callSiteExpr;
- public StratifiedCallSite(CallSite cs, SubstitutingVCExprVisitor substVisitor, VCExprSubstitution subst, Dictionary<Block, VCExprVar> reachVars) {
+ public StratifiedCallSite(CallSite cs, SubstitutingVCExprVisitor substVisitor, VCExprSubstitution subst) {
callSite = cs;
interfaceExprs = new List<VCExpr>();
foreach (VCExpr v in cs.interfaceExprs) {
interfaceExprs.Add(substVisitor.Mutate(v, subst));
}
- reachVar = reachVars[cs.block];
+ if (callSite.callSiteVar != null)
+ callSiteExpr = substVisitor.Mutate(callSite.callSiteVar, subst);
}
public VCExpr Attach(StratifiedVC svc) {
Contract.Assert(interfaceExprs.Count == svc.interfaceExprVars.Count);
StratifiedInliningInfo info = svc.info;
- VCExpressionGenerator gen = info.vcgen.prover.VCExprGen;
- VCExpr ret = gen.Eq(reachVar, svc.reachVars[info.impl.Blocks[0]]);
- for (int i = 0; i < interfaceExprs.Count; i++) {
- ret = gen.And(ret, gen.Eq(interfaceExprs[i], svc.interfaceExprVars[i]));
+ ProverInterface prover = info.vcgen.prover;
+ VCExpressionGenerator gen = prover.VCExprGen;
+
+ Dictionary<VCExprVar, VCExpr> substDict = new Dictionary<VCExprVar, VCExpr>();
+ for (int i = 0; i < svc.interfaceExprVars.Count; i++) {
+ VCExprVar v = svc.interfaceExprVars[i];
+ substDict.Add(v, interfaceExprs[i]);
}
- return ret;
+ VCExprSubstitution subst = new VCExprSubstitution(substDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>());
+ SubstitutingVCExprVisitor substVisitor = new SubstitutingVCExprVisitor(prover.VCExprGen);
+ svc.vcexpr = substVisitor.Mutate(svc.vcexpr, subst);
+ foreach (StratifiedCallSite scs in svc.CallSites) {
+ List<VCExpr> newInterfaceExprs = new List<VCExpr>();
+ foreach (VCExpr expr in scs.interfaceExprs) {
+ newInterfaceExprs.Add(substVisitor.Mutate(expr, subst));
+ }
+ scs.interfaceExprs = newInterfaceExprs;
+ }
+ foreach (StratifiedCallSite scs in svc.RecordProcCallSites) {
+ List<VCExpr> newInterfaceExprs = new List<VCExpr>();
+ foreach (VCExpr expr in scs.interfaceExprs) {
+ newInterfaceExprs.Add(substVisitor.Mutate(expr, subst));
+ }
+ scs.interfaceExprs = newInterfaceExprs;
+ }
+ return gen.Implies(callSiteExpr, svc.vcexpr);
}
}
@@ -149,7 +182,7 @@ namespace VC { public Implementation impl;
public Function function;
public Variable controlFlowVariable;
- public Expr assertExpr;
+ public AssertCmd exitAssertCmd;
public VCExpr vcexpr;
public List<VCExprVar> interfaceExprVars;
public List<VCExprVar> privateExprVars;
@@ -209,7 +242,7 @@ namespace VC { public void GenerateVC() {
if (initialized) return;
List<Variable> outputVariables = new List<Variable>();
- assertExpr = new LiteralExpr(Token.NoToken, true);
+ Expr assertExpr = new LiteralExpr(Token.NoToken, true);
foreach (Variable v in impl.OutParams) {
Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
outputVariables.Add(c);
@@ -224,26 +257,29 @@ namespace VC { Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
assertExpr = Expr.And(assertExpr, eqExpr);
}
- assertExpr = Expr.Not(assertExpr);
+ exitAssertCmd = new AssertCmd(Token.NoToken, Expr.Not(assertExpr));
Program program = vcgen.program;
ProverInterface proverInterface = vcgen.prover;
vcgen.ConvertCFG2DAG(impl);
- ModelViewInfo mvInfo;
vcgen.PassifyImpl(impl, out mvInfo);
- controlFlowVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "@cfc", Microsoft.Boogie.Type.Int));
- impl.LocVars.Add(controlFlowVariable);
-
VCExpressionGenerator gen = proverInterface.VCExprGen;
var exprGen = proverInterface.Context.ExprGen;
var translator = proverInterface.Context.BoogieExprTranslator;
- VCExpr controlFlowVariableExpr = CommandLineOptions.Clo.UseLabels ? null : translator.LookupVariable(controlFlowVariable);
+ VCExpr controlFlowVariableExpr = null;
+ if (!CommandLineOptions.Clo.UseLabels) {
+ controlFlowVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "@cfc", Microsoft.Boogie.Type.Int));
+ controlFlowVariableExpr = translator.LookupVariable(controlFlowVariable);
+ vcgen.InstrumentCallSites(impl);
+ }
vcexpr = gen.Not(vcgen.GenerateVC(impl, controlFlowVariableExpr, out label2absy, proverInterface.Context));
if (controlFlowVariableExpr != null) {
VCExpr controlFlowFunctionAppl = exprGen.ControlFlowFunctionApplication(controlFlowVariableExpr, exprGen.Integer(BigNum.ZERO));
VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId)));
vcexpr = exprGen.And(eqExpr, vcexpr);
+ callSites = vcgen.CollectCallSites(impl);
+ recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl);
}
privateExprVars = new List<VCExprVar>();
@@ -265,51 +301,10 @@ namespace VC { interfaceExprVars.Add(translator.LookupVariable(v));
}
- callSites = vcgen.CollectCallSites(impl);
- recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl);
initialized = true;
}
}
- public class CallSitesSimplifier : StandardVisitor {
- VariableSeq localVars;
- StratifiedVCGenBase vcgen;
- public static void SimplifyCallSites(Implementation implementation, StratifiedVCGenBase vcgen) {
- CallSitesSimplifier visitor = new CallSitesSimplifier(vcgen);
- visitor.Visit(implementation);
- implementation.LocVars.AddRange(visitor.localVars);
- }
- private CallSitesSimplifier(StratifiedVCGenBase vcgen) {
- this.vcgen = vcgen;
- this.localVars = new VariableSeq();
- }
- public override CmdSeq VisitCmdSeq(CmdSeq cmdSeq) {
- CmdSeq newCmdSeq = new CmdSeq();
- foreach (Cmd cmd in cmdSeq) {
- AssumeCmd assumeCmd = cmd as AssumeCmd;
- if (assumeCmd == null) {
- newCmdSeq.Add(cmd);
- continue;
- }
- NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
- if (naryExpr == null || !vcgen.implName2StratifiedInliningInfo.ContainsKey(naryExpr.Fun.FunctionName)) {
- newCmdSeq.Add(cmd);
- continue;
- }
-
- ExprSeq exprs = new ExprSeq();
- foreach (Expr e in naryExpr.Args) {
- LocalVariable newVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "CallSiteSimplification@" + localVars.Length, e.Type));
- localVars.Add(newVar);
- newCmdSeq.Add(new AssumeCmd(Token.NoToken, Expr.Eq(Expr.Ident(newVar), e)));
- exprs.Add(Expr.Ident(newVar));
- }
- newCmdSeq.Add(new AssumeCmd(Token.NoToken, new NAryExpr(Token.NoToken, naryExpr.Fun, exprs)));
- }
- return newCmdSeq;
- }
- }
-
public abstract class StratifiedVCGenBase : VCGen {
public readonly static string recordProcName = "boogie_si_record";
public Dictionary<string, StratifiedInliningInfo> implName2StratifiedInliningInfo;
@@ -362,11 +357,33 @@ namespace VC { base.Close();
}
+ public void InstrumentCallSites(Implementation implementation) {
+ var callSiteId = 0;
+ foreach (Block block in implementation.Blocks) {
+ CmdSeq newCmds = new CmdSeq();
+ for (int i = 0; i < block.Cmds.Length; i++) {
+ Cmd cmd = block.Cmds[i];
+ newCmds.Add(cmd);
+ AssumeCmd assumeCmd = cmd as AssumeCmd;
+ if (assumeCmd == null) continue;
+ NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
+ if (naryExpr == null) continue;
+ if (!implName2StratifiedInliningInfo.ContainsKey(naryExpr.Fun.FunctionName)) continue;
+ Variable callSiteVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "StratifiedInliningCallSite" + callSiteId, Microsoft.Boogie.Type.Bool));
+ implementation.LocVars.Add(callSiteVar);
+ newCmds.Add(new AssumeCmd(Token.NoToken, new IdentifierExpr(Token.NoToken, callSiteVar)));
+ callSiteId++;
+ }
+ block.Cmds = newCmds;
+ }
+ }
+
public Dictionary<Block, List<CallSite>> CollectCallSites(Implementation implementation) {
var callSites = new Dictionary<Block, List<CallSite>>();
foreach (Block block in implementation.Blocks) {
for (int i = 0; i < block.Cmds.Length; i++) {
- AssumeCmd assumeCmd = block.Cmds[i] as AssumeCmd;
+ Cmd cmd = block.Cmds[i];
+ AssumeCmd assumeCmd = cmd as AssumeCmd;
if (assumeCmd == null) continue;
NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
if (naryExpr == null) continue;
@@ -375,7 +392,11 @@ namespace VC { foreach (Expr e in naryExpr.Args) {
interfaceExprs.Add(prover.Context.BoogieExprTranslator.Translate(e));
}
- CallSite cs = new CallSite(naryExpr.Fun.FunctionName, interfaceExprs, block, i);
+ int instr = i;
+ i++;
+ AssumeCmd callSiteAssumeCmd = (AssumeCmd)block.Cmds[i];
+ IdentifierExpr iexpr = (IdentifierExpr) callSiteAssumeCmd.Expr;
+ CallSite cs = new CallSite(naryExpr.Fun.FunctionName, interfaceExprs, prover.Context.BoogieExprTranslator.LookupVariable(iexpr.Decl), block, instr);
if (!callSites.ContainsKey(block))
callSites[block] = new List<CallSite>();
callSites[block].Add(cs);
@@ -397,7 +418,7 @@ namespace VC { foreach (Expr e in naryExpr.Args) {
interfaceExprs.Add(prover.Context.BoogieExprTranslator.Translate(e));
}
- CallSite cs = new CallSite(naryExpr.Fun.FunctionName, interfaceExprs, block, i);
+ CallSite cs = new CallSite(naryExpr.Fun.FunctionName, interfaceExprs, null, block, i);
if (!callSites.ContainsKey(block))
callSites[block] = new List<CallSite>();
callSites[block].Add(cs);
@@ -406,10 +427,16 @@ namespace VC { return callSites;
}
- private int newVarCountForStratifiedInlining = 0;
+ private int macroCountForStratifiedInlining = 0;
+ public Macro CreateNewMacro() {
+ string newName = "StratifiedInliningMacro@" + macroCountForStratifiedInlining.ToString();
+ macroCountForStratifiedInlining++;
+ return new Macro(Token.NoToken, newName, new VariableSeq(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool), false));
+ }
+ private int varCountForStratifiedInlining = 0;
public VCExprVar CreateNewVar(Microsoft.Boogie.Type type) {
- string newName = "StratifiedInlining@" + newVarCountForStratifiedInlining.ToString();
- newVarCountForStratifiedInlining++;
+ string newName = "StratifiedInliningVar@" + varCountForStratifiedInlining.ToString();
+ varCountForStratifiedInlining++;
Constant newVar = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, newName, type));
prover.Context.DeclareConstant(newVar, false, null);
return prover.VCExprGen.Variable(newVar.Name, type);
@@ -422,9 +449,9 @@ namespace VC { // Used inside PassifyImpl
protected override void addExitAssert(string implName, Block exitBlock) {
if (implName2StratifiedInliningInfo != null && implName2StratifiedInliningInfo.ContainsKey(implName)) {
- Expr assertExpr = implName2StratifiedInliningInfo[implName].assertExpr;
- Contract.Assert(assertExpr != null);
- exitBlock.Cmds.Add(new AssertCmd(Token.NoToken, assertExpr));
+ AssertCmd exitAssertCmd = implName2StratifiedInliningInfo[implName].exitAssertCmd;
+ Contract.Assert(exitAssertCmd != null);
+ exitBlock.Cmds.Add(exitAssertCmd);
}
}
|