3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 09:34:08 +00:00

Add MSF plugins

This commit is contained in:
Anh-Dung Phan 2013-12-27 11:18:10 -08:00
parent 58f8181a74
commit 5cc4cc8226
24 changed files with 2683 additions and 0 deletions

View file

@ -0,0 +1,60 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="MsfConfig"
type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation"
allowLocation="true"
allowDefinition="Everywhere"
allowExeDefinition="MachineToApplication"
restartOnExternalChanges="true"
requirePermission="true"/>
</configSections>
<MsfConfig>
<MsfPluginSolvers>
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
capability="MILP"
assembly="SolverFoundation.Plugin.Z3.dll"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
capability="LP"
assembly="SolverFoundation.Plugin.Z3.dll"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="MILP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="LP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="MINLP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="NLP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
</MsfPluginSolvers>
</MsfConfig>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SolverFoundation.Plugin.Z3.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SolverFoundation.Plugin.Z3.Tests")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("27657eee-ca7b-4996-a905-86a3f4584988")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Solvers;
using Microsoft.SolverFoundation.Services;
using Microsoft.SolverFoundation.Plugin.Z3;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.SolverFoundation.Plugin.Z3.Tests
{
[TestClass]
public class ServiceTests
{
[TestInitialize]
public void SetUp()
{
SolverContext context = SolverContext.GetContext();
context.ClearModel();
}
private void TestService1(Directive directive)
{
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
Decision x1 = new Decision(Domain.RealRange(0, 2), "x1");
Decision x2 = new Decision(Domain.RealRange(0, 2), "x2");
Decision z = new Decision(Domain.IntegerRange(0, 1), "z");
model.AddDecisions(x1, x2, z);
model.AddConstraint("Row0", x1 - z <= 1);
model.AddConstraint("Row1", x2 + z <= 2);
Goal goal = model.AddGoal("Goal0", GoalKind.Maximize, x1 + x2);
Solution solution = context.Solve(directive);
Assert.IsTrue(goal.ToInt32() == 3);
context.ClearModel();
}
private void TestService2(Directive directive)
{
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
Decision x1 = new Decision(Domain.RealNonnegative, "x1");
Decision x2 = new Decision(Domain.RealNonnegative, "x2");
Decision z = new Decision(Domain.IntegerRange(0, 1), "z");
Rational M = 100;
model.AddDecisions(x1, x2, z);
model.AddConstraint("Row0", x1 + x2 >= 1);
model.AddConstraint("Row1", x1 - z * 100 <= 0);
model.AddConstraint("Row2", x2 + z * 100 <= 100);
Goal goal = model.AddGoal("Goal0", GoalKind.Maximize, x1 + x2);
Solution solution = context.Solve(directive);
Assert.IsTrue(goal.ToInt32() == 100);
context.ClearModel();
}
[TestMethod]
public void TestService1()
{
TestService1(new Z3MILPDirective());
TestService1(new Z3TermDirective());
}
[TestMethod]
public void TestService2()
{
TestService2(new Z3MILPDirective());
TestService2(new Z3TermDirective());
}
}
}

