mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge branch 'opt' of https://git01.codeplex.com/z3 into opt
This commit is contained in:
		
						commit
						f020b7c7b8
					
				
					 380 changed files with 66767 additions and 3722 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -18,6 +18,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,5 +1,10 @@
 | 
				
			||||||
RELEASE NOTES
 | 
					RELEASE NOTES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Version 4.3.3
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed bug in floating point models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Version 4.3.2
 | 
					Version 4.3.2
 | 
				
			||||||
=============
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@ void demorgan() {
 | 
				
			||||||
    // adding the negation of the conjecture as a constraint.
 | 
					    // adding the negation of the conjecture as a constraint.
 | 
				
			||||||
    s.add(!conjecture);
 | 
					    s.add(!conjecture);
 | 
				
			||||||
    std::cout << s << "\n";
 | 
					    std::cout << s << "\n";
 | 
				
			||||||
 | 
					    std::cout << s.to_smt2() << "\n";
 | 
				
			||||||
    switch (s.check()) {
 | 
					    switch (s.check()) {
 | 
				
			||||||
    case unsat:   std::cout << "de-Morgan is valid\n"; break;
 | 
					    case unsat:   std::cout << "de-Morgan is valid\n"; break;
 | 
				
			||||||
    case sat:     std::cout << "de-Morgan is not valid\n"; break;
 | 
					    case sat:     std::cout << "de-Morgan is not valid\n"; break;
 | 
				
			||||||
| 
						 | 
					@ -974,6 +975,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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        demorgan(); std::cout << "\n";
 | 
					        demorgan(); std::cout << "\n";
 | 
				
			||||||
| 
						 | 
					@ -1012,6 +1037,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";
 | 
				
			||||||
        std::cout << "done\n";
 | 
					        std::cout << "done\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch (exception & ex) {
 | 
					    catch (exception & ex) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										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,36 @@
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Runtime.CompilerServices;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// General Information about an assembly is controlled through the following 
 | 
				
			||||||
 | 
					// set of attributes. Change these attribute values to modify the information
 | 
				
			||||||
 | 
					// associated with an assembly.
 | 
				
			||||||
 | 
					[assembly: AssemblyTitle("SolverFoundation.Plugin.Z3")]
 | 
				
			||||||
 | 
					[assembly: AssemblyDescription("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyConfiguration("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCompany("Microsoft")]
 | 
				
			||||||
 | 
					[assembly: AssemblyProduct("SolverFoundation.Plugin.Z3")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCopyright("Copyright © Microsoft 2013")]
 | 
				
			||||||
 | 
					[assembly: AssemblyTrademark("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCulture("")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Setting ComVisible to false makes the types in this assembly not visible 
 | 
				
			||||||
 | 
					// to COM components.  If you need to access a type in this assembly from 
 | 
				
			||||||
 | 
					// COM, set the ComVisible attribute to true on that type.
 | 
				
			||||||
 | 
					[assembly: ComVisible(false)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The following GUID is for the ID of the typelib if this project is exposed to COM
 | 
				
			||||||
 | 
					[assembly: Guid("ed1476c0-96de-4d2c-983d-3888b140c3ad")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Version information for an assembly consists of the following four values:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      Major Version
 | 
				
			||||||
 | 
					//      Minor Version 
 | 
				
			||||||
 | 
					//      Build Number
 | 
				
			||||||
 | 
					//      Revision
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You can specify all the values or you can default the Build and Revision Numbers 
 | 
				
			||||||
 | 
					// by using the '*' as shown below:
 | 
				
			||||||
 | 
					// [assembly: AssemblyVersion("1.0.*")]
 | 
				
			||||||
 | 
					[assembly: AssemblyVersion("1.0.0.0")]
 | 
				
			||||||
 | 
					[assembly: AssemblyFileVersion("1.0.0.0")]
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -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, 3, 2, 0)
 | 
					    set_version(4, 3, 3, 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,7 +50,7 @@ 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')
 | 
				
			||||||
| 
						 | 
					@ -61,25 +62,27 @@ def init_project_def():
 | 
				
			||||||
    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('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe'], 'tactic/smtlogics')
 | 
				
			||||||
    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']
 | 
					    API_files = ['z3_api.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_interp.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', 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -979,6 +979,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"
 | 
				
			||||||
| 
						 | 
					@ -1075,7 +1076,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();
 | 
				
			||||||
| 
						 | 
					@ -1087,6 +1087,7 @@ extern "C" {
 | 
				
			||||||
            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;
 | 
				
			||||||
| 
						 | 
					@ -1124,6 +1125,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());
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,6 +109,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");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,6 +75,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;
 | 
				
			||||||
        datatype_decl_plugin *     m_dt_plugin;
 | 
					        datatype_decl_plugin *     m_dt_plugin;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        std::string                m_string_buffer; // temporary buffer used to cache strings sent to the "external" world.
 | 
					        std::string                m_string_buffer; // temporary buffer used to cache strings sent to the "external" world.
 | 
				
			||||||
| 
						 | 
					@ -121,6 +122,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; }
 | 
				
			||||||
        datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
 | 
					        datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Z3_error_code get_error_code() const { return m_error_code; }
 | 
					        Z3_error_code get_error_code() const { return m_error_code; }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1314,6 +1314,26 @@ namespace z3 {
 | 
				
			||||||
        expr_vector assertions() const { Z3_ast_vector r = Z3_solver_get_assertions(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
 | 
					        expr_vector assertions() const { Z3_ast_vector r = Z3_solver_get_assertions(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
 | 
				
			||||||
        expr proof() const { Z3_ast r = Z3_solver_get_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); }
 | 
					        expr proof() const { Z3_ast r = Z3_solver_get_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); }
 | 
				
			||||||
        friend std::ostream & operator<<(std::ostream & out, solver const & s) { out << Z3_solver_to_string(s.ctx(), s); return out; }
 | 
					        friend std::ostream & operator<<(std::ostream & out, solver const & s) { out << Z3_solver_to_string(s.ctx(), s); return out; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::string to_smt2(char const* status = "unknown") {
 | 
				
			||||||
 | 
					            array<Z3_ast> es(assertions());
 | 
				
			||||||
 | 
					            Z3_ast const* fmls = es.ptr();
 | 
				
			||||||
 | 
					            Z3_ast fml = 0;
 | 
				
			||||||
 | 
					            unsigned sz = es.size();
 | 
				
			||||||
 | 
					            if (sz > 0) {
 | 
				
			||||||
 | 
					                --sz;
 | 
				
			||||||
 | 
					                fml = fmls[sz];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                fml = ctx().bool_val(true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return std::string(Z3_benchmark_to_smtlib_string(
 | 
				
			||||||
 | 
					                                   ctx(),
 | 
				
			||||||
 | 
					                                   "", "", status, "", 
 | 
				
			||||||
 | 
					                                   sz, 
 | 
				
			||||||
 | 
					                                   fmls, 
 | 
				
			||||||
 | 
					                                   fml));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class goal : public object {
 | 
					    class goal : public object {
 | 
				
			||||||
| 
						 | 
					@ -1513,6 +1533,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();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 Miscellaneous
 | 
					        #region Miscellaneous
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -3594,6 +3649,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();
 | 
				
			||||||
| 
						 | 
					@ -3611,6 +3667,7 @@ namespace Microsoft.Z3
 | 
				
			||||||
        readonly private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue();
 | 
					        readonly private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue();
 | 
				
			||||||
        readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue();
 | 
					        readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue();
 | 
				
			||||||
        readonly private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue();
 | 
					        readonly private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue();
 | 
				
			||||||
 | 
					        readonly private Optimize.DecRefQueue m_Optimize_DRQ = new Optimize.DecRefQueue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal AST.DecRefQueue AST_DRQ { get { Contract.Ensures(Contract.Result<AST.DecRefQueue>() != null); return m_AST_DRQ; } }
 | 
					        internal AST.DecRefQueue AST_DRQ { get { Contract.Ensures(Contract.Result<AST.DecRefQueue>() != null); return m_AST_DRQ; } }
 | 
				
			||||||
        internal ASTMap.DecRefQueue ASTMap_DRQ { get { Contract.Ensures(Contract.Result<ASTMap.DecRefQueue>() != null); return m_ASTMap_DRQ; } }
 | 
					        internal ASTMap.DecRefQueue ASTMap_DRQ { get { Contract.Ensures(Contract.Result<ASTMap.DecRefQueue>() != null); return m_ASTMap_DRQ; } }
 | 
				
			||||||
| 
						 | 
					@ -3627,6 +3684,7 @@ namespace Microsoft.Z3
 | 
				
			||||||
        internal Statistics.DecRefQueue Statistics_DRQ { get { Contract.Ensures(Contract.Result<Statistics.DecRefQueue>() != null); return m_Statistics_DRQ; } }
 | 
					        internal Statistics.DecRefQueue Statistics_DRQ { get { Contract.Ensures(Contract.Result<Statistics.DecRefQueue>() != null); return m_Statistics_DRQ; } }
 | 
				
			||||||
        internal Tactic.DecRefQueue Tactic_DRQ { get { Contract.Ensures(Contract.Result<Tactic.DecRefQueue>() != null); return m_Tactic_DRQ; } }
 | 
					        internal Tactic.DecRefQueue Tactic_DRQ { get { Contract.Ensures(Contract.Result<Tactic.DecRefQueue>() != null); return m_Tactic_DRQ; } }
 | 
				
			||||||
        internal Fixedpoint.DecRefQueue Fixedpoint_DRQ { get { Contract.Ensures(Contract.Result<Fixedpoint.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
 | 
					        internal Fixedpoint.DecRefQueue Fixedpoint_DRQ { get { Contract.Ensures(Contract.Result<Fixedpoint.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
 | 
				
			||||||
 | 
					        internal Optimize.DecRefQueue Optimize_DRQ { get { Contract.Ensures(Contract.Result<Optimize.DecRefQueue>() != null); return m_Optimize_DRQ; } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal long refCount = 0;
 | 
					        internal long refCount = 0;
 | 
				
			||||||
| 
						 | 
					@ -3670,6 +3728,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);
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -303,6 +303,19 @@ namespace Microsoft.Z3
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <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));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
        /// Parse an SMT-LIB2 file with fixedpoint rules. 
 | 
					        /// Parse an SMT-LIB2 file with fixedpoint rules. 
 | 
				
			||||||
        /// Add the rules to the current fixedpoint context. 
 | 
					        /// Add the rules to the current fixedpoint context. 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,12 +19,12 @@
 | 
				
			||||||
    <DebugSymbols>true</DebugSymbols>
 | 
					    <DebugSymbols>true</DebugSymbols>
 | 
				
			||||||
    <DebugType>full</DebugType>
 | 
					    <DebugType>full</DebugType>
 | 
				
			||||||
    <Optimize>false</Optimize>
 | 
					    <Optimize>false</Optimize>
 | 
				
			||||||
    <OutputPath>..\..\..\..\..\cwinter\bugs\z3bugs\Debug\</OutputPath>
 | 
					    <OutputPath>..\Debug\</OutputPath>
 | 
				
			||||||
    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
					    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
				
			||||||
    <ErrorReport>prompt</ErrorReport>
 | 
					    <ErrorReport>prompt</ErrorReport>
 | 
				
			||||||
    <WarningLevel>4</WarningLevel>
 | 
					    <WarningLevel>4</WarningLevel>
 | 
				
			||||||
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
					    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
				
			||||||
    <DocumentationFile>C:\cwinter\bugs\z3bugs\Debug\Microsoft.Z3.XML</DocumentationFile>
 | 
					    <DocumentationFile>..\Debug\Microsoft.Z3.XML</DocumentationFile>
 | 
				
			||||||
    <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
 | 
					    <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
 | 
				
			||||||
    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
 | 
					    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
 | 
				
			||||||
    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
 | 
					    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
 | 
				
			||||||
| 
						 | 
					@ -254,7 +254,7 @@
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
 | 
					  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
 | 
				
			||||||
    <DebugSymbols>true</DebugSymbols>
 | 
					    <DebugSymbols>true</DebugSymbols>
 | 
				
			||||||
    <OutputPath>..\..\..\..\..\cwinter\bugs\z3bugs\Debug\</OutputPath>
 | 
					    <OutputPath>..\x86\Debug\</OutputPath>
 | 
				
			||||||
    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
					    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
				
			||||||
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
					    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
				
			||||||
    <DebugType>full</DebugType>
 | 
					    <DebugType>full</DebugType>
 | 
				
			||||||
| 
						 | 
					@ -266,7 +266,7 @@
 | 
				
			||||||
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
 | 
					    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
 | 
				
			||||||
    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
 | 
					    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
 | 
				
			||||||
    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
 | 
					    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
 | 
				
			||||||
    <DocumentationFile>C:\cwinter\bugs\z3bugs\Debug\Microsoft.Z3.XML</DocumentationFile>
 | 
					    <DocumentationFile>..\x86\Debug\Microsoft.Z3.XML</DocumentationFile>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
 | 
					  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
 | 
				
			||||||
    <OutputPath>bin\x86\Release\</OutputPath>
 | 
					    <OutputPath>bin\x86\Release\</OutputPath>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										296
									
								
								src/api/dotnet/Optimize.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								src/api/dotnet/Optimize.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,296 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					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 override void IncRef(Context ctx, IntPtr obj)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Native.Z3_optimize_inc_ref(ctx.nCtx, obj);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public 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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/api/dotnet/Readme.NET35
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/api/dotnet/Readme.NET35
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					The default Z3 bindings for .NET are built for the .NET framework version 4.
 | 
				
			||||||
 | 
					Should the need arise, it is also possible to build them for .NET 3.5; the
 | 
				
			||||||
 | 
					instructions are as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the project properties of Microsoft.Z3.csproj:
 | 
				
			||||||
 | 
					- Under 'Application': Change Target framework to .NET Framework 3.5
 | 
				
			||||||
 | 
					- Under 'Build': Add FRAMEWORK_LT_4 to the condidional compilation symbols
 | 
				
			||||||
 | 
					- Remove the reference to System.Numerics
 | 
				
			||||||
 | 
					- Install the NuGet Package "Microsoft Code Contracts for Net3.5"
 | 
				
			||||||
| 
						 | 
					@ -375,6 +375,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.
 | 
				
			||||||
     **/
 | 
					     **/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -319,6 +319,18 @@ public class Fixedpoint extends Z3Object
 | 
				
			||||||
        return res;
 | 
					        return res;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Fixedpoint statistics.
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @throws Z3Exception
 | 
				
			||||||
 | 
					     **/
 | 
				
			||||||
 | 
					    public Statistics getStatistics() throws Z3Exception
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return new Statistics(getContext(), Native.fixedpointGetStatistics(
 | 
				
			||||||
 | 
					                getContext().nCtx(), getNativeObject()));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Fixedpoint(Context ctx, long obj) throws Z3Exception
 | 
					    Fixedpoint(Context ctx, long obj) throws Z3Exception
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        super(ctx, obj);
 | 
					        super(ctx, obj);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
    return SortRef(s, ctx)
 | 
					    return SortRef(s, ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _sort(ctx, a):
 | 
					def _sort(ctx, a):
 | 
				
			||||||
| 
						 | 
					@ -6048,8 +6048,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. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6166,7 +6164,7 @@ class Fixedpoint(Z3PPObject):
 | 
				
			||||||
            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)            
 | 
					            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)            
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            body = _get_args(body)
 | 
					            body = _get_args(body)
 | 
				
			||||||
            f    = self.abstract(Implies(And(body),head))
 | 
					            f    = self.abstract(Implies(And(body, self.ctx),head))
 | 
				
			||||||
            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
 | 
					            Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def rule(self, head, body = None, name = None):
 | 
					    def rule(self, head, body = None, name = None):
 | 
				
			||||||
| 
						 | 
					@ -6183,7 +6181,7 @@ class Fixedpoint(Z3PPObject):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        query = _get_args(query)
 | 
					        query = _get_args(query)
 | 
				
			||||||
        sz = len(query)
 | 
					        sz = len(query)
 | 
				
			||||||
        if sz >= 1 and isinstance(query[0], FuncDecl):            
 | 
					        if sz >= 1 and isinstance(query[0], FuncDeclRef):            
 | 
				
			||||||
            _decls = (FuncDecl * sz)()
 | 
					            _decls = (FuncDecl * sz)()
 | 
				
			||||||
            i = 0
 | 
					            i = 0
 | 
				
			||||||
            for q in query:
 | 
					            for q in query:
 | 
				
			||||||
| 
						 | 
					@ -6194,7 +6192,7 @@ class Fixedpoint(Z3PPObject):
 | 
				
			||||||
            if sz == 1:
 | 
					            if sz == 1:
 | 
				
			||||||
                query = query[0]
 | 
					                query = query[0]
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                query = And(query)
 | 
					                query = And(query, self.ctx)
 | 
				
			||||||
            query = self.abstract(query, False)
 | 
					            query = self.abstract(query, False)
 | 
				
			||||||
            r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
 | 
					            r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
 | 
				
			||||||
        return CheckSatResult(r)
 | 
					        return CheckSatResult(r)
 | 
				
			||||||
| 
						 | 
					@ -6213,7 +6211,7 @@ class Fixedpoint(Z3PPObject):
 | 
				
			||||||
            name = ""
 | 
					            name = ""
 | 
				
			||||||
        name = to_symbol(name, self.ctx)
 | 
					        name = to_symbol(name, self.ctx)
 | 
				
			||||||
        body = _get_args(body)
 | 
					        body = _get_args(body)
 | 
				
			||||||
        f    = self.abstract(Implies(And(body),head))
 | 
					        f    = self.abstract(Implies(And(body, self.ctx),head))
 | 
				
			||||||
        Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
 | 
					        Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_answer(self):       
 | 
					    def get_answer(self):       
 | 
				
			||||||
| 
						 | 
					@ -6310,6 +6308,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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -842,6 +842,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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										264
									
								
								src/api/z3_api.h
									
										
									
									
									
								
							
							
						
						
									
										264
									
								
								src/api/z3_api.h
									
										
									
									
									
								
							| 
						 | 
					@ -47,6 +47,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 +86,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.
 | 
				
			||||||
| 
						 | 
					@ -875,6 +877,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_UNINTERPRETED: kind used for uninterpreted symbols.
 | 
					      - Z3_OP_UNINTERPRETED: kind used for uninterpreted symbols.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
| 
						 | 
					@ -1055,6 +1068,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,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Z3_OP_UNINTERPRETED         
 | 
					    Z3_OP_UNINTERPRETED         
 | 
				
			||||||
} Z3_decl_kind;
 | 
					} Z3_decl_kind;
 | 
				
			||||||
| 
						 | 
					@ -1192,6 +1211,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')
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
| 
						 | 
					@ -3734,6 +3754,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.
 | 
				
			||||||
| 
						 | 
					@ -3759,6 +3801,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
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
| 
						 | 
					@ -3988,6 +4053,12 @@ END_MLAPI_EXCLUDE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
        \brief Return a unique identifier for \c t.
 | 
					        \brief Return a unique identifier for \c t.
 | 
				
			||||||
 | 
					        The identifier is unique up to structural equality. Thus, two ast nodes
 | 
				
			||||||
 | 
					        created by the same context and having the same children and same function symbols
 | 
				
			||||||
 | 
					        have the same identifiers. Ast nodes created in the same context, but having
 | 
				
			||||||
 | 
					        different children or different functions have different identifiers.
 | 
				
			||||||
 | 
					        Variables and quantifiers are also assigned different identifiers according to
 | 
				
			||||||
 | 
					        their structure.        
 | 
				
			||||||
        \mlonly \remark Implicitly used by [Pervasives.compare] for values of type [ast], [app], [sort], [func_decl], and [pattern]. \endmlonly
 | 
					        \mlonly \remark Implicitly used by [Pervasives.compare] for values of type [ast], [app], [sort], [func_decl], and [pattern]. \endmlonly
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def_API('Z3_get_ast_id', UINT, (_in(CONTEXT), _in(AST)))
 | 
					        def_API('Z3_get_ast_id', UINT, (_in(CONTEXT), _in(AST)))
 | 
				
			||||||
| 
						 | 
					@ -3996,6 +4067,8 @@ END_MLAPI_EXCLUDE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
       \brief Return a hash code for the given AST.
 | 
					       \brief Return a hash code for the given AST.
 | 
				
			||||||
 | 
					       The hash code is structural. You can use Z3_get_ast_id interchangably with 
 | 
				
			||||||
 | 
					       this function.
 | 
				
			||||||
       \mlonly \remark Implicitly used by [Hashtbl.hash] for values of type [ast], [app], [sort], [func_decl], and [pattern]. \endmlonly
 | 
					       \mlonly \remark Implicitly used by [Hashtbl.hash] for values of type [ast], [app], [sort], [func_decl], and [pattern]. \endmlonly
 | 
				
			||||||
 | 
					
 | 
				
			||||||
       def_API('Z3_get_ast_hash', UINT, (_in(CONTEXT), _in(AST)))
 | 
					       def_API('Z3_get_ast_hash', UINT, (_in(CONTEXT), _in(AST)))
 | 
				
			||||||
| 
						 | 
					@ -5904,6 +5977,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
 | 
				
			||||||
    /*@}*/
 | 
					    /*@}*/
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 {
 | 
				
			||||||
| 
						 | 
					@ -44,7 +46,37 @@ 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 };
 | 
					    enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, INT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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";
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
| 
						 | 
					@ -68,6 +100,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),
 | 
				
			||||||
| 
						 | 
					@ -295,6 +328,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;
 | 
				
			||||||
| 
						 | 
					@ -457,8 +499,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;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -467,8 +508,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();
 | 
				
			||||||
| 
						 | 
					@ -493,70 +533,65 @@ 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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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";
 | 
				
			||||||
| 
						 | 
					@ -565,38 +600,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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -615,6 +644,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();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
| 
						 | 
					@ -673,6 +703,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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -417,6 +417,7 @@ inline decl_kind arith_decl_plugin::fix_kind(decl_kind k, unsigned arity) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app * arith_decl_plugin::mk_numeral(rational const & val, bool is_int) {
 | 
					app * arith_decl_plugin::mk_numeral(rational const & val, bool is_int) {
 | 
				
			||||||
    if (is_int && !val.is_int()) {
 | 
					    if (is_int && !val.is_int()) {
 | 
				
			||||||
 | 
					        SASSERT(false);
 | 
				
			||||||
        m_manager->raise_exception("invalid rational value passed as an integer");
 | 
					        m_manager->raise_exception("invalid rational value passed as an integer");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (val.is_unsigned()) {
 | 
					    if (val.is_unsigned()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1013,6 +1013,17 @@ func_decl * basic_decl_plugin::mk_ite_decl(sort * s) {
 | 
				
			||||||
    return m_ite_decls[id];
 | 
					    return m_ite_decls[id];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sort* basic_decl_plugin::join(sort* s1, sort* s2) {
 | 
				
			||||||
 | 
					    if (s1 == s2) return s1;
 | 
				
			||||||
 | 
					    if (s1->get_family_id() == m_manager->m_arith_family_id && 
 | 
				
			||||||
 | 
					        s2->get_family_id() == m_manager->m_arith_family_id) {
 | 
				
			||||||
 | 
					        if (s1->get_decl_kind() == REAL_SORT) {
 | 
				
			||||||
 | 
					            return s1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return s2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
 | 
					func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
 | 
				
			||||||
                                          unsigned arity, sort * const * domain, sort * range) {
 | 
					                                          unsigned arity, sort * const * domain, sort * range) {
 | 
				
			||||||
    switch (static_cast<basic_op_kind>(k)) {
 | 
					    switch (static_cast<basic_op_kind>(k)) {
 | 
				
			||||||
| 
						 | 
					@ -1025,10 +1036,10 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
 | 
				
			||||||
    case OP_IFF:     return m_iff_decl;
 | 
					    case OP_IFF:     return m_iff_decl;
 | 
				
			||||||
    case OP_IMPLIES: return m_implies_decl;
 | 
					    case OP_IMPLIES: return m_implies_decl;
 | 
				
			||||||
    case OP_XOR:     return m_xor_decl;
 | 
					    case OP_XOR:     return m_xor_decl;
 | 
				
			||||||
    case OP_ITE:     return arity == 3 ? mk_ite_decl(domain[1]) : 0;
 | 
					    case OP_ITE:     return arity == 3 ? mk_ite_decl(join(domain[1], domain[2])) : 0;
 | 
				
			||||||
        // eq and oeq must have at least two arguments, they can have more since they are chainable
 | 
					        // eq and oeq must have at least two arguments, they can have more since they are chainable
 | 
				
			||||||
    case OP_EQ:      return arity >= 2 ? mk_eq_decl_core("=", OP_EQ, domain[0], m_eq_decls) : 0;
 | 
					    case OP_EQ:      return arity >= 2 ? mk_eq_decl_core("=", OP_EQ, join(domain[0],domain[1]), m_eq_decls) : 0;
 | 
				
			||||||
    case OP_OEQ:     return arity >= 2 ? mk_eq_decl_core("~", OP_OEQ, domain[0], m_oeq_decls) : 0;
 | 
					    case OP_OEQ:     return arity >= 2 ? mk_eq_decl_core("~", OP_OEQ, join(domain[0],domain[1]), m_oeq_decls) : 0;
 | 
				
			||||||
    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();
 | 
				
			||||||
| 
						 | 
					@ -1061,10 +1072,12 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
 | 
				
			||||||
    case OP_IFF:     return m_iff_decl;
 | 
					    case OP_IFF:     return m_iff_decl;
 | 
				
			||||||
    case OP_IMPLIES: return m_implies_decl;
 | 
					    case OP_IMPLIES: return m_implies_decl;
 | 
				
			||||||
    case OP_XOR:     return m_xor_decl;
 | 
					    case OP_XOR:     return m_xor_decl;
 | 
				
			||||||
    case OP_ITE:     return num_args == 3 ? mk_ite_decl(m_manager->get_sort(args[1])): 0;
 | 
					    case OP_ITE:     return num_args == 3 ? mk_ite_decl(join(m_manager->get_sort(args[1]), m_manager->get_sort(args[2]))): 0;
 | 
				
			||||||
        // eq and oeq must have at least two arguments, they can have more since they are chainable
 | 
					        // eq and oeq must have at least two arguments, they can have more since they are chainable
 | 
				
			||||||
    case OP_EQ:      return num_args >= 2 ? mk_eq_decl_core("=", OP_EQ, m_manager->get_sort(args[0]), m_eq_decls) : 0;
 | 
					    case OP_EQ:      return num_args >= 2 ? mk_eq_decl_core("=", OP_EQ, join(m_manager->get_sort(args[0]),
 | 
				
			||||||
    case OP_OEQ:     return num_args >= 2 ? mk_eq_decl_core("~", OP_OEQ, m_manager->get_sort(args[0]), m_oeq_decls) : 0;
 | 
					                                                                             m_manager->get_sort(args[1])), m_eq_decls) : 0;
 | 
				
			||||||
 | 
					    case OP_OEQ:     return num_args >= 2 ? mk_eq_decl_core("~", OP_OEQ, join(m_manager->get_sort(args[0]),
 | 
				
			||||||
 | 
					                                                                              m_manager->get_sort(args[1])), m_oeq_decls) : 0;
 | 
				
			||||||
    case OP_DISTINCT:
 | 
					    case OP_DISTINCT:
 | 
				
			||||||
        return decl_plugin::mk_func_decl(k, num_parameters, parameters, num_args, args, range);
 | 
					        return decl_plugin::mk_func_decl(k, num_parameters, parameters, num_args, args, range);
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
| 
						 | 
					@ -2058,6 +2071,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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1100,6 +1100,7 @@ protected:
 | 
				
			||||||
    virtual void set_manager(ast_manager * m, family_id id);
 | 
					    virtual void set_manager(ast_manager * m, family_id id);
 | 
				
			||||||
    func_decl * mk_eq_decl_core(char const * name, decl_kind k, sort * s, ptr_vector<func_decl> & cache);
 | 
					    func_decl * mk_eq_decl_core(char const * name, decl_kind k, sort * s, ptr_vector<func_decl> & cache);
 | 
				
			||||||
    func_decl * mk_ite_decl(sort * s);
 | 
					    func_decl * mk_ite_decl(sort * s);
 | 
				
			||||||
 | 
					    sort* join(sort* s1, sort* s2);
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    basic_decl_plugin();
 | 
					    basic_decl_plugin();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -1378,7 +1379,7 @@ enum proof_gen_mode {
 | 
				
			||||||
// -----------------------------------
 | 
					// -----------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ast_manager {
 | 
					class ast_manager {
 | 
				
			||||||
protected:
 | 
					    friend class basic_decl_plugin;
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    struct config {
 | 
					    struct config {
 | 
				
			||||||
        typedef ast_manager              value_manager;
 | 
					        typedef ast_manager              value_manager;
 | 
				
			||||||
| 
						 | 
					@ -2005,6 +2006,7 @@ public:
 | 
				
			||||||
    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())));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1126,6 +1132,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) {
 | 
				
			||||||
 | 
					        smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 1);
 | 
				
			||||||
        strm << "(assert\n ";
 | 
					        strm << "(assert\n ";
 | 
				
			||||||
        smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
 | 
					 | 
				
			||||||
        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) {        
 | 
				
			||||||
 | 
					        smt_printer p(strm, m, ql, rn, m_logic, false, true, m_simplify_implies, 1);
 | 
				
			||||||
        strm << "(assert\n ";
 | 
					        strm << "(assert\n ";
 | 
				
			||||||
        smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, 0);
 | 
					 | 
				
			||||||
        p(m_assumptions_star[i].get());
 | 
					        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)) {
 | 
				
			||||||
 | 
					        if (!m.is_true(n)) {
 | 
				
			||||||
            strm << "(assert\n ";
 | 
					            strm << "(assert\n ";
 | 
				
			||||||
            p(n);
 | 
					            p(n);
 | 
				
			||||||
            strm << ")\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_ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -422,8 +422,55 @@ static sort * get_type(ast_manager & m, family_id datatype_fid, sort * source_da
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func_decl * datatype_decl_plugin::mk_update_field(
 | 
				
			||||||
 | 
					    unsigned num_parameters, parameter const * parameters, 
 | 
				
			||||||
 | 
					    unsigned arity, sort * const * domain, sort * range) {
 | 
				
			||||||
 | 
					    decl_kind k = OP_DT_UPDATE_FIELD;
 | 
				
			||||||
 | 
					    ast_manager& m = *m_manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (num_parameters != 1 || !parameters[0].is_ast()) {
 | 
				
			||||||
 | 
					        m.raise_exception("invalid parameters for datatype field update");
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (arity != 2) {
 | 
				
			||||||
 | 
					        m.raise_exception("invalid number of arguments for datatype field update");
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    func_decl* acc = 0;
 | 
				
			||||||
 | 
					    if (is_func_decl(parameters[0].get_ast())) {
 | 
				
			||||||
 | 
					        acc = to_func_decl(parameters[0].get_ast());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (acc && !get_util().is_accessor(acc)) {
 | 
				
			||||||
 | 
					        acc = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!acc) {
 | 
				
			||||||
 | 
					        m.raise_exception("datatype field update requires a datatype accessor as the second argument");
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sort* dom = acc->get_domain(0);
 | 
				
			||||||
 | 
					    sort* rng = acc->get_range();
 | 
				
			||||||
 | 
					    if (dom != domain[0]) {
 | 
				
			||||||
 | 
					        m.raise_exception("first argument to field update should be a data-type");
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (rng != domain[1]) {
 | 
				
			||||||
 | 
					        std::ostringstream buffer;
 | 
				
			||||||
 | 
					        buffer << "second argument to field update should be " << mk_ismt2_pp(rng, m) 
 | 
				
			||||||
 | 
					               << " instead of " << mk_ismt2_pp(domain[1], m);
 | 
				
			||||||
 | 
					        m.raise_exception(buffer.str().c_str());
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    range = domain[0];
 | 
				
			||||||
 | 
					    func_decl_info info(m_family_id, k, num_parameters, parameters);
 | 
				
			||||||
 | 
					    return m.mk_func_decl(symbol("update_field"), arity, domain, range, info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, 
 | 
					func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, 
 | 
				
			||||||
                                             unsigned arity, sort * const * domain, sort * range) {
 | 
					                                             unsigned arity, sort * const * domain, sort * range) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (k == OP_DT_UPDATE_FIELD) {
 | 
				
			||||||
 | 
					        return mk_update_field(num_parameters, parameters, arity, domain, range);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (num_parameters < 2 || !parameters[0].is_ast() || !is_sort(parameters[0].get_ast())) {
 | 
					    if (num_parameters < 2 || !parameters[0].is_ast() || !is_sort(parameters[0].get_ast())) {
 | 
				
			||||||
        m_manager->raise_exception("invalid parameters for datatype operator");
 | 
					        m_manager->raise_exception("invalid parameters for datatype operator");
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
| 
						 | 
					@ -521,6 +568,9 @@ func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_paramet
 | 
				
			||||||
            return m_manager->mk_func_decl(a_name, arity, domain, a_type, info);
 | 
					            return m_manager->mk_func_decl(a_name, arity, domain, a_type, info);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case OP_DT_UPDATE_FIELD: 
 | 
				
			||||||
 | 
					        UNREACHABLE();
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        m_manager->raise_exception("invalid datatype operator kind");
 | 
					        m_manager->raise_exception("invalid datatype operator kind");
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
| 
						 | 
					@ -672,6 +722,13 @@ bool datatype_decl_plugin::is_value(app * e) const {
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void datatype_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const & logic) {
 | 
				
			||||||
 | 
					    if (logic == symbol::null) {
 | 
				
			||||||
 | 
					        op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
datatype_util::datatype_util(ast_manager & m):
 | 
					datatype_util::datatype_util(ast_manager & m):
 | 
				
			||||||
    m_manager(m),
 | 
					    m_manager(m),
 | 
				
			||||||
    m_family_id(m.mk_family_id("datatype")),
 | 
					    m_family_id(m.mk_family_id("datatype")),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@ enum datatype_op_kind {
 | 
				
			||||||
    OP_DT_CONSTRUCTOR,
 | 
					    OP_DT_CONSTRUCTOR,
 | 
				
			||||||
    OP_DT_RECOGNISER,
 | 
					    OP_DT_RECOGNISER,
 | 
				
			||||||
    OP_DT_ACCESSOR,
 | 
					    OP_DT_ACCESSOR,
 | 
				
			||||||
 | 
					    OP_DT_UPDATE_FIELD,
 | 
				
			||||||
    LAST_DT_OP
 | 
					    LAST_DT_OP
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,8 +150,14 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual bool is_unique_value(app * e) const { return is_value(e); }
 | 
					    virtual bool is_unique_value(app * e) const { return is_value(e); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual void get_op_names(svector<builtin_name> & op_names, symbol const & logic);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    bool is_value_visit(expr * arg, ptr_buffer<app> & todo) const;
 | 
					    bool is_value_visit(expr * arg, ptr_buffer<app> & todo) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    func_decl * mk_update_field(
 | 
				
			||||||
 | 
					        unsigned num_parameters, parameter const * parameters, 
 | 
				
			||||||
 | 
					        unsigned arity, sort * const * domain, sort * range);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class datatype_util {
 | 
					class datatype_util {
 | 
				
			||||||
| 
						 | 
					@ -181,9 +188,11 @@ public:
 | 
				
			||||||
    bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); }
 | 
					    bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); }
 | 
				
			||||||
    bool is_recognizer(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); }
 | 
					    bool is_recognizer(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); }
 | 
				
			||||||
    bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); }
 | 
					    bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); }
 | 
				
			||||||
 | 
					    bool is_update_field(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_UPDATE_FIELD); }
 | 
				
			||||||
    bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); }
 | 
					    bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); }
 | 
				
			||||||
    bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); }
 | 
					    bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); }
 | 
				
			||||||
    bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); }
 | 
					    bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); }
 | 
				
			||||||
 | 
					    bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); }
 | 
				
			||||||
    ptr_vector<func_decl> const * get_datatype_constructors(sort * ty);
 | 
					    ptr_vector<func_decl> const * get_datatype_constructors(sort * ty);
 | 
				
			||||||
    unsigned get_datatype_num_constructors(sort * ty) { return get_datatype_constructors(ty)->size(); }
 | 
					    unsigned get_datatype_num_constructors(sort * ty) { return get_datatype_constructors(ty)->size(); }
 | 
				
			||||||
    unsigned get_constructor_idx(func_decl * f) const { SASSERT(is_constructor(f)); return f->get_parameter(1).get_int(); }
 | 
					    unsigned get_constructor_idx(func_decl * f) const { SASSERT(is_constructor(f)); return f->get_parameter(1).get_int(); }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,10 @@ public:
 | 
				
			||||||
    void erase(expr * k);
 | 
					    void erase(expr * k);
 | 
				
			||||||
    void reset();
 | 
					    void reset();
 | 
				
			||||||
    void flush();
 | 
					    void flush();
 | 
				
			||||||
 | 
					    void set_store_proofs(bool f) { 
 | 
				
			||||||
 | 
					        if (m_store_proofs != f) flush();
 | 
				
			||||||
 | 
					        m_store_proofs = f; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2155,15 +2155,15 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg
 | 
				
			||||||
    SASSERT(f->get_num_parameters() == 1);
 | 
					    SASSERT(f->get_num_parameters() == 1);
 | 
				
			||||||
    SASSERT(f->get_parameter(0).is_int());
 | 
					    SASSERT(f->get_parameter(0).is_int());
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    unsigned ebits = m_util.get_ebits(f->get_range());
 | 
					    //unsigned ebits = m_util.get_ebits(f->get_range());
 | 
				
			||||||
    unsigned sbits = m_util.get_sbits(f->get_range());
 | 
					    //unsigned sbits = m_util.get_sbits(f->get_range());
 | 
				
			||||||
    int width = f->get_parameter(0).get_int();
 | 
					    //int width = f->get_parameter(0).get_int();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expr * rm = args[0];
 | 
					    //expr * rm = args[0];
 | 
				
			||||||
    expr * x = args[1];
 | 
					    //expr * x = args[1];
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    expr * sgn, *s, *e;
 | 
					    //expr * sgn, *s, *e;
 | 
				
			||||||
    split(x, sgn, s, e);
 | 
					    //split(x, sgn, s, e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NOT_IMPLEMENTED_YET();
 | 
					    NOT_IMPLEMENTED_YET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2173,15 +2173,15 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg
 | 
				
			||||||
    SASSERT(f->get_num_parameters() == 1);
 | 
					    SASSERT(f->get_num_parameters() == 1);
 | 
				
			||||||
    SASSERT(f->get_parameter(0).is_int());
 | 
					    SASSERT(f->get_parameter(0).is_int());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsigned ebits = m_util.get_ebits(f->get_range());
 | 
					    //unsigned ebits = m_util.get_ebits(f->get_range());
 | 
				
			||||||
    unsigned sbits = m_util.get_sbits(f->get_range());
 | 
					    //unsigned sbits = m_util.get_sbits(f->get_range());
 | 
				
			||||||
    int width = f->get_parameter(0).get_int();
 | 
					    //int width = f->get_parameter(0).get_int();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expr * rm = args[0];
 | 
					    //expr * rm = args[0];
 | 
				
			||||||
    expr * x = args[1];
 | 
					    //expr * x = args[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expr * sgn, *s, *e;
 | 
					    //expr * sgn, *s, *e;
 | 
				
			||||||
    split(x, sgn, s, e);
 | 
					    //split(x, sgn, s, e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NOT_IMPLEMENTED_YET();
 | 
					    NOT_IMPLEMENTED_YET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2189,15 +2189,15 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg
 | 
				
			||||||
void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
 | 
					void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
 | 
				
			||||||
    SASSERT(num == 1);
 | 
					    SASSERT(num == 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsigned ebits = m_util.get_ebits(f->get_range());
 | 
					    //unsigned ebits = m_util.get_ebits(f->get_range());
 | 
				
			||||||
    unsigned sbits = m_util.get_sbits(f->get_range());
 | 
					    //unsigned sbits = m_util.get_sbits(f->get_range());
 | 
				
			||||||
    int width = f->get_parameter(0).get_int();
 | 
					    //int width = f->get_parameter(0).get_int();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expr * rm = args[0];
 | 
					    //expr * rm = args[0];
 | 
				
			||||||
    expr * x = args[1];
 | 
					    //expr * x = args[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expr * sgn, *s, *e;
 | 
					    //expr * sgn, *s, *e;
 | 
				
			||||||
    split(x, sgn, s, e);
 | 
					    //split(x, sgn, s, e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NOT_IMPLEMENTED_YET();
 | 
					    NOT_IMPLEMENTED_YET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,9 +255,9 @@ bool macro_manager::macro_expander::get_subst(expr * _n, expr_ref & r, proof_ref
 | 
				
			||||||
    app * n = to_app(_n);
 | 
					    app * n = to_app(_n);
 | 
				
			||||||
    quantifier * q = 0;
 | 
					    quantifier * q = 0;
 | 
				
			||||||
    func_decl * d  = n->get_decl(); 
 | 
					    func_decl * d  = n->get_decl(); 
 | 
				
			||||||
    TRACE("macro_manager_bug", tout << "trying to expand:\n" << mk_pp(n, m_manager) << "\nd:\n" << d->get_name() << "\n";);
 | 
					    TRACE("macro_manager_bug", tout << "trying to expand:\n" << mk_pp(n, m) << "\nd:\n" << d->get_name() << "\n";);
 | 
				
			||||||
    if (m_macro_manager.m_decl2macro.find(d, q)) {
 | 
					    if (m_macro_manager.m_decl2macro.find(d, q)) {
 | 
				
			||||||
        TRACE("macro_manager", tout << "expanding: " << mk_pp(n, m_manager) << "\n";);
 | 
					        TRACE("macro_manager", tout << "expanding: " << mk_pp(n, m) << "\n";);
 | 
				
			||||||
        app * head = 0;
 | 
					        app * head = 0;
 | 
				
			||||||
        expr * def = 0;
 | 
					        expr * def = 0;
 | 
				
			||||||
        m_macro_manager.get_head_def(q, d, head, def);
 | 
					        m_macro_manager.get_head_def(q, d, head, def);
 | 
				
			||||||
| 
						 | 
					@ -272,17 +272,17 @@ bool macro_manager::macro_expander::get_subst(expr * _n, expr_ref & r, proof_ref
 | 
				
			||||||
            SASSERT(subst_args[nidx] == 0);
 | 
					            SASSERT(subst_args[nidx] == 0);
 | 
				
			||||||
            subst_args[nidx] = n->get_arg(i);
 | 
					            subst_args[nidx] = n->get_arg(i);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        var_subst s(m_manager);
 | 
					        var_subst s(m);
 | 
				
			||||||
        s(def, num, subst_args.c_ptr(), r);
 | 
					        s(def, num, subst_args.c_ptr(), r);
 | 
				
			||||||
        if (m_manager.proofs_enabled()) {
 | 
					        if (m.proofs_enabled()) {
 | 
				
			||||||
            expr_ref instance(m_manager);
 | 
					            expr_ref instance(m);
 | 
				
			||||||
            s(q->get_expr(), num, subst_args.c_ptr(), instance);
 | 
					            s(q->get_expr(), num, subst_args.c_ptr(), instance);
 | 
				
			||||||
            proof * qi_pr = m_manager.mk_quant_inst(m_manager.mk_or(m_manager.mk_not(q), instance), num, subst_args.c_ptr());
 | 
					            proof * qi_pr = m.mk_quant_inst(m.mk_or(m.mk_not(q), instance), num, subst_args.c_ptr());
 | 
				
			||||||
            proof * q_pr  = 0;
 | 
					            proof * q_pr  = 0;
 | 
				
			||||||
            m_macro_manager.m_decl2macro_pr.find(d, q_pr);
 | 
					            m_macro_manager.m_decl2macro_pr.find(d, q_pr);
 | 
				
			||||||
            SASSERT(q_pr != 0);
 | 
					            SASSERT(q_pr != 0);
 | 
				
			||||||
            proof * prs[2] = { qi_pr, q_pr };
 | 
					            proof * prs[2] = { qi_pr, q_pr };
 | 
				
			||||||
            p = m_manager.mk_unit_resolution(2, prs);
 | 
					            p = m.mk_unit_resolution(2, prs);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            p = 0;
 | 
					            p = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,7 +116,7 @@ void pattern_inference::collect::operator()(expr * n, unsigned num_bindings) {
 | 
				
			||||||
        n              = e.m_node;
 | 
					        n              = e.m_node;
 | 
				
			||||||
        unsigned delta = e.m_delta;
 | 
					        unsigned delta = e.m_delta;
 | 
				
			||||||
        TRACE("collect", tout << "processing: " << n->get_id() << " " << delta << " kind: " << n->get_kind() << "\n";);
 | 
					        TRACE("collect", tout << "processing: " << n->get_id() << " " << delta << " kind: " << n->get_kind() << "\n";);
 | 
				
			||||||
        TRACE("collect_info", tout << mk_pp(n, m_manager) << "\n";);
 | 
					        TRACE("collect_info", tout << mk_pp(n, m) << "\n";);
 | 
				
			||||||
        if (visit_children(n, delta)) {
 | 
					        if (visit_children(n, delta)) {
 | 
				
			||||||
            m_todo.pop_back();
 | 
					            m_todo.pop_back();
 | 
				
			||||||
            save_candidate(n, delta);
 | 
					            save_candidate(n, delta);
 | 
				
			||||||
| 
						 | 
					@ -170,9 +170,9 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) {
 | 
				
			||||||
                free_vars.insert(idx);
 | 
					                free_vars.insert(idx);
 | 
				
			||||||
            info * i = 0;
 | 
					            info * i = 0;
 | 
				
			||||||
            if (delta == 0)
 | 
					            if (delta == 0)
 | 
				
			||||||
                i = alloc(info, m_manager, n, free_vars, 1);
 | 
					                i = alloc(info, m, n, free_vars, 1);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                i = alloc(info, m_manager, m_manager.mk_var(idx, to_var(n)->get_sort()), free_vars, 1);
 | 
					                i = alloc(info, m, m.mk_var(idx, to_var(n)->get_sort()), free_vars, 1);
 | 
				
			||||||
            save(n, delta, i);
 | 
					            save(n, delta, i);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
| 
						 | 
					@ -189,7 +189,7 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (c->get_num_args() == 0) {
 | 
					        if (c->get_num_args() == 0) {
 | 
				
			||||||
            save(n, delta, alloc(info, m_manager, n, uint_set(), 1));
 | 
					            save(n, delta, alloc(info, m, n, uint_set(), 1));
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -219,10 +219,10 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) {
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        app * new_node = 0;
 | 
					        app * new_node = 0;
 | 
				
			||||||
        if (changed)
 | 
					        if (changed)
 | 
				
			||||||
            new_node = m_manager.mk_app(decl, buffer.size(), buffer.c_ptr());
 | 
					            new_node = m.mk_app(decl, buffer.size(), buffer.c_ptr());
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            new_node = to_app(n);
 | 
					            new_node = to_app(n);
 | 
				
			||||||
        save(n, delta, alloc(info, m_manager, new_node, free_vars, size));
 | 
					        save(n, delta, alloc(info, m, new_node, free_vars, size));
 | 
				
			||||||
        // Remark: arithmetic patterns are only used if they are nested inside other terms.
 | 
					        // Remark: arithmetic patterns are only used if they are nested inside other terms.
 | 
				
			||||||
        // That is, we never consider x + 1 as pattern. On the other hand, f(x+1) can be a pattern
 | 
					        // That is, we never consider x + 1 as pattern. On the other hand, f(x+1) can be a pattern
 | 
				
			||||||
        // if arithmetic is not in the forbidden list.
 | 
					        // if arithmetic is not in the forbidden list.
 | 
				
			||||||
| 
						 | 
					@ -235,7 +235,7 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) {
 | 
				
			||||||
        decl_kind k   = c->get_decl_kind();
 | 
					        decl_kind k   = c->get_decl_kind();
 | 
				
			||||||
        if (!free_vars.empty() && 
 | 
					        if (!free_vars.empty() && 
 | 
				
			||||||
            (fid != m_afid || (fid == m_afid && !m_owner.m_nested_arith_only && (k == OP_DIV || k == OP_IDIV || k == OP_MOD || k == OP_REM || k == OP_MUL)))) {
 | 
					            (fid != m_afid || (fid == m_afid && !m_owner.m_nested_arith_only && (k == OP_DIV || k == OP_IDIV || k == OP_MOD || k == OP_REM || k == OP_MUL)))) {
 | 
				
			||||||
            TRACE("pattern_inference", tout << "potential candidate: \n" << mk_pp(new_node, m_manager) << "\n";);
 | 
					            TRACE("pattern_inference", tout << "potential candidate: \n" << mk_pp(new_node, m) << "\n";);
 | 
				
			||||||
            m_owner.add_candidate(new_node, free_vars, size);
 | 
					            m_owner.add_candidate(new_node, free_vars, size);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -338,7 +338,7 @@ bool pattern_inference::contains_subpattern::operator()(expr * n) {
 | 
				
			||||||
                    uint_set const & s2 = e->get_data().m_value.m_free_vars;
 | 
					                    uint_set const & s2 = e->get_data().m_value.m_free_vars;
 | 
				
			||||||
                    SASSERT(s2.subset_of(s1));
 | 
					                    SASSERT(s2.subset_of(s1));
 | 
				
			||||||
                    if (s1 == s2) {
 | 
					                    if (s1 == s2) {
 | 
				
			||||||
                        TRACE("pattern_inference", tout << mk_pp(n, m_owner.m_manager) << "\nis bigger than\n" << mk_pp(to_app(curr), m_owner.m_manager) << "\n";);
 | 
					                        TRACE("pattern_inference", tout << mk_pp(n, m_owner.m) << "\nis bigger than\n" << mk_pp(to_app(curr), m_owner.m) << "\n";);
 | 
				
			||||||
                        return true;
 | 
					                        return true;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -411,7 +411,7 @@ void pattern_inference::candidates2unary_patterns(ptr_vector<app> const & candid
 | 
				
			||||||
        expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate);
 | 
					        expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate);
 | 
				
			||||||
        info const & i = e->get_data().m_value;
 | 
					        info const & i = e->get_data().m_value;
 | 
				
			||||||
        if (i.m_free_vars.num_elems() == m_num_bindings) {
 | 
					        if (i.m_free_vars.num_elems() == m_num_bindings) {
 | 
				
			||||||
            app * new_pattern = m_manager.mk_pattern(candidate);
 | 
					            app * new_pattern = m.mk_pattern(candidate);
 | 
				
			||||||
            result.push_back(new_pattern);
 | 
					            result.push_back(new_pattern);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
| 
						 | 
					@ -435,7 +435,7 @@ void pattern_inference::candidates2multi_patterns(unsigned max_num_patterns,
 | 
				
			||||||
    for (unsigned j = 0; j < m_pre_patterns.size(); j++) {
 | 
					    for (unsigned j = 0; j < m_pre_patterns.size(); j++) {
 | 
				
			||||||
        pre_pattern * curr = m_pre_patterns[j];
 | 
					        pre_pattern * curr = m_pre_patterns[j];
 | 
				
			||||||
        if (curr->m_free_vars.num_elems() == m_num_bindings) {
 | 
					        if (curr->m_free_vars.num_elems() == m_num_bindings) {
 | 
				
			||||||
            app * new_pattern = m_manager.mk_pattern(curr->m_exprs.size(), curr->m_exprs.c_ptr());
 | 
					            app * new_pattern = m.mk_pattern(curr->m_exprs.size(), curr->m_exprs.c_ptr());
 | 
				
			||||||
            result.push_back(new_pattern);
 | 
					            result.push_back(new_pattern);
 | 
				
			||||||
            if (result.size() >= max_num_patterns)
 | 
					            if (result.size() >= max_num_patterns)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
| 
						 | 
					@ -489,7 +489,7 @@ bool pattern_inference::is_forbidden(app * n) const {
 | 
				
			||||||
    // occur outside of the quantifier. That is, Z3 will never match this kind of 
 | 
					    // occur outside of the quantifier. That is, Z3 will never match this kind of 
 | 
				
			||||||
    // pattern.
 | 
					    // pattern.
 | 
				
			||||||
    if (m_params.m_pi_avoid_skolems && decl->is_skolem()) {
 | 
					    if (m_params.m_pi_avoid_skolems && decl->is_skolem()) {
 | 
				
			||||||
        CTRACE("pattern_inference_skolem", decl->is_skolem(), tout << "ignoring: " << mk_pp(n, m_manager) << "\n";);
 | 
					        CTRACE("pattern_inference_skolem", decl->is_skolem(), tout << "ignoring: " << mk_pp(n, m) << "\n";);
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (is_forbidden(decl))
 | 
					    if (is_forbidden(decl))
 | 
				
			||||||
| 
						 | 
					@ -509,8 +509,8 @@ bool pattern_inference::has_preferred_patterns(ptr_vector<app> & candidate_patte
 | 
				
			||||||
            expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate);
 | 
					            expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate);
 | 
				
			||||||
            info const & i = e->get_data().m_value;
 | 
					            info const & i = e->get_data().m_value;
 | 
				
			||||||
            if (i.m_free_vars.num_elems() == m_num_bindings) {
 | 
					            if (i.m_free_vars.num_elems() == m_num_bindings) {
 | 
				
			||||||
                TRACE("pattern_inference", tout << "found preferred pattern:\n" << mk_pp(candidate, m_manager) << "\n";);
 | 
					                TRACE("pattern_inference", tout << "found preferred pattern:\n" << mk_pp(candidate, m) << "\n";);
 | 
				
			||||||
                app * p = m_manager.mk_pattern(candidate);
 | 
					                app * p = m.mk_pattern(candidate);
 | 
				
			||||||
                result.push_back(p);
 | 
					                result.push_back(p);
 | 
				
			||||||
                found = true;
 | 
					                found = true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -531,11 +531,11 @@ void pattern_inference::mk_patterns(unsigned num_bindings,
 | 
				
			||||||
    m_collect(n, num_bindings);
 | 
					    m_collect(n, num_bindings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TRACE("pattern_inference", 
 | 
					    TRACE("pattern_inference", 
 | 
				
			||||||
          tout << mk_pp(n, m_manager);
 | 
					          tout << mk_pp(n, m);
 | 
				
			||||||
          tout << "\ncandidates:\n";
 | 
					          tout << "\ncandidates:\n";
 | 
				
			||||||
          unsigned num = m_candidates.size();
 | 
					          unsigned num = m_candidates.size();
 | 
				
			||||||
          for (unsigned i = 0; i < num; i++) {
 | 
					          for (unsigned i = 0; i < num; i++) {
 | 
				
			||||||
              tout << mk_pp(m_candidates.get(i), m_manager) << "\n";
 | 
					              tout << mk_pp(m_candidates.get(i), m) << "\n";
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!m_candidates.empty()) {
 | 
					    if (!m_candidates.empty()) {
 | 
				
			||||||
| 
						 | 
					@ -543,7 +543,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings,
 | 
				
			||||||
        filter_looping_patterns(m_tmp1);
 | 
					        filter_looping_patterns(m_tmp1);
 | 
				
			||||||
        TRACE("pattern_inference",
 | 
					        TRACE("pattern_inference",
 | 
				
			||||||
              tout << "candidates after removing looping-patterns:\n";
 | 
					              tout << "candidates after removing looping-patterns:\n";
 | 
				
			||||||
              dump_app_vector(tout, m_tmp1, m_manager););
 | 
					              dump_app_vector(tout, m_tmp1, m););
 | 
				
			||||||
        SASSERT(!m_tmp1.empty());
 | 
					        SASSERT(!m_tmp1.empty());
 | 
				
			||||||
        if (!has_preferred_patterns(m_tmp1, result)) {
 | 
					        if (!has_preferred_patterns(m_tmp1, result)) {
 | 
				
			||||||
            // continue if there are no preferred patterns
 | 
					            // continue if there are no preferred patterns
 | 
				
			||||||
| 
						 | 
					@ -552,7 +552,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings,
 | 
				
			||||||
            SASSERT(!m_tmp2.empty());
 | 
					            SASSERT(!m_tmp2.empty());
 | 
				
			||||||
            TRACE("pattern_inference",
 | 
					            TRACE("pattern_inference",
 | 
				
			||||||
                  tout << "candidates after removing bigger patterns:\n";
 | 
					                  tout << "candidates after removing bigger patterns:\n";
 | 
				
			||||||
                  dump_app_vector(tout, m_tmp2, m_manager););
 | 
					                  dump_app_vector(tout, m_tmp2, m););
 | 
				
			||||||
            m_tmp1.reset();
 | 
					            m_tmp1.reset();
 | 
				
			||||||
            candidates2unary_patterns(m_tmp2, m_tmp1, result);
 | 
					            candidates2unary_patterns(m_tmp2, m_tmp1, result);
 | 
				
			||||||
            unsigned num_extra_multi_patterns = m_params.m_pi_max_multi_patterns;
 | 
					            unsigned num_extra_multi_patterns = m_params.m_pi_max_multi_patterns;
 | 
				
			||||||
| 
						 | 
					@ -563,7 +563,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings,
 | 
				
			||||||
                std::stable_sort(m_tmp1.begin(), m_tmp1.end(), m_pattern_weight_lt);
 | 
					                std::stable_sort(m_tmp1.begin(), m_tmp1.end(), m_pattern_weight_lt);
 | 
				
			||||||
                TRACE("pattern_inference",
 | 
					                TRACE("pattern_inference",
 | 
				
			||||||
                      tout << "candidates after sorting:\n";
 | 
					                      tout << "candidates after sorting:\n";
 | 
				
			||||||
                      dump_app_vector(tout, m_tmp1, m_manager););
 | 
					                      dump_app_vector(tout, m_tmp1, m););
 | 
				
			||||||
                candidates2multi_patterns(num_extra_multi_patterns, m_tmp1, result);
 | 
					                candidates2multi_patterns(num_extra_multi_patterns, m_tmp1, result);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -577,7 +577,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings,
 | 
				
			||||||
#include"database.h" // defines g_pattern_database
 | 
					#include"database.h" // defines g_pattern_database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pattern_inference::reduce1_quantifier(quantifier * q) {
 | 
					void pattern_inference::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
    TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m_manager) << "\n";);
 | 
					    TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";);
 | 
				
			||||||
    if (!q->is_forall()) {
 | 
					    if (!q->is_forall()) {
 | 
				
			||||||
        simplifier::reduce1_quantifier(q);
 | 
					        simplifier::reduce1_quantifier(q);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -587,27 +587,27 @@ void pattern_inference::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (m_params.m_pi_use_database) {
 | 
					    if (m_params.m_pi_use_database) {
 | 
				
			||||||
        m_database.initialize(g_pattern_database);
 | 
					        m_database.initialize(g_pattern_database);
 | 
				
			||||||
        app_ref_vector new_patterns(m_manager);
 | 
					        app_ref_vector new_patterns(m);
 | 
				
			||||||
        unsigned new_weight;
 | 
					        unsigned new_weight;
 | 
				
			||||||
        if (m_database.match_quantifier(q, new_patterns, new_weight)) {
 | 
					        if (m_database.match_quantifier(q, new_patterns, new_weight)) {
 | 
				
			||||||
#ifdef Z3DEBUG
 | 
					#ifdef Z3DEBUG
 | 
				
			||||||
            for (unsigned i = 0; i < new_patterns.size(); i++) { SASSERT(is_well_sorted(m_manager, new_patterns.get(i))); }
 | 
					            for (unsigned i = 0; i < new_patterns.size(); i++) { SASSERT(is_well_sorted(m, new_patterns.get(i))); }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            quantifier_ref new_q(m_manager);
 | 
					            quantifier_ref new_q(m);
 | 
				
			||||||
            if (q->get_num_patterns() > 0) {
 | 
					            if (q->get_num_patterns() > 0) {
 | 
				
			||||||
                // just update the weight...
 | 
					                // just update the weight...
 | 
				
			||||||
                TRACE("pattern_inference", tout << "updating weight to: " << new_weight << "\n" << mk_pp(q, m_manager) << "\n";);
 | 
					                TRACE("pattern_inference", tout << "updating weight to: " << new_weight << "\n" << mk_pp(q, m) << "\n";);
 | 
				
			||||||
                new_q = m_manager.update_quantifier_weight(q, new_weight);
 | 
					                new_q = m.update_quantifier_weight(q, new_weight);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                quantifier_ref tmp(m_manager);
 | 
					                quantifier_ref tmp(m);
 | 
				
			||||||
                tmp   = m_manager.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), q->get_expr());
 | 
					                tmp   = m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), q->get_expr());
 | 
				
			||||||
                new_q = m_manager.update_quantifier_weight(tmp, new_weight); 
 | 
					                new_q = m.update_quantifier_weight(tmp, new_weight); 
 | 
				
			||||||
                TRACE("pattern_inference", tout << "found patterns in database, weight: " << new_weight << "\n" << mk_pp(new_q, m_manager) << "\n";);
 | 
					                TRACE("pattern_inference", tout << "found patterns in database, weight: " << new_weight << "\n" << mk_pp(new_q, m) << "\n";);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            proof * pr = 0;
 | 
					            proof * pr = 0;
 | 
				
			||||||
            if (m_manager.fine_grain_proofs())
 | 
					            if (m.fine_grain_proofs())
 | 
				
			||||||
                pr = m_manager.mk_rewrite(q, new_q);
 | 
					                pr = m.mk_rewrite(q, new_q);
 | 
				
			||||||
            cache_result(q, new_q, pr);
 | 
					            cache_result(q, new_q, pr);
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -635,7 +635,7 @@ void pattern_inference::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
        new_no_patterns.push_back(new_pattern);
 | 
					        new_no_patterns.push_back(new_pattern);
 | 
				
			||||||
    } 
 | 
					    } 
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    app_ref_buffer new_patterns(m_manager);
 | 
					    app_ref_buffer new_patterns(m);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (m_params.m_pi_arith == AP_CONSERVATIVE)
 | 
					    if (m_params.m_pi_arith == AP_CONSERVATIVE)
 | 
				
			||||||
        m_forbidden.push_back(m_afid);
 | 
					        m_forbidden.push_back(m_afid);
 | 
				
			||||||
| 
						 | 
					@ -677,26 +677,26 @@ void pattern_inference::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
                    warning_msg("using non nested arith. pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_NON_NESTED_ARITH_WEIGHT=<val>).", 
 | 
					                    warning_msg("using non nested arith. pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_NON_NESTED_ARITH_WEIGHT=<val>).", 
 | 
				
			||||||
                                q->get_qid().str().c_str(), weight);         
 | 
					                                q->get_qid().str().c_str(), weight);         
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                // verbose_stream() << mk_pp(q, m_manager) << "\n";
 | 
					                // verbose_stream() << mk_pp(q, m) << "\n";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    quantifier_ref new_q(m_manager);
 | 
					    quantifier_ref new_q(m);
 | 
				
			||||||
    new_q = m_manager.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_body);
 | 
					    new_q = m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_body);
 | 
				
			||||||
    if (weight != q->get_weight())
 | 
					    if (weight != q->get_weight())
 | 
				
			||||||
        new_q = m_manager.update_quantifier_weight(new_q, weight);
 | 
					        new_q = m.update_quantifier_weight(new_q, weight);
 | 
				
			||||||
    proof_ref pr(m_manager);
 | 
					    proof_ref pr(m);
 | 
				
			||||||
    if (m_manager.fine_grain_proofs()) {  
 | 
					    if (m.fine_grain_proofs()) {  
 | 
				
			||||||
        if (new_body_pr == 0)
 | 
					        if (new_body_pr == 0)
 | 
				
			||||||
            new_body_pr = m_manager.mk_reflexivity(new_body);
 | 
					            new_body_pr = m.mk_reflexivity(new_body);
 | 
				
			||||||
        pr = m_manager.mk_quant_intro(q, new_q, new_body_pr);
 | 
					        pr = m.mk_quant_intro(q, new_q, new_body_pr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (new_patterns.empty() && m_params.m_pi_pull_quantifiers) {
 | 
					    if (new_patterns.empty() && m_params.m_pi_pull_quantifiers) {
 | 
				
			||||||
        pull_quant pull(m_manager);
 | 
					        pull_quant pull(m);
 | 
				
			||||||
        expr_ref   new_expr(m_manager);
 | 
					        expr_ref   new_expr(m);
 | 
				
			||||||
        proof_ref  new_pr(m_manager);
 | 
					        proof_ref  new_pr(m);
 | 
				
			||||||
        pull(new_q, new_expr, new_pr);
 | 
					        pull(new_q, new_expr, new_pr);
 | 
				
			||||||
        quantifier * new_new_q = to_quantifier(new_expr);
 | 
					        quantifier * new_new_q = to_quantifier(new_expr);
 | 
				
			||||||
        if (new_new_q != new_q) {
 | 
					        if (new_new_q != new_q) {
 | 
				
			||||||
| 
						 | 
					@ -705,12 +705,12 @@ void pattern_inference::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
                if (m_params.m_pi_warnings) {
 | 
					                if (m_params.m_pi_warnings) {
 | 
				
			||||||
                    warning_msg("pulled nested quantifier to be able to find an useable pattern (quantifier id: %s)", q->get_qid().str().c_str());
 | 
					                    warning_msg("pulled nested quantifier to be able to find an useable pattern (quantifier id: %s)", q->get_qid().str().c_str());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                new_q = m_manager.update_quantifier(new_new_q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_new_q->get_expr());
 | 
					                new_q = m.update_quantifier(new_new_q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_new_q->get_expr());
 | 
				
			||||||
                if (m_manager.fine_grain_proofs()) {
 | 
					                if (m.fine_grain_proofs()) {
 | 
				
			||||||
                    pr = m_manager.mk_transitivity(pr, new_pr);
 | 
					                    pr = m.mk_transitivity(pr, new_pr);
 | 
				
			||||||
                    pr = m_manager.mk_transitivity(pr, m_manager.mk_quant_intro(new_new_q, new_q, m_manager.mk_reflexivity(new_q->get_expr())));
 | 
					                    pr = m.mk_transitivity(pr, m.mk_quant_intro(new_new_q, new_q, m.mk_reflexivity(new_q->get_expr())));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRACE("pattern_inference", tout << "pulled quantifier:\n" << mk_pp(new_q, m_manager) << "\n";);
 | 
					                TRACE("pattern_inference", tout << "pulled quantifier:\n" << mk_pp(new_q, m) << "\n";);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -719,7 +719,7 @@ void pattern_inference::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
        if (m_params.m_pi_warnings) {
 | 
					        if (m_params.m_pi_warnings) {
 | 
				
			||||||
            warning_msg("failed to find a pattern for quantifier (quantifier id: %s)", q->get_qid().str().c_str());
 | 
					            warning_msg("failed to find a pattern for quantifier (quantifier id: %s)", q->get_qid().str().c_str());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        TRACE("pi_failed", tout << mk_pp(q, m_manager) << "\n";);
 | 
					        TRACE("pi_failed", tout << mk_pp(q, m) << "\n";);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (new_patterns.empty() && new_body == q->get_expr()) {
 | 
					    if (new_patterns.empty() && new_body == q->get_expr()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ Revision History:
 | 
				
			||||||
   every instance of f(g(X)) is also an instance of f(X).
 | 
					   every instance of f(g(X)) is also an instance of f(X).
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
class smaller_pattern {
 | 
					class smaller_pattern {
 | 
				
			||||||
    ast_manager &    m_manager;
 | 
					    ast_manager &    m;
 | 
				
			||||||
    ptr_vector<expr> m_bindings;
 | 
					    ptr_vector<expr> m_bindings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    typedef std::pair<expr *, expr *> expr_pair;
 | 
					    typedef std::pair<expr *, expr *> expr_pair;
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ class smaller_pattern {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    smaller_pattern(ast_manager & m):
 | 
					    smaller_pattern(ast_manager & m):
 | 
				
			||||||
        m_manager(m) {
 | 
					        m(m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool operator()(unsigned num_bindings, expr * p1, expr * p2);
 | 
					    bool operator()(unsigned num_bindings, expr * p1, expr * p2);
 | 
				
			||||||
| 
						 | 
					@ -135,7 +135,7 @@ class pattern_inference : public simplifier {
 | 
				
			||||||
                m_node(n, m), m_free_vars(vars), m_size(sz) {}
 | 
					                m_node(n, m), m_free_vars(vars), m_size(sz) {}
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        ast_manager &            m_manager;
 | 
					        ast_manager &            m;
 | 
				
			||||||
        pattern_inference &      m_owner;
 | 
					        pattern_inference &      m_owner;
 | 
				
			||||||
        family_id                m_afid;
 | 
					        family_id                m_afid;
 | 
				
			||||||
        unsigned                 m_num_bindings;
 | 
					        unsigned                 m_num_bindings;
 | 
				
			||||||
| 
						 | 
					@ -150,7 +150,7 @@ class pattern_inference : public simplifier {
 | 
				
			||||||
        void save_candidate(expr * n, unsigned delta);
 | 
					        void save_candidate(expr * n, unsigned delta);
 | 
				
			||||||
        void reset();
 | 
					        void reset();
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        collect(ast_manager & m, pattern_inference & o):m_manager(m), m_owner(o), m_afid(m.mk_family_id("arith")) {}
 | 
					        collect(ast_manager & m, pattern_inference & o):m(m), m_owner(o), m_afid(m.mk_family_id("arith")) {}
 | 
				
			||||||
        void operator()(expr * n, unsigned num_bindings);
 | 
					        void operator()(expr * n, unsigned num_bindings);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										282
									
								
								src/ast/pb_decl_plugin.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								src/ast/pb_decl_plugin.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,282 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) 2013 Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pb_decl_plugin.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Cardinality Constraints plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Nikolaj Bjorner (nbjorner) 2013-05-11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Revision History:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pb_decl_plugin.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pb_decl_plugin::pb_decl_plugin():
 | 
				
			||||||
 | 
					    m_at_most_sym("at-most"),
 | 
				
			||||||
 | 
					    m_at_least_sym("at-least"),
 | 
				
			||||||
 | 
					    m_pble_sym("pble"),
 | 
				
			||||||
 | 
					    m_pbge_sym("pbge"),
 | 
				
			||||||
 | 
					    m_pbeq_sym("pbeq")
 | 
				
			||||||
 | 
					{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func_decl * pb_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, 
 | 
				
			||||||
 | 
					                                         unsigned arity, sort * const * domain, sort * range) {
 | 
				
			||||||
 | 
					    SASSERT(m_manager);
 | 
				
			||||||
 | 
					    ast_manager& m = *m_manager;
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < arity; ++i) {
 | 
				
			||||||
 | 
					        if (!m.is_bool(domain[i])) {
 | 
				
			||||||
 | 
					            m.raise_exception("invalid non-Boolean sort applied to 'at-most'");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    symbol sym;
 | 
				
			||||||
 | 
					    switch(k) {
 | 
				
			||||||
 | 
					    case OP_AT_LEAST_K: sym = m_at_least_sym; break;
 | 
				
			||||||
 | 
					    case OP_AT_MOST_K: sym = m_at_most_sym; break;
 | 
				
			||||||
 | 
					    case OP_PB_LE: sym = m_pble_sym; break;
 | 
				
			||||||
 | 
					    case OP_PB_GE: sym = m_pbge_sym; break;
 | 
				
			||||||
 | 
					    case OP_PB_EQ: sym = m_pbeq_sym; break;
 | 
				
			||||||
 | 
					    default: break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    switch(k) {
 | 
				
			||||||
 | 
					    case OP_AT_LEAST_K:
 | 
				
			||||||
 | 
					    case OP_AT_MOST_K: {
 | 
				
			||||||
 | 
					        if (num_parameters != 1 || !parameters[0].is_int() || parameters[0].get_int() < 0) {
 | 
				
			||||||
 | 
					            m.raise_exception("function expects one non-negative integer parameter");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        func_decl_info info(m_family_id, k, 1, parameters);
 | 
				
			||||||
 | 
					        return m.mk_func_decl(sym, arity, domain, m.mk_bool_sort(), info);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case OP_PB_GE:
 | 
				
			||||||
 | 
					    case OP_PB_LE: 
 | 
				
			||||||
 | 
					    case OP_PB_EQ: {
 | 
				
			||||||
 | 
					        if (num_parameters != 1 + arity) {
 | 
				
			||||||
 | 
					            m.raise_exception("function expects arity+1 rational parameters");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vector<parameter> params;
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < num_parameters; ++i) {
 | 
				
			||||||
 | 
					            parameter const& p = parameters[i];
 | 
				
			||||||
 | 
					            if (p.is_int()) {
 | 
				
			||||||
 | 
					                params.push_back(p);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (p.is_rational()) {
 | 
				
			||||||
 | 
					                // HACK: ast pretty printer does not work with rationals.
 | 
				
			||||||
 | 
					                rational r = p.get_rational();
 | 
				
			||||||
 | 
					                if (r.is_int32()) {
 | 
				
			||||||
 | 
					                    params.push_back(parameter(r.get_int32()));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    params.push_back(p);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                m.raise_exception("functions 'pble/pbge/pbeq' expect arity+1 integer parameters");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        func_decl_info info(m_family_id, k, num_parameters, params.c_ptr());
 | 
				
			||||||
 | 
					        return m.mk_func_decl(sym, arity, domain, m.mk_bool_sort(), info);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        UNREACHABLE();
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pb_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const & logic) {
 | 
				
			||||||
 | 
					    if (logic == symbol::null) {
 | 
				
			||||||
 | 
					        op_names.push_back(builtin_name(m_at_most_sym.bare_str(), OP_AT_MOST_K));
 | 
				
			||||||
 | 
					        op_names.push_back(builtin_name(m_at_least_sym.bare_str(), OP_AT_LEAST_K));
 | 
				
			||||||
 | 
					        op_names.push_back(builtin_name(m_pble_sym.bare_str(), OP_PB_LE));
 | 
				
			||||||
 | 
					        op_names.push_back(builtin_name(m_pbge_sym.bare_str(), OP_PB_GE));
 | 
				
			||||||
 | 
					        op_names.push_back(builtin_name(m_pbeq_sym.bare_str(), OP_PB_EQ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app * pb_util::mk_le(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k) {
 | 
				
			||||||
 | 
					    vector<parameter> params;
 | 
				
			||||||
 | 
					    params.push_back(parameter(k));
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					        params.push_back(parameter(coeffs[i]));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return m.mk_app(m_fid, OP_PB_LE, params.size(), params.c_ptr(), num_args, args, m.mk_bool_sort());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app * pb_util::mk_ge(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k) {
 | 
				
			||||||
 | 
					    vector<parameter> params;
 | 
				
			||||||
 | 
					    params.push_back(parameter(k));
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					        params.push_back(parameter(coeffs[i]));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return m.mk_app(m_fid, OP_PB_GE, params.size(), params.c_ptr(), num_args, args, m.mk_bool_sort());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app * pb_util::mk_eq(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k) {
 | 
				
			||||||
 | 
					    vector<parameter> params;
 | 
				
			||||||
 | 
					    params.push_back(parameter(k));
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					        params.push_back(parameter(coeffs[i]));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return m.mk_app(m_fid, OP_PB_EQ, params.size(), params.c_ptr(), num_args, args, m.mk_bool_sort());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ax + by < k
 | 
				
			||||||
 | 
					// <=>
 | 
				
			||||||
 | 
					// -ax - by >= -k + 1
 | 
				
			||||||
 | 
					// <=>
 | 
				
			||||||
 | 
					// a(1-x) + b(1-y) >= -k + a + b + 1
 | 
				
			||||||
 | 
					app * pb_util::mk_lt(unsigned num_args, rational const * _coeffs, expr * const * _args, rational const& _k) {
 | 
				
			||||||
 | 
					    vector<rational> coeffs;
 | 
				
			||||||
 | 
					    rational k(_k);
 | 
				
			||||||
 | 
					    expr_ref_vector args(m);
 | 
				
			||||||
 | 
					    expr* f;
 | 
				
			||||||
 | 
					    rational d(denominator(k));
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					        coeffs.push_back(_coeffs[i]);
 | 
				
			||||||
 | 
					        d = lcm(d, denominator(coeffs[i]));
 | 
				
			||||||
 | 
					        if (m.is_not(_args[i], f)) {
 | 
				
			||||||
 | 
					            args.push_back(f);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            args.push_back(m.mk_not(_args[i]));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!d.is_one()) {
 | 
				
			||||||
 | 
					        k *= d;
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					            coeffs[i] *= d;        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    k.neg();
 | 
				
			||||||
 | 
					    k += rational::one();
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					        k += coeffs[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return mk_ge(num_args, coeffs.c_ptr(), args.c_ptr(), k);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app * pb_util::mk_at_most_k(unsigned num_args, expr * const * args, unsigned k) {
 | 
				
			||||||
 | 
					    parameter param(k);
 | 
				
			||||||
 | 
					    return m.mk_app(m_fid, OP_AT_MOST_K, 1, ¶m, num_args, args, m.mk_bool_sort());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_at_most_k(func_decl *a) const {
 | 
				
			||||||
 | 
					    return is_decl_of(a, m_fid, OP_AT_MOST_K);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_at_most_k(expr *a, rational& k) const {
 | 
				
			||||||
 | 
					    if (is_at_most_k(a)) {
 | 
				
			||||||
 | 
					        k = get_k(a);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app * pb_util::mk_at_least_k(unsigned num_args, expr * const * args, unsigned k) {
 | 
				
			||||||
 | 
					    parameter param(k);
 | 
				
			||||||
 | 
					    return m.mk_app(m_fid, OP_AT_LEAST_K, 1, ¶m, num_args, args, m.mk_bool_sort());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_at_least_k(func_decl *a) const {
 | 
				
			||||||
 | 
					    return is_decl_of(a, m_fid, OP_AT_LEAST_K);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_at_least_k(expr *a, rational& k) const {
 | 
				
			||||||
 | 
					    if (is_at_least_k(a)) {
 | 
				
			||||||
 | 
					        k = get_k(a);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rational pb_util::get_k(func_decl *a) const {
 | 
				
			||||||
 | 
					    parameter const& p = a->get_parameter(0);
 | 
				
			||||||
 | 
					    if (is_at_most_k(a) || is_at_least_k(a)) {
 | 
				
			||||||
 | 
					        return to_rational(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        SASSERT(is_le(a) || is_ge(a) || is_eq(a));
 | 
				
			||||||
 | 
					        return to_rational(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_le(func_decl *a) const {
 | 
				
			||||||
 | 
					    return is_decl_of(a, m_fid, OP_PB_LE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_le(expr* a, rational& k) const {
 | 
				
			||||||
 | 
					    if (is_le(a)) {
 | 
				
			||||||
 | 
					        k = get_k(a);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_ge(func_decl *a) const {
 | 
				
			||||||
 | 
					    return is_decl_of(a, m_fid, OP_PB_GE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_ge(expr* a, rational& k) const {
 | 
				
			||||||
 | 
					    if (is_ge(a)) {
 | 
				
			||||||
 | 
					        k = get_k(a);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_eq(func_decl *a) const {
 | 
				
			||||||
 | 
					    return is_decl_of(a, m_fid, OP_PB_EQ);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::is_eq(expr* a, rational& k) const {
 | 
				
			||||||
 | 
					    if (is_eq(a)) {
 | 
				
			||||||
 | 
					        k = get_k(a);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rational pb_util::get_coeff(func_decl* a, unsigned index) const {
 | 
				
			||||||
 | 
					    if (is_at_most_k(a) || is_at_least_k(a)) {
 | 
				
			||||||
 | 
					        return rational::one();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SASSERT(is_le(a) || is_ge(a) || is_eq(a));
 | 
				
			||||||
 | 
					    SASSERT(1 + index < a->get_num_parameters());
 | 
				
			||||||
 | 
					    return to_rational(a->get_parameter(index + 1));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rational pb_util::to_rational(parameter const& p) const {
 | 
				
			||||||
 | 
					    if (p.is_int()) {
 | 
				
			||||||
 | 
					        return rational(p.get_int());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SASSERT(p.is_rational());
 | 
				
			||||||
 | 
					    return p.get_rational();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool pb_util::has_unit_coefficients(func_decl* f) const {
 | 
				
			||||||
 | 
					    if (is_at_most_k(f) || is_at_least_k(f)) return true;
 | 
				
			||||||
 | 
					    unsigned sz = f->get_arity();
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
 | 
					        if (!get_coeff(f, i).is_one()) return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										123
									
								
								src/ast/pb_decl_plugin.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/ast/pb_decl_plugin.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,123 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) 2013 Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pb_decl_plugin.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Pseudo-Boolean and Cardinality Constraints plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Nikolaj Bjorner (nbjorner) 2013-05-11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (at-most-k x1 .... x_n) means x1 + ... + x_n <= k
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					hence:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (not (at-most-k x1 .... x_n)) means x1 + ... + x_n >= k + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					#ifndef _PB_DECL_PLUGIN_H_
 | 
				
			||||||
 | 
					#define _PB_DECL_PLUGIN_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include"ast.h"
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					enum pb_op_kind {
 | 
				
			||||||
 | 
					    OP_AT_MOST_K,  // at most K Booleans are true.
 | 
				
			||||||
 | 
					    OP_AT_LEAST_K, // at least K Booleans are true.
 | 
				
			||||||
 | 
					    OP_PB_LE,      // pseudo-Boolean <= (generalizes at_most_k)
 | 
				
			||||||
 | 
					    OP_PB_GE,      // pseudo-Boolean >= 
 | 
				
			||||||
 | 
					    OP_PB_EQ,      // equality
 | 
				
			||||||
 | 
					    LAST_PB_OP
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class pb_decl_plugin : public decl_plugin {
 | 
				
			||||||
 | 
					    symbol m_at_most_sym;
 | 
				
			||||||
 | 
					    symbol m_at_least_sym;
 | 
				
			||||||
 | 
					    symbol m_pble_sym;
 | 
				
			||||||
 | 
					    symbol m_pbge_sym;
 | 
				
			||||||
 | 
					    symbol m_pbeq_sym;
 | 
				
			||||||
 | 
					    func_decl * mk_at_most(unsigned arity, unsigned k);
 | 
				
			||||||
 | 
					    func_decl * mk_at_least(unsigned arity, unsigned k);
 | 
				
			||||||
 | 
					    func_decl * mk_le(unsigned arity, rational const* coeffs, int k);
 | 
				
			||||||
 | 
					    func_decl * mk_ge(unsigned arity, rational const* coeffs, int k);
 | 
				
			||||||
 | 
					    func_decl * mk_eq(unsigned arity, rational const* coeffs, int k);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    pb_decl_plugin();
 | 
				
			||||||
 | 
					    virtual ~pb_decl_plugin() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
 | 
				
			||||||
 | 
					        UNREACHABLE();
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual decl_plugin * mk_fresh() {
 | 
				
			||||||
 | 
					        return alloc(pb_decl_plugin);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Contract for func_decl:
 | 
				
			||||||
 | 
					    //   parameters[0] - integer (at most k elements)
 | 
				
			||||||
 | 
					    //      all sorts are Booleans
 | 
				
			||||||
 | 
					    //    parameters[1] .. parameters[arity] - coefficients
 | 
				
			||||||
 | 
					    virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, 
 | 
				
			||||||
 | 
					                                     unsigned arity, sort * const * domain, sort * range);
 | 
				
			||||||
 | 
					    virtual void get_op_names(svector<builtin_name> & op_names, symbol const & logic);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class pb_util {
 | 
				
			||||||
 | 
					    ast_manager & m;
 | 
				
			||||||
 | 
					    family_id     m_fid;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    pb_util(ast_manager& m):m(m), m_fid(m.mk_family_id("pb")) {}
 | 
				
			||||||
 | 
					    ast_manager & get_manager() const { return m; }
 | 
				
			||||||
 | 
					    family_id get_family_id() const { return m_fid; }
 | 
				
			||||||
 | 
					    app * mk_at_most_k(unsigned num_args, expr * const * args, unsigned k);
 | 
				
			||||||
 | 
					    app * mk_at_least_k(unsigned num_args, expr * const * args, unsigned k);
 | 
				
			||||||
 | 
					    app * mk_le(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
 | 
				
			||||||
 | 
					    app * mk_ge(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
 | 
				
			||||||
 | 
					    app * mk_eq(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
 | 
				
			||||||
 | 
					    app * mk_lt(unsigned num_args, rational const * coeffs, expr * const * args, rational const& k);
 | 
				
			||||||
 | 
					    bool is_at_most_k(func_decl *a) const;
 | 
				
			||||||
 | 
					    bool is_at_most_k(expr *a) const { return is_app(a) && is_at_most_k(to_app(a)->get_decl()); }
 | 
				
			||||||
 | 
					    bool is_at_most_k(expr *a, rational& k) const;
 | 
				
			||||||
 | 
					    bool is_at_least_k(func_decl *a) const;
 | 
				
			||||||
 | 
					    bool is_at_least_k(expr *a) const { return is_app(a) && is_at_least_k(to_app(a)->get_decl()); }
 | 
				
			||||||
 | 
					    bool is_at_least_k(expr *a, rational& k) const;
 | 
				
			||||||
 | 
					    rational get_k(func_decl *a) const;
 | 
				
			||||||
 | 
					    rational get_k(expr *a) const { return get_k(to_app(a)->get_decl()); }
 | 
				
			||||||
 | 
					    bool is_le(func_decl *a) const;
 | 
				
			||||||
 | 
					    bool is_le(expr *a) const { return is_app(a) && is_le(to_app(a)->get_decl()); }
 | 
				
			||||||
 | 
					    bool is_le(expr* a, rational& k) const;
 | 
				
			||||||
 | 
					    bool is_ge(func_decl* a) const;
 | 
				
			||||||
 | 
					    bool is_ge(expr* a) const { return is_app(a) && is_ge(to_app(a)->get_decl()); }
 | 
				
			||||||
 | 
					    bool is_ge(expr* a, rational& k) const;
 | 
				
			||||||
 | 
					    rational get_coeff(expr* a, unsigned index) const { return get_coeff(to_app(a)->get_decl(), index); }
 | 
				
			||||||
 | 
					    rational get_coeff(func_decl* a, unsigned index) const; 
 | 
				
			||||||
 | 
					    bool has_unit_coefficients(func_decl* f) const;
 | 
				
			||||||
 | 
					    bool has_unit_coefficients(expr* f) const { return is_app(f) && has_unit_coefficients(to_app(f)->get_decl()); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_eq(func_decl* f) const;
 | 
				
			||||||
 | 
					    bool is_eq(expr* e) const { return is_app(e) && is_eq(to_app(e)->get_decl()); }
 | 
				
			||||||
 | 
					    bool is_eq(expr* e, rational& k) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    rational to_rational(parameter const& p) const;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _PB_DECL_PLUGIN_H_ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@ Revision History:
 | 
				
			||||||
#include"dl_decl_plugin.h"
 | 
					#include"dl_decl_plugin.h"
 | 
				
			||||||
#include"seq_decl_plugin.h"
 | 
					#include"seq_decl_plugin.h"
 | 
				
			||||||
#include"float_decl_plugin.h"
 | 
					#include"float_decl_plugin.h"
 | 
				
			||||||
 | 
					#include"pb_decl_plugin.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void reg_decl_plugins(ast_manager & m) {
 | 
					void reg_decl_plugins(ast_manager & m) {
 | 
				
			||||||
    if (!m.get_plugin(m.mk_family_id(symbol("arith")))) {
 | 
					    if (!m.get_plugin(m.mk_family_id(symbol("arith")))) {
 | 
				
			||||||
| 
						 | 
					@ -48,4 +49,7 @@ void reg_decl_plugins(ast_manager & m) {
 | 
				
			||||||
    if (!m.get_plugin(m.mk_family_id(symbol("float")))) {
 | 
					    if (!m.get_plugin(m.mk_family_id(symbol("float")))) {
 | 
				
			||||||
        m.register_plugin(symbol("float"), alloc(float_decl_plugin));
 | 
					        m.register_plugin(symbol("float"), alloc(float_decl_plugin));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (!m.get_plugin(m.mk_family_id(symbol("pb")))) {
 | 
				
			||||||
 | 
					        m.register_plugin(symbol("pb"), alloc(pb_decl_plugin));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,12 +18,9 @@ Revision History:
 | 
				
			||||||
--*/
 | 
					--*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ast_counter.h"
 | 
					#include "ast_counter.h"
 | 
				
			||||||
#include "var_subst.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void counter::update(unsigned el, int delta) {
 | 
					void counter::update(unsigned el, int delta) {
 | 
				
			||||||
    int & counter = get(el);
 | 
					    int & counter = get(el);
 | 
				
			||||||
    SASSERT(!m_stay_non_negative || counter>=0);
 | 
					 | 
				
			||||||
    SASSERT(!m_stay_non_negative || static_cast<int>(counter)>=-delta);
 | 
					 | 
				
			||||||
    counter += delta;
 | 
					    counter += delta;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,16 +89,14 @@ int counter::get_max_counter_value() const {
 | 
				
			||||||
void var_counter::count_vars(ast_manager & m, const app * pred, int coef) {
 | 
					void var_counter::count_vars(ast_manager & m, const app * pred, int coef) {
 | 
				
			||||||
    unsigned n = pred->get_num_args();
 | 
					    unsigned n = pred->get_num_args();
 | 
				
			||||||
    for (unsigned i = 0; i < n; i++) {
 | 
					    for (unsigned i = 0; i < n; i++) {
 | 
				
			||||||
        m_sorts.reset();
 | 
					        m_fv(pred->get_arg(i));
 | 
				
			||||||
        m_todo.reset();
 | 
					        for (unsigned j = 0; j < m_fv.size(); ++j) {
 | 
				
			||||||
        m_mark.reset();
 | 
					            if (m_fv[j]) {
 | 
				
			||||||
        ::get_free_vars(m_mark, m_todo, pred->get_arg(i), m_sorts);
 | 
					 | 
				
			||||||
        for (unsigned j = 0; j < m_sorts.size(); ++j) {
 | 
					 | 
				
			||||||
            if (m_sorts[j]) {
 | 
					 | 
				
			||||||
                update(j, coef);
 | 
					                update(j, coef);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    m_fv.reset();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,16 +27,16 @@ Revision History:
 | 
				
			||||||
#include "ast.h"
 | 
					#include "ast.h"
 | 
				
			||||||
#include "map.h"
 | 
					#include "map.h"
 | 
				
			||||||
#include "uint_set.h"
 | 
					#include "uint_set.h"
 | 
				
			||||||
 | 
					#include "var_subst.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class counter {
 | 
					class counter {
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    typedef u_map<int> map_impl;
 | 
					    typedef u_map<int> map_impl;
 | 
				
			||||||
    map_impl m_data;
 | 
					    map_impl m_data;
 | 
				
			||||||
    const bool m_stay_non_negative;
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    typedef map_impl::iterator iterator;
 | 
					    typedef map_impl::iterator iterator;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    counter(bool stay_non_negative = true) : m_stay_non_negative(stay_non_negative) {}
 | 
					    counter() {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    void reset() { m_data.reset(); }
 | 
					    void reset() { m_data.reset(); }
 | 
				
			||||||
    iterator begin() const { return m_data.begin(); }
 | 
					    iterator begin() const { return m_data.begin(); }
 | 
				
			||||||
| 
						 | 
					@ -69,14 +69,13 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class var_counter : public counter {
 | 
					class var_counter : public counter {
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    ptr_vector<sort> m_sorts;
 | 
					 | 
				
			||||||
    expr_fast_mark1  m_visited;
 | 
					    expr_fast_mark1  m_visited;
 | 
				
			||||||
 | 
					    expr_free_vars   m_fv;
 | 
				
			||||||
    ptr_vector<expr> m_todo;
 | 
					    ptr_vector<expr> m_todo;
 | 
				
			||||||
    ast_mark         m_mark;
 | 
					 | 
				
			||||||
    unsigned_vector  m_scopes;
 | 
					    unsigned_vector  m_scopes;
 | 
				
			||||||
    unsigned get_max_var(bool & has_var);    
 | 
					    unsigned get_max_var(bool & has_var);    
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    var_counter(bool stay_non_negative = true): counter(stay_non_negative) {}
 | 
					    var_counter() {}
 | 
				
			||||||
    void count_vars(ast_manager & m, const app * t, int coef = 1);
 | 
					    void count_vars(ast_manager & m, const app * t, int coef = 1);
 | 
				
			||||||
    unsigned get_max_var(expr* e);
 | 
					    unsigned get_max_var(expr* e);
 | 
				
			||||||
    unsigned get_next_var(expr* e);
 | 
					    unsigned get_next_var(expr* e);
 | 
				
			||||||
| 
						 | 
					@ -85,11 +84,10 @@ public:
 | 
				
			||||||
class ast_counter {
 | 
					class ast_counter {
 | 
				
			||||||
    typedef obj_map<ast, int> map_impl;
 | 
					    typedef obj_map<ast, int> map_impl;
 | 
				
			||||||
    map_impl m_data;
 | 
					    map_impl m_data;
 | 
				
			||||||
    bool     m_stay_non_negative;
 | 
					 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
    typedef map_impl::iterator iterator;
 | 
					    typedef map_impl::iterator iterator;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    ast_counter(bool stay_non_negative = true) : m_stay_non_negative(stay_non_negative) {}
 | 
					    ast_counter() {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    iterator begin() const { return m_data.begin(); }
 | 
					    iterator begin() const { return m_data.begin(); }
 | 
				
			||||||
    iterator end() const { return m_data.end(); }
 | 
					    iterator end() const { return m_data.end(); }
 | 
				
			||||||
| 
						 | 
					@ -99,7 +97,6 @@ class ast_counter {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    void update(ast * el, int delta){
 | 
					    void update(ast * el, int delta){
 | 
				
			||||||
        get(el) += delta;
 | 
					        get(el) += delta;
 | 
				
			||||||
        SASSERT(!m_stay_non_negative || get(el) >= 0);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    void inc(ast * el) { update(el, 1); }
 | 
					    void inc(ast * el) { update(el, 1); }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1038,6 +1038,11 @@ void bit_blaster_tpl<Cfg>::mk_ext_rotate_left_right(unsigned sz, expr * const *
 | 
				
			||||||
            mk_rotate_right(sz, a_bits, static_cast<unsigned>(k.get_uint64()), out_bits);
 | 
					            mk_rotate_right(sz, a_bits, static_cast<unsigned>(k.get_uint64()), out_bits);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        // Review: a better tuned implementation is possible by using shifts by power of two.
 | 
				
			||||||
 | 
					        // e.g., looping over the bits of b_bits, then rotate by a power of two depending
 | 
				
			||||||
 | 
					        // on the bit-position. This would get rid of the mk_urem.
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
        expr_ref_vector sz_bits(m());
 | 
					        expr_ref_vector sz_bits(m());
 | 
				
			||||||
        expr_ref_vector masked_b_bits(m());
 | 
					        expr_ref_vector masked_b_bits(m());
 | 
				
			||||||
        expr_ref_vector eqs(m());
 | 
					        expr_ref_vector eqs(m());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,32 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr
 | 
				
			||||||
        UNREACHABLE();
 | 
					        UNREACHABLE();
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    case OP_DT_UPDATE_FIELD: {
 | 
				
			||||||
 | 
					        SASSERT(num_args == 2);
 | 
				
			||||||
 | 
					        if (!is_app(args[0]) || !m_util.is_constructor(to_app(args[0])))
 | 
				
			||||||
 | 
					            return BR_FAILED;
 | 
				
			||||||
 | 
					        app * a = to_app(args[0]);
 | 
				
			||||||
 | 
					        func_decl * c_decl = a->get_decl();
 | 
				
			||||||
 | 
					        if (c_decl != m_util.get_accessor_constructor(f)) {
 | 
				
			||||||
 | 
					            result = a;
 | 
				
			||||||
 | 
					            return BR_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ptr_vector<func_decl> const * acc = m_util.get_constructor_accessors(c_decl);
 | 
				
			||||||
 | 
					        SASSERT(acc && acc->size() == a->get_num_args());
 | 
				
			||||||
 | 
					        unsigned num = acc->size();
 | 
				
			||||||
 | 
					        ptr_buffer<expr> new_args;
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < num; ++i) {
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (f == (*acc)[i]) {
 | 
				
			||||||
 | 
					                new_args.push_back(args[1]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                new_args.push_back(a->get_arg(i));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        result = m().mk_app(c_decl, num, new_args.c_ptr());
 | 
				
			||||||
 | 
					        return BR_DONE;        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        UNREACHABLE();
 | 
					        UNREACHABLE();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,43 +29,39 @@ void expr_safe_replace::insert(expr* src, expr* dst) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void expr_safe_replace::operator()(expr* e, expr_ref& res) {
 | 
					void expr_safe_replace::operator()(expr* e, expr_ref& res) {
 | 
				
			||||||
    obj_map<expr,expr*> cache;
 | 
					    m_todo.push_back(e);
 | 
				
			||||||
    ptr_vector<expr> todo, args;
 | 
					 | 
				
			||||||
    expr_ref_vector refs(m);
 | 
					 | 
				
			||||||
    todo.push_back(e);
 | 
					 | 
				
			||||||
    expr* a, *b, *d;
 | 
					    expr* a, *b, *d;
 | 
				
			||||||
    todo.push_back(e);
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    while (!todo.empty()) {
 | 
					    while (!m_todo.empty()) {
 | 
				
			||||||
        a = todo.back();
 | 
					        a = m_todo.back();
 | 
				
			||||||
        if (cache.contains(a)) {
 | 
					        if (m_cache.contains(a)) {
 | 
				
			||||||
            todo.pop_back();
 | 
					            m_todo.pop_back();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (m_subst.find(a, b)) {
 | 
					        else if (m_subst.find(a, b)) {
 | 
				
			||||||
            cache.insert(a, b);
 | 
					            m_cache.insert(a, b);
 | 
				
			||||||
            todo.pop_back();
 | 
					            m_todo.pop_back();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (is_var(a)) {
 | 
					        else if (is_var(a)) {
 | 
				
			||||||
            cache.insert(a, a);
 | 
					            m_cache.insert(a, a);
 | 
				
			||||||
            todo.pop_back();
 | 
					            m_todo.pop_back();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (is_app(a)) {
 | 
					        else if (is_app(a)) {
 | 
				
			||||||
            app* c = to_app(a);
 | 
					            app* c = to_app(a);
 | 
				
			||||||
            unsigned n = c->get_num_args();
 | 
					            unsigned n = c->get_num_args();
 | 
				
			||||||
            args.reset();
 | 
					            m_args.reset();
 | 
				
			||||||
            for (unsigned i = 0; i < n; ++i) {
 | 
					            for (unsigned i = 0; i < n; ++i) {
 | 
				
			||||||
                if (cache.find(c->get_arg(i), d)) {
 | 
					                if (m_cache.find(c->get_arg(i), d)) {
 | 
				
			||||||
                    args.push_back(d);
 | 
					                    m_args.push_back(d);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                    todo.push_back(c->get_arg(i));
 | 
					                    m_todo.push_back(c->get_arg(i));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (args.size() == n) {
 | 
					            if (m_args.size() == n) {
 | 
				
			||||||
                b = m.mk_app(c->get_decl(), args.size(), args.c_ptr());
 | 
					                b = m.mk_app(c->get_decl(), m_args.size(), m_args.c_ptr());
 | 
				
			||||||
                refs.push_back(b);
 | 
					                m_refs.push_back(b);
 | 
				
			||||||
                cache.insert(a, b);
 | 
					                m_cache.insert(a, b);
 | 
				
			||||||
                todo.pop_back();
 | 
					                m_todo.pop_back();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
| 
						 | 
					@ -93,12 +89,16 @@ void expr_safe_replace::operator()(expr* e, expr_ref& res) {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            replace(q->get_expr(), new_body);
 | 
					            replace(q->get_expr(), new_body);
 | 
				
			||||||
            b = m.update_quantifier(q, pats.size(), pats.c_ptr(), nopats.size(), nopats.c_ptr(), new_body);
 | 
					            b = m.update_quantifier(q, pats.size(), pats.c_ptr(), nopats.size(), nopats.c_ptr(), new_body);
 | 
				
			||||||
            refs.push_back(b);
 | 
					            m_refs.push_back(b);
 | 
				
			||||||
            cache.insert(a, b);
 | 
					            m_cache.insert(a, b);
 | 
				
			||||||
            todo.pop_back();
 | 
					            m_todo.pop_back();
 | 
				
			||||||
        }        
 | 
					        }        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    res = cache.find(e);
 | 
					    res = m_cache.find(e);
 | 
				
			||||||
 | 
					    m_cache.reset();
 | 
				
			||||||
 | 
					    m_todo.reset();
 | 
				
			||||||
 | 
					    m_args.reset();
 | 
				
			||||||
 | 
					    m_refs.reset();    
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void expr_safe_replace::reset() {
 | 
					void expr_safe_replace::reset() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,9 +29,12 @@ class expr_safe_replace {
 | 
				
			||||||
    expr_ref_vector m_src;
 | 
					    expr_ref_vector m_src;
 | 
				
			||||||
    expr_ref_vector m_dst;
 | 
					    expr_ref_vector m_dst;
 | 
				
			||||||
    obj_map<expr, expr*> m_subst;
 | 
					    obj_map<expr, expr*> m_subst;
 | 
				
			||||||
 | 
					    obj_map<expr,expr*> m_cache;
 | 
				
			||||||
 | 
					    ptr_vector<expr> m_todo, m_args;
 | 
				
			||||||
 | 
					    expr_ref_vector m_refs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    expr_safe_replace(ast_manager& m): m(m), m_src(m), m_dst(m) {}
 | 
					    expr_safe_replace(ast_manager& m): m(m), m_src(m), m_dst(m), m_refs(m) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void insert(expr* src, expr* dst);
 | 
					    void insert(expr* src, expr* dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +45,8 @@ public:
 | 
				
			||||||
    void apply_substitution(expr* s, expr* def, expr_ref& t);
 | 
					    void apply_substitution(expr* s, expr* def, expr_ref& t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void reset();
 | 
					    void reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool empty() const { return m_subst.empty(); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __EXPR_SAFE_REPLACE_H__ */
 | 
					#endif /* __EXPR_SAFE_REPLACE_H__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										275
									
								
								src/ast/rewriter/pb_rewriter.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								src/ast/rewriter/pb_rewriter.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,275 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) 2013 Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pb_rewriter.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Basic rewriting rules for PB constraints.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Nikolaj Bjorner (nbjorner) 2013-14-12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pb_rewriter.h"
 | 
				
			||||||
 | 
					#include "pb_rewriter_def.h"
 | 
				
			||||||
 | 
					#include "ast_pp.h"
 | 
				
			||||||
 | 
					#include "ast_smt_pp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class pb_ast_rewriter_util {
 | 
				
			||||||
 | 
					    ast_manager& m;
 | 
				
			||||||
 | 
					    expr_ref_vector m_refs;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef std::pair<expr*, rational> arg_t;
 | 
				
			||||||
 | 
					    typedef vector<arg_t> args_t;
 | 
				
			||||||
 | 
					    typedef rational numeral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pb_ast_rewriter_util(ast_manager& m): m(m), m_refs(m) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expr* negate(expr* e) {
 | 
				
			||||||
 | 
					        if (m.is_true(e)) {
 | 
				
			||||||
 | 
					            return m.mk_false();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (m.is_false(e)) {
 | 
				
			||||||
 | 
					            return m.mk_true();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (m.is_not(e, e)) {
 | 
				
			||||||
 | 
					            return e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        m_refs.push_back(m.mk_not(e));
 | 
				
			||||||
 | 
					        return m_refs.back();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void display(std::ostream& out, expr* e) {
 | 
				
			||||||
 | 
					        out << mk_pp(e, m);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_negated(expr* e) const {
 | 
				
			||||||
 | 
					        return m.is_not(e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_true(expr* e) const {
 | 
				
			||||||
 | 
					        return m.is_true(e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_false(expr* e) const {
 | 
				
			||||||
 | 
					        return m.is_false(e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct compare {
 | 
				
			||||||
 | 
					        bool operator()(std::pair<expr*,rational> const& a,
 | 
				
			||||||
 | 
					                        std::pair<expr*,rational> const& b) {
 | 
				
			||||||
 | 
					            return a.first->get_id() < b.first->get_id();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					expr_ref pb_rewriter::translate_pb2lia(obj_map<expr,expr*>& vars, expr* fml) {
 | 
				
			||||||
 | 
					    pb_util util(m());
 | 
				
			||||||
 | 
					    arith_util a(m());
 | 
				
			||||||
 | 
					    expr_ref result(m()), tmp(m());
 | 
				
			||||||
 | 
					    expr_ref_vector es(m());
 | 
				
			||||||
 | 
					    expr*const* args = to_app(fml)->get_args();
 | 
				
			||||||
 | 
					    unsigned sz = to_app(fml)->get_num_args();
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
 | 
					        expr* e = args[i];
 | 
				
			||||||
 | 
					        if (m().is_not(e, e)) {
 | 
				
			||||||
 | 
					            es.push_back(a.mk_sub(a.mk_numeral(rational(1),true),vars.find(e)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            es.push_back(vars.find(e));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (util.is_at_most_k(fml) || util.is_at_least_k(fml)) {
 | 
				
			||||||
 | 
					        if (es.empty()) {
 | 
				
			||||||
 | 
					            tmp = a.mk_numeral(rational(0), true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            tmp = a.mk_add(es.size(), es.c_ptr());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (util.is_at_most_k(fml)) {
 | 
				
			||||||
 | 
					            result = a.mk_le(tmp, a.mk_numeral(util.get_k(fml), false));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            result = a.mk_ge(tmp, a.mk_numeral(util.get_k(fml), false));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (util.is_le(fml) || util.is_ge(fml) || util.is_eq(fml)) {
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
 | 
					            es[i] = a.mk_mul(a.mk_numeral(util.get_coeff(fml, i),false), es[i].get());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (es.empty()) {
 | 
				
			||||||
 | 
					            tmp = a.mk_numeral(rational(0), true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            tmp = a.mk_add(es.size(), es.c_ptr());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (util.is_le(fml)) {
 | 
				
			||||||
 | 
					            result = a.mk_le(tmp, a.mk_numeral(util.get_k(fml), false));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (util.is_ge(fml)) {
 | 
				
			||||||
 | 
					            result = a.mk_ge(tmp, a.mk_numeral(util.get_k(fml), false));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            result = m().mk_eq(tmp, a.mk_numeral(util.get_k(fml), false));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        result = fml;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					expr_ref pb_rewriter::mk_validate_rewrite(app_ref& e1, app_ref& e2) {
 | 
				
			||||||
 | 
					    ast_manager& m = e1.get_manager();
 | 
				
			||||||
 | 
					    arith_util a(m);
 | 
				
			||||||
 | 
					    symbol name;
 | 
				
			||||||
 | 
					    obj_map<expr,expr*> vars;
 | 
				
			||||||
 | 
					    expr_ref_vector trail(m), fmls(m);    
 | 
				
			||||||
 | 
					    unsigned sz = to_app(e1)->get_num_args();
 | 
				
			||||||
 | 
					    expr*const*args = to_app(e1)->get_args();
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
 | 
					        expr* e = args[i];
 | 
				
			||||||
 | 
					        if (m.is_true(e)) {
 | 
				
			||||||
 | 
					            if (!vars.contains(e)) {
 | 
				
			||||||
 | 
					                trail.push_back(a.mk_numeral(rational(1), true));
 | 
				
			||||||
 | 
					                vars.insert(e, trail.back());            
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (m.is_false(e)) {
 | 
				
			||||||
 | 
					            if (!vars.contains(e)) {
 | 
				
			||||||
 | 
					                trail.push_back(a.mk_numeral(rational(0), true));
 | 
				
			||||||
 | 
					                vars.insert(e, trail.back());            
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::ostringstream strm;
 | 
				
			||||||
 | 
					        strm << "x" << i;
 | 
				
			||||||
 | 
					        name = symbol(strm.str().c_str());
 | 
				
			||||||
 | 
					        trail.push_back(m.mk_const(name, a.mk_int()));
 | 
				
			||||||
 | 
					        expr* x = trail.back();
 | 
				
			||||||
 | 
					        m.is_not(e,e);
 | 
				
			||||||
 | 
					        vars.insert(e, x);
 | 
				
			||||||
 | 
					        fmls.push_back(a.mk_le(a.mk_numeral(rational(0), true), x));
 | 
				
			||||||
 | 
					        fmls.push_back(a.mk_le(x, a.mk_numeral(rational(1), true)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    expr_ref tmp(m);
 | 
				
			||||||
 | 
					    expr_ref fml1 = translate_pb2lia(vars, e1);
 | 
				
			||||||
 | 
					    expr_ref fml2 = translate_pb2lia(vars, e2);    
 | 
				
			||||||
 | 
					    tmp = m.mk_not(m.mk_eq(fml1, fml2));
 | 
				
			||||||
 | 
					    fmls.push_back(tmp);
 | 
				
			||||||
 | 
					    tmp = m.mk_and(fmls.size(), fmls.c_ptr());
 | 
				
			||||||
 | 
					    return tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned s_lemma = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pb_rewriter::validate_rewrite(func_decl* f, unsigned sz, expr*const* args, expr_ref& fml) {
 | 
				
			||||||
 | 
					    ast_manager& m = fml.get_manager();
 | 
				
			||||||
 | 
					    app_ref tmp1(m), tmp2(m);
 | 
				
			||||||
 | 
					    tmp1 = m.mk_app(f, sz, args);
 | 
				
			||||||
 | 
					    tmp2 = to_app(fml);
 | 
				
			||||||
 | 
					    expr_ref tmp = mk_validate_rewrite(tmp1, tmp2);
 | 
				
			||||||
 | 
					    dump_pb_rewrite(tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pb_rewriter::dump_pb_rewrite(expr* fml) {
 | 
				
			||||||
 | 
					    std::ostringstream strm;
 | 
				
			||||||
 | 
					    strm << "pb_rewrite_" << (s_lemma++) << ".smt2";
 | 
				
			||||||
 | 
					    std::ofstream out(strm.str().c_str());    
 | 
				
			||||||
 | 
					    ast_smt_pp pp(m());
 | 
				
			||||||
 | 
					    pp.display_smt2(out, fml);    
 | 
				
			||||||
 | 
					    out.close();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					br_status pb_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
 | 
				
			||||||
 | 
					    ast_manager& m = result.get_manager();
 | 
				
			||||||
 | 
					    rational sum(0), maxsum(0);
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					        if (m.is_true(args[i])) {
 | 
				
			||||||
 | 
					            sum += m_util.get_coeff(f, i);
 | 
				
			||||||
 | 
					            maxsum += m_util.get_coeff(f, i);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (!m.is_false(args[i])) {
 | 
				
			||||||
 | 
					            maxsum += m_util.get_coeff(f, i);            
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    rational k = m_util.get_k(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vector<std::pair<expr*,rational> > vec;
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					        vec.push_back(std::make_pair(args[i], m_util.get_coeff(f, i)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    switch(f->get_decl_kind()) {
 | 
				
			||||||
 | 
					    case OP_AT_MOST_K:
 | 
				
			||||||
 | 
					    case OP_PB_LE:
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < num_args; ++i) {
 | 
				
			||||||
 | 
					            vec[i].second.neg();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        k.neg();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case OP_AT_LEAST_K:
 | 
				
			||||||
 | 
					    case OP_PB_GE:
 | 
				
			||||||
 | 
					    case OP_PB_EQ:
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        UNREACHABLE();
 | 
				
			||||||
 | 
					        return BR_FAILED;
 | 
				
			||||||
 | 
					    }    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_eq = f->get_decl_kind() == OP_PB_EQ;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pb_ast_rewriter_util pbu(m);
 | 
				
			||||||
 | 
					    pb_rewriter_util<pb_ast_rewriter_util> util(pbu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    util.unique(vec, k, is_eq);
 | 
				
			||||||
 | 
					    lbool is_sat = util.normalize(vec, k, is_eq);
 | 
				
			||||||
 | 
					    util.prune(vec, k, is_eq);
 | 
				
			||||||
 | 
					    switch (is_sat) {
 | 
				
			||||||
 | 
					    case l_true:
 | 
				
			||||||
 | 
					        result = m.mk_true();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case l_false:
 | 
				
			||||||
 | 
					        result = m.mk_false();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        m_args.reset();
 | 
				
			||||||
 | 
					        m_coeffs.reset();
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < vec.size(); ++i) {
 | 
				
			||||||
 | 
					            m_args.push_back(vec[i].first);
 | 
				
			||||||
 | 
					            m_coeffs.push_back(vec[i].second);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (is_eq) {
 | 
				
			||||||
 | 
					            result = m_util.mk_eq(vec.size(), m_coeffs.c_ptr(), m_args.c_ptr(), k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            result = m_util.mk_ge(vec.size(), m_coeffs.c_ptr(), m_args.c_ptr(), k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    TRACE("pb",
 | 
				
			||||||
 | 
					          expr_ref tmp(m);
 | 
				
			||||||
 | 
					          tmp = m.mk_app(f, num_args, args);
 | 
				
			||||||
 | 
					          tout << tmp << "\n";
 | 
				
			||||||
 | 
					          tout << result << "\n";
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					    TRACE("pb_validate",
 | 
				
			||||||
 | 
					          validate_rewrite(f, num_args, args, result););
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					    return BR_DONE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										65
									
								
								src/ast/rewriter/pb_rewriter.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/ast/rewriter/pb_rewriter.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,65 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) 2013 Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pb_rewriter.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Basic rewriting rules for PB constraints.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Nikolaj Bjorner (nbjorner) 2013-14-12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					#ifndef _PB_REWRITER_H_
 | 
				
			||||||
 | 
					#define _PB_REWRITER_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include"pb_decl_plugin.h"
 | 
				
			||||||
 | 
					#include"rewriter_types.h"
 | 
				
			||||||
 | 
					#include"params.h"
 | 
				
			||||||
 | 
					#include"lbool.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename PBU>
 | 
				
			||||||
 | 
					class pb_rewriter_util {    
 | 
				
			||||||
 | 
					    PBU& m_util;
 | 
				
			||||||
 | 
					    void display(std::ostream& out, typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    pb_rewriter_util(PBU& u) : m_util(u) {}
 | 
				
			||||||
 | 
					    void unique(typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq);
 | 
				
			||||||
 | 
					    lbool normalize(typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq);
 | 
				
			||||||
 | 
					    void prune(typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					   \brief Cheap rewrite rules for PB constraints
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					class pb_rewriter {
 | 
				
			||||||
 | 
					    pb_util       m_util;
 | 
				
			||||||
 | 
					    vector<rational> m_coeffs;
 | 
				
			||||||
 | 
					    ptr_vector<expr> m_args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void validate_rewrite(func_decl* f, unsigned sz, expr*const* args, expr_ref& fml);
 | 
				
			||||||
 | 
					public:    
 | 
				
			||||||
 | 
					    pb_rewriter(ast_manager & m, params_ref const & p = params_ref()):
 | 
				
			||||||
 | 
					        m_util(m) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ast_manager & m() const { return m_util.get_manager(); }
 | 
				
			||||||
 | 
					    family_id get_fid() const { return m_util.get_family_id(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void updt_params(params_ref const & p) {}
 | 
				
			||||||
 | 
					    static void get_param_descrs(param_descrs & r) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    br_status mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expr_ref translate_pb2lia(obj_map<expr,expr*>& vars, expr* fml);
 | 
				
			||||||
 | 
					    expr_ref mk_validate_rewrite(app_ref& e1, app_ref& e2);
 | 
				
			||||||
 | 
					    void dump_pb_rewrite(expr* fml);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										298
									
								
								src/ast/rewriter/pb_rewriter_def.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								src/ast/rewriter/pb_rewriter_def.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,298 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) 2013 Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pb_rewriter_def.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Basic rewriting rules for PB constraints.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Nikolaj Bjorner (nbjorner) 2013-14-12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					#ifndef _PB_REWRITER_DEF_H_
 | 
				
			||||||
 | 
					#define _PB_REWRITER_DEF_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include"pb_rewriter.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename PBU>
 | 
				
			||||||
 | 
					void pb_rewriter_util<PBU>::display(std::ostream& out, typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq) {
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        out << args[i].second << " * ";
 | 
				
			||||||
 | 
					        m_util.display(out, args[i].first);
 | 
				
			||||||
 | 
					        out << " ";
 | 
				
			||||||
 | 
					        if (i+1 < args.size()) out << "+ ";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    out << (is_eq?" = ":" >= ") << k << "\n";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename PBU>
 | 
				
			||||||
 | 
					void pb_rewriter_util<PBU>::unique(typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    TRACE("pb_verbose", display(tout << "pre-unique:", args, k, is_eq););
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        if (m_util.is_negated(args[i].first)) {
 | 
				
			||||||
 | 
					            args[i].first = m_util.negate(args[i].first);
 | 
				
			||||||
 | 
					            k -= args[i].second;
 | 
				
			||||||
 | 
					            args[i].second = -args[i].second;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // remove constants
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        if (m_util.is_true(args[i].first)) {
 | 
				
			||||||
 | 
					            k -= args[i].second;
 | 
				
			||||||
 | 
					            std::swap(args[i], args[args.size()-1]);
 | 
				
			||||||
 | 
					            args.pop_back();
 | 
				
			||||||
 | 
					            --i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (m_util.is_false(args[i].first)) {
 | 
				
			||||||
 | 
					            std::swap(args[i], args[args.size()-1]);
 | 
				
			||||||
 | 
					            args.pop_back();                
 | 
				
			||||||
 | 
					            --i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // sort and coalesce arguments:
 | 
				
			||||||
 | 
					    typename PBU::compare cmp;
 | 
				
			||||||
 | 
					    std::sort(args.begin(), args.end(), cmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // coallesce
 | 
				
			||||||
 | 
					    unsigned i, j;
 | 
				
			||||||
 | 
					    for (i = 0, j = 1; j < args.size(); ++j) {
 | 
				
			||||||
 | 
					        if (args[i].first == args[j].first) {
 | 
				
			||||||
 | 
					            args[i].second += args[j].second;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            ++i;
 | 
				
			||||||
 | 
					            args[i] = args[j];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    args.resize(i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // remove 0s.
 | 
				
			||||||
 | 
					    for (i = 0, j = 0; j < args.size(); ++j) {
 | 
				
			||||||
 | 
					        if (!args[j].second.is_zero()) {
 | 
				
			||||||
 | 
					            if (i != j) {
 | 
				
			||||||
 | 
					                args[i] = args[j];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ++i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    args.resize(i);
 | 
				
			||||||
 | 
					    TRACE("pb_verbose", display(tout << "post-unique:", args, k, is_eq););
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename PBU>
 | 
				
			||||||
 | 
					lbool pb_rewriter_util<PBU>::normalize(typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq) {
 | 
				
			||||||
 | 
					    TRACE("pb_verbose", display(tout << "pre-normalize:", args, k, is_eq););
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEBUG_CODE(
 | 
				
			||||||
 | 
					        bool found = false;
 | 
				
			||||||
 | 
					        for (unsigned i = 0; !found && i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            found = args[i].second.is_zero();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (found) display(verbose_stream(), args, k, is_eq);
 | 
				
			||||||
 | 
					        SASSERT(!found););
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 
 | 
				
			||||||
 | 
					    // Ensure all coefficients are positive:
 | 
				
			||||||
 | 
					    //    c*l + y >= k 
 | 
				
			||||||
 | 
					    // <=> 
 | 
				
			||||||
 | 
					    //    c*(1-~l) + y >= k
 | 
				
			||||||
 | 
					    // <=>
 | 
				
			||||||
 | 
					    //    c - c*~l + y >= k
 | 
				
			||||||
 | 
					    // <=> 
 | 
				
			||||||
 | 
					    //    -c*~l + y >= k - c
 | 
				
			||||||
 | 
					    // 
 | 
				
			||||||
 | 
					    typename PBU::numeral sum(0);
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        typename PBU::numeral c = args[i].second;
 | 
				
			||||||
 | 
					        if (c.is_neg()) {
 | 
				
			||||||
 | 
					            args[i].second = -c;
 | 
				
			||||||
 | 
					            args[i].first = m_util.negate(args[i].first);
 | 
				
			||||||
 | 
					            k -= c;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        sum += args[i].second;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // detect tautologies:
 | 
				
			||||||
 | 
					    if (!is_eq && k <= PBU::numeral::zero()) {
 | 
				
			||||||
 | 
					        args.reset();
 | 
				
			||||||
 | 
					        k = PBU::numeral::zero();
 | 
				
			||||||
 | 
					        return l_true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (is_eq && k.is_zero() && args.empty()) {
 | 
				
			||||||
 | 
					        return l_true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // detect infeasible constraints:
 | 
				
			||||||
 | 
					    if (sum < k) {
 | 
				
			||||||
 | 
					        args.reset();
 | 
				
			||||||
 | 
					        k = PBU::numeral::one();
 | 
				
			||||||
 | 
					        return l_false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_eq && k == sum) {
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            args[i].second = PBU::numeral::one();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        typename PBU::numeral num(args.size()); 
 | 
				
			||||||
 | 
					        k = num;
 | 
				
			||||||
 | 
					        return l_undef;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    bool all_int = true;
 | 
				
			||||||
 | 
					    for (unsigned i = 0; all_int && i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        all_int = args[i].second.is_int();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!all_int) {
 | 
				
			||||||
 | 
					        // normalize to integers.
 | 
				
			||||||
 | 
					        typename PBU::numeral d(denominator(k));
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            d = lcm(d, denominator(args[i].second));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        SASSERT(!d.is_one());
 | 
				
			||||||
 | 
					        k *= d;
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            args[i].second *= d;
 | 
				
			||||||
 | 
					        }            
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_eq) {
 | 
				
			||||||
 | 
					        TRACE("pb_verbose", display(tout << "post-normalize:", args, k, is_eq););
 | 
				
			||||||
 | 
					        return l_undef;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Ensure the largest coefficient is not larger than k:
 | 
				
			||||||
 | 
					    sum = PBU::numeral::zero();
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        typename PBU::numeral c = args[i].second;
 | 
				
			||||||
 | 
					        if (c > k) {
 | 
				
			||||||
 | 
					            args[i].second = k;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        sum += args[i].second;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SASSERT(!args.empty());
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // normalize tight inequalities to unit coefficients.
 | 
				
			||||||
 | 
					    if (sum == k) {
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            args[i].second = PBU::numeral::one();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        typename PBU::numeral num(args.size()); 
 | 
				
			||||||
 | 
					        k = num;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // apply cutting plane reduction:
 | 
				
			||||||
 | 
					    typename PBU::numeral g(0);
 | 
				
			||||||
 | 
					    for (unsigned i = 0; !g.is_one() && i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        typename PBU::numeral c = args[i].second;
 | 
				
			||||||
 | 
					        if (c != k) {
 | 
				
			||||||
 | 
					            if (g.is_zero()) {
 | 
				
			||||||
 | 
					                g = c;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                g = gcd(g, c);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (g.is_zero()) {
 | 
				
			||||||
 | 
					        // all coefficients are equal to k.
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            SASSERT(args[i].second == k);
 | 
				
			||||||
 | 
					            args[i].second = PBU::numeral::one();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        k = PBU::numeral::one();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (g > PBU::numeral::one()) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        // Example 5x + 5y + 2z + 2u >= 5
 | 
				
			||||||
 | 
					        // becomes 3x + 3y + z + u >= 3
 | 
				
			||||||
 | 
					        // 
 | 
				
			||||||
 | 
					        typename PBU::numeral k_new = div(k, g);    
 | 
				
			||||||
 | 
					        if (!(k % g).is_zero()) {     // k_new is the ceiling of k / g.
 | 
				
			||||||
 | 
					            k_new++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            SASSERT(args[i].second.is_pos());
 | 
				
			||||||
 | 
					            typename PBU::numeral c = args[i].second;
 | 
				
			||||||
 | 
					            if (c == k) {
 | 
				
			||||||
 | 
					                c = k_new;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                c = div(c, g);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            args[i].second = c;
 | 
				
			||||||
 | 
					            SASSERT(args[i].second.is_pos());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        k = k_new;            
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // normalize coefficients that fall within a range
 | 
				
			||||||
 | 
					    // k/n <= ... < k/(n-1) for some n = 1,2,...
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // e.g, k/n <= min <= max < k/(n-1)
 | 
				
			||||||
 | 
					    //      k/min <= n, n-1 < k/max
 | 
				
			||||||
 | 
					    // .    floor(k/max) = ceil(k/min) - 1  
 | 
				
			||||||
 | 
					    // .    floor(k/max) < k/max
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // example: k = 5, min = 3, max = 4: 5/3 -> 2   5/4 -> 1, n = 2
 | 
				
			||||||
 | 
					    // replace all coefficients by 1, and k by 2.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    if (!k.is_one()) {
 | 
				
			||||||
 | 
					        typename PBU::numeral min = args[0].second, max = args[0].second;
 | 
				
			||||||
 | 
					        for (unsigned i = 1; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            if (args[i].second < min) min = args[i].second;
 | 
				
			||||||
 | 
					            if (args[i].second > max) max = args[i].second;
 | 
				
			||||||
 | 
					        }            
 | 
				
			||||||
 | 
					        SASSERT(min.is_pos());
 | 
				
			||||||
 | 
					        typename PBU::numeral n0 = k/max;
 | 
				
			||||||
 | 
					        typename PBU::numeral n1 = floor(n0);
 | 
				
			||||||
 | 
					        typename PBU::numeral n2 = ceil(k/min) - PBU::numeral::one();
 | 
				
			||||||
 | 
					        if (n1 == n2 && !n0.is_int()) {
 | 
				
			||||||
 | 
					            IF_VERBOSE(3, display(verbose_stream() << "set cardinality\n", args, k, is_eq););
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					                args[i].second = PBU::numeral::one();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            k = n1 + PBU::numeral::one();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    TRACE("pb_verbose", display(tout << "post-normalize:", args, k, is_eq););
 | 
				
			||||||
 | 
					    return l_undef;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename PBU>
 | 
				
			||||||
 | 
					void pb_rewriter_util<PBU>::prune(typename PBU::args_t& args, typename PBU::numeral& k, bool is_eq) {
 | 
				
			||||||
 | 
					    if (is_eq) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    typename PBU::numeral nlt(0);
 | 
				
			||||||
 | 
					    unsigned occ = 0;
 | 
				
			||||||
 | 
					    for (unsigned i = 0; nlt < k && i < args.size(); ++i) {
 | 
				
			||||||
 | 
					        if (args[i].second < k) {
 | 
				
			||||||
 | 
					            nlt += args[i].second;
 | 
				
			||||||
 | 
					            ++occ;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (0 < occ && nlt < k) {        
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
 | 
					            if (args[i].second < k) {
 | 
				
			||||||
 | 
					                args[i] = args.back();
 | 
				
			||||||
 | 
					                args.pop_back();
 | 
				
			||||||
 | 
					                --i;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        unique(args, k, is_eq);
 | 
				
			||||||
 | 
					        normalize(args, k, is_eq);
 | 
				
			||||||
 | 
					    }    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,8 @@ void poly_rewriter<Config>::updt_params(params_ref const & _p) {
 | 
				
			||||||
    m_hoist_mul = p.hoist_mul();
 | 
					    m_hoist_mul = p.hoist_mul();
 | 
				
			||||||
    m_hoist_cmul = p.hoist_cmul();
 | 
					    m_hoist_cmul = p.hoist_cmul();
 | 
				
			||||||
    m_som_blowup = p.som_blowup();
 | 
					    m_som_blowup = p.som_blowup();
 | 
				
			||||||
 | 
					    if (!m_flat) m_som = false;
 | 
				
			||||||
 | 
					    if (m_som) m_hoist_mul = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename Config>
 | 
					template<typename Config>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@ Notes:
 | 
				
			||||||
#include"array_rewriter.h"
 | 
					#include"array_rewriter.h"
 | 
				
			||||||
#include"float_rewriter.h"
 | 
					#include"float_rewriter.h"
 | 
				
			||||||
#include"dl_rewriter.h"
 | 
					#include"dl_rewriter.h"
 | 
				
			||||||
 | 
					#include"pb_rewriter.h"
 | 
				
			||||||
#include"rewriter_def.h"
 | 
					#include"rewriter_def.h"
 | 
				
			||||||
#include"expr_substitution.h"
 | 
					#include"expr_substitution.h"
 | 
				
			||||||
#include"ast_smt2_pp.h"
 | 
					#include"ast_smt2_pp.h"
 | 
				
			||||||
| 
						 | 
					@ -41,6 +42,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
 | 
				
			||||||
    datatype_rewriter   m_dt_rw;
 | 
					    datatype_rewriter   m_dt_rw;
 | 
				
			||||||
    float_rewriter      m_f_rw;
 | 
					    float_rewriter      m_f_rw;
 | 
				
			||||||
    dl_rewriter         m_dl_rw;
 | 
					    dl_rewriter         m_dl_rw;
 | 
				
			||||||
 | 
					    pb_rewriter         m_pb_rw;
 | 
				
			||||||
    arith_util          m_a_util;
 | 
					    arith_util          m_a_util;
 | 
				
			||||||
    bv_util             m_bv_util;
 | 
					    bv_util             m_bv_util;
 | 
				
			||||||
    unsigned long long  m_max_memory; // in bytes
 | 
					    unsigned long long  m_max_memory; // in bytes
 | 
				
			||||||
| 
						 | 
					@ -196,6 +198,8 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
 | 
				
			||||||
            return m_f_rw.mk_app_core(f, num, args, result);
 | 
					            return m_f_rw.mk_app_core(f, num, args, result);
 | 
				
			||||||
        if (fid == m_dl_rw.get_fid())
 | 
					        if (fid == m_dl_rw.get_fid())
 | 
				
			||||||
            return m_dl_rw.mk_app_core(f, num, args, result);
 | 
					            return m_dl_rw.mk_app_core(f, num, args, result);
 | 
				
			||||||
 | 
					        if (fid == m_pb_rw.get_fid())
 | 
				
			||||||
 | 
					            return m_pb_rw.mk_app_core(f, num, args, result);
 | 
				
			||||||
        return BR_FAILED;
 | 
					        return BR_FAILED;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -645,6 +649,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
 | 
				
			||||||
        m_dt_rw(m),
 | 
					        m_dt_rw(m),
 | 
				
			||||||
        m_f_rw(m, p),
 | 
					        m_f_rw(m, p),
 | 
				
			||||||
        m_dl_rw(m),
 | 
					        m_dl_rw(m),
 | 
				
			||||||
 | 
					        m_pb_rw(m),
 | 
				
			||||||
        m_a_util(m),
 | 
					        m_a_util(m),
 | 
				
			||||||
        m_bv_util(m),
 | 
					        m_bv_util(m),
 | 
				
			||||||
        m_used_dependencies(m),
 | 
					        m_used_dependencies(m),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,7 +164,7 @@ void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref
 | 
				
			||||||
          tout << "\n----->\n" << mk_ismt2_pp(result, m) << "\n";);
 | 
					          tout << "\n----->\n" << mk_ismt2_pp(result, m) << "\n";);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void get_free_vars_offset(ast_mark& mark, ptr_vector<expr>& todo, unsigned offset, expr* e, ptr_vector<sort>& sorts) {
 | 
					static void get_free_vars_offset(expr_sparse_mark& mark, ptr_vector<expr>& todo, unsigned offset, expr* e, ptr_vector<sort>& sorts) {
 | 
				
			||||||
    todo.push_back(e);
 | 
					    todo.push_back(e);
 | 
				
			||||||
    while (!todo.empty()) {
 | 
					    while (!todo.empty()) {
 | 
				
			||||||
        e = todo.back();
 | 
					        e = todo.back();
 | 
				
			||||||
| 
						 | 
					@ -176,7 +176,7 @@ static void get_free_vars_offset(ast_mark& mark, ptr_vector<expr>& todo, unsigne
 | 
				
			||||||
        switch(e->get_kind()) {
 | 
					        switch(e->get_kind()) {
 | 
				
			||||||
        case AST_QUANTIFIER: {
 | 
					        case AST_QUANTIFIER: {
 | 
				
			||||||
            quantifier* q = to_quantifier(e);
 | 
					            quantifier* q = to_quantifier(e);
 | 
				
			||||||
            ast_mark mark1;
 | 
					            expr_sparse_mark mark1;
 | 
				
			||||||
            ptr_vector<expr> todo1;
 | 
					            ptr_vector<expr> todo1;
 | 
				
			||||||
            get_free_vars_offset(mark1, todo1, offset+q->get_num_decls(), q->get_expr(), sorts);
 | 
					            get_free_vars_offset(mark1, todo1, offset+q->get_num_decls(), q->get_expr(), sorts);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
| 
						 | 
					@ -210,11 +210,33 @@ static void get_free_vars_offset(ast_mark& mark, ptr_vector<expr>& todo, unsigne
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void get_free_vars(expr* e, ptr_vector<sort>& sorts) {
 | 
					void get_free_vars(expr* e, ptr_vector<sort>& sorts) {
 | 
				
			||||||
    ast_mark mark;
 | 
					    expr_sparse_mark mark;
 | 
				
			||||||
    ptr_vector<expr> todo;
 | 
					    ptr_vector<expr> todo;
 | 
				
			||||||
    get_free_vars_offset(mark, todo, 0, e, sorts);
 | 
					    get_free_vars_offset(mark, todo, 0, e, sorts);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void get_free_vars(ast_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts) {
 | 
					void get_free_vars(expr_sparse_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts) {
 | 
				
			||||||
    get_free_vars_offset(mark, todo, 0, e, sorts);
 | 
					    get_free_vars_offset(mark, todo, 0, e, sorts);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void expr_free_vars::reset() {
 | 
				
			||||||
 | 
					    m_mark.reset();
 | 
				
			||||||
 | 
					    m_sorts.reset();
 | 
				
			||||||
 | 
					    SASSERT(m_todo.empty());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void expr_free_vars::set_default_sort(sort *s) {
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < m_sorts.size(); ++i) {
 | 
				
			||||||
 | 
					        if (!m_sorts[i]) m_sorts[i] = s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void expr_free_vars::operator()(expr* e) {
 | 
				
			||||||
 | 
					    reset();
 | 
				
			||||||
 | 
					    get_free_vars_offset(m_mark, m_todo, 0, e, m_sorts);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void expr_free_vars::accumulate(expr* e) {
 | 
				
			||||||
 | 
					    SASSERT(m_todo.empty());
 | 
				
			||||||
 | 
					    get_free_vars_offset(m_mark, m_todo, 0, e, m_sorts);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,9 +81,23 @@ void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   Return the sorts of the free variables.
 | 
					   Return the sorts of the free variables.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
void get_free_vars(expr* e, ptr_vector<sort>& sorts);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void get_free_vars(ast_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts);
 | 
					class expr_free_vars {
 | 
				
			||||||
 | 
					    expr_sparse_mark m_mark;
 | 
				
			||||||
 | 
					    ptr_vector<sort> m_sorts;
 | 
				
			||||||
 | 
					    ptr_vector<expr> m_todo;
 | 
				
			||||||
 | 
					public:    
 | 
				
			||||||
 | 
					    void reset();
 | 
				
			||||||
 | 
					    void operator()(expr* e);
 | 
				
			||||||
 | 
					    void accumulate(expr* e);
 | 
				
			||||||
 | 
					    bool empty() const { return m_sorts.empty(); }
 | 
				
			||||||
 | 
					    unsigned size() const { return m_sorts.size(); }
 | 
				
			||||||
 | 
					    sort* operator[](unsigned idx) const { return m_sorts[idx]; }
 | 
				
			||||||
 | 
					    bool contains(unsigned idx) const { return idx < m_sorts.size() && m_sorts[idx] != 0; }
 | 
				
			||||||
 | 
					    void set_default_sort(sort* s);
 | 
				
			||||||
 | 
					    void reverse() { m_sorts.reverse(); }
 | 
				
			||||||
 | 
					    sort*const* c_ptr() const { return m_sorts.c_ptr(); }  
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,21 +20,32 @@ Notes:
 | 
				
			||||||
#define _BASE_SIMPLIFIER_H_
 | 
					#define _BASE_SIMPLIFIER_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include"expr_map.h"
 | 
					#include"expr_map.h"
 | 
				
			||||||
 | 
					#include"ast_pp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
   \brief Implements basic functionality used by expression simplifiers.
 | 
					   \brief Implements basic functionality used by expression simplifiers.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
class base_simplifier {
 | 
					class base_simplifier {
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    ast_manager &                  m_manager;
 | 
					    ast_manager &                  m;
 | 
				
			||||||
    expr_map                       m_cache;
 | 
					    expr_map                       m_cache;
 | 
				
			||||||
    ptr_vector<expr>               m_todo;
 | 
					    ptr_vector<expr>               m_todo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void cache_result(expr * n, expr * r, proof * p) { m_cache.insert(n, r, p); }
 | 
					    void cache_result(expr * n, expr * r, proof * p) { 
 | 
				
			||||||
 | 
					        m_cache.insert(n, r, p); 
 | 
				
			||||||
 | 
					        CTRACE("simplifier", !is_rewrite_proof(n, r, p),
 | 
				
			||||||
 | 
					               tout << mk_pp(n, m) << "\n";
 | 
				
			||||||
 | 
					               tout << mk_pp(r, m) << "\n";
 | 
				
			||||||
 | 
					               tout << mk_pp(p, m) << "\n";);
 | 
				
			||||||
 | 
					        SASSERT(is_rewrite_proof(n, r, p));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    void reset_cache() { m_cache.reset(); }
 | 
					    void reset_cache() { m_cache.reset(); }
 | 
				
			||||||
    void flush_cache() { m_cache.flush(); }
 | 
					    void flush_cache() { m_cache.flush(); }
 | 
				
			||||||
    void get_cached(expr * n, expr * & r, proof * & p) const { m_cache.get(n, r, p); }
 | 
					    void get_cached(expr * n, expr * & r, proof * & p) const { m_cache.get(n, r, p); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void reinitialize() { m_cache.set_store_proofs(m.fine_grain_proofs()); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void visit(expr * n, bool & visited) {
 | 
					    void visit(expr * n, bool & visited) {
 | 
				
			||||||
        if (!is_cached(n)) {
 | 
					        if (!is_cached(n)) {
 | 
				
			||||||
            m_todo.push_back(n);
 | 
					            m_todo.push_back(n);
 | 
				
			||||||
| 
						 | 
					@ -44,11 +55,22 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    base_simplifier(ast_manager & m):
 | 
					    base_simplifier(ast_manager & m):
 | 
				
			||||||
        m_manager(m),
 | 
					        m(m),
 | 
				
			||||||
        m_cache(m, m.fine_grain_proofs()) {
 | 
					        m_cache(m, m.fine_grain_proofs()) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    bool is_cached(expr * n) const {  return m_cache.contains(n); }
 | 
					    bool is_cached(expr * n) const {  return m_cache.contains(n); }
 | 
				
			||||||
    ast_manager & get_manager() { return m_manager; }
 | 
					    ast_manager & get_manager() { return m; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_rewrite_proof(expr* n, expr* r, proof* p) {
 | 
				
			||||||
 | 
					        if (p && 
 | 
				
			||||||
 | 
					            !m.is_undef_proof(p) && 
 | 
				
			||||||
 | 
					            !(m.has_fact(p) && 
 | 
				
			||||||
 | 
					              (m.is_eq(m.get_fact(p)) || m.is_oeq(m.get_fact(p)) || m.is_iff(m.get_fact(p))) && 
 | 
				
			||||||
 | 
					              to_app(m.get_fact(p))->get_arg(0) == n && 
 | 
				
			||||||
 | 
					              to_app(m.get_fact(p))->get_arg(1) == r)) return false;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return (!m.fine_grain_proofs() || p || (n == r));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _BASE_SIMPLIFIER_H_ */
 | 
					#endif /* _BASE_SIMPLIFIER_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,11 +100,11 @@ bool bv_elim_star::visit_quantifier(quantifier* q) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void bv_elim_star::reduce1_quantifier(quantifier* q) {
 | 
					void bv_elim_star::reduce1_quantifier(quantifier* q) {
 | 
				
			||||||
    quantifier_ref r(m_manager);
 | 
					    quantifier_ref r(m);
 | 
				
			||||||
    proof_ref pr(m_manager);
 | 
					    proof_ref pr(m);
 | 
				
			||||||
    m_bv_elim.elim(q, r);
 | 
					    m_bv_elim.elim(q, r);
 | 
				
			||||||
    if (m_manager.fine_grain_proofs()) {
 | 
					    if (m.fine_grain_proofs()) {
 | 
				
			||||||
        pr = m_manager.mk_rewrite(q, r.get());
 | 
					        pr = m.mk_rewrite(q, r.get());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        pr = 0;
 | 
					        pr = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,6 +81,8 @@ bool datatype_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr *
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        UNREACHABLE();
 | 
					        UNREACHABLE();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    case OP_DT_UPDATE_FIELD:
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        UNREACHABLE();
 | 
					        UNREACHABLE();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,20 +203,20 @@ void elim_bounds_star::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
        cache_result(q, q, 0); 
 | 
					        cache_result(q, q, 0); 
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    quantifier_ref new_q(m_manager);
 | 
					    quantifier_ref new_q(m);
 | 
				
			||||||
    expr * new_body = 0;
 | 
					    expr * new_body = 0;
 | 
				
			||||||
    proof * new_pr;
 | 
					    proof * new_pr;
 | 
				
			||||||
    get_cached(q->get_expr(), new_body, new_pr);
 | 
					    get_cached(q->get_expr(), new_body, new_pr);
 | 
				
			||||||
    new_q = m_manager.update_quantifier(q, new_body);
 | 
					    new_q = m.update_quantifier(q, new_body);
 | 
				
			||||||
    expr_ref r(m_manager);
 | 
					    expr_ref r(m);
 | 
				
			||||||
    m_elim(new_q, r);
 | 
					    m_elim(new_q, r);
 | 
				
			||||||
    if (q == r.get()) {
 | 
					    if (q == r.get()) {
 | 
				
			||||||
        cache_result(q, q, 0);
 | 
					        cache_result(q, q, 0);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    proof_ref pr(m_manager);
 | 
					    proof_ref pr(m);
 | 
				
			||||||
    if (m_manager.fine_grain_proofs())
 | 
					    if (m.fine_grain_proofs())
 | 
				
			||||||
        pr = m_manager.mk_rewrite(q, r); // TODO: improve justification
 | 
					        pr = m.mk_rewrite(q, r); // TODO: improve justification
 | 
				
			||||||
    cache_result(q, r, pr);
 | 
					    cache_result(q, r, pr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,7 +187,7 @@ pull_ite_tree_star::pull_ite_tree_star(ast_manager & m, simplifier & s):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool pull_ite_tree_star::get_subst(expr * n, expr_ref & r, proof_ref & p) {
 | 
					bool pull_ite_tree_star::get_subst(expr * n, expr_ref & r, proof_ref & p) {
 | 
				
			||||||
    if (is_app(n) && is_target(to_app(n))) {
 | 
					    if (is_app(n) && is_target(to_app(n))) {
 | 
				
			||||||
        app_ref tmp(m_manager);
 | 
					        app_ref tmp(m);
 | 
				
			||||||
        m_proc(to_app(n), tmp, p);
 | 
					        m_proc(to_app(n), tmp, p);
 | 
				
			||||||
        r = tmp;
 | 
					        r = tmp;
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
| 
						 | 
					@ -199,10 +199,10 @@ bool pull_cheap_ite_tree_star::is_target(app * n) const {
 | 
				
			||||||
    bool r = 
 | 
					    bool r = 
 | 
				
			||||||
        n->get_num_args() == 2 &&
 | 
					        n->get_num_args() == 2 &&
 | 
				
			||||||
        n->get_family_id() != null_family_id &&
 | 
					        n->get_family_id() != null_family_id &&
 | 
				
			||||||
        m_manager.is_bool(n) &&
 | 
					        m.is_bool(n) &&
 | 
				
			||||||
        (m_manager.is_value(n->get_arg(0)) || m_manager.is_value(n->get_arg(1))) &&
 | 
					        (m.is_value(n->get_arg(0)) || m.is_value(n->get_arg(1))) &&
 | 
				
			||||||
        (m_manager.is_term_ite(n->get_arg(0)) || m_manager.is_term_ite(n->get_arg(1)));
 | 
					        (m.is_term_ite(n->get_arg(0)) || m.is_term_ite(n->get_arg(1)));
 | 
				
			||||||
    TRACE("pull_ite_target", tout << mk_pp(n, m_manager) << "\nresult: " << r << "\n";);
 | 
					    TRACE("pull_ite_target", tout << mk_pp(n, m) << "\nresult: " << r << "\n";);
 | 
				
			||||||
    return r;
 | 
					    return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ push_app_ite::~push_app_ite() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int push_app_ite::has_ite_arg(unsigned num_args, expr * const * args) {
 | 
					int push_app_ite::has_ite_arg(unsigned num_args, expr * const * args) {
 | 
				
			||||||
    for (unsigned i = 0; i < num_args; i++)
 | 
					    for (unsigned i = 0; i < num_args; i++)
 | 
				
			||||||
        if (m_manager.is_ite(args[i]))
 | 
					        if (m.is_ite(args[i]))
 | 
				
			||||||
            return i;
 | 
					            return i;
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -53,10 +53,10 @@ void push_app_ite::apply(func_decl * decl, unsigned num_args, expr * const * arg
 | 
				
			||||||
    expr ** args_prime      = const_cast<expr**>(args);
 | 
					    expr ** args_prime      = const_cast<expr**>(args);
 | 
				
			||||||
    expr * old              = args_prime[ite_arg_idx];
 | 
					    expr * old              = args_prime[ite_arg_idx];
 | 
				
			||||||
    args_prime[ite_arg_idx] = t;
 | 
					    args_prime[ite_arg_idx] = t;
 | 
				
			||||||
    expr_ref t_new(m_manager);
 | 
					    expr_ref t_new(m);
 | 
				
			||||||
    apply(decl, num_args, args_prime, t_new);
 | 
					    apply(decl, num_args, args_prime, t_new);
 | 
				
			||||||
    args_prime[ite_arg_idx] = e;
 | 
					    args_prime[ite_arg_idx] = e;
 | 
				
			||||||
    expr_ref e_new(m_manager);
 | 
					    expr_ref e_new(m);
 | 
				
			||||||
    apply(decl, num_args, args_prime, e_new);
 | 
					    apply(decl, num_args, args_prime, e_new);
 | 
				
			||||||
    args_prime[ite_arg_idx] = old;
 | 
					    args_prime[ite_arg_idx] = old;
 | 
				
			||||||
    expr * new_args[3] = { c, t_new, e_new };
 | 
					    expr * new_args[3] = { c, t_new, e_new };
 | 
				
			||||||
| 
						 | 
					@ -67,11 +67,11 @@ void push_app_ite::apply(func_decl * decl, unsigned num_args, expr * const * arg
 | 
				
			||||||
   \brief Default (conservative) implementation. Return true if there one and only one ite-term argument.
 | 
					   \brief Default (conservative) implementation. Return true if there one and only one ite-term argument.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
bool push_app_ite::is_target(func_decl * decl, unsigned num_args, expr * const * args) {
 | 
					bool push_app_ite::is_target(func_decl * decl, unsigned num_args, expr * const * args) {
 | 
				
			||||||
    if (m_manager.is_ite(decl))
 | 
					    if (m.is_ite(decl))
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    bool found_ite = false;
 | 
					    bool found_ite = false;
 | 
				
			||||||
    for (unsigned i = 0; i < num_args; i++) {
 | 
					    for (unsigned i = 0; i < num_args; i++) {
 | 
				
			||||||
        if (m_manager.is_ite(args[i]) && !m_manager.is_bool(args[i])) {
 | 
					        if (m.is_ite(args[i]) && !m.is_bool(args[i])) {
 | 
				
			||||||
            if (found_ite) {
 | 
					            if (found_ite) {
 | 
				
			||||||
                if (m_conservative)
 | 
					                if (m_conservative)
 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,7 @@ bool push_app_ite::is_target(func_decl * decl, unsigned num_args, expr * const *
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    CTRACE("push_app_ite", found_ite, tout << "found target for push app ite:\n";
 | 
					    CTRACE("push_app_ite", found_ite, tout << "found target for push app ite:\n";
 | 
				
			||||||
          tout << decl->get_name();
 | 
					          tout << decl->get_name();
 | 
				
			||||||
          for (unsigned i = 0; i < num_args; i++) tout << " " << mk_pp(args[i], m_manager);
 | 
					          for (unsigned i = 0; i < num_args; i++) tout << " " << mk_pp(args[i], m);
 | 
				
			||||||
          tout << "\n";);
 | 
					          tout << "\n";);
 | 
				
			||||||
    return found_ite;
 | 
					    return found_ite;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -94,19 +94,19 @@ void push_app_ite::operator()(expr * s, expr_ref & r, proof_ref & p) {
 | 
				
			||||||
    reduce_core(s);
 | 
					    reduce_core(s);
 | 
				
			||||||
    get_cached(s, result, result_proof);
 | 
					    get_cached(s, result, result_proof);
 | 
				
			||||||
    r = result;
 | 
					    r = result;
 | 
				
			||||||
    switch (m_manager.proof_mode()) {
 | 
					    switch (m.proof_mode()) {
 | 
				
			||||||
    case PGM_DISABLED:
 | 
					    case PGM_DISABLED:
 | 
				
			||||||
        p = m_manager.mk_undef_proof();
 | 
					        p = m.mk_undef_proof();
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case PGM_COARSE:
 | 
					    case PGM_COARSE:
 | 
				
			||||||
        if (result == s)
 | 
					        if (result == s)
 | 
				
			||||||
            p = m_manager.mk_reflexivity(s);
 | 
					            p = m.mk_reflexivity(s);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            p = m_manager.mk_rewrite_star(s, result, 0, 0);
 | 
					            p = m.mk_rewrite_star(s, result, 0, 0);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case PGM_FINE:
 | 
					    case PGM_FINE:
 | 
				
			||||||
        if (result == s)
 | 
					        if (result == s)
 | 
				
			||||||
            p = m_manager.mk_reflexivity(s);
 | 
					            p = m.mk_reflexivity(s);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            p = result_proof;
 | 
					            p = result_proof;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
| 
						 | 
					@ -171,24 +171,24 @@ void push_app_ite::reduce1_app(app * n) {
 | 
				
			||||||
    m_args.reset();
 | 
					    m_args.reset();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    func_decl * decl = n->get_decl();
 | 
					    func_decl * decl = n->get_decl();
 | 
				
			||||||
    proof_ref p1(m_manager);
 | 
					    proof_ref p1(m);
 | 
				
			||||||
    get_args(n, m_args, p1);
 | 
					    get_args(n, m_args, p1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expr_ref r(m_manager);
 | 
					    expr_ref r(m);
 | 
				
			||||||
    if (is_target(decl, m_args.size(), m_args.c_ptr()))
 | 
					    if (is_target(decl, m_args.size(), m_args.c_ptr()))
 | 
				
			||||||
        apply(decl, m_args.size(), m_args.c_ptr(), r);
 | 
					        apply(decl, m_args.size(), m_args.c_ptr(), r);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        mk_app(decl, m_args.size(), m_args.c_ptr(), r);
 | 
					        mk_app(decl, m_args.size(), m_args.c_ptr(), r);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (!m_manager.fine_grain_proofs())
 | 
					    if (!m.fine_grain_proofs())
 | 
				
			||||||
        cache_result(n, r, 0);
 | 
					        cache_result(n, r, 0);
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        expr * s = m_manager.mk_app(decl, m_args.size(), m_args.c_ptr());
 | 
					        expr * s = m.mk_app(decl, m_args.size(), m_args.c_ptr());
 | 
				
			||||||
        proof * p;
 | 
					        proof * p;
 | 
				
			||||||
        if (n == r)
 | 
					        if (n == r)
 | 
				
			||||||
            p = 0;
 | 
					            p = 0;
 | 
				
			||||||
        else if (r != s) 
 | 
					        else if (r != s) 
 | 
				
			||||||
            p = m_manager.mk_transitivity(p1, m_manager.mk_rewrite(s, r));
 | 
					            p = m.mk_transitivity(p1, m.mk_rewrite(s, r));
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            p = p1;
 | 
					            p = p1;
 | 
				
			||||||
        cache_result(n, r, p);
 | 
					        cache_result(n, r, p);
 | 
				
			||||||
| 
						 | 
					@ -200,8 +200,8 @@ void push_app_ite::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
    proof * new_body_pr;
 | 
					    proof * new_body_pr;
 | 
				
			||||||
    get_cached(q->get_expr(), new_body, new_body_pr);
 | 
					    get_cached(q->get_expr(), new_body, new_body_pr);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    quantifier * new_q = m_manager.update_quantifier(q, new_body);
 | 
					    quantifier * new_q = m.update_quantifier(q, new_body);
 | 
				
			||||||
    proof *      p     = q == new_q ? 0 : m_manager.mk_quant_intro(q, new_q, new_body_pr);   
 | 
					    proof *      p     = q == new_q ? 0 : m.mk_quant_intro(q, new_q, new_body_pr);   
 | 
				
			||||||
    cache_result(q, new_q, p);
 | 
					    cache_result(q, new_q, p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,16 +61,18 @@ void simplifier::enable_ac_support(bool flag) {
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
void simplifier::operator()(expr * s, expr_ref & r, proof_ref & p) {
 | 
					void simplifier::operator()(expr * s, expr_ref & r, proof_ref & p) {
 | 
				
			||||||
    m_need_reset = true;
 | 
					    m_need_reset = true;
 | 
				
			||||||
 | 
					    reinitialize();
 | 
				
			||||||
 | 
					    expr  * s_orig = s;
 | 
				
			||||||
    expr  * old_s;
 | 
					    expr  * old_s;
 | 
				
			||||||
    expr  * result;
 | 
					    expr  * result;
 | 
				
			||||||
    proof * result_proof;
 | 
					    proof * result_proof;
 | 
				
			||||||
    switch (m_manager.proof_mode()) {
 | 
					    switch (m.proof_mode()) {
 | 
				
			||||||
    case PGM_DISABLED: // proof generation is disabled.
 | 
					    case PGM_DISABLED: // proof generation is disabled.
 | 
				
			||||||
        reduce_core(s); 
 | 
					        reduce_core(s); 
 | 
				
			||||||
        // after executing reduce_core, the result of the simplification is in the cache
 | 
					        // after executing reduce_core, the result of the simplification is in the cache
 | 
				
			||||||
        get_cached(s, result, result_proof);
 | 
					        get_cached(s, result, result_proof);
 | 
				
			||||||
        r = result;
 | 
					        r = result;
 | 
				
			||||||
        p = m_manager.mk_undef_proof();
 | 
					        p = m.mk_undef_proof();
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case PGM_COARSE: // coarse proofs... in this case, we do not produce a step by step (fine grain) proof to show the equivalence (or equisatisfiability) of s an r.
 | 
					    case PGM_COARSE: // coarse proofs... in this case, we do not produce a step by step (fine grain) proof to show the equivalence (or equisatisfiability) of s an r.
 | 
				
			||||||
        m_subst_proofs.reset(); // m_subst_proofs is an auxiliary vector that is used to justify substitutions. See comment on method get_subst. 
 | 
					        m_subst_proofs.reset(); // m_subst_proofs is an auxiliary vector that is used to justify substitutions. See comment on method get_subst. 
 | 
				
			||||||
| 
						 | 
					@ -78,10 +80,10 @@ void simplifier::operator()(expr * s, expr_ref & r, proof_ref & p) {
 | 
				
			||||||
        get_cached(s, result, result_proof);
 | 
					        get_cached(s, result, result_proof);
 | 
				
			||||||
        r = result;
 | 
					        r = result;
 | 
				
			||||||
        if (result == s)
 | 
					        if (result == s)
 | 
				
			||||||
            p = m_manager.mk_reflexivity(s);
 | 
					            p = m.mk_reflexivity(s);
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            remove_duplicates(m_subst_proofs);
 | 
					            remove_duplicates(m_subst_proofs);
 | 
				
			||||||
            p = m_manager.mk_rewrite_star(s, result, m_subst_proofs.size(), m_subst_proofs.c_ptr());
 | 
					            p = m.mk_rewrite_star(s, result, m_subst_proofs.size(), m_subst_proofs.c_ptr());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case PGM_FINE: // fine grain proofs... in this mode, every proof step (or most of them) is described.
 | 
					    case PGM_FINE: // fine grain proofs... in this mode, every proof step (or most of them) is described.
 | 
				
			||||||
| 
						 | 
					@ -90,17 +92,20 @@ void simplifier::operator()(expr * s, expr_ref & r, proof_ref & p) {
 | 
				
			||||||
        // keep simplyfing until no further simplifications are possible.
 | 
					        // keep simplyfing until no further simplifications are possible.
 | 
				
			||||||
        while (s != old_s) {
 | 
					        while (s != old_s) {
 | 
				
			||||||
            TRACE("simplifier", tout << "simplification pass... " << s->get_id() << "\n";);
 | 
					            TRACE("simplifier", tout << "simplification pass... " << s->get_id() << "\n";);
 | 
				
			||||||
            TRACE("simplifier_loop", tout << mk_ll_pp(s, m_manager) << "\n";);
 | 
					            TRACE("simplifier_loop", tout << mk_ll_pp(s, m) << "\n";);
 | 
				
			||||||
            reduce_core(s);
 | 
					            reduce_core(s);
 | 
				
			||||||
            get_cached(s, result, result_proof);
 | 
					            get_cached(s, result, result_proof);
 | 
				
			||||||
            if (result_proof != 0)
 | 
					            SASSERT(is_rewrite_proof(s, result, result_proof));
 | 
				
			||||||
 | 
					            if (result_proof != 0) {
 | 
				
			||||||
                m_proofs.push_back(result_proof);
 | 
					                m_proofs.push_back(result_proof);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            old_s = s;
 | 
					            old_s = s;
 | 
				
			||||||
            s     = result;
 | 
					            s     = result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        SASSERT(s != 0);
 | 
					        SASSERT(s != 0);
 | 
				
			||||||
        r = s;
 | 
					        r = s;
 | 
				
			||||||
        p = m_proofs.empty() ? m_manager.mk_reflexivity(s) : m_manager.mk_transitivity(m_proofs.size(), m_proofs.c_ptr());
 | 
					        p = m_proofs.empty() ? m.mk_reflexivity(s) : m.mk_transitivity(m_proofs.size(), m_proofs.c_ptr());
 | 
				
			||||||
 | 
					        SASSERT(is_rewrite_proof(s_orig, r, p));
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        UNREACHABLE();
 | 
					        UNREACHABLE();
 | 
				
			||||||
| 
						 | 
					@ -259,9 +264,9 @@ void simplifier::reduce1(expr * n) {
 | 
				
			||||||
   specific simplifications via plugins.
 | 
					   specific simplifications via plugins.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
void simplifier::reduce1_app(app * n) {
 | 
					void simplifier::reduce1_app(app * n) {
 | 
				
			||||||
    expr_ref r(m_manager);
 | 
					    expr_ref r(m);
 | 
				
			||||||
    proof_ref p(m_manager);
 | 
					    proof_ref p(m);
 | 
				
			||||||
    TRACE("reduce", tout << "reducing...\n" << mk_pp(n, m_manager) << "\n";);
 | 
					    TRACE("reduce", tout << "reducing...\n" << mk_pp(n, m) << "\n";);
 | 
				
			||||||
    if (get_subst(n, r, p)) {
 | 
					    if (get_subst(n, r, p)) {
 | 
				
			||||||
        TRACE("reduce", tout << "applying substitution...\n";);
 | 
					        TRACE("reduce", tout << "applying substitution...\n";);
 | 
				
			||||||
        cache_result(n, r, p);
 | 
					        cache_result(n, r, p);
 | 
				
			||||||
| 
						 | 
					@ -279,7 +284,7 @@ void simplifier::reduce1_app(app * n) {
 | 
				
			||||||
void simplifier::reduce1_app_core(app * n) {
 | 
					void simplifier::reduce1_app_core(app * n) {
 | 
				
			||||||
    m_args.reset();
 | 
					    m_args.reset();
 | 
				
			||||||
    func_decl * decl = n->get_decl();
 | 
					    func_decl * decl = n->get_decl();
 | 
				
			||||||
    proof_ref p1(m_manager);
 | 
					    proof_ref p1(m);
 | 
				
			||||||
    // Stores the new arguments of n in m_args.
 | 
					    // Stores the new arguments of n in m_args.
 | 
				
			||||||
    // Let n be of the form
 | 
					    // Let n be of the form
 | 
				
			||||||
    // (decl arg_0 ... arg_{n-1})
 | 
					    // (decl arg_0 ... arg_{n-1})
 | 
				
			||||||
| 
						 | 
					@ -296,23 +301,23 @@ void simplifier::reduce1_app_core(app * n) {
 | 
				
			||||||
    //   If none of the arguments have been simplified, and n is not a theory symbol,
 | 
					    //   If none of the arguments have been simplified, and n is not a theory symbol,
 | 
				
			||||||
    //   Then no simplification is possible, and we can cache the result of the simplification of n as n.
 | 
					    //   Then no simplification is possible, and we can cache the result of the simplification of n as n.
 | 
				
			||||||
    if (has_new_args || decl->get_family_id() != null_family_id) {
 | 
					    if (has_new_args || decl->get_family_id() != null_family_id) {
 | 
				
			||||||
        expr_ref r(m_manager);
 | 
					        expr_ref r(m);
 | 
				
			||||||
        TRACE("reduce", tout << "reduce1_app\n"; for(unsigned i = 0; i < m_args.size(); i++) tout << mk_ll_pp(m_args[i], m_manager););
 | 
					        TRACE("reduce", tout << "reduce1_app\n"; for(unsigned i = 0; i < m_args.size(); i++) tout << mk_ll_pp(m_args[i], m););
 | 
				
			||||||
        // the method mk_app invokes get_subst and plugins to simplify
 | 
					        // the method mk_app invokes get_subst and plugins to simplify
 | 
				
			||||||
        // (decl arg_0' ... arg_{n-1}')
 | 
					        // (decl arg_0' ... arg_{n-1}')
 | 
				
			||||||
        mk_app(decl, m_args.size(), m_args.c_ptr(), r);
 | 
					        mk_app(decl, m_args.size(), m_args.c_ptr(), r);
 | 
				
			||||||
        if (!m_manager.fine_grain_proofs()) {
 | 
					        if (!m.fine_grain_proofs()) {
 | 
				
			||||||
            cache_result(n, r, 0);
 | 
					            cache_result(n, r, 0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            expr * s = m_manager.mk_app(decl, m_args.size(), m_args.c_ptr());
 | 
					            expr * s = m.mk_app(decl, m_args.size(), m_args.c_ptr());
 | 
				
			||||||
            proof * p;
 | 
					            proof * p;
 | 
				
			||||||
            if (n == r)
 | 
					            if (n == r)
 | 
				
			||||||
                p = 0;
 | 
					                p = 0;
 | 
				
			||||||
            else if (r != s) 
 | 
					            else if (r != s) 
 | 
				
			||||||
                // we use a "theory rewrite generic proof" to justify the step
 | 
					                // we use a "theory rewrite generic proof" to justify the step
 | 
				
			||||||
                // s = (decl arg_0' ... arg_{n-1}') --> r
 | 
					                // s = (decl arg_0' ... arg_{n-1}') --> r
 | 
				
			||||||
                p = m_manager.mk_transitivity(p1, m_manager.mk_rewrite(s, r));
 | 
					                p = m.mk_transitivity(p1, m.mk_rewrite(s, r));
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                p = p1;
 | 
					                p = p1;
 | 
				
			||||||
            cache_result(n, r, p);
 | 
					            cache_result(n, r, p);
 | 
				
			||||||
| 
						 | 
					@ -354,11 +359,11 @@ bool is_ac_vector(app * n) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void simplifier::reduce1_ac_app_core(app * n) {
 | 
					void simplifier::reduce1_ac_app_core(app * n) {
 | 
				
			||||||
    app_ref    n_c(m_manager);
 | 
					    app_ref    n_c(m);
 | 
				
			||||||
    proof_ref  p1(m_manager);
 | 
					    proof_ref  p1(m);
 | 
				
			||||||
    mk_ac_congruent_term(n, n_c, p1);
 | 
					    mk_ac_congruent_term(n, n_c, p1);
 | 
				
			||||||
    TRACE("ac", tout << "expr:\n" << mk_pp(n, m_manager) << "\ncongruent term:\n" << mk_pp(n_c, m_manager) << "\n";);
 | 
					    TRACE("ac", tout << "expr:\n" << mk_pp(n, m) << "\ncongruent term:\n" << mk_pp(n_c, m) << "\n";);
 | 
				
			||||||
    expr_ref r(m_manager); 
 | 
					    expr_ref r(m); 
 | 
				
			||||||
    func_decl * decl = n->get_decl();
 | 
					    func_decl * decl = n->get_decl();
 | 
				
			||||||
    family_id fid    = decl->get_family_id();
 | 
					    family_id fid    = decl->get_family_id();
 | 
				
			||||||
    plugin * p       = get_plugin(fid);
 | 
					    plugin * p       = get_plugin(fid);
 | 
				
			||||||
| 
						 | 
					@ -376,7 +381,7 @@ void simplifier::reduce1_ac_app_core(app * n) {
 | 
				
			||||||
            // done...
 | 
					            // done...
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            r = m_manager.mk_app(decl, m_args.size(), m_args.c_ptr());
 | 
					            r = m.mk_app(decl, m_args.size(), m_args.c_ptr());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
| 
						 | 
					@ -385,7 +390,7 @@ void simplifier::reduce1_ac_app_core(app * n) {
 | 
				
			||||||
        get_ac_args(n_c, m_args, m_mults);
 | 
					        get_ac_args(n_c, m_args, m_mults);
 | 
				
			||||||
        TRACE("ac", tout << "AC args:\n";
 | 
					        TRACE("ac", tout << "AC args:\n";
 | 
				
			||||||
              for (unsigned i = 0; i < m_args.size(); i++) {
 | 
					              for (unsigned i = 0; i < m_args.size(); i++) {
 | 
				
			||||||
                  tout << mk_pp(m_args[i], m_manager) << " * " << m_mults[i] << "\n";
 | 
					                  tout << mk_pp(m_args[i], m) << " * " << m_mults[i] << "\n";
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
        if (p != 0 && p->reduce(decl, m_args.size(), m_mults.c_ptr(), m_args.c_ptr(), r)) {
 | 
					        if (p != 0 && p->reduce(decl, m_args.size(), m_mults.c_ptr(), m_args.c_ptr(), r)) {
 | 
				
			||||||
            // done...
 | 
					            // done...
 | 
				
			||||||
| 
						 | 
					@ -393,12 +398,12 @@ void simplifier::reduce1_ac_app_core(app * n) {
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            ptr_buffer<expr> new_args;
 | 
					            ptr_buffer<expr> new_args;
 | 
				
			||||||
            expand_args(m_args.size(), m_mults.c_ptr(), m_args.c_ptr(), new_args);
 | 
					            expand_args(m_args.size(), m_mults.c_ptr(), m_args.c_ptr(), new_args);
 | 
				
			||||||
            r = m_manager.mk_app(decl, new_args.size(), new_args.c_ptr());
 | 
					            r = m.mk_app(decl, new_args.size(), new_args.c_ptr());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    TRACE("ac", tout << "AC result:\n" << mk_pp(r, m_manager) << "\n";);
 | 
					    TRACE("ac", tout << "AC result:\n" << mk_pp(r, m) << "\n";);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!m_manager.fine_grain_proofs()) {
 | 
					    if (!m.fine_grain_proofs()) {
 | 
				
			||||||
        cache_result(n, r, 0);
 | 
					        cache_result(n, r, 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
| 
						 | 
					@ -406,7 +411,7 @@ void simplifier::reduce1_ac_app_core(app * n) {
 | 
				
			||||||
        if (n == r.get())
 | 
					        if (n == r.get())
 | 
				
			||||||
            p = 0;
 | 
					            p = 0;
 | 
				
			||||||
        else if (r.get() != n_c.get()) 
 | 
					        else if (r.get() != n_c.get()) 
 | 
				
			||||||
            p = m_manager.mk_transitivity(p1, m_manager.mk_rewrite(n_c, r));
 | 
					            p = m.mk_transitivity(p1, m.mk_rewrite(n_c, r));
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            p = p1;
 | 
					            p = p1;
 | 
				
			||||||
        cache_result(n, r, p);
 | 
					        cache_result(n, r, p);
 | 
				
			||||||
| 
						 | 
					@ -416,8 +421,8 @@ void simplifier::reduce1_ac_app_core(app * n) {
 | 
				
			||||||
static unsigned g_rewrite_lemma_id = 0;
 | 
					static unsigned g_rewrite_lemma_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void simplifier::dump_rewrite_lemma(func_decl * decl, unsigned num_args, expr * const * args, expr* result) {
 | 
					void simplifier::dump_rewrite_lemma(func_decl * decl, unsigned num_args, expr * const * args, expr* result) {
 | 
				
			||||||
    expr_ref arg(m_manager);
 | 
					    expr_ref arg(m);
 | 
				
			||||||
    arg = m_manager.mk_app(decl, num_args, args);
 | 
					    arg = m.mk_app(decl, num_args, args);
 | 
				
			||||||
    if (arg.get() != result) {
 | 
					    if (arg.get() != result) {
 | 
				
			||||||
        char buffer[128];
 | 
					        char buffer[128];
 | 
				
			||||||
#ifdef _WINDOWS
 | 
					#ifdef _WINDOWS
 | 
				
			||||||
| 
						 | 
					@ -425,11 +430,11 @@ void simplifier::dump_rewrite_lemma(func_decl * decl, unsigned num_args, expr *
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        sprintf(buffer, "rewrite_lemma_%d.smt", g_rewrite_lemma_id);
 | 
					        sprintf(buffer, "rewrite_lemma_%d.smt", g_rewrite_lemma_id);
 | 
				
			||||||
#endif        
 | 
					#endif        
 | 
				
			||||||
        ast_smt_pp pp(m_manager);
 | 
					        ast_smt_pp pp(m);
 | 
				
			||||||
        pp.set_benchmark_name("rewrite_lemma");
 | 
					        pp.set_benchmark_name("rewrite_lemma");
 | 
				
			||||||
        pp.set_status("unsat");
 | 
					        pp.set_status("unsat");
 | 
				
			||||||
        expr_ref n(m_manager);
 | 
					        expr_ref n(m);
 | 
				
			||||||
        n = m_manager.mk_not(m_manager.mk_eq(arg.get(), result));
 | 
					        n = m.mk_not(m.mk_eq(arg.get(), result));
 | 
				
			||||||
        std::ofstream out(buffer);
 | 
					        std::ofstream out(buffer);
 | 
				
			||||||
        pp.display(out, n);
 | 
					        pp.display(out, n);
 | 
				
			||||||
        out.close();
 | 
					        out.close();
 | 
				
			||||||
| 
						 | 
					@ -445,14 +450,14 @@ void simplifier::dump_rewrite_lemma(func_decl * decl, unsigned num_args, expr *
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
void simplifier::mk_app(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & result) {
 | 
					void simplifier::mk_app(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & result) {
 | 
				
			||||||
    m_need_reset = true;
 | 
					    m_need_reset = true;
 | 
				
			||||||
    if (m_manager.is_eq(decl)) {
 | 
					    if (m.is_eq(decl)) {
 | 
				
			||||||
        sort * s = m_manager.get_sort(args[0]);
 | 
					        sort * s = m.get_sort(args[0]);
 | 
				
			||||||
        plugin * p = get_plugin(s->get_family_id());
 | 
					        plugin * p = get_plugin(s->get_family_id());
 | 
				
			||||||
        if (p != 0 && p->reduce_eq(args[0], args[1], result))
 | 
					        if (p != 0 && p->reduce_eq(args[0], args[1], result))
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (m_manager.is_distinct(decl)) {
 | 
					    else if (m.is_distinct(decl)) {
 | 
				
			||||||
        sort * s = m_manager.get_sort(args[0]);
 | 
					        sort * s = m.get_sort(args[0]);
 | 
				
			||||||
        plugin * p = get_plugin(s->get_family_id());
 | 
					        plugin * p = get_plugin(s->get_family_id());
 | 
				
			||||||
        if (p != 0 && p->reduce_distinct(num_args, args, result))
 | 
					        if (p != 0 && p->reduce_distinct(num_args, args, result))
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
| 
						 | 
					@ -464,7 +469,7 @@ void simplifier::mk_app(func_decl * decl, unsigned num_args, expr * const * args
 | 
				
			||||||
        //dump_rewrite_lemma(decl, num_args, args, result.get());
 | 
					        //dump_rewrite_lemma(decl, num_args, args, result.get());
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    result = m_manager.mk_app(decl, num_args, args);
 | 
					    result = m.mk_app(decl, num_args, args);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -484,7 +489,7 @@ void simplifier::mk_congruent_term(app * n, app_ref & r, proof_ref & p) {
 | 
				
			||||||
        get_cached(arg, new_arg, arg_proof);
 | 
					        get_cached(arg, new_arg, arg_proof);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CTRACE("simplifier_bug", (arg != new_arg) != (arg_proof != 0), 
 | 
					        CTRACE("simplifier_bug", (arg != new_arg) != (arg_proof != 0), 
 | 
				
			||||||
               tout << mk_ll_pp(arg, m_manager) << "\n---->\n" << mk_ll_pp(new_arg, m_manager) << "\n";
 | 
					               tout << mk_ll_pp(arg, m) << "\n---->\n" << mk_ll_pp(new_arg, m) << "\n";
 | 
				
			||||||
               tout << "#" << arg->get_id() << " #" << new_arg->get_id() << "\n";
 | 
					               tout << "#" << arg->get_id() << " #" << new_arg->get_id() << "\n";
 | 
				
			||||||
               tout << arg << " " << new_arg << "\n";);
 | 
					               tout << arg << " " << new_arg << "\n";);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -500,11 +505,11 @@ void simplifier::mk_congruent_term(app * n, app_ref & r, proof_ref & p) {
 | 
				
			||||||
        args.push_back(new_arg);
 | 
					        args.push_back(new_arg);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (has_new_args) {
 | 
					    if (has_new_args) {
 | 
				
			||||||
        r = m_manager.mk_app(n->get_decl(), args.size(), args.c_ptr());
 | 
					        r = m.mk_app(n->get_decl(), args.size(), args.c_ptr());
 | 
				
			||||||
        if (m_use_oeq)
 | 
					        if (m_use_oeq)
 | 
				
			||||||
            p = m_manager.mk_oeq_congruence(n, r, proofs.size(), proofs.c_ptr());
 | 
					            p = m.mk_oeq_congruence(n, r, proofs.size(), proofs.c_ptr());
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            p = m_manager.mk_congruence(n, r, proofs.size(), proofs.c_ptr());
 | 
					            p = m.mk_congruence(n, r, proofs.size(), proofs.c_ptr());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        r = n;
 | 
					        r = n;
 | 
				
			||||||
| 
						 | 
					@ -523,8 +528,8 @@ void simplifier::mk_congruent_term(app * n, app_ref & r, proof_ref & p) {
 | 
				
			||||||
bool simplifier::get_args(app * n, ptr_vector<expr> & result, proof_ref & p) {
 | 
					bool simplifier::get_args(app * n, ptr_vector<expr> & result, proof_ref & p) {
 | 
				
			||||||
    bool has_new_args  = false;
 | 
					    bool has_new_args  = false;
 | 
				
			||||||
    unsigned num       = n->get_num_args();
 | 
					    unsigned num       = n->get_num_args();
 | 
				
			||||||
    if (m_manager.fine_grain_proofs()) {
 | 
					    if (m.fine_grain_proofs()) {
 | 
				
			||||||
        app_ref r(m_manager);
 | 
					        app_ref r(m);
 | 
				
			||||||
        mk_congruent_term(n, r, p);
 | 
					        mk_congruent_term(n, r, p);
 | 
				
			||||||
        result.append(r->get_num_args(), r->get_args());
 | 
					        result.append(r->get_num_args(), r->get_args());
 | 
				
			||||||
        SASSERT(n->get_num_args() == result.size());
 | 
					        SASSERT(n->get_num_args() == result.size());
 | 
				
			||||||
| 
						 | 
					@ -582,7 +587,7 @@ void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) {
 | 
				
			||||||
                    new_args.push_back(new_arg);
 | 
					                    new_args.push_back(new_arg);
 | 
				
			||||||
                    if (arg != new_arg)
 | 
					                    if (arg != new_arg)
 | 
				
			||||||
                        has_new_arg = true;
 | 
					                        has_new_arg = true;
 | 
				
			||||||
                    if (m_manager.fine_grain_proofs()) {
 | 
					                    if (m.fine_grain_proofs()) {
 | 
				
			||||||
                        proof * pr = 0;
 | 
					                        proof * pr = 0;
 | 
				
			||||||
                        m_ac_pr_cache.find(to_app(arg), pr);
 | 
					                        m_ac_pr_cache.find(to_app(arg), pr);
 | 
				
			||||||
                        if (pr != 0)
 | 
					                        if (pr != 0)
 | 
				
			||||||
| 
						 | 
					@ -601,7 +606,7 @@ void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) {
 | 
				
			||||||
                new_args.push_back(new_arg);
 | 
					                new_args.push_back(new_arg);
 | 
				
			||||||
                if (arg != new_arg)
 | 
					                if (arg != new_arg)
 | 
				
			||||||
                    has_new_arg = true;
 | 
					                    has_new_arg = true;
 | 
				
			||||||
                if (m_manager.fine_grain_proofs() && pr != 0)
 | 
					                if (m.fine_grain_proofs() && pr != 0)
 | 
				
			||||||
                    new_arg_prs.push_back(pr);
 | 
					                    new_arg_prs.push_back(pr);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -610,14 +615,14 @@ void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) {
 | 
				
			||||||
            todo.pop_back();
 | 
					            todo.pop_back();
 | 
				
			||||||
            if (!has_new_arg) {
 | 
					            if (!has_new_arg) {
 | 
				
			||||||
                m_ac_cache.insert(curr, curr);
 | 
					                m_ac_cache.insert(curr, curr);
 | 
				
			||||||
                if (m_manager.fine_grain_proofs()) 
 | 
					                if (m.fine_grain_proofs()) 
 | 
				
			||||||
                    m_ac_pr_cache.insert(curr, 0);
 | 
					                    m_ac_pr_cache.insert(curr, 0);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                app * new_curr = m_manager.mk_app(f, new_args.size(), new_args.c_ptr());
 | 
					                app * new_curr = m.mk_app(f, new_args.size(), new_args.c_ptr());
 | 
				
			||||||
                m_ac_cache.insert(curr, new_curr);
 | 
					                m_ac_cache.insert(curr, new_curr);
 | 
				
			||||||
                if (m_manager.fine_grain_proofs()) {
 | 
					                if (m.fine_grain_proofs()) {
 | 
				
			||||||
                    proof * p = m_manager.mk_congruence(curr, new_curr, new_arg_prs.size(), new_arg_prs.c_ptr());
 | 
					                    proof * p = m.mk_congruence(curr, new_curr, new_arg_prs.size(), new_arg_prs.c_ptr());
 | 
				
			||||||
                    m_ac_pr_cache.insert(curr, p);
 | 
					                    m_ac_pr_cache.insert(curr, p);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -628,7 +633,7 @@ void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) {
 | 
				
			||||||
    app *   new_n = 0;
 | 
					    app *   new_n = 0;
 | 
				
			||||||
    m_ac_cache.find(n, new_n);
 | 
					    m_ac_cache.find(n, new_n);
 | 
				
			||||||
    r = new_n;
 | 
					    r = new_n;
 | 
				
			||||||
    if (m_manager.fine_grain_proofs()) {
 | 
					    if (m.fine_grain_proofs()) {
 | 
				
			||||||
        proof * new_pr = 0;
 | 
					        proof * new_pr = 0;
 | 
				
			||||||
        m_ac_pr_cache.find(n, new_pr);
 | 
					        m_ac_pr_cache.find(n, new_pr);
 | 
				
			||||||
        p = new_pr;
 | 
					        p = new_pr;
 | 
				
			||||||
| 
						 | 
					@ -719,7 +724,7 @@ void simplifier::get_ac_args(app * n, ptr_vector<expr> & args, vector<rational>
 | 
				
			||||||
    SASSERT(!sorted_exprs.empty());
 | 
					    SASSERT(!sorted_exprs.empty());
 | 
				
			||||||
    SASSERT(sorted_exprs[sorted_exprs.size()-1] == n);
 | 
					    SASSERT(sorted_exprs[sorted_exprs.size()-1] == n);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    TRACE("ac", tout << mk_ll_pp(n, m_manager, true, false) << "#" << n->get_id() << "\nsorted expressions...\n";
 | 
					    TRACE("ac", tout << mk_ll_pp(n, m, true, false) << "#" << n->get_id() << "\nsorted expressions...\n";
 | 
				
			||||||
          for (unsigned i = 0; i < sorted_exprs.size(); i++) {
 | 
					          for (unsigned i = 0; i < sorted_exprs.size(); i++) {
 | 
				
			||||||
              tout << "#" << sorted_exprs[i]->get_id() << " ";
 | 
					              tout << "#" << sorted_exprs[i]->get_id() << " ";
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
| 
						 | 
					@ -754,10 +759,10 @@ void simplifier::get_ac_args(app * n, ptr_vector<expr> & args, vector<rational>
 | 
				
			||||||
void simplifier::reduce1_quantifier(quantifier * q) {
 | 
					void simplifier::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
    expr *  new_body;
 | 
					    expr *  new_body;
 | 
				
			||||||
    proof * new_body_pr;
 | 
					    proof * new_body_pr;
 | 
				
			||||||
    SASSERT(is_well_sorted(m_manager, q));
 | 
					    SASSERT(is_well_sorted(m, q));
 | 
				
			||||||
    get_cached(q->get_expr(), new_body, new_body_pr);
 | 
					    get_cached(q->get_expr(), new_body, new_body_pr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    quantifier_ref q1(m_manager);
 | 
					    quantifier_ref q1(m);
 | 
				
			||||||
    proof * p1 = 0;
 | 
					    proof * p1 = 0;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (is_quantifier(new_body) && 
 | 
					    if (is_quantifier(new_body) && 
 | 
				
			||||||
| 
						 | 
					@ -774,7 +779,7 @@ void simplifier::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
        sorts.append(nested_q->get_num_decls(), nested_q->get_decl_sorts());
 | 
					        sorts.append(nested_q->get_num_decls(), nested_q->get_decl_sorts());
 | 
				
			||||||
        names.append(nested_q->get_num_decls(), nested_q->get_decl_names());
 | 
					        names.append(nested_q->get_num_decls(), nested_q->get_decl_names());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        q1 = m_manager.mk_quantifier(q->is_forall(),
 | 
					        q1 = m.mk_quantifier(q->is_forall(),
 | 
				
			||||||
                                     sorts.size(),
 | 
					                                     sorts.size(),
 | 
				
			||||||
                                     sorts.c_ptr(),
 | 
					                                     sorts.c_ptr(),
 | 
				
			||||||
                                     names.c_ptr(),
 | 
					                                     names.c_ptr(),
 | 
				
			||||||
| 
						 | 
					@ -783,13 +788,13 @@ void simplifier::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
                                     q->get_qid(),
 | 
					                                     q->get_qid(),
 | 
				
			||||||
                                     q->get_skid(),
 | 
					                                     q->get_skid(),
 | 
				
			||||||
                                     0, 0, 0, 0);
 | 
					                                     0, 0, 0, 0);
 | 
				
			||||||
        SASSERT(is_well_sorted(m_manager, q1));
 | 
					        SASSERT(is_well_sorted(m, q1));
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (m_manager.fine_grain_proofs()) {
 | 
					        if (m.fine_grain_proofs()) {
 | 
				
			||||||
            quantifier * q0 = m_manager.update_quantifier(q, new_body);
 | 
					            quantifier * q0 = m.update_quantifier(q, new_body);
 | 
				
			||||||
            proof * p0 = q == q0 ? 0 : m_manager.mk_quant_intro(q, q0, new_body_pr);
 | 
					            proof * p0 = q == q0 ? 0 : m.mk_quant_intro(q, q0, new_body_pr);
 | 
				
			||||||
            p1 = m_manager.mk_pull_quant(q0, q1);
 | 
					            p1 = m.mk_pull_quant(q0, q1);
 | 
				
			||||||
            p1 = m_manager.mk_transitivity(p0, p1);
 | 
					            p1 = m.mk_transitivity(p0, p1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
| 
						 | 
					@ -802,7 +807,7 @@ void simplifier::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
        unsigned num = q->get_num_patterns();
 | 
					        unsigned num = q->get_num_patterns();
 | 
				
			||||||
        for (unsigned i = 0; i < num; i++) {
 | 
					        for (unsigned i = 0; i < num; i++) {
 | 
				
			||||||
            get_cached(q->get_pattern(i), new_pattern, new_pattern_pr);
 | 
					            get_cached(q->get_pattern(i), new_pattern, new_pattern_pr);
 | 
				
			||||||
            if (m_manager.is_pattern(new_pattern)) {
 | 
					            if (m.is_pattern(new_pattern)) {
 | 
				
			||||||
                new_patterns.push_back(new_pattern);
 | 
					                new_patterns.push_back(new_pattern);
 | 
				
			||||||
            }            
 | 
					            }            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -815,7 +820,7 @@ void simplifier::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
        remove_duplicates(new_patterns);
 | 
					        remove_duplicates(new_patterns);
 | 
				
			||||||
        remove_duplicates(new_no_patterns);
 | 
					        remove_duplicates(new_no_patterns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        q1 = m_manager.mk_quantifier(q->is_forall(),
 | 
					        q1 = m.mk_quantifier(q->is_forall(),
 | 
				
			||||||
                                     q->get_num_decls(),
 | 
					                                     q->get_num_decls(),
 | 
				
			||||||
                                     q->get_decl_sorts(),
 | 
					                                     q->get_decl_sorts(),
 | 
				
			||||||
                                     q->get_decl_names(),
 | 
					                                     q->get_decl_names(),
 | 
				
			||||||
| 
						 | 
					@ -827,26 +832,26 @@ void simplifier::reduce1_quantifier(quantifier * q) {
 | 
				
			||||||
                                     new_patterns.c_ptr(),
 | 
					                                     new_patterns.c_ptr(),
 | 
				
			||||||
                                     new_no_patterns.size(),
 | 
					                                     new_no_patterns.size(),
 | 
				
			||||||
                                     new_no_patterns.c_ptr());
 | 
					                                     new_no_patterns.c_ptr());
 | 
				
			||||||
        SASSERT(is_well_sorted(m_manager, q1));
 | 
					        SASSERT(is_well_sorted(m, q1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TRACE("simplifier", tout << mk_pp(q, m_manager) << "\n" << mk_pp(q1, m_manager) << "\n";);
 | 
					        TRACE("simplifier", tout << mk_pp(q, m) << "\n" << mk_pp(q1, m) << "\n";);
 | 
				
			||||||
        if (m_manager.fine_grain_proofs()) {
 | 
					        if (m.fine_grain_proofs()) {
 | 
				
			||||||
            if (q != q1 && !new_body_pr) {
 | 
					            if (q != q1 && !new_body_pr) {
 | 
				
			||||||
                new_body_pr = m_manager.mk_rewrite(q->get_expr(), new_body);
 | 
					                new_body_pr = m.mk_rewrite(q->get_expr(), new_body);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            p1 = q == q1 ? 0 : m_manager.mk_quant_intro(q, q1, new_body_pr);
 | 
					            p1 = q == q1 ? 0 : m.mk_quant_intro(q, q1, new_body_pr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    expr_ref r(m_manager);
 | 
					    expr_ref r(m);
 | 
				
			||||||
    elim_unused_vars(m_manager, q1, r);
 | 
					    elim_unused_vars(m, q1, r);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    proof * pr = 0;
 | 
					    proof * pr = 0;
 | 
				
			||||||
    if (m_manager.fine_grain_proofs()) {
 | 
					    if (m.fine_grain_proofs()) {
 | 
				
			||||||
        proof * p2 = 0;
 | 
					        proof * p2 = 0;
 | 
				
			||||||
        if (q1.get() != r.get())
 | 
					        if (q1.get() != r.get())
 | 
				
			||||||
            p2 = m_manager.mk_elim_unused_vars(q1, r);
 | 
					            p2 = m.mk_elim_unused_vars(q1, r);
 | 
				
			||||||
        pr = m_manager.mk_transitivity(p1, p2);
 | 
					        pr = m.mk_transitivity(p1, p2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cache_result(q, r, pr);
 | 
					    cache_result(q, r, pr);
 | 
				
			||||||
| 
						 | 
					@ -892,7 +897,7 @@ bool subst_simplifier::get_subst(expr * n, expr_ref & r, proof_ref & p) {
 | 
				
			||||||
        m_subst_map->get(n, _r, _p);
 | 
					        m_subst_map->get(n, _r, _p);
 | 
				
			||||||
        r = _r;
 | 
					        r = _r;
 | 
				
			||||||
        p = _p;
 | 
					        p = _p;
 | 
				
			||||||
        if (m_manager.coarse_grain_proofs()) 
 | 
					        if (m.coarse_grain_proofs()) 
 | 
				
			||||||
            m_subst_proofs.push_back(p);
 | 
					            m_subst_proofs.push_back(p);
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -210,7 +210,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    plugin * get_plugin(family_id fid) const { return m_plugins.get_plugin(fid); }
 | 
					    plugin * get_plugin(family_id fid) const { return m_plugins.get_plugin(fid); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ast_manager & get_manager() { return m_manager; }
 | 
					    ast_manager & get_manager() { return m; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void borrow_plugins(simplifier const & s);
 | 
					    void borrow_plugins(simplifier const & s);
 | 
				
			||||||
    void release_plugins();
 | 
					    void release_plugins();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -793,8 +793,10 @@ bool substitution_tree::visit(expr * e, st_visitor & st, node * r) {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                    TRACE("st_bug", tout << "found match:\n"; m_subst->display(tout); tout << "m_subst: " << m_subst << "\n";);
 | 
					                    TRACE("st_bug", tout << "found match:\n"; m_subst->display(tout); tout << "m_subst: " << m_subst << "\n";);
 | 
				
			||||||
                    if (!st(n->m_expr))
 | 
					                    if (!st(n->m_expr)) {
 | 
				
			||||||
 | 
					                        clear_stack();
 | 
				
			||||||
                        return false;
 | 
					                        return false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    if (!backtrack())
 | 
					                    if (!backtrack())
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -806,12 +808,16 @@ bool substitution_tree::visit(expr * e, st_visitor & st, node * r) {
 | 
				
			||||||
        else if (!backtrack())
 | 
					        else if (!backtrack())
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    clear_stack();
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void substitution_tree::clear_stack() {
 | 
				
			||||||
    while (!m_bstack.empty()) {
 | 
					    while (!m_bstack.empty()) {
 | 
				
			||||||
        m_subst->pop_scope();
 | 
					        m_subst->pop_scope();
 | 
				
			||||||
        m_bstack.pop_back();
 | 
					        m_bstack.pop_back();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    m_subst->pop_scope();
 | 
					    m_subst->pop_scope();
 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<substitution_tree::st_visit_mode Mode>
 | 
					template<substitution_tree::st_visit_mode Mode>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,6 +123,8 @@ class substitution_tree {
 | 
				
			||||||
    template<st_visit_mode Mode>
 | 
					    template<st_visit_mode Mode>
 | 
				
			||||||
    void visit(expr * e, st_visitor & st, unsigned in_offset, unsigned st_offset, unsigned reg_offset);
 | 
					    void visit(expr * e, st_visitor & st, unsigned in_offset, unsigned st_offset, unsigned reg_offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void clear_stack();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    substitution_tree(ast_manager & m);
 | 
					    substitution_tree(ast_manager & m);
 | 
				
			||||||
    ~substitution_tree();
 | 
					    ~substitution_tree();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@ Notes:
 | 
				
			||||||
#include"datatype_decl_plugin.h"
 | 
					#include"datatype_decl_plugin.h"
 | 
				
			||||||
#include"seq_decl_plugin.h"
 | 
					#include"seq_decl_plugin.h"
 | 
				
			||||||
#include"float_decl_plugin.h"
 | 
					#include"float_decl_plugin.h"
 | 
				
			||||||
 | 
					#include"pb_decl_plugin.h"
 | 
				
			||||||
#include"ast_pp.h"
 | 
					#include"ast_pp.h"
 | 
				
			||||||
#include"var_subst.h"
 | 
					#include"var_subst.h"
 | 
				
			||||||
#include"pp.h"
 | 
					#include"pp.h"
 | 
				
			||||||
| 
						 | 
					@ -316,6 +317,7 @@ cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l):
 | 
				
			||||||
    m_exit_on_error(false),
 | 
					    m_exit_on_error(false),
 | 
				
			||||||
    m_manager(m),   
 | 
					    m_manager(m),   
 | 
				
			||||||
    m_own_manager(m == 0),
 | 
					    m_own_manager(m == 0),
 | 
				
			||||||
 | 
					    m_manager_initialized(false),
 | 
				
			||||||
    m_pmanager(0),
 | 
					    m_pmanager(0),
 | 
				
			||||||
    m_sexpr_manager(0),
 | 
					    m_sexpr_manager(0),
 | 
				
			||||||
    m_regular("stdout", std::cout),
 | 
					    m_regular("stdout", std::cout),
 | 
				
			||||||
| 
						 | 
					@ -326,8 +328,6 @@ cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l):
 | 
				
			||||||
    install_core_tactic_cmds(*this);
 | 
					    install_core_tactic_cmds(*this);
 | 
				
			||||||
    install_interpolant_cmds(*this);
 | 
					    install_interpolant_cmds(*this);
 | 
				
			||||||
    SASSERT(m != 0 || !has_manager());
 | 
					    SASSERT(m != 0 || !has_manager());
 | 
				
			||||||
    if (m)
 | 
					 | 
				
			||||||
        init_external_manager();
 | 
					 | 
				
			||||||
    if (m_main_ctx) { 
 | 
					    if (m_main_ctx) { 
 | 
				
			||||||
        set_verbose_stream(diagnostic_stream());
 | 
					        set_verbose_stream(diagnostic_stream());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -337,10 +337,10 @@ cmd_context::~cmd_context() {
 | 
				
			||||||
    if (m_main_ctx) {
 | 
					    if (m_main_ctx) {
 | 
				
			||||||
        set_verbose_stream(std::cerr);
 | 
					        set_verbose_stream(std::cerr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    reset(true); 
 | 
					 | 
				
			||||||
    finalize_cmds();
 | 
					    finalize_cmds();
 | 
				
			||||||
    finalize_tactic_cmds();
 | 
					    finalize_tactic_cmds();
 | 
				
			||||||
    finalize_probes();
 | 
					    finalize_probes();
 | 
				
			||||||
 | 
					    reset(true); 
 | 
				
			||||||
    m_solver = 0;
 | 
					    m_solver = 0;
 | 
				
			||||||
    m_check_sat_result = 0;
 | 
					    m_check_sat_result = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -358,6 +358,18 @@ void cmd_context::set_cancel(bool f) {
 | 
				
			||||||
        m().set_cancel(f);
 | 
					        m().set_cancel(f);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					opt_wrapper* cmd_context::get_opt() {
 | 
				
			||||||
 | 
					    return m_opt.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cmd_context::set_opt(opt_wrapper* opt) {
 | 
				
			||||||
 | 
					    m_opt = opt;
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < m_scopes.size(); ++i) {
 | 
				
			||||||
 | 
					        m_opt->push();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m_opt->set_logic(m_logic);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::global_params_updated() {
 | 
					void cmd_context::global_params_updated() {
 | 
				
			||||||
    m_params.updt_params();
 | 
					    m_params.updt_params();
 | 
				
			||||||
    if (m_params.m_smtlib2_compliant)
 | 
					    if (m_params.m_smtlib2_compliant)
 | 
				
			||||||
| 
						 | 
					@ -471,6 +483,16 @@ void cmd_context::register_plugin(symbol const & name, decl_plugin * p, bool ins
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cmd_context::load_plugin(symbol const & name, bool install, svector<family_id>& fids) {
 | 
				
			||||||
 | 
					    family_id id = m_manager->get_family_id(name);
 | 
				
			||||||
 | 
					    decl_plugin* p = m_manager->get_plugin(id);
 | 
				
			||||||
 | 
					    if (install && p && fids.contains(id)) {
 | 
				
			||||||
 | 
					        register_builtin_sorts(p);
 | 
				
			||||||
 | 
					        register_builtin_ops(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fids.erase(id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cmd_context::logic_has_arith_core(symbol const & s) const {
 | 
					bool cmd_context::logic_has_arith_core(symbol const & s) const {
 | 
				
			||||||
    return 
 | 
					    return 
 | 
				
			||||||
        s == "QF_LRA" ||
 | 
					        s == "QF_LRA" ||
 | 
				
			||||||
| 
						 | 
					@ -551,6 +573,7 @@ bool cmd_context::logic_has_floats() const {
 | 
				
			||||||
    return !has_logic() || m_logic == "QF_FPA" || m_logic == "QF_FPABV";
 | 
					    return !has_logic() || m_logic == "QF_FPA" || m_logic == "QF_FPABV";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cmd_context::logic_has_array_core(symbol const & s) const {
 | 
					bool cmd_context::logic_has_array_core(symbol const & s) const {
 | 
				
			||||||
    return 
 | 
					    return 
 | 
				
			||||||
        s == "QF_AX" ||
 | 
					        s == "QF_AX" ||
 | 
				
			||||||
| 
						 | 
					@ -593,11 +616,21 @@ void cmd_context::init_manager_core(bool new_manager) {
 | 
				
			||||||
        register_plugin(symbol("datatype"), alloc(datatype_decl_plugin), logic_has_datatype());
 | 
					        register_plugin(symbol("datatype"), alloc(datatype_decl_plugin), logic_has_datatype());
 | 
				
			||||||
        register_plugin(symbol("seq"),      alloc(seq_decl_plugin), logic_has_seq());
 | 
					        register_plugin(symbol("seq"),      alloc(seq_decl_plugin), logic_has_seq());
 | 
				
			||||||
        register_plugin(symbol("float"),    alloc(float_decl_plugin), logic_has_floats());
 | 
					        register_plugin(symbol("float"),    alloc(float_decl_plugin), logic_has_floats());
 | 
				
			||||||
 | 
					        register_plugin(symbol("pb"),     alloc(pb_decl_plugin), !has_logic());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        // the manager was created by an external module, we must register all plugins available in the manager.
 | 
					        // the manager was created by an external module
 | 
				
			||||||
 | 
					        // we register all plugins available in the manager.
 | 
				
			||||||
 | 
					        // unless the logic specifies otherwise.
 | 
				
			||||||
        svector<family_id> fids;
 | 
					        svector<family_id> fids;
 | 
				
			||||||
        m_manager->get_range(fids);
 | 
					        m_manager->get_range(fids);
 | 
				
			||||||
 | 
					        load_plugin(symbol("arith"),    logic_has_arith(), fids);
 | 
				
			||||||
 | 
					        load_plugin(symbol("bv"),       logic_has_bv(), fids);
 | 
				
			||||||
 | 
					        load_plugin(symbol("array"),    logic_has_array(), fids);
 | 
				
			||||||
 | 
					        load_plugin(symbol("datatype"), logic_has_datatype(), fids);
 | 
				
			||||||
 | 
					        load_plugin(symbol("seq"),      logic_has_seq(), fids);
 | 
				
			||||||
 | 
					        load_plugin(symbol("float"),    logic_has_floats(), fids);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        svector<family_id>::iterator it  = fids.begin();
 | 
					        svector<family_id>::iterator it  = fids.begin();
 | 
				
			||||||
        svector<family_id>::iterator end = fids.end();
 | 
					        svector<family_id>::iterator end = fids.end();
 | 
				
			||||||
        for (; it != end; ++it) {
 | 
					        for (; it != end; ++it) {
 | 
				
			||||||
| 
						 | 
					@ -620,13 +653,23 @@ void cmd_context::init_manager_core(bool new_manager) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::init_manager() {
 | 
					void cmd_context::init_manager() {
 | 
				
			||||||
    SASSERT(m_manager == 0);
 | 
					    if (m_manager_initialized) {
 | 
				
			||||||
 | 
					        // no-op
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (m_manager) {
 | 
				
			||||||
 | 
					        m_manager_initialized = true;
 | 
				
			||||||
 | 
					        SASSERT(!m_own_manager);
 | 
				
			||||||
 | 
					        init_external_manager();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        m_manager_initialized = true;
 | 
				
			||||||
        SASSERT(m_pmanager == 0);
 | 
					        SASSERT(m_pmanager == 0);
 | 
				
			||||||
        m_check_sat_result = 0;
 | 
					        m_check_sat_result = 0;
 | 
				
			||||||
        m_manager  = m_params.mk_ast_manager();
 | 
					        m_manager  = m_params.mk_ast_manager();
 | 
				
			||||||
        m_pmanager = alloc(pdecl_manager, *m_manager);
 | 
					        m_pmanager = alloc(pdecl_manager, *m_manager);
 | 
				
			||||||
        init_manager_core(true);
 | 
					        init_manager_core(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::init_external_manager() {
 | 
					void cmd_context::init_external_manager() {
 | 
				
			||||||
    SASSERT(m_manager != 0);
 | 
					    SASSERT(m_manager != 0);
 | 
				
			||||||
| 
						 | 
					@ -708,7 +751,7 @@ void cmd_context::insert(symbol const & s, func_decl * f) {
 | 
				
			||||||
    if (!m_global_decls) {
 | 
					    if (!m_global_decls) {
 | 
				
			||||||
        m_func_decls_stack.push_back(sf_pair(s, f));
 | 
					        m_func_decls_stack.push_back(sf_pair(s, f));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    TRACE("cmd_context", tout << "new sort decl\n" << mk_pp(f, m()) << "\n";);
 | 
					    TRACE("cmd_context", tout << "new function decl\n" << mk_pp(f, m()) << "\n";);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::insert(symbol const & s, psort_decl * p) {
 | 
					void cmd_context::insert(symbol const & s, psort_decl * p) {
 | 
				
			||||||
| 
						 | 
					@ -1141,7 +1184,6 @@ void cmd_context::insert_aux_pdecl(pdecl * p) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::reset(bool finalize) {
 | 
					void cmd_context::reset(bool finalize) {
 | 
				
			||||||
    m_check_sat_result = 0;
 | 
					 | 
				
			||||||
    m_logic = symbol::null;
 | 
					    m_logic = symbol::null;
 | 
				
			||||||
    m_check_sat_result = 0;
 | 
					    m_check_sat_result = 0;
 | 
				
			||||||
    m_numeral_as_real = false;
 | 
					    m_numeral_as_real = false;
 | 
				
			||||||
| 
						 | 
					@ -1157,6 +1199,7 @@ void cmd_context::reset(bool finalize) {
 | 
				
			||||||
    restore_assertions(0);
 | 
					    restore_assertions(0);
 | 
				
			||||||
    if (m_solver)
 | 
					    if (m_solver)
 | 
				
			||||||
        m_solver = 0;
 | 
					        m_solver = 0;
 | 
				
			||||||
 | 
					    m_opt = 0;
 | 
				
			||||||
    m_pp_env = 0;
 | 
					    m_pp_env = 0;
 | 
				
			||||||
    m_dt_eh  = 0;
 | 
					    m_dt_eh  = 0;
 | 
				
			||||||
    if (m_manager) {
 | 
					    if (m_manager) {
 | 
				
			||||||
| 
						 | 
					@ -1165,12 +1208,15 @@ void cmd_context::reset(bool finalize) {
 | 
				
			||||||
        if (m_own_manager) {
 | 
					        if (m_own_manager) {
 | 
				
			||||||
            dealloc(m_manager);
 | 
					            dealloc(m_manager);
 | 
				
			||||||
            m_manager = 0;
 | 
					            m_manager = 0;
 | 
				
			||||||
 | 
					            m_manager_initialized = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            // doesn't own manager... so it cannot be deleted
 | 
					            // doesn't own manager... so it cannot be deleted
 | 
				
			||||||
            // reinit cmd_context if this is not a finalization step
 | 
					            // reinit cmd_context if this is not a finalization step
 | 
				
			||||||
            if (!finalize)
 | 
					            if (!finalize)
 | 
				
			||||||
                init_external_manager();
 | 
					                init_external_manager();
 | 
				
			||||||
 | 
					            else 
 | 
				
			||||||
 | 
					                m_manager_initialized = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (m_sexpr_manager) {
 | 
					    if (m_sexpr_manager) {
 | 
				
			||||||
| 
						 | 
					@ -1211,7 +1257,6 @@ void cmd_context::assert_expr(symbol const & name, expr * t) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::push() {
 | 
					void cmd_context::push() {
 | 
				
			||||||
    m_check_sat_result = 0;
 | 
					    m_check_sat_result = 0;
 | 
				
			||||||
    if (!has_manager())
 | 
					 | 
				
			||||||
    init_manager();
 | 
					    init_manager();
 | 
				
			||||||
    m_scopes.push_back(scope());
 | 
					    m_scopes.push_back(scope());
 | 
				
			||||||
    scope & s = m_scopes.back();
 | 
					    scope & s = m_scopes.back();
 | 
				
			||||||
| 
						 | 
					@ -1222,6 +1267,8 @@ void cmd_context::push() {
 | 
				
			||||||
    s.m_assertions_lim         = m_assertions.size();
 | 
					    s.m_assertions_lim         = m_assertions.size();
 | 
				
			||||||
    if (m_solver) 
 | 
					    if (m_solver) 
 | 
				
			||||||
        m_solver->push();
 | 
					        m_solver->push();
 | 
				
			||||||
 | 
					    if (m_opt) 
 | 
				
			||||||
 | 
					        m_opt->push();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::push(unsigned n) {
 | 
					void cmd_context::push(unsigned n) {
 | 
				
			||||||
| 
						 | 
					@ -1317,6 +1364,8 @@ void cmd_context::pop(unsigned n) {
 | 
				
			||||||
    if (m_solver) {
 | 
					    if (m_solver) {
 | 
				
			||||||
        m_solver->pop(n);
 | 
					        m_solver->pop(n);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (m_opt) 
 | 
				
			||||||
 | 
					        m_opt->pop(n);
 | 
				
			||||||
    unsigned new_lvl = lvl - n;
 | 
					    unsigned new_lvl = lvl - n;
 | 
				
			||||||
    scope & s        = m_scopes[new_lvl];
 | 
					    scope & s        = m_scopes[new_lvl];
 | 
				
			||||||
    restore_func_decls(s.m_func_decls_stack_lim);
 | 
					    restore_func_decls(s.m_func_decls_stack_lim);
 | 
				
			||||||
| 
						 | 
					@ -1332,17 +1381,49 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    IF_VERBOSE(100, verbose_stream() << "(started \"check-sat\")" << std::endl;);
 | 
					    IF_VERBOSE(100, verbose_stream() << "(started \"check-sat\")" << std::endl;);
 | 
				
			||||||
    TRACE("before_check_sat", dump_assertions(tout););
 | 
					    TRACE("before_check_sat", dump_assertions(tout););
 | 
				
			||||||
    if (!has_manager())
 | 
					 | 
				
			||||||
    init_manager();
 | 
					    init_manager();
 | 
				
			||||||
    if (m_solver) {
 | 
					 | 
				
			||||||
        m_check_sat_result = m_solver.get(); // solver itself stores the result.
 | 
					 | 
				
			||||||
        m_solver->set_progress_callback(this);
 | 
					 | 
				
			||||||
    unsigned timeout = m_params.m_timeout;
 | 
					    unsigned timeout = m_params.m_timeout;
 | 
				
			||||||
    scoped_watch sw(*this);
 | 
					    scoped_watch sw(*this);
 | 
				
			||||||
 | 
					    lbool r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (m_opt && !m_opt->empty()) {
 | 
				
			||||||
 | 
					        bool was_pareto = false;
 | 
				
			||||||
 | 
					        m_check_sat_result = get_opt();
 | 
				
			||||||
 | 
					        cancel_eh<opt_wrapper> eh(*get_opt());
 | 
				
			||||||
 | 
					        scoped_ctrl_c ctrlc(eh);
 | 
				
			||||||
 | 
					        scoped_timer timer(timeout, &eh);
 | 
				
			||||||
 | 
					        ptr_vector<expr> cnstr(m_assertions);
 | 
				
			||||||
 | 
					        cnstr.append(num_assumptions, assumptions);
 | 
				
			||||||
 | 
					        get_opt()->set_hard_constraints(cnstr);
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            r = get_opt()->optimize();
 | 
				
			||||||
 | 
					            while (r == l_true && get_opt()->is_pareto()) {
 | 
				
			||||||
 | 
					                was_pareto = true;
 | 
				
			||||||
 | 
					                get_opt()->display_assignment(regular_stream());
 | 
				
			||||||
 | 
					                regular_stream() << "\n";
 | 
				
			||||||
 | 
					                r = get_opt()->optimize();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch (z3_error & ex) {
 | 
				
			||||||
 | 
					            throw ex;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch (z3_exception & ex) {
 | 
				
			||||||
 | 
					            throw cmd_exception(ex.msg());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (was_pareto && r == l_false) {
 | 
				
			||||||
 | 
					            r = l_true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        get_opt()->set_status(r);
 | 
				
			||||||
 | 
					        if (r != l_false && !was_pareto) {
 | 
				
			||||||
 | 
					            get_opt()->display_assignment(regular_stream());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (m_solver) {
 | 
				
			||||||
 | 
					        m_check_sat_result = m_solver.get(); // solver itself stores the result.
 | 
				
			||||||
 | 
					        m_solver->set_progress_callback(this);
 | 
				
			||||||
        cancel_eh<solver> eh(*m_solver);
 | 
					        cancel_eh<solver> eh(*m_solver);
 | 
				
			||||||
        scoped_ctrl_c ctrlc(eh);
 | 
					        scoped_ctrl_c ctrlc(eh);
 | 
				
			||||||
        scoped_timer timer(timeout, &eh);
 | 
					        scoped_timer timer(timeout, &eh);
 | 
				
			||||||
        lbool r;
 | 
					 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            r = m_solver->check_sat(num_assumptions, assumptions);
 | 
					            r = m_solver->check_sat(num_assumptions, assumptions);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -1353,15 +1434,17 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
 | 
				
			||||||
            throw cmd_exception(ex.msg());
 | 
					            throw cmd_exception(ex.msg());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        m_solver->set_status(r);
 | 
					        m_solver->set_status(r);
 | 
				
			||||||
        display_sat_result(r);
 | 
					 | 
				
			||||||
        validate_check_sat_result(r);
 | 
					 | 
				
			||||||
        if (r == l_true)
 | 
					 | 
				
			||||||
            validate_model();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        // There is no solver installed in the command context.
 | 
					        // There is no solver installed in the command context.
 | 
				
			||||||
        regular_stream() << "unknown" << std::endl;
 | 
					        regular_stream() << "unknown" << std::endl;
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    display_sat_result(r);
 | 
				
			||||||
 | 
					    validate_check_sat_result(r);
 | 
				
			||||||
 | 
					    if (r == l_true)
 | 
				
			||||||
 | 
					        validate_model();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cmd_context::display_sat_result(lbool r) {
 | 
					void cmd_context::display_sat_result(lbool r) {
 | 
				
			||||||
| 
						 | 
					@ -1538,6 +1621,9 @@ void cmd_context::display_statistics(bool show_total_time, double total_time) {
 | 
				
			||||||
    else if (m_solver) {
 | 
					    else if (m_solver) {
 | 
				
			||||||
        m_solver->collect_statistics(st);
 | 
					        m_solver->collect_statistics(st);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else if (m_opt) {
 | 
				
			||||||
 | 
					        m_opt->collect_statistics(st);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    st.display_smt2(regular_stream());
 | 
					    st.display_smt2(regular_stream());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,6 +111,21 @@ struct builtin_decl {
 | 
				
			||||||
    builtin_decl(family_id fid, decl_kind k, builtin_decl * n = 0):m_fid(fid), m_decl(k), m_next(n) {}
 | 
					    builtin_decl(family_id fid, decl_kind k, builtin_decl * n = 0):m_fid(fid), m_decl(k), m_next(n) {}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class opt_wrapper : public check_sat_result {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual bool empty() = 0;
 | 
				
			||||||
 | 
					    virtual void push() = 0;
 | 
				
			||||||
 | 
					    virtual void pop(unsigned n) = 0;
 | 
				
			||||||
 | 
					    virtual void set_cancel(bool f) = 0;
 | 
				
			||||||
 | 
					    virtual void reset_cancel() = 0;
 | 
				
			||||||
 | 
					    virtual void cancel() = 0;
 | 
				
			||||||
 | 
					    virtual lbool optimize() = 0;
 | 
				
			||||||
 | 
					    virtual void set_hard_constraints(ptr_vector<expr> & hard) = 0;
 | 
				
			||||||
 | 
					    virtual void display_assignment(std::ostream& out) = 0;
 | 
				
			||||||
 | 
					    virtual bool is_pareto() = 0;
 | 
				
			||||||
 | 
					    virtual void set_logic(symbol const& s) = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cmd_context : public progress_callback, public tactic_manager, public ast_printer_context {
 | 
					class cmd_context : public progress_callback, public tactic_manager, public ast_printer_context {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    enum status {
 | 
					    enum status {
 | 
				
			||||||
| 
						 | 
					@ -149,6 +164,7 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ast_manager *                m_manager;
 | 
					    ast_manager *                m_manager;
 | 
				
			||||||
    bool                         m_own_manager;
 | 
					    bool                         m_own_manager;
 | 
				
			||||||
 | 
					    bool                         m_manager_initialized;
 | 
				
			||||||
    pdecl_manager *              m_pmanager;
 | 
					    pdecl_manager *              m_pmanager;
 | 
				
			||||||
    sexpr_manager *              m_sexpr_manager;
 | 
					    sexpr_manager *              m_sexpr_manager;
 | 
				
			||||||
    check_logic                  m_check_logic;
 | 
					    check_logic                  m_check_logic;
 | 
				
			||||||
| 
						 | 
					@ -189,6 +205,7 @@ protected:
 | 
				
			||||||
    scoped_ptr<solver_factory>   m_interpolating_solver_factory;
 | 
					    scoped_ptr<solver_factory>   m_interpolating_solver_factory;
 | 
				
			||||||
    ref<solver>                  m_solver;    
 | 
					    ref<solver>                  m_solver;    
 | 
				
			||||||
    ref<check_sat_result>        m_check_sat_result;
 | 
					    ref<check_sat_result>        m_check_sat_result;
 | 
				
			||||||
 | 
					    ref<opt_wrapper>             m_opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stopwatch                    m_watch;
 | 
					    stopwatch                    m_watch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -212,7 +229,7 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void register_builtin_sorts(decl_plugin * p);
 | 
					    void register_builtin_sorts(decl_plugin * p);
 | 
				
			||||||
    void register_builtin_ops(decl_plugin * p);
 | 
					    void register_builtin_ops(decl_plugin * p);
 | 
				
			||||||
    void register_plugin(symbol const & name, decl_plugin * p, bool install_names);
 | 
					    void load_plugin(symbol const & name, bool install_names, svector<family_id>& fids);
 | 
				
			||||||
    void init_manager_core(bool new_manager);
 | 
					    void init_manager_core(bool new_manager);
 | 
				
			||||||
    void init_manager();
 | 
					    void init_manager();
 | 
				
			||||||
    void init_external_manager();
 | 
					    void init_external_manager();
 | 
				
			||||||
| 
						 | 
					@ -256,6 +273,8 @@ public:
 | 
				
			||||||
    context_params  & params() { return m_params; }
 | 
					    context_params  & params() { return m_params; }
 | 
				
			||||||
    solver_factory &get_solver_factory() { return *m_solver_factory; }
 | 
					    solver_factory &get_solver_factory() { return *m_solver_factory; }
 | 
				
			||||||
    solver_factory &get_interpolating_solver_factory() { return *m_interpolating_solver_factory; }
 | 
					    solver_factory &get_interpolating_solver_factory() { return *m_interpolating_solver_factory; }
 | 
				
			||||||
 | 
					    opt_wrapper*  get_opt();
 | 
				
			||||||
 | 
					    void          set_opt(opt_wrapper* o);
 | 
				
			||||||
    void global_params_updated(); // this method should be invoked when global (and module) params are updated.
 | 
					    void global_params_updated(); // this method should be invoked when global (and module) params are updated.
 | 
				
			||||||
    bool set_logic(symbol const & s);
 | 
					    bool set_logic(symbol const & s);
 | 
				
			||||||
    bool has_logic() const { return m_logic != symbol::null; }
 | 
					    bool has_logic() const { return m_logic != symbol::null; }
 | 
				
			||||||
| 
						 | 
					@ -293,7 +312,7 @@ public:
 | 
				
			||||||
    std::string reason_unknown() const;
 | 
					    std::string reason_unknown() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool has_manager() const { return m_manager != 0; }
 | 
					    bool has_manager() const { return m_manager != 0; }
 | 
				
			||||||
    ast_manager & m() const { if (!m_manager) const_cast<cmd_context*>(this)->init_manager(); return *m_manager; }
 | 
					    ast_manager & m() const { const_cast<cmd_context*>(this)->init_manager(); return *m_manager; }
 | 
				
			||||||
    virtual ast_manager & get_ast_manager() { return m(); }
 | 
					    virtual ast_manager & get_ast_manager() { return m(); }
 | 
				
			||||||
    pdecl_manager & pm() const { if (!m_pmanager) const_cast<cmd_context*>(this)->init_manager(); return *m_pmanager; }
 | 
					    pdecl_manager & pm() const { if (!m_pmanager) const_cast<cmd_context*>(this)->init_manager(); return *m_pmanager; }
 | 
				
			||||||
    sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast<cmd_context*>(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; }
 | 
					    sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast<cmd_context*>(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; }
 | 
				
			||||||
| 
						 | 
					@ -305,6 +324,7 @@ public:
 | 
				
			||||||
    check_sat_state cs_state() const;
 | 
					    check_sat_state cs_state() const;
 | 
				
			||||||
    void validate_model();
 | 
					    void validate_model();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void register_plugin(symbol const & name, decl_plugin * p, bool install_names);    
 | 
				
			||||||
    bool is_func_decl(symbol const & s) const;
 | 
					    bool is_func_decl(symbol const & s) const;
 | 
				
			||||||
    bool is_sort_decl(symbol const& s) const { return m_psort_decls.contains(s); }
 | 
					    bool is_sort_decl(symbol const& s) const { return m_psort_decls.contains(s); }
 | 
				
			||||||
    void insert(cmd * c);
 | 
					    void insert(cmd * c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								src/duality/duality.h
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										4
									
								
								src/duality/duality.h
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
						 | 
					@ -778,6 +778,10 @@ protected:
 | 
				
			||||||
      struct Bad {
 | 
					      struct Bad {
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					      // thrown on more serious internal error
 | 
				
			||||||
 | 
					      struct ReallyBad {
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /** Pop a scope (see Push). Note, you cannot pop axioms. */
 | 
					      /** Pop a scope (see Push). Note, you cannot pop axioms. */
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      void Pop(int num_scopes);
 | 
					      void Pop(int num_scopes);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2643,6 +2643,10 @@ namespace Duality {
 | 
				
			||||||
	GetGroundLitsUnderQuants(memo,f.body(),res,1);
 | 
						GetGroundLitsUnderQuants(memo,f.body(),res,1);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if(f.is_var()){
 | 
				
			||||||
 | 
					      //      std::cout << "foo!\n";
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if(under && f.is_ground())
 | 
					    if(under && f.is_ground())
 | 
				
			||||||
      res.push_back(f);
 | 
					      res.push_back(f);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -3065,10 +3069,14 @@ namespace Duality {
 | 
				
			||||||
    node->Annotation.SetEmpty();
 | 
					    node->Annotation.SetEmpty();
 | 
				
			||||||
    hash_set<ast> *core = new hash_set<ast>;
 | 
					    hash_set<ast> *core = new hash_set<ast>;
 | 
				
			||||||
    core->insert(node->Outgoing->dual);
 | 
					    core->insert(node->Outgoing->dual);
 | 
				
			||||||
 | 
					    expr prev_annot = ctx.bool_val(false);
 | 
				
			||||||
 | 
					    expr prev_impl = ctx.bool_val(false);
 | 
				
			||||||
 | 
					    int repeated_case_count = 0;
 | 
				
			||||||
    while(1){
 | 
					    while(1){
 | 
				
			||||||
      by_case_counter++;
 | 
					      by_case_counter++;
 | 
				
			||||||
      is.push();
 | 
					      is.push();
 | 
				
			||||||
      expr annot = !GetAnnotation(node);
 | 
					      expr annot = !GetAnnotation(node);
 | 
				
			||||||
 | 
					      Transformer old_annot = node->Annotation;
 | 
				
			||||||
      is.add(annot);
 | 
					      is.add(annot);
 | 
				
			||||||
      if(is.check() == unsat){
 | 
					      if(is.check() == unsat){
 | 
				
			||||||
	is.pop(1);
 | 
						is.pop(1);
 | 
				
			||||||
| 
						 | 
					@ -3076,12 +3084,25 @@ namespace Duality {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      is.pop(1);
 | 
					      is.pop(1);
 | 
				
			||||||
      Push();
 | 
					      Push();
 | 
				
			||||||
      ConstrainEdgeLocalized(node->Outgoing,is.get_implicant());
 | 
					      expr the_impl = is.get_implicant();
 | 
				
			||||||
 | 
					      if(eq(the_impl,prev_impl)){
 | 
				
			||||||
 | 
						//	std::cout << "got old implicant\n";
 | 
				
			||||||
 | 
						repeated_case_count++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      prev_impl = the_impl;
 | 
				
			||||||
 | 
					      ConstrainEdgeLocalized(node->Outgoing,the_impl);
 | 
				
			||||||
      ConstrainEdgeLocalized(node->Outgoing,!GetAnnotation(node)); //TODO: need this?
 | 
					      ConstrainEdgeLocalized(node->Outgoing,!GetAnnotation(node)); //TODO: need this?
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
	check_result foo = Check(root);
 | 
						check_result foo = Check(root);
 | 
				
			||||||
	if(foo != unsat){
 | 
						if(foo != unsat){
 | 
				
			||||||
	slvr().print("should_be_unsat.smt2");
 | 
						  Pop(1);
 | 
				
			||||||
	throw "should be unsat";
 | 
						  is.pop(1);
 | 
				
			||||||
 | 
						  delete core;
 | 
				
			||||||
 | 
						  timer_stop("InterpolateByCases");
 | 
				
			||||||
 | 
						  throw ReallyBad();
 | 
				
			||||||
 | 
						  // slvr().print("should_be_unsat.smt2");
 | 
				
			||||||
 | 
						  // throw "should be unsat";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	std::vector<expr> assumps, axioms_to_add;
 | 
						std::vector<expr> assumps, axioms_to_add;
 | 
				
			||||||
	slvr().get_proof().get_assumptions(assumps);
 | 
						slvr().get_proof().get_assumptions(assumps);
 | 
				
			||||||
| 
						 | 
					@ -3093,7 +3114,6 @@ namespace Duality {
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// AddToProofCore(*core);
 | 
						// AddToProofCore(*core);
 | 
				
			||||||
      Transformer old_annot = node->Annotation;
 | 
					 | 
				
			||||||
	SolveSingleNode(root,node);
 | 
						SolveSingleNode(root,node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -3124,8 +3144,10 @@ namespace Duality {
 | 
				
			||||||
	  bad_count++;
 | 
						  bad_count++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if(node->Annotation.IsEmpty()){
 | 
					      if(node->Annotation.IsEmpty() || eq(node->Annotation.Formula,prev_annot) || (repeated_case_count > 0 && !axioms_added) || (repeated_case_count >= 10)){
 | 
				
			||||||
 | 
					//      looks_bad:
 | 
				
			||||||
	if(!axioms_added){
 | 
						if(!axioms_added){
 | 
				
			||||||
	  // add the axioms in the off chance they are useful
 | 
						  // add the axioms in the off chance they are useful
 | 
				
			||||||
	  const std::vector<expr> &theory = ls->get_axioms();
 | 
						  const std::vector<expr> &theory = ls->get_axioms();
 | 
				
			||||||
| 
						 | 
					@ -3134,6 +3156,7 @@ namespace Duality {
 | 
				
			||||||
	  axioms_added = true;
 | 
						  axioms_added = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
 | 
						  //#define KILL_ON_BAD_INTERPOLANT	  
 | 
				
			||||||
#ifdef KILL_ON_BAD_INTERPOLANT	  
 | 
					#ifdef KILL_ON_BAD_INTERPOLANT	  
 | 
				
			||||||
	  std::cout << "bad in InterpolateByCase -- core:\n";
 | 
						  std::cout << "bad in InterpolateByCase -- core:\n";
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
| 
						 | 
					@ -3175,10 +3198,11 @@ namespace Duality {
 | 
				
			||||||
	  is.pop(1);
 | 
						  is.pop(1);
 | 
				
			||||||
	  delete core;
 | 
						  delete core;
 | 
				
			||||||
	  timer_stop("InterpolateByCases");
 | 
						  timer_stop("InterpolateByCases");
 | 
				
			||||||
	  throw Bad();
 | 
						  throw ReallyBad();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      Pop(1);
 | 
					      Pop(1);
 | 
				
			||||||
 | 
					      prev_annot = node->Annotation.Formula;
 | 
				
			||||||
      node->Annotation.UnionWith(old_annot);
 | 
					      node->Annotation.UnionWith(old_annot);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(proof_core)
 | 
					    if(proof_core)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/duality/duality_solver.cpp
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										12
									
								
								src/duality/duality_solver.cpp
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
						 | 
					@ -2279,6 +2279,18 @@ namespace Duality {
 | 
				
			||||||
		  // bad interpolants can get us here
 | 
							  // bad interpolants can get us here
 | 
				
			||||||
		  throw DoRestart();
 | 
							  throw DoRestart();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							catch(const RPFP::ReallyBad &){
 | 
				
			||||||
 | 
							  // this could be caused by incompleteness
 | 
				
			||||||
 | 
							  for(unsigned i = 0; i < expansions.size(); i++){
 | 
				
			||||||
 | 
							    Node *node = expansions[i];
 | 
				
			||||||
 | 
							    node->map->Annotation.SetFull();
 | 
				
			||||||
 | 
							    std::vector<Node *> &chs = node->map->Outgoing->Children;
 | 
				
			||||||
 | 
							    for(unsigned j = 0; j < chs.size(); j++)
 | 
				
			||||||
 | 
							      chs[j]->Annotation.SetFull();
 | 
				
			||||||
 | 
							    reporter->Message("incompleteness: cleared annotation and child annotations");
 | 
				
			||||||
 | 
							  }
 | 
				
			||||||
 | 
							  throw DoRestart();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		catch(char const *msg){
 | 
							catch(char const *msg){
 | 
				
			||||||
		  // bad interpolants can get us here
 | 
							  // bad interpolants can get us here
 | 
				
			||||||
		  reporter->Message(std::string("interpolation failure:") + msg);
 | 
							  reporter->Message(std::string("interpolation failure:") + msg);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
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