mirror of
https://github.com/Z3Prover/z3
synced 2025-07-18 02:16:40 +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
|
# Emacs temp files
|
||||||
\#*\#
|
\#*\#
|
||||||
# Directories with generated code and documentation
|
# Directories with generated code and documentation
|
||||||
|
release/*
|
||||||
build/*
|
build/*
|
||||||
build-dist/*
|
build-dist/*
|
||||||
dist/*
|
dist/*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
RELEASE NOTES
|
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.
|
- 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 os
|
||||||
import shutil
|
import shutil
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#include<vector>
|
#include<vector>
|
||||||
#include"z3++.h"
|
#include"z3++.h"
|
||||||
|
|
||||||
|
@ -205,6 +211,9 @@ void bitvector_example1() {
|
||||||
|
|
||||||
// using unsigned <=
|
// using unsigned <=
|
||||||
prove(ule(x - 10, 0) == ule(x, 10));
|
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;
|
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() {
|
void extract_example() {
|
||||||
std::cout << "extract example\n";
|
std::cout << "extract example\n";
|
||||||
context c;
|
context c;
|
||||||
|
@ -1025,6 +1058,7 @@ int main() {
|
||||||
expr_vector_example(); std::cout << "\n";
|
expr_vector_example(); std::cout << "\n";
|
||||||
exists_expr_vector_example(); std::cout << "\n";
|
exists_expr_vector_example(); std::cout << "\n";
|
||||||
substitute_example(); std::cout << "\n";
|
substitute_example(); std::cout << "\n";
|
||||||
|
opt_example(); std::cout << "\n";
|
||||||
extract_example(); std::cout << "\n";
|
extract_example(); std::cout << "\n";
|
||||||
std::cout << "done\n";
|
std::cout << "done\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#include<stdio.h>
|
#include<stdio.h>
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include<stdarg.h>
|
#include<stdarg.h>
|
||||||
|
|
|
@ -759,7 +759,7 @@ namespace test_mapi
|
||||||
foreach (BoolExpr a in g.Formulas)
|
foreach (BoolExpr a in g.Formulas)
|
||||||
solver.Assert(a);
|
solver.Assert(a);
|
||||||
|
|
||||||
if (solver.Check() != Status.SATISFIABLE)
|
if (solver.Check() != Status.SATISFIABLE)
|
||||||
throw new TestFailedException();
|
throw new TestFailedException();
|
||||||
|
|
||||||
ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g);
|
ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g);
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Simple MAXSAT solver on top of the Z3 API.
|
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)
|
return ComplexExpr(other.r*self.r - other.i*self.i, other.i*self.r + other.r*self.i)
|
||||||
|
|
||||||
def __pow__(self, k):
|
def __pow__(self, k):
|
||||||
if k == 0:
|
if k == 0:
|
||||||
return ComplexExpr(1, 0)
|
return ComplexExpr(1, 0)
|
||||||
if k == 1:
|
if k == 1:
|
||||||
return self
|
return self
|
||||||
if k < 0:
|
if k < 0:
|
||||||
return (self ** (-k)).inv()
|
return (self ** (-k)).inv()
|
||||||
return reduce(lambda x, y: x * y, [self for _ in xrange(k)], ComplexExpr(1, 0))
|
return reduce(lambda x, y: x * y, [self for _ in xrange(k)], ComplexExpr(1, 0))
|
||||||
|
|
||||||
def inv(self):
|
def inv(self):
|
||||||
den = self.r*self.r + self.i*self.i
|
den = self.r*self.r + self.i*self.i
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
# Copyright (c) Microsoft Corporation 2015
|
||||||
|
|
||||||
from z3 import *
|
from z3 import *
|
||||||
|
|
||||||
x = Real('x')
|
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 <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -809,8 +815,12 @@ class env {
|
||||||
r = terms[0] / terms[1];
|
r = terms[0] / terms[1];
|
||||||
}
|
}
|
||||||
else if (!strcmp(ch,"$distinct")) {
|
else if (!strcmp(ch,"$distinct")) {
|
||||||
check_arity(terms.size(), 2);
|
if (terms.size() == 2) {
|
||||||
r = terms[0] != terms[1];
|
r = terms[0] != terms[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = distinct(terms);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(ch,"$floor") || !strcmp(ch,"$to_int")) {
|
else if (!strcmp(ch,"$floor") || !strcmp(ch,"$to_int")) {
|
||||||
check_arity(terms.size(), 1);
|
check_arity(terms.size(), 1);
|
||||||
|
@ -1089,12 +1099,11 @@ class env {
|
||||||
}
|
}
|
||||||
|
|
||||||
z3::sort mk_sort(char const* s) {
|
z3::sort mk_sort(char const* s) {
|
||||||
z3::symbol sym = symbol(s);
|
return m_context.uninterpreted_sort(s);
|
||||||
return mk_sort(sym);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
z3::sort mk_sort(z3::symbol& 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:
|
public:
|
||||||
|
@ -2083,7 +2092,7 @@ bool parse_is_sat_line(char const* line, bool& is_sat) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_is_sat(char const* filename, bool& is_sat) {
|
bool parse_is_sat(char const* filename, bool& is_sat) {
|
||||||
std::ifstream is(filename);
|
std::ifstream is(filename);
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#ifndef TPTP5_H_
|
#ifndef TPTP5_H_
|
||||||
#define TPTP5_H_
|
#define TPTP5_H_
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#line 2 "tptp5.lex.cpp"
|
#line 2 "tptp5.lex.cpp"
|
||||||
|
|
||||||
#line 4 "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
|
# Z3 Project definition
|
||||||
def init_project_def():
|
def init_project_def():
|
||||||
set_version(4, 4, 0, 0)
|
set_version(4, 4, 1, 0)
|
||||||
add_lib('util', [])
|
add_lib('util', [])
|
||||||
add_lib('polynomial', ['util'], 'math/polynomial')
|
add_lib('polynomial', ['util'], 'math/polynomial')
|
||||||
add_lib('sat', ['util'])
|
add_lib('sat', ['util'])
|
||||||
add_lib('nlsat', ['polynomial', 'sat'])
|
add_lib('nlsat', ['polynomial', 'sat'])
|
||||||
add_lib('hilbert', ['util'], 'math/hilbert')
|
add_lib('hilbert', ['util'], 'math/hilbert')
|
||||||
|
add_lib('simplex', ['util'], 'math/simplex')
|
||||||
add_lib('interval', ['util'], 'math/interval')
|
add_lib('interval', ['util'], 'math/interval')
|
||||||
add_lib('realclosure', ['interval'], 'math/realclosure')
|
add_lib('realclosure', ['interval'], 'math/realclosure')
|
||||||
add_lib('subpaving', ['interval'], 'math/subpaving')
|
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('smt_params', ['ast', 'simplifier', 'pattern', 'bit_blaster'], 'smt/params')
|
||||||
add_lib('proto_model', ['model', 'simplifier', 'smt_params'], 'smt/proto_model')
|
add_lib('proto_model', ['model', 'simplifier', 'smt_params'], 'smt/proto_model')
|
||||||
add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', '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('user_plugin', ['smt'], 'smt/user_plugin')
|
||||||
add_lib('bv_tactics', ['tactic', 'bit_blaster'], 'tactic/bv')
|
add_lib('bv_tactics', ['tactic', 'bit_blaster'], 'tactic/bv')
|
||||||
add_lib('fuzzing', ['ast'], 'test/fuzzing')
|
add_lib('fuzzing', ['ast'], 'test/fuzzing')
|
||||||
add_lib('smt_tactic', ['smt'], 'smt/tactic')
|
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('sls_tactic', ['tactic', 'normal_forms', 'core_tactics', 'bv_tactics'], 'tactic/sls')
|
||||||
add_lib('qe', ['smt','sat'], 'qe')
|
add_lib('qe', ['smt','sat'], 'qe')
|
||||||
add_lib('duality', ['smt', 'interp', 'qe'])
|
add_lib('duality', ['smt', 'interp', 'qe'])
|
||||||
add_lib('muz', ['smt', 'sat', 'smt2parser', 'aig_tactic', 'qe'], 'muz/base')
|
add_lib('muz', ['smt', 'sat', 'smt2parser', 'aig_tactic', 'qe'], 'muz/base')
|
||||||
add_lib('transforms', ['muz', 'hilbert'], 'muz/transforms')
|
add_lib('transforms', ['muz', 'hilbert'], 'muz/transforms')
|
||||||
add_lib('rel', ['muz', 'transforms'], 'muz/rel')
|
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('clp', ['muz', 'transforms'], 'muz/clp')
|
||||||
add_lib('tab', ['muz', 'transforms'], 'muz/tab')
|
add_lib('tab', ['muz', 'transforms'], 'muz/tab')
|
||||||
add_lib('bmc', ['muz', 'transforms'], 'muz/bmc')
|
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('duality_intf', ['muz', 'transforms', 'duality'], 'muz/duality')
|
||||||
add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf'], 'muz/fp')
|
add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf'], 'muz/fp')
|
||||||
add_lib('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe'], 'tactic/smtlogics')
|
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('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('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('smtparser', ['portfolio'], 'parsers/smt')
|
||||||
|
add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic'], 'opt')
|
||||||
# add_dll('foci2', ['util'], 'interp/foci2stub',
|
# add_dll('foci2', ['util'], 'interp/foci2stub',
|
||||||
# dll_name='foci2',
|
# dll_name='foci2',
|
||||||
# export_files=['foci2stub.cpp'])
|
# export_files=['foci2stub.cpp'])
|
||||||
# add_lib('interp', ['solver','foci2'])
|
# 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']
|
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)
|
includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files)
|
||||||
add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3')
|
add_exe('shell', ['api', 'sat', 'extra_cmds','opt'], exe_name='z3')
|
||||||
add_exe('test', ['api', 'fuzzing'], exe_name='test-z3', install=False)
|
add_exe('test', ['api', 'fuzzing', 'simplex'], exe_name='test-z3', install=False)
|
||||||
add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll',
|
add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll',
|
||||||
reexports=['api'],
|
reexports=['api'],
|
||||||
dll_name='libz3',
|
dll_name='libz3',
|
||||||
|
|
|
@ -85,6 +85,10 @@ VS_PAR=False
|
||||||
VS_PAR_NUM=8
|
VS_PAR_NUM=8
|
||||||
GPROF=False
|
GPROF=False
|
||||||
GIT_HASH=False
|
GIT_HASH=False
|
||||||
|
OPTIMIZE=False
|
||||||
|
|
||||||
|
FPMATH="Default"
|
||||||
|
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
|
||||||
|
|
||||||
def check_output(cmd):
|
def check_output(cmd):
|
||||||
return str(subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]).rstrip('\r\n')
|
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.add('#include<omp.h>\nint main() { return omp_in_parallel() ? 1 : 0; }\n')
|
||||||
t.commit()
|
t.commit()
|
||||||
if IS_WINDOWS:
|
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:
|
else:
|
||||||
return exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '-fopenmp']) == 0
|
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):
|
def find_jni_h(path):
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
for f in files:
|
for f in files:
|
||||||
|
@ -357,10 +388,14 @@ def check_ml():
|
||||||
r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml'])
|
r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml'])
|
||||||
if r != 0:
|
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.')
|
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')
|
try:
|
||||||
rmf('hello.cmo')
|
rmf('hello.cmi')
|
||||||
rmf('hello.cmx')
|
rmf('hello.cmo')
|
||||||
rmf('a.out')
|
rmf('hello.cmx')
|
||||||
|
rmf('a.out')
|
||||||
|
rmf('hello.o')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
find_ml_lib()
|
find_ml_lib()
|
||||||
find_ocaml_find()
|
find_ocaml_find()
|
||||||
|
|
||||||
|
@ -517,6 +552,8 @@ def display_help(exit_code):
|
||||||
print(" -v, --vsproj generate Visual Studio Project Files.")
|
print(" -v, --vsproj generate Visual Studio Project Files.")
|
||||||
if IS_WINDOWS:
|
if IS_WINDOWS:
|
||||||
print(" -n, --nodotnet do not generate Microsoft.Z3.dll make rules.")
|
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(" -j, --java generate Java bindings.")
|
||||||
print(" --ml generate OCaml bindings.")
|
print(" --ml generate OCaml bindings.")
|
||||||
print(" --staticlib build Z3 static library.")
|
print(" --staticlib build Z3 static library.")
|
||||||
|
@ -543,13 +580,13 @@ def display_help(exit_code):
|
||||||
def parse_options():
|
def parse_options():
|
||||||
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
|
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 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:
|
try:
|
||||||
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
||||||
'b:df:sxhmcvtnp:gj',
|
'b:df:sxhmcvtnp:gj',
|
||||||
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
|
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
|
||||||
'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof',
|
'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof',
|
||||||
'githash=', 'x86', 'ml'])
|
'githash=', 'x86', 'ml', 'optimize'])
|
||||||
except:
|
except:
|
||||||
print("ERROR: Invalid command line option")
|
print("ERROR: Invalid command line option")
|
||||||
display_help(1)
|
display_help(1)
|
||||||
|
@ -584,6 +621,8 @@ def parse_options():
|
||||||
DOTNET_ENABLED = False
|
DOTNET_ENABLED = False
|
||||||
elif opt in ('--staticlib'):
|
elif opt in ('--staticlib'):
|
||||||
STATIC_LIB = True
|
STATIC_LIB = True
|
||||||
|
elif opt in ('--optimize'):
|
||||||
|
OPTIMIZE = True
|
||||||
elif not IS_WINDOWS and opt in ('-p', '--prefix'):
|
elif not IS_WINDOWS and opt in ('-p', '--prefix'):
|
||||||
PREFIX = arg
|
PREFIX = arg
|
||||||
PYTHON_PACKAGE_DIR = os.path.join(PREFIX, 'lib', 'python%s' % distutils.sysconfig.get_python_version(), 'dist-packages')
|
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'
|
'OBJ_EXT=.obj\n'
|
||||||
'LIB_EXT=.lib\n'
|
'LIB_EXT=.lib\n'
|
||||||
'AR=lib\n'
|
'AR=lib\n'
|
||||||
'AR_FLAGS=/nologo /LTCG\n'
|
|
||||||
'AR_OUTFLAG=/OUT:\n'
|
'AR_OUTFLAG=/OUT:\n'
|
||||||
'EXE_EXT=.exe\n'
|
'EXE_EXT=.exe\n'
|
||||||
'LINK=cl\n'
|
'LINK=cl\n'
|
||||||
|
@ -1731,22 +1769,25 @@ def mk_config():
|
||||||
extra_opt = ' %s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH)
|
extra_opt = ' %s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH)
|
||||||
if DEBUG_MODE:
|
if DEBUG_MODE:
|
||||||
config.write(
|
config.write(
|
||||||
|
'AR_FLAGS=/nologo\n'
|
||||||
'LINK_FLAGS=/nologo /MDd\n'
|
'LINK_FLAGS=/nologo /MDd\n'
|
||||||
'SLINK_FLAGS=/nologo /LDd\n')
|
'SLINK_FLAGS=/nologo /LDd\n')
|
||||||
if not VS_X64:
|
if not VS_X64:
|
||||||
config.write(
|
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(
|
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'
|
'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 /LTCG /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
||||||
else:
|
else:
|
||||||
config.write(
|
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(
|
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'
|
'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 /LTCG /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
||||||
else:
|
else:
|
||||||
# Windows Release mode
|
# Windows Release mode
|
||||||
|
if OPTIMIZE:
|
||||||
|
config.write('AR_FLAGS=/nologo /LTCG\n')
|
||||||
config.write(
|
config.write(
|
||||||
'LINK_FLAGS=/nologo /MD\n'
|
'LINK_FLAGS=/nologo /MD\n'
|
||||||
'SLINK_FLAGS=/nologo /LD\n')
|
'SLINK_FLAGS=/nologo /LD\n')
|
||||||
|
@ -1777,7 +1818,7 @@ def mk_config():
|
||||||
print('OCaml Native: %s' % OCAMLOPT)
|
print('OCaml Native: %s' % OCAMLOPT)
|
||||||
print('OCaml Library: %s' % OCAML_LIB)
|
print('OCaml Library: %s' % OCAML_LIB)
|
||||||
else:
|
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 = ""
|
OS_DEFINES = ""
|
||||||
ARITH = "internal"
|
ARITH = "internal"
|
||||||
check_ar()
|
check_ar()
|
||||||
|
@ -1806,9 +1847,11 @@ def mk_config():
|
||||||
if GIT_HASH:
|
if GIT_HASH:
|
||||||
CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH)
|
CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH)
|
||||||
CXXFLAGS = '%s -fvisibility=hidden -c' % CXXFLAGS
|
CXXFLAGS = '%s -fvisibility=hidden -c' % CXXFLAGS
|
||||||
|
FPMATH = test_fpmath(CXX)
|
||||||
|
CXXFLAGS = '%s %s' % (CXXFLAGS, FPMATH_FLAGS)
|
||||||
HAS_OMP = test_openmp(CXX)
|
HAS_OMP = test_openmp(CXX)
|
||||||
if HAS_OMP:
|
if HAS_OMP:
|
||||||
CXXFLAGS = '%s -fopenmp -mfpmath=sse' % CXXFLAGS
|
CXXFLAGS = '%s -fopenmp' % CXXFLAGS
|
||||||
LDFLAGS = '%s -fopenmp' % LDFLAGS
|
LDFLAGS = '%s -fopenmp' % LDFLAGS
|
||||||
SLIBEXTRAFLAGS = '%s -fopenmp' % SLIBEXTRAFLAGS
|
SLIBEXTRAFLAGS = '%s -fopenmp' % SLIBEXTRAFLAGS
|
||||||
else:
|
else:
|
||||||
|
@ -1849,7 +1892,8 @@ def mk_config():
|
||||||
else:
|
else:
|
||||||
raise MKException('Unsupported platform: %s' % sysname)
|
raise MKException('Unsupported platform: %s' % sysname)
|
||||||
if is64():
|
if is64():
|
||||||
CXXFLAGS = '%s -fPIC' % CXXFLAGS
|
if sysname[:6] != 'CYGWIN':
|
||||||
|
CXXFLAGS = '%s -fPIC' % CXXFLAGS
|
||||||
CPPFLAGS = '%s -D_AMD64_' % CPPFLAGS
|
CPPFLAGS = '%s -D_AMD64_' % CPPFLAGS
|
||||||
if sysname == 'Linux':
|
if sysname == 'Linux':
|
||||||
CPPFLAGS = '%s -D_USE_THREAD_LOCAL' % CPPFLAGS
|
CPPFLAGS = '%s -D_USE_THREAD_LOCAL' % CPPFLAGS
|
||||||
|
@ -1861,7 +1905,6 @@ def mk_config():
|
||||||
CPPFLAGS = '%s -DZ3DEBUG' % CPPFLAGS
|
CPPFLAGS = '%s -DZ3DEBUG' % CPPFLAGS
|
||||||
if TRACE or DEBUG_MODE:
|
if TRACE or DEBUG_MODE:
|
||||||
CPPFLAGS = '%s -D_TRACE' % CPPFLAGS
|
CPPFLAGS = '%s -D_TRACE' % CPPFLAGS
|
||||||
CXXFLAGS = '%s -msse -msse2' % CXXFLAGS
|
|
||||||
config.write('PREFIX=%s\n' % PREFIX)
|
config.write('PREFIX=%s\n' % PREFIX)
|
||||||
config.write('CC=%s\n' % CC)
|
config.write('CC=%s\n' % CC)
|
||||||
config.write('CXX=%s\n' % CXX)
|
config.write('CXX=%s\n' % CXX)
|
||||||
|
@ -1892,6 +1935,7 @@ def mk_config():
|
||||||
print('OpenMP: %s' % HAS_OMP)
|
print('OpenMP: %s' % HAS_OMP)
|
||||||
print('Prefix: %s' % PREFIX)
|
print('Prefix: %s' % PREFIX)
|
||||||
print('64-bit: %s' % is64())
|
print('64-bit: %s' % is64())
|
||||||
|
print('FP math: %s' % FPMATH)
|
||||||
if GPROF:
|
if GPROF:
|
||||||
print('gprof: enabled')
|
print('gprof: enabled')
|
||||||
print('Python version: %s' % distutils.sysconfig.get_python_version())
|
print('Python version: %s' % distutils.sysconfig.get_python_version())
|
||||||
|
|
|
@ -47,16 +47,16 @@ def set_build_dir(path):
|
||||||
mk_dir(BUILD_X64_DIR)
|
mk_dir(BUILD_X64_DIR)
|
||||||
|
|
||||||
def display_help():
|
def display_help():
|
||||||
print "mk_win_dist.py: Z3 Windows distribution generator\n"
|
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("This script generates the zip files containing executables, dlls, header files for Windows.")
|
||||||
print "It must be executed from the Z3 root directory."
|
print("It must be executed from the Z3 root directory.")
|
||||||
print "\nOptions:"
|
print("\nOptions:")
|
||||||
print " -h, --help display this message."
|
print(" -h, --help display this message.")
|
||||||
print " -s, --silent do not print verbose messages."
|
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(" -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(" -f, --force force script to regenerate Makefiles.")
|
||||||
print " --nojava do not include Java bindings in the binary distribution files."
|
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||||
print " --githash include git hash in the Zip file."
|
print(" --githash include git hash in the Zip file.")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
# Parse configuration option for mk_make script
|
# Parse configuration option for mk_make script
|
||||||
|
@ -180,7 +180,7 @@ def mk_dist_dir_core(x64):
|
||||||
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
||||||
mk_win_dist(build_path, dist_path)
|
mk_win_dist(build_path, dist_path)
|
||||||
if is_verbose():
|
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():
|
def mk_dist_dir():
|
||||||
mk_dist_dir_core(False)
|
mk_dist_dir_core(False)
|
||||||
|
@ -208,7 +208,7 @@ def mk_zip_core(x64):
|
||||||
ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED)
|
ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED)
|
||||||
os.path.walk(dist_path, mk_zip_visitor, '*')
|
os.path.walk(dist_path, mk_zip_visitor, '*')
|
||||||
if is_verbose():
|
if is_verbose():
|
||||||
print "Generated '%s'" % zfname
|
print("Generated '%s'" % zfname)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
ZIPOUT = None
|
ZIPOUT = None
|
||||||
|
@ -253,7 +253,7 @@ def cp_vs_runtime_core(x64):
|
||||||
for f in VS_RUNTIME_FILES:
|
for f in VS_RUNTIME_FILES:
|
||||||
shutil.copy(f, bin_dist_path)
|
shutil.copy(f, bin_dist_path)
|
||||||
if is_verbose():
|
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():
|
def cp_vs_runtime():
|
||||||
cp_vs_runtime_core(True)
|
cp_vs_runtime_core(True)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (c) 2015 Microsoft Corporation
|
||||||
# Script for "cloning" (and tracking) all branches at codeplex.
|
# Script for "cloning" (and tracking) all branches at codeplex.
|
||||||
# On Windows, this script must be executed in the "git Bash" console.
|
# 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
|
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do
|
||||||
git branch --track ${branch##*/} $branch
|
git branch --track ${branch##*/} $branch
|
||||||
done
|
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 ObjArrayPtr { public long[] value; }\n')
|
||||||
java_native.write(' public static class UIntArrayPtr { public int[] 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')
|
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)
|
java_native.write(' static {\n')
|
||||||
else:
|
java_native.write(' try { System.loadLibrary("z3java"); }\n')
|
||||||
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(' catch (UnsatisfiedLinkError ex) { System.loadLibrary("libz3java"); }\n')
|
||||||
|
java_native.write(' }\n')
|
||||||
|
|
||||||
java_native.write('\n')
|
java_native.write('\n')
|
||||||
for name, result, params in _dotnet_decls:
|
for name, result, params in _dotnet_decls:
|
||||||
java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name)))
|
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(" }\n")
|
||||||
log_c.write(" Au(a%s);\n" % sz)
|
log_c.write(" Au(a%s);\n" % sz)
|
||||||
exe_c.write("in.get_uint_array(%s)" % i)
|
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:
|
else:
|
||||||
error ("unsupported parameter for %s, %s" % (ty, name, p))
|
error ("unsupported parameter for %s, %s" % (ty, name, p))
|
||||||
elif kind == OUT_ARRAY:
|
elif kind == OUT_ARRAY:
|
||||||
|
|
|
@ -24,6 +24,7 @@ Revision History:
|
||||||
#include"bv_decl_plugin.h"
|
#include"bv_decl_plugin.h"
|
||||||
#include"datatype_decl_plugin.h"
|
#include"datatype_decl_plugin.h"
|
||||||
#include"array_decl_plugin.h"
|
#include"array_decl_plugin.h"
|
||||||
|
#include"pb_decl_plugin.h"
|
||||||
#include"ast_translation.h"
|
#include"ast_translation.h"
|
||||||
#include"ast_pp.h"
|
#include"ast_pp.h"
|
||||||
#include"ast_ll_pp.h"
|
#include"ast_ll_pp.h"
|
||||||
|
@ -1081,7 +1082,6 @@ extern "C" {
|
||||||
case OP_BSREM_I:
|
case OP_BSREM_I:
|
||||||
case OP_BUREM_I:
|
case OP_BUREM_I:
|
||||||
case OP_BSMOD_I:
|
case OP_BSMOD_I:
|
||||||
|
|
||||||
return Z3_OP_UNINTERPRETED;
|
return Z3_OP_UNINTERPRETED;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -1090,9 +1090,10 @@ extern "C" {
|
||||||
}
|
}
|
||||||
if (mk_c(c)->get_dt_fid() == _d->get_family_id()) {
|
if (mk_c(c)->get_dt_fid() == _d->get_family_id()) {
|
||||||
switch(_d->get_decl_kind()) {
|
switch(_d->get_decl_kind()) {
|
||||||
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
|
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
|
||||||
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
|
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
|
||||||
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
|
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
|
||||||
|
case OP_DT_UPDATE_FIELD: return Z3_OP_DT_UPDATE_FIELD;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return Z3_OP_UNINTERPRETED;
|
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;
|
return Z3_OP_UNINTERPRETED;
|
||||||
Z3_CATCH_RETURN(Z3_OP_UNINTERPRETED);
|
Z3_CATCH_RETURN(Z3_OP_UNINTERPRETED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,7 @@ extern "C" {
|
||||||
catch (z3_exception & ex) {
|
catch (z3_exception & ex) {
|
||||||
// The error handler is only available for contexts
|
// The error handler is only available for contexts
|
||||||
// Just throw a warning.
|
// Just throw a warning.
|
||||||
std::ostringstream buffer;
|
warning_msg(ex.msg());
|
||||||
buffer << "Error setting " << param_id << ", " << ex.msg();
|
|
||||||
warning_msg(buffer.str().c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,9 +62,7 @@ extern "C" {
|
||||||
catch (z3_exception & ex) {
|
catch (z3_exception & ex) {
|
||||||
// The error handler is only available for contexts
|
// The error handler is only available for contexts
|
||||||
// Just throw a warning.
|
// Just throw a warning.
|
||||||
std::ostringstream buffer;
|
warning_msg(ex.msg());
|
||||||
buffer << "Error setting " << param_id << ": " << ex.msg();
|
|
||||||
warning_msg(buffer.str().c_str());
|
|
||||||
return Z3_FALSE;
|
return Z3_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,9 +88,7 @@ extern "C" {
|
||||||
catch (z3_exception & ex) {
|
catch (z3_exception & ex) {
|
||||||
// The error handler is only available for contexts
|
// The error handler is only available for contexts
|
||||||
// Just throw a warning.
|
// Just throw a warning.
|
||||||
std::ostringstream buffer;
|
warning_msg(ex.msg());
|
||||||
buffer << "Error setting " << param_id << ": " << ex.msg();
|
|
||||||
warning_msg(buffer.str().c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace api {
|
||||||
m_bv_util(m()),
|
m_bv_util(m()),
|
||||||
m_datalog_util(m()),
|
m_datalog_util(m()),
|
||||||
m_fpa_util(m()),
|
m_fpa_util(m()),
|
||||||
m_dtutil(m()),
|
m_dtutil(m()),
|
||||||
m_last_result(m()),
|
m_last_result(m()),
|
||||||
m_ast_trail(m()),
|
m_ast_trail(m()),
|
||||||
m_replay_stack() {
|
m_replay_stack() {
|
||||||
|
@ -111,6 +111,7 @@ namespace api {
|
||||||
m_basic_fid = m().get_basic_family_id();
|
m_basic_fid = m().get_basic_family_id();
|
||||||
m_arith_fid = m().mk_family_id("arith");
|
m_arith_fid = m().mk_family_id("arith");
|
||||||
m_bv_fid = m().mk_family_id("bv");
|
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_array_fid = m().mk_family_id("array");
|
||||||
m_dt_fid = m().mk_family_id("datatype");
|
m_dt_fid = m().mk_family_id("datatype");
|
||||||
m_datalog_fid = m().mk_family_id("datalog_relation");
|
m_datalog_fid = m().mk_family_id("datalog_relation");
|
||||||
|
@ -515,6 +516,11 @@ extern "C" {
|
||||||
memory::initialize(0);
|
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) {
|
Z3_error_code Z3_API Z3_get_error_code(Z3_context c) {
|
||||||
LOG_Z3_get_error_code(c);
|
LOG_Z3_get_error_code(c);
|
||||||
return mk_c(c)->get_error_code();
|
return mk_c(c)->get_error_code();
|
||||||
|
|
|
@ -78,6 +78,7 @@ namespace api {
|
||||||
family_id m_bv_fid;
|
family_id m_bv_fid;
|
||||||
family_id m_dt_fid;
|
family_id m_dt_fid;
|
||||||
family_id m_datalog_fid;
|
family_id m_datalog_fid;
|
||||||
|
family_id m_pb_fid;
|
||||||
family_id m_fpa_fid;
|
family_id m_fpa_fid;
|
||||||
datatype_decl_plugin * m_dt_plugin;
|
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_bv_fid() const { return m_bv_fid; }
|
||||||
family_id get_dt_fid() const { return m_dt_fid; }
|
family_id get_dt_fid() const { return m_dt_fid; }
|
||||||
family_id get_datalog_fid() const { return m_datalog_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; }
|
family_id get_fpa_fid() const { return m_fpa_fid; }
|
||||||
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
|
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ namespace api {
|
||||||
return "unknown";
|
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;
|
std::stringstream str;
|
||||||
m_context.display_smt2(num_queries, queries, str);
|
m_context.display_smt2(num_queries, queries, str);
|
||||||
return str.str();
|
return str.str();
|
||||||
|
@ -466,13 +466,16 @@ extern "C" {
|
||||||
ast_manager& m = mk_c(c)->m();
|
ast_manager& m = mk_c(c)->m();
|
||||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
||||||
mk_c(c)->save_object(v);
|
mk_c(c)->save_object(v);
|
||||||
expr_ref_vector rules(m);
|
expr_ref_vector rules(m), queries(m);
|
||||||
svector<symbol> names;
|
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) {
|
for (unsigned i = 0; i < rules.size(); ++i) {
|
||||||
v->m_ast_vector.push_back(rules[i].get());
|
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));
|
RETURN_Z3(of_ast_vector(v));
|
||||||
Z3_CATCH_RETURN(0);
|
Z3_CATCH_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,7 +476,7 @@ extern "C" {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
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);
|
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -506,9 +506,9 @@ extern "C" {
|
||||||
RETURN_Z3(0);
|
RETURN_Z3(0);
|
||||||
}
|
}
|
||||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
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);
|
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||||
return 0;
|
RETURN_Z3(0);
|
||||||
}
|
}
|
||||||
func_decl* decl = (*decls)[idx];
|
func_decl* decl = (*decls)[idx];
|
||||||
decl = dt_util.get_constructor_recognizer(decl);
|
decl = dt_util.get_constructor_recognizer(decl);
|
||||||
|
@ -529,7 +529,7 @@ extern "C" {
|
||||||
RETURN_Z3(0);
|
RETURN_Z3(0);
|
||||||
}
|
}
|
||||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
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);
|
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -618,4 +618,25 @@ extern "C" {
|
||||||
Z3_CATCH_RETURN(0);
|
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) {
|
unsigned Z3_API Z3_fpa_get_sbits(Z3_context c, Z3_sort s) {
|
||||||
Z3_TRY;
|
Z3_TRY;
|
||||||
LOG_Z3_fpa_get_ebits(c, s);
|
LOG_Z3_fpa_get_sbits(c, s);
|
||||||
RESET_ERROR_CODE();
|
RESET_ERROR_CODE();
|
||||||
CHECK_NON_NULL(s, 0);
|
CHECK_NON_NULL(s, 0);
|
||||||
return mk_c(c)->fpautil().get_sbits(to_sort(s));
|
return mk_c(c)->fpautil().get_sbits(to_sort(s));
|
||||||
|
@ -765,7 +765,30 @@ extern "C" {
|
||||||
mpqm.display_decimal(ss, q, sbits);
|
mpqm.display_decimal(ss, q, sbits);
|
||||||
return mk_c(c)->mk_external_string(ss.str());
|
return mk_c(c)->mk_external_string(ss.str());
|
||||||
Z3_CATCH_RETURN("");
|
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) {
|
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_bool Z3_API Z3_fpa_get_numeral_exponent_int64(__in Z3_context c, __in Z3_ast t, __out __int64 * n) {
|
||||||
Z3_TRY;
|
Z3_TRY;
|
||||||
LOG_Z3_fpa_get_numeral_exponent_string(c, t);
|
LOG_Z3_fpa_get_numeral_exponent_int64(c, t, n);
|
||||||
RESET_ERROR_CODE();
|
RESET_ERROR_CODE();
|
||||||
ast_manager & m = mk_c(c)->m();
|
ast_manager & m = mk_c(c)->m();
|
||||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||||
|
|
|
@ -290,10 +290,10 @@ extern "C" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
model_ref _m;
|
model_ref mr;
|
||||||
m_solver.get()->get_model(_m);
|
m_solver.get()->get_model(mr);
|
||||||
Z3_model_ref *tmp_val = alloc(Z3_model_ref);
|
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);
|
mk_c(c)->save_object(tmp_val);
|
||||||
*model = of_model(tmp_val);
|
*model = of_model(tmp_val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,18 @@ extern "C" {
|
||||||
Z3_CATCH_RETURN(0);
|
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_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f) {
|
||||||
Z3_TRY;
|
Z3_TRY;
|
||||||
LOG_Z3_model_get_func_interp(c, m, f);
|
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);
|
init_solver(c, s);
|
||||||
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
||||||
to_solver_ref(s)->collect_statistics(st->m_stats);
|
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);
|
mk_c(c)->save_object(st);
|
||||||
Z3_stats r = of_stats(st);
|
Z3_stats r = of_stats(st);
|
||||||
RETURN_Z3(r);
|
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.
|
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);
|
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(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(char const * name, unsigned arity, sort const * domain, sort const & range);
|
||||||
func_decl function(symbol const& name, sort_vector 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 ite(expr const & c, expr const & t, expr const & e);
|
||||||
|
|
||||||
friend expr distinct(expr_vector const& args);
|
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) {
|
friend expr operator==(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
|
@ -677,7 +683,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator+(expr const & a, expr const & b) {
|
friend expr operator+(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
Z3_ast args[2] = { a, b };
|
Z3_ast args[2] = { a, b };
|
||||||
r = Z3_mk_add(a.ctx(), 2, args);
|
r = Z3_mk_add(a.ctx(), 2, args);
|
||||||
|
@ -697,7 +703,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator*(expr const & a, expr const & b) {
|
friend expr operator*(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
Z3_ast args[2] = { a, b };
|
Z3_ast args[2] = { a, b };
|
||||||
r = Z3_mk_mul(a.ctx(), 2, args);
|
r = Z3_mk_mul(a.ctx(), 2, args);
|
||||||
|
@ -724,7 +730,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator/(expr const & a, expr const & b) {
|
friend expr operator/(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
r = Z3_mk_div(a.ctx(), a, b);
|
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/(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) / b; }
|
||||||
|
|
||||||
friend expr operator-(expr const & a) {
|
friend expr operator-(expr const & a) {
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith()) {
|
if (a.is_arith()) {
|
||||||
r = Z3_mk_unary_minus(a.ctx(), a);
|
r = Z3_mk_unary_minus(a.ctx(), a);
|
||||||
}
|
}
|
||||||
|
@ -759,7 +765,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator-(expr const & a, expr const & b) {
|
friend expr operator-(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
Z3_ast args[2] = { a, b };
|
Z3_ast args[2] = { a, b };
|
||||||
r = Z3_mk_sub(a.ctx(), 2, args);
|
r = Z3_mk_sub(a.ctx(), 2, args);
|
||||||
|
@ -779,7 +785,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator<=(expr const & a, expr const & b) {
|
friend expr operator<=(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
r = Z3_mk_le(a.ctx(), a, b);
|
r = Z3_mk_le(a.ctx(), a, b);
|
||||||
}
|
}
|
||||||
|
@ -798,7 +804,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator>=(expr const & a, expr const & b) {
|
friend expr operator>=(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
r = Z3_mk_ge(a.ctx(), a, b);
|
r = Z3_mk_ge(a.ctx(), a, b);
|
||||||
}
|
}
|
||||||
|
@ -817,7 +823,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator<(expr const & a, expr const & b) {
|
friend expr operator<(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
r = Z3_mk_lt(a.ctx(), a, b);
|
r = Z3_mk_lt(a.ctx(), a, b);
|
||||||
}
|
}
|
||||||
|
@ -836,7 +842,7 @@ namespace z3 {
|
||||||
|
|
||||||
friend expr operator>(expr const & a, expr const & b) {
|
friend expr operator>(expr const & a, expr const & b) {
|
||||||
check_context(a, b);
|
check_context(a, b);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
if (a.is_arith() && b.is_arith()) {
|
if (a.is_arith() && b.is_arith()) {
|
||||||
r = Z3_mk_gt(a.ctx(), a, b);
|
r = Z3_mk_gt(a.ctx(), a, b);
|
||||||
}
|
}
|
||||||
|
@ -1108,6 +1114,13 @@ namespace z3 {
|
||||||
ctx.check_error();
|
ctx.check_error();
|
||||||
return expr(ctx, r);
|
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 {
|
class func_entry : public object {
|
||||||
Z3_func_entry m_entry;
|
Z3_func_entry m_entry;
|
||||||
|
@ -1176,7 +1189,7 @@ namespace z3 {
|
||||||
|
|
||||||
expr eval(expr const & n, bool model_completion=false) const {
|
expr eval(expr const & n, bool model_completion=false) const {
|
||||||
check_context(*this, n);
|
check_context(*this, n);
|
||||||
Z3_ast r;
|
Z3_ast r = 0;
|
||||||
Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r);
|
Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r);
|
||||||
check_error();
|
check_error();
|
||||||
if (status == Z3_FALSE)
|
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) {
|
inline tactic fail_if(probe const & p) {
|
||||||
Z3_tactic r = Z3_tactic_fail_if(p.ctx(), p);
|
Z3_tactic r = Z3_tactic_fail_if(p.ctx(), p);
|
||||||
p.check_error();
|
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])); }
|
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;
|
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) {
|
inline func_decl context::function(symbol const & name, unsigned arity, sort const * domain, sort const & range) {
|
||||||
array<Z3_sort> args(arity);
|
array<Z3_sort> args(arity);
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
|
|
||||||
#include<windows.h>
|
#include<windows.h>
|
||||||
|
|
|
@ -98,11 +98,12 @@ namespace Microsoft.Z3
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The keys stored in the map.
|
/// The keys stored in the map.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ASTVector Keys
|
public AST[] Keys
|
||||||
{
|
{
|
||||||
get
|
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);
|
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
|
#region Internal
|
||||||
internal ASTVector(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
|
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); }
|
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);
|
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
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -2251,6 +2264,36 @@ namespace Microsoft.Z3
|
||||||
}
|
}
|
||||||
#endregion
|
#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 Numerals
|
||||||
|
|
||||||
#region General Numerals
|
#region General Numerals
|
||||||
|
@ -3438,6 +3481,18 @@ namespace Microsoft.Z3
|
||||||
}
|
}
|
||||||
#endregion
|
#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 Floating-Point Arithmetic
|
||||||
|
|
||||||
#region Rounding Modes
|
#region Rounding Modes
|
||||||
|
@ -4383,6 +4438,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Invariant(m_Statistics_DRQ != null);
|
Contract.Invariant(m_Statistics_DRQ != null);
|
||||||
Contract.Invariant(m_Tactic_DRQ != null);
|
Contract.Invariant(m_Tactic_DRQ != null);
|
||||||
Contract.Invariant(m_Fixedpoint_DRQ != null);
|
Contract.Invariant(m_Fixedpoint_DRQ != null);
|
||||||
|
Contract.Invariant(m_Optimize_DRQ != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly private AST.DecRefQueue m_AST_DRQ = new AST.DecRefQueue();
|
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 Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue(10);
|
||||||
readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.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 Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue(10);
|
||||||
|
readonly private Optimize.DecRefQueue m_Optimize_DRQ = new Optimize.DecRefQueue(10);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// AST DRQ
|
/// AST DRQ
|
||||||
|
@ -4476,6 +4533,11 @@ namespace Microsoft.Z3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDecRefQueue Fixedpoint_DRQ { get { Contract.Ensures(Contract.Result<Fixedpoint.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
|
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;
|
internal long refCount = 0;
|
||||||
|
|
||||||
|
@ -4518,6 +4580,7 @@ namespace Microsoft.Z3
|
||||||
Statistics_DRQ.Clear(this);
|
Statistics_DRQ.Clear(this);
|
||||||
Tactic_DRQ.Clear(this);
|
Tactic_DRQ.Clear(this);
|
||||||
Fixedpoint_DRQ.Clear(this);
|
Fixedpoint_DRQ.Clear(this);
|
||||||
|
Optimize_DRQ.Clear(this);
|
||||||
|
|
||||||
m_boolSort = null;
|
m_boolSort = null;
|
||||||
m_intSort = 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>
|
/// <summary>
|
||||||
/// Return the exponent value of a floating-point numeral as a string
|
/// Return the exponent value of a floating-point numeral as a string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -269,14 +269,6 @@ namespace Microsoft.Z3
|
||||||
AST.ArrayLength(queries), AST.ArrayToNative(queries));
|
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>
|
/// <summary>
|
||||||
/// Retrieve set of rules added to fixedpoint context.
|
/// Retrieve set of rules added to fixedpoint context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -286,7 +278,8 @@ namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
|
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);
|
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.
|
/// Add the rules to the current fixedpoint context.
|
||||||
/// Return the set of queries in the file.
|
/// Return the set of queries in the file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BoolExpr[] ParseFile(string file) {
|
public BoolExpr[] ParseFile(string file)
|
||||||
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file)));
|
{
|
||||||
|
ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file));
|
||||||
|
return av.ToBoolExprArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Similar to ParseFile. Instead it takes as argument a string.
|
/// Similar to ParseFile. Instead it takes as argument a string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
public BoolExpr[] ParseString(string s)
|
||||||
public BoolExpr[] ParseString(string s) {
|
{
|
||||||
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_string(Context.nCtx, NativeObject, 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);
|
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
|
#region Internal
|
||||||
internal Goal(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
|
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
|
/// <remarks>For more information on interpolation please refer
|
||||||
/// too the function Z3_get_interpolant in the C/C++ API, which is
|
/// too the function Z3_get_interpolant in the C/C++ API, which is
|
||||||
/// well documented.</remarks>
|
/// 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(pf != null);
|
||||||
Contract.Requires(pat != null);
|
Contract.Requires(pat != null);
|
||||||
|
@ -59,11 +59,7 @@ namespace Microsoft.Z3
|
||||||
CheckContextMatch(p);
|
CheckContextMatch(p);
|
||||||
|
|
||||||
ASTVector seq = new ASTVector(this, Native.Z3_get_interpolant(nCtx, pf.NativeObject, pat.NativeObject, p.NativeObject));
|
ASTVector seq = new ASTVector(this, Native.Z3_get_interpolant(nCtx, pf.NativeObject, pat.NativeObject, p.NativeObject));
|
||||||
uint n = seq.Size;
|
return seq.ToBoolExprArray();
|
||||||
Expr[] res = new Expr[n];
|
|
||||||
for (uint i = 0; i < n; i++)
|
|
||||||
res[i] = Expr.Create(this, seq[i].NativeObject);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -72,7 +68,7 @@ namespace Microsoft.Z3
|
||||||
/// <remarks>For more information on interpolation please refer
|
/// <remarks>For more information on interpolation please refer
|
||||||
/// too the function Z3_compute_interpolant in the C/C++ API, which is
|
/// too the function Z3_compute_interpolant in the C/C++ API, which is
|
||||||
/// well documented.</remarks>
|
/// 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(pat != null);
|
||||||
Contract.Requires(p != null);
|
Contract.Requires(p != null);
|
||||||
|
@ -84,7 +80,7 @@ namespace Microsoft.Z3
|
||||||
|
|
||||||
IntPtr i = IntPtr.Zero, m = IntPtr.Zero;
|
IntPtr i = IntPtr.Zero, m = IntPtr.Zero;
|
||||||
int r = Native.Z3_compute_interpolant(nCtx, pat.NativeObject, p.NativeObject, ref i, ref m);
|
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);
|
model = new Model(this, m);
|
||||||
return (Z3_lbool)r;
|
return (Z3_lbool)r;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +102,7 @@ namespace Microsoft.Z3
|
||||||
/// <remarks>For more information on interpolation please refer
|
/// <remarks>For more information on interpolation please refer
|
||||||
/// too the function Z3_check_interpolant in the C/C++ API, which is
|
/// too the function Z3_check_interpolant in the C/C++ API, which is
|
||||||
/// well documented.</remarks>
|
/// 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 == parents.Length);
|
||||||
Contract.Requires(cnsts.Length == interps.Length + 1);
|
Contract.Requires(cnsts.Length == interps.Length + 1);
|
||||||
|
|
|
@ -365,6 +365,7 @@
|
||||||
<Compile Include="IntSymbol.cs" />
|
<Compile Include="IntSymbol.cs" />
|
||||||
<Compile Include="ListSort.cs" />
|
<Compile Include="ListSort.cs" />
|
||||||
<Compile Include="Model.cs" />
|
<Compile Include="Model.cs" />
|
||||||
|
<Compile Include="Optimize.cs" />
|
||||||
<Compile Include="Params.cs" />
|
<Compile Include="Params.cs" />
|
||||||
<Compile Include="ParamDescrs.cs" />
|
<Compile Include="ParamDescrs.cs" />
|
||||||
<Compile Include="Pattern.cs" />
|
<Compile Include="Pattern.cs" />
|
||||||
|
|
|
@ -265,12 +265,8 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(s != null);
|
Contract.Requires(s != null);
|
||||||
Contract.Ensures(Contract.Result<Expr[]>() != null);
|
Contract.Ensures(Contract.Result<Expr[]>() != null);
|
||||||
|
|
||||||
ASTVector nUniv = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject));
|
ASTVector av = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject));
|
||||||
uint n = nUniv.Size;
|
return av.ToExprArray();
|
||||||
Expr[] res = new Expr[n];
|
|
||||||
for (uint i = 0; i < n; i++)
|
|
||||||
res[i] = Expr.Create(Context, nUniv[i].NativeObject);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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);
|
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a parameter setting.
|
/// Adds a parameter setting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -118,6 +119,7 @@ namespace Microsoft.Z3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Add(string name, string value)
|
public void Add(string name, string value)
|
||||||
{
|
{
|
||||||
|
Contract.Requires(name != null);
|
||||||
Contract.Requires(value != null);
|
Contract.Requires(value != null);
|
||||||
|
|
||||||
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, Context.MkSymbol(value).NativeObject);
|
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, Context.MkSymbol(value).NativeObject);
|
||||||
|
|
|
@ -178,8 +178,8 @@ namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
|
ASTVector assertions = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
|
||||||
return ass.Size;
|
return assertions.Size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,12 +192,8 @@ namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
|
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
|
||||||
|
|
||||||
ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
|
ASTVector assertions = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
|
||||||
uint n = ass.Size;
|
return assertions.ToBoolExprArray();
|
||||||
BoolExpr[] res = new BoolExpr[n];
|
|
||||||
for (uint i = 0; i < n; i++)
|
|
||||||
res[i] = new BoolExpr(Context, ass[i].NativeObject);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,18 +266,14 @@ namespace Microsoft.Z3
|
||||||
/// The result is empty if <c>Check</c> was not invoked before,
|
/// 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.
|
/// if its results was not <c>UNSATISFIABLE</c>, or if core production is disabled.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public Expr[] UnsatCore
|
public BoolExpr[] UnsatCore
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Contract.Ensures(Contract.Result<Expr[]>() != null);
|
Contract.Ensures(Contract.Result<Expr[]>() != null);
|
||||||
|
|
||||||
ASTVector core = new ASTVector(Context, Native.Z3_solver_get_unsat_core(Context.nCtx, NativeObject));
|
ASTVector core = new ASTVector(Context, Native.Z3_solver_get_unsat_core(Context.nCtx, NativeObject));
|
||||||
uint n = core.Size;
|
return core.ToBoolExprArray();
|
||||||
Expr[] res = new Expr[n];
|
|
||||||
for (uint i = 0; i < n; i++)
|
|
||||||
res[i] = Expr.Create(Context, core[i].NativeObject);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,10 @@ class ASTMap extends Z3Object
|
||||||
*
|
*
|
||||||
* @throws Z3Exception
|
* @throws Z3Exception
|
||||||
**/
|
**/
|
||||||
public ASTVector getKeys()
|
public AST[] getKeys()
|
||||||
{
|
{
|
||||||
return new ASTVector(getContext(), Native.astMapKeys(getContext().nCtx(),
|
ASTVector av = new ASTVector(getContext(), Native.astMapKeys(getContext().nCtx(), getNativeObject()));
|
||||||
getNativeObject()));
|
return av.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -119,4 +119,135 @@ public class ASTVector extends Z3Object
|
||||||
getContext().getASTVectorDRQ().add(o);
|
getContext().getASTVectorDRQ().add(o);
|
||||||
super.decRef(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);
|
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.
|
* Creates a new function declaration.
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -43,6 +43,21 @@ public class FPNum extends FPExpr
|
||||||
return Native.fpaGetNumeralSignificandString(getContext().nCtx(), getNativeObject());
|
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
|
* Return the exponent value of a floating-point numeral as a string
|
||||||
* @throws Z3Exception
|
* @throws Z3Exception
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class FPSort extends Sort
|
||||||
* The number of significand bits.
|
* The number of significand bits.
|
||||||
*/
|
*/
|
||||||
public int getSBits() {
|
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()
|
public BoolExpr[] getRules()
|
||||||
{
|
{
|
||||||
|
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetRules(getContext().nCtx(), getNativeObject()));
|
||||||
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetRules(
|
return v.ToBoolExprArray();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -312,17 +306,45 @@ public class Fixedpoint extends Z3Object
|
||||||
**/
|
**/
|
||||||
public BoolExpr[] getAssertions()
|
public BoolExpr[] getAssertions()
|
||||||
{
|
{
|
||||||
|
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetAssertions(getContext().nCtx(), getNativeObject()));
|
||||||
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetAssertions(
|
return v.ToBoolExprArray();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
super(ctx, obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,22 @@ public class Goal extends Z3Object
|
||||||
return "Z3Exception: " + e.getMessage();
|
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)
|
Goal(Context ctx, long obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,20 +73,23 @@ public class InterpolationContext extends Context
|
||||||
* well documented.
|
* well documented.
|
||||||
* @throws Z3Exception
|
* @throws Z3Exception
|
||||||
**/
|
**/
|
||||||
public Expr[] GetInterpolant(Expr pf, Expr pat, Params p)
|
public BoolExpr[] GetInterpolant(Expr pf, Expr pat, Params p)
|
||||||
{
|
{
|
||||||
checkContextMatch(pf);
|
checkContextMatch(pf);
|
||||||
checkContextMatch(pat);
|
checkContextMatch(pat);
|
||||||
checkContextMatch(p);
|
checkContextMatch(p);
|
||||||
|
|
||||||
ASTVector seq = new ASTVector(this, Native.getInterpolant(nCtx(), pf.getNativeObject(), pat.getNativeObject(), p.getNativeObject()));
|
ASTVector seq = new ASTVector(this, Native.getInterpolant(nCtx(), pf.getNativeObject(), pat.getNativeObject(), p.getNativeObject()));
|
||||||
int n = seq.size();
|
return seq.ToBoolExprArray();
|
||||||
Expr[] res = new Expr[n];
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
res[i] = Expr.create(this, seq.get(i).getNativeObject());
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ComputeInterpolantResult
|
||||||
|
{
|
||||||
|
public Z3_lbool status = Z3_lbool.Z3_L_UNDEF;
|
||||||
|
public BoolExpr[] interp = null;
|
||||||
|
public Model model = null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes an interpolant.
|
* Computes an interpolant.
|
||||||
* Remarks: For more information on interpolation please refer
|
* Remarks: For more information on interpolation please refer
|
||||||
|
@ -94,17 +97,20 @@ public class InterpolationContext extends Context
|
||||||
* well documented.
|
* well documented.
|
||||||
* @throws Z3Exception
|
* @throws Z3Exception
|
||||||
**/
|
**/
|
||||||
public Z3_lbool ComputeInterpolant(Expr pat, Params p, ASTVector interp, Model model)
|
public ComputeInterpolantResult ComputeInterpolant(Expr pat, Params p)
|
||||||
{
|
{
|
||||||
checkContextMatch(pat);
|
checkContextMatch(pat);
|
||||||
checkContextMatch(p);
|
checkContextMatch(p);
|
||||||
|
|
||||||
|
ComputeInterpolantResult res = new ComputeInterpolantResult();
|
||||||
Native.LongPtr n_i = new Native.LongPtr();
|
Native.LongPtr n_i = new Native.LongPtr();
|
||||||
Native.LongPtr n_m = new Native.LongPtr();
|
Native.LongPtr n_m = new Native.LongPtr();
|
||||||
int r = Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m);
|
res.status = Z3_lbool.fromInt(Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m));
|
||||||
interp = new ASTVector(this, n_i.value);
|
if (res.status == Z3_lbool.Z3_L_FALSE)
|
||||||
model = new Model(this, n_m.value);
|
res.interp = (new ASTVector(this, n_i.value)).ToBoolExprArray();
|
||||||
return Z3_lbool.fromInt(r);
|
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());
|
return Native.interpolationProfile(nCtx());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CheckInterpolantResult
|
||||||
|
{
|
||||||
|
public int return_value = 0;
|
||||||
|
public String error = null;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks the correctness of an interpolant.
|
/// Checks the correctness of an interpolant.
|
||||||
///
|
///
|
||||||
/// Remarks: For more information on interpolation please refer
|
/// Remarks: For more information on interpolation please refer
|
||||||
/// too the function Z3_check_interpolant in the C/C++ API, which is
|
/// too the function Z3_check_interpolant in the C/C++ API, which is
|
||||||
/// well documented.
|
/// 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();
|
Native.StringPtr n_err_str = new Native.StringPtr();
|
||||||
int r = Native.checkInterpolant(nCtx(),
|
res.return_value = Native.checkInterpolant(nCtx(),
|
||||||
cnsts.length,
|
cnsts.length,
|
||||||
Expr.arrayToNative(cnsts),
|
Expr.arrayToNative(cnsts),
|
||||||
parents,
|
parents,
|
||||||
|
@ -135,41 +148,52 @@ public class InterpolationContext extends Context
|
||||||
n_err_str,
|
n_err_str,
|
||||||
theory.length,
|
theory.length,
|
||||||
Expr.arrayToNative(theory));
|
Expr.arrayToNative(theory));
|
||||||
error = n_err_str.value;
|
res.error = n_err_str.value;
|
||||||
return r;
|
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.
|
/// Reads an interpolation problem from a file.
|
||||||
///
|
///
|
||||||
/// Remarks: For more information on interpolation please refer
|
/// Remarks: For more information on interpolation please refer
|
||||||
/// too the function Z3_read_interpolation_problem in the C/C++ API, which is
|
/// too the function Z3_read_interpolation_problem in the C/C++ API, which is
|
||||||
/// well documented.
|
/// 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 = new Native.IntPtr();
|
||||||
Native.IntPtr n_num_theory = new Native.IntPtr();
|
Native.IntPtr n_num_theory = new Native.IntPtr();
|
||||||
Native.ObjArrayPtr n_cnsts = new Native.ObjArrayPtr();
|
Native.ObjArrayPtr n_cnsts = new Native.ObjArrayPtr();
|
||||||
Native.UIntArrayPtr n_parents = new Native.UIntArrayPtr();
|
Native.UIntArrayPtr n_parents = new Native.UIntArrayPtr();
|
||||||
Native.ObjArrayPtr n_theory = new Native.ObjArrayPtr();
|
Native.ObjArrayPtr n_theory = new Native.ObjArrayPtr();
|
||||||
Native.StringPtr n_err_str = new Native.StringPtr();
|
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 = n_num.value;
|
||||||
int num_theory = n_num_theory.value;
|
int num_theory = n_num_theory.value;
|
||||||
error = n_err_str.value;
|
res.error = n_err_str.value;
|
||||||
cnsts = new Expr[num];
|
res.cnsts = new Expr[num];
|
||||||
parents = new int[num];
|
res.parents = new int[num];
|
||||||
theory = new Expr[num_theory];
|
theory = new Expr[num_theory];
|
||||||
for (int i = 0; i < num; i++)
|
for (int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
cnsts[i] = Expr.create(this, n_cnsts.value[i]);
|
res.cnsts[i] = Expr.create(this, n_cnsts.value[i]);
|
||||||
parents[i] = n_parents.value[i];
|
res.parents[i] = n_parents.value[i];
|
||||||
}
|
}
|
||||||
for (int i = 0; i < num_theory; i++)
|
for (int i = 0; i < num_theory; i++)
|
||||||
theory[i] = Expr.create(this, n_theory.value[i]);
|
res.theory[i] = Expr.create(this, n_theory.value[i]);
|
||||||
return r;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes an interpolation problem to a file.
|
/// Writes an interpolation problem to a file.
|
||||||
///
|
///
|
||||||
|
|
|
@ -273,11 +273,7 @@ public class Model extends Z3Object
|
||||||
|
|
||||||
ASTVector nUniv = new ASTVector(getContext(), Native.modelGetSortUniverse(
|
ASTVector nUniv = new ASTVector(getContext(), Native.modelGetSortUniverse(
|
||||||
getContext().nCtx(), getNativeObject(), s.getNativeObject()));
|
getContext().nCtx(), getNativeObject(), s.getNativeObject()));
|
||||||
int n = nUniv.size();
|
return nUniv.ToExprArray();
|
||||||
Expr[] res = new Expr[n];
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
res[i] = Expr.create(getContext(), nUniv.get(i).getNativeObject());
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -176,8 +176,7 @@ public class Solver extends Z3Object
|
||||||
**/
|
**/
|
||||||
public int getNumAssertions()
|
public int getNumAssertions()
|
||||||
{
|
{
|
||||||
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(
|
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(getContext().nCtx(), getNativeObject()));
|
||||||
getContext().nCtx(), getNativeObject()));
|
|
||||||
return assrts.size();
|
return assrts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,13 +187,8 @@ public class Solver extends Z3Object
|
||||||
**/
|
**/
|
||||||
public BoolExpr[] getAssertions()
|
public BoolExpr[] getAssertions()
|
||||||
{
|
{
|
||||||
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(
|
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(getContext().nCtx(), getNativeObject()));
|
||||||
getContext().nCtx(), getNativeObject()));
|
return assrts.ToBoolExprArray();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,16 +276,11 @@ public class Solver extends Z3Object
|
||||||
*
|
*
|
||||||
* @throws Z3Exception
|
* @throws Z3Exception
|
||||||
**/
|
**/
|
||||||
public Expr[] getUnsatCore()
|
public BoolExpr[] getUnsatCore()
|
||||||
{
|
{
|
||||||
|
|
||||||
ASTVector core = new ASTVector(getContext(), Native.solverGetUnsatCore(
|
ASTVector core = new ASTVector(getContext(), Native.solverGetUnsatCore(getContext().nCtx(), getNativeObject()));
|
||||||
getContext().nCtx(), getNativeObject()));
|
return core.ToBoolExprArray();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
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
|
end
|
||||||
|
|
||||||
(** The abstract syntax tree (AST) module *)
|
(** The abstract syntax tree (AST) module *)
|
||||||
module AST :
|
module rec AST :
|
||||||
sig
|
sig
|
||||||
type ast
|
type ast
|
||||||
|
|
||||||
|
@ -156,6 +156,12 @@ sig
|
||||||
@return A new ASTVector *)
|
@return A new ASTVector *)
|
||||||
val translate : ast_vector -> context -> ast_vector
|
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. *)
|
(** Retrieves a string representation of the vector. *)
|
||||||
val to_string : ast_vector -> string
|
val to_string : ast_vector -> string
|
||||||
end
|
end
|
||||||
|
@ -189,7 +195,7 @@ sig
|
||||||
val get_size : ast_map -> int
|
val get_size : ast_map -> int
|
||||||
|
|
||||||
(** The keys stored in the map. *)
|
(** 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.*)
|
(** Retrieves a string representation of the map.*)
|
||||||
val to_string : ast_map -> string
|
val to_string : ast_map -> string
|
||||||
|
@ -260,7 +266,7 @@ sig
|
||||||
end
|
end
|
||||||
|
|
||||||
(** The Sort module implements type information for ASTs *)
|
(** The Sort module implements type information for ASTs *)
|
||||||
module Sort :
|
and Sort :
|
||||||
sig
|
sig
|
||||||
type sort = Sort of AST.ast
|
type sort = Sort of AST.ast
|
||||||
|
|
||||||
|
@ -291,7 +297,7 @@ sig
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Function declarations *)
|
(** Function declarations *)
|
||||||
module rec FuncDecl :
|
and FuncDecl :
|
||||||
sig
|
sig
|
||||||
type func_decl = FuncDecl of AST.ast
|
type func_decl = FuncDecl of AST.ast
|
||||||
|
|
||||||
|
@ -2155,6 +2161,12 @@ sig
|
||||||
(** Return the significand value of a floating-point numeral as a string. *)
|
(** Return the significand value of a floating-point numeral as a string. *)
|
||||||
val get_numeral_significand_string : context -> Expr.expr -> 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 *)
|
(** Return the exponent value of a floating-point numeral as a string *)
|
||||||
val get_numeral_exponent_string : context -> Expr.expr -> string
|
val get_numeral_exponent_string : context -> Expr.expr -> string
|
||||||
|
|
||||||
|
@ -2641,6 +2653,9 @@ sig
|
||||||
|
|
||||||
(** A string representation of the Goal. *)
|
(** A string representation of the Goal. *)
|
||||||
val to_string : goal -> string
|
val to_string : goal -> string
|
||||||
|
|
||||||
|
(** Goal to BoolExpr conversion. *)
|
||||||
|
val as_expr : goal -> Expr.expr
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Models
|
(** Models
|
||||||
|
@ -2751,7 +2766,7 @@ sig
|
||||||
(** The finite set of distinct values that represent the interpretation of a sort.
|
(** The finite set of distinct values that represent the interpretation of a sort.
|
||||||
{!get_sorts}
|
{!get_sorts}
|
||||||
@return A list of expressions, where each is an element of the universe of the sort *)
|
@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.
|
(** Conversion of models to strings.
|
||||||
@return A string representation of the model. *)
|
@return A string representation of the model. *)
|
||||||
|
@ -2938,6 +2953,55 @@ sig
|
||||||
val interrupt : context -> unit
|
val interrupt : context -> unit
|
||||||
end
|
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 *)
|
(** Solvers *)
|
||||||
module Solver :
|
module Solver :
|
||||||
sig
|
sig
|
||||||
|
@ -2946,56 +3010,6 @@ sig
|
||||||
|
|
||||||
val string_of_status : status -> string
|
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. *)
|
(** A string that describes all available solver parameters. *)
|
||||||
val get_help : solver -> string
|
val get_help : solver -> string
|
||||||
|
|
||||||
|
@ -3081,7 +3095,7 @@ sig
|
||||||
The unsat core is a subset of [Assertions]
|
The unsat core is a subset of [Assertions]
|
||||||
The result is empty if [Check] was not invoked before,
|
The result is empty if [Check] was not invoked before,
|
||||||
if its results was not [UNSATISFIABLE], or if core production is disabled. *)
|
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]. *)
|
(** A brief justification of why the last call to [Check] returned [UNKNOWN]. *)
|
||||||
val get_reason_unknown : solver -> string
|
val get_reason_unknown : solver -> string
|
||||||
|
@ -3198,6 +3212,19 @@ sig
|
||||||
|
|
||||||
(** Create a Fixedpoint context. *)
|
(** Create a Fixedpoint context. *)
|
||||||
val mk_fixedpoint : context -> fixedpoint
|
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
|
end
|
||||||
|
|
||||||
(** Functions for handling SMT and SMT2 expressions and files *)
|
(** Functions for handling SMT and SMT2 expressions and files *)
|
||||||
|
@ -3272,12 +3299,12 @@ sig
|
||||||
(** Gets an interpolant.
|
(** Gets an interpolant.
|
||||||
For more information on interpolation please refer
|
For more information on interpolation please refer
|
||||||
too the C/C++ API, which is well documented. *)
|
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.
|
(** Computes an interpolant.
|
||||||
For more information on interpolation please refer
|
For more information on interpolation please refer
|
||||||
too the C/C++ API, which is well documented. *)
|
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.
|
(** Retrieves an interpolation profile.
|
||||||
For more information on interpolation please refer
|
For more information on interpolation please refer
|
||||||
|
@ -3355,3 +3382,5 @@ val enable_trace : string -> unit
|
||||||
*)
|
*)
|
||||||
val disable_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:
|
Z3 exceptions:
|
||||||
|
|
||||||
>>> try:
|
>>> try:
|
||||||
... x = Int('x')
|
... x = BitVec('x', 32)
|
||||||
... y = Bool('y')
|
... y = Bool('y')
|
||||||
... # the expression x + y is type incorrect
|
... # the expression x + y is type incorrect
|
||||||
... n = x + y
|
... 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 unique identifier for object. It can be used for hash-tables and maps."""
|
||||||
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
|
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
|
||||||
|
|
||||||
|
|
||||||
def ctx_ref(self):
|
def ctx_ref(self):
|
||||||
"""Return a reference to the C context where this AST node is stored."""
|
"""Return a reference to the C context where this AST node is stored."""
|
||||||
return self.ctx.ref()
|
return self.ctx.ref()
|
||||||
|
@ -455,7 +454,6 @@ class SortRef(AstRef):
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
|
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
|
||||||
|
|
||||||
|
|
||||||
def kind(self):
|
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.
|
"""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)
|
return ArraySortRef(s, ctx)
|
||||||
elif k == Z3_DATATYPE_SORT:
|
elif k == Z3_DATATYPE_SORT:
|
||||||
return DatatypeSortRef(s, ctx)
|
return DatatypeSortRef(s, ctx)
|
||||||
|
elif k == Z3_FINITE_DOMAIN_SORT:
|
||||||
|
return FiniteDomainSortRef(s, ctx)
|
||||||
elif k == Z3_FLOATING_POINT_SORT:
|
elif k == Z3_FLOATING_POINT_SORT:
|
||||||
return FPSortRef(s, ctx)
|
return FPSortRef(s, ctx)
|
||||||
elif k == Z3_ROUNDING_MODE_SORT:
|
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")
|
_z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
|
||||||
return val
|
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):
|
class BoolRef(ExprRef):
|
||||||
"""All Boolean expressions are instances of this class."""
|
"""All Boolean expressions are instances of this class."""
|
||||||
def sort(self):
|
def sort(self):
|
||||||
|
@ -1900,6 +1910,10 @@ class ArithSortRef(SortRef):
|
||||||
return val
|
return val
|
||||||
if val_s.is_int() and self.is_real():
|
if val_s.is_int() and self.is_real():
|
||||||
return ToReal(val)
|
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__:
|
if __debug__:
|
||||||
_z3_assert(False, "Z3 Integer/Real expression expected" )
|
_z3_assert(False, "Z3 Integer/Real expression expected" )
|
||||||
else:
|
else:
|
||||||
|
@ -5603,7 +5617,7 @@ class Statistics:
|
||||||
sat
|
sat
|
||||||
>>> st = s.statistics()
|
>>> st = s.statistics()
|
||||||
>>> len(st)
|
>>> len(st)
|
||||||
2
|
4
|
||||||
"""
|
"""
|
||||||
return int(Z3_stats_size(self.ctx.ref(), self.stats))
|
return int(Z3_stats_size(self.ctx.ref(), self.stats))
|
||||||
|
|
||||||
|
@ -5617,7 +5631,7 @@ class Statistics:
|
||||||
sat
|
sat
|
||||||
>>> st = s.statistics()
|
>>> st = s.statistics()
|
||||||
>>> len(st)
|
>>> len(st)
|
||||||
2
|
4
|
||||||
>>> st[0]
|
>>> st[0]
|
||||||
('nlsat propagations', 2)
|
('nlsat propagations', 2)
|
||||||
>>> st[1]
|
>>> st[1]
|
||||||
|
@ -5641,7 +5655,7 @@ class Statistics:
|
||||||
sat
|
sat
|
||||||
>>> st = s.statistics()
|
>>> st = s.statistics()
|
||||||
>>> st.keys()
|
>>> 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))]
|
return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
|
||||||
|
|
||||||
|
@ -5678,7 +5692,7 @@ class Statistics:
|
||||||
sat
|
sat
|
||||||
>>> st = s.statistics()
|
>>> st = s.statistics()
|
||||||
>>> st.keys()
|
>>> st.keys()
|
||||||
['nlsat propagations', 'nlsat stages']
|
['nlsat propagations', 'nlsat stages', 'max memory', 'memory']
|
||||||
>>> st.nlsat_propagations
|
>>> st.nlsat_propagations
|
||||||
2
|
2
|
||||||
>>> st.nlsat_stages
|
>>> st.nlsat_stages
|
||||||
|
@ -6071,8 +6085,6 @@ class Solver(Z3PPObject):
|
||||||
e = BoolVal(True, self.ctx).as_ast()
|
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)
|
return Z3_benchmark_to_smtlib_string(self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def SolverFor(logic, ctx=None):
|
def SolverFor(logic, ctx=None):
|
||||||
"""Create a solver customized for the given logic.
|
"""Create a solver customized for the given logic.
|
||||||
|
|
||||||
|
@ -6333,6 +6345,166 @@ class Fixedpoint(Z3PPObject):
|
||||||
else:
|
else:
|
||||||
return Exists(self.vars, fml)
|
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
|
# ApplyResult
|
||||||
|
@ -8022,23 +8194,24 @@ def FP(name, fpsort, ctx=None):
|
||||||
>>> eq(x, x2)
|
>>> eq(x, x2)
|
||||||
True
|
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)
|
return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
|
||||||
|
|
||||||
def FPs(names, fpsort, ctx=None):
|
def FPs(names, fpsort, ctx=None):
|
||||||
"""Return an array of floating-point constants.
|
"""Return an array of floating-point constants.
|
||||||
|
|
||||||
>>> x, y, z = BitVecs('x y z', 16)
|
>>> x, y, z = FPs('x y z', FPSort(8, 24))
|
||||||
>>> x.size()
|
|
||||||
16
|
|
||||||
>>> x.sort()
|
>>> x.sort()
|
||||||
BitVec(16)
|
FPSort(8, 24)
|
||||||
>>> Sum(x, y, z)
|
>>> x.sbits()
|
||||||
0 + x + y + z
|
24
|
||||||
>>> Product(x, y, z)
|
>>> x.ebits()
|
||||||
1*x*y*z
|
8
|
||||||
>>> simplify(Product(x, y, z))
|
>>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
|
||||||
x*y*z
|
fpMul(RNE(), fpAdd(RNE(), x, y), z)
|
||||||
"""
|
"""
|
||||||
ctx = z3._get_ctx(ctx)
|
ctx = z3._get_ctx(ctx)
|
||||||
if isinstance(names, str):
|
if isinstance(names, str):
|
||||||
|
|
|
@ -1017,6 +1017,8 @@ class Formatter:
|
||||||
return self.pp_seq(a.assertions(), 0, [])
|
return self.pp_seq(a.assertions(), 0, [])
|
||||||
elif isinstance(a, z3.Fixedpoint):
|
elif isinstance(a, z3.Fixedpoint):
|
||||||
return a.sexpr()
|
return a.sexpr()
|
||||||
|
elif isinstance(a, z3.Optimize):
|
||||||
|
return a.sexpr()
|
||||||
elif isinstance(a, z3.ApplyResult):
|
elif isinstance(a, z3.ApplyResult):
|
||||||
return self.pp_seq_seq(a, 0, [])
|
return self.pp_seq_seq(a, 0, [])
|
||||||
elif isinstance(a, z3.ModelRef):
|
elif isinstance(a, z3.ModelRef):
|
||||||
|
|
|
@ -78,6 +78,10 @@ class FixedpointObj(ctypes.c_void_p):
|
||||||
def __init__(self, fixedpoint): self._as_parameter_ = fixedpoint
|
def __init__(self, fixedpoint): self._as_parameter_ = fixedpoint
|
||||||
def from_param(obj): return obj
|
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):
|
class ModelObj(ctypes.c_void_p):
|
||||||
def __init__(self, model): self._as_parameter_ = model
|
def __init__(self, model): self._as_parameter_ = model
|
||||||
def from_param(obj): return obj
|
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_
|
#ifndef _Z3_API_H_
|
||||||
#define _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 Z3_func_interp_opt Z3_func_interp
|
||||||
DEFINE_TYPE(Z3_func_entry);
|
DEFINE_TYPE(Z3_func_entry);
|
||||||
DEFINE_TYPE(Z3_fixedpoint);
|
DEFINE_TYPE(Z3_fixedpoint);
|
||||||
|
DEFINE_TYPE(Z3_optimize);
|
||||||
DEFINE_TYPE(Z3_rcf_num);
|
DEFINE_TYPE(Z3_rcf_num);
|
||||||
DEFINE_VOID(Z3_theory_data);
|
DEFINE_VOID(Z3_theory_data);
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,6 +92,7 @@ DEFINE_VOID(Z3_theory_data);
|
||||||
- \c Z3_func_interp: interpretation of a function in a model.
|
- \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_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_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_vector: vector of \c Z3_ast objects.
|
||||||
- \c Z3_ast_map: mapping from \c Z3_ast to \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.
|
- \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.
|
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)),
|
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:
|
- Z3_OP_PR_UNIT_RESOLUTION:
|
||||||
\nicebox{
|
\nicebox{
|
||||||
|
@ -877,6 +888,17 @@ typedef enum
|
||||||
|
|
||||||
- Z3_OP_DT_ACCESSOR: datatype accessor.
|
- 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_EVEN: Floating-point rounding mode RNE
|
||||||
|
|
||||||
- Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY: Floating-point rounding mode RNA
|
- 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_CONSTRUCTOR=0x800,
|
||||||
Z3_OP_DT_RECOGNISER,
|
Z3_OP_DT_RECOGNISER,
|
||||||
Z3_OP_DT_ACCESSOR,
|
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
|
// Floating-Point Arithmetic
|
||||||
Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
|
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_INTERP', 'Z3_func_interp', 'FuncInterpObj')
|
||||||
def_Type('FUNC_ENTRY', 'Z3_func_entry', 'FuncEntryObj')
|
def_Type('FUNC_ENTRY', 'Z3_func_entry', 'FuncEntryObj')
|
||||||
def_Type('FIXEDPOINT', 'Z3_fixedpoint', 'FixedpointObj')
|
def_Type('FIXEDPOINT', 'Z3_fixedpoint', 'FixedpointObj')
|
||||||
|
def_Type('OPTIMIZE', 'Z3_optimize', 'OptimizeObj')
|
||||||
def_Type('PARAM_DESCRS', 'Z3_param_descrs', 'ParamDescrs')
|
def_Type('PARAM_DESCRS', 'Z3_param_descrs', 'ParamDescrs')
|
||||||
def_Type('RCF_NUM', 'Z3_rcf_num', 'RCFNumObj')
|
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(
|
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);
|
__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.
|
\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);
|
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
|
\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);
|
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.
|
\brief Return the interpretation of the function \c f in the model \c m.
|
||||||
Return \mlonly [None], \endmlonly \conly \c NULL,
|
Return \mlonly [None], \endmlonly \conly \c NULL,
|
||||||
|
@ -5290,7 +5371,19 @@ END_MLAPI_EXCLUDE
|
||||||
*/
|
*/
|
||||||
void Z3_API Z3_reset_memory(void);
|
void Z3_API Z3_reset_memory(void);
|
||||||
#endif
|
#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
|
#ifdef CorML3
|
||||||
|
@ -5947,7 +6040,7 @@ END_MLAPI_EXCLUDE
|
||||||
/**
|
/**
|
||||||
\brief Parse an SMT-LIB2 string with fixedpoint rules.
|
\brief Parse an SMT-LIB2 string with fixedpoint rules.
|
||||||
Add the rules to the current fixedpoint context.
|
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 c - context.
|
||||||
\param f - fixedpoint context.
|
\param f - fixedpoint context.
|
||||||
|
@ -6039,6 +6132,197 @@ END_MLAPI_EXCLUDE
|
||||||
#endif
|
#endif
|
||||||
#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
|
#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)))
|
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
|
#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);
|
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
|
\brief Return the exponent value of a floating-point numeral as a string
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#ifndef __in
|
#ifndef __in
|
||||||
#define __in
|
#define __in
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,12 +22,14 @@ Notes:
|
||||||
#include"stream_buffer.h"
|
#include"stream_buffer.h"
|
||||||
#include"symbol.h"
|
#include"symbol.h"
|
||||||
#include"trace.h"
|
#include"trace.h"
|
||||||
|
#include<sstream>
|
||||||
|
|
||||||
void register_z3_replayer_cmds(z3_replayer & in);
|
void register_z3_replayer_cmds(z3_replayer & in);
|
||||||
|
|
||||||
|
|
||||||
void throw_invalid_reference() {
|
void throw_invalid_reference() {
|
||||||
TRACE("z3_replayer", tout << "invalid argument reference\n";);
|
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 {
|
struct z3_replayer::imp {
|
||||||
|
@ -45,7 +47,38 @@ struct z3_replayer::imp {
|
||||||
size_t_map<void *> m_heap;
|
size_t_map<void *> m_heap;
|
||||||
svector<z3_replayer_cmd> m_cmds;
|
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 {
|
struct value {
|
||||||
value_kind m_kind;
|
value_kind m_kind;
|
||||||
|
@ -71,6 +104,7 @@ struct z3_replayer::imp {
|
||||||
vector<ptr_vector<void> > m_obj_arrays;
|
vector<ptr_vector<void> > m_obj_arrays;
|
||||||
vector<svector<Z3_symbol> > m_sym_arrays;
|
vector<svector<Z3_symbol> > m_sym_arrays;
|
||||||
vector<unsigned_vector> m_unsigned_arrays;
|
vector<unsigned_vector> m_unsigned_arrays;
|
||||||
|
vector<svector<int> > m_int_arrays;
|
||||||
|
|
||||||
imp(z3_replayer & o, std::istream & in):
|
imp(z3_replayer & o, std::istream & in):
|
||||||
m_owner(o),
|
m_owner(o),
|
||||||
|
@ -321,6 +355,15 @@ struct z3_replayer::imp {
|
||||||
v.push_back(static_cast<unsigned>(m_args[i].m_uint));
|
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) {
|
else if (k == SYMBOL) {
|
||||||
aidx = m_sym_arrays.size();
|
aidx = m_sym_arrays.size();
|
||||||
nk = SYMBOL_ARRAY;
|
nk = SYMBOL_ARRAY;
|
||||||
|
@ -489,8 +532,7 @@ struct z3_replayer::imp {
|
||||||
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
||||||
unsigned pos = static_cast<unsigned>(m_uint64);
|
unsigned pos = static_cast<unsigned>(m_uint64);
|
||||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "* " << m_ptr << " " << pos << "\n";);
|
TRACE("z3_replayer", tout << "[" << m_line << "] " << "* " << m_ptr << " " << pos << "\n";);
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
check_arg(pos, OBJECT);
|
||||||
throw_invalid_reference();
|
|
||||||
m_heap.insert(m_ptr, m_args[pos].m_obj);
|
m_heap.insert(m_ptr, m_args[pos].m_obj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -499,8 +541,7 @@ struct z3_replayer::imp {
|
||||||
// @ obj_id array_pos idx
|
// @ obj_id array_pos idx
|
||||||
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
||||||
unsigned pos = static_cast<unsigned>(m_uint64);
|
unsigned pos = static_cast<unsigned>(m_uint64);
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
|
check_arg(pos, OBJECT_ARRAY);
|
||||||
throw_invalid_reference();
|
|
||||||
unsigned aidx = static_cast<unsigned>(m_args[pos].m_uint);
|
unsigned aidx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||||
ptr_vector<void> & v = m_obj_arrays[aidx];
|
ptr_vector<void> & v = m_obj_arrays[aidx];
|
||||||
skip_blank(); read_uint64();
|
skip_blank(); read_uint64();
|
||||||
|
@ -525,26 +566,22 @@ struct z3_replayer::imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_int(unsigned pos) const {
|
int get_int(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
check_arg(pos, INT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return static_cast<int>(m_args[pos].m_int);
|
return static_cast<int>(m_args[pos].m_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
__int64 get_int64(unsigned pos) const {
|
__int64 get_int64(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
check_arg(pos, INT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return m_args[pos].m_int;
|
return m_args[pos].m_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_uint(unsigned pos) const {
|
unsigned get_uint(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
check_arg(pos, UINT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return static_cast<unsigned>(m_args[pos].m_uint);
|
return static_cast<unsigned>(m_args[pos].m_uint);
|
||||||
}
|
}
|
||||||
|
|
||||||
__uint64 get_uint64(unsigned pos) const {
|
__uint64 get_uint64(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
check_arg(pos, UINT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return m_args[pos].m_uint;
|
return m_args[pos].m_uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,46 +592,45 @@ struct z3_replayer::imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_double(unsigned pos) const {
|
double get_double(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != DOUBLE)
|
check_arg(pos, DOUBLE);
|
||||||
throw_invalid_reference();
|
|
||||||
return m_args[pos].m_double;
|
return m_args[pos].m_double;
|
||||||
}
|
}
|
||||||
|
|
||||||
Z3_string get_str(unsigned pos) const {
|
Z3_string get_str(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
|
check_arg(pos, STRING);
|
||||||
throw_invalid_reference();
|
|
||||||
return m_args[pos].m_str;
|
return m_args[pos].m_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Z3_symbol get_symbol(unsigned pos) const {
|
Z3_symbol get_symbol(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL)
|
check_arg(pos, SYMBOL);
|
||||||
throw_invalid_reference();
|
|
||||||
return reinterpret_cast<Z3_symbol>(const_cast<char*>(m_args[pos].m_str));
|
return reinterpret_cast<Z3_symbol>(const_cast<char*>(m_args[pos].m_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
void * get_obj(unsigned pos) const {
|
void * get_obj(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
check_arg(pos, OBJECT);
|
||||||
throw_invalid_reference();
|
|
||||||
return m_args[pos].m_obj;
|
return m_args[pos].m_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned * get_uint_array(unsigned pos) const {
|
unsigned * get_uint_array(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT_ARRAY)
|
check_arg(pos, UINT_ARRAY);
|
||||||
throw_invalid_reference();
|
|
||||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||||
return m_unsigned_arrays[idx].c_ptr();
|
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 {
|
Z3_symbol * get_symbol_array(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
|
check_arg(pos, SYMBOL_ARRAY);
|
||||||
throw_invalid_reference();
|
|
||||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||||
return m_sym_arrays[idx].c_ptr();
|
return m_sym_arrays[idx].c_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ** get_obj_array(unsigned pos) const {
|
void ** get_obj_array(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
|
check_arg(pos, OBJECT_ARRAY);
|
||||||
throw_invalid_reference();
|
|
||||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||||
ptr_vector<void> const & v = m_obj_arrays[idx];
|
ptr_vector<void> const & v = m_obj_arrays[idx];
|
||||||
TRACE("z3_replayer_bug", tout << "pos: " << pos << ", idx: " << idx << " size(): " << v.size() << "\n";
|
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) {
|
int * get_int_addr(unsigned pos) {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
check_arg(pos, INT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return reinterpret_cast<int*>(&(m_args[pos].m_int));
|
return reinterpret_cast<int*>(&(m_args[pos].m_int));
|
||||||
}
|
}
|
||||||
|
|
||||||
__int64 * get_int64_addr(unsigned pos) {
|
__int64 * get_int64_addr(unsigned pos) {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
check_arg(pos, INT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return &(m_args[pos].m_int);
|
return &(m_args[pos].m_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned * get_uint_addr(unsigned pos) {
|
unsigned * get_uint_addr(unsigned pos) {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
check_arg(pos, UINT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return reinterpret_cast<unsigned*>(&(m_args[pos].m_uint));
|
return reinterpret_cast<unsigned*>(&(m_args[pos].m_uint));
|
||||||
}
|
}
|
||||||
|
|
||||||
__uint64 * get_uint64_addr(unsigned pos) {
|
__uint64 * get_uint64_addr(unsigned pos) {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
check_arg(pos, UINT64);
|
||||||
throw_invalid_reference();
|
|
||||||
return &(m_args[pos].m_uint);
|
return &(m_args[pos].m_uint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Z3_string * get_str_addr(unsigned pos) {
|
Z3_string * get_str_addr(unsigned pos) {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
|
check_arg(pos, STRING);
|
||||||
throw_invalid_reference();
|
|
||||||
return &(m_args[pos].m_str);
|
return &(m_args[pos].m_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ** get_obj_addr(unsigned pos) {
|
void ** get_obj_addr(unsigned pos) {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
check_arg(pos, OBJECT);
|
||||||
throw_invalid_reference();
|
|
||||||
return &(m_args[pos].m_obj);
|
return &(m_args[pos].m_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,6 +683,7 @@ struct z3_replayer::imp {
|
||||||
m_obj_arrays.reset();
|
m_obj_arrays.reset();
|
||||||
m_sym_arrays.reset();
|
m_sym_arrays.reset();
|
||||||
m_unsigned_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);
|
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 {
|
Z3_symbol * z3_replayer::get_symbol_array(unsigned pos) const {
|
||||||
return m_imp->get_symbol_array(pos);
|
return m_imp->get_symbol_array(pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
void * get_obj(unsigned pos) const;
|
void * get_obj(unsigned pos) const;
|
||||||
|
|
||||||
unsigned * get_uint_array(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;
|
Z3_symbol * get_symbol_array(unsigned pos) const;
|
||||||
void ** get_obj_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),
|
decl(AST_FUNC_DECL, name, info),
|
||||||
m_arity(arity),
|
m_arity(arity),
|
||||||
m_range(range) {
|
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<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<symbol*>(get_decl_names()), decl_names, sizeof(symbol) * num_decls);
|
||||||
memcpy(const_cast<expr **>(get_patterns()), patterns, sizeof(expr *) * num_patterns);
|
if (num_patterns != 0)
|
||||||
memcpy(const_cast<expr **>(get_no_patterns()), no_patterns, sizeof(expr *) * num_no_patterns);
|
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: {
|
case OP_DISTINCT: {
|
||||||
func_decl_info info(m_family_id, OP_DISTINCT);
|
func_decl_info info(m_family_id, OP_DISTINCT);
|
||||||
info.set_pairwise();
|
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);
|
return m_manager->mk_func_decl(symbol("distinct"), arity, domain, m_bool_sort, info);
|
||||||
}
|
}
|
||||||
default:
|
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) {
|
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;
|
app * r = 0;
|
||||||
if (num_args > 2 && !decl->is_flat_associative()) {
|
if (num_args > 2 && !decl->is_flat_associative()) {
|
||||||
if (decl->is_right_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;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func_decl * ast_manager::mk_fresh_func_decl(symbol const & prefix, symbol const & suffix, unsigned arity,
|
func_decl * ast_manager::mk_fresh_func_decl(symbol const & prefix, symbol const & suffix, unsigned arity,
|
||||||
sort * const * domain, sort * range) {
|
sort * const * domain, sort * range) {
|
||||||
func_decl_info info(null_family_id, null_decl_kind);
|
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);
|
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) {
|
app * ast_manager::mk_distinct_expanded(unsigned num_args, expr * const * args) {
|
||||||
if (num_args < 2)
|
if (num_args < 2)
|
||||||
return mk_true();
|
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_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_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_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_distinct_expanded(unsigned num_args, expr * const * args);
|
||||||
app * mk_true() { return m_true; }
|
app * mk_true() { return m_true; }
|
||||||
app * mk_false() { return m_false; }
|
app * mk_false() { return m_false; }
|
||||||
app * mk_interp(expr * arg) { return mk_app(m_basic_family_id, OP_INTERP, arg); }
|
app * mk_interp(expr * arg) { return mk_app(m_basic_family_id, OP_INTERP, arg); }
|
||||||
|
|
||||||
|
|
||||||
func_decl* mk_and_decl() {
|
func_decl* mk_and_decl() {
|
||||||
sort* domain[2] = { m_bool_sort, m_bool_sort };
|
sort* domain[2] = { m_bool_sort, m_bool_sort };
|
||||||
return mk_func_decl(m_basic_family_id, OP_AND, 0, 0, 2, domain);
|
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++) {
|
for (i = 0; i < num; i++) {
|
||||||
if (f->get_parameter(i).is_int())
|
if (f->get_parameter(i).is_int())
|
||||||
continue;
|
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()))
|
if (f->get_parameter(i).is_ast() && is_func_decl(f->get_parameter(i).get_ast()))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
@ -105,9 +107,13 @@ format * smt2_pp_environment::pp_fdecl_params(format * fname, func_decl * f) {
|
||||||
ptr_buffer<format> fs;
|
ptr_buffer<format> fs;
|
||||||
fs.push_back(fname);
|
fs.push_back(fname);
|
||||||
for (unsigned i = 0; i < num; i++) {
|
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())
|
if (f->get_parameter(i).is_int())
|
||||||
fs.push_back(mk_int(get_manager(), f->get_parameter(i).get_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
|
else
|
||||||
fs.push_back(pp_fdecl_ref(to_func_decl(f->get_parameter(i).get_ast())));
|
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 {
|
else {
|
||||||
SASSERT(u.is_irrational_algebraic_numeral(t));
|
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();
|
algebraic_numbers::manager & am = u.am();
|
||||||
format * vf;
|
format * vf;
|
||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
bool is_neg = false;
|
bool is_neg = false;
|
||||||
if (decimal) {
|
if (decimal) {
|
||||||
scoped_anum abs_val(am);
|
scoped_anum abs_val(am);
|
||||||
am.set(abs_val, val);
|
am.set(abs_val, val2);
|
||||||
if (am.is_neg(val)) {
|
if (am.is_neg(val2)) {
|
||||||
is_neg = true;
|
is_neg = true;
|
||||||
am.neg(abs_val);
|
am.neg(abs_val);
|
||||||
}
|
}
|
||||||
am.display_decimal(buffer, abs_val, decimal_prec);
|
am.display_decimal(buffer, abs_val, decimal_prec);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
am.display_root_smt2(buffer, val);
|
am.display_root_smt2(buffer, val2);
|
||||||
}
|
}
|
||||||
vf = mk_string(get_manager(), buffer.str().c_str());
|
vf = mk_string(get_manager(), buffer.str().c_str());
|
||||||
return is_neg ? mk_neg(vf) : vf;
|
return is_neg ? mk_neg(vf) : vf;
|
||||||
|
@ -1159,6 +1165,26 @@ std::ostream& operator<<(std::ostream& out, mk_ismt2_pp const & p) {
|
||||||
return out;
|
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
|
#ifdef Z3DEBUG
|
||||||
void pp(expr const * n, ast_manager & m) {
|
void pp(expr const * n, ast_manager & m) {
|
||||||
std::cout << mk_ismt2_pp(const_cast<expr*>(n), m) << std::endl;
|
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, 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
|
#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) {
|
void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
|
||||||
ptr_vector<quantifier> ql;
|
ptr_vector<quantifier> ql;
|
||||||
decl_collector decls(m_manager);
|
ast_manager& m = m_manager;
|
||||||
|
decl_collector decls(m);
|
||||||
smt_renaming rn;
|
smt_renaming rn;
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
|
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);
|
decls.visit(n);
|
||||||
|
|
||||||
if (m_manager.is_proof(n)) {
|
if (m.is_proof(n)) {
|
||||||
strm << "(";
|
strm << "(";
|
||||||
}
|
}
|
||||||
if (m_benchmark_name != symbol::null) {
|
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("")) {
|
if (m_source_info != symbol::null && m_source_info != symbol("")) {
|
||||||
strm << "; :source { " << m_source_info << " }\n";
|
strm << "; :source { " << m_source_info << " }\n";
|
||||||
}
|
}
|
||||||
if (m_manager.is_bool(n)) {
|
if (m.is_bool(n)) {
|
||||||
strm << "(set-info :status " << m_status << ")\n";
|
strm << "(set-info :status " << m_status << ")\n";
|
||||||
}
|
}
|
||||||
if (m_category != symbol::null && m_category != symbol("")) {
|
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) {
|
for (unsigned i = 0; i < decls.get_num_sorts(); ++i) {
|
||||||
sort* s = decls.get_sorts()[i];
|
sort* s = decls.get_sorts()[i];
|
||||||
if (!(*m_is_declared)(s)) {
|
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);
|
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) {
|
for (unsigned i = 0; i < decls.get_num_decls(); ++i) {
|
||||||
func_decl* d = decls.get_func_decls()[i];
|
func_decl* d = decls.get_func_decls()[i];
|
||||||
if (!(*m_is_declared)(d)) {
|
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);
|
p(d);
|
||||||
strm << "\n";
|
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) {
|
for (unsigned i = 0; i < decls.get_num_preds(); ++i) {
|
||||||
func_decl* d = decls.get_pred_decls()[i];
|
func_decl* d = decls.get_pred_decls()[i];
|
||||||
if (!(*m_is_declared)(d)) {
|
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);
|
p(d);
|
||||||
strm << "\n";
|
strm << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
|
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
|
||||||
strm << "(assert\n";
|
smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 1);
|
||||||
smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
|
strm << "(assert\n ";
|
||||||
p(m_assumptions[i].get());
|
p(m_assumptions[i].get());
|
||||||
strm << ")\n";
|
strm << ")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_assumptions_star.size(); ++i) {
|
for (unsigned i = 0; i < m_assumptions_star.size(); ++i) {
|
||||||
strm << "(assert\n";
|
smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 1);
|
||||||
smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
|
strm << "(assert\n ";
|
||||||
p(m_assumptions_star[i].get());
|
p(m_assumptions_star[i].get());
|
||||||
strm << ")\n";
|
strm << ")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
|
smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 0);
|
||||||
if (m_manager.is_bool(n)) {
|
if (m.is_bool(n)) {
|
||||||
strm << "(assert\n";
|
if (!m.is_true(n)) {
|
||||||
p(n);
|
strm << "(assert\n ";
|
||||||
strm << ")\n";
|
p(n);
|
||||||
|
strm << ")\n";
|
||||||
|
}
|
||||||
strm << "(check-sat)\n";
|
strm << "(check-sat)\n";
|
||||||
}
|
}
|
||||||
else if (m_manager.is_proof(n)) {
|
else if (m.is_proof(n)) {
|
||||||
strm << "(proof\n";
|
strm << "(proof\n";
|
||||||
p(n);
|
p(n);
|
||||||
strm << "))\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