View file

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{280AEE2F-1FDB-4A27-BE37-14DC154C873B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.SolverFoundation.Plugin.Z3.Tests</RootNamespace>
<AssemblyName>SolverFoundation.Plugin.Z3.Tests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Solver.Foundation">
<HintPath>..\Microsoft.Solver.Foundation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceTests.cs" />
<Compile Include="SolverTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SolverFoundation.Plugin.Z3\SolverFoundation.Plugin.Z3.csproj">
<Project>{7340e664-f648-4ff7-89b2-f4da424996d3}</Project>
<Name>SolverFoundation.Plugin.Z3</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Solvers;
using Microsoft.SolverFoundation.Services;
using Microsoft.SolverFoundation.Plugin.Z3;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.SolverFoundation.Plugin.Z3.Tests
{
[TestClass]
public class SolverTests
{
[TestMethod]
public void TestMILPSolver1()
{
var solver = new Z3MILPSolver();
int goal;
solver.AddRow("goal", out goal);
int x1, x2, z;
// 0 <= x1 <= 2
solver.AddVariable("x1", out x1);
solver.SetBounds(x1, 0, 2);
// 0 <= x2 <= 2
solver.AddVariable("x2", out x2);
solver.SetBounds(x2, 0, 2);
// z is an integer in [0,1]
solver.AddVariable("z", out z);
solver.SetIntegrality(z, true);
solver.SetBounds(z, 0, 1);
//max x1 + x2
solver.SetCoefficient(goal, x1, 1);
solver.SetCoefficient(goal, x2, 1);
solver.AddGoal(goal, 1, false);
// 0 <= x1 -z <= 1
int row1;
solver.AddRow("rowI1", out row1);
solver.SetBounds(row1, 0, 1);
solver.SetCoefficient(row1, x1, 1);
solver.SetCoefficient(row1, z, -1);
// 0 <= x2 + z <= 2
int row2;
solver.AddRow("rowI2", out row2);
solver.SetBounds(row2, 0, 2);
solver.SetCoefficient(row2, x2, 1);
solver.SetCoefficient(row2, z, 1);
var p = new Z3MILPParams();
solver.Solve(p);
Assert.IsTrue(solver.Result == LinearResult.Optimal);
Assert.AreEqual(solver.GetValue(x1), 2 * Rational.One);
Assert.AreEqual(solver.GetValue(x2), Rational.One);
Assert.AreEqual(solver.GetValue(z), Rational.One);
Assert.AreEqual(solver.GetValue(goal), 3 * Rational.One);
}
[TestMethod]
public void TestMILPSolver2()
{
var solver = new Z3MILPSolver();
int goal, extraGoal;
Rational M = 100;
solver.AddRow("goal", out goal);
int x1, x2, z;
// 0 <= x1 <= 100
solver.AddVariable("x1", out x1);
solver.SetBounds(x1, 0, M);
// 0 <= x2 <= 100
solver.AddVariable("x2", out x2);
solver.SetBounds(x2, 0, M);
// z is an integer in [0,1]
solver.AddVariable("z", out z);
solver.SetIntegrality(z, true);
solver.SetBounds(z, 0, 1);
solver.SetCoefficient(goal, x1, 1);
solver.SetCoefficient(goal, x2, 2);
solver.AddGoal(goal, 1, false);
solver.AddRow("extraGoal", out extraGoal);
solver.SetCoefficient(extraGoal, x1, 2);
solver.SetCoefficient(extraGoal, x2, 1);
solver.AddGoal(extraGoal, 2, false);
// x1 + x2 >= 1
int row;
solver.AddRow("row", out row);
solver.SetBounds(row, 1, Rational.PositiveInfinity);
solver.SetCoefficient(row, x1, 1);
solver.SetCoefficient(row, x2, 1);
// x1 - M*z <= 0
int row1;
solver.AddRow("rowI1", out row1);
solver.SetBounds(row1, Rational.NegativeInfinity, 0);
solver.SetCoefficient(row1, x1, 1);
solver.SetCoefficient(row1, z, -M);
// x2 - M* (1-z) <= 0
int row2;
solver.AddRow("rowI2", out row2);
solver.SetBounds(row2, Rational.NegativeInfinity, M);
solver.SetCoefficient(row2, x2, 1);
solver.SetCoefficient(row2, z, M);
var p = new Z3MILPParams();
p.OptKind = OptimizationKind.BoundingBox;
solver.Solve(p);
Assert.IsTrue(solver.Result == LinearResult.Optimal);
Assert.AreEqual(solver.GetValue(goal), 200 * Rational.One);
Assert.AreEqual(solver.GetValue(extraGoal), 200 * Rational.One);
}
}
}

View file

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Z3;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
/// <summary>
/// Thread that will wait until the query abort function returns true or
/// the stop method is called. If the abort function returns true at some
/// point it will issue a softCancel() call to Z3.
/// </summary>
internal class AbortWorker
{
#region Private Members
/// <summary>The Z3 solver</summary>
private Microsoft.Z3.Context _context;
/// <summary>The abort function to use to check if we are aborted</summary>
private Func<bool> _QueryAbortFunction;
/// <summary>Flag indicating that worker should stop</summary>
private bool _stop = false;
/// <summary>Flag indicating that we have been sent an abort signal</summary>
private bool _aborted = false;
#endregion Private Members
#region Construction
/// <summary>
/// Worker constructor taking a Z3 instance and a function to periodically
/// check for aborts.
/// </summary>
/// <param name="z3">Z3 instance</param>
/// <param name="queryAbortFunction">method to call to check for aborts</param>
public AbortWorker(Context context, Func<bool> queryAbortFunction)
{
_context = context;
_QueryAbortFunction = queryAbortFunction;
}
#endregion Construction
#region Public Methods
/// <summary>
/// Stop the abort worker.
/// </summary>
public void Stop()
{
_stop = true;
}
/// <summary>
/// Is true if we have been aborted.
/// </summary>
public bool Aborted
{
get
{
return _aborted;
}
}
/// <summary>
/// Starts the abort worker. The worker checks the abort method
/// periodically until either it is stopped by a call to the Stop()
/// method or it gets an abort signal. In the latter case it will
/// issue a soft abort signal to Z3.
/// </summary>
public void Start()
{
// We go until someone stops us
_stop = false;
while (!_stop && !_QueryAbortFunction())
{
// Wait for a while
Thread.Sleep(10);
}
// If we were stopped on abort, cancel z3
if (!_stop)
{
_context.Interrupt();
_aborted = true;
}
}
#endregion Public Methods
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SolverFoundation.Plugin.Z3")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("SolverFoundation.Plugin.Z3")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("ed1476c0-96de-4d2c-983d-3888b140c3ad")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7340E664-F648-4FF7-89B2-F4DA424996D3}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.SolverFoundation.Plugin.Z3</RootNamespace>
<AssemblyName>SolverFoundation.Plugin.Z3</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial|AnyCPU'">
<OutputPath>bin\commercial\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Release\Z3Solver.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>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial_64|AnyCPU'">
<OutputPath>bin\commercial_64\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Release\Z3Solver.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>
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
<CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
</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>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial|x86'">
<OutputPath>bin\x86\commercial\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial_64|x86'">
<OutputPath>bin\x86\commercial_64\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Solver.Foundation">
<HintPath>..\Microsoft.Solver.Foundation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Z3">
<HintPath>..\Microsoft.Z3.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AbortWorker.cs" />
<Compile Include="Utils.cs" />
<Compile Include="Z3BaseDirective.cs" />
<Compile Include="Z3BaseParams.cs" />
<Compile Include="Z3BaseSolver.cs" />
<Compile Include="Z3MILPDirective.cs" />
<Compile Include="Z3MILPParams.cs" />
<Compile Include="Z3MILPSolver.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Z3TermDirective.cs" />
<Compile Include="Z3TermParams.cs" />
<Compile Include="Z3TermSolver.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Z3;
using Microsoft.SolverFoundation.Common;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
public class Utils
{
/// <summary>
/// Returns the Z3 term corresponding to the MSF rational number.
/// </summary>
/// <param name="rational">The MSF rational</param>
/// <returns>The Z3 term</returns>
public static ArithExpr GetNumeral(Context context, Rational rational, Sort sort = null)
{
try
{
sort = rational.IsInteger() ? ((Sort)context.IntSort) : (sort == null ? (Sort)context.RealSort : sort);
return (ArithExpr)context.MkNumeral(rational.ToString(), sort);
}
catch (Z3Exception e)
{
Console.Error.WriteLine("Conversion of {0} failed:\n {1}", rational, e);
throw new NotSupportedException();
}
}
private static long BASE = 10 ^ 18;
private static Rational ToRational(System.Numerics.BigInteger bi)
{
if (System.Numerics.BigInteger.Abs(bi) <= BASE)
{
return (Rational)((long)bi);
}
return BASE * ToRational(bi / BASE) + ToRational(bi % BASE);
}
public static Rational ToRational(IntNum i)
{
return ToRational(i.BigInteger);
}
public static Rational ToRational(RatNum r)
{
return ToRational(r.BigIntNumerator) / ToRational(r.BigIntDenominator);
}
public static Rational ToRational(Expr expr)
{
Debug.Assert(expr is ArithExpr, "Only accept ArithExpr for now.");
var e = expr as ArithExpr;
if (e is IntNum)
{
Debug.Assert(expr.IsIntNum, "Number should be an integer.");
return ToRational(expr as IntNum);
}
if (e is RatNum)
{
Debug.Assert(expr.IsRatNum, "Number should be a rational.");
return ToRational(expr as RatNum);
}
if (e.IsAdd)
{
Rational r = Rational.Zero;
foreach (var arg in e.Args)
{
r += ToRational(arg);
}
return r;
}
if (e.IsMul)
{
Rational r = Rational.One;
foreach (var arg in e.Args)
{
r *= ToRational(arg);
}
return r;
}
if (e.IsUMinus)
{
return -ToRational(e.Args[0]);
}
if (e.IsDiv)
{
return ToRational(e.Args[0]) / ToRational(e.Args[1]);
}
if (e.IsSub)
{
Rational r = ToRational(e.Args[0]);
for (int i = 1; i < e.Args.Length; ++i)
{
r -= ToRational(e.Args[i]);
}
return r;
}
if (e.IsConst && e.FuncDecl.Name.ToString() == "oo")
{
return Rational.PositiveInfinity;
}
if (e.IsConst && e.FuncDecl.Name.ToString() == "epsilon")
{
return Rational.One/Rational.PositiveInfinity;
}
Debug.Assert(false, "Should not happen");
return Rational.One;
}
}
}

View file

@ -0,0 +1,101 @@
using System;
using System.Text;
using Microsoft.SolverFoundation.Services;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
/// <summary>
/// Combining objective functions
/// </summary>
public enum OptimizationKind
{
Lexicographic,
BoundingBox,
ParetoOptimal
};
/// <summary>
/// Algorithm for solving cardinality constraints
/// </summary>
public enum CardinalityAlgorithm
{
FuMalik,
CoreMaxSAT
}
/// <summary>
/// Algorithm for solving pseudo-boolean constraints
/// </summary>
public enum PseudoBooleanAlgorithm
{
WeightedMaxSAT,
IterativeWeightedMaxSAT,
BisectionWeightedMaxSAT,
WeightedPartialMaxSAT2
}
/// <summary>
/// Strategy for solving arithmetic optimization
/// </summary>
public enum ArithmeticStrategy
{
Basic,
Farkas
}
public abstract class Z3BaseDirective : Directive
{
protected OptimizationKind _optKind;
protected CardinalityAlgorithm _cardAlgorithm;
protected PseudoBooleanAlgorithm _pboAlgorithm;
protected ArithmeticStrategy _arithStrategy;
protected string _smt2LogFile;
public Z3BaseDirective()
{
Arithmetic = Arithmetic.Exact;
}
public OptimizationKind OptKind
{
get { return _optKind; }
set { _optKind = value; }
}
public CardinalityAlgorithm CardinalityAlgorithm
{
get { return _cardAlgorithm; }
set { _cardAlgorithm = value; }
}
public PseudoBooleanAlgorithm PseudoBooleanAlgorithm
{
get { return _pboAlgorithm; }
set { _pboAlgorithm = value; }
}
public ArithmeticStrategy ArithmeticStrategy
{
get { return _arithStrategy; }
set { _arithStrategy = value; }
}
public string SMT2LogFile
{
get { return _smt2LogFile; }
set { _smt2LogFile = value; }
}
public override string ToString()
{
var sb = new StringBuilder();
sb.Append(this.GetType().Name);
sb.Append("(");
sb.AppendFormat("OptKind: {0}, ", _optKind);
sb.AppendFormat("SMT2LogFile: {0}", _smt2LogFile);
sb.Append(")");
return sb.ToString();
}
}
}

