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:
commit
3a49223076
545 changed files with 70367 additions and 4623 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,6 +19,7 @@ ocamlz3
|
|||
# Emacs temp files
|
||||
\#*\#
|
||||
# Directories with generated code and documentation
|
||||
release/*
|
||||
build/*
|
||||
build-dist/*
|
||||
dist/*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Copyright (c) Microsoft Corporation 2015
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<stdarg.h>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
/*
|
||||
Simple MAXSAT solver on top of the Z3 API.
|
||||
*/
|
||||
|
|
20
examples/msf/README
Normal file
20
examples/msf/README
Normal 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!
|
||||
|
||||
|
||||
|
||||
|
||||
|
60
examples/msf/SolverFoundation.Plugin.Z3.Tests/App.config
Normal file
60
examples/msf/SolverFoundation.Plugin.Z3.Tests/App.config
Normal 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>
|
|
@ -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")]
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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>
|
132
examples/msf/SolverFoundation.Plugin.Z3.Tests/SolverTests.cs
Normal file
132
examples/msf/SolverFoundation.Plugin.Z3.Tests/SolverTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
92
examples/msf/SolverFoundation.Plugin.Z3/AbortWorker.cs
Normal file
92
examples/msf/SolverFoundation.Plugin.Z3/AbortWorker.cs
Normal 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
|
||||
}
|
||||
}
|
60
examples/msf/SolverFoundation.Plugin.Z3/App.config
Normal file
60
examples/msf/SolverFoundation.Plugin.Z3/App.config
Normal 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>
|
|
@ -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>
|
124
examples/msf/SolverFoundation.Plugin.Z3/Utils.cs
Normal file
124
examples/msf/SolverFoundation.Plugin.Z3/Utils.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
101
examples/msf/SolverFoundation.Plugin.Z3/Z3BaseDirective.cs
Normal file
101
examples/msf/SolverFoundation.Plugin.Z3/Z3BaseDirective.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
103
examples/msf/SolverFoundation.Plugin.Z3/Z3BaseParams.cs
Normal file
103
examples/msf/SolverFoundation.Plugin.Z3/Z3BaseParams.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
381
examples/msf/SolverFoundation.Plugin.Z3/Z3BaseSolver.cs
Normal file
381
examples/msf/SolverFoundation.Plugin.Z3/Z3BaseSolver.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using Microsoft.SolverFoundation.Services;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
public class Z3MILPDirective : Z3BaseDirective
|
||||
{
|
||||
}
|
||||
}
|
19
examples/msf/SolverFoundation.Plugin.Z3/Z3MILPParams.cs
Normal file
19
examples/msf/SolverFoundation.Plugin.Z3/Z3MILPParams.cs
Normal 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) { }
|
||||
}
|
||||
|
||||
}
|
230
examples/msf/SolverFoundation.Plugin.Z3/Z3MILPSolver.cs
Normal file
230
examples/msf/SolverFoundation.Plugin.Z3/Z3MILPSolver.cs
Normal 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) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using Microsoft.SolverFoundation.Services;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
public class Z3TermDirective : Z3BaseDirective
|
||||
{
|
||||
}
|
||||
}
|
17
examples/msf/SolverFoundation.Plugin.Z3/Z3TermParams.cs
Normal file
17
examples/msf/SolverFoundation.Plugin.Z3/Z3TermParams.cs
Normal 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) { }
|
||||
}
|
||||
|
||||
}
|
382
examples/msf/SolverFoundation.Plugin.Z3/Z3TermSolver.cs
Normal file
382
examples/msf/SolverFoundation.Plugin.Z3/Z3TermSolver.cs
Normal 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
60
examples/msf/Validator/App.config
Normal file
60
examples/msf/Validator/App.config
Normal 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>
|
|
@ -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>
|
194
examples/msf/Validator/Program.cs
Normal file
194
examples/msf/Validator/Program.cs
Normal 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
|
||||
|
||||
");
|
||||
}
|
||||
}
|
||||
}
|
36
examples/msf/Validator/Properties/AssemblyInfo.cs
Normal file
36
examples/msf/Validator/Properties/AssemblyInfo.cs
Normal 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")]
|
123
examples/msf/Validator/Validator.csproj
Normal file
123
examples/msf/Validator/Validator.csproj
Normal 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>
|
125
examples/msf/Z3MSFPlugin.sln
Normal file
125
examples/msf/Z3MSFPlugin.sln
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Copyright (c) Microsoft Corporation 2015
|
||||
|
||||
from z3 import *
|
||||
|
||||
x = Real('x')
|
||||
|
|
88
examples/python/hamiltonian/hamiltonian.py
Normal file
88
examples/python/hamiltonian/hamiltonian.py
Normal 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()
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef TPTP5_H_
|
||||
#define TPTP5_H_
|
||||
|
||||
|
|
|
@ -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
57
scripts/mk_copyright.py
Normal 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')
|
|
@ -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',
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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, ¶m, 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);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
243
src/api/api_opt.cpp
Normal 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
61
src/api/api_pb.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
};
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
#include<windows.h>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
111
src/api/dotnet/Deprecated.cs
Normal file
111
src/api/dotnet/Deprecated.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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
298
src/api/dotnet/Optimize.cs
Normal 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
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
**/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
673
src/api/ml/z3.ml
673
src/api/ml/z3.ml
File diff suppressed because it is too large
Load diff
|
@ -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
18978
src/api/ml/z3_stubs.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
468
src/api/python/z3util.py
Normal 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
|
||||
|
292
src/api/z3_api.h
292
src/api/z3_api.h
|
@ -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
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __in
|
||||
#define __in
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
76
src/ast/ast_trail.h
Normal 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
Loading…
Add table
Add a link
Reference in a new issue