3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-06 15:25:46 +00:00

Merge branch 'unstable' of https://github.com/wintersteiger/z3 into unstable

This commit is contained in:
Christoph M. Wintersteiger 2015-06-14 19:00:09 -07:00
commit 3a49223076
545 changed files with 70367 additions and 4623 deletions

1
.gitignore vendored
View file

@ -19,6 +19,7 @@ ocamlz3
# Emacs temp files
\#*\#
# Directories with generated code and documentation
release/*
build/*
build-dist/*
dist/*

View file

@ -1,6 +1,6 @@
RELEASE NOTES
Version 4.4
Version 4.4.0
=============
- New feature: Support for the theory of floating-point numbers. This comes in the form of logics (QF_FP and QF_FPBV), tactics (qffp and qffpbv), as well as a theory plugin that allows theory combinations. Z3 supports the official SMT theory definition of FP (see http://smtlib.cs.uiowa.edu/theories/FloatingPoint.smt2) in SMT2 files, as well as all APIs.

View file

@ -1,3 +1,5 @@
# Copyright (c) Microsoft Corporation 2015
import os
import shutil
import re

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#include<vector>
#include"z3++.h"
@ -205,6 +211,9 @@ void bitvector_example1() {
// using unsigned <=
prove(ule(x - 10, 0) == ule(x, 10));
expr y = c.bv_const("y", 32);
prove(implies(concat(x, y) == concat(y, x), x == y));
}
/**
@ -977,6 +986,30 @@ void substitute_example() {
std::cout << new_f << std::endl;
}
void opt_example() {
context c;
optimize opt(c);
params p(c);
p.set("priority",c.str_symbol("pareto"));
opt.set(p);
expr x = c.int_const("x");
expr y = c.int_const("y");
opt.add(10 >= x && x >= 0);
opt.add(10 >= y && y >= 0);
opt.add(x + y <= 11);
optimize::handle h1 = opt.maximize(x);
optimize::handle h2 = opt.maximize(y);
check_result r = sat;
while (true) {
if (sat == opt.check()) {
std::cout << x << ": " << opt.lower(h1) << " " << y << ": " << opt.lower(h2) << "\n";
}
else {
break;
}
}
}
void extract_example() {
std::cout << "extract example\n";
context c;
@ -1025,6 +1058,7 @@ int main() {
expr_vector_example(); std::cout << "\n";
exists_expr_vector_example(); std::cout << "\n";
substitute_example(); std::cout << "\n";
opt_example(); std::cout << "\n";
extract_example(); std::cout << "\n";
std::cout << "done\n";
}

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

View file

@ -759,7 +759,7 @@ namespace test_mapi
foreach (BoolExpr a in g.Formulas)
solver.Assert(a);
if (solver.Check() != Status.SATISFIABLE)
if (solver.Check() != Status.SATISFIABLE)
throw new TestFailedException();
ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g);

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
/*
Simple MAXSAT solver on top of the Z3 API.
*/

20
examples/msf/README Normal file
View file

@ -0,0 +1,20 @@
In order to use Z3 MSF plugin, follow the following steps:
1. Compile latest Z3 .NET API (from any branch consisting of opt features) and copy 'libz3.dll' and 'Microsoft.Z3.dll' to the folder of 'Z3MSFPlugin.sln'.
2. Retrieve 'Microsoft.Solver.Foundation.dll' from http://archive.msdn.microsoft.com/solverfoundation/Release/ProjectReleases.aspx?ReleaseId=1799,
preferably using DLL only version. Copy 'Microsoft.Solver.Foundation.dll' to the folder of 'Z3MSFPlugin.sln'
3. Build 'Z3MSFPlugin.sln'. Note that you have to compile using x86 target for Microsoft.Z3.dll 32-bit and x64 target for Microsoft.Z3.dll 64-bit.
The solution consists of a plugin project, a test project with a few simple test cases and a command line projects for external OML, MPS and SMPS models.
To retrieve SMT2 models which are native to Z3, set the logging file in corresponding directives or solver params e.g.
var p = new Z3MILPParams();
p.SMT2LogFile = "model.smt2";
For more details, check out the commands in 'Validator\Program.cs'.
Enjoy!

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,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,149 @@
<?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>
<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>
<ErrorReport>prompt</ErrorReport>
</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>
<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>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>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Solver.Foundation">
<HintPath>..\Microsoft.Solver.Foundation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Z3, Version=4.3.2.0, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Microsoft.Z3.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq">
</Reference>
<Reference Include="System.Data.DataSetExtensions">
</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>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

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,123 @@
<?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>
<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">
</Reference>
<Reference Include="System.Xml.Linq">
</Reference>
<Reference Include="System.Data.DataSetExtensions">
</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>
<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,125 @@

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
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F1E99540-BA5E-46DF-9E29-6146A309CD18}"
ProjectSection(SolutionItems) = preProject
README = README
EndProjectSection
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

View file

@ -47,13 +47,13 @@ class ComplexExpr:
return ComplexExpr(other.r*self.r - other.i*self.i, other.i*self.r + other.r*self.i)
def __pow__(self, k):
if k == 0:
return ComplexExpr(1, 0)
if k == 1:
return self
if k < 0:
return (self ** (-k)).inv()
return reduce(lambda x, y: x * y, [self for _ in xrange(k)], ComplexExpr(1, 0))
if k == 0:
return ComplexExpr(1, 0)
if k == 1:
return self
if k < 0:
return (self ** (-k)).inv()
return reduce(lambda x, y: x * y, [self for _ in xrange(k)], ComplexExpr(1, 0))
def inv(self):
den = self.r*self.r + self.i*self.i

View file

@ -1,3 +1,5 @@
# Copyright (c) Microsoft Corporation 2015
from z3 import *
x = Real('x')

View file

@ -0,0 +1,88 @@
############################################
# Copyright (c) 2012 Ganesh Gopalakrishnan ganesh@cs.utah.edu
#
# Check if the given graph has a Hamiltonian cycle.
#
# Author: Ganesh Gopalakrishnan ganesh@cs.utah.edu
############################################
from z3 import *
def gencon(gr):
"""
Input a graph as an adjacency list, e.g. {0:[1,2], 1:[2], 2:[1,0]}.
Produces solver to check if the given graph has
a Hamiltonian cycle. Query the solver using s.check() and if sat,
then s.model() spells out the cycle. Two example graphs from
http://en.wikipedia.org/wiki/Hamiltonian_path are tested.
=======================================================
Explanation:
Generate a list of Int vars. Constrain the first Int var ("Node 0") to be 0.
Pick a node i, and attempt to number all nodes reachable from i to have a
number one higher (mod L) than assigned to node i (use an Or constraint).
=======================================================
"""
L = len(gr)
cv = [Int('cv%s'%i) for i in range(L)]
s = Solver()
s.add(cv[0]==0)
for i in range(L):
s.add(Or([cv[j]==(cv[i]+1)%L for j in gr[i]]))
return s
def examples():
# Example Graphs: The Dodecahedral graph from http://en.wikipedia.org/wiki/Hamiltonian_path
grdodec = { 0: [1, 4, 5],
1: [0, 7, 2],
2: [1, 9, 3],
3: [2, 11, 4],
4: [3, 13, 0],
5: [0, 14, 6],
6: [5, 16, 7],
7: [6, 8, 1],
8: [7, 17, 9],
9: [8, 10, 2],
10: [9, 18, 11],
11: [10, 3, 12],
12: [11, 19, 13],
13: [12, 14, 4],
14: [13, 15, 5],
15: [14, 16, 19],
16: [6, 17, 15],
17: [16, 8, 18],
18: [10, 19, 17],
19: [18, 12, 15] }
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(grdodec)
sdodec=gencon(grdodec)
print(sdodec.check())
print(sdodec.model())
# =======================================================
# See http://en.wikipedia.org/wiki/Hamiltonian_path for the Herschel graph
# being the smallest possible polyhdral graph that does not have a Hamiltonian
# cycle.
#
grherschel = { 0: [1, 9, 10, 7],
1: [0, 8, 2],
2: [1, 9, 3],
3: [2, 8, 4],
4: [3, 9, 10, 5],
5: [4, 8, 6],
6: [5, 10, 7],
7: [6, 8, 0],
8: [1, 3, 5, 7],
9: [2, 0, 4],
10: [6, 4, 0] }
pp.pprint(grherschel)
sherschel=gencon(grherschel)
print(sherschel.check())
# =======================================================
if __name__ == "__main__":
examples()

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#include <string>
#include <cstring>
#include <list>
@ -809,8 +815,12 @@ class env {
r = terms[0] / terms[1];
}
else if (!strcmp(ch,"$distinct")) {
check_arity(terms.size(), 2);
r = terms[0] != terms[1];
if (terms.size() == 2) {
r = terms[0] != terms[1];
}
else {
r = distinct(terms);
}
}
else if (!strcmp(ch,"$floor") || !strcmp(ch,"$to_int")) {
check_arity(terms.size(), 1);
@ -1089,12 +1099,11 @@ class env {
}
z3::sort mk_sort(char const* s) {
z3::symbol sym = symbol(s);
return mk_sort(sym);
return m_context.uninterpreted_sort(s);
}
z3::sort mk_sort(z3::symbol& s) {
return z3::sort(m_context, Z3_mk_uninterpreted_sort(m_context, s));
return m_context.uninterpreted_sort(s);
}
public:
@ -2083,7 +2092,7 @@ bool parse_is_sat_line(char const* line, bool& is_sat) {
return true;
}
return false;
}
}
bool parse_is_sat(char const* filename, bool& is_sat) {
std::ifstream is(filename);

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#ifndef TPTP5_H_
#define TPTP5_H_

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#line 2 "tptp5.lex.cpp"
#line 4 "tptp5.lex.cpp"

57
scripts/mk_copyright.py Normal file
View file

@ -0,0 +1,57 @@
# Copyright (c) 2015 Microsoft Corporation
import os
import re
cr = re.compile("Copyright")
aut = re.compile("Automatically generated")
cr_notice = """
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
"""
def has_cr(file):
ins = open(file)
lines = 0
line = ins.readline()
while line and lines < 20:
m = cr.search(line)
if m:
ins.close()
return True
m = aut.search(line)
if m:
ins.close()
return True
line = ins.readline()
ins.close()
return False
def add_cr(file):
tmp = "%s.tmp" % file
ins = open(file)
ous = open(tmp,'w')
ous.write(cr_notice)
line = ins.readline()
while line:
ous.write(line)
line = ins.readline()
ins.close()
ous.close()
os.system("move %s %s" % (tmp, file))
def add_missing_cr(dir):
for root, dirs, files in os.walk(dir):
for f in files:
if f.endswith('.cpp') or f.endswith('.h') or f.endswith('.c'):
path = "%s\\%s" % (root, f)
if not has_cr(path):
print "Missing CR for %s" % path
add_cr(path)
add_missing_cr('src')
add_missing_cr('examples')

View file

@ -9,12 +9,13 @@ from mk_util import *
# Z3 Project definition
def init_project_def():
set_version(4, 4, 0, 0)
set_version(4, 4, 1, 0)
add_lib('util', [])
add_lib('polynomial', ['util'], 'math/polynomial')
add_lib('sat', ['util'])
add_lib('nlsat', ['polynomial', 'sat'])
add_lib('hilbert', ['util'], 'math/hilbert')
add_lib('simplex', ['util'], 'math/simplex')
add_lib('interval', ['util'], 'math/interval')
add_lib('realclosure', ['interval'], 'math/realclosure')
add_lib('subpaving', ['interval'], 'math/subpaving')
@ -49,37 +50,40 @@ def init_project_def():
add_lib('smt_params', ['ast', 'simplifier', 'pattern', 'bit_blaster'], 'smt/params')
add_lib('proto_model', ['model', 'simplifier', 'smt_params'], 'smt/proto_model')
add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', 'proto_model',
'substitution', 'grobner', 'euclid', 'proof_checker', 'pattern', 'parser_util', 'fpa'])
'substitution', 'grobner', 'euclid', 'simplex', 'proof_checker', 'pattern', 'parser_util', 'fpa'])
add_lib('user_plugin', ['smt'], 'smt/user_plugin')
add_lib('bv_tactics', ['tactic', 'bit_blaster'], 'tactic/bv')
add_lib('fuzzing', ['ast'], 'test/fuzzing')
add_lib('smt_tactic', ['smt'], 'smt/tactic')
add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic', 'smt_tactic'], 'tactic/fpa')
add_lib('sls_tactic', ['tactic', 'normal_forms', 'core_tactics', 'bv_tactics'], 'tactic/sls')
add_lib('qe', ['smt','sat'], 'qe')
add_lib('duality', ['smt', 'interp', 'qe'])
add_lib('muz', ['smt', 'sat', 'smt2parser', 'aig_tactic', 'qe'], 'muz/base')
add_lib('transforms', ['muz', 'hilbert'], 'muz/transforms')
add_lib('rel', ['muz', 'transforms'], 'muz/rel')
add_lib('pdr', ['muz', 'transforms', 'arith_tactics', 'smt_tactic'], 'muz/pdr')
add_lib('pdr', ['muz', 'transforms', 'arith_tactics', 'core_tactics', 'smt_tactic'], 'muz/pdr')
add_lib('clp', ['muz', 'transforms'], 'muz/clp')
add_lib('tab', ['muz', 'transforms'], 'muz/tab')
add_lib('bmc', ['muz', 'transforms'], 'muz/bmc')
add_lib('ddnf', ['muz', 'transforms', 'rel'], 'muz/ddnf')
add_lib('duality_intf', ['muz', 'transforms', 'duality'], 'muz/duality')
add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf'], 'muz/fp')
add_lib('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe'], 'tactic/smtlogics')
add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf'], 'muz/fp')
add_lib('nlsat_smt_tactic', ['nlsat_tactic', 'smt_tactic'], 'tactic/nlsat_smt')
add_lib('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe','nlsat_smt_tactic'], 'tactic/smtlogics')
add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic', 'smt_tactic', 'arith_tactics', 'smtlogic_tactics'], 'tactic/fpa')
add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv')
add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
add_lib('smtparser', ['portfolio'], 'parsers/smt')
add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic'], 'opt')
# add_dll('foci2', ['util'], 'interp/foci2stub',
# dll_name='foci2',
# export_files=['foci2stub.cpp'])
# add_lib('interp', ['solver','foci2'])
API_files = ['z3_api.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_interp.h', 'z3_fpa.h']
add_lib('api', ['portfolio', 'user_plugin', 'smtparser', 'realclosure', 'interp'],
add_lib('api', ['portfolio', 'user_plugin', 'smtparser', 'realclosure', 'interp', 'opt'],
includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files)
add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3')
add_exe('test', ['api', 'fuzzing'], exe_name='test-z3', install=False)
add_exe('shell', ['api', 'sat', 'extra_cmds','opt'], exe_name='z3')
add_exe('test', ['api', 'fuzzing', 'simplex'], exe_name='test-z3', install=False)
add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll',
reexports=['api'],
dll_name='libz3',

View file

@ -85,6 +85,10 @@ VS_PAR=False
VS_PAR_NUM=8
GPROF=False
GIT_HASH=False
OPTIMIZE=False
FPMATH="Default"
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
def check_output(cmd):
return str(subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]).rstrip('\r\n')
@ -227,10 +231,37 @@ def test_openmp(cc):
t.add('#include<omp.h>\nint main() { return omp_in_parallel() ? 1 : 0; }\n')
t.commit()
if IS_WINDOWS:
return exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '/openmp']) == 0
r = exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '/openmp']) == 0
try:
rmf('tstomp.obj')
rmf('tstomp.exe')
except:
pass
return r
else:
return exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '-fopenmp']) == 0
def test_fpmath(cc):
global FPMATH_FLAGS
if is_verbose():
print("Testing floating point support...")
t = TempFile('tstsse.cpp')
t.add('int main() { return 42; }\n')
t.commit()
if exec_compiler_cmd([cc, CPPFLAGS, 'tstsse.cpp', LDFLAGS, '-mfpmath=sse -msse -msse2']) == 0:
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
return "SSE2-GCC"
elif exec_compiler_cmd([cc, CPPFLAGS, 'tstsse.cpp', LDFLAGS, '-msse -msse2']) == 0:
FPMATH_FLAGS="-msse -msse2"
return "SSE2-CLANG"
elif exec_compiler_cmd([cc, CPPFLAGS, 'tstsse.cpp', LDFLAGS, '-mfpu=vfp -mfloat-abi=hard']) == 0:
FPMATH_FLAGS="-mfpu=vfp -mfloat-abi=hard"
return "ARM-VFP"
else:
FPMATH_FLAGS=""
return "UNKNOWN"
def find_jni_h(path):
for root, dirs, files in os.walk(path):
for f in files:
@ -357,10 +388,14 @@ def check_ml():
r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml'])
if r != 0:
raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler. Note that ocamlopt may require flexlink to be in your path.')
rmf('hello.cmi')
rmf('hello.cmo')
rmf('hello.cmx')
rmf('a.out')
try:
rmf('hello.cmi')
rmf('hello.cmo')
rmf('hello.cmx')
rmf('a.out')
rmf('hello.o')
except:
pass
find_ml_lib()
find_ocaml_find()
@ -517,6 +552,8 @@ def display_help(exit_code):
print(" -v, --vsproj generate Visual Studio Project Files.")
if IS_WINDOWS:
print(" -n, --nodotnet do not generate Microsoft.Z3.dll make rules.")
if IS_WINDOWS:
print(" --optimize generate optimized code during linking.")
print(" -j, --java generate Java bindings.")
print(" --ml generate OCaml bindings.")
print(" --staticlib build Z3 static library.")
@ -543,13 +580,13 @@ def display_help(exit_code):
def parse_options():
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
global DOTNET_ENABLED, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH
global LINUX_X64
global LINUX_X64, OPTIMIZE
try:
options, remainder = getopt.gnu_getopt(sys.argv[1:],
'b:df:sxhmcvtnp:gj',
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof',
'githash=', 'x86', 'ml'])
'githash=', 'x86', 'ml', 'optimize'])
except:
print("ERROR: Invalid command line option")
display_help(1)
@ -584,6 +621,8 @@ def parse_options():
DOTNET_ENABLED = False
elif opt in ('--staticlib'):
STATIC_LIB = True
elif opt in ('--optimize'):
OPTIMIZE = True
elif not IS_WINDOWS and opt in ('-p', '--prefix'):
PREFIX = arg
PYTHON_PACKAGE_DIR = os.path.join(PREFIX, 'lib', 'python%s' % distutils.sysconfig.get_python_version(), 'dist-packages')
@ -1712,7 +1751,6 @@ def mk_config():
'OBJ_EXT=.obj\n'
'LIB_EXT=.lib\n'
'AR=lib\n'
'AR_FLAGS=/nologo /LTCG\n'
'AR_OUTFLAG=/OUT:\n'
'EXE_EXT=.exe\n'
'LINK=cl\n'
@ -1731,22 +1769,25 @@ def mk_config():
extra_opt = ' %s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH)
if DEBUG_MODE:
config.write(
'AR_FLAGS=/nologo\n'
'LINK_FLAGS=/nologo /MDd\n'
'SLINK_FLAGS=/nologo /LDd\n')
if not VS_X64:
config.write(
'CXXFLAGS=/c /GL /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
config.write(
'LINK_EXTRA_FLAGS=/link /LTCG /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /LTCG /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
else:
config.write(
'CXXFLAGS=/c /GL /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n' % extra_opt)
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n' % extra_opt)
config.write(
'LINK_EXTRA_FLAGS=/link /LTCG /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /LTCG /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
else:
# Windows Release mode
if OPTIMIZE:
config.write('AR_FLAGS=/nologo /LTCG\n')
config.write(
'LINK_FLAGS=/nologo /MD\n'
'SLINK_FLAGS=/nologo /LD\n')
@ -1777,7 +1818,7 @@ def mk_config():
print('OCaml Native: %s' % OCAMLOPT)
print('OCaml Library: %s' % OCAML_LIB)
else:
global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG
global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG, FPMATH_FLAGS
OS_DEFINES = ""
ARITH = "internal"
check_ar()
@ -1806,9 +1847,11 @@ def mk_config():
if GIT_HASH:
CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH)
CXXFLAGS = '%s -fvisibility=hidden -c' % CXXFLAGS
FPMATH = test_fpmath(CXX)
CXXFLAGS = '%s %s' % (CXXFLAGS, FPMATH_FLAGS)
HAS_OMP = test_openmp(CXX)
if HAS_OMP:
CXXFLAGS = '%s -fopenmp -mfpmath=sse' % CXXFLAGS
CXXFLAGS = '%s -fopenmp' % CXXFLAGS
LDFLAGS = '%s -fopenmp' % LDFLAGS
SLIBEXTRAFLAGS = '%s -fopenmp' % SLIBEXTRAFLAGS
else:
@ -1849,7 +1892,8 @@ def mk_config():
else:
raise MKException('Unsupported platform: %s' % sysname)
if is64():
CXXFLAGS = '%s -fPIC' % CXXFLAGS
if sysname[:6] != 'CYGWIN':
CXXFLAGS = '%s -fPIC' % CXXFLAGS
CPPFLAGS = '%s -D_AMD64_' % CPPFLAGS
if sysname == 'Linux':
CPPFLAGS = '%s -D_USE_THREAD_LOCAL' % CPPFLAGS
@ -1861,7 +1905,6 @@ def mk_config():
CPPFLAGS = '%s -DZ3DEBUG' % CPPFLAGS
if TRACE or DEBUG_MODE:
CPPFLAGS = '%s -D_TRACE' % CPPFLAGS
CXXFLAGS = '%s -msse -msse2' % CXXFLAGS
config.write('PREFIX=%s\n' % PREFIX)
config.write('CC=%s\n' % CC)
config.write('CXX=%s\n' % CXX)
@ -1892,6 +1935,7 @@ def mk_config():
print('OpenMP: %s' % HAS_OMP)
print('Prefix: %s' % PREFIX)
print('64-bit: %s' % is64())
print('FP math: %s' % FPMATH)
if GPROF:
print('gprof: enabled')
print('Python version: %s' % distutils.sysconfig.get_python_version())

View file

@ -47,16 +47,16 @@ def set_build_dir(path):
mk_dir(BUILD_X64_DIR)
def display_help():
print "mk_win_dist.py: Z3 Windows distribution generator\n"
print "This script generates the zip files containing executables, dlls, header files for Windows."
print "It must be executed from the Z3 root directory."
print "\nOptions:"
print " -h, --help display this message."
print " -s, --silent do not print verbose messages."
print " -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist)."
print " -f, --force force script to regenerate Makefiles."
print " --nojava do not include Java bindings in the binary distribution files."
print " --githash include git hash in the Zip file."
print("mk_win_dist.py: Z3 Windows distribution generator\n")
print("This script generates the zip files containing executables, dlls, header files for Windows.")
print("It must be executed from the Z3 root directory.")
print("\nOptions:")
print(" -h, --help display this message.")
print(" -s, --silent do not print verbose messages.")
print(" -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist).")
print(" -f, --force force script to regenerate Makefiles.")
print(" --nojava do not include Java bindings in the binary distribution files.")
print(" --githash include git hash in the Zip file.")
exit(0)
# Parse configuration option for mk_make script
@ -180,7 +180,7 @@ def mk_dist_dir_core(x64):
mk_util.JAVA_ENABLED = JAVA_ENABLED
mk_win_dist(build_path, dist_path)
if is_verbose():
print "Generated %s distribution folder at '%s'" % (platform, dist_path)
print("Generated %s distribution folder at '%s'" % (platform, dist_path))
def mk_dist_dir():
mk_dist_dir_core(False)
@ -208,7 +208,7 @@ def mk_zip_core(x64):
ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED)
os.path.walk(dist_path, mk_zip_visitor, '*')
if is_verbose():
print "Generated '%s'" % zfname
print("Generated '%s'" % zfname)
except:
pass
ZIPOUT = None
@ -253,7 +253,7 @@ def cp_vs_runtime_core(x64):
for f in VS_RUNTIME_FILES:
shutil.copy(f, bin_dist_path)
if is_verbose():
print "Copied '%s' to '%s'" % (f, bin_dist_path)
print("Copied '%s' to '%s'" % (f, bin_dist_path))
def cp_vs_runtime():
cp_vs_runtime_core(True)

View file

@ -1,7 +1,9 @@
#!/bin/bash
# Copyright (c) 2015 Microsoft Corporation
# Script for "cloning" (and tracking) all branches at codeplex.
# On Windows, this script must be executed in the "git Bash" console.
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do
git branch --track ${branch##*/} $branch
done

View file

@ -568,10 +568,12 @@ def mk_java():
java_native.write(' public static class ObjArrayPtr { public long[] value; }\n')
java_native.write(' public static class UIntArrayPtr { public int[] value; }\n')
java_native.write(' public static native void setInternalErrorHandler(long ctx);\n\n')
if IS_WINDOWS or os.uname()[0]=="CYGWIN":
java_native.write(' static { System.loadLibrary("%s"); }\n' % get_component('java').dll_name)
else:
java_native.write(' static { System.loadLibrary("%s"); }\n' % get_component('java').dll_name[3:]) # We need 3: to extract the prexi 'lib' form the dll_name
java_native.write(' static {\n')
java_native.write(' try { System.loadLibrary("z3java"); }\n')
java_native.write(' catch (UnsatisfiedLinkError ex) { System.loadLibrary("libz3java"); }\n')
java_native.write(' }\n')
java_native.write('\n')
for name, result, params in _dotnet_decls:
java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name)))
@ -1010,6 +1012,11 @@ def def_API(name, result, params):
log_c.write(" }\n")
log_c.write(" Au(a%s);\n" % sz)
exe_c.write("in.get_uint_array(%s)" % i)
elif ty == INT:
log_c.write("U(a%s[i]);" % i)
log_c.write(" }\n")
log_c.write(" Au(a%s);\n" % sz)
exe_c.write("in.get_int_array(%s)" % i)
else:
error ("unsupported parameter for %s, %s" % (ty, name, p))
elif kind == OUT_ARRAY:

View file

@ -24,6 +24,7 @@ Revision History:
#include"bv_decl_plugin.h"
#include"datatype_decl_plugin.h"
#include"array_decl_plugin.h"
#include"pb_decl_plugin.h"
#include"ast_translation.h"
#include"ast_pp.h"
#include"ast_ll_pp.h"
@ -1081,7 +1082,6 @@ extern "C" {
case OP_BSREM_I:
case OP_BUREM_I:
case OP_BSMOD_I:
return Z3_OP_UNINTERPRETED;
default:
UNREACHABLE();
@ -1090,9 +1090,10 @@ extern "C" {
}
if (mk_c(c)->get_dt_fid() == _d->get_family_id()) {
switch(_d->get_decl_kind()) {
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
case OP_DT_UPDATE_FIELD: return Z3_OP_DT_UPDATE_FIELD;
default:
UNREACHABLE();
return Z3_OP_UNINTERPRETED;
@ -1186,6 +1187,15 @@ extern "C" {
}
}
if (mk_c(c)->get_pb_fid() == _d->get_family_id()) {
switch(_d->get_decl_kind()) {
case OP_PB_LE: return Z3_OP_PB_LE;
case OP_PB_GE: return Z3_OP_PB_GE;
case OP_AT_MOST_K: return Z3_OP_PB_AT_MOST;
default: UNREACHABLE();
}
}
return Z3_OP_UNINTERPRETED;
Z3_CATCH_RETURN(Z3_OP_UNINTERPRETED);
}

View file

@ -37,9 +37,7 @@ extern "C" {
catch (z3_exception & ex) {
// The error handler is only available for contexts
// Just throw a warning.
std::ostringstream buffer;
buffer << "Error setting " << param_id << ", " << ex.msg();
warning_msg(buffer.str().c_str());
warning_msg(ex.msg());
}
}
@ -64,9 +62,7 @@ extern "C" {
catch (z3_exception & ex) {
// The error handler is only available for contexts
// Just throw a warning.
std::ostringstream buffer;
buffer << "Error setting " << param_id << ": " << ex.msg();
warning_msg(buffer.str().c_str());
warning_msg(ex.msg());
return Z3_FALSE;
}
}
@ -92,9 +88,7 @@ extern "C" {
catch (z3_exception & ex) {
// The error handler is only available for contexts
// Just throw a warning.
std::ostringstream buffer;
buffer << "Error setting " << param_id << ": " << ex.msg();
warning_msg(buffer.str().c_str());
warning_msg(ex.msg());
}
}

View file

@ -89,7 +89,7 @@ namespace api {
m_bv_util(m()),
m_datalog_util(m()),
m_fpa_util(m()),
m_dtutil(m()),
m_dtutil(m()),
m_last_result(m()),
m_ast_trail(m()),
m_replay_stack() {
@ -111,6 +111,7 @@ namespace api {
m_basic_fid = m().get_basic_family_id();
m_arith_fid = m().mk_family_id("arith");
m_bv_fid = m().mk_family_id("bv");
m_pb_fid = m().mk_family_id("pb");
m_array_fid = m().mk_family_id("array");
m_dt_fid = m().mk_family_id("datatype");
m_datalog_fid = m().mk_family_id("datalog_relation");
@ -515,6 +516,11 @@ extern "C" {
memory::initialize(0);
}
void Z3_API Z3_finalize_memory(void) {
LOG_Z3_finalize_memory();
memory::finalize();
}
Z3_error_code Z3_API Z3_get_error_code(Z3_context c) {
LOG_Z3_get_error_code(c);
return mk_c(c)->get_error_code();

View file

@ -78,6 +78,7 @@ namespace api {
family_id m_bv_fid;
family_id m_dt_fid;
family_id m_datalog_fid;
family_id m_pb_fid;
family_id m_fpa_fid;
datatype_decl_plugin * m_dt_plugin;
@ -127,6 +128,7 @@ namespace api {
family_id get_bv_fid() const { return m_bv_fid; }
family_id get_dt_fid() const { return m_dt_fid; }
family_id get_datalog_fid() const { return m_datalog_fid; }
family_id get_pb_fid() const { return m_pb_fid; }
family_id get_fpa_fid() const { return m_fpa_fid; }
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }

View file

@ -125,7 +125,7 @@ namespace api {
return "unknown";
}
}
std::string to_string(unsigned num_queries, expr*const* queries) {
std::string to_string(unsigned num_queries, expr* const* queries) {
std::stringstream str;
m_context.display_smt2(num_queries, queries, str);
return str.str();
@ -466,13 +466,16 @@ extern "C" {
ast_manager& m = mk_c(c)->m();
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
mk_c(c)->save_object(v);
expr_ref_vector rules(m);
expr_ref_vector rules(m), queries(m);
svector<symbol> names;
to_fixedpoint_ref(d)->ctx().get_rules_as_formulas(rules, names);
to_fixedpoint_ref(d)->ctx().get_rules_as_formulas(rules, queries, names);
for (unsigned i = 0; i < rules.size(); ++i) {
v->m_ast_vector.push_back(rules[i].get());
}
for (unsigned i = 0; i < queries.size(); ++i) {
v->m_ast_vector.push_back(m.mk_not(queries[i].get()));
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(0);
}

View file

@ -476,7 +476,7 @@ extern "C" {
return 0;
}
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
if (idx >= decls->size()) {
if (!decls || idx >= decls->size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return 0;
}
@ -506,9 +506,9 @@ extern "C" {
RETURN_Z3(0);
}
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
if (idx >= decls->size()) {
if (!decls || idx >= decls->size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return 0;
RETURN_Z3(0);
}
func_decl* decl = (*decls)[idx];
decl = dt_util.get_constructor_recognizer(decl);
@ -529,7 +529,7 @@ extern "C" {
RETURN_Z3(0);
}
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
if (idx_c >= decls->size()) {
if (!decls || idx_c >= decls->size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return 0;
}
@ -618,4 +618,25 @@ extern "C" {
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_datatype_update_field(
__in Z3_context c, __in Z3_func_decl f, __in Z3_ast t, __in Z3_ast v) {
Z3_TRY;
LOG_Z3_datatype_update_field(c, f, t, v);
RESET_ERROR_CODE();
ast_manager & m = mk_c(c)->m();
func_decl* _f = to_func_decl(f);
expr* _t = to_expr(t);
expr* _v = to_expr(v);
expr* args[2] = { _t, _v };
sort* domain[2] = { m.get_sort(_t), m.get_sort(_v) };
parameter param(_f);
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_DT_UPDATE_FIELD, 1, &param, 2, domain);
app* r = m.mk_app(d, 2, args);
mk_c(c)->save_ast_trail(r);
check_sorts(c, r);
RETURN_Z3(of_ast(r));
Z3_CATCH_RETURN(0);
}
};

View file

@ -712,7 +712,7 @@ extern "C" {
unsigned Z3_API Z3_fpa_get_sbits(Z3_context c, Z3_sort s) {
Z3_TRY;
LOG_Z3_fpa_get_ebits(c, s);
LOG_Z3_fpa_get_sbits(c, s);
RESET_ERROR_CODE();
CHECK_NON_NULL(s, 0);
return mk_c(c)->fpautil().get_sbits(to_sort(s));
@ -765,7 +765,30 @@ extern "C" {
mpqm.display_decimal(ss, q, sbits);
return mk_c(c)->mk_external_string(ss.str());
Z3_CATCH_RETURN("");
}
Z3_bool Z3_API Z3_fpa_get_numeral_significand_uint64(__in Z3_context c, __in Z3_ast t, __out __uint64 * n) {
Z3_TRY;
LOG_Z3_fpa_get_numeral_significand_uint64(c, t, n);
RESET_ERROR_CODE();
ast_manager & m = mk_c(c)->m();
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
unsynch_mpz_manager & mpzm = mpfm.mpz_manager();
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid());
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(to_expr(t), val);
if (!r) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return 0;
}
const mpz & z = mpfm.sig(val);
if (!mpzm.is_uint64(z)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return 0;
}
*n = mpzm.get_uint64(z);
return 1;
Z3_CATCH_RETURN(0);
}
Z3_string Z3_API Z3_fpa_get_numeral_exponent_string(__in Z3_context c, __in Z3_ast t) {
@ -794,7 +817,7 @@ extern "C" {
Z3_bool Z3_API Z3_fpa_get_numeral_exponent_int64(__in Z3_context c, __in Z3_ast t, __out __int64 * n) {
Z3_TRY;
LOG_Z3_fpa_get_numeral_exponent_string(c, t);
LOG_Z3_fpa_get_numeral_exponent_int64(c, t, n);
RESET_ERROR_CODE();
ast_manager & m = mk_c(c)->m();
mpf_manager & mpfm = mk_c(c)->fpautil().fm();

View file

@ -290,10 +290,10 @@ extern "C" {
}
}
else {
model_ref _m;
m_solver.get()->get_model(_m);
model_ref mr;
m_solver.get()->get_model(mr);
Z3_model_ref *tmp_val = alloc(Z3_model_ref);
tmp_val->m_model = _m.get();
tmp_val->m_model = mr.get();
mk_c(c)->save_object(tmp_val);
*model = of_model(tmp_val);
}

View file

@ -65,6 +65,18 @@ extern "C" {
Z3_CATCH_RETURN(0);
}
Z3_bool Z3_API Z3_model_has_interp(Z3_context c, Z3_model m, Z3_func_decl a) {
Z3_TRY;
LOG_Z3_model_has_interp(c, m, a);
CHECK_NON_NULL(m, 0);
if (to_model_ref(m)->has_interpretation(to_func_decl(a))) {
return Z3_TRUE;
} else {
return Z3_FALSE;
}
Z3_CATCH_RETURN(Z3_FALSE);
}
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f) {
Z3_TRY;
LOG_Z3_model_get_func_interp(c, m, f);

243
src/api/api_opt.cpp Normal file
View file

@ -0,0 +1,243 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
api_opt.cpp
Abstract:
API for optimization
Author:
Nikolaj Bjorner (nbjorner) 2013-12-3.
Revision History:
--*/
#include<iostream>
#include"z3.h"
#include"api_log_macros.h"
#include"api_stats.h"
#include"api_context.h"
#include"api_util.h"
#include"api_model.h"
#include"opt_context.h"
#include"cancel_eh.h"
#include"scoped_timer.h"
extern "C" {
struct Z3_optimize_ref : public api::object {
opt::context* m_opt;
Z3_optimize_ref():m_opt(0) {}
virtual ~Z3_optimize_ref() { dealloc(m_opt); }
};
inline Z3_optimize_ref * to_optimize(Z3_optimize o) { return reinterpret_cast<Z3_optimize_ref *>(o); }
inline Z3_optimize of_optimize(Z3_optimize_ref * o) { return reinterpret_cast<Z3_optimize>(o); }
inline opt::context* to_optimize_ptr(Z3_optimize o) { return to_optimize(o)->m_opt; }
Z3_optimize Z3_API Z3_mk_optimize(Z3_context c) {
Z3_TRY;
LOG_Z3_mk_optimize(c);
RESET_ERROR_CODE();
Z3_optimize_ref * o = alloc(Z3_optimize_ref);
o->m_opt = alloc(opt::context,mk_c(c)->m());
mk_c(c)->save_object(o);
RETURN_Z3(of_optimize(o));
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_optimize_inc_ref(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_inc_ref(c, o);
RESET_ERROR_CODE();
to_optimize(o)->inc_ref();
Z3_CATCH;
}
void Z3_API Z3_optimize_dec_ref(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_dec_ref(c, o);
RESET_ERROR_CODE();
to_optimize(o)->dec_ref();
Z3_CATCH;
}
void Z3_API Z3_optimize_assert(Z3_context c, Z3_optimize o, Z3_ast a) {
Z3_TRY;
LOG_Z3_optimize_assert(c, o, a);
RESET_ERROR_CODE();
CHECK_FORMULA(a,);
to_optimize_ptr(o)->add_hard_constraint(to_expr(a));
Z3_CATCH;
}
unsigned Z3_API Z3_optimize_assert_soft(Z3_context c, Z3_optimize o, Z3_ast a, Z3_string weight, Z3_symbol id) {
Z3_TRY;
LOG_Z3_optimize_assert_soft(c, o, a, weight, id);
RESET_ERROR_CODE();
CHECK_FORMULA(a,0);
rational w(weight);
return to_optimize_ptr(o)->add_soft_constraint(to_expr(a), w, to_symbol(id));
Z3_CATCH_RETURN(0);
}
unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t) {
Z3_TRY;
LOG_Z3_optimize_maximize(c, o, t);
RESET_ERROR_CODE();
CHECK_VALID_AST(t,0);
return to_optimize_ptr(o)->add_objective(to_app(t), true);
Z3_CATCH_RETURN(0);
}
unsigned Z3_API Z3_optimize_minimize(Z3_context c, Z3_optimize o, Z3_ast t) {
Z3_TRY;
LOG_Z3_optimize_minimize(c, o, t);
RESET_ERROR_CODE();
CHECK_VALID_AST(t,0);
return to_optimize_ptr(o)->add_objective(to_app(t), false);
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_optimize_push(Z3_context c,Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_push(c, d);
RESET_ERROR_CODE();
to_optimize_ptr(d)->push();
Z3_CATCH;
}
void Z3_API Z3_optimize_pop(Z3_context c,Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_pop(c, d);
RESET_ERROR_CODE();
to_optimize_ptr(d)->pop(1);
Z3_CATCH;
}
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_check(c, o);
RESET_ERROR_CODE();
lbool r = l_undef;
cancel_eh<opt::context> eh(*to_optimize_ptr(o));
unsigned timeout = to_optimize_ptr(o)->get_params().get_uint("timeout", mk_c(c)->get_timeout());
api::context::set_interruptable si(*(mk_c(c)), eh);
{
scoped_timer timer(timeout, &eh);
try {
r = to_optimize_ptr(o)->optimize();
}
catch (z3_exception& ex) {
mk_c(c)->handle_exception(ex);
r = l_undef;
}
// to_optimize_ref(d).cleanup();
}
return of_lbool(r);
Z3_CATCH_RETURN(Z3_L_UNDEF);
}
Z3_model Z3_API Z3_optimize_get_model(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_get_model(c, o);
RESET_ERROR_CODE();
model_ref _m;
to_optimize_ptr(o)->get_model(_m);
Z3_model_ref * m_ref = alloc(Z3_model_ref);
if (_m) {
m_ref->m_model = _m;
}
else {
m_ref->m_model = alloc(model, mk_c(c)->m());
}
mk_c(c)->save_object(m_ref);
RETURN_Z3(of_model(m_ref));
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_optimize_set_params(Z3_context c, Z3_optimize o, Z3_params p) {
Z3_TRY;
LOG_Z3_optimize_set_params(c, o, p);
RESET_ERROR_CODE();
param_descrs descrs;
to_optimize_ptr(o)->collect_param_descrs(descrs);
to_params(p)->m_params.validate(descrs);
params_ref pr = to_param_ref(p);
to_optimize_ptr(o)->updt_params(pr);
Z3_CATCH;
}
Z3_param_descrs Z3_API Z3_optimize_get_param_descrs(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_get_param_descrs(c, o);
RESET_ERROR_CODE();
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
mk_c(c)->save_object(d);
to_optimize_ptr(o)->collect_param_descrs(d->m_descrs);
Z3_param_descrs r = of_param_descrs(d);
RETURN_Z3(r);
Z3_CATCH_RETURN(0);
}
// get lower value or current approximation
Z3_ast Z3_API Z3_optimize_get_lower(Z3_context c, Z3_optimize o, unsigned idx) {
Z3_TRY;
LOG_Z3_optimize_get_lower(c, o, idx);
RESET_ERROR_CODE();
expr_ref e = to_optimize_ptr(o)->get_lower(idx);
mk_c(c)->save_ast_trail(e);
RETURN_Z3(of_expr(e));
Z3_CATCH_RETURN(0);
}
// get upper or current approximation
Z3_ast Z3_API Z3_optimize_get_upper(Z3_context c, Z3_optimize o, unsigned idx) {
Z3_TRY;
LOG_Z3_optimize_get_upper(c, o, idx);
RESET_ERROR_CODE();
expr_ref e = to_optimize_ptr(o)->get_upper(idx);
mk_c(c)->save_ast_trail(e);
RETURN_Z3(of_expr(e));
Z3_CATCH_RETURN(0);
}
Z3_string Z3_API Z3_optimize_to_string(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_to_string(c, o);
RESET_ERROR_CODE();
return mk_c(c)->mk_external_string(to_optimize_ptr(o)->to_string());
Z3_CATCH_RETURN("");
}
Z3_string Z3_API Z3_optimize_get_help(Z3_context c, Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_get_help(c, d);
RESET_ERROR_CODE();
std::ostringstream buffer;
param_descrs descrs;
to_optimize_ptr(d)->collect_param_descrs(descrs);
descrs.display(buffer);
return mk_c(c)->mk_external_string(buffer.str());
Z3_CATCH_RETURN("");
}
Z3_stats Z3_API Z3_optimize_get_statistics(Z3_context c,Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_get_statistics(c, d);
RESET_ERROR_CODE();
Z3_stats_ref * st = alloc(Z3_stats_ref);
to_optimize_ptr(d)->collect_statistics(st->m_stats);
mk_c(c)->save_object(st);
Z3_stats r = of_stats(st);
RETURN_Z3(r);
Z3_CATCH_RETURN(0);
}
};

61
src/api/api_pb.cpp Normal file
View file

@ -0,0 +1,61 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
api_pb.cpp
Abstract:
API for pb theory
Author:
Nikolaj Bjorner (nbjorner) 2013-11-13.
Revision History:
--*/
#include<iostream>
#include"z3.h"
#include"api_log_macros.h"
#include"api_context.h"
#include"api_util.h"
#include"pb_decl_plugin.h"
extern "C" {
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
Z3_ast const args[], unsigned k) {
Z3_TRY;
LOG_Z3_mk_atmost(c, num_args, args, k);
RESET_ERROR_CODE();
parameter param(k);
pb_util util(mk_c(c)->m());
ast* a = util.mk_at_most_k(num_args, to_exprs(args), k);
mk_c(c)->save_ast_trail(a);
check_sorts(c, a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
Z3_ast const args[], int _coeffs[],
int k) {
Z3_TRY;
LOG_Z3_mk_pble(c, num_args, args, _coeffs, k);
RESET_ERROR_CODE();
pb_util util(mk_c(c)->m());
vector<rational> coeffs;
for (unsigned i = 0; i < num_args; ++i) {
coeffs.push_back(rational(_coeffs[i]));
}
ast* a = util.mk_le(num_args, coeffs.c_ptr(), to_exprs(args), rational(k));
mk_c(c)->save_ast_trail(a);
check_sorts(c, a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
};

View file

@ -355,6 +355,10 @@ extern "C" {
init_solver(c, s);
Z3_stats_ref * st = alloc(Z3_stats_ref);
to_solver_ref(s)->collect_statistics(st->m_stats);
unsigned long long max_mem = memory::get_max_used_memory();
unsigned long long mem = memory::get_allocation_size();
st->m_stats.update("max memory", static_cast<double>(max_mem)/(1024.0*1024.0));
st->m_stats.update("memory", static_cast<double>(mem)/(1024.0*1024.0));
mk_c(c)->save_object(st);
Z3_stats r = of_stats(st);
RETURN_Z3(r);

View file

@ -203,7 +203,12 @@ namespace z3 {
and in \c ts the predicates for testing if terms of the enumeration sort correspond to an enumeration.
*/
sort enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts);
/**
\brief create an uninterpreted sort with the name given by the string or symbol.
*/
sort uninterpreted_sort(char const* name);
sort uninterpreted_sort(symbol const& name);
func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range);
func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range);
func_decl function(symbol const& name, sort_vector const& domain, sort const& range);
@ -655,6 +660,7 @@ namespace z3 {
friend expr ite(expr const & c, expr const & t, expr const & e);
friend expr distinct(expr_vector const& args);
friend expr concat(expr const& a, expr const& b);
friend expr operator==(expr const & a, expr const & b) {
check_context(a, b);
@ -677,7 +683,7 @@ namespace z3 {
friend expr operator+(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
Z3_ast args[2] = { a, b };
r = Z3_mk_add(a.ctx(), 2, args);
@ -697,7 +703,7 @@ namespace z3 {
friend expr operator*(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
Z3_ast args[2] = { a, b };
r = Z3_mk_mul(a.ctx(), 2, args);
@ -724,7 +730,7 @@ namespace z3 {
friend expr operator/(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
r = Z3_mk_div(a.ctx(), a, b);
}
@ -742,7 +748,7 @@ namespace z3 {
friend expr operator/(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) / b; }
friend expr operator-(expr const & a) {
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith()) {
r = Z3_mk_unary_minus(a.ctx(), a);
}
@ -759,7 +765,7 @@ namespace z3 {
friend expr operator-(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
Z3_ast args[2] = { a, b };
r = Z3_mk_sub(a.ctx(), 2, args);
@ -779,7 +785,7 @@ namespace z3 {
friend expr operator<=(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
r = Z3_mk_le(a.ctx(), a, b);
}
@ -798,7 +804,7 @@ namespace z3 {
friend expr operator>=(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
r = Z3_mk_ge(a.ctx(), a, b);
}
@ -817,7 +823,7 @@ namespace z3 {
friend expr operator<(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
r = Z3_mk_lt(a.ctx(), a, b);
}
@ -836,7 +842,7 @@ namespace z3 {
friend expr operator>(expr const & a, expr const & b) {
check_context(a, b);
Z3_ast r;
Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) {
r = Z3_mk_gt(a.ctx(), a, b);
}
@ -1108,6 +1114,13 @@ namespace z3 {
ctx.check_error();
return expr(ctx, r);
}
inline expr concat(expr const& a, expr const& b) {
check_context(a, b);
Z3_ast r = Z3_mk_concat(a.ctx(), a, b);
a.ctx().check_error();
return expr(a.ctx(), r);
}
class func_entry : public object {
Z3_func_entry m_entry;
@ -1176,7 +1189,7 @@ namespace z3 {
expr eval(expr const & n, bool model_completion=false) const {
check_context(*this, n);
Z3_ast r;
Z3_ast r = 0;
Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r);
check_error();
if (status == Z3_FALSE)
@ -1536,6 +1549,62 @@ namespace z3 {
}
};
class optimize : public object {
Z3_optimize m_opt;
public:
class handle {
unsigned m_h;
public:
handle(unsigned h): m_h(h) {}
unsigned h() const { return m_h; }
};
optimize(context& c):object(c) { m_opt = Z3_mk_optimize(c); Z3_optimize_inc_ref(c, m_opt); }
~optimize() { Z3_optimize_dec_ref(ctx(), m_opt); }
operator Z3_optimize() const { return m_opt; }
void add(expr const& e) {
assert(e.is_bool());
Z3_optimize_assert(ctx(), m_opt, e);
}
handle add(expr const& e, unsigned weight) {
assert(e.is_bool());
std::stringstream strm;
strm << weight;
return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, strm.str().c_str(), 0));
}
handle add(expr const& e, char const* weight) {
assert(e.is_bool());
return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, weight, 0));
}
handle maximize(expr const& e) {
return handle(Z3_optimize_maximize(ctx(), m_opt, e));
}
handle minimize(expr const& e) {
return handle(Z3_optimize_minimize(ctx(), m_opt, e));
}
void push() {
Z3_optimize_push(ctx(), m_opt);
}
void pop() {
Z3_optimize_pop(ctx(), m_opt);
}
check_result check() { Z3_lbool r = Z3_optimize_check(ctx(), m_opt); check_error(); return to_check_result(r); }
model get_model() const { Z3_model m = Z3_optimize_get_model(ctx(), m_opt); check_error(); return model(ctx(), m); }
void set(params const & p) { Z3_optimize_set_params(ctx(), m_opt, p); check_error(); }
expr lower(handle const& h) {
Z3_ast r = Z3_optimize_get_lower(ctx(), m_opt, h.h());
check_error();
return expr(ctx(), r);
}
expr upper(handle const& h) {
Z3_ast r = Z3_optimize_get_upper(ctx(), m_opt, h.h());
check_error();
return expr(ctx(), r);
}
stats statistics() const { Z3_stats r = Z3_optimize_get_statistics(ctx(), m_opt); check_error(); return stats(ctx(), r); }
friend std::ostream & operator<<(std::ostream & out, optimize const & s) { out << Z3_optimize_to_string(s.ctx(), s.m_opt); return out; }
std::string help() const { char const * r = Z3_optimize_get_help(ctx(), m_opt); check_error(); return r; }
};
inline tactic fail_if(probe const & p) {
Z3_tactic r = Z3_tactic_fail_if(p.ctx(), p);
p.check_error();
@ -1573,6 +1642,13 @@ namespace z3 {
for (unsigned i = 0; i < n; i++) { cs.push_back(func_decl(*this, _cs[i])); ts.push_back(func_decl(*this, _ts[i])); }
return s;
}
inline sort context::uninterpreted_sort(char const* name) {
Z3_symbol _name = Z3_mk_string_symbol(*this, name);
return to_sort(*this, Z3_mk_uninterpreted_sort(*this, _name));
}
inline sort context::uninterpreted_sort(symbol const& name) {
return to_sort(*this, Z3_mk_uninterpreted_sort(*this, name));
}
inline func_decl context::function(symbol const & name, unsigned arity, sort const * domain, sort const & range) {
array<Z3_sort> args(arity);

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#ifdef _WINDOWS
#include<windows.h>

View file

@ -98,11 +98,12 @@ namespace Microsoft.Z3
/// <summary>
/// The keys stored in the map.
/// </summary>
public ASTVector Keys
public AST[] Keys
{
get
{
return new ASTVector(Context, Native.Z3_ast_map_keys(Context.nCtx, NativeObject));
ASTVector res = new ASTVector(Context, Native.Z3_ast_map_keys(Context.nCtx, NativeObject));
return res.ToArray();
}
}

View file

@ -99,6 +99,138 @@ namespace Microsoft.Z3
return Native.Z3_ast_vector_to_string(Context.nCtx, NativeObject);
}
/// <summary>
/// Translates an AST vector into an AST[]
/// </summary>
public AST[] ToArray()
{
uint n = Size;
AST[] res = new AST[n];
for (uint i = 0; i < n; i++)
res[i] = AST.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into an Expr[]
/// </summary>
public Expr[] ToExprArray()
{
uint n = Size;
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a BoolExpr[]
/// </summary>
public BoolExpr[] ToBoolExprArray()
{
uint n = Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (BoolExpr) Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a BitVecExpr[]
/// </summary>
public BitVecExpr[] ToBitVecExprArray()
{
uint n = Size;
BitVecExpr[] res = new BitVecExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (BitVecExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a ArithExpr[]
/// </summary>
public ArithExpr[] ToArithExprArray()
{
uint n = Size;
ArithExpr[] res = new ArithExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (ArithExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a ArrayExpr[]
/// </summary>
public ArrayExpr[] ToArrayExprArray()
{
uint n = Size;
ArrayExpr[] res = new ArrayExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (ArrayExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a DatatypeExpr[]
/// </summary>
public DatatypeExpr[] ToDatatypeExprArray()
{
uint n = Size;
DatatypeExpr[] res = new DatatypeExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (DatatypeExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a FPExpr[]
/// </summary>
public FPExpr[] ToFPExprArray()
{
uint n = Size;
FPExpr[] res = new FPExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (FPExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a FPRMExpr[]
/// </summary>
public FPRMExpr[] ToFPRMExprArray()
{
uint n = Size;
FPRMExpr[] res = new FPRMExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (FPRMExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a IntExpr[]
/// </summary>
public IntExpr[] ToIntExprArray()
{
uint n = Size;
IntExpr[] res = new IntExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (IntExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a RealExpr[]
/// </summary>
public RealExpr[] ToRealExprArray()
{
uint n = Size;
RealExpr[] res = new RealExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (RealExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
#region Internal
internal ASTVector(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
internal ASTVector(Context ctx) : base(ctx, Native.Z3_mk_ast_vector(ctx.nCtx)) { Contract.Requires(ctx != null); }

View file

@ -449,6 +449,19 @@ namespace Microsoft.Z3
return MkDatatypeSorts(MkSymbols(names), c);
}
/// <summary>
/// Update a datatype field at expression t with value v.
/// The function performs a record update at t. The field
/// that is passed in as argument is updated with value v,
/// the remainig fields of t are unchanged.
/// </summary>
public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
{
return Expr.Create(this, Native.Z3_datatype_update_field(
nCtx, field.NativeObject,
t.NativeObject, v.NativeObject));
}
#endregion
#endregion
@ -2251,6 +2264,36 @@ namespace Microsoft.Z3
}
#endregion
#region Pseudo-Boolean constraints
/// <summary>
/// Create an at-most-k constraint.
/// </summary>
public BoolExpr MkAtMost(BoolExpr[] args, uint k)
{
Contract.Requires(args != null);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
AST.ArrayToNative(args), k));
}
/// <summary>
/// Create a pseudo-Boolean less-or-equal constraint.
/// </summary>
public BoolExpr MkPBLe(int[] coeffs, BoolExpr[] args, int k)
{
Contract.Requires(args != null);
Contract.Requires(coeffs != null);
Contract.Requires(args.Length == coeffs.Length);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_pble(nCtx, (uint) args.Length,
AST.ArrayToNative(args),
coeffs, k));
}
#endregion
#region Numerals
#region General Numerals
@ -3438,6 +3481,18 @@ namespace Microsoft.Z3
}
#endregion
#region Optimization
/// <summary>
/// Create an Optimization context.
/// </summary>
public Optimize MkOptimize()
{
Contract.Ensures(Contract.Result<Optimize>() != null);
return new Optimize(this);
}
#endregion
#region Floating-Point Arithmetic
#region Rounding Modes
@ -4383,6 +4438,7 @@ namespace Microsoft.Z3
Contract.Invariant(m_Statistics_DRQ != null);
Contract.Invariant(m_Tactic_DRQ != null);
Contract.Invariant(m_Fixedpoint_DRQ != null);
Contract.Invariant(m_Optimize_DRQ != null);
}
readonly private AST.DecRefQueue m_AST_DRQ = new AST.DecRefQueue();
@ -4400,6 +4456,7 @@ namespace Microsoft.Z3
readonly private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue(10);
readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue(10);
readonly private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue(10);
readonly private Optimize.DecRefQueue m_Optimize_DRQ = new Optimize.DecRefQueue(10);
/// <summary>
/// AST DRQ
@ -4476,6 +4533,11 @@ namespace Microsoft.Z3
/// </summary>
public IDecRefQueue Fixedpoint_DRQ { get { Contract.Ensures(Contract.Result<Fixedpoint.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
/// <summary>
/// Optimize DRQ
/// </summary>
public IDecRefQueue Optimize_DRQ { get { Contract.Ensures(Contract.Result<Optimize.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
internal long refCount = 0;
@ -4518,6 +4580,7 @@ namespace Microsoft.Z3
Statistics_DRQ.Clear(this);
Tactic_DRQ.Clear(this);
Fixedpoint_DRQ.Clear(this);
Optimize_DRQ.Clear(this);
m_boolSort = null;
m_intSort = null;

View file

@ -0,0 +1,111 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
Deprecated.cs
Abstract:
Expose deprecated features for use from the managed API
those who use them for experiments.
Author:
Christoph Wintersteiger (cwinter) 2012-03-15
Notes:
--*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// The main interaction with Z3 happens via the Context.
/// </summary>
[ContractVerification(true)]
public class Deprecated
{
/// <summary>
/// Creates a backtracking point.
/// </summary>
/// <seealso cref="Pop"/>
public static void Push(Context ctx) {
Native.Z3_push(ctx.nCtx);
}
/// <summary>
/// Backtracks <paramref name="n"/> backtracking points.
/// </summary>
/// <remarks>Note that an exception is thrown if <paramref name="n"/> is not smaller than <c>NumScopes</c></remarks>
/// <seealso cref="Push"/>
public static void Pop(Context ctx, uint n = 1) {
Native.Z3_pop(ctx.nCtx, n);
}
/// <summary>
/// Assert a constraint (or multiple) into the solver.
/// </summary>
public static void Assert(Context ctx, params BoolExpr[] constraints)
{
Contract.Requires(constraints != null);
Contract.Requires(Contract.ForAll(constraints, c => c != null));
ctx.CheckContextMatch(constraints);
foreach (BoolExpr a in constraints)
{
Native.Z3_assert_cnstr(ctx.nCtx, a.NativeObject);
}
}
/// <summary>
/// Checks whether the assertions in the context are consistent or not.
/// </summary>
public static Status Check(Context ctx, List<BoolExpr> core, ref Model model, ref Expr proof, params Expr[] assumptions)
{
Z3_lbool r;
model = null;
proof = null;
if (assumptions == null || assumptions.Length == 0)
r = (Z3_lbool)Native.Z3_check(ctx.nCtx);
else {
IntPtr mdl = IntPtr.Zero, prf = IntPtr.Zero;
uint core_size = 0;
IntPtr[] native_core = new IntPtr[assumptions.Length];
r = (Z3_lbool)Native.Z3_check_assumptions(ctx.nCtx,
(uint)assumptions.Length, AST.ArrayToNative(assumptions),
ref mdl, ref prf, ref core_size, native_core);
for (uint i = 0; i < core_size; i++)
core.Add((BoolExpr)Expr.Create(ctx, native_core[i]));
if (mdl != IntPtr.Zero) {
model = new Model(ctx, mdl);
}
if (prf != IntPtr.Zero) {
proof = Expr.Create(ctx, prf);
}
}
switch (r)
{
case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE;
case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE;
default: return Status.UNKNOWN;
}
}
/// <summary>
/// Retrieves an assignment to atomic propositions for a satisfiable context.
/// </summary>
public static BoolExpr GetAssignment(Context ctx)
{
IntPtr x = Native.Z3_get_context_assignment(ctx.nCtx);
return (BoolExpr)Expr.Create(ctx, x);
}
}
}

View file

@ -59,6 +59,25 @@ namespace Microsoft.Z3
}
}
/// <summary>
/// The significand value of a floating-point numeral as a UInt64
/// </summary>
/// <remarks>
/// This function extracts the significand bits, without the
/// hidden bit or normalization. Throws an exception if the
/// significand does not fit into a UInt64.
/// </remarks>
public UInt64 SignificandUInt64
{
get
{
UInt64 result = 0;
if (Native.Z3_fpa_get_numeral_significand_uint64(Context.nCtx, NativeObject, ref result) == 0)
throw new Z3Exception("Significand is not a 64 bit unsigned integer");
return result;
}
}
/// <summary>
/// Return the exponent value of a floating-point numeral as a string
/// </summary>

View file

@ -269,14 +269,6 @@ namespace Microsoft.Z3
AST.ArrayLength(queries), AST.ArrayToNative(queries));
}
BoolExpr[] ToBoolExprs(ASTVector v) {
uint n = v.Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = new BoolExpr(Context, v[i].NativeObject);
return res;
}
/// <summary>
/// Retrieve set of rules added to fixedpoint context.
/// </summary>
@ -286,7 +278,8 @@ namespace Microsoft.Z3
{
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject)));
ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject));
return av.ToBoolExprArray();
}
}
@ -299,7 +292,21 @@ namespace Microsoft.Z3
{
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject)));
ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject));
return av.ToBoolExprArray();
}
}
/// <summary>
/// Fixedpoint statistics.
/// </summary>
public Statistics Statistics
{
get
{
Contract.Ensures(Contract.Result<Statistics>() != null);
return new Statistics(Context, Native.Z3_fixedpoint_get_statistics(Context.nCtx, NativeObject));
}
}
@ -308,16 +315,19 @@ namespace Microsoft.Z3
/// Add the rules to the current fixedpoint context.
/// Return the set of queries in the file.
/// </summary>
public BoolExpr[] ParseFile(string file) {
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file)));
public BoolExpr[] ParseFile(string file)
{
ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file));
return av.ToBoolExprArray();
}
/// <summary>
/// Similar to ParseFile. Instead it takes as argument a string.
/// </summary>
public BoolExpr[] ParseString(string s) {
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_string(Context.nCtx, NativeObject, s)));
/// </summary>
public BoolExpr[] ParseString(string s)
{
ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_from_string(Context.nCtx, NativeObject, s));
return av.ToBoolExprArray();
}

View file

@ -208,6 +208,21 @@ namespace Microsoft.Z3
return Native.Z3_goal_to_string(Context.nCtx, NativeObject);
}
/// <summary>
/// Goal to BoolExpr conversion.
/// </summary>
/// <returns>A string representation of the Goal.</returns>
public BoolExpr AsBoolExpr() {
uint n = Size;
if (n == 0)
return Context.MkTrue();
else if (n == 1)
return Formulas[0];
else {
return Context.MkAnd(Formulas);
}
}
#region Internal
internal Goal(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }

View file

@ -47,7 +47,7 @@ namespace Microsoft.Z3
/// <remarks>For more information on interpolation please refer
/// too the function Z3_get_interpolant in the C/C++ API, which is
/// well documented.</remarks>
public Expr[] GetInterpolant(Expr pf, Expr pat, Params p)
public BoolExpr[] GetInterpolant(Expr pf, Expr pat, Params p)
{
Contract.Requires(pf != null);
Contract.Requires(pat != null);
@ -59,11 +59,7 @@ namespace Microsoft.Z3
CheckContextMatch(p);
ASTVector seq = new ASTVector(this, Native.Z3_get_interpolant(nCtx, pf.NativeObject, pat.NativeObject, p.NativeObject));
uint n = seq.Size;
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(this, seq[i].NativeObject);
return res;
return seq.ToBoolExprArray();
}
/// <summary>
@ -72,7 +68,7 @@ namespace Microsoft.Z3
/// <remarks>For more information on interpolation please refer
/// too the function Z3_compute_interpolant in the C/C++ API, which is
/// well documented.</remarks>
public Z3_lbool ComputeInterpolant(Expr pat, Params p, out ASTVector interp, out Model model)
public Z3_lbool ComputeInterpolant(Expr pat, Params p, out BoolExpr[] interp, out Model model)
{
Contract.Requires(pat != null);
Contract.Requires(p != null);
@ -84,7 +80,7 @@ namespace Microsoft.Z3
IntPtr i = IntPtr.Zero, m = IntPtr.Zero;
int r = Native.Z3_compute_interpolant(nCtx, pat.NativeObject, p.NativeObject, ref i, ref m);
interp = new ASTVector(this, i);
interp = new ASTVector(this, i).ToBoolExprArray();
model = new Model(this, m);
return (Z3_lbool)r;
}
@ -106,7 +102,7 @@ namespace Microsoft.Z3
/// <remarks>For more information on interpolation please refer
/// too the function Z3_check_interpolant in the C/C++ API, which is
/// well documented.</remarks>
public int CheckInterpolant(Expr[] cnsts, uint[] parents, Expr[] interps, out string error, Expr[] theory)
public int CheckInterpolant(Expr[] cnsts, uint[] parents, BoolExpr[] interps, out string error, Expr[] theory)
{
Contract.Requires(cnsts.Length == parents.Length);
Contract.Requires(cnsts.Length == interps.Length + 1);

View file

@ -365,6 +365,7 @@
<Compile Include="IntSymbol.cs" />
<Compile Include="ListSort.cs" />
<Compile Include="Model.cs" />
<Compile Include="Optimize.cs" />
<Compile Include="Params.cs" />
<Compile Include="ParamDescrs.cs" />
<Compile Include="Pattern.cs" />

View file

@ -265,12 +265,8 @@ namespace Microsoft.Z3
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<Expr[]>() != null);
ASTVector nUniv = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject));
uint n = nUniv.Size;
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(Context, nUniv[i].NativeObject);
return res;
ASTVector av = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject));
return av.ToExprArray();
}
/// <summary>

298
src/api/dotnet/Optimize.cs Normal file
View file

@ -0,0 +1,298 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
Optimize.cs
Abstract:
Z3 Managed API: Optimizes
Author:
Nikolaj Bjorner (nbjorner) 2013-12-03
Notes:
--*/
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// Object for managing optimizization context
/// </summary>
[ContractVerification(true)]
public class Optimize : Z3Object
{
/// <summary>
/// A string that describes all available optimize solver parameters.
/// </summary>
public string Help
{
get
{
Contract.Ensures(Contract.Result<string>() != null);
return Native.Z3_optimize_get_help(Context.nCtx, NativeObject);
}
}
/// <summary>
/// Sets the optimize solver parameters.
/// </summary>
public Params Parameters
{
set
{
Contract.Requires(value != null);
Context.CheckContextMatch(value);
Native.Z3_optimize_set_params(Context.nCtx, NativeObject, value.NativeObject);
}
}
/// <summary>
/// Retrieves parameter descriptions for Optimize solver.
/// </summary>
public ParamDescrs ParameterDescriptions
{
get { return new ParamDescrs(Context, Native.Z3_optimize_get_param_descrs(Context.nCtx, NativeObject)); }
}
/// <summary>
/// Assert a constraint (or multiple) into the optimize solver.
/// </summary>
public void Assert(params BoolExpr[] constraints)
{
Contract.Requires(constraints != null);
Contract.Requires(Contract.ForAll(constraints, c => c != null));
Context.CheckContextMatch(constraints);
foreach (BoolExpr a in constraints)
{
Native.Z3_optimize_assert(Context.nCtx, NativeObject, a.NativeObject);
}
}
/// <summary>
/// Alias for Assert.
/// </summary>
public void Add(params BoolExpr[] constraints)
{
Assert(constraints);
}
/// <summary>
/// Handle to objectives returned by objective functions.
/// </summary>
public class Handle
{
Optimize opt;
uint handle;
internal Handle(Optimize opt, uint h)
{
this.opt = opt;
this.handle = h;
}
/// <summary>
/// Retrieve a lower bound for the objective handle.
/// </summary>
public ArithExpr Lower
{
get { return opt.GetLower(handle); }
}
/// <summary>
/// Retrieve an upper bound for the objective handle.
/// </summary>
public ArithExpr Upper
{
get { return opt.GetUpper(handle); }
}
/// <summary>
/// Retrieve the value of an objective.
/// </summary>
public ArithExpr Value
{
get { return Lower; }
}
}
/// <summary>
/// Assert soft constraint
/// </summary>
/// <remarks>
/// Return an objective which associates with the group of constraints.
/// </remarks>
public Handle AssertSoft(BoolExpr constraint, uint weight, string group)
{
Context.CheckContextMatch(constraint);
Symbol s = Context.MkSymbol(group);
return new Handle(this, Native.Z3_optimize_assert_soft(Context.nCtx, NativeObject, constraint.NativeObject, weight.ToString(), s.NativeObject));
}
/// <summary>
/// Check satisfiability of asserted constraints.
/// Produce a model that (when the objectives are bounded and
/// don't use strict inequalities) meets the objectives.
/// </summary>
///
public Status Check()
{
Z3_lbool r = (Z3_lbool)Native.Z3_optimize_check(Context.nCtx, NativeObject);
switch (r)
{
case Z3_lbool.Z3_L_TRUE:
return Status.SATISFIABLE;
case Z3_lbool.Z3_L_FALSE:
return Status.UNSATISFIABLE;
default:
return Status.UNKNOWN;
}
}
/// <summary>
/// Creates a backtracking point.
/// </summary>
/// <seealso cref="Pop"/>
public void Push()
{
Native.Z3_optimize_push(Context.nCtx, NativeObject);
}
/// <summary>
/// Backtrack one backtracking point.
/// </summary>
/// <remarks>Note that an exception is thrown if Pop is called without a corresponding <c>Push</c></remarks>
/// <seealso cref="Push"/>
public void Pop()
{
Native.Z3_optimize_pop(Context.nCtx, NativeObject);
}
/// <summary>
/// The model of the last <c>Check</c>.
/// </summary>
/// <remarks>
/// The result is <c>null</c> if <c>Check</c> was not invoked before,
/// if its results was not <c>SATISFIABLE</c>, or if model production is not enabled.
/// </remarks>
public Model Model
{
get
{
IntPtr x = Native.Z3_optimize_get_model(Context.nCtx, NativeObject);
if (x == IntPtr.Zero)
return null;
else
return new Model(Context, x);
}
}
/// <summary>
/// Declare an arithmetical maximization objective.
/// Return a handle to the objective. The handle is used as
/// to retrieve the values of objectives after calling Check.
/// </summary>
public Handle MkMaximize(ArithExpr e)
{
return new Handle(this, Native.Z3_optimize_maximize(Context.nCtx, NativeObject, e.NativeObject));
}
/// <summary>
/// Declare an arithmetical minimization objective.
/// Similar to MkMaximize.
/// </summary>
public Handle MkMinimize(ArithExpr e)
{
return new Handle(this, Native.Z3_optimize_minimize(Context.nCtx, NativeObject, e.NativeObject));
}
/// <summary>
/// Retrieve a lower bound for the objective handle.
/// </summary>
private ArithExpr GetLower(uint index)
{
return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_lower(Context.nCtx, NativeObject, index));
}
/// <summary>
/// Retrieve an upper bound for the objective handle.
/// </summary>
private ArithExpr GetUpper(uint index)
{
return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_upper(Context.nCtx, NativeObject, index));
}
/// <summary>
/// Print the context to a string (SMT-LIB parseable benchmark).
/// </summary>
public override string ToString()
{
return Native.Z3_optimize_to_string(Context.nCtx, NativeObject);
}
/// <summary>
/// Optimize statistics.
/// </summary>
public Statistics Statistics
{
get
{
Contract.Ensures(Contract.Result<Statistics>() != null);
return new Statistics(Context, Native.Z3_optimize_get_statistics(Context.nCtx, NativeObject));
}
}
#region Internal
internal Optimize(Context ctx, IntPtr obj)
: base(ctx, obj)
{
Contract.Requires(ctx != null);
}
internal Optimize(Context ctx)
: base(ctx, Native.Z3_mk_optimize(ctx.nCtx))
{
Contract.Requires(ctx != null);
}
internal class DecRefQueue : IDecRefQueue
{
public DecRefQueue() : base() { }
public DecRefQueue(uint move_limit) : base(move_limit) { }
internal override void IncRef(Context ctx, IntPtr obj)
{
Native.Z3_optimize_inc_ref(ctx.nCtx, obj);
}
internal override void DecRef(Context ctx, IntPtr obj)
{
Native.Z3_optimize_dec_ref(ctx.nCtx, obj);
}
};
internal override void IncRef(IntPtr o)
{
Context.Optimize_DRQ.IncAndClear(Context, o);
base.IncRef(o);
}
internal override void DecRef(IntPtr o)
{
Context.Optimize_DRQ.Add(o);
base.DecRef(o);
}
#endregion
}
}

View file

@ -79,6 +79,7 @@ namespace Microsoft.Z3
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject);
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
@ -118,6 +119,7 @@ namespace Microsoft.Z3
/// </summary>
public void Add(string name, string value)
{
Contract.Requires(name != null);
Contract.Requires(value != null);
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, Context.MkSymbol(value).NativeObject);

View file

@ -178,8 +178,8 @@ namespace Microsoft.Z3
{
get
{
ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
return ass.Size;
ASTVector assertions = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
return assertions.Size;
}
}
@ -192,12 +192,8 @@ namespace Microsoft.Z3
{
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
uint n = ass.Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = new BoolExpr(Context, ass[i].NativeObject);
return res;
ASTVector assertions = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
return assertions.ToBoolExprArray();
}
}
@ -270,18 +266,14 @@ namespace Microsoft.Z3
/// The result is empty if <c>Check</c> was not invoked before,
/// if its results was not <c>UNSATISFIABLE</c>, or if core production is disabled.
/// </remarks>
public Expr[] UnsatCore
public BoolExpr[] UnsatCore
{
get
{
Contract.Ensures(Contract.Result<Expr[]>() != null);
ASTVector core = new ASTVector(Context, Native.Z3_solver_get_unsat_core(Context.nCtx, NativeObject));
uint n = core.Size;
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(Context, core[i].NativeObject);
return res;
ASTVector core = new ASTVector(Context, Native.Z3_solver_get_unsat_core(Context.nCtx, NativeObject));
return core.ToBoolExprArray();
}
}

View file

@ -92,10 +92,10 @@ class ASTMap extends Z3Object
*
* @throws Z3Exception
**/
public ASTVector getKeys()
public AST[] getKeys()
{
return new ASTVector(getContext(), Native.astMapKeys(getContext().nCtx(),
getNativeObject()));
ASTVector av = new ASTVector(getContext(), Native.astMapKeys(getContext().nCtx(), getNativeObject()));
return av.ToArray();
}
/**

View file

@ -119,4 +119,135 @@ public class ASTVector extends Z3Object
getContext().getASTVectorDRQ().add(o);
super.decRef(o);
}
}
/**
* Translates the AST vector into an AST[]
* */
public AST[] ToArray()
{
int n = size();
AST[] res = new AST[n];
for (int i = 0; i < n; i++)
res[i] = AST.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an Expr[]
* */
public Expr[] ToExprArray() {
int n = size();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an BoolExpr[]
* */
public BoolExpr[] ToBoolExprArray()
{
int n = size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = (BoolExpr) Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an BitVecExpr[]
* */
public BitVecExpr[] ToBitVecExprArray()
{
int n = size();
BitVecExpr[] res = new BitVecExpr[n];
for (int i = 0; i < n; i++)
res[i] = (BitVecExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an ArithExpr[]
* */
public ArithExpr[] ToArithExprExprArray()
{
int n = size();
ArithExpr[] res = new ArithExpr[n];
for (int i = 0; i < n; i++)
res[i] = (ArithExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an ArrayExpr[]
* */
public ArrayExpr[] ToArrayExprArray()
{
int n = size();
ArrayExpr[] res = new ArrayExpr[n];
for (int i = 0; i < n; i++)
res[i] = (ArrayExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an DatatypeExpr[]
* */
public DatatypeExpr[] ToDatatypeExprArray()
{
int n = size();
DatatypeExpr[] res = new DatatypeExpr[n];
for (int i = 0; i < n; i++)
res[i] = (DatatypeExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an FPExpr[]
* */
public FPExpr[] ToFPExprArray()
{
int n = size();
FPExpr[] res = new FPExpr[n];
for (int i = 0; i < n; i++)
res[i] = (FPExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an FPRMExpr[]
* */
public FPRMExpr[] ToFPRMExprArray()
{
int n = size();
FPRMExpr[] res = new FPRMExpr[n];
for (int i = 0; i < n; i++)
res[i] = (FPRMExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an IntExpr[]
* */
public IntExpr[] ToIntExprArray()
{
int n = size();
IntExpr[] res = new IntExpr[n];
for (int i = 0; i < n; i++)
res[i] = (IntExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an RealExpr[]
* */
public RealExpr[] ToRealExprArray()
{
int n = size();
RealExpr[] res = new RealExpr[n];
for (int i = 0; i < n; i++)
res[i] = (RealExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
}

View file

@ -361,6 +361,23 @@ public class Context extends IDisposable
return mkDatatypeSorts(mkSymbols(names), c);
}
/**
* Update a datatype field at expression t with value v.
* The function performs a record update at t. The field
* that is passed in as argument is updated with value v,
* the remainig fields of t are unchanged.
**/
public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
throws Z3Exception
{
return Expr.create
(this,
Native.datatypeUpdateField
(nCtx(), field.getNativeObject(),
t.getNativeObject(), v.getNativeObject()));
}
/**
* Creates a new function declaration.
**/

View file

@ -43,6 +43,21 @@ public class FPNum extends FPExpr
return Native.fpaGetNumeralSignificandString(getContext().nCtx(), getNativeObject());
}
/**
* The significand value of a floating-point numeral as a UInt64
* Remarks: This function extracts the significand bits, without the
* hidden bit or normalization. Throws an exception if the
* significand does not fit into a UInt64.
* @throws Z3Exception
**/
public long getSignificandUInt64()
{
Native.LongPtr res = new Native.LongPtr();
if (Native.fpaGetNumeralSignificandUint64(getContext().nCtx(), getNativeObject(), res) ^ true)
throw new Z3Exception("Significand is not a 64 bit unsigned integer");
return res.value;
}
/**
* Return the exponent value of a floating-point numeral as a string
* @throws Z3Exception

View file

@ -43,7 +43,7 @@ public class FPSort extends Sort
* The number of significand bits.
*/
public int getSBits() {
return Native.fpaGetEbits(getContext().nCtx(), getNativeObject());
return Native.fpaGetSbits(getContext().nCtx(), getNativeObject());
}
}

View file

@ -295,14 +295,8 @@ public class Fixedpoint extends Z3Object
**/
public BoolExpr[] getRules()
{
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetRules(
getContext().nCtx(), getNativeObject()));
int n = v.size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = new BoolExpr(getContext(), v.get(i).getNativeObject());
return res;
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetRules(getContext().nCtx(), getNativeObject()));
return v.ToBoolExprArray();
}
/**
@ -312,17 +306,45 @@ public class Fixedpoint extends Z3Object
**/
public BoolExpr[] getAssertions()
{
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetAssertions(
getContext().nCtx(), getNativeObject()));
int n = v.size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = new BoolExpr(getContext(), v.get(i).getNativeObject());
return res;
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetAssertions(getContext().nCtx(), getNativeObject()));
return v.ToBoolExprArray();
}
Fixedpoint(Context ctx, long obj)
/**
* Fixedpoint statistics.
*
* @throws Z3Exception
**/
public Statistics getStatistics()
{
return new Statistics(getContext(), Native.fixedpointGetStatistics(
getContext().nCtx(), getNativeObject()));
}
/**
* Parse an SMT-LIB2 file with fixedpoint rules.
* Add the rules to the current fixedpoint context.
* Return the set of queries in the file.
**/
public BoolExpr[] ParseFile(String file)
{
ASTVector av = new ASTVector(getContext(), Native.fixedpointFromFile(getContext().nCtx(), getNativeObject(), file));
return av.ToBoolExprArray();
}
/**
* Parse an SMT-LIB2 string with fixedpoint rules.
* Add the rules to the current fixedpoint context.
* Return the set of queries in the file.
**/
public BoolExpr[] ParseString(String s)
{
ASTVector av = new ASTVector(getContext(), Native.fixedpointFromString(getContext().nCtx(), getNativeObject(), s));
return av.ToBoolExprArray();
}
Fixedpoint(Context ctx, long obj) throws Z3Exception
{
super(ctx, obj);
}

View file

@ -221,6 +221,22 @@ public class Goal extends Z3Object
return "Z3Exception: " + e.getMessage();
}
}
/**
* Goal to BoolExpr conversion.
*
* Returns a string representation of the Goal.
**/
public BoolExpr AsBoolExpr() {
int n = size();
if (n == 0)
return getContext().mkTrue();
else if (n == 1)
return getFormulas()[0];
else {
return getContext().mkAnd(getFormulas());
}
}
Goal(Context ctx, long obj)
{

View file

@ -73,20 +73,23 @@ public class InterpolationContext extends Context
* well documented.
* @throws Z3Exception
**/
public Expr[] GetInterpolant(Expr pf, Expr pat, Params p)
public BoolExpr[] GetInterpolant(Expr pf, Expr pat, Params p)
{
checkContextMatch(pf);
checkContextMatch(pat);
checkContextMatch(p);
ASTVector seq = new ASTVector(this, Native.getInterpolant(nCtx(), pf.getNativeObject(), pat.getNativeObject(), p.getNativeObject()));
int n = seq.size();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(this, seq.get(i).getNativeObject());
return res;
return seq.ToBoolExprArray();
}
public class ComputeInterpolantResult
{
public Z3_lbool status = Z3_lbool.Z3_L_UNDEF;
public BoolExpr[] interp = null;
public Model model = null;
};
/**
* Computes an interpolant.
* Remarks: For more information on interpolation please refer
@ -94,17 +97,20 @@ public class InterpolationContext extends Context
* well documented.
* @throws Z3Exception
**/
public Z3_lbool ComputeInterpolant(Expr pat, Params p, ASTVector interp, Model model)
public ComputeInterpolantResult ComputeInterpolant(Expr pat, Params p)
{
checkContextMatch(pat);
checkContextMatch(p);
ComputeInterpolantResult res = new ComputeInterpolantResult();
Native.LongPtr n_i = new Native.LongPtr();
Native.LongPtr n_m = new Native.LongPtr();
int r = Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m);
interp = new ASTVector(this, n_i.value);
model = new Model(this, n_m.value);
return Z3_lbool.fromInt(r);
res.status = Z3_lbool.fromInt(Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m));
if (res.status == Z3_lbool.Z3_L_FALSE)
res.interp = (new ASTVector(this, n_i.value)).ToBoolExprArray();
if (res.status == Z3_lbool.Z3_L_TRUE)
res.model = new Model(this, n_m.value);
return res;
}
///
@ -118,16 +124,23 @@ public class InterpolationContext extends Context
return Native.interpolationProfile(nCtx());
}
public class CheckInterpolantResult
{
public int return_value = 0;
public String error = null;
}
///
/// Checks the correctness of an interpolant.
///
/// Remarks: For more information on interpolation please refer
/// too the function Z3_check_interpolant in the C/C++ API, which is
/// well documented.
public int CheckInterpolant(Expr[] cnsts, int[] parents, Expr[] interps, String error, Expr[] theory)
public CheckInterpolantResult CheckInterpolant(Expr[] cnsts, int[] parents, BoolExpr[] interps, String error, Expr[] theory)
{
CheckInterpolantResult res = new CheckInterpolantResult();
Native.StringPtr n_err_str = new Native.StringPtr();
int r = Native.checkInterpolant(nCtx(),
res.return_value = Native.checkInterpolant(nCtx(),
cnsts.length,
Expr.arrayToNative(cnsts),
parents,
@ -135,41 +148,52 @@ public class InterpolationContext extends Context
n_err_str,
theory.length,
Expr.arrayToNative(theory));
error = n_err_str.value;
return r;
res.error = n_err_str.value;
return res;
}
public class ReadInterpolationProblemResult
{
public int return_value = 0;
public Expr[] cnsts;
public int[] parents;
public String error;
public Expr[] theory;
};
///
/// Reads an interpolation problem from a file.
///
/// Remarks: For more information on interpolation please refer
/// too the function Z3_read_interpolation_problem in the C/C++ API, which is
/// well documented.
public int ReadInterpolationProblem(String filename, Expr[] cnsts, int[] parents, String error, Expr[] theory)
public ReadInterpolationProblemResult ReadInterpolationProblem(String filename, Expr[] cnsts, int[] parents, String error, Expr[] theory)
{
ReadInterpolationProblemResult res = new ReadInterpolationProblemResult();
Native.IntPtr n_num = new Native.IntPtr();
Native.IntPtr n_num_theory = new Native.IntPtr();
Native.ObjArrayPtr n_cnsts = new Native.ObjArrayPtr();
Native.UIntArrayPtr n_parents = new Native.UIntArrayPtr();
Native.ObjArrayPtr n_theory = new Native.ObjArrayPtr();
Native.StringPtr n_err_str = new Native.StringPtr();
int r = Native.readInterpolationProblem(nCtx(), n_num, n_cnsts, n_parents, filename, n_err_str, n_num_theory, n_theory);
res.return_value = Native.readInterpolationProblem(nCtx(), n_num, n_cnsts, n_parents, filename, n_err_str, n_num_theory, n_theory);
int num = n_num.value;
int num_theory = n_num_theory.value;
error = n_err_str.value;
cnsts = new Expr[num];
parents = new int[num];
res.error = n_err_str.value;
res.cnsts = new Expr[num];
res.parents = new int[num];
theory = new Expr[num_theory];
for (int i = 0; i < num; i++)
{
cnsts[i] = Expr.create(this, n_cnsts.value[i]);
parents[i] = n_parents.value[i];
res.cnsts[i] = Expr.create(this, n_cnsts.value[i]);
res.parents[i] = n_parents.value[i];
}
for (int i = 0; i < num_theory; i++)
theory[i] = Expr.create(this, n_theory.value[i]);
return r;
res.theory[i] = Expr.create(this, n_theory.value[i]);
return res;
}
///
/// Writes an interpolation problem to a file.
///

View file

@ -273,11 +273,7 @@ public class Model extends Z3Object
ASTVector nUniv = new ASTVector(getContext(), Native.modelGetSortUniverse(
getContext().nCtx(), getNativeObject(), s.getNativeObject()));
int n = nUniv.size();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(getContext(), nUniv.get(i).getNativeObject());
return res;
return nUniv.ToExprArray();
}
/**

View file

@ -176,8 +176,7 @@ public class Solver extends Z3Object
**/
public int getNumAssertions()
{
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(
getContext().nCtx(), getNativeObject()));
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(getContext().nCtx(), getNativeObject()));
return assrts.size();
}
@ -188,13 +187,8 @@ public class Solver extends Z3Object
**/
public BoolExpr[] getAssertions()
{
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(
getContext().nCtx(), getNativeObject()));
int n = assrts.size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = new BoolExpr(getContext(), assrts.get(i).getNativeObject());
return res;
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(getContext().nCtx(), getNativeObject()));
return assrts.ToBoolExprArray();
}
/**
@ -282,16 +276,11 @@ public class Solver extends Z3Object
*
* @throws Z3Exception
**/
public Expr[] getUnsatCore()
public BoolExpr[] getUnsatCore()
{
ASTVector core = new ASTVector(getContext(), Native.solverGetUnsatCore(
getContext().nCtx(), getNativeObject()));
int n = core.size();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(getContext(), core.get(i).getNativeObject());
return res;
ASTVector core = new ASTVector(getContext(), Native.solverGetUnsatCore(getContext().nCtx(), getNativeObject()));
return core.ToBoolExprArray();
}
/**

File diff suppressed because it is too large Load diff

View file

@ -123,7 +123,7 @@ sig
end
(** The abstract syntax tree (AST) module *)
module AST :
module rec AST :
sig
type ast
@ -156,6 +156,12 @@ sig
@return A new ASTVector *)
val translate : ast_vector -> context -> ast_vector
(** Translates the ASTVector into an (Ast.ast list) *)
val to_list : ast_vector -> ast list
(** Translates the ASTVector into an (Expr.expr list) *)
val to_expr_list : ast_vector -> Expr.expr list
(** Retrieves a string representation of the vector. *)
val to_string : ast_vector -> string
end
@ -189,7 +195,7 @@ sig
val get_size : ast_map -> int
(** The keys stored in the map. *)
val get_keys : ast_map -> ast list
val get_keys : ast_map -> Expr.expr list
(** Retrieves a string representation of the map.*)
val to_string : ast_map -> string
@ -260,7 +266,7 @@ sig
end
(** The Sort module implements type information for ASTs *)
module Sort :
and Sort :
sig
type sort = Sort of AST.ast
@ -291,7 +297,7 @@ sig
end
(** Function declarations *)
module rec FuncDecl :
and FuncDecl :
sig
type func_decl = FuncDecl of AST.ast
@ -2155,6 +2161,12 @@ sig
(** Return the significand value of a floating-point numeral as a string. *)
val get_numeral_significand_string : context -> Expr.expr -> string
(** Return the significand value of a floating-point numeral as a uint64.
Remark: This function extracts the significand bits, without the
hidden bit or normalization. Throws an exception if the
significand does not fit into a uint64. *)
val get_numeral_significand_uint : context -> Expr.expr -> bool * int
(** Return the exponent value of a floating-point numeral as a string *)
val get_numeral_exponent_string : context -> Expr.expr -> string
@ -2641,6 +2653,9 @@ sig
(** A string representation of the Goal. *)
val to_string : goal -> string
(** Goal to BoolExpr conversion. *)
val as_expr : goal -> Expr.expr
end
(** Models
@ -2751,7 +2766,7 @@ sig
(** The finite set of distinct values that represent the interpretation of a sort.
{!get_sorts}
@return A list of expressions, where each is an element of the universe of the sort *)
val sort_universe : model -> Sort.sort -> AST.ast list
val sort_universe : model -> Sort.sort -> Expr.expr list
(** Conversion of models to strings.
@return A string representation of the model. *)
@ -2938,6 +2953,55 @@ sig
val interrupt : context -> unit
end
(** Objects that track statistical information. *)
module Statistics :
sig
type statistics
(** Statistical data is organized into pairs of \[Key, Entry\], where every
Entry is either a floating point or integer value. *)
module Entry :
sig
type statistics_entry
(** The key of the entry. *)
val get_key : statistics_entry -> string
(** The int-value of the entry. *)
val get_int : statistics_entry -> int
(** The float-value of the entry. *)
val get_float : statistics_entry -> float
(** True if the entry is uint-valued. *)
val is_int : statistics_entry -> bool
(** True if the entry is float-valued. *)
val is_float : statistics_entry -> bool
(** The string representation of the the entry's value. *)
val to_string_value : statistics_entry -> string
(** The string representation of the entry (key and value) *)
val to_string : statistics_entry -> string
end
(** A string representation of the statistical data. *)
val to_string : statistics -> string
(** The number of statistical data. *)
val get_size : statistics -> int
(** The data entries. *)
val get_entries : statistics -> Entry.statistics_entry list
(** The statistical counters. *)
val get_keys : statistics -> string list
(** The value of a particular statistical counter. *)
val get : statistics -> string -> Entry.statistics_entry option
end
(** Solvers *)
module Solver :
sig
@ -2946,56 +3010,6 @@ sig
val string_of_status : status -> string
(** Objects that track statistical information about solvers. *)
module Statistics :
sig
type statistics
(** Statistical data is organized into pairs of \[Key, Entry\], where every
Entry is either a floating point or integer value.
*)
module Entry :
sig
type statistics_entry
(** The key of the entry. *)
val get_key : statistics_entry -> string
(** The int-value of the entry. *)
val get_int : statistics_entry -> int
(** The float-value of the entry. *)
val get_float : statistics_entry -> float
(** True if the entry is uint-valued. *)
val is_int : statistics_entry -> bool
(** True if the entry is float-valued. *)
val is_float : statistics_entry -> bool
(** The string representation of the the entry's value. *)
val to_string_value : statistics_entry -> string
(** The string representation of the entry (key and value) *)
val to_string : statistics_entry -> string
end
(** A string representation of the statistical data. *)
val to_string : statistics -> string
(** The number of statistical data. *)
val get_size : statistics -> int
(** The data entries. *)
val get_entries : statistics -> Entry.statistics_entry list
(** The statistical counters. *)
val get_keys : statistics -> string list
(** The value of a particular statistical counter. *)
val get : statistics -> string -> Entry.statistics_entry option
end
(** A string that describes all available solver parameters. *)
val get_help : solver -> string
@ -3081,7 +3095,7 @@ sig
The unsat core is a subset of [Assertions]
The result is empty if [Check] was not invoked before,
if its results was not [UNSATISFIABLE], or if core production is disabled. *)
val get_unsat_core : solver -> AST.ast list
val get_unsat_core : solver -> Expr.expr list
(** A brief justification of why the last call to [Check] returned [UNKNOWN]. *)
val get_reason_unknown : solver -> string
@ -3198,6 +3212,19 @@ sig
(** Create a Fixedpoint context. *)
val mk_fixedpoint : context -> fixedpoint
(** Retrieve statistics information from the last call to #Z3_fixedpoint_query. *)
val get_statistics : fixedpoint -> Statistics.statistics
(** Parse an SMT-LIB2 string with fixedpoint rules.
Add the rules to the current fixedpoint context.
Return the set of queries in the string. *)
val parse_string : fixedpoint -> string -> Expr.expr list
(** Parse an SMT-LIB2 file with fixedpoint rules.
Add the rules to the current fixedpoint context.
Return the set of queries in the file. *)
val parse_file : fixedpoint -> string -> Expr.expr list
end
(** Functions for handling SMT and SMT2 expressions and files *)
@ -3272,12 +3299,12 @@ sig
(** Gets an interpolant.
For more information on interpolation please refer
too the C/C++ API, which is well documented. *)
val get_interpolant : context -> Expr.expr -> Expr.expr -> Params.params -> AST.ASTVector.ast_vector
val get_interpolant : context -> Expr.expr -> Expr.expr -> Params.params -> Expr.expr list
(** Computes an interpolant.
For more information on interpolation please refer
too the C/C++ API, which is well documented. *)
val compute_interpolant : context -> Expr.expr -> Params.params -> (AST.ASTVector.ast_vector * Model.model)
val compute_interpolant : context -> Expr.expr -> Params.params -> (Z3enums.lbool * Expr.expr list option * Model.model option)
(** Retrieves an interpolation profile.
For more information on interpolation please refer
@ -3355,3 +3382,5 @@ val enable_trace : string -> unit
*)
val disable_trace : string -> unit

18978
src/api/ml/z3_stubs.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,7 @@ sat
Z3 exceptions:
>>> try:
... x = Int('x')
... x = BitVec('x', 32)
... y = Bool('y')
... # the expression x + y is type incorrect
... n = x + y
@ -301,7 +301,6 @@ class AstRef(Z3PPObject):
"""Return unique identifier for object. It can be used for hash-tables and maps."""
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def ctx_ref(self):
"""Return a reference to the C context where this AST node is stored."""
return self.ctx.ref()
@ -455,7 +454,6 @@ class SortRef(AstRef):
def get_id(self):
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def kind(self):
"""Return the Z3 internal kind of a sort. This method can be used to test if `self` is one of the Z3 builtin sorts.
@ -555,6 +553,8 @@ def _to_sort_ref(s, ctx):
return ArraySortRef(s, ctx)
elif k == Z3_DATATYPE_SORT:
return DatatypeSortRef(s, ctx)
elif k == Z3_FINITE_DOMAIN_SORT:
return FiniteDomainSortRef(s, ctx)
elif k == Z3_FLOATING_POINT_SORT:
return FPSortRef(s, ctx)
elif k == Z3_ROUNDING_MODE_SORT:
@ -1228,6 +1228,16 @@ class BoolSortRef(SortRef):
_z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
return val
def subsort(self, other):
return isinstance(other, ArithSortRef)
def is_int(self):
return True
def is_bool(self):
return True
class BoolRef(ExprRef):
"""All Boolean expressions are instances of this class."""
def sort(self):
@ -1900,6 +1910,10 @@ class ArithSortRef(SortRef):
return val
if val_s.is_int() and self.is_real():
return ToReal(val)
if val_s.is_bool() and self.is_int():
return If(val, 1, 0)
if val_s.is_bool() and self.is_real():
return ToReal(If(val, 1, 0))
if __debug__:
_z3_assert(False, "Z3 Integer/Real expression expected" )
else:
@ -5603,7 +5617,7 @@ class Statistics:
sat
>>> st = s.statistics()
>>> len(st)
2
4
"""
return int(Z3_stats_size(self.ctx.ref(), self.stats))
@ -5617,7 +5631,7 @@ class Statistics:
sat
>>> st = s.statistics()
>>> len(st)
2
4
>>> st[0]
('nlsat propagations', 2)
>>> st[1]
@ -5641,7 +5655,7 @@ class Statistics:
sat
>>> st = s.statistics()
>>> st.keys()
['nlsat propagations', 'nlsat stages']
['nlsat propagations', 'nlsat stages', 'max memory', 'memory']
"""
return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
@ -5678,7 +5692,7 @@ class Statistics:
sat
>>> st = s.statistics()
>>> st.keys()
['nlsat propagations', 'nlsat stages']
['nlsat propagations', 'nlsat stages', 'max memory', 'memory']
>>> st.nlsat_propagations
2
>>> st.nlsat_stages
@ -6071,8 +6085,6 @@ class Solver(Z3PPObject):
e = BoolVal(True, self.ctx).as_ast()
return Z3_benchmark_to_smtlib_string(self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e)
def SolverFor(logic, ctx=None):
"""Create a solver customized for the given logic.
@ -6333,6 +6345,166 @@ class Fixedpoint(Z3PPObject):
else:
return Exists(self.vars, fml)
#########################################
#
# Finite domain sorts
#
#########################################
class FiniteDomainSortRef(SortRef):
"""Finite domain sort."""
def size(self):
"""Return the size of the finite domain sort"""
r = (ctype.c_ulonglong * 1)()
if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast(), r):
return r[0]
else:
raise Z3Exception("Failed to retrieve finite domain sort size")
def FiniteDomainSort(name, sz, ctx=None):
"""Create a named finite domain sort of a given size sz"""
ctx = _get_ctx(ctx)
return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
#########################################
#
# Optimize
#
#########################################
class OptimizeObjective:
def __init__(self, opt, value, is_max):
self._opt = opt
self._value = value
self._is_max = is_max
def lower(self):
opt = self._opt
return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
def upper(self):
opt = self._opt
return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
def value(self):
if self._is_max:
return self.upper()
else:
return self.lower()
class Optimize(Z3PPObject):
"""Optimize API provides methods for solving using objective functions and weighted soft constraints"""
def __init__(self, ctx=None):
self.ctx = _get_ctx(ctx)
self.optimize = Z3_mk_optimize(self.ctx.ref())
Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
def __del__(self):
if self.optimize != None:
Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
def set(self, *args, **keys):
"""Set a configuration option. The method `help()` return a string containing all available options.
"""
p = args2params(args, keys, self.ctx)
Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
def help(self):
"""Display a string describing all available options."""
print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
def param_descrs(self):
"""Return the parameter description set."""
return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
def assert_exprs(self, *args):
"""Assert constraints as background axioms for the optimize solver."""
args = _get_args(args)
for arg in args:
if isinstance(arg, Goal) or isinstance(arg, AstVector):
for f in arg:
Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
else:
Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
def add(self, *args):
"""Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
self.assert_exprs(*args)
def add_soft(self, arg, weight = "1", id = None):
"""Add soft constraint with optional weight and optional identifier.
If no weight is supplied, then the penalty for violating the soft constraint
is 1.
Soft constraints are grouped by identifiers. Soft constraints that are
added without identifiers are grouped by default.
"""
if _is_int(weight):
weight = "%d" % weight
if not isinstance(weight, str):
raise Z3Exception("weight should be a string or an integer")
if id == None:
id = ""
id = to_symbol(id, self.ctx)
v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, arg.as_ast(), weight, id)
return OptimizeObjective(self, v, False)
def maximize(self, arg):
"""Add objective function to maximize."""
return OptimizeObjective(self, Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()), True)
def minimize(self, arg):
"""Add objective function to minimize."""
return OptimizeObjective(self, Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()), False)
def push(self):
"""create a backtracking point for added rules, facts and assertions"""
Z3_optimize_push(self.ctx.ref(), self.optimize)
def pop(self):
"""restore to previously created backtracking point"""
Z3_optimize_pop(self.ctx.ref(), self.optimize)
def check(self):
"""Check satisfiability while optimizing objective functions."""
return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize))
def model(self):
"""Return a model for the last check()."""
try:
return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
except Z3Exception:
raise Z3Exception("model is not available")
def lower(self, obj):
if not isinstance(obj, OptimizeObjective):
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
return obj.lower()
def upper(self, obj):
if not isinstance(obj, OptimizeObjective):
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
return obj.upper()
def __repr__(self):
"""Return a formatted string with all added rules and constraints."""
return self.sexpr()
def sexpr(self):
"""Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
"""
return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
def statistics(self):
"""Return statistics for the last `query()`.
"""
return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
#########################################
#
# ApplyResult
@ -8022,23 +8194,24 @@ def FP(name, fpsort, ctx=None):
>>> eq(x, x2)
True
"""
ctx = fpsort.ctx
if isinstance(fpsort, FPSortRef):
ctx = fpsort.ctx
else:
ctx = _get_ctx(ctx)
return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
def FPs(names, fpsort, ctx=None):
"""Return an array of floating-point constants.
>>> x, y, z = BitVecs('x y z', 16)
>>> x.size()
16
>>> x, y, z = FPs('x y z', FPSort(8, 24))
>>> x.sort()
BitVec(16)
>>> Sum(x, y, z)
0 + x + y + z
>>> Product(x, y, z)
1*x*y*z
>>> simplify(Product(x, y, z))
x*y*z
FPSort(8, 24)
>>> x.sbits()
24
>>> x.ebits()
8
>>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
fpMul(RNE(), fpAdd(RNE(), x, y), z)
"""
ctx = z3._get_ctx(ctx)
if isinstance(names, str):

View file

@ -1017,6 +1017,8 @@ class Formatter:
return self.pp_seq(a.assertions(), 0, [])
elif isinstance(a, z3.Fixedpoint):
return a.sexpr()
elif isinstance(a, z3.Optimize):
return a.sexpr()
elif isinstance(a, z3.ApplyResult):
return self.pp_seq_seq(a, 0, [])
elif isinstance(a, z3.ModelRef):

View file

@ -78,6 +78,10 @@ class FixedpointObj(ctypes.c_void_p):
def __init__(self, fixedpoint): self._as_parameter_ = fixedpoint
def from_param(obj): return obj
class OptimizeObj(ctypes.c_void_p):
def __init__(self, optimize): self._as_parameter_ = optimize
def from_param(obj): return obj
class ModelObj(ctypes.c_void_p):
def __init__(self, model): self._as_parameter_ = model
def from_param(obj): return obj

468
src/api/python/z3util.py Normal file
View file

@ -0,0 +1,468 @@
"""
Usage:
import common_z3 as CM_Z3
"""
import common as CM
from z3 import *
def get_z3_version(as_str=False):
major = ctypes.c_uint(0)
minor = ctypes.c_uint(0)
build = ctypes.c_uint(0)
rev = ctypes.c_uint(0)
Z3_get_version(major,minor,build,rev)
rs = map(int,(major.value,minor.value,build.value,rev.value))
if as_str:
return "{}.{}.{}.{}".format(*rs)
else:
return rs
def ehash(v):
"""
Returns a 'stronger' hash value than the default hash() method.
The result from hash() is not enough to distinguish between 2
z3 expressions in some cases.
>>> x1 = Bool('x'); x2 = Bool('x'); x3 = Int('x')
>>> print x1.hash(),x2.hash(),x3.hash() #BAD: all same hash values
783810685 783810685 783810685
>>> print ehash(x1), ehash(x2), ehash(x3)
x_783810685_1 x_783810685_1 x_783810685_2
"""
if __debug__:
assert is_expr(v)
return "{}_{}_{}".format(str(v),v.hash(),v.sort_kind())
"""
In Z3, variables are caleld *uninterpreted* consts and
variables are *interpreted* consts.
"""
def is_expr_var(v):
"""
EXAMPLES:
>>> is_expr_var(Int('7'))
True
>>> is_expr_var(IntVal('7'))
False
>>> is_expr_var(Bool('y'))
True
>>> is_expr_var(Int('x') + 7 == Int('y'))
False
>>> LOnOff, (On,Off) = EnumSort("LOnOff",['On','Off'])
>>> Block,Reset,SafetyInjection=Consts("Block Reset SafetyInjection",LOnOff)
>>> is_expr_var(LOnOff)
False
>>> is_expr_var(On)
False
>>> is_expr_var(Block)
True
>>> is_expr_var(SafetyInjection)
True
"""
return is_const(v) and v.decl().kind()==Z3_OP_UNINTERPRETED
def is_expr_val(v):
"""
EXAMPLES:
>>> is_expr_val(Int('7'))
False
>>> is_expr_val(IntVal('7'))
True
>>> is_expr_val(Bool('y'))
False
>>> is_expr_val(Int('x') + 7 == Int('y'))
False
>>> LOnOff, (On,Off) = EnumSort("LOnOff",['On','Off'])
>>> Block,Reset,SafetyInjection=Consts("Block Reset SafetyInjection",LOnOff)
>>> is_expr_val(LOnOff)
False
>>> is_expr_val(On)
True
>>> is_expr_val(Block)
False
>>> is_expr_val(SafetyInjection)
False
"""
return is_const(v) and v.decl().kind()!=Z3_OP_UNINTERPRETED
def get_vars(f,rs=[]):
"""
>>> x,y = Ints('x y')
>>> a,b = Bools('a b')
>>> get_vars(Implies(And(x+y==0,x*2==10),Or(a,Implies(a,b==False))))
[x, y, a, b]
"""
if __debug__:
assert is_expr(f)
if is_const(f):
if is_expr_val(f):
return rs
else: #variable
return CM.vset(rs + [f],str)
else:
for f_ in f.children():
rs = get_vars(f_,rs)
return CM.vset(rs,str)
def mk_var(name,vsort):
if vsort.kind() == Z3_INT_SORT:
v = Int(name)
elif vsort.kind() == Z3_REAL_SORT:
v = Real(name)
elif vsort.kind() == Z3_BOOL_SORT:
v = Bool(name)
elif vsort.kind() == Z3_DATATYPE_SORT:
v = Const(name,vsort)
else:
assert False, 'Cannot handle this sort (s: %sid: %d)'\
%(vsort,vsort.kind())
return v
def prove(claim,assume=None,verbose=0):
"""
>>> r,m = prove(BoolVal(True),verbose=0); r,model_str(m,as_str=False)
(True, None)
#infinite counter example when proving contradiction
>>> r,m = prove(BoolVal(False)); r,model_str(m,as_str=False)
(False, [])
>>> x,y,z=Bools('x y z')
>>> r,m = prove(And(x,Not(x))); r,model_str(m,as_str=True)
(False, '[]')
>>> r,m = prove(True,assume=And(x,Not(x)),verbose=0)
Traceback (most recent call last):
...
AssertionError: Assumption is alway False!
>>> r,m = prove(Implies(x,x),assume=y,verbose=2); r,model_str(m,as_str=False)
assume:
y
claim:
Implies(x, x)
to_prove:
Implies(y, Implies(x, x))
(True, None)
>>> r,m = prove(And(x,True),assume=y,verbose=0); r,model_str(m,as_str=False)
(False, [(x, False), (y, True)])
>>> r,m = prove(And(x,y),assume=y,verbose=0)
>>> print r
False
>>> print model_str(m,as_str=True)
x = False
y = True
>>> a,b = Ints('a b')
>>> r,m = prove(a**b == b**a,assume=None,verbose=0)
E: cannot solve !
>>> r is None and m is None
True
"""
if __debug__:
assert not assume or is_expr(assume)
to_prove = claim
if assume:
if __debug__:
is_proved,_ = prove(Not(assume))
def _f():
emsg = "Assumption is alway False!"
if verbose >= 2:
emsg = "{}\n{}".format(assume,emsg)
return emsg
assert is_proved==False, _f()
to_prove = Implies(assume,to_prove)
if verbose >= 2:
print('assume: ')
print(assume)
print('claim: ')
print(claim)
print('to_prove: ')
print(to_prove)
f = Not(to_prove)
models = get_models(f,k=1)
if models is None: #unknown
print('E: cannot solve !')
return None, None
elif models == False: #unsat
return True,None
else: #sat
if __debug__:
assert isinstance(models,list)
if models:
return False, models[0] #the first counterexample
else:
return False, [] #infinite counterexample,models
def get_models(f,k):
"""
Returns the first k models satisfiying f.
If f is not satisfiable, returns False.
If f cannot be solved, returns None
If f is satisfiable, returns the first k models
Note that if f is a tautology, e.g.\ True, then the result is []
Based on http://stackoverflow.com/questions/11867611/z3py-checking-all-solutions-for-equation
EXAMPLES:
>>> x, y = Ints('x y')
>>> len(get_models(And(0<=x,x <= 4),k=11))
5
>>> get_models(And(0<=x**y,x <= 1),k=2) is None
True
>>> get_models(And(0<=x,x <= -1),k=2)
False
>>> len(get_models(x+y==7,5))
5
>>> len(get_models(And(x<=5,x>=1),7))
5
>>> get_models(And(x<=0,x>=5),7)
False
>>> x = Bool('x')
>>> get_models(And(x,Not(x)),k=1)
False
>>> get_models(Implies(x,x),k=1)
[]
>>> get_models(BoolVal(True),k=1)
[]
"""
if __debug__:
assert is_expr(f)
assert k>=1
s = Solver()
s.add(f)
models = []
i = 0
while s.check() == sat and i < k:
i = i + 1
m = s.model()
if not m: #if m == []
break
models.append(m)
#create new constraint to block the current model
block = Not(And([v() == m[v] for v in m]))
s.add(block)
if s.check() == unknown:
return None
elif s.check() == unsat and i==0:
return False
else:
return models
def is_tautology(claim,verbose=0):
"""
>>> is_tautology(Implies(Bool('x'),Bool('x')))
True
>>> is_tautology(Implies(Bool('x'),Bool('y')))
False
>>> is_tautology(BoolVal(True))
True
>>> is_tautology(BoolVal(False))
False
"""
return prove(claim=claim,assume=None,verbose=verbose)[0]
def is_contradiction(claim,verbose=0):
"""
>>> x,y=Bools('x y')
>>> is_contradiction(BoolVal(False))
True
>>> is_contradiction(BoolVal(True))
False
>>> is_contradiction(x)
False
>>> is_contradiction(Implies(x,y))
False
>>> is_contradiction(Implies(x,x))
False
>>> is_contradiction(And(x,Not(x)))
True
"""
return prove(claim=Not(claim),assume=None,verbose=verbose)[0]
def exact_one_model(f):
"""
return True if f has exactly 1 model, False otherwise.
EXAMPLES:
>>> x, y = Ints('x y')
>>> exact_one_model(And(0<=x**y,x <= 0))
False
>>> exact_one_model(And(0<=x,x <= 0))
True
>>> exact_one_model(And(0<=x,x <= 1))
False
>>> exact_one_model(And(0<=x,x <= -1))
False
"""
models = get_models(f,k=2)
if isinstance(models,list):
return len(models)==1
else:
return False
def myBinOp(op,*L):
"""
>>> myAnd(*[Bool('x'),Bool('y')])
And(x, y)
>>> myAnd(*[Bool('x'),None])
x
>>> myAnd(*[Bool('x')])
x
>>> myAnd(*[])
>>> myAnd(Bool('x'),Bool('y'))
And(x, y)
>>> myAnd(*[Bool('x'),Bool('y')])
And(x, y)
>>> myAnd([Bool('x'),Bool('y')])
And(x, y)
>>> myAnd((Bool('x'),Bool('y')))
And(x, y)
>>> myAnd(*[Bool('x'),Bool('y'),True])
Traceback (most recent call last):
...
AssertionError
"""
if __debug__:
assert op == Z3_OP_OR or op == Z3_OP_AND or op == Z3_OP_IMPLIES
if len(L)==1 and (isinstance(L[0],list) or isinstance(L[0],tuple)):
L = L[0]
if __debug__:
assert all(not isinstance(l,bool) for l in L)
L = [l for l in L if is_expr(l)]
if L:
if len(L)==1:
return L[0]
else:
if op == Z3_OP_OR:
return Or(L)
elif op == Z3_OP_AND:
return And(L)
else: #IMPLIES
return Implies(L[0],L[1])
else:
return None
def myAnd(*L): return myBinOp(Z3_OP_AND,*L)
def myOr(*L): return myBinOp(Z3_OP_OR,*L)
def myImplies(a,b):return myBinOp(Z3_OP_IMPLIES,[a,b])
Iff = lambda f,g: And(Implies(f,g),Implies(g,f))
def model_str(m,as_str=True):
"""
Returned a 'sorted' model (so that it's easier to see)
The model is sorted by its key,
e.g. if the model is y = 3 , x = 10, then the result is
x = 10, y = 3
EXAMPLES:
see doctest exampels from function prove()
"""
if __debug__:
assert m is None or m == [] or isinstance(m,ModelRef)
if m :
vs = [(v,m[v]) for v in m]
vs = sorted(vs,key=lambda a,_: str(a))
if as_str:
return '\n'.join(['{} = {}'.format(k,v) for (k,v) in vs])
else:
return vs
else:
return str(m) if as_str else m

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#ifndef _Z3_API_H_
#define _Z3_API_H_
@ -47,6 +53,7 @@ DEFINE_TYPE(Z3_func_interp);
#define Z3_func_interp_opt Z3_func_interp
DEFINE_TYPE(Z3_func_entry);
DEFINE_TYPE(Z3_fixedpoint);
DEFINE_TYPE(Z3_optimize);
DEFINE_TYPE(Z3_rcf_num);
DEFINE_VOID(Z3_theory_data);
#endif
@ -85,6 +92,7 @@ DEFINE_VOID(Z3_theory_data);
- \c Z3_func_interp: interpretation of a function in a model.
- \c Z3_func_entry: representation of the value of a \c Z3_func_interp at a particular point.
- \c Z3_fixedpoint: context for the recursive predicate solver.
- \c Z3_optimize: context for solving optimization queries.
- \c Z3_ast_vector: vector of \c Z3_ast objects.
- \c Z3_ast_map: mapping from \c Z3_ast to \c Z3_ast objects.
- \c Z3_goal: set of formulas that can be solved and/or transformed using tactics and solvers.
@ -592,7 +600,10 @@ typedef enum
}
This proof object has one antecedent: a hypothetical proof for false.
It converts the proof in a proof for (or (not l_1) ... (not l_n)),
when T1 contains the hypotheses: l_1, ..., l_n.
when T1 contains the open hypotheses: l_1, ..., l_n.
The hypotheses are closed after an application of a lemma.
Furthermore, there are no other open hypotheses in the subtree covered by
the lemma.
- Z3_OP_PR_UNIT_RESOLUTION:
\nicebox{
@ -877,6 +888,17 @@ typedef enum
- Z3_OP_DT_ACCESSOR: datatype accessor.
- Z3_OP_DT_UPDATE_FIELD: datatype field update.
- Z3_OP_PB_AT_MOST: Cardinality constraint.
E.g., x + y + z <= 2
- Z3_OP_PB_LE: Generalized Pseudo-Boolean cardinality constraint.
Example 2*x + 3*y <= 4
- Z3_OP_PB_GE: Generalized Pseudo-Boolean cardinality constraint.
Example 2*x + 3*y + 2*z >= 4
- Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN: Floating-point rounding mode RNE
- Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY: Floating-point rounding mode RNA
@ -1141,6 +1163,12 @@ typedef enum {
Z3_OP_DT_CONSTRUCTOR=0x800,
Z3_OP_DT_RECOGNISER,
Z3_OP_DT_ACCESSOR,
Z3_OP_DT_UPDATE_FIELD,
// Pseudo Booleans
Z3_OP_PB_AT_MOST=0x900,
Z3_OP_PB_LE,
Z3_OP_PB_GE,
// Floating-Point Arithmetic
Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
@ -1327,6 +1355,7 @@ typedef enum
def_Type('FUNC_INTERP', 'Z3_func_interp', 'FuncInterpObj')
def_Type('FUNC_ENTRY', 'Z3_func_entry', 'FuncEntryObj')
def_Type('FIXEDPOINT', 'Z3_fixedpoint', 'FixedpointObj')
def_Type('OPTIMIZE', 'Z3_optimize', 'OptimizeObj')
def_Type('PARAM_DESCRS', 'Z3_param_descrs', 'ParamDescrs')
def_Type('RCF_NUM', 'Z3_rcf_num', 'RCFNumObj')
*/
@ -3868,6 +3897,28 @@ END_MLAPI_EXCLUDE
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(
__in Z3_context c, __in Z3_sort t, unsigned idx_c, unsigned idx_a);
/**
\brief Update record field with a value.
This corresponds to the 'with' construct in OCaml.
It has the effect of updating a record field with a given value.
The remaining fields are left unchanged. It is the record
equivalent of an array store (see \sa Z3_mk_store).
If the datatype has more than one constructor, then the update function
behaves as identity if there is a miss-match between the accessor and
constructor. For example ((_ update-field car) nil 1) is nil,
while ((_ update-field car) (cons 2 nil) 1) is (cons 1 nil).
\pre Z3_get_sort_kind(Z3_get_sort(c, t)) == Z3_get_domain(c, field_access, 1) == Z3_DATATYPE_SORT
\pre Z3_get_sort(c, value) == Z3_get_range(c, field_access)
def_API('Z3_datatype_update_field', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_datatype_update_field(
__in Z3_context c, __in Z3_func_decl field_access,
__in Z3_ast t, __in Z3_ast value);
/**
\brief Return arity of relation.
@ -3893,6 +3944,29 @@ END_MLAPI_EXCLUDE
Z3_sort Z3_API Z3_get_relation_column(__in Z3_context c, __in Z3_sort s, unsigned col);
/**
\brief Pseudo-Boolean relations.
Encode p1 + p2 + ... + pn <= k
def_API('Z3_mk_atmost', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in(UINT)))
*/
Z3_ast Z3_API Z3_mk_atmost(__in Z3_context c, __in unsigned num_args,
__in_ecount(num_args) Z3_ast const args[], __in unsigned k);
/**
\brief Pseudo-Boolean relations.
Encode k1*p1 + k2*p2 + ... + kn*pn <= k
def_API('Z3_mk_pble', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
*/
Z3_ast Z3_API Z3_mk_pble(__in Z3_context c, __in unsigned num_args,
__in_ecount(num_args) Z3_ast const args[], __in_ecount(num_args) int coeffs[],
__in int k);
/**
\mlonly {3 {L Function Declarations}} \endmlonly
*/
@ -4659,6 +4733,13 @@ END_MLAPI_EXCLUDE
*/
Z3_ast_opt Z3_API Z3_model_get_const_interp(__in Z3_context c, __in Z3_model m, __in Z3_func_decl a);
/**
\brief Test if there exists an interpretation (i.e., assignment) for \c a in the model \c m.
def_API('Z3_model_has_interp', BOOL, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL)))
*/
Z3_bool Z3_API Z3_model_has_interp(__in Z3_context c, __in Z3_model m, __in Z3_func_decl a);
/**
\brief Return the interpretation of the function \c f in the model \c m.
Return \mlonly [None], \endmlonly \conly \c NULL,
@ -5290,7 +5371,19 @@ END_MLAPI_EXCLUDE
*/
void Z3_API Z3_reset_memory(void);
#endif
#ifdef CorML3
/**
\brief Destroy all allocated resources.
Any pointers previously returned by the API become invalid.
Can be used for memory leak detection.
def_API('Z3_finalize_memory', VOID, ())
*/
void Z3_API Z3_finalize_memory(void);
#endif
/*@}*/
#ifdef CorML3
@ -5947,7 +6040,7 @@ END_MLAPI_EXCLUDE
/**
\brief Parse an SMT-LIB2 string with fixedpoint rules.
Add the rules to the current fixedpoint context.
Return the set of queries in the file.
Return the set of queries in the string.
\param c - context.
\param f - fixedpoint context.
@ -6039,6 +6132,197 @@ END_MLAPI_EXCLUDE
#endif
#endif
#ifdef CorML4
/**
@name Optimize facilities
*/
/*@{*/
/**
\brief Create a new optimize context.
\conly \remark User must use #Z3_optimize_inc_ref and #Z3_optimize_dec_ref to manage optimize objects.
\conly Even if the context was created using #Z3_mk_context instead of #Z3_mk_context_rc.
def_API('Z3_mk_optimize', OPTIMIZE, (_in(CONTEXT), ))
*/
Z3_optimize Z3_API Z3_mk_optimize(__in Z3_context c);
#ifdef Conly
/**
\brief Increment the reference counter of the given optimize context
def_API('Z3_optimize_inc_ref', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_inc_ref(__in Z3_context c,__in Z3_optimize d);
/**
\brief Decrement the reference counter of the given optimize context.
def_API('Z3_optimize_dec_ref', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_dec_ref(__in Z3_context c,__in Z3_optimize d);
#endif
/**
\brief Assert hard constraint to the optimization context.
def_API('Z3_optimize_assert', VOID, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/
void Z3_API Z3_optimize_assert(Z3_context c, Z3_optimize o, Z3_ast a);
/**
\brief Assert soft constraint to the optimization context.
\param c - context
\param o - optimization context
\param a - formula
\param weight - a positive weight, penalty for violating soft constraint
\param id - optional identifier to group soft constraints
def_API('Z3_optimize_assert_soft', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST), _in(STRING), _in(SYMBOL)))
*/
unsigned Z3_API Z3_optimize_assert_soft(Z3_context c, Z3_optimize o, Z3_ast a, Z3_string weight, Z3_symbol id);
/**
\brief Add a maximization constraint.
\param c - context
\param o - optimization context
\param a - arithmetical term
def_API('Z3_optimize_maximize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/
unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t);
/**
\brief Add a minimization constraint.
\param c - context
\param o - optimization context
\param a - arithmetical term
def_API('Z3_optimize_minimize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/
unsigned Z3_API Z3_optimize_minimize(Z3_context c, Z3_optimize o, Z3_ast t);
/**
\brief Create a backtracking point.
The optimize solver contains a set of rules, added facts and assertions.
The set of rules, facts and assertions are restored upon calling #Z3_optimize_pop.
\sa Z3_optimize_pop
def_API('Z3_optimize_push', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_push(Z3_context c,Z3_optimize d);
/**
\brief Backtrack one level.
\sa Z3_optimize_push
\pre The number of calls to pop cannot exceed calls to push.
def_API('Z3_optimize_pop', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_pop(Z3_context c,Z3_optimize d);
/**
\brief Check consistency and produce optimal values.
\param c - context
\param o - optimization context
def_API('Z3_optimize_check', INT, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o);
/**
\brief Retrieve the model for the last #Z3_optimize_check
The error handler is invoked if a model is not available because
the commands above were not invoked for the given optimization
solver, or if the result was \c Z3_L_FALSE.
def_API('Z3_optimize_get_model', MODEL, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_model Z3_API Z3_optimize_get_model(Z3_context c, Z3_optimize o);
/**
\brief Set parameters on optimization context.
\param c - context
\param o - optimization context
\param p - parameters
def_API('Z3_optimize_set_params', VOID, (_in(CONTEXT), _in(OPTIMIZE), _in(PARAMS)))
*/
void Z3_API Z3_optimize_set_params(Z3_context c, Z3_optimize o, Z3_params p);
/**
\brief Return the parameter description set for the given optimize object.
\param c - context
\param o - optimization context
def_API('Z3_optimize_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_param_descrs Z3_API Z3_optimize_get_param_descrs(Z3_context c, Z3_optimize o);
/**
\brief Retrieve lower bound value or approximation for the i'th optimization objective.
\param c - context
\param o - optimization context
\param idx - index of optimization objective
def_API('Z3_optimize_get_lower', AST, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
*/
Z3_ast Z3_API Z3_optimize_get_lower(Z3_context c, Z3_optimize o, unsigned idx);
/**
\brief Retrieve upper bound value or approximation for the i'th optimization objective.
\param c - context
\param o - optimization context
\param idx - index of optimization objective
def_API('Z3_optimize_get_upper', AST, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
*/
Z3_ast Z3_API Z3_optimize_get_upper(Z3_context c, Z3_optimize o, unsigned idx);
/**
\brief Print the current context as a string.
\param c - context.
\param o - optimization context.
def_API('Z3_optimize_to_string', STRING, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_string Z3_API Z3_optimize_to_string(
__in Z3_context c,
__in Z3_optimize o);
/**
\brief Return a string containing a description of parameters accepted by optimize.
def_API('Z3_optimize_get_help', STRING, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_string Z3_API Z3_optimize_get_help(__in Z3_context c, __in Z3_optimize t);
/**
\brief Retrieve statistics information from the last call to #Z3_optimize_check
def_API('Z3_optimize_get_statistics', STATS, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_stats Z3_API Z3_optimize_get_statistics(__in Z3_context c,__in Z3_optimize d);
#endif
#ifdef CorML4
/*@}*/
@ -6667,7 +6951,7 @@ END_MLAPI_EXCLUDE
def_API('Z3_tactic_apply_ex', APPLY_RESULT, (_in(CONTEXT), _in(TACTIC), _in(GOAL), _in(PARAMS)))
*/
Z3_apply_result Z3_API Z3_tactic_apply_ex(Z3_context c, Z3_tactic t, Z3_goal g, Z3_params p);
Z3_apply_result Z3_API Z3_tactic_apply_ex(__in Z3_context c, __in Z3_tactic t, __in Z3_goal g, __in Z3_params p);
#ifdef CorML3
/**

View file

@ -858,6 +858,20 @@ extern "C" {
*/
Z3_string Z3_API Z3_fpa_get_numeral_significand_string(__in Z3_context c, __in Z3_ast t);
/**
\brief Return the significand value of a floating-point numeral as a uint64.
\param c logical context
\param t a floating-point numeral
Remarks: This function extracts the significand bits in `t`, without the
hidden bit or normalization. Sets the Z3_INVALID_ARG error code if the
significand does not fit into a uint64.
def_API('Z3_fpa_get_numeral_significand_uint64', BOOL, (_in(CONTEXT), _in(AST), _out(UINT64)))
*/
Z3_bool Z3_API Z3_fpa_get_numeral_significand_uint64(__in Z3_context c, __in Z3_ast t, __out __uint64 * n);
/**
\brief Return the exponent value of a floating-point numeral as a string

View file

@ -1,3 +1,9 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#ifndef __in
#define __in
#endif

View file

@ -22,12 +22,14 @@ Notes:
#include"stream_buffer.h"
#include"symbol.h"
#include"trace.h"
#include<sstream>
void register_z3_replayer_cmds(z3_replayer & in);
void throw_invalid_reference() {
TRACE("z3_replayer", tout << "invalid argument reference\n";);
throw z3_replayer_exception("invalid argument reference");
throw z3_replayer_exception("invalid argument reference1");
}
struct z3_replayer::imp {
@ -45,7 +47,38 @@ struct z3_replayer::imp {
size_t_map<void *> m_heap;
svector<z3_replayer_cmd> m_cmds;
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY, FLOAT };
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, INT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY, FLOAT };
char const* kind2string(value_kind k) const {
switch (k) {
case INT64: return "int64";
case UINT64: return "uint64";
case DOUBLE: return "double";
case STRING: return "string";
case SYMBOL: return "symbol";
case OBJECT: return "object";
case UINT_ARRAY: return "uint_array";
case INT_ARRAY: return "int_array";
case SYMBOL_ARRAY: return "symbol_array";
case OBJECT_ARRAY: return "object_array";
case FLOAT: return "float";
default: UNREACHABLE(); return "unknown";
}
}
void check_arg(unsigned pos, value_kind k) const {
if (pos >= m_args.size()) {
TRACE("z3_replayer", tout << "too few arguments " << m_args.size() << " expecting " << kind2string(k) << "\n";);
throw z3_replayer_exception("invalid argument reference2");
}
if (m_args[pos].m_kind != k) {
std::stringstream strm;
strm << "expecting " << kind2string(k) << " at position "
<< pos << " but got " << kind2string(m_args[pos].m_kind);
throw z3_replayer_exception(strm.str().c_str());
}
}
struct value {
value_kind m_kind;
@ -71,6 +104,7 @@ struct z3_replayer::imp {
vector<ptr_vector<void> > m_obj_arrays;
vector<svector<Z3_symbol> > m_sym_arrays;
vector<unsigned_vector> m_unsigned_arrays;
vector<svector<int> > m_int_arrays;
imp(z3_replayer & o, std::istream & in):
m_owner(o),
@ -321,6 +355,15 @@ struct z3_replayer::imp {
v.push_back(static_cast<unsigned>(m_args[i].m_uint));
}
}
if (k == INT64) {
aidx = m_int_arrays.size();
nk = INT_ARRAY;
m_int_arrays.push_back(svector<int>());
svector<int> & v = m_int_arrays.back();
for (unsigned i = asz - sz; i < asz; i++) {
v.push_back(static_cast<int>(m_args[i].m_int));
}
}
else if (k == SYMBOL) {
aidx = m_sym_arrays.size();
nk = SYMBOL_ARRAY;
@ -489,8 +532,7 @@ struct z3_replayer::imp {
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
unsigned pos = static_cast<unsigned>(m_uint64);
TRACE("z3_replayer", tout << "[" << m_line << "] " << "* " << m_ptr << " " << pos << "\n";);
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
throw_invalid_reference();
check_arg(pos, OBJECT);
m_heap.insert(m_ptr, m_args[pos].m_obj);
break;
}
@ -499,8 +541,7 @@ struct z3_replayer::imp {
// @ obj_id array_pos idx
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
unsigned pos = static_cast<unsigned>(m_uint64);
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
throw_invalid_reference();
check_arg(pos, OBJECT_ARRAY);
unsigned aidx = static_cast<unsigned>(m_args[pos].m_uint);
ptr_vector<void> & v = m_obj_arrays[aidx];
skip_blank(); read_uint64();
@ -525,26 +566,22 @@ struct z3_replayer::imp {
}
int get_int(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return static_cast<int>(m_args[pos].m_int);
}
__int64 get_int64(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return m_args[pos].m_int;
}
unsigned get_uint(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return static_cast<unsigned>(m_args[pos].m_uint);
}
__uint64 get_uint64(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return m_args[pos].m_uint;
}
@ -555,46 +592,45 @@ struct z3_replayer::imp {
}
double get_double(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != DOUBLE)
throw_invalid_reference();
check_arg(pos, DOUBLE);
return m_args[pos].m_double;
}
Z3_string get_str(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
throw_invalid_reference();
check_arg(pos, STRING);
return m_args[pos].m_str;
}
Z3_symbol get_symbol(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL)
throw_invalid_reference();
check_arg(pos, SYMBOL);
return reinterpret_cast<Z3_symbol>(const_cast<char*>(m_args[pos].m_str));
}
void * get_obj(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
throw_invalid_reference();
check_arg(pos, OBJECT);
return m_args[pos].m_obj;
}
unsigned * get_uint_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT_ARRAY)
throw_invalid_reference();
check_arg(pos, UINT_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
return m_unsigned_arrays[idx].c_ptr();
}
int * get_int_array(unsigned pos) const {
check_arg(pos, INT_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
return m_int_arrays[idx].c_ptr();
}
Z3_symbol * get_symbol_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
throw_invalid_reference();
check_arg(pos, SYMBOL_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
return m_sym_arrays[idx].c_ptr();
}
void ** get_obj_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
throw_invalid_reference();
check_arg(pos, OBJECT_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
ptr_vector<void> const & v = m_obj_arrays[idx];
TRACE("z3_replayer_bug", tout << "pos: " << pos << ", idx: " << idx << " size(): " << v.size() << "\n";
@ -603,38 +639,32 @@ struct z3_replayer::imp {
}
int * get_int_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return reinterpret_cast<int*>(&(m_args[pos].m_int));
}
__int64 * get_int64_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return &(m_args[pos].m_int);
}
unsigned * get_uint_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return reinterpret_cast<unsigned*>(&(m_args[pos].m_uint));
}
__uint64 * get_uint64_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return &(m_args[pos].m_uint);
}
Z3_string * get_str_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
throw_invalid_reference();
check_arg(pos, STRING);
return &(m_args[pos].m_str);
}
void ** get_obj_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
throw_invalid_reference();
check_arg(pos, OBJECT);
return &(m_args[pos].m_obj);
}
@ -653,6 +683,7 @@ struct z3_replayer::imp {
m_obj_arrays.reset();
m_sym_arrays.reset();
m_unsigned_arrays.reset();
m_int_arrays.reset();
}
@ -715,6 +746,10 @@ unsigned * z3_replayer::get_uint_array(unsigned pos) const {
return m_imp->get_uint_array(pos);
}
int * z3_replayer::get_int_array(unsigned pos) const {
return m_imp->get_int_array(pos);
}
Z3_symbol * z3_replayer::get_symbol_array(unsigned pos) const {
return m_imp->get_symbol_array(pos);
}

View file

@ -50,6 +50,7 @@ public:
void * get_obj(unsigned pos) const;
unsigned * get_uint_array(unsigned pos) const;
int * get_int_array(unsigned pos) const;
Z3_symbol * get_symbol_array(unsigned pos) const;
void ** get_obj_array(unsigned pos) const;

View file

@ -316,7 +316,8 @@ func_decl::func_decl(symbol const & name, unsigned arity, sort * const * domain,
decl(AST_FUNC_DECL, name, info),
m_arity(arity),
m_range(range) {
memcpy(const_cast<sort **>(get_domain()), domain, sizeof(sort *) * arity);
if (arity != 0)
memcpy(const_cast<sort **>(get_domain()), domain, sizeof(sort *) * arity);
}
// -----------------------------------
@ -378,8 +379,10 @@ quantifier::quantifier(bool forall, unsigned num_decls, sort * const * decl_sort
memcpy(const_cast<sort **>(get_decl_sorts()), decl_sorts, sizeof(sort *) * num_decls);
memcpy(const_cast<symbol*>(get_decl_names()), decl_names, sizeof(symbol) * num_decls);
memcpy(const_cast<expr **>(get_patterns()), patterns, sizeof(expr *) * num_patterns);
memcpy(const_cast<expr **>(get_no_patterns()), no_patterns, sizeof(expr *) * num_no_patterns);
if (num_patterns != 0)
memcpy(const_cast<expr **>(get_patterns()), patterns, sizeof(expr *) * num_patterns);
if (num_no_patterns != 0)
memcpy(const_cast<expr **>(get_no_patterns()), no_patterns, sizeof(expr *) * num_no_patterns);
}
// -----------------------------------
@ -1043,6 +1046,13 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
case OP_DISTINCT: {
func_decl_info info(m_family_id, OP_DISTINCT);
info.set_pairwise();
for (unsigned i = 1; i < arity; i++) {
if (domain[i] != domain[0]) {
std::ostringstream buffer;
buffer << "Sort mismatch between first argument and argument " << (i+1);
throw ast_exception(buffer.str().c_str());
}
}
return m_manager->mk_func_decl(symbol("distinct"), arity, domain, m_bool_sort, info);
}
default:
@ -2036,7 +2046,13 @@ inline app * ast_manager::mk_app_core(func_decl * decl, expr * arg1, expr * arg2
}
app * ast_manager::mk_app(func_decl * decl, unsigned num_args, expr * const * args) {
SASSERT(decl->get_arity() == num_args || decl->is_right_associative() || decl->is_left_associative() || decl->is_chainable());
if (decl->get_arity() != num_args && !decl->is_right_associative() &&
!decl->is_left_associative() && !decl->is_chainable()) {
std::ostringstream buffer;
buffer << "Wrong number of arguments (" << num_args
<< ") passed to function " << mk_pp(decl, *this);
throw ast_exception(buffer.str().c_str());
}
app * r = 0;
if (num_args > 2 && !decl->is_flat_associative()) {
if (decl->is_right_associative()) {
@ -2071,6 +2087,8 @@ app * ast_manager::mk_app(func_decl * decl, unsigned num_args, expr * const * ar
return r;
}
func_decl * ast_manager::mk_fresh_func_decl(symbol const & prefix, symbol const & suffix, unsigned arity,
sort * const * domain, sort * range) {
func_decl_info info(null_family_id, null_decl_kind);
@ -2338,6 +2356,10 @@ quantifier * ast_manager::update_quantifier(quantifier * q, bool is_forall, unsi
num_patterns == 0 ? q->get_no_patterns() : 0);
}
app * ast_manager::mk_distinct(unsigned num_args, expr * const * args) {
return mk_app(m_basic_family_id, OP_DISTINCT, num_args, args);
}
app * ast_manager::mk_distinct_expanded(unsigned num_args, expr * const * args) {
if (num_args < 2)
return mk_true();

View file

@ -2000,12 +2000,13 @@ public:
app * mk_and(expr * arg1, expr * arg2, expr * arg3) { return mk_app(m_basic_family_id, OP_AND, arg1, arg2, arg3); }
app * mk_implies(expr * arg1, expr * arg2) { return mk_app(m_basic_family_id, OP_IMPLIES, arg1, arg2); }
app * mk_not(expr * n) { return mk_app(m_basic_family_id, OP_NOT, n); }
app * mk_distinct(unsigned num_args, expr * const * args) { return mk_app(m_basic_family_id, OP_DISTINCT, num_args, args); }
app * mk_distinct(unsigned num_args, expr * const * args);
app * mk_distinct_expanded(unsigned num_args, expr * const * args);
app * mk_true() { return m_true; }
app * mk_false() { return m_false; }
app * mk_interp(expr * arg) { return mk_app(m_basic_family_id, OP_INTERP, arg); }
func_decl* mk_and_decl() {
sort* domain[2] = { m_bool_sort, m_bool_sort };
return mk_func_decl(m_basic_family_id, OP_AND, 0, 0, 2, domain);

View file

@ -77,6 +77,8 @@ bool smt2_pp_environment::is_indexed_fdecl(func_decl * f) const {
for (i = 0; i < num; i++) {
if (f->get_parameter(i).is_int())
continue;
if (f->get_parameter(i).is_rational())
continue;
if (f->get_parameter(i).is_ast() && is_func_decl(f->get_parameter(i).get_ast()))
continue;
break;
@ -105,9 +107,13 @@ format * smt2_pp_environment::pp_fdecl_params(format * fname, func_decl * f) {
ptr_buffer<format> fs;
fs.push_back(fname);
for (unsigned i = 0; i < num; i++) {
SASSERT(f->get_parameter(i).is_int() || (f->get_parameter(i).is_ast() && is_func_decl(f->get_parameter(i).get_ast())));
SASSERT(f->get_parameter(i).is_int() ||
f->get_parameter(i).is_rational() ||
(f->get_parameter(i).is_ast() && is_func_decl(f->get_parameter(i).get_ast())));
if (f->get_parameter(i).is_int())
fs.push_back(mk_int(get_manager(), f->get_parameter(i).get_int()));
else if (f->get_parameter(i).is_rational())
fs.push_back(mk_string(get_manager(), f->get_parameter(i).get_rational().to_string().c_str()));
else
fs.push_back(pp_fdecl_ref(to_func_decl(f->get_parameter(i).get_ast())));
}
@ -335,22 +341,22 @@ format * smt2_pp_environment::pp_arith_literal(app * t, bool decimal, unsigned d
}
else {
SASSERT(u.is_irrational_algebraic_numeral(t));
anum const & val = u.to_irrational_algebraic_numeral(t);
anum const & val2 = u.to_irrational_algebraic_numeral(t);
algebraic_numbers::manager & am = u.am();
format * vf;
std::ostringstream buffer;
bool is_neg = false;
if (decimal) {
scoped_anum abs_val(am);
am.set(abs_val, val);
if (am.is_neg(val)) {
am.set(abs_val, val2);
if (am.is_neg(val2)) {
is_neg = true;
am.neg(abs_val);
}
am.display_decimal(buffer, abs_val, decimal_prec);
}
else {
am.display_root_smt2(buffer, val);
am.display_root_smt2(buffer, val2);
}
vf = mk_string(get_manager(), buffer.str().c_str());
return is_neg ? mk_neg(vf) : vf;
@ -1159,6 +1165,26 @@ std::ostream& operator<<(std::ostream& out, mk_ismt2_pp const & p) {
return out;
}
std::ostream& operator<<(std::ostream& out, expr_ref const& e) {
return out << mk_ismt2_pp(e.get(), e.get_manager());
}
std::ostream& operator<<(std::ostream& out, app_ref const& e) {
return out << mk_ismt2_pp(e.get(), e.get_manager());
}
std::ostream& operator<<(std::ostream& out, expr_ref_vector const& e) {
for (unsigned i = 0; i < e.size(); ++i)
out << mk_ismt2_pp(e[i], e.get_manager()) << "\n";
return out;
}
std::ostream& operator<<(std::ostream& out, app_ref_vector const& e) {
for (unsigned i = 0; i < e.size(); ++i)
out << mk_ismt2_pp(e[i], e.get_manager()) << "\n";
return out;
}
#ifdef Z3DEBUG
void pp(expr const * n, ast_manager & m) {
std::cout << mk_ismt2_pp(const_cast<expr*>(n), m) << std::endl;

View file

@ -110,4 +110,10 @@ struct mk_ismt2_pp {
std::ostream& operator<<(std::ostream& out, mk_ismt2_pp const & p);
std::ostream& operator<<(std::ostream& out, expr_ref const& e);
std::ostream& operator<<(std::ostream& out, app_ref const& e);
std::ostream& operator<<(std::ostream& out, expr_ref_vector const& e);
std::ostream& operator<<(std::ostream& out, app_ref_vector const& e);
#endif

View file

@ -1058,7 +1058,8 @@ void ast_smt_pp::display_ast_smt2(std::ostream& strm, ast* a, unsigned indent, u
void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
ptr_vector<quantifier> ql;
decl_collector decls(m_manager);
ast_manager& m = m_manager;
decl_collector decls(m);
smt_renaming rn;
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
@ -1069,7 +1070,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
}
decls.visit(n);
if (m_manager.is_proof(n)) {
if (m.is_proof(n)) {
strm << "(";
}
if (m_benchmark_name != symbol::null) {
@ -1078,7 +1079,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
if (m_source_info != symbol::null && m_source_info != symbol("")) {
strm << "; :source { " << m_source_info << " }\n";
}
if (m_manager.is_bool(n)) {
if (m.is_bool(n)) {
strm << "(set-info :status " << m_status << ")\n";
}
if (m_category != symbol::null && m_category != symbol("")) {
@ -1095,7 +1096,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
for (unsigned i = 0; i < decls.get_num_sorts(); ++i) {
sort* s = decls.get_sorts()[i];
if (!(*m_is_declared)(s)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0);
smt_printer p(strm, m, ql, rn, m_logic, true, true, m_simplify_implies, 0);
p.pp_sort_decl(sort_mark, s);
}
}
@ -1103,7 +1104,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
for (unsigned i = 0; i < decls.get_num_decls(); ++i) {
func_decl* d = decls.get_func_decls()[i];
if (!(*m_is_declared)(d)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0);
smt_printer p(strm, m, ql, rn, m_logic, true, true, m_simplify_implies, 0);
p(d);
strm << "\n";
}
@ -1112,34 +1113,36 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
for (unsigned i = 0; i < decls.get_num_preds(); ++i) {
func_decl* d = decls.get_pred_decls()[i];
if (!(*m_is_declared)(d)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0);
smt_printer p(strm, m, ql, rn, m_logic, true, true, m_simplify_implies, 0);
p(d);
strm << "\n";
}
}
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
strm << "(assert\n";
smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
p(m_assumptions[i].get());
strm << ")\n";
smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 1);
strm << "(assert\n ";
p(m_assumptions[i].get());
strm << ")\n";
}
for (unsigned i = 0; i < m_assumptions_star.size(); ++i) {
strm << "(assert\n";
smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
p(m_assumptions_star[i].get());
smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 1);
strm << "(assert\n ";
p(m_assumptions_star[i].get());
strm << ")\n";
}
smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
if (m_manager.is_bool(n)) {
strm << "(assert\n";
p(n);
strm << ")\n";
smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 0);
if (m.is_bool(n)) {
if (!m.is_true(n)) {
strm << "(assert\n ";
p(n);
strm << ")\n";
}
strm << "(check-sat)\n";
}
else if (m_manager.is_proof(n)) {
else if (m.is_proof(n)) {
strm << "(proof\n";
p(n);
strm << "))\n";

76
src/ast/ast_trail.h Normal file
View file

@ -0,0 +1,76 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
ast_trail.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-06-02.
Revision History:
Extracted AST specific features from trail.h
nbjorner 2014-9-28
--*/
#ifndef _AST_TRAIL_H_
#define _AST_TRAIL_H_
#include"ast.h"
#include"trail.h"
template<typename S, typename T>
class ast2ast_trailmap {
ref_vector<S, ast_manager> m_domain;
ref_vector<T, ast_manager> m_range;
obj_map<S, T*> m_map;
public:
ast2ast_trailmap(ast_manager& m):
m_domain(m),
m_range(m),
m_map()
{}
bool find(S* s, T*& t) {
return m_map.find(s,t);
}
void insert(S* s, T* t) {
SASSERT(!m_map.contains(s));
m_domain.push_back(s);
m_range.push_back(t);
m_map.insert(s,t);
}
void pop() {
SASSERT(!m_domain.empty());
m_map.remove(m_domain.back());
m_domain.pop_back();
m_range.pop_back();
}
};
template<typename Ctx, typename S, typename T>
class ast2ast_trail : public trail<Ctx> {
ast2ast_trailmap<S,T>& m_map;
public:
ast2ast_trail(ast2ast_trailmap<S,T>& m, S* s, T* t) :
m_map(m) {
m.insert(s,t);
}
virtual void undo(Ctx& ctx) {
m_map.pop();
}
};
#endif /* _AST_TRAIL_H_ */

Some files were not shown because too many files have changed in this diff Show more