View file

@ -0,0 +1,103 @@
using Microsoft.SolverFoundation.Services;
using System;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
/// <summary>
/// Implementation of the solver parameters for Z3
/// </summary>
public class Z3BaseParams : ISolverParameters
{
#region Private Members
/// <summary>The abort method we can call (defaults to always false)
protected Func<bool> _queryAbortFunction = delegate() { return false; };
/// <summary>The directive to use</summary>
protected Directive _directive = null;
protected OptimizationKind _optKind;
protected CardinalityAlgorithm _cardAlgorithm;
protected PseudoBooleanAlgorithm _pboAlgorithm;
protected ArithmeticStrategy _arithStrategy;
protected string _smt2LogFile;
#endregion Private Members
#region Construction
public Z3BaseParams() { }
public Z3BaseParams(Directive directive)
{
_directive = directive;
var z3Directive = directive as Z3BaseDirective;
if (z3Directive != null)
{
_optKind = z3Directive.OptKind;
_cardAlgorithm = z3Directive.CardinalityAlgorithm;
_pboAlgorithm = z3Directive.PseudoBooleanAlgorithm;
_arithStrategy = z3Directive.ArithmeticStrategy;
_smt2LogFile = z3Directive.SMT2LogFile;
}
}
public Z3BaseParams(Func<bool> queryAbortFunction)
{
_queryAbortFunction = queryAbortFunction;
}
public Z3BaseParams(Z3BaseParams z3Parameters)
{
_queryAbortFunction = z3Parameters._queryAbortFunction;
}
#endregion Construction
#region ISolverParameters Members
/// <summary>
/// Getter for the abort method
/// </summary>
public Func<bool> QueryAbort
{
get { return _queryAbortFunction; }
set { _queryAbortFunction = value; }
}
public OptimizationKind OptKind
{
get { return _optKind; }
set { _optKind = value; }
}
public CardinalityAlgorithm CardinalityAlgorithm
{
get { return _cardAlgorithm; }
set { _cardAlgorithm = value; }
}
public PseudoBooleanAlgorithm PseudoBooleanAlgorithm
{
get { return _pboAlgorithm; }
set { _pboAlgorithm = value; }
}
public ArithmeticStrategy ArithmeticStrategy
{
get { return _arithStrategy; }
set { _arithStrategy = value; }
}
public string SMT2LogFile
{
get { return _smt2LogFile; }
set { _smt2LogFile = value; }
}
#endregion
}
}

View file

@ -0,0 +1,381 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Z3;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
internal enum Z3Result
{
Optimal,
LocalOptimal,
Feasible,
Interrupted,
Infeasible
}
/// <summary>
/// The basic solver class to take care of transformation from an MSF instance to an Z3 instance
/// </summary>
internal class Z3BaseSolver
{
/// <summary>Representing MSF model</summary>
private IRowVariableModel _model;
/// <summary>The Z3 solver we are currently using</summary>
private Context _context = null;
/// <summary>Default optimization solver</summary>
private Optimize _optSolver = null;
/// <summary>Marks when we are inside the Solve() method</summary>
private bool _isSolving = false;
/// <summary>A map from MSF variable ids to Z3 variables</summary>
private Dictionary<int, Expr> _variables = new Dictionary<int, Expr>();
/// <summary>A map from MSF variable ids to Z3 goal ids</summary>
private Dictionary<IGoal, uint> _goals = new Dictionary<IGoal, uint>();
internal Z3BaseSolver(IRowVariableModel model)
{
_model = model;
}
internal Context Context
{
get { return _context; }
}
internal Dictionary<int, Expr> Variables
{
get { return _variables; }
}
internal Dictionary<IGoal, uint> Goals
{
get { return _goals; }
}
/// <summary>
/// Destructs a currently active Z3 solver and the associated data.
/// </summary>
internal void DestructSolver(bool checkInSolve)
{
if (_context != null)
{
if (checkInSolve && !_isSolving)
{
_variables.Clear();
if (!_isSolving)
{
_optSolver.Dispose();
_context.Dispose();
}
}
else
{
Console.Error.WriteLine("Z3 destruction is invoked while in Solving phase.");
}
}
}
/// <summary>
/// Constructs a Z3 solver to be used.
/// </summary>
internal void ConstructSolver(Z3BaseParams parameters)
{
// If Z3 is there already, kill it
if (_context != null)
{
DestructSolver(false);
}
_context = new Context();
_optSolver = _context.MkOptimize();
var p = _context.MkParams();
switch (parameters.OptKind)
{
case OptimizationKind.BoundingBox:
p.Add("priority", _context.MkSymbol("box"));
break;
case OptimizationKind.Lexicographic:
p.Add("priority", _context.MkSymbol("lex"));
break;
case OptimizationKind.ParetoOptimal:
p.Add("priority", _context.MkSymbol("pareto"));
break;
default:
Debug.Assert(false, String.Format("Unknown optimization option {0}", parameters.OptKind));
break;
}
switch (parameters.CardinalityAlgorithm)
{
case CardinalityAlgorithm.FuMalik:
p.Add("maxsat_engine", _context.MkSymbol("fu_malik"));
break;
case CardinalityAlgorithm.CoreMaxSAT:
p.Add("maxsat_engine", _context.MkSymbol("core_maxsat"));
break;
default:
Debug.Assert(false, String.Format("Unknown cardinality algorithm option {0}", parameters.CardinalityAlgorithm));
break;
}
switch (parameters.PseudoBooleanAlgorithm)
{
case PseudoBooleanAlgorithm.WeightedMaxSAT:
p.Add("wmaxsat_engine", _context.MkSymbol("wmax"));
break;
case PseudoBooleanAlgorithm.IterativeWeightedMaxSAT:
p.Add("wmaxsat_engine", _context.MkSymbol("iwmax"));
break;
case PseudoBooleanAlgorithm.BisectionWeightedMaxSAT:
p.Add("wmaxsat_engine", _context.MkSymbol("bwmax"));
break;
case PseudoBooleanAlgorithm.WeightedPartialMaxSAT2:
p.Add("wmaxsat_engine", _context.MkSymbol("wpm2"));
break;
default:
Debug.Assert(false, String.Format("Unknown pseudo-boolean algorithm option {0}", parameters.PseudoBooleanAlgorithm));
break;
}
switch (parameters.ArithmeticStrategy)
{
case ArithmeticStrategy.Basic:
p.Add("engine", _context.MkSymbol("basic"));
break;
case ArithmeticStrategy.Farkas:
p.Add("engine", _context.MkSymbol("farkas"));
break;
default:
Debug.Assert(false, String.Format("Unknown arithmetic strategy option {0}", parameters.ArithmeticStrategy));
break;
}
_optSolver.Parameters = p;
}
internal ArithExpr GetVariable(int vid)
{
Expr variable;
if (!_variables.TryGetValue(vid, out variable))
{
AddVariable(vid);
variable = _variables[vid];
}
return (ArithExpr)variable;
}
internal void AssertBool(BoolExpr row)
{
_optSolver.Assert(row);
}
internal void AssertArith(int vid, ArithExpr variable)
{
// Get the bounds on the row
Rational lower, upper;
_model.GetBounds(vid, out lower, out upper);
// Case of equality
if (lower == upper)
{
// Create the equality term
Expr eqConst = GetNumeral(lower, variable.Sort);
BoolExpr constraint = _context.MkEq(eqConst, variable);
// Assert the constraint
_optSolver.Assert(constraint);
}
else
{
// If upper bound is finite assert the upper bound constraint
if (lower.IsFinite)
{
// Create the lower Bound constraint
ArithExpr lowerTerm = GetNumeral(lower, variable.Sort);
BoolExpr constraint = _context.MkLe(lowerTerm, variable);
// Assert the constraint
_optSolver.Assert(constraint);
}
// If lower bound is finite assert the lower bound constraint
if (upper.IsFinite)
{
// Create the upper bound constraint
ArithExpr upperTerm = GetNumeral(upper, variable.Sort);
BoolExpr constraint = _context.MkGe(upperTerm, variable);
// Assert the constraint
_optSolver.Assert(constraint);
}
}
}
/// <summary>
/// Adds a MSF variable with the coresponding assertion to the Z3 variables.
/// </summary>
/// <param name="vid">The MSF id of the variable</param>
internal void AddVariable(int vid)
{
// Is the variable an integer
bool isInteger = _model.GetIntegrality(vid);
// Construct the sort we will be using
Sort sort = isInteger ? (Sort)_context.IntSort : (Sort)_context.RealSort;
// Get the variable key
object key = _model.GetKeyFromIndex(vid);
// Try to construct the name
string name;
if (key != null) name = String.Format("x_{0}_{1}", key, vid);
else name = String.Format("x_{0}", vid);
ArithExpr variable = (ArithExpr)_context.MkConst(name, sort);
// Create the variable and add it to the map
Debug.Assert(!_variables.ContainsKey(vid), "Variable names should be unique.");
_variables.Add(vid, variable);
AssertArith(vid, variable);
}
internal ArithExpr GetNumeral(Rational rational, Sort sort = null)
{
return Utils.GetNumeral(_context, rational, sort);
}
internal void Solve(Z3BaseParams parameters, IEnumerable<IGoal> modelGoals,
Action<int> addRow, Func<int, ArithExpr> mkGoalRow, Action<Z3Result> setResult)
{
_variables.Clear();
_goals.Clear();
try
{
// Mark that we are in solving phase
_isSolving = true;
// Construct Z3
ConstructSolver(parameters);
// Add all the variables
foreach (int vid in _model.VariableIndices)
{
AddVariable(vid);
}
// Add all the rows
foreach (int rid in _model.RowIndices)
{
addRow(rid);
}
// Add enabled goals to optimization problem
foreach (IGoal g in modelGoals)
{
if (!g.Enabled) continue;
ArithExpr gr = mkGoalRow(g.Index);
if (g.Minimize)
_goals.Add(g, _optSolver.MkMinimize(gr));
else
_goals.Add(g, _optSolver.MkMaximize(gr));
}
if (_goals.Any() && parameters.SMT2LogFile != null)
{
Debug.WriteLine("Dumping SMT2 benchmark to log file...");
File.WriteAllText(parameters.SMT2LogFile, _optSolver.ToString());
}
bool aborted = parameters.QueryAbort();
if (!aborted)
{
// Start the abort thread
AbortWorker abortWorker = new AbortWorker(_context, parameters.QueryAbort);
Thread abortThread = new Thread(abortWorker.Start);
abortThread.Start();
// Now solve the problem
Status status = _optSolver.Check();
// Stop the abort thread
abortWorker.Stop();
abortThread.Join();
switch (status)
{
case Status.SATISFIABLE:
Microsoft.Z3.Model model = _optSolver.Model;
Debug.Assert(model != null, "Should be able to get Z3 model.");
// Remember the solution values
foreach (KeyValuePair<int, Expr> pair in _variables)
{
var value = Utils.ToRational(model.Eval(pair.Value, true));
_model.SetValue(pair.Key, value);
}
// Remember all objective values
foreach (var pair in _goals)
{
var optimalValue = Utils.ToRational(_optSolver.GetUpper(pair.Value));
_model.SetValue(pair.Key.Index, optimalValue);
}
model.Dispose();
setResult(_goals.Any() ? Z3Result.Optimal : Z3Result.Feasible);
break;
case Status.UNSATISFIABLE:
setResult(Z3Result.Infeasible);
break;
case Status.UNKNOWN:
if (abortWorker.Aborted)
{
Microsoft.Z3.Model subOptimalModel = _optSolver.Model;
if (subOptimalModel != null && subOptimalModel.NumConsts != 0)
{
// Remember the solution values
foreach (KeyValuePair<int, Expr> pair in _variables)
{
var value = Utils.ToRational(subOptimalModel.Eval(pair.Value, true));
_model.SetValue(pair.Key, value);
}
// Remember all objective values
foreach (var pair in _goals)
{
var optimalValue = Utils.ToRational(_optSolver.GetUpper(pair.Value));
_model.SetValue(pair.Key.Index, optimalValue);
}
subOptimalModel.Dispose();
setResult(Z3Result.LocalOptimal);
}
else
setResult(Z3Result.Infeasible);
}
else
setResult(Z3Result.Interrupted);
break;
default:
Debug.Assert(false, "Unrecognized Z3 Status");
break;
}
}
}
finally
{
_isSolving = false;
}
// Now kill Z3
DestructSolver(true);
}
}
}

View file

@ -0,0 +1,9 @@
using Microsoft.SolverFoundation.Services;
using System;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
public class Z3MILPDirective : Z3BaseDirective
{
}
}

View file

@ -0,0 +1,19 @@
using Microsoft.SolverFoundation.Services;
using System;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
public class Z3MILPParams : Z3BaseParams
{
// Need these constructors for reflection done by plugin model
public Z3MILPParams() : base() { }
public Z3MILPParams(Directive directive) : base(directive) { }
public Z3MILPParams(Func<bool> queryAbortFunction) : base(queryAbortFunction) { }
public Z3MILPParams(Z3BaseParams z3Parameters) : base (z3Parameters) { }
}
}

View file

@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.IO;
using Microsoft.Z3;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;
using Microsoft.SolverFoundation.Plugin;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
/// <summary>
/// The class is implementation of the MSF mixed linear programming solver
/// using the Microsoft Z3 solver as the backend.
/// </summary>
public class Z3MILPSolver : LinearModel, ILinearSolver, ILinearSolution, IReportProvider
{
#region Private members
private LinearResult _result;
private LinearSolutionQuality _solutionQuality;
private Z3BaseSolver _solver;
#endregion Private members
#region Solver construction and destruction
/// <summary>Constructor that initializes the base clases</summary>
public Z3MILPSolver() : base(null)
{
_result = LinearResult.Feasible;
_solver = new Z3BaseSolver(this);
}
/// <summary>Constructor that initializes the base clases</summary>
public Z3MILPSolver(ISolverEnvironment context) : this() { }
/// <summary>
/// Shutdown can be called when when the solver is not active, i.e.
/// when it is done with Solve() or it has gracefully returns from Solve()
/// after an abort.
/// </summary>
public void Shutdown() { _solver.DestructSolver(true); }
#endregion Solver construction and destruction
#region Obtaining information about the solution
public ILinearSolverReport GetReport(LinearSolverReportType reportType)
{
// We don't support sensitivity report
return null;
}
#endregion Obtaining information about the solution
#region Construction of the problem
/// <summary>
/// Get corresponding Z3 formula of a MSF row.
/// </summary>
/// <param name="rid">The MSF row id</param>
private ArithExpr MkGoalRow(int rid)
{
// Start with the 0 term
List<ArithExpr> row = new List<ArithExpr>();
// Now, add all the entries of this row
foreach (LinearEntry entry in GetRowEntries(rid))
{
// Get the variable and constant in the row
ArithExpr e = _solver.GetVariable(entry.Index);
if (!entry.Value.IsOne)
{
e = _solver.Context.MkMul(_solver.GetNumeral(entry.Value, e.Sort), e);
}
row.Add(e);
}
switch (row.Count)
{
case 0: return _solver.GetNumeral(new Rational());
case 1: return row[0];
default: return _solver.Context.MkAdd(row.ToArray());
}
}
/// <summary>
/// Adds a MSF row to the Z3 assertions.
/// </summary>
/// <param name="rid">The MSF row id</param>
private void AddRow(int rid)
{
// Start with the 0 term
ArithExpr row = MkGoalRow(rid);
_solver.AssertArith(rid, row);
}
/// <summary>
/// Set results based on internal solver status
/// </summary>
private void SetResult(Z3Result status)
{
switch (status)
{
case Z3Result.Optimal:
_result = LinearResult.Optimal;
_solutionQuality = LinearSolutionQuality.Exact;
break;
case Z3Result.LocalOptimal:
_result = LinearResult.Feasible;
_solutionQuality = LinearSolutionQuality.Approximate;
break;
case Z3Result.Feasible:
_result = LinearResult.Feasible;
_solutionQuality = LinearSolutionQuality.Exact;
break;
case Z3Result.Infeasible:
_result = LinearResult.InfeasiblePrimal;
_solutionQuality = LinearSolutionQuality.None;
break;
case Z3Result.Interrupted:
_result = LinearResult.Interrupted;
_solutionQuality = LinearSolutionQuality.None;
break;
default:
Debug.Assert(false, "Unrecognized Z3 Result");
break;
}
}
#endregion Construction of the problem
#region Solving the problem
/// <summary>
/// Starts solving the problem using the Z3 solver.
/// </summary>
/// <param name="parameters">Parameters to the solver</param>
/// <returns>The solution to the problem</returns>
public ILinearSolution Solve(ISolverParameters parameters)
{
// Get the Z3 parameters
var z3Params = parameters as Z3BaseParams;
Debug.Assert(z3Params != null, "Parameters should be an instance of Z3BaseParams.");
_solver.Solve(z3Params, Goals, AddRow, MkGoalRow, SetResult);
return this;
}
#endregion Solving the problem
#region ILinearSolution Members
public Rational GetSolutionValue(int goalIndex)
{
var goal = Goals.ElementAt(goalIndex);
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
return GetValue(goal.Index);
}
public void GetSolvedGoal(int goalIndex, out object key, out int vid, out bool minimize, out bool optimal)
{
var goal = Goals.ElementAt(goalIndex);
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
key = goal.Key;
vid = goal.Index;
minimize = goal.Minimize;
optimal = _result == LinearResult.Optimal;
}
// LpResult is LP relaxation assignment.
public LinearResult LpResult
{
get { return _result; }
}
public Rational MipBestBound
{
get
{
Debug.Assert(GoalCount > 0, "MipBestBound is only applicable for optimization instances.");
return GetSolutionValue(0);
}
}
public LinearResult MipResult
{
get { return _result; }
}
public LinearResult Result
{
get { return _result; }
}
public LinearSolutionQuality SolutionQuality
{
get { return _solutionQuality; }
}
public int SolvedGoalCount
{
get { return GoalCount; }
}
#endregion
public Report GetReport(SolverContext context, Solution solution, SolutionMapping solutionMapping)
{
LinearSolutionMapping lpSolutionMapping = solutionMapping as LinearSolutionMapping;
if (lpSolutionMapping == null && solutionMapping != null)
throw new ArgumentException("solutionMapping is not a LinearSolutionMapping", "solutionMapping");
return new Z3LinearSolverReport(context, this, solution, lpSolutionMapping);
}
}
/// <summary>
/// Class implementing the LinearReport.
/// </summary>
public class Z3LinearSolverReport : LinearReport
{
public Z3LinearSolverReport(SolverContext context, ISolver solver, Solution solution, LinearSolutionMapping solutionMapping)
: base(context, solver, solution, solutionMapping) {
}
}
}

View file

@ -0,0 +1,9 @@
using Microsoft.SolverFoundation.Services;
using System;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
public class Z3TermDirective : Z3BaseDirective
{
}
}

View file

@ -0,0 +1,17 @@
using Microsoft.SolverFoundation.Services;
using System;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
public class Z3TermParams : Z3BaseParams
{
public Z3TermParams() : base() { }
public Z3TermParams(Directive directive) : base(directive) { }
public Z3TermParams(Func<bool> queryAbortFunction) : base(queryAbortFunction) { }
public Z3TermParams(Z3BaseParams z3Parameters) : base(z3Parameters) { }
}
}

View file

@ -0,0 +1,382 @@
using System;
using System.Threading;
using System.Globalization;
using System.Collections.Generic;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Properties;
using Microsoft.SolverFoundation.Solvers;
using Microsoft.SolverFoundation.Services;
using Microsoft.Z3;
using System.Linq;
using System.Diagnostics;
using System.IO;
namespace Microsoft.SolverFoundation.Plugin.Z3
{
/// <summary>
/// The class is implementation of the MSF constraint solver
/// using the Microsoft Z3 solver as the backend.
/// This solver supports Int, Real constraints and their arbitrary boolean combinations.
/// </summary>
public class Z3TermSolver : TermModel, ITermSolver, INonlinearSolution, IReportProvider
{
private NonlinearResult _result;
private Z3BaseSolver _solver;
/// <summary>Constructor that initializes the base clases</summary>
public Z3TermSolver() : base(null)
{
_solver = new Z3BaseSolver(this);
}
/// <summary>Constructor that initializes the base clases</summary>
public Z3TermSolver(ISolverEnvironment context) : this() { }
/// <summary>
/// Shutdown can be called when when the solver is not active, i.e.
/// when it is done with Solve() or it has gracefully returns from Solve()
/// after an abort.
/// </summary>
public void Shutdown() { _solver.DestructSolver(true); }
private BoolExpr MkBool(int rid)
{
var context = _solver.Context;
if (IsConstant(rid))
{
Rational lower, upper;
GetBounds(rid, out lower, out upper);
Debug.Assert(lower == upper);
if (lower.IsZero) return context.MkFalse();
return context.MkTrue();
}
if (IsOperation(rid))
{
BoolExpr[] children;
ArithExpr[] operands;
TermModelOperation op = GetOperation(rid);
switch(op) {
case TermModelOperation.And:
Debug.Assert(GetOperandCount(rid) >= 2, "Conjunction requires at least two operands.");
children = (GetOperands(rid)).Select(x => MkBool(x)).ToArray();
return context.MkAnd(children);
case TermModelOperation.Or:
Debug.Assert(GetOperandCount(rid) >= 2, "Disjunction requires at least two operands.");
children = (GetOperands(rid)).Select(x => MkBool(x)).ToArray();
return context.MkOr(children);
case TermModelOperation.Not:
Debug.Assert(GetOperandCount(rid) == 1, "Negation is unary.");
return context.MkNot(MkBool(GetOperand(rid, 0)));
case TermModelOperation.If:
Debug.Assert(GetOperandCount(rid) == 3, "If is ternary.");
BoolExpr b = MkBool(GetOperand(rid, 0));
Expr x1 = MkBool(GetOperand(rid, 1));
Expr x2 = MkBool(GetOperand(rid, 2));
return (BoolExpr)context.MkITE(b, x1, x2);
case TermModelOperation.Unequal:
Debug.Assert(GetOperandCount(rid) >= 2, "Distinct should have at least two operands.");
return context.MkDistinct((GetOperands(rid)).Select(x => MkTerm(x)).ToArray());
case TermModelOperation.Greater:
case TermModelOperation.Less:
case TermModelOperation.GreaterEqual:
case TermModelOperation.LessEqual:
case TermModelOperation.Equal:
Debug.Assert(GetOperandCount(rid) >= 2, "Comparison should have at least two operands.");
operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray();
return ReduceComparison(GetOperation(rid), operands);
case TermModelOperation.Identity:
Debug.Assert(GetOperandCount(rid) == 1, "Identity takes exactly one operand.");
return MkBool(GetOperand(rid, 0));
default:
return context.MkEq(MkTerm(rid), _solver.GetNumeral(Rational.One));
}
}
return context.MkEq(MkTerm(rid), _solver.GetNumeral(Rational.One));
}
private ArithExpr MkBoolToArith(BoolExpr e)
{
var context = _solver.Context;
return (ArithExpr)context.MkITE(e, _solver.GetNumeral(Rational.One), _solver.GetNumeral(Rational.Zero));
}
private ArithExpr MkTerm(int rid)
{
var context = _solver.Context;
if (IsConstant(rid))
{
Rational lower, upper;
GetBounds(rid, out lower, out upper);
Debug.Assert(lower == upper);
return _solver.GetNumeral(lower);
}
else if (IsOperation(rid))
{
ArithExpr[] operands;
TermModelOperation op = GetOperation(rid);
switch(op)
{
case TermModelOperation.And:
case TermModelOperation.Or:
case TermModelOperation.Not:
case TermModelOperation.Unequal:
case TermModelOperation.Greater:
case TermModelOperation.Less:
case TermModelOperation.GreaterEqual:
case TermModelOperation.LessEqual:
case TermModelOperation.Equal:
return MkBoolToArith(MkBool(rid));
case TermModelOperation.If:
Debug.Assert(GetOperandCount(rid) == 3, "If is ternary.");
BoolExpr b = MkBool(GetOperand(rid, 0));
Expr x1 = MkTerm(GetOperand(rid, 1));
Expr x2 = MkTerm(GetOperand(rid, 2));
return (ArithExpr)context.MkITE(b, x1, x2);
case TermModelOperation.Plus:
Debug.Assert(GetOperandCount(rid) >= 2, "Plus takes at least two operands.");
operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray();
return context.MkAdd(operands);
case TermModelOperation.Minus:
Debug.Assert(GetOperandCount(rid) == 1, "Minus takes exactly one operand.");
return context.MkUnaryMinus(MkTerm(GetOperand(rid, 0)));
case TermModelOperation.Times:
Debug.Assert(GetOperandCount(rid) >= 2, "Times requires at least two operands.");
operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray();
return context.MkMul(operands);
case TermModelOperation.Identity:
Debug.Assert(GetOperandCount(rid) == 1, "Identity takes exactly one operand.");
return MkTerm(GetOperand(rid, 0));
case TermModelOperation.Abs:
Debug.Assert(GetOperandCount(rid) == 1, "Abs takes exactly one operand.");
ArithExpr e = MkTerm(GetOperand(rid, 0));
ArithExpr minusE = context.MkUnaryMinus(e);
ArithExpr zero = _solver.GetNumeral(Rational.Zero);
return (ArithExpr)context.MkITE(context.MkGe(e, zero), e, minusE);
default:
Console.Error.WriteLine("{0} operation isn't supported.", op);
throw new NotSupportedException();
}
}
else
{
return _solver.GetVariable(rid);
}
}
private BoolExpr ReduceComparison(TermModelOperation type, ArithExpr[] operands)
{
var context = _solver.Context;
Debug.Assert(operands.Length >= 2);
Func<ArithExpr, ArithExpr, BoolExpr> mkComparison;
switch (type)
{
case TermModelOperation.Greater:
mkComparison = (x, y) => context.MkGt(x, y);
break;
case TermModelOperation.Less:
mkComparison = (x, y) => context.MkLt(x, y);
break;
case TermModelOperation.GreaterEqual:
mkComparison = (x, y) => context.MkGe(x, y);
break;
case TermModelOperation.LessEqual:
mkComparison = (x, y) => context.MkLe(x, y);
break;
case TermModelOperation.Equal:
mkComparison = (x, y) => context.MkEq(x, y);
break;
default:
throw new NotSupportedException();
}
BoolExpr current = mkComparison(operands[0], operands[1]);
for (int i = 1; i < operands.Length - 1; ++i)
current = context.MkAnd(current, mkComparison(operands[i], operands[i + 1]));
return current;
}
private bool IsBoolRow(int rid)
{
Rational lower, upper;
GetBounds(rid, out lower, out upper);
return lower == upper && lower.IsOne && IsBoolTerm(rid);
}
private bool IsBoolTerm(int rid)
{
if (IsConstant(rid))
{
Rational lower, upper;
GetBounds(rid, out lower, out upper);
Debug.Assert(lower == upper);
return lower.IsOne || lower.IsZero;
}
if (IsOperation(rid))
{
TermModelOperation op = GetOperation(rid);
switch (op)
{
case TermModelOperation.And:
case TermModelOperation.Or:
case TermModelOperation.Not:
case TermModelOperation.LessEqual:
case TermModelOperation.Less:
case TermModelOperation.Greater:
case TermModelOperation.GreaterEqual:
case TermModelOperation.Unequal:
case TermModelOperation.Equal:
return true;
case TermModelOperation.If:
return IsBoolTerm(GetOperand(rid, 1)) &&
IsBoolTerm(GetOperand(rid, 2));
case TermModelOperation.Identity:
return IsBoolTerm(GetOperand(rid, 0));
default:
return false;
}
}
return false;
}
/// <summary>
/// Adds a MSF row to the Z3 assertions.
/// </summary>
/// <param name="rid">The MSF row id</param>
private void AddRow(int rid)
{
if (IsConstant(rid))
return;
if (IsBoolRow(rid))
{
_solver.AssertBool(MkBool(rid));
return;
}
// Start with the 0 term
ArithExpr row = MkTerm(rid);
_solver.AssertArith(rid, row);
}
private TermModelOperation[] _supportedOperations =
{ TermModelOperation.And,
TermModelOperation.Or,
TermModelOperation.Not,
TermModelOperation.Unequal,
TermModelOperation.Greater,
TermModelOperation.Less,
TermModelOperation.GreaterEqual,
TermModelOperation.LessEqual,
TermModelOperation.Equal,
TermModelOperation.If,
TermModelOperation.Plus,
TermModelOperation.Minus,
TermModelOperation.Times,
TermModelOperation.Identity,
TermModelOperation.Abs };
/// <summary>
/// Gets the operations supported by the solver.
/// </summary>
/// <returns>All the TermModelOperations supported by the solver.</returns>
public IEnumerable<TermModelOperation> SupportedOperations
{
get { return _supportedOperations; }
}
/// <summary>
/// Set results based on internal solver status
/// </summary>
private void SetResult(Z3Result status)
{
switch (status)
{
case Z3Result.Optimal:
_result = NonlinearResult.Optimal;
break;
case Z3Result.LocalOptimal:
_result = NonlinearResult.LocalOptimal;
break;
case Z3Result.Feasible:
_result = NonlinearResult.Feasible;
break;
case Z3Result.Infeasible:
_result = NonlinearResult.Infeasible;
break;
case Z3Result.Interrupted:
_result = NonlinearResult.Interrupted;
break;
default:
Debug.Assert(false, "Unrecognized Z3 Result");
break;
}
}
/// <summary>
/// Starts solving the problem using the Z3 solver.
/// </summary>
/// <param name="parameters">Parameters to the solver</param>
/// <returns>The solution to the problem</returns>
public INonlinearSolution Solve(ISolverParameters parameters)
{
// Get the Z3 parameters
var z3Params = parameters as Z3BaseParams;
Debug.Assert(z3Params != null, "Parameters should be an instance of Z3BaseParams.");
_solver.Solve(z3Params, Goals, AddRow, MkTerm, SetResult);
return this;
}
double INonlinearSolution.GetValue(int vid)
{
Debug.Assert(_solver.Variables.ContainsKey(vid), "This index should correspond to a variable.");
return GetValue(vid).ToDouble();
}
public int SolvedGoalCount
{
get { return GoalCount; }
}
public double GetSolutionValue(int goalIndex)
{
var goal = Goals.ElementAt(goalIndex);
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
return GetValue(goal.Index).ToDouble();
}
public void GetSolvedGoal(int goalIndex, out object key, out int vid, out bool minimize, out bool optimal)
{
var goal = Goals.ElementAt(goalIndex);
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
key = goal.Key;
vid = goal.Index;
minimize = goal.Minimize;
optimal = _result == NonlinearResult.Optimal;
}
public NonlinearResult Result
{
get { return _result; }
}
public Report GetReport(SolverContext context, Solution solution, SolutionMapping solutionMapping)
{
PluginSolutionMapping pluginSolutionMapping = solutionMapping as PluginSolutionMapping;
if (pluginSolutionMapping == null && solutionMapping != null)
throw new ArgumentException("solutionMapping is not a LinearSolutionMapping", "solutionMapping");
return new Z3TermSolverReport(context, this, solution, pluginSolutionMapping);
}
}
public class Z3TermSolverReport : Report
{
public Z3TermSolverReport(SolverContext context, ISolver solver, Solution solution, PluginSolutionMapping pluginSolutionMapping)
: base(context, solver, solution, pluginSolutionMapping)
{
}
}
}

View file

@ -0,0 +1,60 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="MsfConfig"
type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation"
allowLocation="true"
allowDefinition="Everywhere"
allowExeDefinition="MachineToApplication"
restartOnExternalChanges="true"
requirePermission="true"/>
</configSections>
<MsfConfig>
<MsfPluginSolvers>
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
capability="MILP"
assembly="SolverFoundation.Plugin.Z3.dll"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
capability="LP"
assembly="SolverFoundation.Plugin.Z3.dll"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="MILP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="LP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="MINLP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="NLP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
</MsfPluginSolvers>
</MsfConfig>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="MsfConfig"
type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation"
allowLocation="true"
allowDefinition="Everywhere"
allowExeDefinition="MachineToApplication"
restartOnExternalChanges="true"
requirePermission="true" />
</configSections>
<MsfConfig>
<MsfPluginSolvers>
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
capability="MILP"
assembly="SolverFoundation.Plugin.Z3.dll"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
capability="LP"
assembly="SolverFoundation.Plugin.Z3.dll"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="MILP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="LP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="MINLP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
<MsfPluginSolver name="Microsoft Z3 Term Solver"
capability="NLP"
assembly="SolverFoundation.Plugin.Z3.dll"
interface="Microsoft.SolverFoundation.Services.ITermSolver"
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
</MsfPluginSolvers>
</MsfConfig>
</configuration>

View file

@ -0,0 +1,194 @@
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Solvers;
using Microsoft.SolverFoundation.Plugin.Z3;
using Microsoft.SolverFoundation.Services;
using System.Text;
namespace Validator
{
class Program
{
static void LoadModel(SolverContext context, string fileName)
{
string ext = Path.GetExtension(fileName).ToLower();
if (ext == ".mps")
{
context.LoadModel(FileFormat.MPS, Path.GetFullPath(fileName));
}
else if (ext == ".smps")
{
context.LoadModel(FileFormat.SMPS, Path.GetFullPath(fileName));
}
else if (ext == ".oml")
{
context.LoadModel(FileFormat.OML, Path.GetFullPath(fileName));
}
else
{
throw new NotSupportedException("This file format hasn't been supported.");
}
}
static void ExecuteZ3(string fileName, Z3BaseDirective directive)
{
SolverContext context = SolverContext.GetContext();
try
{
LoadModel(context, fileName);
Solution solution = context.Solve(directive);
Report report = solution.GetReport();
Console.Write("{0}", report);
}
catch (Exception e)
{
Console.WriteLine("Skipping unsolvable instance in {0} with error message '{1}'.", fileName, e.Message);
}
finally
{
context.ClearModel();
}
}
static void ConvertToSMT2(string fileName, Z3BaseDirective directive)
{
SolverContext context = SolverContext.GetContext();
try
{
LoadModel(context, fileName);
if (context.CurrentModel.Goals.Any())
{
directive.SMT2LogFile = Path.ChangeExtension(fileName, ".smt2");
context.Solve(() => true, directive);
}
}
catch (Exception e)
{
Console.WriteLine("Skipping unconvertable instance in {0} with error message '{1}'.", fileName, e.Message);
}
finally
{
context.ClearModel();
}
}
static void ValidateZ3(string fileName, Z3BaseDirective directive)
{
SolverContext context = SolverContext.GetContext();
try
{
LoadModel(context, fileName);
if (context.CurrentModel.Goals.Any())
{
var msfDirective = (directive is Z3MILPDirective) ? (Directive)new MixedIntegerProgrammingDirective() { TimeLimit = 10000 }
: (Directive)new Directive() { TimeLimit = 10000 };
var sol1 = context.Solve(msfDirective);
Console.WriteLine("Solved the model using MSF.");
Console.Write("{0}", sol1.GetReport());
var expectedGoals = sol1.Goals.Select(x => x.ToDouble());
context.ClearModel();
context.LoadModel(FileFormat.OML, Path.GetFullPath(fileName));
directive.SMT2LogFile = Path.ChangeExtension(fileName, ".smt2");
var sol2 = context.Solve(directive);
//Console.Write("{0}", sol2.GetReport());
var actualGoals = sol2.Goals.Select(x => x.ToDouble());
Console.WriteLine("Solved the model using Z3.");
var goalPairs = expectedGoals.Zip(actualGoals, (expected, actual) => new { expected, actual }).ToArray();
bool validated = goalPairs.All(p => Math.Abs(p.expected - p.actual) <= 0.0001);
if (validated)
{
Console.WriteLine("INFO: Two solvers give approximately the same results.");
}
else
{
Console.Error.WriteLine("ERROR: Discrepancy found between results.");
if (!validated && File.Exists(directive.SMT2LogFile))
{
var sb = new StringBuilder();
for(int i = 0; i < goalPairs.Length; i++)
{
sb.AppendFormat("\n(echo \"Goal {0}: actual |-> {1:0.0000}, expected |-> {2:0.0000}\")",
i + 1, goalPairs[i].actual, goalPairs[i].expected);
}
Console.Error.WriteLine(sb.ToString());
File.AppendAllText(directive.SMT2LogFile, sb.ToString());
}
}
}
else
{
Console.WriteLine("Ignoring this instance without having any goal.");
}
}
catch (Exception e)
{
Console.WriteLine("Skipping unsolvable instance in {0} with error message '{1}'.",
fileName, e.Message);
}
finally
{
context.ClearModel();
}
}
static void Main(string[] args)
{
Z3BaseDirective directive = new Z3MILPDirective();
for (int i = 0; i < args.Length; ++i) {
if (args[i] == "-s" || args[i] == "-solve")
{
ExecuteZ3(args[i + 1], directive);
return;
}
if (args[i] == "-c" || args[i] == "-convert")
{
ConvertToSMT2(args[i + 1], directive);
return;
}
if (args[i] == "-v" || args[i] == "-validate")
{
ValidateZ3(args[i + 1], directive);
return;
}
if (args[i] == "-t" || args[i] == "-term")
{
directive = new Z3TermDirective();
}
}
if (args.Length > 0)
{
ExecuteZ3(args[0], directive);
return;
}
Console.WriteLine(@"
Validator is a simple command line to migrate benchmarks from OML, MPS and SMPS to SMT2 formats.
Commands:
-solve <file_name> : solving the model using Z3
-convert <file_name> : converting the model into SMT2 format
-validate <file_name> : validating by comparing results between Z3 and MSF solvers
-term : change the default Z3 MILP solver to Z3 Term solver
where <file_name> is any file with OML, MPS or SMPS extension.
Examples:
Validator.exe -convert model.mps
Validator.exe -term -solve model.oml
");
}
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("testSolver")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("testSolver")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c03c1084-d119-483f-80fe-c639eae75959")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{54835857-129F-44C9-B529-A42158647B36}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Validator</RootNamespace>
<AssemblyName>Validator</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
</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>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Solver.Foundation">
<HintPath>..\Microsoft.Solver.Foundation.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="MicrosoftSolverFoundationForExcel.dll.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SolverFoundation.Plugin.Z3\SolverFoundation.Plugin.Z3.csproj">
<Project>{7340e664-f648-4ff7-89b2-f4da424996d3}</Project>
<Name>SolverFoundation.Plugin.Z3</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,120 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SolverFoundation.Plugin.Z3", "SolverFoundation.Plugin.Z3\SolverFoundation.Plugin.Z3.csproj", "{7340E664-F648-4FF7-89B2-F4DA424996D3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SolverFoundation.Plugin.Z3.Tests", "SolverFoundation.Plugin.Z3.Tests\SolverFoundation.Plugin.Z3.Tests.csproj", "{280AEE2F-1FDB-4A27-BE37-14DC154C873B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validator", "Validator\Validator.csproj", "{54835857-129F-44C9-B529-A42158647B36}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
commercial_64|Any CPU = commercial_64|Any CPU
commercial_64|Mixed Platforms = commercial_64|Mixed Platforms
commercial_64|x64 = commercial_64|x64
commercial_64|x86 = commercial_64|x86
commercial|Any CPU = commercial|Any CPU
commercial|Mixed Platforms = commercial|Mixed Platforms
commercial|x64 = commercial|x64
commercial|x86 = commercial|x86
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Any CPU.ActiveCfg = commercial_64|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Any CPU.Build.0 = commercial_64|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Mixed Platforms.ActiveCfg = commercial_64|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Mixed Platforms.Build.0 = commercial_64|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|x64.ActiveCfg = commercial_64|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|x86.ActiveCfg = commercial_64|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|x86.Build.0 = commercial_64|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Any CPU.ActiveCfg = commercial|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Any CPU.Build.0 = commercial|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Mixed Platforms.ActiveCfg = commercial|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Mixed Platforms.Build.0 = commercial|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|x64.ActiveCfg = commercial|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|x86.ActiveCfg = commercial|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|x86.Build.0 = commercial|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Mixed Platforms.Build.0 = Debug|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|x64.ActiveCfg = Debug|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|x86.ActiveCfg = Debug|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|x86.Build.0 = Debug|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Any CPU.Build.0 = Release|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Mixed Platforms.ActiveCfg = Release|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Mixed Platforms.Build.0 = Release|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|x64.ActiveCfg = Release|Any CPU
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|x86.ActiveCfg = Release|x86
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|x86.Build.0 = Release|x86
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Any CPU.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Any CPU.Build.0 = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Mixed Platforms.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Mixed Platforms.Build.0 = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|x64.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|x86.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Any CPU.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Any CPU.Build.0 = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Mixed Platforms.Build.0 = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|x64.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|x86.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|x64.ActiveCfg = Debug|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|x86.ActiveCfg = Debug|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|x86.Build.0 = Debug|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Any CPU.Build.0 = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|x64.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|x86.ActiveCfg = Release|Any CPU
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|x86.Build.0 = Release|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Any CPU.ActiveCfg = Release|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Any CPU.Build.0 = Release|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Mixed Platforms.ActiveCfg = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Mixed Platforms.Build.0 = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x64.ActiveCfg = Release|x64
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x64.Build.0 = Release|x64
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x86.ActiveCfg = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x86.Build.0 = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.commercial|Any CPU.ActiveCfg = Release|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.commercial|Any CPU.Build.0 = Release|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.commercial|Mixed Platforms.ActiveCfg = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.commercial|Mixed Platforms.Build.0 = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.commercial|x64.ActiveCfg = Release|x64
{54835857-129F-44C9-B529-A42158647B36}.commercial|x64.Build.0 = Release|x64
{54835857-129F-44C9-B529-A42158647B36}.commercial|x86.ActiveCfg = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.commercial|x86.Build.0 = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{54835857-129F-44C9-B529-A42158647B36}.Debug|Mixed Platforms.Build.0 = Debug|x86
{54835857-129F-44C9-B529-A42158647B36}.Debug|x64.ActiveCfg = Debug|x64
{54835857-129F-44C9-B529-A42158647B36}.Debug|x64.Build.0 = Debug|x64
{54835857-129F-44C9-B529-A42158647B36}.Debug|x86.ActiveCfg = Debug|x86
{54835857-129F-44C9-B529-A42158647B36}.Debug|x86.Build.0 = Debug|x86
{54835857-129F-44C9-B529-A42158647B36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.Release|Any CPU.Build.0 = Release|Any CPU
{54835857-129F-44C9-B529-A42158647B36}.Release|Mixed Platforms.ActiveCfg = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.Release|Mixed Platforms.Build.0 = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.Release|x64.ActiveCfg = Release|x64
{54835857-129F-44C9-B529-A42158647B36}.Release|x64.Build.0 = Release|x64
{54835857-129F-44C9-B529-A42158647B36}.Release|x86.ActiveCfg = Release|x86
{54835857-129F-44C9-B529-A42158647B36}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal