mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 13:29:11 +00:00 
			
		
		
		
	Moved dead code to dead branch
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
		
							parent
							
								
									8f7494cb04
								
							
						
					
					
						commit
						81df5ca96f
					
				
					 123 changed files with 0 additions and 33328 deletions
				
			
		| 
						 | 
				
			
			@ -1,34 +0,0 @@
 | 
			
		|||
using namespace System;
 | 
			
		||||
using namespace System::Reflection;
 | 
			
		||||
using namespace System::Runtime::CompilerServices;
 | 
			
		||||
using namespace System::Runtime::InteropServices;
 | 
			
		||||
using namespace System::Security::Permissions;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// 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:AssemblyTitleAttribute("Z3 .NET Interface")];
 | 
			
		||||
[assembly:AssemblyDescriptionAttribute(".NET Interface to the Z3 Theorem Prover")];
 | 
			
		||||
[assembly:AssemblyConfigurationAttribute("")];
 | 
			
		||||
[assembly:AssemblyCompanyAttribute("Microsoft Corporation")];
 | 
			
		||||
[assembly:AssemblyProductAttribute("Z3")];
 | 
			
		||||
[assembly:AssemblyCopyrightAttribute("Copyright (c) Microsoft Corporation 2006")];
 | 
			
		||||
[assembly:AssemblyTrademarkAttribute("")];
 | 
			
		||||
[assembly:AssemblyCultureAttribute("")];
 | 
			
		||||
 | 
			
		||||
[assembly:ComVisible(false)];
 | 
			
		||||
[assembly:CLSCompliantAttribute(true)];
 | 
			
		||||
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
 | 
			
		||||
 | 
			
		||||
[assembly:AssemblyVersionAttribute("4.2.0.0")];
 | 
			
		||||
[assembly:AssemblyFileVersionAttribute("4.2.0.0")];
 | 
			
		||||
 | 
			
		||||
//#ifdef DELAYSIGN
 | 
			
		||||
//[assembly:AssemblyKeyFile("35MSSharedLib1024.snk")];
 | 
			
		||||
//[assembly:AssemblyDelaySign(true)];
 | 
			
		||||
//#else
 | 
			
		||||
//[assembly:AssemblyKeyFile("z3.snk")];
 | 
			
		||||
//[assembly:AssemblyDelaySign(true)];
 | 
			
		||||
//#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,555 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ItemGroup Label="ProjectConfigurations">
 | 
			
		||||
    <ProjectConfiguration Include="commercial|Win32">
 | 
			
		||||
      <Configuration>commercial</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="commercial|x64">
 | 
			
		||||
      <Configuration>commercial</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Debug|Win32">
 | 
			
		||||
      <Configuration>Debug</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Debug|x64">
 | 
			
		||||
      <Configuration>Debug</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="external|Win32">
 | 
			
		||||
      <Configuration>external</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="external|x64">
 | 
			
		||||
      <Configuration>external</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="release_mt|Win32">
 | 
			
		||||
      <Configuration>release_mt</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="release_mt|x64">
 | 
			
		||||
      <Configuration>release_mt</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Release|Win32">
 | 
			
		||||
      <Configuration>Release</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Release|x64">
 | 
			
		||||
      <Configuration>Release</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Trace|Win32">
 | 
			
		||||
      <Configuration>Trace</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Trace|x64">
 | 
			
		||||
      <Configuration>Trace</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <PropertyGroup Label="Globals">
 | 
			
		||||
    <ProjectGuid>{F008F2C4-D652-4A58-8DEF-DB83E2355454}</ProjectGuid>
 | 
			
		||||
    <RootNamespace>Microsoft.Z3V3</RootNamespace>
 | 
			
		||||
    <Keyword>ManagedCProj</Keyword>
 | 
			
		||||
    <ProjectName>Microsoft.Z3V3</ProjectName>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='external|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='external|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='commercial|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Application</ConfigurationType>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Trace|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>DynamicLibrary</ConfigurationType>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
    <CLRSupport>true</CLRSupport>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
 | 
			
		||||
  <ImportGroup Label="ExtensionSettings">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='external|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='external|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='commercial|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Trace|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <PropertyGroup Label="UserMacros" />
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'">$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'">false</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Trace|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Trace|x64'">$(Platform)\$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Trace|x64'">false</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'">$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'">false</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'">$(Platform)\$(Configuration)\</IntDir>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='external|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='external|Win32'">$(Configuration)\</IntDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'">$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='external|Win32'">false</LinkIncremental>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'">false</LinkIncremental>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='external|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
 | 
			
		||||
    <OutDir Condition="'$(Configuration)|$(Platform)'=='commercial|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='external|x64'">$(Platform)\$(Configuration)\</IntDir>
 | 
			
		||||
    <IntDir Condition="'$(Configuration)|$(Platform)'=='commercial|x64'">$(Platform)\$(Configuration)\</IntDir>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='external|x64'">false</LinkIncremental>
 | 
			
		||||
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='commercial|x64'">false</LinkIncremental>
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='commercial_64|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='external|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='external|Win32'" />
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='external|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='external|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='commercial|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='external|x64'" />
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='commercial|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='external|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='commercial|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'" />
 | 
			
		||||
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Trace|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Trace|x64'" />
 | 
			
		||||
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Trace|x64'" />
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <Optimization>Disabled</Optimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;_DEBUG;Z3DEBUG;_WINDOWS;_TRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <AssemblyDebug>true</AssemblyDebug>
 | 
			
		||||
      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 | 
			
		||||
      <DataExecutionPrevention>
 | 
			
		||||
      </DataExecutionPrevention>
 | 
			
		||||
      <TargetMachine>MachineX86</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
 | 
			
		||||
    <Midl>
 | 
			
		||||
      <TargetEnvironment>X64</TargetEnvironment>
 | 
			
		||||
    </Midl>
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <Optimization>Disabled</Optimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_TRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <AssemblyDebug>true</AssemblyDebug>
 | 
			
		||||
      <TargetMachine>MachineX64</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 | 
			
		||||
      <DataExecutionPrevention>
 | 
			
		||||
      </DataExecutionPrevention>
 | 
			
		||||
      <TargetMachine>MachineX86</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
 | 
			
		||||
    <Midl>
 | 
			
		||||
      <TargetEnvironment>X64</TargetEnvironment>
 | 
			
		||||
    </Midl>
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <TargetMachine>MachineX64</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Trace|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 | 
			
		||||
      <DataExecutionPrevention>
 | 
			
		||||
      </DataExecutionPrevention>
 | 
			
		||||
      <TargetMachine>MachineX86</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Trace|x64'">
 | 
			
		||||
    <Midl>
 | 
			
		||||
      <TargetEnvironment>X64</TargetEnvironment>
 | 
			
		||||
    </Midl>
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <TargetMachine>MachineX64</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_mt|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 | 
			
		||||
      <DataExecutionPrevention>
 | 
			
		||||
      </DataExecutionPrevention>
 | 
			
		||||
      <TargetMachine>MachineX86</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='external|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 | 
			
		||||
      <DataExecutionPrevention>
 | 
			
		||||
      </DataExecutionPrevention>
 | 
			
		||||
      <TargetMachine>MachineX86</TargetMachine>
 | 
			
		||||
      <Profile>true</Profile>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='commercial|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_Z3_COMMERCIAL;_EXTERNAL_RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 | 
			
		||||
      <DataExecutionPrevention>
 | 
			
		||||
      </DataExecutionPrevention>
 | 
			
		||||
      <TargetMachine>MachineX86</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='external|x64'">
 | 
			
		||||
    <Midl>
 | 
			
		||||
      <TargetEnvironment>X64</TargetEnvironment>
 | 
			
		||||
    </Midl>
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <TargetMachine>MachineX64</TargetMachine>
 | 
			
		||||
      <Profile>true</Profile>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='commercial|x64'">
 | 
			
		||||
    <Midl>
 | 
			
		||||
      <TargetEnvironment>X64</TargetEnvironment>
 | 
			
		||||
    </Midl>
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WholeProgramOptimization>false</WholeProgramOptimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_Z3_COMMERCIAL;_AMD64_;_EXTERNAL_RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>
 | 
			
		||||
      </AdditionalDependencies>
 | 
			
		||||
      <OutputFile>$(OutDir)Microsoft.Z3V3.dll</OutputFile>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <TargetMachine>MachineX64</TargetMachine>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'">
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_mt|x64'">
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
      <Command>
 | 
			
		||||
      </Command>
 | 
			
		||||
    </PostBuildEvent>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Reference Include="System">
 | 
			
		||||
      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
 | 
			
		||||
      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="System.Data">
 | 
			
		||||
      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
 | 
			
		||||
      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="System.Numerics" />
 | 
			
		||||
    <Reference Include="System.Xml">
 | 
			
		||||
      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
 | 
			
		||||
      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
 | 
			
		||||
    </Reference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClCompile Include="AssemblyInfo.cpp" />
 | 
			
		||||
    <ClCompile Include="Microsoft.Z3V3.cpp" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClInclude Include="Microsoft.Z3V3.h" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\lib\lib.vcxproj">
 | 
			
		||||
      <Project>{4a7e5a93-19d8-4382-8950-fb2edec7a76e}</Project>
 | 
			
		||||
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 | 
			
		||||
  <ImportGroup Label="ExtensionTargets">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,208 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2010 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    array_property_expander.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Expand array operations for the array property fragment formulas.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2010-16-12
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include"array_property_expander.h"
 | 
			
		||||
#include"obj_hashtable.h"
 | 
			
		||||
#include"var_subst.h"
 | 
			
		||||
#include"array_decl_plugin.h"
 | 
			
		||||
#include"for_each_expr.h"
 | 
			
		||||
 | 
			
		||||
array_property_expander::array_property_expander(ast_manager& m):
 | 
			
		||||
    m_manager(m) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace array_property_exp {
 | 
			
		||||
    class proc {
 | 
			
		||||
        ast_manager& m_manager;
 | 
			
		||||
        unsigned&    m_offset;
 | 
			
		||||
        expr_ref_vector m_trail;
 | 
			
		||||
        family_id    m_fid;
 | 
			
		||||
        array_util   m_util;
 | 
			
		||||
        obj_map<expr, expr*> m_mem;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        void insert(expr* a, expr* b) {
 | 
			
		||||
            m_trail.push_back(b);
 | 
			
		||||
            m_mem.insert(a, b);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        proc(ast_manager& m, unsigned& offset) : 
 | 
			
		||||
            m_manager(m),
 | 
			
		||||
            m_offset(offset),
 | 
			
		||||
            m_trail(m),
 | 
			
		||||
            m_fid(m.get_family_id("array")),
 | 
			
		||||
            m_util(m)
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
        expr* find(expr* e) {
 | 
			
		||||
            expr* result = 0;
 | 
			
		||||
            VERIFY(m_mem.find(e, result));
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void operator()(var* n) { insert(n, n); }
 | 
			
		||||
 | 
			
		||||
        void operator()(quantifier* q) {
 | 
			
		||||
            expr* e = find(q->get_expr());
 | 
			
		||||
            quantifier* q2 = m_manager.update_quantifier(q, e);
 | 
			
		||||
            insert(q, q2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void operator()(app* n) {
 | 
			
		||||
            ast_manager& m = m_manager;
 | 
			
		||||
            unsigned num_args = n->get_num_args();
 | 
			
		||||
            ptr_buffer<expr> args;
 | 
			
		||||
            for (unsigned i = 0; i < num_args; ++i) {
 | 
			
		||||
                args.push_back(find(n->get_arg(i)));
 | 
			
		||||
            }
 | 
			
		||||
            if (m_manager.is_eq(n) && m_util.is_array(args[0])) {
 | 
			
		||||
                visit_eq(n);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (m_manager.is_distinct(n) && num_args > 0 && m_util.is_array(args[0])) {
 | 
			
		||||
                ptr_buffer<expr> eqs;
 | 
			
		||||
                for (unsigned i = 0; i < num_args; ++i) {
 | 
			
		||||
                    for (unsigned j = i + 1; j < num_args; ++j) {
 | 
			
		||||
                        eqs.push_back(m.mk_not(m.mk_eq(args[i], args[j])));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                insert(n, m.mk_and(eqs.size(), eqs.c_ptr()));               
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (m_util.is_select(n)) {
 | 
			
		||||
                SASSERT(num_args > 0);
 | 
			
		||||
 | 
			
		||||
                // select(store(A,i,v),j) -> ite(i = j, v, select(A,j))
 | 
			
		||||
                if (m_util.is_store(args[0])) {
 | 
			
		||||
                    app* a = to_app(args[0]);
 | 
			
		||||
                    expr* b = find(a->get_arg(0));
 | 
			
		||||
                    expr* v = find(a->get_arg(a->get_num_args()-1));
 | 
			
		||||
                    ptr_buffer<expr> eqs;
 | 
			
		||||
                    SASSERT(num_args + 1 == a->get_num_args());
 | 
			
		||||
                    for (unsigned i = 1; i < num_args; ++i) {
 | 
			
		||||
                        eqs.push_back(m.mk_eq(args[i], find(a->get_arg(i))));
 | 
			
		||||
                    }
 | 
			
		||||
                    expr* r = m.mk_ite(m.mk_and(eqs.size(), eqs.c_ptr()), v, mk_select(b, num_args-1, args.c_ptr()+1));
 | 
			
		||||
                    insert(n, r);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // select(ite(a,b,c),i) -> ite(a, select(b,i), select(c, i))
 | 
			
		||||
                if (m.is_ite(args[0])) {
 | 
			
		||||
                    app* k = to_app(args[0]);
 | 
			
		||||
                    expr* a = k->get_arg(0);
 | 
			
		||||
                    expr* b = mk_select(k->get_arg(1), args.size()-1, args.c_ptr()+1);
 | 
			
		||||
                    expr* c = mk_select(k->get_arg(2), args.size()-1, args.c_ptr()+1);
 | 
			
		||||
                    expr* r = m.mk_ite(a, b, c);
 | 
			
		||||
                    insert(n, r);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // select(map_f(A,B),i) -> f(select(A,i), select(B,i))
 | 
			
		||||
                if (m_util.is_map(args[0])) {
 | 
			
		||||
                    app* a = to_app(args[0]);
 | 
			
		||||
                    func_decl* f = a->get_decl(); 
 | 
			
		||||
                    SASSERT(f->get_num_parameters() == 1);
 | 
			
		||||
                    SASSERT(f->get_parameter(0).is_ast());
 | 
			
		||||
                    SASSERT(is_func_decl(f->get_parameter(0).get_ast()));                    
 | 
			
		||||
                    parameter p = f->get_parameter(0);
 | 
			
		||||
                    func_decl* d = to_func_decl(p.get_ast());
 | 
			
		||||
                    ptr_buffer<expr> args2;
 | 
			
		||||
                    for (unsigned i = 0; i < a->get_num_args(); ++i) {
 | 
			
		||||
                        args2.push_back(mk_select(find(a->get_arg(i)), args.size()-1, args.c_ptr()+1));
 | 
			
		||||
                    }
 | 
			
		||||
                    expr* r = m.mk_app(d, args2.size(), args2.c_ptr()); 
 | 
			
		||||
                    insert(n, r);
 | 
			
		||||
                    return;                    
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // select(const v, i) -> v
 | 
			
		||||
                if (m_util.is_const(args[0])) {
 | 
			
		||||
                    insert(n, to_app(args[0])->get_arg(0));
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }       
 | 
			
		||||
            expr* r = m_manager.mk_app(n->get_decl(), args.size(), args.c_ptr());
 | 
			
		||||
            insert(n, r);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    private:
 | 
			
		||||
        void visit_eq(app* eq) {
 | 
			
		||||
            ast_manager& m = m_manager;
 | 
			
		||||
            SASSERT(m.is_eq(eq));
 | 
			
		||||
            sort* s = m.get_sort(eq->get_arg(0));
 | 
			
		||||
            SASSERT(is_sort_of(s, m_fid, ARRAY_SORT));
 | 
			
		||||
            // sort* rng = get_array_range(s);
 | 
			
		||||
            unsigned arity = get_array_arity(s);
 | 
			
		||||
            shift_vars sh(m);
 | 
			
		||||
            expr_ref e1(m), e2(m);
 | 
			
		||||
            sh(find(eq->get_arg(0)), arity, e1);
 | 
			
		||||
            sh(find(eq->get_arg(1)), arity, e2);
 | 
			
		||||
            expr_ref_vector args(m);
 | 
			
		||||
            buffer<symbol> names;
 | 
			
		||||
            ptr_buffer<sort>   sorts;
 | 
			
		||||
            args.push_back(e1);
 | 
			
		||||
            for (unsigned i = 0; i < arity; ++i) {
 | 
			
		||||
                args.push_back(m.mk_var(i, get_array_domain(s, i)));
 | 
			
		||||
                sorts.push_back(get_array_domain(s, arity - i - 1));
 | 
			
		||||
                names.push_back(symbol(m_offset++));
 | 
			
		||||
            }
 | 
			
		||||
            e1 = mk_select(args.size(), args.c_ptr());
 | 
			
		||||
            args[0] = e2;
 | 
			
		||||
            e2 = mk_select(args.size(), args.c_ptr());
 | 
			
		||||
            e1 = m.mk_eq(e1, e2);
 | 
			
		||||
            
 | 
			
		||||
            e1 = m.mk_quantifier(true, arity, sorts.c_ptr(), names.c_ptr(), e1, 1);
 | 
			
		||||
            insert(eq, e1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        app* mk_select(unsigned n, expr* const* args) {
 | 
			
		||||
            return m_manager.mk_app(m_fid, OP_SELECT, 0, 0, n, args);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        app* mk_select(expr* a, unsigned n, expr* const* args) {
 | 
			
		||||
            ptr_buffer<expr> args2;
 | 
			
		||||
            args2.push_back(a);
 | 
			
		||||
            args2.append(n, args);
 | 
			
		||||
            return mk_select(n+1, args2.c_ptr());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void array_property_expander::operator()(unsigned num_fmls, expr* const* fmls, expr_ref_vector& result) {
 | 
			
		||||
    ast_manager& m = m_manager;
 | 
			
		||||
    unsigned offset = 0;
 | 
			
		||||
    for (unsigned i = 0; i < num_fmls; ++i) {
 | 
			
		||||
        bool change = false;
 | 
			
		||||
        expr_ref e(m);
 | 
			
		||||
        result.push_back(fmls[i]);
 | 
			
		||||
        do {
 | 
			
		||||
            array_property_exp::proc p(m, offset);
 | 
			
		||||
            e = result[i].get();
 | 
			
		||||
            for_each_expr(p, e);
 | 
			
		||||
            result[i] = p.find(e);
 | 
			
		||||
            change = e != result[i].get();
 | 
			
		||||
        }
 | 
			
		||||
        while (change);        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,33 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2010 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    array_property_expander.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Expand array operations for the array property fragment formulas.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2010-16-12
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _ARRAY_PROPERTY_EXPANDER_H_
 | 
			
		||||
#define _ARRAY_PROPERTY_EXPANDER_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
 | 
			
		||||
class array_property_expander {
 | 
			
		||||
    ast_manager& m_manager;
 | 
			
		||||
public:
 | 
			
		||||
    array_property_expander(ast_manager& m);
 | 
			
		||||
    void operator()(unsigned num_fmls, expr* const* fmls, expr_ref_vector& result);    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* _ARRAY_PROPERTY_EXPANDER_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,103 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2010 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    array_property_recognizer.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2010-16-12
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include"array_decl_plugin.h"
 | 
			
		||||
#include"array_property_recognizer.h"
 | 
			
		||||
#include"for_each_expr.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
array_property_recognizer::array_property_recognizer(ast_manager& m):
 | 
			
		||||
    m_manager(m) {}
 | 
			
		||||
 | 
			
		||||
namespace is_array_property_ns {
 | 
			
		||||
    struct bad {};
 | 
			
		||||
    class proc {
 | 
			
		||||
        ast_manager& m_manager;
 | 
			
		||||
        family_id    m_fid;
 | 
			
		||||
        bool         m_has_quantifier;
 | 
			
		||||
 | 
			
		||||
        void check_array_sort(expr* n) {
 | 
			
		||||
            if (is_sort_of(m_manager.get_sort(n), m_fid, ARRAY_SORT)) {
 | 
			
		||||
                throw bad();
 | 
			
		||||
            }            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        proc(ast_manager& m) : 
 | 
			
		||||
            m_manager(m), 
 | 
			
		||||
            m_fid(m.get_family_id("array")), 
 | 
			
		||||
            m_has_quantifier(false) {}
 | 
			
		||||
 | 
			
		||||
        bool has_quantifier() const { return m_has_quantifier; }
 | 
			
		||||
 | 
			
		||||
        void operator()(var* n) {
 | 
			
		||||
            check_array_sort(n);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void operator()(quantifier * ) { 
 | 
			
		||||
            m_has_quantifier = true; 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void operator()(app* n) {
 | 
			
		||||
            unsigned num_args = n->get_num_args();
 | 
			
		||||
            if (m_manager.is_eq(n) || m_manager.is_distinct(n)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            family_id fid = n->get_family_id();
 | 
			
		||||
            if (fid == m_fid) {                
 | 
			
		||||
                switch(n->get_decl_kind()) {
 | 
			
		||||
                case OP_STORE:
 | 
			
		||||
                    for (unsigned i = 1; i + 1 < num_args; ++i) {
 | 
			
		||||
                        check_array_sort(n->get_arg(i));
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                case OP_SELECT:
 | 
			
		||||
                    for (unsigned i = 1; i < num_args; ++i) {
 | 
			
		||||
                        check_array_sort(n->get_arg(i));
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                case OP_CONST_ARRAY:
 | 
			
		||||
                case OP_ARRAY_MAP:
 | 
			
		||||
                    return;
 | 
			
		||||
                default:
 | 
			
		||||
                    throw bad();
 | 
			
		||||
                }                
 | 
			
		||||
            }
 | 
			
		||||
            // arrays cannot be arguments of other functions.
 | 
			
		||||
            for (unsigned i = 0; i < num_args; ++i) {
 | 
			
		||||
                check_array_sort(n->get_arg(i));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool array_property_recognizer::operator()(unsigned num_fmls, expr* const* fmls) {
 | 
			
		||||
    is_array_property_ns::proc p(m_manager);
 | 
			
		||||
    try {
 | 
			
		||||
        for (unsigned i = 0; i < num_fmls; ++i) {
 | 
			
		||||
            for_each_expr(p, fmls[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    catch (is_array_property_ns::bad) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return p.has_quantifier();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,33 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2010 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    array_property_recognizer.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2010-16-12
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _ARRAY_PROPERTY_RECOGNIZER_H_
 | 
			
		||||
#define _ARRAY_PROPERTY_RECOGNIZER_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
 | 
			
		||||
class array_property_recognizer {
 | 
			
		||||
    ast_manager& m_manager;
 | 
			
		||||
public:
 | 
			
		||||
    array_property_recognizer(ast_manager& m);
 | 
			
		||||
    bool operator()(unsigned num_fmls, expr* const* fmls);    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* _ARRAY_PROPERTY_RECOGNIZER_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,314 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2012 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    assertion_stack.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
    
 | 
			
		||||
    Assertion stacks
 | 
			
		||||
    
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2012-02-17
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"assertion_stack.h"
 | 
			
		||||
#include"well_sorted.h"
 | 
			
		||||
#include"ast_smt2_pp.h"
 | 
			
		||||
#include"ref_util.h"
 | 
			
		||||
 | 
			
		||||
assertion_stack::assertion_stack(ast_manager & m, bool models_enabled, bool core_enabled):
 | 
			
		||||
    m_manager(m),
 | 
			
		||||
    m_forbidden(m),
 | 
			
		||||
    m_csubst(m, core_enabled),
 | 
			
		||||
    m_fsubst(m, core_enabled) {
 | 
			
		||||
    init(m.proofs_enabled(), models_enabled, core_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
assertion_stack::assertion_stack(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled):
 | 
			
		||||
    m_manager(m),
 | 
			
		||||
    m_forbidden(m),
 | 
			
		||||
    m_csubst(m, core_enabled, proofs_enabled),
 | 
			
		||||
    m_fsubst(m, core_enabled, proofs_enabled) {
 | 
			
		||||
    init(proofs_enabled, models_enabled, core_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::init(bool proofs_enabled, bool models_enabled, bool core_enabled) {
 | 
			
		||||
    m_ref_count      = 0;
 | 
			
		||||
    m_models_enabled = models_enabled;
 | 
			
		||||
    m_proofs_enabled = proofs_enabled;
 | 
			
		||||
    m_core_enabled   = core_enabled;
 | 
			
		||||
    m_inconsistent   = false;
 | 
			
		||||
    m_form_qhead     = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
assertion_stack::~assertion_stack() {
 | 
			
		||||
    reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::reset() {
 | 
			
		||||
    m_inconsistent = false;
 | 
			
		||||
    m_form_qhead   = 0;
 | 
			
		||||
    m_mc_qhead     = 0;
 | 
			
		||||
    dec_ref_collection_values(m_manager, m_forms);
 | 
			
		||||
    dec_ref_collection_values(m_manager, m_proofs);
 | 
			
		||||
    dec_ref_collection_values(m_manager, m_deps);
 | 
			
		||||
    m_forbidden_set.reset();
 | 
			
		||||
    m_forbidden.reset();
 | 
			
		||||
    m_csubst.reset();
 | 
			
		||||
    m_fsubst.reset();
 | 
			
		||||
    m_mc.reset();
 | 
			
		||||
    m_scopes.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::expand(expr * f, proof * pr, expr_dependency * dep, expr_ref & new_f, proof_ref & new_pr, expr_dependency_ref & new_dep) {
 | 
			
		||||
    // TODO: expand definitions
 | 
			
		||||
    new_f   = f;
 | 
			
		||||
    new_pr  = pr;
 | 
			
		||||
    new_dep = dep;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::push_back(expr * f, proof * pr, expr_dependency * d) {
 | 
			
		||||
    if (m().is_true(f))
 | 
			
		||||
        return;
 | 
			
		||||
    if (m().is_false(f)) {
 | 
			
		||||
        m_inconsistent = true;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        SASSERT(!m_inconsistent);
 | 
			
		||||
    }
 | 
			
		||||
    m().inc_ref(f);
 | 
			
		||||
    m_forms.push_back(f);
 | 
			
		||||
    if (proofs_enabled()) {
 | 
			
		||||
        m().inc_ref(pr);
 | 
			
		||||
        m_proofs.push_back(pr);
 | 
			
		||||
    }
 | 
			
		||||
    if (unsat_core_enabled()) {
 | 
			
		||||
        m().inc_ref(d);
 | 
			
		||||
        m_deps.push_back(d);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::quick_process(bool save_first, expr * & f, expr_dependency * d) {
 | 
			
		||||
    if (!m().is_and(f) && !(m().is_not(f) && m().is_or(to_app(f)->get_arg(0)))) {
 | 
			
		||||
        if (!save_first) {
 | 
			
		||||
            push_back(f, 0, d);
 | 
			
		||||
        }
 | 
			
		||||
        return; 
 | 
			
		||||
    }
 | 
			
		||||
    typedef std::pair<expr *, bool> expr_pol;
 | 
			
		||||
    sbuffer<expr_pol, 64> todo;
 | 
			
		||||
    todo.push_back(expr_pol(f, true));
 | 
			
		||||
    while (!todo.empty()) {
 | 
			
		||||
        if (m_inconsistent)
 | 
			
		||||
            return;
 | 
			
		||||
        expr_pol p  = todo.back();
 | 
			
		||||
        expr * curr = p.first;
 | 
			
		||||
        bool   pol  = p.second;
 | 
			
		||||
        todo.pop_back();
 | 
			
		||||
        if (pol && m().is_and(curr)) {
 | 
			
		||||
            app * t = to_app(curr);
 | 
			
		||||
            unsigned i = t->get_num_args();
 | 
			
		||||
            while (i > 0) {
 | 
			
		||||
                --i;
 | 
			
		||||
                todo.push_back(expr_pol(t->get_arg(i), true));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (!pol && m().is_or(curr)) {
 | 
			
		||||
            app * t = to_app(curr);
 | 
			
		||||
            unsigned i = t->get_num_args();
 | 
			
		||||
            while (i > 0) {
 | 
			
		||||
                --i;
 | 
			
		||||
                todo.push_back(expr_pol(t->get_arg(i), false));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (m().is_not(curr)) {
 | 
			
		||||
            todo.push_back(expr_pol(to_app(curr)->get_arg(0), !pol));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            if (!pol) 
 | 
			
		||||
                curr = m().mk_not(curr);
 | 
			
		||||
            if (save_first) {
 | 
			
		||||
                f  = curr;
 | 
			
		||||
                save_first = false;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                push_back(curr, 0, d);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::process_and(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) {
 | 
			
		||||
    unsigned num = f->get_num_args();
 | 
			
		||||
    for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
        if (m_inconsistent)
 | 
			
		||||
            return;
 | 
			
		||||
        slow_process(save_first && i == 0, f->get_arg(i), m().mk_and_elim(pr, i), d, out_f, out_pr);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::process_not_or(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) {
 | 
			
		||||
    unsigned num = f->get_num_args();
 | 
			
		||||
    for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
        if (m_inconsistent)
 | 
			
		||||
            return;
 | 
			
		||||
        expr * child = f->get_arg(i);
 | 
			
		||||
        if (m().is_not(child)) {
 | 
			
		||||
            expr * not_child = to_app(child)->get_arg(0);
 | 
			
		||||
            slow_process(save_first && i == 0, not_child, m().mk_not_or_elim(pr, i), d, out_f, out_pr);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            expr_ref not_child(m());
 | 
			
		||||
            not_child = m().mk_not(child);
 | 
			
		||||
            slow_process(save_first && i == 0, not_child, m().mk_not_or_elim(pr, i), d, out_f, out_pr);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::slow_process(bool save_first, expr * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) {
 | 
			
		||||
    if (m().is_and(f)) 
 | 
			
		||||
        process_and(save_first, to_app(f), pr, d, out_f, out_pr);
 | 
			
		||||
    else if (m().is_not(f) && m().is_or(to_app(f)->get_arg(0))) 
 | 
			
		||||
        process_not_or(save_first, to_app(to_app(f)->get_arg(0)), pr, d, out_f, out_pr);
 | 
			
		||||
    else if (save_first) {
 | 
			
		||||
        out_f  = f;
 | 
			
		||||
        out_pr = pr;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        push_back(f, pr, d);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::slow_process(expr * f, proof * pr, expr_dependency * d) {
 | 
			
		||||
    expr_ref out_f(m());
 | 
			
		||||
    proof_ref out_pr(m());
 | 
			
		||||
    slow_process(false, f, pr, d, out_f, out_pr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void assertion_stack::assert_expr(expr * f, proof * pr, expr_dependency * d) {
 | 
			
		||||
    SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
 | 
			
		||||
    if (m_inconsistent)
 | 
			
		||||
        return;
 | 
			
		||||
    expr_ref new_f(m()); proof_ref new_pr(m()); expr_dependency_ref new_d(m());
 | 
			
		||||
    expand(f, pr, d, new_f, new_pr, new_d);
 | 
			
		||||
    if (proofs_enabled())
 | 
			
		||||
        slow_process(f, pr, d);
 | 
			
		||||
    else
 | 
			
		||||
        quick_process(false, f, d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef Z3DEBUG
 | 
			
		||||
// bool assertion_stack::is_expanded(expr * f) {
 | 
			
		||||
// }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void assertion_stack::update(unsigned i, expr * f, proof * pr, expr_dependency * d) {
 | 
			
		||||
    SASSERT(i >= m_form_qhead);
 | 
			
		||||
    SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
 | 
			
		||||
    if (m_inconsistent)
 | 
			
		||||
        return;
 | 
			
		||||
    if (proofs_enabled()) {
 | 
			
		||||
        expr_ref out_f(m());
 | 
			
		||||
        proof_ref out_pr(m());
 | 
			
		||||
        slow_process(true, f, pr, d, out_f, out_pr);
 | 
			
		||||
        if (!m_inconsistent) {
 | 
			
		||||
            if (m().is_false(out_f)) {
 | 
			
		||||
                push_back(out_f, out_pr, d);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                m().inc_ref(out_f);
 | 
			
		||||
                m().dec_ref(m_forms[i]);
 | 
			
		||||
                m_forms[i] = out_f;
 | 
			
		||||
 | 
			
		||||
                m().inc_ref(out_pr);
 | 
			
		||||
                m().dec_ref(m_proofs[i]);
 | 
			
		||||
                m_proofs[i] = out_pr;
 | 
			
		||||
 | 
			
		||||
                if (unsat_core_enabled()) {
 | 
			
		||||
                    m().inc_ref(d);
 | 
			
		||||
                    m().dec_ref(m_deps[i]);
 | 
			
		||||
                    m_deps[i] = d;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        quick_process(true, f, d);
 | 
			
		||||
        if (!m_inconsistent) {
 | 
			
		||||
            if (m().is_false(f)) {
 | 
			
		||||
                push_back(f, 0, d);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                m().inc_ref(f);
 | 
			
		||||
                m().dec_ref(m_forms[i]);
 | 
			
		||||
                m_forms[i] = f;
 | 
			
		||||
 | 
			
		||||
                if (unsat_core_enabled()) {
 | 
			
		||||
                    m().inc_ref(d);
 | 
			
		||||
                    m().dec_ref(m_deps[i]);
 | 
			
		||||
                    m_deps[i] = d;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::expand_and_update(unsigned i, expr * f, proof * pr, expr_dependency * d) {
 | 
			
		||||
    SASSERT(i >= m_form_qhead);
 | 
			
		||||
    SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
 | 
			
		||||
    if (m_inconsistent)
 | 
			
		||||
        return;
 | 
			
		||||
    expr_ref new_f(m()); proof_ref new_pr(m()); expr_dependency_ref new_d(m());
 | 
			
		||||
    expand(f, pr, d, new_f, new_pr, new_d);
 | 
			
		||||
    update(i, new_f, new_pr, new_d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::push() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::pop(unsigned num_scopes) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::commit() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::add_filter(func_decl * f) const {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::add_definition(app * c, expr * def, proof * pr, expr_dependency * dep) {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::add_definition(func_decl * f, quantifier * q, proof * pr, expr_dependency * dep) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::convert(model_ref & m) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assertion_stack::display(std::ostream & out) const {
 | 
			
		||||
    out << "(assertion-stack";
 | 
			
		||||
    unsigned sz = size();
 | 
			
		||||
    for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
        out << "\n  ";
 | 
			
		||||
        if (i == m_form_qhead) 
 | 
			
		||||
            out << "==>\n";
 | 
			
		||||
        out << mk_ismt2_pp(form(i), m(), 2);
 | 
			
		||||
    }
 | 
			
		||||
    out << ")" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool assertion_stack::is_well_sorted() const {
 | 
			
		||||
    unsigned sz = size();
 | 
			
		||||
    for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
        expr * t = form(i);
 | 
			
		||||
        if (!::is_well_sorted(m(), t))
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,141 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2012 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    assertion_stack.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    It should be viewed as the "goal" object for incremental solvers.
 | 
			
		||||
    The main difference is the support of push/pop operations.  Like a
 | 
			
		||||
    goal, an assertion_stack contains expressions, their proofs (if
 | 
			
		||||
    proof generation is enabled), and dependencies (if unsat core
 | 
			
		||||
    generation is enabled).
 | 
			
		||||
 | 
			
		||||
    The assertions on the stack are grouped by scope levels. Scoped
 | 
			
		||||
    levels are created using push, and removed using pop. 
 | 
			
		||||
 | 
			
		||||
    Assertions may be "committed". Whenever a push is executed, all
 | 
			
		||||
    "uncommitted" assertions are automatically committed. 
 | 
			
		||||
    Only uncommitted assertions can be simplified/reduced.
 | 
			
		||||
 | 
			
		||||
    An assertion set has a limited model converter that only supports
 | 
			
		||||
    definitions (for variable/function elimination) and filters (for fresh
 | 
			
		||||
    symbols introduced by tactics).
 | 
			
		||||
 | 
			
		||||
    Some tactics support assertion_stacks and can be applied to them.
 | 
			
		||||
    However, a tactic can only access the assertions on the top level.
 | 
			
		||||
    The assertion stack also informs the tactic which declarations 
 | 
			
		||||
    can't be eliminated since they occur in the already committed part. 
 | 
			
		||||
    
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2012-02-17
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _ASSERTION_STACK_H_
 | 
			
		||||
#define _ASSERTION_STACK_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"model.h"
 | 
			
		||||
#include"expr_substitution.h"
 | 
			
		||||
#include"macro_substitution.h"
 | 
			
		||||
 | 
			
		||||
class assertion_stack {
 | 
			
		||||
    ast_manager &                m_manager;
 | 
			
		||||
    unsigned                     m_ref_count;
 | 
			
		||||
    bool                         m_models_enabled;  // model generation is enabled.
 | 
			
		||||
    bool                         m_proofs_enabled;  // proof production is enabled. m_manager.proofs_enabled() must be true if m_proofs_enabled == true
 | 
			
		||||
    bool                         m_core_enabled;    // unsat core extraction is enabled.
 | 
			
		||||
    bool                         m_inconsistent; 
 | 
			
		||||
    ptr_vector<expr>             m_forms;
 | 
			
		||||
    ptr_vector<proof>            m_proofs;
 | 
			
		||||
    ptr_vector<expr_dependency>  m_deps;
 | 
			
		||||
    unsigned                     m_form_qhead; // position of first uncommitted assertion
 | 
			
		||||
    unsigned                     m_mc_qhead;
 | 
			
		||||
 | 
			
		||||
    // Set of declarations that can't be eliminated
 | 
			
		||||
    obj_hashtable<func_decl>     m_forbidden_set;
 | 
			
		||||
    func_decl_ref_vector         m_forbidden;
 | 
			
		||||
    
 | 
			
		||||
    // Limited model converter support, it supports only extensions
 | 
			
		||||
    // and filters.
 | 
			
		||||
    // It should be viewed as combination of extension_model_converter and 
 | 
			
		||||
    // filter_model_converter for goals.
 | 
			
		||||
    expr_substitution            m_csubst;  // substitution for eliminated constants
 | 
			
		||||
    macro_substitution           m_fsubst;  // substitution for eliminated functions
 | 
			
		||||
 | 
			
		||||
    // Model converter is just a sequence of tagged pointers.
 | 
			
		||||
    // Tag 0 (extension) func_decl was eliminated, and its definition is in m_vsubst or m_fsubst.
 | 
			
		||||
    // Tag 1 (filter) func_decl was introduced by tactic, and must be removed from model.
 | 
			
		||||
    ptr_vector<func_decl>        m_mc;      
 | 
			
		||||
    
 | 
			
		||||
    struct scope {
 | 
			
		||||
        unsigned                 m_forms_lim;
 | 
			
		||||
        unsigned                 m_forbidden_vars_lim;
 | 
			
		||||
        unsigned                 m_mc_lim;
 | 
			
		||||
        bool                     m_inconsistent_old;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    svector<scope>               m_scopes;
 | 
			
		||||
 | 
			
		||||
    void init(bool proofs_enabled, bool models_enabled, bool core_enabled);
 | 
			
		||||
    void expand(expr * f, proof * pr, expr_dependency * dep, expr_ref & new_f, proof_ref & new_pr, expr_dependency_ref & new_dep);
 | 
			
		||||
    void push_back(expr * f, proof * pr, expr_dependency * d);
 | 
			
		||||
    void quick_process(bool save_first, expr * & f, expr_dependency * d);
 | 
			
		||||
    void process_and(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
 | 
			
		||||
    void process_not_or(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
 | 
			
		||||
    void slow_process(bool save_first, expr * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
 | 
			
		||||
    void slow_process(expr * f, proof * pr, expr_dependency * d);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    assertion_stack(ast_manager & m, bool models_enabled = true, bool core_enabled = true);
 | 
			
		||||
    assertion_stack(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled);
 | 
			
		||||
    ~assertion_stack();
 | 
			
		||||
 | 
			
		||||
    void reset();
 | 
			
		||||
 | 
			
		||||
    void inc_ref() { ++m_ref_count; }
 | 
			
		||||
    void dec_ref() { --m_ref_count; if (m_ref_count == 0) dealloc(this); }
 | 
			
		||||
    
 | 
			
		||||
    ast_manager & m() const { return m_manager; }
 | 
			
		||||
    
 | 
			
		||||
    bool models_enabled() const { return m_models_enabled; }
 | 
			
		||||
    bool proofs_enabled() const { return m_proofs_enabled; }
 | 
			
		||||
    bool unsat_core_enabled() const { return m_core_enabled; }
 | 
			
		||||
    bool inconsistent() const { return m_inconsistent; }
 | 
			
		||||
    
 | 
			
		||||
    unsigned size() const { return m_forms.size(); }
 | 
			
		||||
    unsigned qhead() const { return m_form_qhead; }
 | 
			
		||||
    expr * form(unsigned i) const { return m_forms[i]; }
 | 
			
		||||
    proof * pr(unsigned i) const { return proofs_enabled() ? static_cast<proof*>(m_proofs[i]) : 0; }
 | 
			
		||||
    expr_dependency * dep(unsigned i) const { return unsat_core_enabled() ? m_deps[i] : 0; }
 | 
			
		||||
    
 | 
			
		||||
    void assert_expr(expr * f, proof * pr, expr_dependency * d);
 | 
			
		||||
    void assert_expr(expr * f) {
 | 
			
		||||
        assert_expr(f, proofs_enabled() ? m().mk_asserted(f) : 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
    void update(unsigned i, expr * f, proof * pr = 0, expr_dependency * dep = 0);
 | 
			
		||||
    void expand_and_update(unsigned i, expr * f, proof * pr = 0, expr_dependency * d = 0);
 | 
			
		||||
    
 | 
			
		||||
    void commit();
 | 
			
		||||
    void push();
 | 
			
		||||
    void pop(unsigned num_scopes);
 | 
			
		||||
    unsigned scope_lvl() const { return m_scopes.size(); }
 | 
			
		||||
  
 | 
			
		||||
    bool is_well_sorted() const;
 | 
			
		||||
 | 
			
		||||
    bool is_forbidden(func_decl * f) const { return m_forbidden_set.contains(f); }
 | 
			
		||||
    void add_filter(func_decl * f) const;
 | 
			
		||||
    void add_definition(app * c, expr * def, proof * pr, expr_dependency * dep);
 | 
			
		||||
    void add_definition(func_decl * f, quantifier * q, proof * pr, expr_dependency * dep);
 | 
			
		||||
 | 
			
		||||
    void convert(model_ref & m);
 | 
			
		||||
 | 
			
		||||
    void display(std::ostream & out) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,33 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    big_rational.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Big rational numbers
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-09-18.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _BIG_RATIONAL_H_
 | 
			
		||||
#define _BIG_RATIONAL_H_
 | 
			
		||||
 | 
			
		||||
#ifdef _WINDOWS
 | 
			
		||||
#include"..\msbig_rational\msbig_rational.h"
 | 
			
		||||
#else
 | 
			
		||||
#ifdef NO_GMP
 | 
			
		||||
#include"dummy_big_rational.h"
 | 
			
		||||
#else
 | 
			
		||||
#include"gmp_big_rational.h"
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BIG_RATIONAL_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,168 +0,0 @@
 | 
			
		|||
AC_PREREQ(2.50)
 | 
			
		||||
AC_INIT(lib/util.h)
 | 
			
		||||
 | 
			
		||||
ARITH="internal"
 | 
			
		||||
AC_ARG_WITH([gmp], [AS_HELP_STRING([--with-gmp], [Use GMP for multi-precision naturals (default=no)])], [use_gmp=yes], [use_gmp=no])
 | 
			
		||||
AS_IF([test "$use_gmp" = "yes"],[
 | 
			
		||||
  ARITH="gmp"
 | 
			
		||||
  CPPFLAGS="$CPPFLAGS -D_MP_GMP"
 | 
			
		||||
],[
 | 
			
		||||
  CPPFLAGS="$CPPFLAGS -D_MP_INTERNAL"
 | 
			
		||||
])
 | 
			
		||||
AC_SUBST(EXTRA_LIB_SRCS)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(python,
 | 
			
		||||
[AS_HELP_STRING([--with-python=PYTHON_PATH],
 | 
			
		||||
		[specify the location of the python 2.x executable.])])
 | 
			
		||||
 | 
			
		||||
PYTHON="python"
 | 
			
		||||
if test "x$with_python" != x; then
 | 
			
		||||
  PYTHON="$with_python"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_SUBST(PYTHON)
 | 
			
		||||
 | 
			
		||||
AC_PATH_PROG([D2U], [dos2unix], [no], [~/bin$PATH_SEPARATOR$PATH])
 | 
			
		||||
AS_IF([test "$D2U" = "no"], [AC_MSG_ERROR(dos2unix not found)])
 | 
			
		||||
AC_SUBST(D2U)
 | 
			
		||||
 | 
			
		||||
AC_PROG_CXX(g++)
 | 
			
		||||
AC_PROG_MAKE_SET
 | 
			
		||||
 | 
			
		||||
AC_LANG_CPLUSPLUS
 | 
			
		||||
 | 
			
		||||
host_os=`uname -s`
 | 
			
		||||
 | 
			
		||||
AS_IF([test "$host_os" = "Darwin"], [
 | 
			
		||||
  PLATFORM=osx
 | 
			
		||||
  SO_EXT=dylib
 | 
			
		||||
  SLIBFLAGS="-dynamiclib -fopenmp"
 | 
			
		||||
  COMP_VERSIONS="-compatibility_version \$(Z3_VERSION) -current_version \$(Z3_VERSION)"
 | 
			
		||||
  STATIC_FLAGS=
 | 
			
		||||
  CPPFLAGS+=""
 | 
			
		||||
], [test "$host_os" = "Linux"], [
 | 
			
		||||
  PLATFORM=linux
 | 
			
		||||
  SO_EXT=so
 | 
			
		||||
  LDFLAGS=-lrt
 | 
			
		||||
  SLIBFLAGS="-shared -fopenmp"
 | 
			
		||||
  COMP_VERSIONS=
 | 
			
		||||
  STATIC_FLAGS=-static
 | 
			
		||||
], [test "${host_os:0:6}" = "CYGWIN"], [
 | 
			
		||||
   PLATFORM=win
 | 
			
		||||
   SO_EXT=dll
 | 
			
		||||
   LDFLAGS=
 | 
			
		||||
   SLIBFLAGS="-shared -fopenmp"
 | 
			
		||||
   COMP_VERSIONS=
 | 
			
		||||
   STATIC_FLAGS=-static
 | 
			
		||||
   CPPFLAGS+=" -D_CYGWIN"
 | 
			
		||||
],
 | 
			
		||||
[
 | 
			
		||||
  AC_MSG_ERROR([Unknown host platform: $host_os])
 | 
			
		||||
])
 | 
			
		||||
AC_SUBST(PLATFORM)
 | 
			
		||||
AC_SUBST(SO_EXT)
 | 
			
		||||
AC_SUBST(SLIBFLAGS)
 | 
			
		||||
AC_SUBST(COMP_VERSIONS)
 | 
			
		||||
AC_SUBST(STATIC_FLAGS)
 | 
			
		||||
 | 
			
		||||
cat > tst_python.py <<EOF
 | 
			
		||||
from sys import version
 | 
			
		||||
if version >= "3":
 | 
			
		||||
   exit(1)
 | 
			
		||||
exit(0)
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
if $PYTHON tst_python.py; then
 | 
			
		||||
  HAS_PYTHON="1"
 | 
			
		||||
  HAS_PYTHON_MSG="yes"
 | 
			
		||||
cat > get_py_dir.py << EOF
 | 
			
		||||
import distutils.sysconfig
 | 
			
		||||
print distutils.sysconfig.get_python_lib()
 | 
			
		||||
EOF
 | 
			
		||||
  if $PYTHON get_py_dir.py > dir.txt; then
 | 
			
		||||
    PYTHON_PACKAGE_DIR=`cat dir.txt`
 | 
			
		||||
  else
 | 
			
		||||
    HAS_PYTHON="0"
 | 
			
		||||
    HAS_PYTHON_MSG="no"
 | 
			
		||||
  fi
 | 
			
		||||
  rm -f dir.txt
 | 
			
		||||
  rm -f get_py_dir.py
 | 
			
		||||
else
 | 
			
		||||
  HAS_PYTHON="0"
 | 
			
		||||
  HAS_PYTHON_MSG="no"
 | 
			
		||||
fi
 | 
			
		||||
AC_SUBST(PYTHON_PACKAGE_DIR)
 | 
			
		||||
AC_SUBST(HAS_PYTHON)
 | 
			
		||||
rm -f tst_python.py
 | 
			
		||||
 | 
			
		||||
cat > tst64.c <<EOF
 | 
			
		||||
    int main() {
 | 
			
		||||
    	return sizeof(unsigned) == sizeof(void*);
 | 
			
		||||
    }
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
AC_SUBST(EXTRA_LIBS)
 | 
			
		||||
 | 
			
		||||
g++ $CPPFLAGS tst64.c -o tst64
 | 
			
		||||
if ./tst64; then
 | 
			
		||||
   dnl In 64-bit systems we have to compile using -fPIC
 | 
			
		||||
   CPPFLAGS="$CPPFLAGS -D_AMD64_"
 | 
			
		||||
   dnl Only enable use of thread local storage for 64-bit Linux. It is disabled for OSX and 32-bit Linux
 | 
			
		||||
   if test $PLATFORM = "linux"; then
 | 
			
		||||
      CPPFLAGS="$CPPFLAGS -D_USE_THREAD_LOCAL" 
 | 
			
		||||
   fi
 | 
			
		||||
   CXXFLAGS="-fPIC"
 | 
			
		||||
   EXTRA_LIBS=""
 | 
			
		||||
   dnl Rewrite -lz3-gmp to -lz3 in the files:
 | 
			
		||||
   dnl  - test_capi/build-external-linux.sh 
 | 
			
		||||
   dnl  - test_user_theory/build-external-linux.sh
 | 
			
		||||
   dnl Reason: the library libz3-gmp.so is not available in 64-bit systems
 | 
			
		||||
   dnl sed 's|lz3-gmp|lz3|' test_capi/build-external-linux.sh > tmp.sh
 | 
			
		||||
   dnl mv tmp.sh test_capi/build-external-linux.sh
 | 
			
		||||
   dnl sed 's|lz3-gmp|lz3|' test_user_theory/build-external-linux.sh > tmp.sh
 | 
			
		||||
   dnl mv tmp.sh test_user_theory/build-external-linux.sh
 | 
			
		||||
else
 | 
			
		||||
   CXXFLAGS=""
 | 
			
		||||
   dnl In 64-bit systems it is not possible to build a dynamic library using static gmp.
 | 
			
		||||
   dnl EXTRA_LIBS="\$(BIN_DIR)/lib\$(Z3)-gmp.so"
 | 
			
		||||
fi
 | 
			
		||||
rm -f tst64.c
 | 
			
		||||
rm -f tst64
 | 
			
		||||
 | 
			
		||||
AC_SUBST(GMP_STATIC_LIB)
 | 
			
		||||
GMP_STATIC_LIB=""
 | 
			
		||||
 | 
			
		||||
if test "$ARITH" = "gmp"; then
 | 
			
		||||
   AC_CHECK_HEADER([gmp.h], GMP='gmp', AC_MSG_ERROR([GMP include file not found]))
 | 
			
		||||
   AC_SUBST(LIBS)
 | 
			
		||||
   AC_CHECK_LIB(gmp, __gmpz_cmp, LIBS="-lgmp $LIBS", AC_MSG_ERROR([GMP library not found]))
 | 
			
		||||
   dnl Look for libgmp.a at /usr/local/lib and /usr/lib
 | 
			
		||||
   dnl TODO: make the following test more robust...
 | 
			
		||||
   if test -e /usr/local/lib/libgmp.a; then
 | 
			
		||||
      GMP_STATIC_LIB="/usr/local/lib/libgmp.a"
 | 
			
		||||
   else if test -e /usr/lib/libgmp.a; then
 | 
			
		||||
      GMP_STATIC_LIB="/usr/lib/libgmp.a"
 | 
			
		||||
   else if test -e /usr/lib/libgmp.dll.a; then
 | 
			
		||||
      GMP_STATIC_LIB="/usr/lib/libgmp.dll.a"
 | 
			
		||||
   else
 | 
			
		||||
      AC_MSG_ERROR([Failed to find libgmp.a])   
 | 
			
		||||
   fi fi fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_PROG_CXXCPP
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT(Makefile)
 | 
			
		||||
 | 
			
		||||
cat <<EOF
 | 
			
		||||
 | 
			
		||||
Z3 was configured with success.
 | 
			
		||||
Host platform:  $PLATFORM
 | 
			
		||||
Arithmetic:     $ARITH
 | 
			
		||||
Python Support: $HAS_PYTHON_MSG
 | 
			
		||||
Python:         $PYTHON 
 | 
			
		||||
Prefix:         $prefix
 | 
			
		||||
 | 
			
		||||
Type 'make' to compile Z3.
 | 
			
		||||
Type 'sudo make install' to install Z3.
 | 
			
		||||
Type 'sudo make install-z3py' to install Z3 Python (Z3Py) bindings.
 | 
			
		||||
EOF
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    contains_var.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2007-06-12.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _CONTAINS_VAR_H_
 | 
			
		||||
#define _CONTAINS_VAR_H_
 | 
			
		||||
 | 
			
		||||
class ast;
 | 
			
		||||
 | 
			
		||||
bool contains_var(ast * n);
 | 
			
		||||
 | 
			
		||||
#endif /* _CONTAINS_VAR_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,64 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2010 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dl_simplifier_plugin.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2010-08-10
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include"dl_simplifier_plugin.h"
 | 
			
		||||
 | 
			
		||||
namespace datalog {
 | 
			
		||||
 | 
			
		||||
    dl_simplifier_plugin::dl_simplifier_plugin(ast_manager& m) 
 | 
			
		||||
        : simplifier_plugin(symbol("datalog_relation"), m),
 | 
			
		||||
          m_util(m)
 | 
			
		||||
    {}
 | 
			
		||||
        
 | 
			
		||||
    bool dl_simplifier_plugin::reduce(
 | 
			
		||||
        func_decl * f, unsigned num_args, expr* const* args, expr_ref& result) {
 | 
			
		||||
        uint64 v1, v2;
 | 
			
		||||
        switch(f->get_decl_kind()) {
 | 
			
		||||
        case OP_DL_LT:
 | 
			
		||||
            if (m_util.try_get_constant(args[0], v1) &&
 | 
			
		||||
                m_util.try_get_constant(args[1], v2)) {
 | 
			
		||||
                result = (v1 < v2)?m_manager.mk_true():m_manager.mk_false();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            // x < x <=> false
 | 
			
		||||
            if (args[0] == args[1]) {
 | 
			
		||||
                result = m_manager.mk_false();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            // x < 0 <=> false
 | 
			
		||||
            if (m_util.try_get_constant(args[1], v2) && v2 == 0) {
 | 
			
		||||
                result = m_manager.mk_false();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            // 0 < x <=> 0 != x
 | 
			
		||||
            if (m_util.try_get_constant(args[1], v1) && v1 == 0) {
 | 
			
		||||
                result = m_manager.mk_not(m_manager.mk_eq(args[0], args[1]));
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,38 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2010 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dl_simplifier_plugin.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2010-08-10
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _DL_SIMPLIFIER_PLUGIN_H_
 | 
			
		||||
#define _DL_SIMPLIFIER_PLUGIN_H_
 | 
			
		||||
 | 
			
		||||
#include"dl_decl_plugin.h"
 | 
			
		||||
#include "simplifier_plugin.h"
 | 
			
		||||
 | 
			
		||||
namespace datalog {
 | 
			
		||||
 | 
			
		||||
    class dl_simplifier_plugin : public simplifier_plugin {
 | 
			
		||||
        dl_decl_util  m_util;
 | 
			
		||||
    public:
 | 
			
		||||
        dl_simplifier_plugin(ast_manager& m);
 | 
			
		||||
        
 | 
			
		||||
        virtual bool reduce(func_decl * f, unsigned num_args, expr* const* args, expr_ref& result);
 | 
			
		||||
        
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
#endif /* _DL_SIMPLIFIER_PLUGIN_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dummy_big_rational.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Dummy big rational
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-09-26.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#ifndef _DUMMY_BIG_RATIONAL_H_
 | 
			
		||||
#define _DUMMY_BIG_RATIONAL_H_
 | 
			
		||||
 | 
			
		||||
#include<string>
 | 
			
		||||
#include"debug.h"
 | 
			
		||||
 | 
			
		||||
class big_rational {
 | 
			
		||||
public:
 | 
			
		||||
    big_rational() { }
 | 
			
		||||
    big_rational(int n) {}
 | 
			
		||||
    ~big_rational() {}
 | 
			
		||||
    void reset() {}
 | 
			
		||||
    unsigned hash() const { return 0; }
 | 
			
		||||
    void set(int num, int den) { UNREACHABLE(); }
 | 
			
		||||
    void set(const char * str) { UNREACHABLE(); }
 | 
			
		||||
    bool is_int() const { UNREACHABLE(); return false; }
 | 
			
		||||
    long get_int() const { UNREACHABLE(); return 0; }
 | 
			
		||||
    void neg() { UNREACHABLE(); }
 | 
			
		||||
    big_rational & operator=(const big_rational & r) { UNREACHABLE(); return *this; }
 | 
			
		||||
    bool operator==(const big_rational & r) const { UNREACHABLE(); return false; }
 | 
			
		||||
    bool operator<(const big_rational & r) const { UNREACHABLE(); return false; }
 | 
			
		||||
    big_rational & operator+=(const big_rational & r) { UNREACHABLE(); return *this; }
 | 
			
		||||
    big_rational & operator-=(const big_rational & r) { UNREACHABLE(); return *this; }
 | 
			
		||||
    big_rational & operator*=(const big_rational & r) { UNREACHABLE(); return *this; }
 | 
			
		||||
    big_rational & operator/=(const big_rational & r) { UNREACHABLE(); return *this; }
 | 
			
		||||
    big_rational & operator%=(const big_rational & r) { UNREACHABLE(); return *this; }
 | 
			
		||||
    friend void div(const big_rational & r1, const big_rational & r2, big_rational & result) { UNREACHABLE(); }
 | 
			
		||||
    void get_numerator(big_rational & result) { UNREACHABLE(); }
 | 
			
		||||
    void get_denominator(big_rational & result) { UNREACHABLE(); }
 | 
			
		||||
    void get_floor(big_rational & result) { UNREACHABLE(); }
 | 
			
		||||
    std::string to_string() const { UNREACHABLE(); return std::string(""); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _DUMMY_BIG_RATIONAL_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,32 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2007 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    expr_weight.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Functor for computing the weight of an expression.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo (leonardo) 2008-01-11
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"expr_weight.h"
 | 
			
		||||
#include"recurse_expr_def.h"
 | 
			
		||||
 | 
			
		||||
template class recurse_expr<weight, expr_weight_visitor, true>;
 | 
			
		||||
 | 
			
		||||
weight expr_weight_visitor::visit(app const * n, weight const * args) {
 | 
			
		||||
    weight r(1);
 | 
			
		||||
    unsigned j = n->get_num_args();
 | 
			
		||||
    while (j > 0) {
 | 
			
		||||
        --j;
 | 
			
		||||
        r += args[j];
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,35 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2007 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    expr_weight.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Functor for computing the weight of an expression.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo (leonardo) 2008-01-11
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _EXPR_WEIGHT_H_
 | 
			
		||||
#define _EXPR_WEIGHT_H_
 | 
			
		||||
 | 
			
		||||
#include"recurse_expr.h"
 | 
			
		||||
#include"approx_nat.h"
 | 
			
		||||
 | 
			
		||||
typedef approx_nat weight;
 | 
			
		||||
 | 
			
		||||
struct expr_weight_visitor {
 | 
			
		||||
    weight visit(var * n) { return weight(1); }
 | 
			
		||||
    weight visit(app const * n, weight const * args);
 | 
			
		||||
    weight visit(quantifier * n, weight body, weight *, weight *) { body += 1; return body; } 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef recurse_expr<weight, expr_weight_visitor, true> expr_weight;
 | 
			
		||||
 | 
			
		||||
#endif /* _EXPR_WEIGHT_H_ */
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,29 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    gl_tactic.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    A T-function/Goldreich Levin-based heuristic.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj (nbjorner) 2011-12-18
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#ifndef _GL_TACTIC_H_
 | 
			
		||||
#define _GL_TACTIC_H_
 | 
			
		||||
 | 
			
		||||
#include"tactic.h"
 | 
			
		||||
 | 
			
		||||
namespace gl {
 | 
			
		||||
    tactic * mk_tactic(ast_manager& m, params_ref const& p);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,117 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    gmp_big_rational.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Big rationals using GMP
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-09-26.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include<limits.h>
 | 
			
		||||
 | 
			
		||||
#include"gmp_big_rational.h"
 | 
			
		||||
#include"trace.h"
 | 
			
		||||
#include"buffer.h"
 | 
			
		||||
 | 
			
		||||
#ifndef NO_GMP
 | 
			
		||||
mpz_t big_rational::m_tmp;
 | 
			
		||||
bool  big_rational::m_tmp_initialized = false;
 | 
			
		||||
mpz_t big_rational::m_int_min;
 | 
			
		||||
mpz_t big_rational::m_int_max;
 | 
			
		||||
mpz_t big_rational::m_uint_max;
 | 
			
		||||
mpz_t big_rational::m_two32;
 | 
			
		||||
mpz_t big_rational::m_int64_min;
 | 
			
		||||
mpz_t big_rational::m_int64_max;
 | 
			
		||||
mpz_t big_rational::m_uint64_max;
 | 
			
		||||
bool  big_rational::m_has_limits = false;
 | 
			
		||||
 | 
			
		||||
void big_rational::init_limits() {
 | 
			
		||||
    mpz_init(m_int_min);
 | 
			
		||||
    mpz_init(m_int_max);
 | 
			
		||||
    mpz_init(m_uint_max);
 | 
			
		||||
    mpz_init(m_two32);
 | 
			
		||||
    mpz_init(m_int64_min);
 | 
			
		||||
    mpz_init(m_int64_max);
 | 
			
		||||
    mpz_init(m_uint64_max);
 | 
			
		||||
    mpz_set_si(m_int_min,  INT_MIN);
 | 
			
		||||
    mpz_set_si(m_int_max,  INT_MAX);
 | 
			
		||||
    mpz_set_ui(m_uint_max, UINT_MAX);
 | 
			
		||||
    mpz_set_ui(m_two32, UINT_MAX);
 | 
			
		||||
    mpz_t & tmp = get_tmp();
 | 
			
		||||
    mpz_set_si(tmp, 1);
 | 
			
		||||
    mpz_add(m_two32, m_two32, tmp);
 | 
			
		||||
    unsigned max_l = static_cast<unsigned>(INT64_MAX % static_cast<int64>(UINT_MAX));
 | 
			
		||||
    unsigned max_h = static_cast<unsigned>(INT64_MAX / static_cast<int64>(UINT_MAX));
 | 
			
		||||
    mpz_set_ui(m_int64_max, max_h);
 | 
			
		||||
    mpz_mul(m_int64_max, m_uint_max, m_int64_max);
 | 
			
		||||
    mpz_set_ui(tmp, max_l);
 | 
			
		||||
    mpz_add(m_int64_max, tmp, m_int64_max);
 | 
			
		||||
    mpz_neg(m_int64_min, m_int64_max);
 | 
			
		||||
    mpz_set_si(tmp, -1);
 | 
			
		||||
    mpz_add(m_int64_min, m_int64_min, tmp);
 | 
			
		||||
    mpz_set(m_uint64_max, m_int64_max);
 | 
			
		||||
    mpz_set_si(tmp, 2);
 | 
			
		||||
    mpz_mul(m_uint64_max, m_uint64_max, tmp);
 | 
			
		||||
    mpz_set_si(tmp, 1);
 | 
			
		||||
    mpz_add(m_uint64_max, m_uint64_max, tmp);
 | 
			
		||||
    m_has_limits = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string big_rational::to_string() const {
 | 
			
		||||
    size_t sz = mpz_sizeinbase(mpq_numref(m_data), 10) + mpz_sizeinbase(mpq_numref(m_data), 10) + 3;
 | 
			
		||||
    buffer<char> b(sz, 0);
 | 
			
		||||
    mpq_get_str(b.c_ptr(), 10, m_data);
 | 
			
		||||
    std::string result(b.c_ptr());
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64 big_rational::get_int64() const {
 | 
			
		||||
    if (!m_has_limits) {
 | 
			
		||||
        init_limits();
 | 
			
		||||
    }
 | 
			
		||||
    SASSERT(is_int64());
 | 
			
		||||
    mpz_t & tmp = get_tmp();
 | 
			
		||||
    mpq_get_num(tmp, m_data);
 | 
			
		||||
    if (sizeof(int64) == sizeof(long) || mpz_fits_slong_p(tmp)) {
 | 
			
		||||
        return mpz_get_si(tmp);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        mpz_mod(tmp, tmp, two32());
 | 
			
		||||
        int64 r = static_cast<int64>(mpz_get_ui(tmp));
 | 
			
		||||
        mpq_get_num(tmp, m_data);
 | 
			
		||||
        mpz_div(tmp, tmp, two32());
 | 
			
		||||
        r += static_cast<int64>(mpz_get_si(tmp)) << static_cast<int64>(32);
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64 big_rational::get_uint64() const {
 | 
			
		||||
    if (!m_has_limits) {
 | 
			
		||||
        init_limits();
 | 
			
		||||
    }
 | 
			
		||||
    SASSERT(is_uint64());
 | 
			
		||||
    mpz_t & tmp = get_tmp();
 | 
			
		||||
    mpq_get_num(tmp, m_data);
 | 
			
		||||
    if (sizeof(uint64) == sizeof(unsigned long) || mpz_fits_ulong_p(tmp)) {
 | 
			
		||||
        return mpz_get_ui(tmp);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        mpz_mod(tmp, tmp, two32());
 | 
			
		||||
        uint64 r = static_cast<uint64>(mpz_get_ui(tmp));
 | 
			
		||||
        mpq_get_num(tmp, m_data);
 | 
			
		||||
        mpz_div(tmp, tmp, two32());
 | 
			
		||||
        r += static_cast<uint64>(mpz_get_ui(tmp)) << static_cast<uint64>(32);
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,193 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    gmp_big_rational.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Big rationals using gmp
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-09-26.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _GMP_BIG_RATIONAL_H_
 | 
			
		||||
#define _GMP_BIG_RATIONAL_H_
 | 
			
		||||
 | 
			
		||||
#ifndef NO_GMP
 | 
			
		||||
 | 
			
		||||
#include<string>
 | 
			
		||||
#include<gmp.h>
 | 
			
		||||
#include"util.h"
 | 
			
		||||
#include"debug.h"
 | 
			
		||||
#include"trace.h"
 | 
			
		||||
 | 
			
		||||
class big_rational {
 | 
			
		||||
    mpq_t        m_data;
 | 
			
		||||
    static mpz_t m_tmp;
 | 
			
		||||
    static bool  m_tmp_initialized;
 | 
			
		||||
    static mpz_t & get_tmp() { 
 | 
			
		||||
        if (!m_tmp_initialized) {
 | 
			
		||||
            mpz_init(m_tmp);
 | 
			
		||||
            m_tmp_initialized = true;
 | 
			
		||||
        }
 | 
			
		||||
        return m_tmp;
 | 
			
		||||
    }
 | 
			
		||||
    static mpz_t m_int_min;
 | 
			
		||||
    static mpz_t m_int_max;
 | 
			
		||||
    static mpz_t m_uint_max;
 | 
			
		||||
    static mpz_t m_two32;
 | 
			
		||||
    static mpz_t m_int64_min;
 | 
			
		||||
    static mpz_t m_int64_max;
 | 
			
		||||
    static mpz_t m_uint64_max;
 | 
			
		||||
    static bool  m_has_limits;
 | 
			
		||||
    static void init_limits();
 | 
			
		||||
 | 
			
		||||
    static mpz_t & int64_min() {
 | 
			
		||||
        if (!m_has_limits) {
 | 
			
		||||
            init_limits();
 | 
			
		||||
        }
 | 
			
		||||
        return m_int64_min;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static mpz_t & int64_max() {
 | 
			
		||||
        if (!m_has_limits) {
 | 
			
		||||
            init_limits();
 | 
			
		||||
        }
 | 
			
		||||
        return m_int64_max;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static mpz_t & uint64_max() {
 | 
			
		||||
        if (!m_has_limits) {
 | 
			
		||||
            init_limits();
 | 
			
		||||
        }
 | 
			
		||||
        return m_uint64_max;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static mpz_t & uint_max() {
 | 
			
		||||
        if (!m_has_limits) {
 | 
			
		||||
            init_limits();
 | 
			
		||||
        }
 | 
			
		||||
        return m_uint_max;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static mpz_t & two32() {
 | 
			
		||||
        if (!m_has_limits) {
 | 
			
		||||
            init_limits();
 | 
			
		||||
        }
 | 
			
		||||
        return m_two32;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
public:
 | 
			
		||||
    big_rational() { mpq_init(m_data); reset(); }
 | 
			
		||||
    big_rational(int n) { mpq_init(m_data); mpq_set_si(m_data, n, 1); }
 | 
			
		||||
    ~big_rational() { mpq_clear(m_data); }
 | 
			
		||||
    void reset() { mpq_set_si(m_data, 0, 1); }
 | 
			
		||||
    unsigned hash() const { return mpz_get_si(mpq_numref(m_data)); }
 | 
			
		||||
    void set(int num, int den) { 
 | 
			
		||||
        mpq_set_si(m_data, num, den);
 | 
			
		||||
        mpq_canonicalize(m_data);
 | 
			
		||||
    }
 | 
			
		||||
    void setu(unsigned num) {
 | 
			
		||||
        mpq_set_ui(m_data, num, 1);
 | 
			
		||||
        mpq_canonicalize(m_data);
 | 
			
		||||
    }
 | 
			
		||||
    void set(const char * str) {
 | 
			
		||||
        mpq_set_str(m_data, str, 10);
 | 
			
		||||
    }
 | 
			
		||||
    bool is_int() const {
 | 
			
		||||
        return mpz_cmp_ui(mpq_denref(m_data), 1) == 0;
 | 
			
		||||
    }
 | 
			
		||||
    bool is_even() const {
 | 
			
		||||
        if (!is_int()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpq_get_num(tmp, m_data);
 | 
			
		||||
        return mpz_even_p(tmp) != 0;
 | 
			
		||||
    }
 | 
			
		||||
    bool is_int64() const {
 | 
			
		||||
        if (!is_int()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpq_get_num(tmp, m_data);
 | 
			
		||||
        return mpz_fits_slong_p(tmp) || 
 | 
			
		||||
            (mpz_cmp(tmp, int64_min()) >= 0 && mpz_cmp(tmp, int64_max()) <= 0);
 | 
			
		||||
    }
 | 
			
		||||
    bool is_uint64() const {
 | 
			
		||||
        if (!is_int()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpq_get_num(tmp, m_data);
 | 
			
		||||
        return mpz_sgn(tmp) >= 0 && (mpz_fits_ulong_p(tmp) || mpz_cmp(tmp, uint64_max()) <= 0);
 | 
			
		||||
    }
 | 
			
		||||
    int64 get_int64() const;
 | 
			
		||||
    uint64 get_uint64() const;
 | 
			
		||||
    void neg() { mpq_neg(m_data, m_data); }
 | 
			
		||||
    big_rational & operator=(const big_rational & r) {
 | 
			
		||||
        mpq_set(m_data, r.m_data);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    bool operator==(const big_rational & r) const { return mpq_equal(m_data, r.m_data) != 0; }
 | 
			
		||||
    bool operator<(const big_rational & r) const { return mpq_cmp(m_data, r.m_data) < 0; }
 | 
			
		||||
    big_rational & operator+=(const big_rational & r) {
 | 
			
		||||
        mpq_add(m_data, m_data, r.m_data);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    big_rational & operator-=(const big_rational & r) {
 | 
			
		||||
        mpq_sub(m_data, m_data, r.m_data);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    big_rational & operator*=(const big_rational & r) {
 | 
			
		||||
        mpq_mul(m_data, m_data, r.m_data);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    big_rational & operator/=(const big_rational & r) {
 | 
			
		||||
        mpq_div(m_data, m_data, r.m_data);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    big_rational & operator%=(const big_rational & r) {
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpz_tdiv_r(tmp, mpq_numref(m_data), mpq_numref(r.m_data));
 | 
			
		||||
        mpq_set_z(m_data, tmp);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    friend void div(const big_rational & r1, const big_rational & r2, big_rational & result) {
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpz_tdiv_q(tmp, mpq_numref(r1.m_data), mpq_numref(r2.m_data));
 | 
			
		||||
        mpq_set_z(result.m_data, tmp);
 | 
			
		||||
    }
 | 
			
		||||
    void get_numerator(big_rational & result) {
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpq_get_num(tmp, m_data);
 | 
			
		||||
        mpq_set_z(result.m_data, tmp);
 | 
			
		||||
    }
 | 
			
		||||
    void get_denominator(big_rational & result) {
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpq_get_den(tmp, m_data);
 | 
			
		||||
        mpq_set_z(result.m_data, tmp);
 | 
			
		||||
    }
 | 
			
		||||
    void get_floor(big_rational & result) {
 | 
			
		||||
        mpz_t & tmp = get_tmp();
 | 
			
		||||
        mpz_fdiv_q(tmp, mpq_numref(m_data), mpq_denref(m_data));
 | 
			
		||||
        mpq_set_z(result.m_data, tmp);
 | 
			
		||||
    }
 | 
			
		||||
    std::string to_string() const;
 | 
			
		||||
#ifdef Z3DEBUG
 | 
			
		||||
    static void test() {
 | 
			
		||||
        init_limits();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif 
 | 
			
		||||
 | 
			
		||||
#endif /* _GMP_BIG_RATIONAL_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,424 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    lru_cache.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    expr -> expr LRU cache
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo (leonardo) 2011-04-12
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"lru_cache.h"
 | 
			
		||||
#include"ast_ll_pp.h"
 | 
			
		||||
 | 
			
		||||
#define MIN_MAX_SIZE     1024
 | 
			
		||||
#define INITIAL_CAPACITY 128
 | 
			
		||||
 | 
			
		||||
lru_cache::cell * lru_cache::allocate(unsigned capacity) {
 | 
			
		||||
    cell * mem = static_cast<cell*>(memory::allocate(sizeof(cell) * capacity));
 | 
			
		||||
    memset(mem, 0, sizeof(cell)*capacity);
 | 
			
		||||
    return mem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::deallocate(cell * table) {
 | 
			
		||||
    memory::deallocate(table);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
lru_cache::cell * lru_cache::copy_table(cell * old_head, cell * new_table, unsigned new_capacity) {
 | 
			
		||||
    SASSERT(old_head);
 | 
			
		||||
    cell * it = old_head;
 | 
			
		||||
    cell * new_head = 0;
 | 
			
		||||
    cell * prev = 0;
 | 
			
		||||
    do {
 | 
			
		||||
        expr * k       = it->m_key;
 | 
			
		||||
        unsigned h     = k->hash();
 | 
			
		||||
        unsigned mask  = new_capacity - 1;
 | 
			
		||||
        unsigned idx   = h & mask;
 | 
			
		||||
        
 | 
			
		||||
        cell * begin = new_table + idx;
 | 
			
		||||
        cell * end   = new_table + new_capacity;
 | 
			
		||||
        cell * curr  = begin;
 | 
			
		||||
 | 
			
		||||
        for (; curr != end; ++curr) {
 | 
			
		||||
            if (curr->m_key == 0) {
 | 
			
		||||
                curr->m_key   = k;
 | 
			
		||||
                curr->m_value = it->m_value;
 | 
			
		||||
                LCS_CODE(curr->m_hits = it->m_hits;);
 | 
			
		||||
                LCS_CODE(curr->m_birthday = it->m_birthday;);
 | 
			
		||||
                if (prev == 0) {
 | 
			
		||||
                    new_head = curr;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    prev->m_next = curr;
 | 
			
		||||
                    curr->m_prev = prev;
 | 
			
		||||
                }
 | 
			
		||||
                goto end;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for (curr = new_table; curr != begin; ++curr) {
 | 
			
		||||
            if (curr->m_key == 0) {
 | 
			
		||||
                curr->m_key   = k;
 | 
			
		||||
                curr->m_value = it->m_value;
 | 
			
		||||
                SASSERT(prev != 0);
 | 
			
		||||
                prev->m_next = curr;
 | 
			
		||||
                curr->m_prev = prev;
 | 
			
		||||
            }
 | 
			
		||||
            goto end;
 | 
			
		||||
        }
 | 
			
		||||
        UNREACHABLE();
 | 
			
		||||
    end:
 | 
			
		||||
        prev = curr;
 | 
			
		||||
        it = it->m_next;
 | 
			
		||||
    }
 | 
			
		||||
    while (it != old_head);
 | 
			
		||||
    prev->m_next     = new_head;
 | 
			
		||||
    new_head->m_prev = prev;
 | 
			
		||||
    return new_head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::expand_table() {
 | 
			
		||||
    SASSERT(m_head);
 | 
			
		||||
    unsigned new_capacity = m_capacity * 2;
 | 
			
		||||
    TRACE("lru_cache", tout << "expanding table new_capacity: " << new_capacity << "\n";);
 | 
			
		||||
    cell *   new_table    = allocate(new_capacity);
 | 
			
		||||
    m_head     = copy_table(m_head, new_table, new_capacity);
 | 
			
		||||
    deallocate(m_table);
 | 
			
		||||
    m_table    = new_table;
 | 
			
		||||
    m_capacity = new_capacity;
 | 
			
		||||
    m_num_deleted = 0;
 | 
			
		||||
    SASSERT(check_invariant());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::remove_deleted() {
 | 
			
		||||
    SASSERT(m_head);
 | 
			
		||||
    TRACE("lru_cache", tout << "removing deleted entries\n";);
 | 
			
		||||
    cell *   new_table    = allocate(m_capacity);
 | 
			
		||||
    m_head     = copy_table(m_head, new_table, m_capacity);
 | 
			
		||||
    deallocate(m_table);
 | 
			
		||||
    m_table    = new_table;
 | 
			
		||||
    m_num_deleted = 0;
 | 
			
		||||
    SASSERT(check_invariant());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::init() {
 | 
			
		||||
    if (m_max_size < MIN_MAX_SIZE)
 | 
			
		||||
        m_max_size = MIN_MAX_SIZE;
 | 
			
		||||
    m_size = 0;
 | 
			
		||||
    m_capacity = INITIAL_CAPACITY;
 | 
			
		||||
    m_table = allocate(m_capacity);
 | 
			
		||||
    m_head  = 0;
 | 
			
		||||
    m_num_deleted = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
lru_cache::lru_cache(ast_manager & m):
 | 
			
		||||
    m_manager(m),
 | 
			
		||||
    m_max_size(m.get_num_asts() * 100) {
 | 
			
		||||
    init();
 | 
			
		||||
    TRACE("lru_cache", tout << "new lru cache, max-size: " << m_max_size << "\n";);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
lru_cache::lru_cache(ast_manager & m, unsigned max_size):
 | 
			
		||||
    m_manager(m),
 | 
			
		||||
    m_max_size(max_size) {
 | 
			
		||||
    init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::dec_refs() {
 | 
			
		||||
    if (m_head) {
 | 
			
		||||
        cell * curr = m_head;
 | 
			
		||||
#ifdef Z3DEBUG
 | 
			
		||||
        unsigned sz = 0;
 | 
			
		||||
#endif
 | 
			
		||||
        do {
 | 
			
		||||
            m_manager.dec_ref(curr->m_key);
 | 
			
		||||
            m_manager.dec_ref(curr->m_value);
 | 
			
		||||
            curr = curr->m_next;
 | 
			
		||||
            DEBUG_CODE(sz++;);
 | 
			
		||||
        }
 | 
			
		||||
        while (curr != m_head);
 | 
			
		||||
        SASSERT(sz == m_size);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
lru_cache::~lru_cache() {
 | 
			
		||||
    TRACE("lru_cache", tout << "destructor invoked size: " << m_size << ", m_head: " << m_head << "\n";);
 | 
			
		||||
    LCS_CODE({
 | 
			
		||||
        if (m_head) {
 | 
			
		||||
            unsigned used = 0;
 | 
			
		||||
            cell * curr = m_head;
 | 
			
		||||
            do {
 | 
			
		||||
                if (curr->m_hits > 0)
 | 
			
		||||
                    used++;
 | 
			
		||||
                curr = curr->m_next;
 | 
			
		||||
            }
 | 
			
		||||
            while (curr != m_head);
 | 
			
		||||
            verbose_stream() << "[lru_cache] num-used: " << used << " size: " << m_size << "\n";
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    SASSERT(check_invariant());
 | 
			
		||||
    dec_refs();
 | 
			
		||||
    deallocate(m_table);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::del_least_used() {
 | 
			
		||||
    SASSERT(m_head);
 | 
			
		||||
    SASSERT(m_size >= 2);
 | 
			
		||||
    cell * c = m_head->m_prev;
 | 
			
		||||
    TRACE("lru_cache", tout << "del least used: " << mk_bounded_pp(c->m_key, m_manager, 3) << "\n";);
 | 
			
		||||
    LCS_CODE({
 | 
			
		||||
        static unsigned non_zero = 0;
 | 
			
		||||
        static unsigned long long total_hits;
 | 
			
		||||
        static unsigned counter = 0;
 | 
			
		||||
        if (c->m_hits > 0) {
 | 
			
		||||
            counter++;
 | 
			
		||||
            total_hits += c->m_hits;
 | 
			
		||||
            non_zero++;
 | 
			
		||||
            if (non_zero % 1000 == 0)
 | 
			
		||||
                verbose_stream() << "[lru_cache] cell with non-zero hits was deleted: " << non_zero << " avg: " << ((double)total_hits/(double) counter) << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    SASSERT(c->m_prev != c);
 | 
			
		||||
    SASSERT(c->m_next != c);
 | 
			
		||||
    m_manager.dec_ref(c->m_key);
 | 
			
		||||
    m_manager.dec_ref(c->m_value);
 | 
			
		||||
    c->m_prev->m_next = c->m_next;
 | 
			
		||||
    c->m_next->m_prev = c->m_prev;
 | 
			
		||||
    SASSERT(m_head->m_prev == c->m_prev);
 | 
			
		||||
    c->m_key  = reinterpret_cast<expr*>(1);
 | 
			
		||||
    c->m_prev = 0;
 | 
			
		||||
    c->m_next = 0;
 | 
			
		||||
    m_size--;
 | 
			
		||||
    m_num_deleted++;
 | 
			
		||||
    CASSERT("lru_cache", check_invariant());
 | 
			
		||||
    if (m_num_deleted * 3 > m_capacity)
 | 
			
		||||
        remove_deleted();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::add_front(cell * c) {
 | 
			
		||||
    SASSERT(c->m_next == 0);
 | 
			
		||||
    SASSERT(c->m_prev == 0);
 | 
			
		||||
    if (m_head == 0) {
 | 
			
		||||
        c->m_next = c;
 | 
			
		||||
        c->m_prev = c;
 | 
			
		||||
        m_head    = c;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        c->m_prev = m_head->m_prev;
 | 
			
		||||
        c->m_next = m_head;
 | 
			
		||||
        m_head->m_prev->m_next = c;
 | 
			
		||||
        m_head->m_prev = c;
 | 
			
		||||
        m_head = c;
 | 
			
		||||
    }
 | 
			
		||||
    CASSERT("lru_cache", check_invariant());
 | 
			
		||||
    SASSERT(m_head == c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::move_front(cell * c) {
 | 
			
		||||
    SASSERT(m_head);
 | 
			
		||||
    SASSERT(c->m_next);
 | 
			
		||||
    SASSERT(c->m_prev);
 | 
			
		||||
    if (m_head != c) {
 | 
			
		||||
        c->m_prev->m_next = c->m_next;
 | 
			
		||||
        c->m_next->m_prev = c->m_prev;
 | 
			
		||||
        
 | 
			
		||||
        c->m_prev = m_head->m_prev;
 | 
			
		||||
        c->m_next = m_head;
 | 
			
		||||
        
 | 
			
		||||
        m_head->m_prev->m_next = c;
 | 
			
		||||
        m_head->m_prev         = c;
 | 
			
		||||
        
 | 
			
		||||
        m_head = c;
 | 
			
		||||
    }
 | 
			
		||||
    CASSERT("lru_cache", check_invariant());
 | 
			
		||||
    SASSERT(m_head == c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::insert(expr * k, expr * v) {
 | 
			
		||||
    LCS_CODE(m_time++;);
 | 
			
		||||
    if (m_size == m_max_size)
 | 
			
		||||
        del_least_used();
 | 
			
		||||
    else if (m_size * 2 > m_capacity)
 | 
			
		||||
        expand_table();
 | 
			
		||||
    SASSERT(m_size < m_max_size);
 | 
			
		||||
    unsigned h     = k->hash();
 | 
			
		||||
    unsigned mask  = m_capacity - 1;
 | 
			
		||||
    unsigned idx   = h & mask;
 | 
			
		||||
 | 
			
		||||
    cell * begin = m_table + idx;
 | 
			
		||||
    cell * end   = m_table + m_capacity;
 | 
			
		||||
    cell * curr  = begin;
 | 
			
		||||
    cell * del_cell = 0;
 | 
			
		||||
 | 
			
		||||
#define INSERT_LOOP()                                           \
 | 
			
		||||
        if (curr->m_key == 0) {                                 \
 | 
			
		||||
            cell * new_cell;                                    \
 | 
			
		||||
            if (del_cell) {                                     \
 | 
			
		||||
                new_cell = del_cell;                            \
 | 
			
		||||
                m_num_deleted--;                                \
 | 
			
		||||
            }                                                   \
 | 
			
		||||
            else {                                              \
 | 
			
		||||
                new_cell = curr;                                \
 | 
			
		||||
            }                                                   \
 | 
			
		||||
            m_manager.inc_ref(k);                               \
 | 
			
		||||
            m_manager.inc_ref(v);                               \
 | 
			
		||||
            new_cell->m_key   = k;                              \
 | 
			
		||||
            new_cell->m_value = v;                              \
 | 
			
		||||
            LCS_CODE(new_cell->m_hits = 0;);                    \
 | 
			
		||||
            LCS_CODE(new_cell->m_birthday = m_time;);           \
 | 
			
		||||
            m_size++;                                           \
 | 
			
		||||
            add_front(new_cell);                                \
 | 
			
		||||
            return;                                             \
 | 
			
		||||
        }                                                       \
 | 
			
		||||
        if (curr->m_key == reinterpret_cast<expr*>(1)) {        \
 | 
			
		||||
            del_cell = curr;                                    \
 | 
			
		||||
            continue;                                           \
 | 
			
		||||
        }                                                       \
 | 
			
		||||
        if (curr->m_key == k) {                                 \
 | 
			
		||||
            m_manager.inc_ref(v);                               \
 | 
			
		||||
            m_manager.dec_ref(curr->m_value);                   \
 | 
			
		||||
            curr->m_value = v;                                  \
 | 
			
		||||
            LCS_CODE(curr->m_hits = 0;);                        \
 | 
			
		||||
            LCS_CODE(curr->m_birthday = m_time;);               \
 | 
			
		||||
            move_front(curr);                                   \
 | 
			
		||||
            return;                                             \
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    for (; curr != end; ++curr) {
 | 
			
		||||
        INSERT_LOOP();
 | 
			
		||||
    }
 | 
			
		||||
    for (curr = m_table; curr != begin; ++curr) {
 | 
			
		||||
        INSERT_LOOP();
 | 
			
		||||
    } 
 | 
			
		||||
    UNREACHABLE();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
expr * lru_cache::find(expr * k) {
 | 
			
		||||
    unsigned h     = k->hash();
 | 
			
		||||
    unsigned mask  = m_capacity - 1;
 | 
			
		||||
    unsigned idx   = h & mask;
 | 
			
		||||
 | 
			
		||||
#ifdef LRU_CACHE_STATISTICS
 | 
			
		||||
    static unsigned long long total_age = 0;
 | 
			
		||||
    static unsigned long long max_time = 0;
 | 
			
		||||
    static unsigned counter = 0;
 | 
			
		||||
#define COLLECT()                                                                                                                                       \
 | 
			
		||||
    if (curr->m_hits == 0) {                                                                                                                            \
 | 
			
		||||
        counter ++;                                                                                                                                     \
 | 
			
		||||
        unsigned age = m_time - curr->m_birthday;                                                                                                       \
 | 
			
		||||
        if (age > max_time)                                                                                                                             \
 | 
			
		||||
            max_time = age;                                                                                                                             \
 | 
			
		||||
        total_age += age;                                                                                                                               \
 | 
			
		||||
        if (counter % 1000 == 0)                                                                                                                        \
 | 
			
		||||
            verbose_stream() << "[lru_cache] avg time for first hit: " << ((double) total_age / (double) counter) << " max time: " << max_time << "\n";        \
 | 
			
		||||
    }
 | 
			
		||||
#endif    
 | 
			
		||||
 | 
			
		||||
    cell * begin = m_table + idx;
 | 
			
		||||
    cell * end   = m_table + m_capacity;
 | 
			
		||||
    cell * curr  = begin;
 | 
			
		||||
    for (; curr != end; ++curr) {
 | 
			
		||||
        if (curr->m_key == k) {
 | 
			
		||||
            // LCS_CODE(COLLECT());
 | 
			
		||||
            LCS_CODE(if (curr->m_hits == 0 && m_time - curr->m_birthday >= 5000) return 0;)
 | 
			
		||||
            LCS_CODE(curr->m_hits++;);
 | 
			
		||||
            move_front(curr);
 | 
			
		||||
            return curr->m_value;
 | 
			
		||||
        }
 | 
			
		||||
        if (curr->m_key == 0) 
 | 
			
		||||
            return 0;
 | 
			
		||||
    }
 | 
			
		||||
    for (curr = m_table; curr != begin; ++curr) {
 | 
			
		||||
        if (curr->m_key == k) {
 | 
			
		||||
            // LCS_CODE(COLLECT());
 | 
			
		||||
            LCS_CODE(curr->m_hits++;);
 | 
			
		||||
            LCS_CODE(if (curr->m_hits == 0 && m_time - curr->m_birthday >= 5000) return 0;);
 | 
			
		||||
            move_front(curr);
 | 
			
		||||
            return curr->m_value;
 | 
			
		||||
        }
 | 
			
		||||
        if (curr->m_key == 0) 
 | 
			
		||||
            return 0;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lru_cache::reset() {
 | 
			
		||||
    TRACE("lru_cache", tout << "reset... m_size: " << m_size << "\n";);
 | 
			
		||||
    LCS_CODE(m_time = 0;);
 | 
			
		||||
    if (m_head) {
 | 
			
		||||
        cell * curr = m_head;
 | 
			
		||||
#ifdef Z3DEBUG
 | 
			
		||||
        unsigned sz = 0;
 | 
			
		||||
#endif
 | 
			
		||||
        do {
 | 
			
		||||
            m_manager.dec_ref(curr->m_key);
 | 
			
		||||
            m_manager.dec_ref(curr->m_value);
 | 
			
		||||
            cell * next = curr->m_next;
 | 
			
		||||
            curr->m_key   = 0;
 | 
			
		||||
            curr->m_value = 0;
 | 
			
		||||
            curr->m_next  = 0;
 | 
			
		||||
            curr->m_prev  = 0;
 | 
			
		||||
            LCS_CODE(curr->m_hits = 0;);
 | 
			
		||||
            LCS_CODE(curr->m_birthday = 0;);
 | 
			
		||||
            curr = next;
 | 
			
		||||
            DEBUG_CODE(sz++;);
 | 
			
		||||
        }
 | 
			
		||||
        while (curr != m_head);
 | 
			
		||||
        SASSERT(sz == m_size);
 | 
			
		||||
        m_head = 0;
 | 
			
		||||
        m_size = 0;
 | 
			
		||||
        SASSERT(check_invariant());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void lru_cache::cleanup() {
 | 
			
		||||
    dec_refs();
 | 
			
		||||
    deallocate(m_table);
 | 
			
		||||
    m_capacity    = INITIAL_CAPACITY;
 | 
			
		||||
    m_table       = allocate(m_capacity); 
 | 
			
		||||
    m_head        = 0;
 | 
			
		||||
    m_size        = 0;
 | 
			
		||||
    m_num_deleted = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool lru_cache::check_invariant() const {
 | 
			
		||||
    SASSERT(m_size <= m_max_size);
 | 
			
		||||
    cell * begin         = m_table;
 | 
			
		||||
    cell * end           = m_table + m_capacity;
 | 
			
		||||
    unsigned sz          = 0;
 | 
			
		||||
    if (m_head) {
 | 
			
		||||
        cell * curr  = m_head;
 | 
			
		||||
        do {
 | 
			
		||||
            sz++;
 | 
			
		||||
            SASSERT(curr->m_key != 0 && curr->m_key != reinterpret_cast<expr*>(1));
 | 
			
		||||
            SASSERT(curr->m_next->m_prev == curr);
 | 
			
		||||
            SASSERT(curr->m_prev->m_next == curr);
 | 
			
		||||
            SASSERT(curr < end);
 | 
			
		||||
            SASSERT(curr >= begin);
 | 
			
		||||
            curr = curr->m_next;
 | 
			
		||||
        }
 | 
			
		||||
        while (curr != m_head);
 | 
			
		||||
    }
 | 
			
		||||
    SASSERT(m_size == sz);
 | 
			
		||||
    sz = 0;
 | 
			
		||||
    unsigned num_deleted = 0;
 | 
			
		||||
    for (cell * it = begin; it != end; it++) {
 | 
			
		||||
        if (it->m_key == reinterpret_cast<expr*>(1)) {
 | 
			
		||||
            num_deleted++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (it->m_key != 0) {
 | 
			
		||||
            sz++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    SASSERT(m_size == sz);
 | 
			
		||||
    SASSERT(m_num_deleted == num_deleted);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,80 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    lru_cache.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    expr -> expr LRU cache
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo (leonardo) 2011-04-12
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _LRU_CACHE_H_
 | 
			
		||||
#define _LRU_CACHE_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
 | 
			
		||||
// #define LRU_CACHE_STATISTICS
 | 
			
		||||
 | 
			
		||||
#ifdef LRU_CACHE_STATISTICS
 | 
			
		||||
#define LCS_CODE(CODE) { CODE }
 | 
			
		||||
#else
 | 
			
		||||
#define LCS_CODE(CODE)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class lru_cache {
 | 
			
		||||
    struct cell {
 | 
			
		||||
        expr *  m_key;
 | 
			
		||||
        expr *  m_value;
 | 
			
		||||
        cell *  m_prev;
 | 
			
		||||
        cell *  m_next;
 | 
			
		||||
#ifdef LRU_CACHE_STATISTICS
 | 
			
		||||
        unsigned m_hits;
 | 
			
		||||
        unsigned m_birthday;
 | 
			
		||||
#endif
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ast_manager & m_manager;
 | 
			
		||||
    cell *        m_table;
 | 
			
		||||
    cell *        m_head;
 | 
			
		||||
    unsigned      m_size;
 | 
			
		||||
    unsigned      m_max_size;
 | 
			
		||||
    unsigned      m_capacity;
 | 
			
		||||
    unsigned      m_num_deleted;
 | 
			
		||||
#ifdef LRU_CACHE_STATISTICS
 | 
			
		||||
    unsigned      m_time;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    static cell * allocate(unsigned capacity);
 | 
			
		||||
    static void deallocate(cell * table);
 | 
			
		||||
    static cell * copy_table(cell * old_head, cell * new_table, unsigned new_capacity);
 | 
			
		||||
 | 
			
		||||
    void del_least_used();
 | 
			
		||||
    void add_front(cell * c);
 | 
			
		||||
    void move_front(cell * c);
 | 
			
		||||
    void expand_table();
 | 
			
		||||
    void remove_deleted();
 | 
			
		||||
    void init();
 | 
			
		||||
    void dec_refs();
 | 
			
		||||
public:
 | 
			
		||||
    lru_cache(ast_manager & m);
 | 
			
		||||
    lru_cache(ast_manager & m, unsigned max_size);
 | 
			
		||||
    ~lru_cache();
 | 
			
		||||
    void insert(expr * k, expr * v);
 | 
			
		||||
    expr * find(expr * k);
 | 
			
		||||
    void reset();
 | 
			
		||||
    void cleanup();
 | 
			
		||||
    unsigned size() const { return m_size; }
 | 
			
		||||
    unsigned capacity() const { return m_capacity; }
 | 
			
		||||
    bool empty() const { return m_size == 0; }
 | 
			
		||||
    bool check_invariant() const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,32 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2007 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    parameters.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Settings and parameters supplied to pre-processing and solver
 | 
			
		||||
    modules.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-10-18.
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2007-02-15
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
    2007-02-15, nbjorner.
 | 
			
		||||
    Hoisted out from simplify_parser.h and core_theory_types.h
 | 
			
		||||
    in order to share functionality with SMTLIB and other
 | 
			
		||||
    front-ends without bringing in the simplifier and core_theory.
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _PARAMETERS_H_
 | 
			
		||||
#define _PARAMETERS_H_
 | 
			
		||||
 | 
			
		||||
#include"sat_params.h"
 | 
			
		||||
#include"core_theory_params.h"
 | 
			
		||||
#include"front_end_params.h"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,118 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    simple_sat.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-10-10.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include<fstream>
 | 
			
		||||
#include<time.h>
 | 
			
		||||
#include"front_end_params.h"
 | 
			
		||||
#include"sat_def.h"
 | 
			
		||||
#include"dimacs_parser.h"
 | 
			
		||||
#include"timeit.h"
 | 
			
		||||
#include"mem_stat.h"
 | 
			
		||||
 | 
			
		||||
class simple_sat_solver : public no_extension {
 | 
			
		||||
    const front_end_params &         m_params;
 | 
			
		||||
    sat_solver<simple_sat_solver> *  m_sat;
 | 
			
		||||
    unsigned                         m_num_vars;
 | 
			
		||||
    svector<lbool>                   m_model;
 | 
			
		||||
public:
 | 
			
		||||
    simple_sat_solver(const front_end_params & p):
 | 
			
		||||
        m_params(p),
 | 
			
		||||
        m_sat(new sat_solver<simple_sat_solver>(*this, p)),
 | 
			
		||||
        m_num_vars(0) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~simple_sat_solver() {
 | 
			
		||||
        delete m_sat;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static bool enable_ref_counters() {
 | 
			
		||||
        return false; 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void mk_var() {
 | 
			
		||||
	m_sat->mk_var();
 | 
			
		||||
	m_num_vars++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void mk_clause(const literal_vector & lits) {
 | 
			
		||||
	m_sat->mk_main_clause(lits);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned get_num_vars() const {
 | 
			
		||||
	return m_num_vars;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lbool check() {
 | 
			
		||||
	return m_sat->check();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void mk_model() {
 | 
			
		||||
        if (m_params.m_build_model) {
 | 
			
		||||
            m_sat->save_assignment(m_model);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void display_model(std::ostream & out) const {
 | 
			
		||||
        int sz = m_model.size();
 | 
			
		||||
        for (int i = 1; i < sz; i++) {
 | 
			
		||||
            if (m_model[i] == l_true) {
 | 
			
		||||
                out << i << " ";
 | 
			
		||||
            }
 | 
			
		||||
            else if (m_model[i] == l_false) {
 | 
			
		||||
                out << -i << " ";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        out << "\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void display_statistics(std::ostream & out) const {
 | 
			
		||||
	m_sat->display_statistics(out);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern bool g_display_statistics;
 | 
			
		||||
extern front_end_params g_front_end_params;
 | 
			
		||||
 | 
			
		||||
void solve_cnf(const char * file) {
 | 
			
		||||
    clock_t start_time = clock();
 | 
			
		||||
    simple_sat_solver solver(g_front_end_params);
 | 
			
		||||
    std::ifstream in(file);
 | 
			
		||||
    parse_dimacs(in, solver);
 | 
			
		||||
    lbool r = solver.check();
 | 
			
		||||
    clock_t end_time   = clock();
 | 
			
		||||
    switch(r) {
 | 
			
		||||
    case l_false:
 | 
			
		||||
        std::cout << "unsat\n";
 | 
			
		||||
	break;
 | 
			
		||||
    case l_undef:
 | 
			
		||||
	std::cout << "unknown\n";
 | 
			
		||||
	break;
 | 
			
		||||
    case l_true:
 | 
			
		||||
	std::cout << "sat\n";
 | 
			
		||||
        if (g_front_end_params.m_build_model) {
 | 
			
		||||
            solver.display_model(std::cout);
 | 
			
		||||
        }
 | 
			
		||||
	break;
 | 
			
		||||
    }
 | 
			
		||||
    if (g_display_statistics) {
 | 
			
		||||
	solver.display_statistics(std::cerr);
 | 
			
		||||
        memory::display_max_usage(std::cerr);
 | 
			
		||||
        std::cerr << "time:               " << ((static_cast<double>(end_time) - static_cast<double>(start_time)) / CLOCKS_PER_SEC) << "\n";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,26 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    simple_sat.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Simple SAT solver using the Z3 SAT template.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-10-10.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#ifndef _SIMPLE_SAT_H_
 | 
			
		||||
#define _SIMPLE_SAT_H_
 | 
			
		||||
 | 
			
		||||
void solve_cnf(const char * file);
 | 
			
		||||
 | 
			
		||||
#endif /* _SIMPLE_SAT_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,46 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    smt_classifier.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-06-24.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SMT_CLASSIFIER_H_
 | 
			
		||||
#define _SMT_CLASSIFIER_H_
 | 
			
		||||
 | 
			
		||||
#include"static_features.h"
 | 
			
		||||
 | 
			
		||||
namespace smt {
 | 
			
		||||
 | 
			
		||||
    class classifier {
 | 
			
		||||
        context     &     m_context;
 | 
			
		||||
        ast_manager &     m_manager;
 | 
			
		||||
        static_features   m_static_features;
 | 
			
		||||
        symbol            m_logic;
 | 
			
		||||
    public:
 | 
			
		||||
        classifier(context & c);
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Give a hint by specifying the logic used to describe a problem.
 | 
			
		||||
        */
 | 
			
		||||
        void set_logic(symbol & s);
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Setup the logical context for solving the following formulas.
 | 
			
		||||
        */
 | 
			
		||||
        void setup(unsigned num_formulas, expr * const * fs);
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SMT_CLASSIFIER_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,187 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2012 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    smt_euf.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Equality and uninterpreted functions
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2012-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"smt_euf.h"
 | 
			
		||||
#include"smt_context.h"
 | 
			
		||||
#include"ast_smt2_pp.h"
 | 
			
		||||
 | 
			
		||||
namespace smt {
 | 
			
		||||
 | 
			
		||||
    struct euf_manager::imp {
 | 
			
		||||
        context &                   m_context;
 | 
			
		||||
        ast_manager &               m_manager;
 | 
			
		||||
        region &                    m_region;
 | 
			
		||||
        expr_ref_vector             m_e_internalized_stack; // stack of the expressions already internalized as enodes. 
 | 
			
		||||
        ptr_vector<enode>           m_app2enode;    // app -> enode
 | 
			
		||||
        ptr_vector<enode>           m_enodes;
 | 
			
		||||
        vector<enode_vector>        m_decl2enodes;  // decl -> enode (for decls with arity > 0)
 | 
			
		||||
        cg_table                    m_cg_table; 
 | 
			
		||||
        dyn_ack_manager             m_dyn_ack_manager;
 | 
			
		||||
        struct new_eq {
 | 
			
		||||
            enode *                 m_lhs;
 | 
			
		||||
            enode *                 m_rhs;
 | 
			
		||||
            eq_justification        m_justification;
 | 
			
		||||
            new_eq() {}
 | 
			
		||||
            new_eq(enode * lhs, enode * rhs, eq_justification const & js):
 | 
			
		||||
                m_lhs(lhs), m_rhs(rhs), m_justification(js) {}
 | 
			
		||||
        };
 | 
			
		||||
        svector<new_eq>             m_eq_propagation_queue;
 | 
			
		||||
        struct new_th_eq {
 | 
			
		||||
            theory_id  m_th_id;
 | 
			
		||||
            theory_var m_lhs;
 | 
			
		||||
            theory_var m_rhs;
 | 
			
		||||
            new_th_eq():m_th_id(null_theory_id), m_lhs(null_theory_var), m_rhs(null_theory_var) {}
 | 
			
		||||
            new_th_eq(theory_id id, theory_var l, theory_var r):m_th_id(id), m_lhs(l), m_rhs(r) {}
 | 
			
		||||
        };
 | 
			
		||||
        svector<new_th_eq>          m_th_eq_propagation_queue;
 | 
			
		||||
        svector<new_th_eq>          m_th_diseq_propagation_queue;
 | 
			
		||||
        enode *                     m_is_diseq_tmp; // auxiliary enode used to find congruent equality atoms.
 | 
			
		||||
        tmp_enode                   m_tmp_enode;
 | 
			
		||||
        ptr_vector<almost_cg_table> m_almost_cg_tables; // temporary field for is_ext_diseq
 | 
			
		||||
        obj_map<expr, unsigned>     m_cached_generation;
 | 
			
		||||
        obj_hashtable<expr>         m_cache_generation_visited;
 | 
			
		||||
        friend class mk_enode_trail;
 | 
			
		||||
        class mk_enode_trail : public trail<context> {
 | 
			
		||||
            imp & m_owner;
 | 
			
		||||
        public:
 | 
			
		||||
            mk_enode_trail(imp & o):m_owner(o) {}
 | 
			
		||||
            virtual void undo(context & ctx) { m_owner.undo_mk_enode(); }
 | 
			
		||||
        };
 | 
			
		||||
        mk_enode_trail              m_mk_enode_trail;
 | 
			
		||||
        volatile bool               m_cancel_flag;
 | 
			
		||||
 | 
			
		||||
        // Statistics
 | 
			
		||||
        unsigned                    m_num_mk_enode;
 | 
			
		||||
        unsigned                    m_num_del_enode;
 | 
			
		||||
 | 
			
		||||
        void push_eq(enode * lhs, enode * rhs, eq_justification const & js) {
 | 
			
		||||
            SASSERT(lhs != rhs);
 | 
			
		||||
            m_eq_propagation_queue.push_back(new_eq(lhs, rhs, js));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void push_new_congruence(enode * n1, enode * n2, bool used_commutativity) {
 | 
			
		||||
            SASSERT(n1->m_cg == n2);
 | 
			
		||||
            push_eq(n1, n2, eq_justification::mk_cg(used_commutativity));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool e_internalized(expr const * n) const {
 | 
			
		||||
            return m_app2enode.get(n->get_id(), 0) != 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void set_app2enode(expr const * n, enode * e) {
 | 
			
		||||
            m_app2enode.setx(n->get_id(), e, 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        enode * mk_enode(app * n, bool suppress_args, bool merge_tf, bool cgc_enabled, unsigned generation) {
 | 
			
		||||
            TRACE("mk_enode_detail", 
 | 
			
		||||
                  tout << mk_ismt2_pp(n, m_manager) << "\n";
 | 
			
		||||
                  tout <<"suppress_args: " << suppress_args << ", merge_tf: " << merge_tf << ", cgc_enabled: " << cgc_enabled << "\n";);
 | 
			
		||||
            SASSERT(!e_internalized(n));
 | 
			
		||||
            unsigned scope_lvl   = m_context.get_scope_level();
 | 
			
		||||
            unsigned id          = n->get_id();
 | 
			
		||||
            unsigned _generation = 0;
 | 
			
		||||
            if (!m_cached_generation.empty() && m_cached_generation.find(n, _generation)) {
 | 
			
		||||
                generation = _generation;
 | 
			
		||||
            }
 | 
			
		||||
            enode * e            = enode::mk(m_manager, m_region, m_app2enode, n, generation, suppress_args, merge_tf, scope_lvl, cgc_enabled, true);
 | 
			
		||||
            TRACE("mk_enode_detail", tout << "e.get_num_args() = " << e->get_num_args() << "\n";);
 | 
			
		||||
            if (n->get_num_args() == 0 && m_manager.is_value(n))
 | 
			
		||||
                e->mark_as_interpreted();
 | 
			
		||||
            TRACE("mk_var_bug", tout << "mk_enode: " << id << "\n";);
 | 
			
		||||
            TRACE("generation", tout << "mk_enode: " << id << " " << generation << "\n";);
 | 
			
		||||
            set_app2enode(n, e);
 | 
			
		||||
            m_e_internalized_stack.push_back(n);
 | 
			
		||||
            m_context.push_trail_ptr(&m_mk_enode_trail);
 | 
			
		||||
            m_enodes.push_back(e);
 | 
			
		||||
            if (e->get_num_args() > 0) {
 | 
			
		||||
                if (e->is_true_eq()) {
 | 
			
		||||
                    /* 
 | 
			
		||||
                        bool_var v = enode2bool_var(e);
 | 
			
		||||
                        assign(literal(v), mk_justification(eq_propagation_justification(e->get_arg(0), e->get_arg(1))));
 | 
			
		||||
                        e->m_cg    = e;
 | 
			
		||||
                    */
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    if (cgc_enabled) {
 | 
			
		||||
                        enode_bool_pair pair = m_cg_table.insert(e);
 | 
			
		||||
                        enode * e_prime      = pair.first;
 | 
			
		||||
                        if (e != e_prime) {
 | 
			
		||||
                            e->m_cg = e_prime;
 | 
			
		||||
                            bool used_commutativity = pair.second;
 | 
			
		||||
                            push_new_congruence(e, e_prime, used_commutativity);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            e->m_cg = e;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        e->m_cg = e;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (!e->is_eq()) {
 | 
			
		||||
                    unsigned decl_id = n->get_decl()->get_decl_id();
 | 
			
		||||
                    if (decl_id >= m_decl2enodes.size())
 | 
			
		||||
                        m_decl2enodes.resize(decl_id+1);
 | 
			
		||||
                    m_decl2enodes[decl_id].push_back(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            SASSERT(e_internalized(n));
 | 
			
		||||
            m_num_mk_enode++;
 | 
			
		||||
            
 | 
			
		||||
            // #ifndef SMTCOMP
 | 
			
		||||
            // if (m_params.m_trace_stream != NULL)
 | 
			
		||||
            //    *m_params.m_trace_stream << "[attach-enode] #" << n->get_id() << " " << m_generation << "\n";        
 | 
			
		||||
            // #endif
 | 
			
		||||
 | 
			
		||||
            return e;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void undo_mk_enode() {
 | 
			
		||||
            SASSERT(!m_e_internalized_stack.empty());
 | 
			
		||||
            m_num_del_enode++;
 | 
			
		||||
            expr * n              = m_e_internalized_stack.back();
 | 
			
		||||
            TRACE("undo_mk_enode", tout << "undo_enode: #" << n->get_id() << "\n" << mk_ismt2_pp(n, m_manager) << "\n";);
 | 
			
		||||
            TRACE("mk_var_bug", tout << "undo_mk_enode: " << n->get_id() << "\n";);
 | 
			
		||||
            unsigned n_id         = n->get_id();
 | 
			
		||||
            SASSERT(is_app(n));
 | 
			
		||||
            enode * e             = m_app2enode[n_id];
 | 
			
		||||
            m_app2enode[n_id]     = 0;
 | 
			
		||||
            if (e->is_cgr() && !e->is_true_eq() && e->is_cgc_enabled()) {
 | 
			
		||||
                SASSERT(m_cg_table.contains_ptr(e));
 | 
			
		||||
                m_cg_table.erase(e);
 | 
			
		||||
            }
 | 
			
		||||
            if (e->get_num_args() > 0 && !e->is_eq()) {
 | 
			
		||||
                unsigned decl_id = to_app(n)->get_decl()->get_decl_id();
 | 
			
		||||
                SASSERT(decl_id < m_decl2enodes.size());
 | 
			
		||||
                SASSERT(m_decl2enodes[decl_id].back() == e);
 | 
			
		||||
                m_decl2enodes[decl_id].pop_back();
 | 
			
		||||
            }
 | 
			
		||||
            e->del_eh(m_manager);
 | 
			
		||||
            SASSERT(m_e_internalized_stack.size() == m_enodes.size());
 | 
			
		||||
            m_enodes.pop_back();
 | 
			
		||||
            m_e_internalized_stack.pop_back();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    euf_manager::euf_manager(context & ctx) {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    euf_manager::~euf_manager() {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,55 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2012 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    smt_euf.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Equality and uninterpreted functions
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2012-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SMT_EUF_H_
 | 
			
		||||
#define _SMT_EUF_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"smt_enode.h"
 | 
			
		||||
#include"smt_eq_justification.h"
 | 
			
		||||
 | 
			
		||||
namespace smt {
 | 
			
		||||
    class context;
 | 
			
		||||
 | 
			
		||||
    class euf_manager {
 | 
			
		||||
        struct imp;
 | 
			
		||||
        imp * m_imp;
 | 
			
		||||
    public:
 | 
			
		||||
        euf_manager(context & ctx);
 | 
			
		||||
        ~euf_manager();
 | 
			
		||||
 | 
			
		||||
        enode * mk_enode(app * n, bool suppress_args, bool merge_tf, bool cgc_enabled);
 | 
			
		||||
        
 | 
			
		||||
        void add_eq(enode * n1, enode * n2, eq_justification js);
 | 
			
		||||
        bool assume_eq(enode * lhs, enode * rhs);
 | 
			
		||||
        void reset();
 | 
			
		||||
        
 | 
			
		||||
        static bool is_eq(enode const * n1, enode const * n2) { return n1->get_root() == n2->get_root(); }
 | 
			
		||||
        bool is_diseq(enode * n1, enode * n2) const;
 | 
			
		||||
        bool is_ext_diseq(enode * n1, enode * n2, unsigned depth);
 | 
			
		||||
        enode * get_enode_eq_to(func_decl * f, unsigned num_args, enode * const * args);
 | 
			
		||||
        bool is_shared(enode * n) const;
 | 
			
		||||
 | 
			
		||||
        unsigned get_num_enodes_of(func_decl const * decl) const;
 | 
			
		||||
        enode_vector::const_iterator begin_enodes_of(func_decl const * decl) const;
 | 
			
		||||
        enode_vector::const_iterator end_enodes_of(func_decl const * decl) const;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,131 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    smt_trail.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-19.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SMT_TRAIL_H_
 | 
			
		||||
#define _SMT_TRAIL_H_
 | 
			
		||||
 | 
			
		||||
namespace smt {
 | 
			
		||||
 | 
			
		||||
    class context;
 | 
			
		||||
 | 
			
		||||
    class trail {
 | 
			
		||||
    public:
 | 
			
		||||
        virtual ~trail() {
 | 
			
		||||
        }
 | 
			
		||||
        virtual void undo(context & ctx) = 0;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    class value_trail : public trail {
 | 
			
		||||
        T & m_value;
 | 
			
		||||
        T   m_old_value;
 | 
			
		||||
        
 | 
			
		||||
    public:
 | 
			
		||||
        value_trail(T & value):
 | 
			
		||||
            m_value(value),
 | 
			
		||||
            m_old_value(value) {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual ~value_trail() {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual void undo(context & ctx) {
 | 
			
		||||
            m_value = m_old_value;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    class set_ptr_trail : public trail {
 | 
			
		||||
        T * & m_ptr;
 | 
			
		||||
    public:
 | 
			
		||||
        set_ptr_trail(T * & ptr):
 | 
			
		||||
            m_ptr(ptr) {
 | 
			
		||||
            SASSERT(m_ptr == 0);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual void undo(context & ctx) {
 | 
			
		||||
            m_ptr = 0;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template<typename T, bool CallDestructors=true>
 | 
			
		||||
    class vector_value_trail : public trail {
 | 
			
		||||
        vector<T, CallDestructors> & m_vector;
 | 
			
		||||
        unsigned                     m_idx;
 | 
			
		||||
        T                            m_old_value;
 | 
			
		||||
    public:
 | 
			
		||||
        vector_value_trail(vector<T, CallDestructors> & v, unsigned idx):
 | 
			
		||||
            m_vector(v),
 | 
			
		||||
            m_idx(idx),
 | 
			
		||||
            m_old_value(v[idx]) {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual ~vector_value_trail() {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual void undo(context & ctx) {
 | 
			
		||||
            m_vector[m_idx] = m_old_value;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template<typename T, bool CallDestructors=true>
 | 
			
		||||
    class push_back_trail : public trail {
 | 
			
		||||
        vector<T, CallDestructors> & m_vector;
 | 
			
		||||
    public:
 | 
			
		||||
        push_back_trail(vector<T, CallDestructors> & v):
 | 
			
		||||
            m_vector(v) {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual void undo(context & ctx) {
 | 
			
		||||
            m_vector.pop_back();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    class set_bitvector_trail : public trail {
 | 
			
		||||
        svector<bool> & m_vector;
 | 
			
		||||
        unsigned        m_idx;
 | 
			
		||||
    public:
 | 
			
		||||
        set_bitvector_trail(svector<bool> & v, unsigned idx):
 | 
			
		||||
            m_vector(v),
 | 
			
		||||
            m_idx(idx) {
 | 
			
		||||
            SASSERT(m_vector[m_idx] == false);
 | 
			
		||||
            m_vector[m_idx] = true;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual void undo(context & ctx) {
 | 
			
		||||
            m_vector[m_idx] = false;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    class new_obj_trail : public trail {
 | 
			
		||||
        T * m_obj;
 | 
			
		||||
    public:
 | 
			
		||||
        new_obj_trail(T * obj):
 | 
			
		||||
            m_obj(obj) {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual void undo(context & ctx) {
 | 
			
		||||
            dealloc(m_obj);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SMT_TRAIL_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
Superposition Calculus.
 | 
			
		||||
This module is currently disabled.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,214 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    fvi.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Feature Vector Indexing.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-01.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _FVI_H_
 | 
			
		||||
#define _FVI_H_
 | 
			
		||||
 | 
			
		||||
#include"splay_tree_map.h"
 | 
			
		||||
#include"hashtable.h"
 | 
			
		||||
#include"vector.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief A feature vector indexing for objects of type T *.
 | 
			
		||||
 | 
			
		||||
   ToVector is a functor for converting T into a vector of natural numbers.
 | 
			
		||||
   It should provide a method:
 | 
			
		||||
      - void operator(T * d, unsigned * f);
 | 
			
		||||
      This method should fill the vector f with the features of d.
 | 
			
		||||
 | 
			
		||||
   Hash: functor for computing the hashcode of T *.
 | 
			
		||||
 | 
			
		||||
   Eq  : functor for comparing T pointers.
 | 
			
		||||
*/
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq=ptr_eq<T> >
 | 
			
		||||
class fvi : private ToVector {
 | 
			
		||||
public:
 | 
			
		||||
    struct statistics {
 | 
			
		||||
        unsigned m_size;
 | 
			
		||||
        unsigned m_num_nodes;
 | 
			
		||||
        unsigned m_num_leaves;
 | 
			
		||||
        unsigned m_min_leaf_size;
 | 
			
		||||
        unsigned m_avg_leaf_size;
 | 
			
		||||
        unsigned m_max_leaf_size;
 | 
			
		||||
        statistics() { reset(); }
 | 
			
		||||
 | 
			
		||||
        void reset() { 
 | 
			
		||||
            m_size = m_num_nodes = m_num_leaves = m_avg_leaf_size = m_max_leaf_size = 0;
 | 
			
		||||
            m_min_leaf_size = UINT_MAX;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    struct ucompare {
 | 
			
		||||
        int operator()(unsigned i1, unsigned i2) const {
 | 
			
		||||
            if (i1 < i2) return -1;
 | 
			
		||||
            if (i1 > i2) return  1;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct node {
 | 
			
		||||
        node() {}
 | 
			
		||||
        virtual ~node() {}
 | 
			
		||||
        virtual bool is_leaf() const = 0;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef splay_tree_map<unsigned, node *, ucompare> children;
 | 
			
		||||
 | 
			
		||||
    struct non_leaf : public node {
 | 
			
		||||
        children m_children;
 | 
			
		||||
        non_leaf() {}
 | 
			
		||||
 | 
			
		||||
        struct delete_children {
 | 
			
		||||
            void operator()(unsigned k, node * n) const {
 | 
			
		||||
                dealloc(n);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        virtual ~non_leaf() {
 | 
			
		||||
            delete_children visitor;
 | 
			
		||||
            m_children.visit(visitor);
 | 
			
		||||
            m_children.reset();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual bool is_leaf() const { return false; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef ptr_hashtable<T, Hash, Eq>     set;
 | 
			
		||||
  
 | 
			
		||||
    struct leaf : public node {
 | 
			
		||||
        set   m_set;
 | 
			
		||||
        leaf() {}
 | 
			
		||||
        virtual ~leaf() {}
 | 
			
		||||
        virtual bool is_leaf() const { return true; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    unsigned          m_num_features;
 | 
			
		||||
    svector<unsigned> m_tmp_buffer;
 | 
			
		||||
    non_leaf *        m_root;
 | 
			
		||||
 | 
			
		||||
    struct stop {};
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_leaf(leaf * n, Visitor & v, bool le) const {
 | 
			
		||||
        typename set::iterator it  = n->m_set.begin();
 | 
			
		||||
        typename set::iterator end = n->m_set.end();
 | 
			
		||||
        for (; it != end; ++it)
 | 
			
		||||
            if (!v(*it))
 | 
			
		||||
                throw stop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    struct non_leaf_visitor {
 | 
			
		||||
        fvi const & m_owner;        
 | 
			
		||||
        unsigned    m_fidx;
 | 
			
		||||
        Visitor &   m_visitor;
 | 
			
		||||
        bool        m_le;
 | 
			
		||||
 | 
			
		||||
        non_leaf_visitor(fvi const & o, unsigned fidx, Visitor & v, bool le):
 | 
			
		||||
            m_owner(o), m_fidx(fidx), m_visitor(v), m_le(le) {}
 | 
			
		||||
        
 | 
			
		||||
        void operator()(unsigned k, node * n) {
 | 
			
		||||
            if (n->is_leaf())
 | 
			
		||||
                m_owner.visit_leaf(static_cast<leaf*>(n), m_visitor, m_le);
 | 
			
		||||
            else
 | 
			
		||||
                m_owner.visit_non_leaf(static_cast<non_leaf*>(n), m_fidx + 1, m_visitor, m_le);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
        
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_non_leaf(non_leaf * n, unsigned fidx, Visitor & v, bool le) const {
 | 
			
		||||
        // Remark: this function is recursive, but there is no risk
 | 
			
		||||
        // of stack overflow since the number of features is small.
 | 
			
		||||
        non_leaf_visitor<Visitor> v2(*this, fidx, v, le);
 | 
			
		||||
        if (le)
 | 
			
		||||
            n->m_children.visit_le(v2, m_tmp_buffer[fidx]);
 | 
			
		||||
        else
 | 
			
		||||
            n->m_children.visit_ge(v2, m_tmp_buffer[fidx]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef Z3DEBUG
 | 
			
		||||
    bool m_visiting;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    void to_fvector(T * d) const {
 | 
			
		||||
        fvi * _this = const_cast<fvi *>(this);
 | 
			
		||||
        _this->ToVector::operator()(d, _this->m_tmp_buffer.c_ptr()); 
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    struct non_leaf_stat_visitor {
 | 
			
		||||
        fvi const &  m_owner;        
 | 
			
		||||
        statistics & m_stats;
 | 
			
		||||
        non_leaf_stat_visitor(fvi const & o, statistics & st):m_owner(o), m_stats(st) {}
 | 
			
		||||
        void operator()(unsigned k, node * n);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    void stats(leaf * n, statistics & result) const;
 | 
			
		||||
    void stats(non_leaf * n, statistics & result) const;
 | 
			
		||||
 | 
			
		||||
    struct non_leaf_collect_visitor {
 | 
			
		||||
        fvi const &     m_owner;
 | 
			
		||||
        ptr_vector<T> & m_elems;
 | 
			
		||||
        non_leaf_collect_visitor(fvi const & o, ptr_vector<T> & elems):m_owner(o), m_elems(elems) {}
 | 
			
		||||
        void operator()(unsigned k, node * n);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    void collect(leaf * n, ptr_vector<T> & result) const;
 | 
			
		||||
    void collect(non_leaf * n, ptr_vector<T> & result) const;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    fvi(unsigned num_features, ToVector const & t = ToVector());
 | 
			
		||||
    ~fvi() { reset(); dealloc(m_root); }
 | 
			
		||||
 | 
			
		||||
    void insert(T * d);
 | 
			
		||||
    bool contains(T * d) const;
 | 
			
		||||
    void erase(T * d);
 | 
			
		||||
    void reset();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Traverse the elements that have features  smaller (greater) or equal than the one of the given element.
 | 
			
		||||
 | 
			
		||||
       For each visited element the following method of v is executed:
 | 
			
		||||
 | 
			
		||||
       - bool operator()(T * d)
 | 
			
		||||
 | 
			
		||||
       If false is returned, the traversal is aborted.
 | 
			
		||||
       
 | 
			
		||||
       \warning The object cannot be updated during the traversal.
 | 
			
		||||
    */
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit(T * d, Visitor & v, bool le = true) const {
 | 
			
		||||
        DEBUG_CODE(const_cast<fvi*>(this)->m_visiting = true;);
 | 
			
		||||
        to_fvector(d);
 | 
			
		||||
        try {
 | 
			
		||||
            visit_non_leaf(m_root, 0, v, le);
 | 
			
		||||
        }
 | 
			
		||||
        catch (stop) {
 | 
			
		||||
        }
 | 
			
		||||
        DEBUG_CODE(const_cast<fvi*>(this)->m_visiting = false;);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void stats(statistics & result) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Copy to result the set of elements stored in the index.
 | 
			
		||||
    */
 | 
			
		||||
    void collect(ptr_vector<T> & result) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _FVI_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,199 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    fvi_def.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Feature Vector Indexing.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-01.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _FVI_DEF_H_
 | 
			
		||||
#define _FVI_DEF_H_
 | 
			
		||||
 | 
			
		||||
#include"fvi.h"
 | 
			
		||||
#include"splay_tree_def.h"
 | 
			
		||||
#include"buffer.h"
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
fvi<T, ToVector, Hash, Eq>::fvi(unsigned num_features, ToVector const & t):
 | 
			
		||||
    ToVector(t),
 | 
			
		||||
    m_num_features(num_features),
 | 
			
		||||
    m_root(0) {
 | 
			
		||||
    m_tmp_buffer.resize(num_features, 0);
 | 
			
		||||
    m_root = alloc(non_leaf);
 | 
			
		||||
    SASSERT(num_features >= 2);
 | 
			
		||||
    DEBUG_CODE(m_visiting = false;);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::reset() {
 | 
			
		||||
    SASSERT(!m_visiting);
 | 
			
		||||
    dealloc(m_root);
 | 
			
		||||
    m_root = alloc(non_leaf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::insert(T * d) {
 | 
			
		||||
    SASSERT(!m_visiting);
 | 
			
		||||
    to_fvector(d);
 | 
			
		||||
    non_leaf * n = m_root;
 | 
			
		||||
    unsigned i = 0;
 | 
			
		||||
    for (; i < m_num_features - 1; i++) {
 | 
			
		||||
        node * child = 0;
 | 
			
		||||
        if (!n->m_children.find(m_tmp_buffer[i], child)) { 
 | 
			
		||||
            child = alloc(non_leaf);
 | 
			
		||||
            n->m_children.insert(m_tmp_buffer[i], child);
 | 
			
		||||
        }
 | 
			
		||||
        SASSERT(child);
 | 
			
		||||
        SASSERT(!child->is_leaf());
 | 
			
		||||
        n = static_cast<non_leaf*>(child);
 | 
			
		||||
    }
 | 
			
		||||
    node * l = 0;
 | 
			
		||||
    SASSERT(i == m_num_features - 1);
 | 
			
		||||
    if (!n->m_children.find(m_tmp_buffer[i], l)) {
 | 
			
		||||
        l = alloc(leaf);
 | 
			
		||||
        n->m_children.insert(m_tmp_buffer[i], l);
 | 
			
		||||
    }
 | 
			
		||||
    SASSERT(l);
 | 
			
		||||
    SASSERT(l->is_leaf());
 | 
			
		||||
    static_cast<leaf*>(l)->m_set.insert(d);
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
bool fvi<T, ToVector, Hash, Eq>::contains(T * d) const {
 | 
			
		||||
    to_fvector(d);
 | 
			
		||||
    non_leaf * n = m_root;
 | 
			
		||||
    node * child;
 | 
			
		||||
    unsigned i = 0;
 | 
			
		||||
    for (; i < m_num_features - 1; i++) {        
 | 
			
		||||
        if (!n->m_children.find(m_tmp_buffer[i], child))
 | 
			
		||||
            return false;
 | 
			
		||||
        SASSERT(child);
 | 
			
		||||
        SASSERT(!child->is_leaf());
 | 
			
		||||
        n = static_cast<non_leaf*>(child);
 | 
			
		||||
    }
 | 
			
		||||
    SASSERT(i == m_num_features - 1);
 | 
			
		||||
    return 
 | 
			
		||||
        n->m_children.find(m_tmp_buffer[i], child) &&
 | 
			
		||||
        static_cast<leaf*>(child)->m_set.contains(d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::erase(T * d) {
 | 
			
		||||
    SASSERT(!m_visiting);
 | 
			
		||||
    SASSERT(contains(d));
 | 
			
		||||
    ptr_buffer<non_leaf> path;
 | 
			
		||||
    to_fvector(d);
 | 
			
		||||
    non_leaf * n = m_root;
 | 
			
		||||
    node * child;
 | 
			
		||||
    unsigned i = 0;
 | 
			
		||||
    for (; i < m_num_features - 1; i++) {        
 | 
			
		||||
        path.push_back(n);
 | 
			
		||||
        if (!n->m_children.find(m_tmp_buffer[i], child)) {
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
        }
 | 
			
		||||
        SASSERT(child);
 | 
			
		||||
        SASSERT(!child->is_leaf());
 | 
			
		||||
        n = static_cast<non_leaf*>(child);
 | 
			
		||||
    }
 | 
			
		||||
    path.push_back(n);    
 | 
			
		||||
    SASSERT(i == m_num_features - 1);
 | 
			
		||||
    if (!n->m_children.find(m_tmp_buffer[i], child)) {
 | 
			
		||||
        UNREACHABLE();
 | 
			
		||||
    }
 | 
			
		||||
    SASSERT(child);
 | 
			
		||||
    SASSERT(child->is_leaf());
 | 
			
		||||
    leaf * l = static_cast<leaf*>(child);
 | 
			
		||||
    l->m_set.erase(d);
 | 
			
		||||
    if (l->m_set.empty()) {
 | 
			
		||||
        dealloc(l);
 | 
			
		||||
        while (true) {
 | 
			
		||||
            non_leaf * n = path.back();
 | 
			
		||||
            n->m_children.erase(m_tmp_buffer[i]);
 | 
			
		||||
            path.pop_back();
 | 
			
		||||
            i--;
 | 
			
		||||
            if (!n->m_children.empty() || n == m_root)
 | 
			
		||||
                break;
 | 
			
		||||
            dealloc(n);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::non_leaf_stat_visitor::operator()(unsigned k, node * n) {
 | 
			
		||||
    if (n->is_leaf())
 | 
			
		||||
        m_owner.stats(static_cast<leaf*>(n), m_stats);
 | 
			
		||||
    else
 | 
			
		||||
        m_owner.stats(static_cast<non_leaf*>(n), m_stats);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::stats(leaf * n, statistics & result) const {
 | 
			
		||||
    unsigned sz = n->m_set.size();
 | 
			
		||||
    result.m_size += sz;
 | 
			
		||||
    if (sz > result.m_max_leaf_size)
 | 
			
		||||
        result.m_max_leaf_size = sz;
 | 
			
		||||
    if (sz < result.m_min_leaf_size)
 | 
			
		||||
        result.m_min_leaf_size = sz;
 | 
			
		||||
    result.m_num_leaves ++;
 | 
			
		||||
    result.m_num_nodes ++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::stats(non_leaf * n, statistics & result) const {
 | 
			
		||||
    result.m_num_nodes++;
 | 
			
		||||
    // Remark: this function is recursive, but there is no risk
 | 
			
		||||
    // of stack overflow since the number of features is small.
 | 
			
		||||
    non_leaf_stat_visitor v(*this, result);
 | 
			
		||||
    n->m_children.visit(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::stats(statistics & result) const {
 | 
			
		||||
    result.reset();
 | 
			
		||||
    stats(m_root, result);
 | 
			
		||||
    if (m_root->m_children.empty())
 | 
			
		||||
        result.m_min_leaf_size = 0;
 | 
			
		||||
    if (result.m_num_leaves > 0)
 | 
			
		||||
        result.m_avg_leaf_size = result.m_size / result.m_num_leaves;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::non_leaf_collect_visitor::operator()(unsigned k, node * n) {
 | 
			
		||||
    if (n->is_leaf())
 | 
			
		||||
        m_owner.collect(static_cast<leaf*>(n), m_elems);
 | 
			
		||||
    else
 | 
			
		||||
        m_owner.collect(static_cast<non_leaf*>(n), m_elems);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::collect(leaf * n, ptr_vector<T> & result) const {
 | 
			
		||||
    typename set::iterator it  = n->m_set.begin();
 | 
			
		||||
    typename set::iterator end = n->m_set.end();
 | 
			
		||||
    for (; it != end; ++it)
 | 
			
		||||
        result.push_back(*it);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::collect(non_leaf * n, ptr_vector<T> & result) const {
 | 
			
		||||
    // Remark: this function is recursive, but there is no risk
 | 
			
		||||
    // of stack overflow since the number of features is small.
 | 
			
		||||
    non_leaf_collect_visitor v(*this, result);
 | 
			
		||||
    n->m_children.visit(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename ToVector, typename Hash, typename Eq>
 | 
			
		||||
void fvi<T, ToVector, Hash, Eq>::collect(ptr_vector<T> & result) const {
 | 
			
		||||
    collect(m_root, result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* _FVI_DEF_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,276 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    kbo.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Knuth-Bendix ordering.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-01-28.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"kbo.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
 | 
			
		||||
inline unsigned kbo::f_weight(func_decl * f) const {
 | 
			
		||||
    // TODO
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline unsigned kbo::var_weight() const {
 | 
			
		||||
    return m_var_weight;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void kbo::reset() {
 | 
			
		||||
    m_weight_balance = 0;
 | 
			
		||||
    m_deltas.reset();
 | 
			
		||||
    m_num_pos = 0;
 | 
			
		||||
    m_num_neg = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Increase the balance of the given variable.
 | 
			
		||||
*/
 | 
			
		||||
inline void kbo::inc(expr_offset v) {
 | 
			
		||||
    SASSERT(is_var(v.get_expr()));
 | 
			
		||||
    int val;
 | 
			
		||||
    unsigned v_idx  = to_var(v.get_expr())->get_idx();
 | 
			
		||||
    unsigned offset = v.get_offset();
 | 
			
		||||
    if (m_deltas.find(v_idx, offset, val)) {
 | 
			
		||||
        if (val == -1) 
 | 
			
		||||
            m_num_neg--;
 | 
			
		||||
        else if (val == 0)
 | 
			
		||||
            m_num_pos++;
 | 
			
		||||
        m_deltas.insert(v_idx, offset, val + 1);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        m_deltas.insert(v_idx, offset, 1);
 | 
			
		||||
        m_num_pos ++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Decreate the balance of the given variable.
 | 
			
		||||
*/
 | 
			
		||||
inline void kbo::dec(expr_offset v) {
 | 
			
		||||
    int val;
 | 
			
		||||
    unsigned v_idx  = to_var(v.get_expr())->get_idx();
 | 
			
		||||
    unsigned offset = v.get_offset();
 | 
			
		||||
    if (m_deltas.find(v_idx, offset, val)) {
 | 
			
		||||
        if (val == 0) 
 | 
			
		||||
            m_num_neg++;
 | 
			
		||||
        else if (val == 1)
 | 
			
		||||
            m_num_pos--;
 | 
			
		||||
        m_deltas.insert(v_idx, offset, val - 1);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        m_deltas.insert(v_idx, offset, -1);
 | 
			
		||||
        m_num_neg ++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Accumulate the variables and weight balance of t. Return
 | 
			
		||||
   true if t contains target_var.
 | 
			
		||||
*/
 | 
			
		||||
template<bool pos>
 | 
			
		||||
bool kbo::VWBc(expr_offset t, expr_offset target_var) {
 | 
			
		||||
    SASSERT(target_var.get_expr() == 0 || is_var(target_var.get_expr()));
 | 
			
		||||
    svector<expr_offset> & todo = m_vwbc_todo;
 | 
			
		||||
    expr_offset s;
 | 
			
		||||
    bool found = false;
 | 
			
		||||
    unsigned j;
 | 
			
		||||
    SASSERT(todo.empty());
 | 
			
		||||
    todo.push_back(t);
 | 
			
		||||
    while (!todo.empty()) {
 | 
			
		||||
        t        = todo.back();
 | 
			
		||||
        if (t == target_var)
 | 
			
		||||
            found = true;
 | 
			
		||||
        expr * n        = t.get_expr();
 | 
			
		||||
        unsigned offset = t.get_offset();
 | 
			
		||||
        todo.pop_back();
 | 
			
		||||
        switch (n->get_kind()) {
 | 
			
		||||
        case AST_VAR:
 | 
			
		||||
            if (m_subst && m_subst->find(to_var(n), offset, s))
 | 
			
		||||
                todo.push_back(s);
 | 
			
		||||
            else if (pos) {
 | 
			
		||||
                inc(t);
 | 
			
		||||
                m_weight_balance += var_weight();
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                dec(t);
 | 
			
		||||
                m_weight_balance -= var_weight();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case AST_APP:
 | 
			
		||||
            if (pos)
 | 
			
		||||
                m_weight_balance += f_weight(to_app(n)->get_decl());
 | 
			
		||||
            else
 | 
			
		||||
                m_weight_balance -= f_weight(to_app(n)->get_decl());
 | 
			
		||||
            j = to_app(n)->get_num_args();
 | 
			
		||||
            while (j > 0) {
 | 
			
		||||
                --j;
 | 
			
		||||
                todo.push_back(expr_offset(to_app(n)->get_arg(j), offset));
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return found;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<bool pos>
 | 
			
		||||
inline void kbo::VWB(expr_offset t, unsigned idx) {
 | 
			
		||||
    expr_offset null(0, 0);
 | 
			
		||||
    app * n = to_app(t.get_expr());
 | 
			
		||||
    unsigned num = n->get_num_args();
 | 
			
		||||
    for (; idx < num; idx++)
 | 
			
		||||
        VWBc<pos>(expr_offset(n->get_arg(idx), t.get_offset()), null);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool is_unary_app(expr * n) {
 | 
			
		||||
    return is_app(n) && to_app(n)->get_num_args() == 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline kbo::result kbo::no_neg() const {
 | 
			
		||||
    return m_num_neg == 0 ? GREATER : UNCOMPARABLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline kbo::result kbo::no_pos() const {
 | 
			
		||||
    return m_num_pos == 0 ? LESSER : UNCOMPARABLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
order::result kbo::compare(expr_offset const & t1, expr_offset const & t2, substitution * s) {
 | 
			
		||||
    reset();
 | 
			
		||||
    m_subst = s;
 | 
			
		||||
 | 
			
		||||
    if (t1 == t2) 
 | 
			
		||||
        return EQUAL;
 | 
			
		||||
 | 
			
		||||
    expr * n1 = t1.get_expr();
 | 
			
		||||
    expr * n2 = t2.get_expr();
 | 
			
		||||
 | 
			
		||||
    // f(s) >_{kbo} f(t) iff s >_{kbo} t
 | 
			
		||||
    while (is_unary_app(n1) && is_unary_app(n2) && to_app(n1)->get_decl() == to_app(n2)->get_decl()) {
 | 
			
		||||
        n1 = to_app(n1)->get_arg(0);
 | 
			
		||||
        n2 = to_app(n2)->get_arg(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    svector<entry> & todo = m_compare_todo;
 | 
			
		||||
    SASSERT(todo.empty());
 | 
			
		||||
    todo.push_back(entry(find(expr_offset(n1, t1.get_offset())),
 | 
			
		||||
                         find(expr_offset(n2, t2.get_offset())),
 | 
			
		||||
                         0));
 | 
			
		||||
 | 
			
		||||
    result res = UNKNOWN;
 | 
			
		||||
 | 
			
		||||
    while (!todo.empty()) {
 | 
			
		||||
        entry & e = todo.back();
 | 
			
		||||
        expr_offset t1 = e.m_t1;
 | 
			
		||||
        expr_offset t2 = e.m_t2;
 | 
			
		||||
        expr * n1 = t1.get_expr();
 | 
			
		||||
        expr * n2 = t2.get_expr();
 | 
			
		||||
        TRACE("kbo", tout << "processing with idx: " << e.m_idx << "\n" << 
 | 
			
		||||
              mk_pp(n1, m_manager) << "\n" << mk_pp(n2, m_manager) << "\n";
 | 
			
		||||
              tout << "wb : " << m_weight_balance << "\n";);
 | 
			
		||||
        SASSERT(!is_quantifier(n1) && !is_quantifier(n2));
 | 
			
		||||
        bool v1 = is_var(n1);
 | 
			
		||||
        bool v2 = is_var(n2);
 | 
			
		||||
        if (v1 && v2) {
 | 
			
		||||
            todo.pop_back();
 | 
			
		||||
            inc(t1);
 | 
			
		||||
            dec(t2);
 | 
			
		||||
            res = t1 == t2 ? EQUAL : UNCOMPARABLE;
 | 
			
		||||
        }
 | 
			
		||||
        else if (v1) {
 | 
			
		||||
            todo.pop_back();
 | 
			
		||||
            res = VWBc<false>(t2, t1) ? LESSER : UNCOMPARABLE;
 | 
			
		||||
            inc(t1);
 | 
			
		||||
            m_weight_balance += var_weight();
 | 
			
		||||
        }
 | 
			
		||||
        else if (v2) {
 | 
			
		||||
            todo.pop_back();
 | 
			
		||||
            res = VWBc<true>(t1, t2) ? GREATER : UNCOMPARABLE;
 | 
			
		||||
            dec(t2);
 | 
			
		||||
            m_weight_balance -= var_weight();
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            func_decl * f = to_app(n1)->get_decl();
 | 
			
		||||
            func_decl * g = to_app(n2)->get_decl();
 | 
			
		||||
            result lex;
 | 
			
		||||
            if (f != g || to_app(n1)->get_num_args() != to_app(n2)->get_num_args()) {
 | 
			
		||||
                VWB<true>(t1, 0);
 | 
			
		||||
                VWB<false>(t2, 0);
 | 
			
		||||
                lex = UNCOMPARABLE;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                unsigned & idx = e.m_idx;
 | 
			
		||||
                // when idx > 0, res contains the result for child (idx - 1)
 | 
			
		||||
                if (idx > 0 && res != EQUAL) {
 | 
			
		||||
                    VWB<true>(t1, idx);
 | 
			
		||||
                    VWB<false>(t2, idx);
 | 
			
		||||
                    lex = res;
 | 
			
		||||
                }
 | 
			
		||||
                else if (idx == to_app(n1)->get_num_args()) {
 | 
			
		||||
                    // all children were visited
 | 
			
		||||
                    lex = EQUAL;
 | 
			
		||||
                }
 | 
			
		||||
                else if (idx < to_app(n1)->get_num_args()) {
 | 
			
		||||
                    expr_offset c1 = find(expr_offset(to_app(n1)->get_arg(idx), t1.get_offset()));
 | 
			
		||||
                    expr_offset c2 = find(expr_offset(to_app(n2)->get_arg(idx), t2.get_offset()));
 | 
			
		||||
                    idx++; // move curr entry child idx
 | 
			
		||||
                    entry new_entry(c1, c2, 0);
 | 
			
		||||
                    todo.push_back(new_entry);
 | 
			
		||||
                    continue; // process child before continuing
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            todo.pop_back();
 | 
			
		||||
            m_weight_balance += f_weight(f);
 | 
			
		||||
            m_weight_balance -= f_weight(g);
 | 
			
		||||
 | 
			
		||||
            if (m_weight_balance > 0)
 | 
			
		||||
                res = no_neg();
 | 
			
		||||
            else if (m_weight_balance < 0)
 | 
			
		||||
                res = no_pos();
 | 
			
		||||
            else if (f_greater(f, g))
 | 
			
		||||
                res = no_neg();
 | 
			
		||||
            else if (f_greater(g, f))
 | 
			
		||||
                res = no_pos();
 | 
			
		||||
            else if (f != g)
 | 
			
		||||
                res = UNCOMPARABLE;
 | 
			
		||||
            else if (lex == EQUAL)
 | 
			
		||||
                res = EQUAL;
 | 
			
		||||
            else if (lex == GREATER)
 | 
			
		||||
                res = no_neg();
 | 
			
		||||
            else if (lex == LESSER)
 | 
			
		||||
                res = no_pos();
 | 
			
		||||
            else
 | 
			
		||||
                res = UNCOMPARABLE;
 | 
			
		||||
        }
 | 
			
		||||
        TRACE("kbo", tout << "result: " << res << "\n";);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool kbo::greater(expr_offset const & t1, expr_offset const & t2, substitution * s) {
 | 
			
		||||
    return compare(t1, t2, s) == GREATER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int kbo::compare_ge(expr_offset const & t1, expr_offset const & t2, substitution * s) {
 | 
			
		||||
    switch (compare(t1, t2, s)) {
 | 
			
		||||
    case GREATER: return 1;
 | 
			
		||||
    case EQUAL:   return 0;
 | 
			
		||||
    default: return -1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,70 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    kbo.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Knuth-Bendix ordering.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-01-28.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _KBO_H_
 | 
			
		||||
#define _KBO_H_
 | 
			
		||||
 | 
			
		||||
#include"order.h"
 | 
			
		||||
 | 
			
		||||
class kbo : public order {
 | 
			
		||||
    struct entry {
 | 
			
		||||
        expr_offset m_t1;
 | 
			
		||||
        expr_offset m_t2;
 | 
			
		||||
        unsigned    m_idx;
 | 
			
		||||
        entry():m_idx(UINT_MAX) {}
 | 
			
		||||
        entry(expr_offset const & t1, expr_offset const & t2, unsigned idx):
 | 
			
		||||
            m_t1(t1), m_t2(t2), m_idx(idx) {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    unsigned              m_var_weight;
 | 
			
		||||
    int                   m_weight_balance;
 | 
			
		||||
    var_offset_map<int>   m_deltas;
 | 
			
		||||
    unsigned              m_num_pos;
 | 
			
		||||
    unsigned              m_num_neg;
 | 
			
		||||
    svector<expr_offset>  m_vwbc_todo;
 | 
			
		||||
    svector<entry>        m_compare_todo;
 | 
			
		||||
 | 
			
		||||
    unsigned f_weight(func_decl * f) const;
 | 
			
		||||
    unsigned var_weight() const;
 | 
			
		||||
    
 | 
			
		||||
    void reset();
 | 
			
		||||
    void inc(expr_offset v);
 | 
			
		||||
    void dec(expr_offset v);
 | 
			
		||||
 | 
			
		||||
    template<bool pos>
 | 
			
		||||
    bool VWBc(expr_offset t, expr_offset target_var);
 | 
			
		||||
 | 
			
		||||
    template<bool pos>
 | 
			
		||||
    void VWB(expr_offset t, unsigned idx);
 | 
			
		||||
    
 | 
			
		||||
    result no_neg() const;
 | 
			
		||||
    result no_pos() const;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    kbo(ast_manager & m, precedence * p, unsigned var_weight = 1):order(m, p), m_var_weight(var_weight) {}
 | 
			
		||||
    virtual ~kbo() {}
 | 
			
		||||
    virtual void reserve(unsigned num_offsets, unsigned num_vars) { m_deltas.reserve(num_offsets, num_vars); }
 | 
			
		||||
    virtual void reserve_offsets(unsigned num_offsets) { m_deltas.reserve_offsets(num_offsets); }
 | 
			
		||||
    virtual void reserve_vars(unsigned num_vars) { m_deltas.reserve_vars(num_vars); }
 | 
			
		||||
    virtual result compare(expr_offset const & t1, expr_offset const & t2, substitution * s);
 | 
			
		||||
    result compare(expr * t1, expr * t2) { return compare(expr_offset(t1, 0), expr_offset(t2, 0), 0); }
 | 
			
		||||
    virtual bool greater(expr_offset const & t1, expr_offset const & t2, substitution * s);
 | 
			
		||||
    virtual int compare_ge(expr_offset const & t1, expr_offset const & t2, substitution * s);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _KBO_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,184 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    lpo.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Lexicographical Path Ordering
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-01.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"lpo.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Check whether the variable in t1 occurs in t2.
 | 
			
		||||
*/
 | 
			
		||||
bool lpo::occurs(expr_offset const & t1, expr_offset const & t2) {
 | 
			
		||||
    SASSERT(is_var(t1.get_expr()));
 | 
			
		||||
    if (is_ground(t2.get_expr()))
 | 
			
		||||
        return false;
 | 
			
		||||
    m_todo.reset();
 | 
			
		||||
    m_todo.push_back(t2);
 | 
			
		||||
    while (!m_todo.empty()) {
 | 
			
		||||
        expr_offset t = m_todo.back();
 | 
			
		||||
        m_todo.pop_back();
 | 
			
		||||
        t = find(t);
 | 
			
		||||
        expr * n        = t.get_expr();
 | 
			
		||||
        if (is_ground(n))
 | 
			
		||||
            continue;
 | 
			
		||||
        unsigned offset = t.get_offset();
 | 
			
		||||
        unsigned j;
 | 
			
		||||
        switch (n->get_kind()) {
 | 
			
		||||
        case AST_VAR:
 | 
			
		||||
            if (t == t1)
 | 
			
		||||
                return true;
 | 
			
		||||
            break;
 | 
			
		||||
        case AST_APP:
 | 
			
		||||
            j = to_app(n)->get_num_args();
 | 
			
		||||
            while (j > 0) {
 | 
			
		||||
                --j;
 | 
			
		||||
                expr * arg = to_app(n)->get_arg(j);
 | 
			
		||||
                if (!is_ground(arg)) 
 | 
			
		||||
                    m_todo.push_back(expr_offset(arg, offset));
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool lpo::greater(expr_offset s, expr_offset t, unsigned depth) {
 | 
			
		||||
    return lpo::compare(s, t, depth) == GREATER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Return true if s >_{lpo} t_i forall children t_i of t.
 | 
			
		||||
*/
 | 
			
		||||
bool lpo::dominates_args(expr_offset s, expr_offset t, unsigned depth) {
 | 
			
		||||
    SASSERT(is_app(t.get_expr()));
 | 
			
		||||
    unsigned num_args = to_app(t.get_expr())->get_num_args();
 | 
			
		||||
    unsigned off      = t.get_offset();
 | 
			
		||||
    for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
        expr * t_i = to_app(t.get_expr())->get_arg(i);
 | 
			
		||||
        if (!greater(s, expr_offset(t_i, off), depth+1))
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Return true if s_i >=_{lpo} t for some arg s_i of s.
 | 
			
		||||
 */
 | 
			
		||||
bool lpo::arg_dominates_expr(expr_offset s, expr_offset t, unsigned depth) {
 | 
			
		||||
    SASSERT(is_app(s.get_expr()));
 | 
			
		||||
    unsigned num_args = to_app(s.get_expr())->get_num_args();
 | 
			
		||||
    unsigned off      = s.get_offset();
 | 
			
		||||
    for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
        expr * s_i = to_app(s.get_expr())->get_arg(i);
 | 
			
		||||
        result r   = compare(expr_offset(s_i, off), t, depth+1);
 | 
			
		||||
        if (r == EQUAL || r == GREATER)
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
order::result lpo::lex_compare(expr_offset s, expr_offset t, unsigned depth) {
 | 
			
		||||
    SASSERT(is_app(s.get_expr()));
 | 
			
		||||
    SASSERT(is_app(t.get_expr()));
 | 
			
		||||
    app * _s = to_app(s.get_expr());
 | 
			
		||||
    app * _t = to_app(t.get_expr());
 | 
			
		||||
    unsigned num_args1 = _s->get_num_args();
 | 
			
		||||
    unsigned num_args2 = _t->get_num_args();
 | 
			
		||||
    unsigned num_args  = std::min(num_args1, num_args2);
 | 
			
		||||
    unsigned off1      = s.get_offset();
 | 
			
		||||
    unsigned off2      = t.get_offset();
 | 
			
		||||
    result r = EQUAL;
 | 
			
		||||
    for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
        r = compare(expr_offset(_s->get_arg(i), off1), expr_offset(_t->get_arg(i), off2), depth+1);
 | 
			
		||||
        if (r != EQUAL)
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    if (r == EQUAL) {
 | 
			
		||||
        if (num_args1 > num_args2)
 | 
			
		||||
            return GREATER;
 | 
			
		||||
        if (num_args1 < num_args2)
 | 
			
		||||
            return NOT_GTEQ;
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline order::result lpo::compare_core(expr_offset s, expr_offset t, unsigned depth) {
 | 
			
		||||
    s = find(s);
 | 
			
		||||
    t = find(t);
 | 
			
		||||
    
 | 
			
		||||
    if (max_depth(depth))
 | 
			
		||||
        return UNKNOWN;
 | 
			
		||||
 | 
			
		||||
    if (is_var(s.get_expr()))
 | 
			
		||||
        return s == t ? EQUAL : UNCOMPARABLE;
 | 
			
		||||
    else if (is_var(t.get_expr()))
 | 
			
		||||
        return occurs(t, s) ? GREATER : UNCOMPARABLE;
 | 
			
		||||
    else {
 | 
			
		||||
        func_decl * f = to_app(s.get_expr())->get_decl();
 | 
			
		||||
        func_decl * g = to_app(t.get_expr())->get_decl();
 | 
			
		||||
        if (f_greater(f, g))
 | 
			
		||||
            return dominates_args(s, t, depth) ? GREATER : NOT_GTEQ;
 | 
			
		||||
        else if (f != g)
 | 
			
		||||
            return arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ;
 | 
			
		||||
        else {
 | 
			
		||||
            result r = lex_compare(s, t, depth);
 | 
			
		||||
            if (r == GREATER) {
 | 
			
		||||
                if (dominates_args(s, t, depth))
 | 
			
		||||
                    return GREATER;
 | 
			
		||||
            }
 | 
			
		||||
            else if (r == EQUAL)
 | 
			
		||||
                return EQUAL;
 | 
			
		||||
            return to_app(s.get_expr())->get_num_args() > 1 && arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
order::result lpo::compare(expr_offset s, expr_offset t, unsigned depth) {
 | 
			
		||||
    TRACE("lpo", tout << "comparing:\n" << mk_pp(s.get_expr(), m_manager) << "\n" << mk_pp(t.get_expr(), m_manager) << "\n";);
 | 
			
		||||
    result r = compare_core(s, t, depth);
 | 
			
		||||
    TRACE("lpo", tout << "result of comparing:\n" << mk_pp(s.get_expr(), m_manager) << "\n" << mk_pp(t.get_expr(), m_manager) << "\nresult: " << r << "\n";);
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool lpo::greater(expr_offset const & t1, expr_offset const & t2, substitution * s) {
 | 
			
		||||
    m_subst = s;
 | 
			
		||||
    return greater(t1, t2, static_cast<unsigned>(0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
order::result lpo::compare(expr_offset const & t1, expr_offset const & t2, substitution * s) {
 | 
			
		||||
    m_subst = s;
 | 
			
		||||
    result r = compare(t1, t2, static_cast<unsigned>(0));
 | 
			
		||||
    if (r != NOT_GTEQ) 
 | 
			
		||||
        return r;
 | 
			
		||||
    r = compare(t2, t1, static_cast<unsigned>(0));
 | 
			
		||||
    if (r == GREATER)
 | 
			
		||||
        return LESSER;
 | 
			
		||||
    if (r == UNKNOWN)
 | 
			
		||||
        return UNKNOWN;
 | 
			
		||||
    return UNCOMPARABLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lpo::compare_ge(expr_offset const & t1, expr_offset const & t2, substitution * s) {
 | 
			
		||||
    m_subst = s;
 | 
			
		||||
    result r = compare(t1, t2, static_cast<unsigned>(0));
 | 
			
		||||
    switch (r) {
 | 
			
		||||
    case GREATER: return 1;
 | 
			
		||||
    case EQUAL:   return 0;
 | 
			
		||||
    default:      return -1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    lpo.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Lexicographical Path Ordering
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-01.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _LPO_H_
 | 
			
		||||
#define _LPO_H_
 | 
			
		||||
 | 
			
		||||
#include"order.h"
 | 
			
		||||
#include"vector.h"
 | 
			
		||||
#include"map.h"
 | 
			
		||||
 | 
			
		||||
class lpo : public order {
 | 
			
		||||
    svector<expr_offset>  m_todo;
 | 
			
		||||
 | 
			
		||||
    bool occurs(expr_offset const & t1, expr_offset const & t2);
 | 
			
		||||
    bool greater(expr_offset s, expr_offset t, unsigned depth);
 | 
			
		||||
    bool dominates_args(expr_offset s, expr_offset t, unsigned depth);
 | 
			
		||||
    bool arg_dominates_expr(expr_offset s, expr_offset t, unsigned depth);
 | 
			
		||||
    result lex_compare(expr_offset s, expr_offset t, unsigned depth);
 | 
			
		||||
    result compare_core(expr_offset s, expr_offset t, unsigned depth);
 | 
			
		||||
    result compare(expr_offset s, expr_offset t, unsigned depth);
 | 
			
		||||
    bool max_depth(unsigned d) { /* TODO */ return false; }
 | 
			
		||||
public:
 | 
			
		||||
    lpo(ast_manager & m, precedence * p):order(m, p) {}
 | 
			
		||||
    virtual ~lpo() {}
 | 
			
		||||
    
 | 
			
		||||
    virtual result compare(expr_offset const & t1, expr_offset const & t2, substitution * s);
 | 
			
		||||
    result compare(expr * t1, expr * t2) { return compare(expr_offset(t1, 0), expr_offset(t2, 0), static_cast<substitution*>(0)); }
 | 
			
		||||
 | 
			
		||||
    virtual bool greater(expr_offset const & t1, expr_offset const & t2, substitution * s);
 | 
			
		||||
    bool greater(expr_offset const & t1, expr_offset const & t2) { return greater(t1, t2); }
 | 
			
		||||
    virtual int compare_ge(expr_offset const & t1, expr_offset const & t2, substitution * s);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _LPO_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,56 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    marker.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Auxiliary object for managing markings
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-07.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _MARKER_H_
 | 
			
		||||
#define _MARKER_H_
 | 
			
		||||
 | 
			
		||||
#include"vector.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Keep track of all marked objects. Unmark them when the method
 | 
			
		||||
   unmark or destructor is invoked.
 | 
			
		||||
*/
 | 
			
		||||
template<typename T>
 | 
			
		||||
class marker {
 | 
			
		||||
    ptr_vector<T> m_to_unmark;
 | 
			
		||||
public:
 | 
			
		||||
    ~marker() {
 | 
			
		||||
        unmark();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void mark(T * obj) { 
 | 
			
		||||
        obj->set_mark(true);
 | 
			
		||||
        m_to_unmark.push_back(obj);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    bool is_marked(T * obj) const {
 | 
			
		||||
        return obj->is_marked();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unmark() {
 | 
			
		||||
        typename ptr_vector<T>::iterator it  = m_to_unmark.begin();
 | 
			
		||||
        typename ptr_vector<T>::iterator end = m_to_unmark.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            T * obj = *it;
 | 
			
		||||
            obj->set_mark(false);
 | 
			
		||||
        }
 | 
			
		||||
        m_to_unmark.reset();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _MARKER_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,88 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    normalize_vars.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-16.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"normalize_vars.h"
 | 
			
		||||
 | 
			
		||||
expr * normalize_vars::operator()(expr * n) {
 | 
			
		||||
    SASSERT(m_todo.empty());
 | 
			
		||||
    m_todo.push_back(n);
 | 
			
		||||
    while (!m_todo.empty()) {
 | 
			
		||||
        n = m_todo.back();
 | 
			
		||||
        if (m_cache.contains(n)) {
 | 
			
		||||
            m_todo.pop_back();
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (is_var(n)) {
 | 
			
		||||
            m_todo.pop_back();
 | 
			
		||||
            unsigned idx = to_var(n)->get_idx();
 | 
			
		||||
            var * new_var = m_map.get(idx, 0);
 | 
			
		||||
            if (new_var == 0) {
 | 
			
		||||
                new_var = m_manager.mk_var(m_next_var, to_var(n)->get_sort());
 | 
			
		||||
                m_next_var++;
 | 
			
		||||
                m_new_vars.push_back(new_var);
 | 
			
		||||
                m_map.setx(idx, new_var, 0);
 | 
			
		||||
            }
 | 
			
		||||
            SASSERT(new_var->get_sort() == to_var(n)->get_sort());
 | 
			
		||||
            m_cache.insert(n, new_var);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            SASSERT(is_app(n));
 | 
			
		||||
            bool visited = true;
 | 
			
		||||
            unsigned num_args = to_app(n)->get_num_args();
 | 
			
		||||
            unsigned j = num_args;
 | 
			
		||||
            while (j > 0) {
 | 
			
		||||
                --j;
 | 
			
		||||
                expr * child = to_app(n)->get_arg(j);
 | 
			
		||||
                if (!m_cache.contains(child)) {
 | 
			
		||||
                    m_todo.push_back(child);
 | 
			
		||||
                    visited = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (visited) {
 | 
			
		||||
                m_todo.pop_back();
 | 
			
		||||
                m_new_children.reset();
 | 
			
		||||
                bool modified = false;
 | 
			
		||||
                for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
                    expr * child = to_app(n)->get_arg(i);
 | 
			
		||||
                    expr * new_child = 0;
 | 
			
		||||
                    m_cache.find(child, new_child);
 | 
			
		||||
                    SASSERT(new_child);
 | 
			
		||||
                    if (child != new_child)
 | 
			
		||||
                        modified = true;
 | 
			
		||||
                    m_new_children.push_back(new_child);
 | 
			
		||||
                }
 | 
			
		||||
                if (!modified) 
 | 
			
		||||
                    m_cache.insert(n, n);
 | 
			
		||||
                else
 | 
			
		||||
                    m_cache.insert(n, m_manager.mk_app(to_app(n)->get_decl(), m_new_children.size(), m_new_children.c_ptr()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    expr * r = 0;
 | 
			
		||||
    m_cache.find(n, r);
 | 
			
		||||
    SASSERT(r);
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void normalize_vars::reset() {
 | 
			
		||||
    m_cache.reset();
 | 
			
		||||
    m_map.reset();
 | 
			
		||||
    m_new_vars.reset();
 | 
			
		||||
    m_next_var = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,47 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    normalize_vars.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-16.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _NORMALIZE_VARS_H_
 | 
			
		||||
#define _NORMALIZE_VARS_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"obj_hashtable.h"
 | 
			
		||||
 | 
			
		||||
class normalize_vars {
 | 
			
		||||
    ast_manager &    m_manager;
 | 
			
		||||
    var_ref_vector   m_new_vars;
 | 
			
		||||
    unsigned         m_next_var;
 | 
			
		||||
    ptr_vector<var>  m_map;
 | 
			
		||||
    typedef obj_map<expr, expr *> cache;
 | 
			
		||||
    cache            m_cache;
 | 
			
		||||
    ptr_vector<expr> m_todo;
 | 
			
		||||
    ptr_vector<expr> m_new_children;
 | 
			
		||||
public:
 | 
			
		||||
    normalize_vars(ast_manager & m):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_new_vars(m) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    expr * operator()(expr * n);
 | 
			
		||||
    void reset();
 | 
			
		||||
    unsigned get_num_vars() const { return m_new_vars.size(); }
 | 
			
		||||
    var * const * get_vars() const { return m_new_vars.c_ptr(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _NORMALIZE_VARS_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,51 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    order.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-15.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include"order.h"
 | 
			
		||||
 | 
			
		||||
bool order::equal(expr_offset const & _t1, expr_offset const & _t2, substitution * s) {
 | 
			
		||||
    if (_t1 == _t2)
 | 
			
		||||
        return true;
 | 
			
		||||
    if (s == 0)
 | 
			
		||||
        return false;
 | 
			
		||||
    m_eq_todo.reset();
 | 
			
		||||
    m_eq_todo.push_back(expr_offset_pair(_t1, _t2));
 | 
			
		||||
    while (!m_eq_todo.empty()) {
 | 
			
		||||
        expr_offset_pair const & p = m_eq_todo.back();
 | 
			
		||||
        expr_offset t1 = find(p.first);
 | 
			
		||||
        expr_offset t2 = find(p.second);
 | 
			
		||||
        m_eq_todo.pop_back();
 | 
			
		||||
        if (t1 == t2)
 | 
			
		||||
            continue;
 | 
			
		||||
        expr * n1 = t1.get_expr();
 | 
			
		||||
        expr * n2 = t2.get_expr();
 | 
			
		||||
        if (!is_app(n1) || !is_app(n2))
 | 
			
		||||
            return false;
 | 
			
		||||
        if (to_app(n1)->get_decl() != to_app(n2)->get_decl())
 | 
			
		||||
            return false;
 | 
			
		||||
        if (to_app(n1)->get_num_args() != to_app(n2)->get_num_args())
 | 
			
		||||
            return false;
 | 
			
		||||
        unsigned num = to_app(n1)->get_num_args();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) 
 | 
			
		||||
            m_eq_todo.push_back(expr_offset_pair(expr_offset(to_app(n1)->get_arg(i), t1.get_offset()),
 | 
			
		||||
                                                 expr_offset(to_app(n2)->get_arg(i), t2.get_offset())));
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,87 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    order.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Abstract class for term orderings.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-01-28.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _ORDER_H_
 | 
			
		||||
#define _ORDER_H_
 | 
			
		||||
 | 
			
		||||
#include"substitution.h"
 | 
			
		||||
#include"precedence.h"
 | 
			
		||||
#include"trace.h"
 | 
			
		||||
 | 
			
		||||
class order {
 | 
			
		||||
protected:
 | 
			
		||||
    ast_manager &  m_manager;
 | 
			
		||||
    precedence *   m_precedence;
 | 
			
		||||
    substitution * m_subst;
 | 
			
		||||
 | 
			
		||||
    typedef std::pair<expr_offset, expr_offset> expr_offset_pair;
 | 
			
		||||
    svector<expr_offset_pair> m_eq_todo;
 | 
			
		||||
 | 
			
		||||
    expr_offset find(expr_offset t) {
 | 
			
		||||
        while (m_subst && is_var(t.get_expr()) && m_subst->find(to_var(t.get_expr()), t.get_offset(), t))
 | 
			
		||||
            ;
 | 
			
		||||
        return t;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool f_greater(func_decl * f, func_decl * g) const {
 | 
			
		||||
        bool r = m_precedence->compare(f, g) > 0;
 | 
			
		||||
        TRACE("order", tout << f->get_name() << " greater than " << g->get_name() << " == " << r << "\n";);
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
public:
 | 
			
		||||
    enum result {
 | 
			
		||||
        UNKNOWN,
 | 
			
		||||
        UNCOMPARABLE,
 | 
			
		||||
        EQUAL,
 | 
			
		||||
        GREATER,
 | 
			
		||||
        LESSER,
 | 
			
		||||
        NOT_GTEQ
 | 
			
		||||
    };
 | 
			
		||||
    static bool ok(result r) { return r == EQUAL || r == GREATER || r == LESSER; }
 | 
			
		||||
    order(ast_manager & m, precedence * p):m_manager(m), m_precedence(p) { SASSERT(p); }
 | 
			
		||||
    virtual ~order() { dealloc(m_precedence); }
 | 
			
		||||
    virtual void reserve(unsigned num_offsets, unsigned num_vars) {}
 | 
			
		||||
    virtual void reserve_offsets(unsigned num_offsets) {}
 | 
			
		||||
    virtual void reserve_vars(unsigned num_vars) {}
 | 
			
		||||
    ast_manager & get_manager() { return m_manager; }
 | 
			
		||||
 | 
			
		||||
    virtual result compare(expr_offset const & t1, expr_offset const & t2, substitution * s) = 0;
 | 
			
		||||
    result compare(expr * t1, expr * t2, unsigned offset, substitution * s) { return compare(expr_offset(t1, offset), expr_offset(t2, offset), s); }
 | 
			
		||||
    result compare(expr * t1, expr * t2) { return compare(expr_offset(t1, 0), expr_offset(t2, 0), 0); }
 | 
			
		||||
    virtual bool greater(expr_offset const & t1, expr_offset const & t2, substitution * s) = 0;
 | 
			
		||||
    bool greater(expr * t1, expr * t2) { return greater(expr_offset(t1,0), expr_offset(t2,0), 0); }
 | 
			
		||||
    bool greater(expr * t1, expr * t2, substitution * s) { return greater(expr_offset(t1,0), expr_offset(t2,0), s); }
 | 
			
		||||
    bool greater(expr * t1, expr * t2, unsigned offset, substitution * s) { 
 | 
			
		||||
        return greater(expr_offset(t1, offset), expr_offset(t2, offset), s); 
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return a value > 0 if t1 is greater than t2, 0 if t1 == t2, and < 0 otherwise (uncomparable, unknown, lesser).
 | 
			
		||||
    */
 | 
			
		||||
    virtual int compare_ge(expr_offset const & t1, expr_offset const & t2, substitution * s) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if the given terms are equal modulo the given substitution
 | 
			
		||||
    */
 | 
			
		||||
    bool equal(expr_offset const & t1, expr_offset const & t2, substitution * s);
 | 
			
		||||
 | 
			
		||||
    bool equal(expr * t1, expr * t2, unsigned offset = 0, substitution * s = 0) {
 | 
			
		||||
        return equal(expr_offset(t1, offset), expr_offset(t2, offset), s);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _ORDER_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,191 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    precedence.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-08.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"precedence.h"
 | 
			
		||||
#include"warning.h"
 | 
			
		||||
 | 
			
		||||
lex_precedence::lex_precedence(unsigned n, precedence ** ps):
 | 
			
		||||
    m_precedences(n, ps) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
lex_precedence::~lex_precedence() {
 | 
			
		||||
    std::for_each(m_precedences.begin(), m_precedences.end(), delete_proc<precedence>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lex_precedence::compare(func_decl * f, func_decl * g) {
 | 
			
		||||
    int r = 0;
 | 
			
		||||
    ptr_vector<precedence>::iterator it  = m_precedences.begin();
 | 
			
		||||
    ptr_vector<precedence>::iterator end = m_precedences.end();
 | 
			
		||||
    for (; it != end; ++it) {
 | 
			
		||||
        r = (*it)->compare(f, g);
 | 
			
		||||
        if (r != 0)
 | 
			
		||||
            return r;
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inv_precedence::inv_precedence(precedence * p):
 | 
			
		||||
    m_precedence(p) {
 | 
			
		||||
    SASSERT(p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inv_precedence::~inv_precedence() {
 | 
			
		||||
    dealloc(m_precedence);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int inv_precedence::compare(func_decl * f, func_decl * g) {
 | 
			
		||||
    return m_precedence->compare(g, f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int arbitrary_precedence::compare(func_decl * f, func_decl * g) { 
 | 
			
		||||
    return static_cast<int>(f->get_decl_id()) - static_cast<int>(g->get_decl_id()); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int arity_precedence::compare(func_decl * f, func_decl * g) { 
 | 
			
		||||
    return static_cast<int>(f->get_arity()) - static_cast<int>(g->get_arity());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int interpreted_precedence::compare(func_decl * f, func_decl * g) {
 | 
			
		||||
    return static_cast<int>(f->get_family_id() == null_family_id) - static_cast<int>(g->get_family_id() == null_family_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int ext_precedence::get_func_pos(func_decl * f) {
 | 
			
		||||
    unsigned id = f->get_decl_id();
 | 
			
		||||
    return m_cached.get(id, m_undefined);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ext_precedence::compare(func_decl * f, func_decl * g) {
 | 
			
		||||
    return get_func_pos(f) - get_func_pos(g);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ext_precedence::ext_precedence(ast_manager & m, unsigned num_decls, func_decl ** decls):
 | 
			
		||||
    m_undefined(num_decls),
 | 
			
		||||
    m_cached_domain(m) {
 | 
			
		||||
    for (unsigned i = 0; i < num_decls; i++) {
 | 
			
		||||
        m_cached.setx(decls[i]->get_decl_id(), i, m_undefined);
 | 
			
		||||
        m_cached_domain.push_back(decls[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ext_precedence::~ext_precedence() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int abstract_user_precedence::get_decl_pos(decl * d) {
 | 
			
		||||
    unsigned id = d->get_decl_id();
 | 
			
		||||
    int pos = m_cached.get(id, -1);
 | 
			
		||||
    if (pos == -1) {
 | 
			
		||||
        if (!m_symbol2pos.find(d->get_name(), pos))
 | 
			
		||||
            pos = m_undefined;
 | 
			
		||||
        m_cached.setx(id, pos, -1);
 | 
			
		||||
        SASSERT(pos != -1);
 | 
			
		||||
    }
 | 
			
		||||
    return pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abstract_user_precedence::abstract_user_precedence(ast_manager & m, unsigned num_syms, symbol * syms):
 | 
			
		||||
    m_undefined(num_syms),
 | 
			
		||||
    m_cached_domain(m) {
 | 
			
		||||
    for (unsigned i = 0; i < num_syms; i++)
 | 
			
		||||
        m_symbol2pos.insert(syms[i], i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abstract_user_precedence::~abstract_user_precedence() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int user_precedence::compare(func_decl * f, func_decl * g) {
 | 
			
		||||
    return get_decl_pos(f) - get_decl_pos(g);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int user_sort_precedence::compare(func_decl * f, func_decl * g) {
 | 
			
		||||
    return get_decl_pos(f->get_range()) - get_decl_pos(g->get_range());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static precedence * mk_default_precedence(ast_manager & m, order_params const & params) {
 | 
			
		||||
    ptr_buffer<precedence> ps;
 | 
			
		||||
    if (!params.m_order_precedence.empty())
 | 
			
		||||
        ps.push_back(alloc(user_precedence, m, params.m_order_precedence.size(), params.m_order_precedence.c_ptr()));
 | 
			
		||||
    ps.push_back(alloc(interpreted_precedence));
 | 
			
		||||
    ps.push_back(alloc(arity_precedence));
 | 
			
		||||
    ps.push_back(alloc(arbitrary_precedence));
 | 
			
		||||
    return alloc(lex_precedence, ps.size(), ps.c_ptr());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static precedence * mk_inv_precedence(bool inv, precedence * p) {
 | 
			
		||||
    return inv ? alloc(inv_precedence,p) : p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static precedence * mk_lex_precedence(ptr_buffer<precedence> const & ps) {
 | 
			
		||||
    unsigned sz = ps.size();
 | 
			
		||||
    if (sz == 0)
 | 
			
		||||
        return alloc(arbitrary_precedence);
 | 
			
		||||
    else if (sz == 1)
 | 
			
		||||
        return ps[0];
 | 
			
		||||
    else 
 | 
			
		||||
        return alloc(lex_precedence, sz, ps.c_ptr());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
precedence * mk_precedence(ast_manager & m, order_params const & params) {
 | 
			
		||||
    if (params.m_order_precedence_gen.empty())
 | 
			
		||||
        return mk_default_precedence(m, params);
 | 
			
		||||
 | 
			
		||||
    symbol user("user");
 | 
			
		||||
    symbol definition("definition");
 | 
			
		||||
    symbol interpreted("interpreted");
 | 
			
		||||
    symbol frequency("frequency");
 | 
			
		||||
    symbol arity("arity");
 | 
			
		||||
    symbol arbitrary("arbitrary");
 | 
			
		||||
    symbol inv("-");
 | 
			
		||||
 | 
			
		||||
    ptr_buffer<precedence> ps;
 | 
			
		||||
 | 
			
		||||
    svector<symbol>::const_iterator it  =  params.m_order_precedence_gen.begin();
 | 
			
		||||
    svector<symbol>::const_iterator end =  params.m_order_precedence_gen.end();
 | 
			
		||||
    bool prev_inv = false;
 | 
			
		||||
    for (; it != end; ++it) {
 | 
			
		||||
        symbol curr = *it;
 | 
			
		||||
        if (curr == user) {
 | 
			
		||||
            if (params.m_order_precedence.empty())
 | 
			
		||||
                ps.push_back(mk_inv_precedence(prev_inv, alloc(user_precedence, m, params.m_order_precedence.size(), params.m_order_precedence.c_ptr())));
 | 
			
		||||
        }
 | 
			
		||||
        else if (curr == definition) {
 | 
			
		||||
            warning_msg("definition precedence was not implement yet.");
 | 
			
		||||
        }
 | 
			
		||||
        else if (curr == interpreted) {
 | 
			
		||||
            ps.push_back(mk_inv_precedence(prev_inv, alloc(interpreted_precedence)));
 | 
			
		||||
        }
 | 
			
		||||
        else if (curr == frequency) {
 | 
			
		||||
            warning_msg("frequency precedence was not implement yet.");
 | 
			
		||||
        }
 | 
			
		||||
        else if (curr == arity) {
 | 
			
		||||
            ps.push_back(mk_inv_precedence(prev_inv, alloc(arity_precedence)));
 | 
			
		||||
        }
 | 
			
		||||
        else if (curr == arbitrary) {
 | 
			
		||||
            ps.push_back(mk_inv_precedence(prev_inv, alloc(arbitrary_precedence)));
 | 
			
		||||
            // it is pointless to continue, arbitrary_precedence is a total order
 | 
			
		||||
            return mk_lex_precedence(ps);
 | 
			
		||||
        }
 | 
			
		||||
        else if (curr == inv) {
 | 
			
		||||
            prev_inv = true;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            warning_msg("invalid precedence generator: ignoring atom '%s'.", curr.bare_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return mk_lex_precedence(ps);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,142 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    precedence.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-08.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _PRECEDENCE_H_
 | 
			
		||||
#define _PRECEDENCE_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"order_params.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Abstract functor used to implement an order on function symbols.
 | 
			
		||||
*/
 | 
			
		||||
class precedence {
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~precedence() {}
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g) = 0;
 | 
			
		||||
    bool operator()(func_decl * f, func_decl * g) { return compare(f, g) < 0; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Compose different precedence functors using lexicographical order.
 | 
			
		||||
*/
 | 
			
		||||
class lex_precedence : public precedence {
 | 
			
		||||
    ptr_vector<precedence> m_precedences;
 | 
			
		||||
public:
 | 
			
		||||
    lex_precedence(unsigned n, precedence ** ps);
 | 
			
		||||
    virtual ~lex_precedence();
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Invert functor
 | 
			
		||||
 */
 | 
			
		||||
class inv_precedence : public precedence {
 | 
			
		||||
    precedence * m_precedence;
 | 
			
		||||
public:
 | 
			
		||||
    inv_precedence(precedence * p);
 | 
			
		||||
    virtual ~inv_precedence();
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief An arbitrary total order based on the func_decl ids.
 | 
			
		||||
*/
 | 
			
		||||
class arbitrary_precedence : public precedence {
 | 
			
		||||
public:
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Precedence based on the arity. 
 | 
			
		||||
 | 
			
		||||
   \remark This is not a total order, so it must be combined
 | 
			
		||||
   with other precedence functors (e.g., arbitrary_precedence).
 | 
			
		||||
*/
 | 
			
		||||
class arity_precedence : public precedence {
 | 
			
		||||
public:
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Interpreted function symbols are smaller.
 | 
			
		||||
 */
 | 
			
		||||
class interpreted_precedence : public precedence {
 | 
			
		||||
public:
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief A precedence given as a sequence of func_decls.
 | 
			
		||||
   This functor is used to encapsulate automatically/externally generated
 | 
			
		||||
   precedences.
 | 
			
		||||
*/
 | 
			
		||||
class ext_precedence : public precedence {
 | 
			
		||||
    unsigned          m_undefined;  // position for func_decl's not specified by the user.
 | 
			
		||||
    int_vector        m_cached;     // mapping: decl -> int 
 | 
			
		||||
    decl_ref_vector   m_cached_domain;
 | 
			
		||||
    
 | 
			
		||||
    int get_func_pos(func_decl * f);
 | 
			
		||||
public:
 | 
			
		||||
    ext_precedence(ast_manager & m, unsigned num_decls, func_decl ** decls);
 | 
			
		||||
    virtual ~ext_precedence();
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Abstract class for user precedences based on
 | 
			
		||||
   function or sort symbols.
 | 
			
		||||
*/
 | 
			
		||||
class abstract_user_precedence : public precedence {
 | 
			
		||||
protected:
 | 
			
		||||
    symbol_table<int> m_symbol2pos;
 | 
			
		||||
    unsigned          m_undefined;  // position for symbols not specified by the user.
 | 
			
		||||
    int_vector        m_cached;     // mapping: decl -> int 
 | 
			
		||||
    decl_ref_vector   m_cached_domain;
 | 
			
		||||
 | 
			
		||||
    int get_decl_pos(decl * d);
 | 
			
		||||
public:
 | 
			
		||||
    abstract_user_precedence(ast_manager & m, unsigned num_syms, symbol * syms);
 | 
			
		||||
    virtual ~abstract_user_precedence();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief A user defined precedence given as a sequence of symbols.
 | 
			
		||||
 | 
			
		||||
   \remark User provided precedences are usually not total.
 | 
			
		||||
*/
 | 
			
		||||
class user_precedence : public abstract_user_precedence {
 | 
			
		||||
public:
 | 
			
		||||
    user_precedence(ast_manager & m, unsigned num_syms, symbol * syms):abstract_user_precedence(m, num_syms, syms) {}
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief A user defined precedence given as a sequence of sort symbols.
 | 
			
		||||
   The functions are ordered based on their range sort.
 | 
			
		||||
*/
 | 
			
		||||
class user_sort_precedence : public abstract_user_precedence {
 | 
			
		||||
public:
 | 
			
		||||
    user_sort_precedence(ast_manager & m, unsigned num_syms, symbol * syms):abstract_user_precedence(m, num_syms, syms) {}
 | 
			
		||||
    virtual int compare(func_decl * f, func_decl * g);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
precedence * mk_precedence(ast_manager & m, order_params const & params);
 | 
			
		||||
 | 
			
		||||
#endif /* _PRECEDENCE_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,155 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    preprocessor.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Preprocessor
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-01-17.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
#include"ast_ll_pp.h"
 | 
			
		||||
#include"preprocessor.h"
 | 
			
		||||
#include"for_each_expr.h"
 | 
			
		||||
#include"num_occurs.h"
 | 
			
		||||
 | 
			
		||||
preprocessor::preprocessor(ast_manager & m, defined_names & d, simplifier & s, preprocessor_params & p):
 | 
			
		||||
    m_params(p),
 | 
			
		||||
    m_manager(m),
 | 
			
		||||
    m_simp(s),
 | 
			
		||||
    m_nnf(m, d, p),
 | 
			
		||||
    m_cnf(m, d, p),
 | 
			
		||||
    m_der(m),
 | 
			
		||||
    m_push_app_ite(s, p.m_lift_ite == LI_CONSERVATIVE),
 | 
			
		||||
    m_cnf_todo(m),
 | 
			
		||||
    m_cnf_todo_prs(m),
 | 
			
		||||
    m_push_todo(m),
 | 
			
		||||
    m_push_todo_prs(m) {
 | 
			
		||||
    switch (m_params.m_cnf_mode) {
 | 
			
		||||
    case CNF_QUANT: 
 | 
			
		||||
        if (m_params.m_nnf_mode == NNF_SKOLEM)
 | 
			
		||||
            m_params.m_nnf_mode = NNF_QUANT;
 | 
			
		||||
        break;
 | 
			
		||||
    case CNF_OPPORTUNISTIC:
 | 
			
		||||
        if (m_params.m_nnf_mode == NNF_SKOLEM)
 | 
			
		||||
            m_params.m_nnf_mode = NNF_QUANT;
 | 
			
		||||
        break;
 | 
			
		||||
    case CNF_FULL:
 | 
			
		||||
        m_params.m_nnf_mode = NNF_FULL;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _TRACE
 | 
			
		||||
struct num_occurs_pp {
 | 
			
		||||
    
 | 
			
		||||
    ast_manager &  m_manager;
 | 
			
		||||
    std::ostream & m_out;
 | 
			
		||||
    num_occurs     m_occurs;
 | 
			
		||||
 | 
			
		||||
    num_occurs_pp(ast_manager & m, std::ostream & out, expr * root):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_out(out) {
 | 
			
		||||
        m_occurs(root);
 | 
			
		||||
    }
 | 
			
		||||
    void operator()(var * n) {}
 | 
			
		||||
    void operator()(app * n) { 
 | 
			
		||||
        unsigned val = m_occurs.get_num_occs(n);
 | 
			
		||||
        if (val > 1 && m_manager.is_bool(n))
 | 
			
		||||
            m_out << "#" << n->get_id() << " -> " << val << " " << n->get_ref_count() << "\n";
 | 
			
		||||
    }
 | 
			
		||||
    void operator()(quantifier * n) {}
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void preprocessor::operator()(expr * e, proof * in_pr, expr_ref_vector & result, proof_ref_vector & result_prs) {
 | 
			
		||||
    m_cnf_todo.reset();
 | 
			
		||||
    m_cnf_todo_prs.reset();
 | 
			
		||||
    
 | 
			
		||||
    expr_ref   r1(m_manager);
 | 
			
		||||
    proof_ref  pr1(m_manager);
 | 
			
		||||
    m_simp(e, r1, pr1);
 | 
			
		||||
    in_pr = m_manager.mk_modus_ponens(in_pr, pr1);
 | 
			
		||||
    
 | 
			
		||||
    expr_ref   r2(m_manager);
 | 
			
		||||
    proof_ref  pr2(m_manager);
 | 
			
		||||
    m_nnf(r1, m_cnf_todo, m_cnf_todo_prs, r2, pr2);
 | 
			
		||||
    in_pr = m_manager.mk_modus_ponens(in_pr, pr2);
 | 
			
		||||
 | 
			
		||||
    TRACE("preprocessor", tout << mk_ll_pp(r2, m_manager);
 | 
			
		||||
          num_occurs_pp proc(m_manager, tout, r2);
 | 
			
		||||
          for_each_expr(proc, r2););
 | 
			
		||||
    
 | 
			
		||||
    m_cnf_todo.push_back(r2);
 | 
			
		||||
    m_cnf_todo_prs.push_back(in_pr);
 | 
			
		||||
 | 
			
		||||
    unsigned sz = m_cnf_todo.size();
 | 
			
		||||
    for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
        m_push_todo.reset();
 | 
			
		||||
        m_push_todo_prs.reset();
 | 
			
		||||
 | 
			
		||||
        expr * e = m_cnf_todo.get(i);
 | 
			
		||||
        if (m_params.m_lift_ite != LI_NONE) {
 | 
			
		||||
            m_push_app_ite(e, r1, pr1);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            r1  = e;
 | 
			
		||||
            pr1 = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TRACE("preprocessor", tout << mk_ll_pp(r1, m_manager););
 | 
			
		||||
        
 | 
			
		||||
        expr_ref aux(r1, m_manager);
 | 
			
		||||
        m_simp(aux, r1, pr2);
 | 
			
		||||
        pr1 = m_manager.mk_transitivity(pr1, pr2);
 | 
			
		||||
 | 
			
		||||
        TRACE("preprocessor", tout << mk_ll_pp(r1, m_manager););
 | 
			
		||||
 | 
			
		||||
        aux = r1;
 | 
			
		||||
        m_der(aux, r1, pr2);
 | 
			
		||||
        pr1 = m_manager.mk_transitivity(pr1, pr2);
 | 
			
		||||
 | 
			
		||||
        TRACE("preprocessor", tout << mk_ll_pp(r1, m_manager););
 | 
			
		||||
 | 
			
		||||
        if (m_manager.proofs_enabled())
 | 
			
		||||
            in_pr = m_manager.mk_modus_ponens(m_cnf_todo_prs.get(i), pr1);
 | 
			
		||||
        else
 | 
			
		||||
            in_pr = 0;
 | 
			
		||||
 | 
			
		||||
        aux = r1;
 | 
			
		||||
        m_cnf(aux, m_push_todo, m_push_todo_prs, r1, pr1);
 | 
			
		||||
        m_push_todo.push_back(r1);
 | 
			
		||||
 | 
			
		||||
        TRACE("preprocessor", tout << mk_ll_pp(r1, m_manager););
 | 
			
		||||
 | 
			
		||||
        if (m_manager.proofs_enabled()) {
 | 
			
		||||
            in_pr = m_manager.mk_modus_ponens(in_pr, pr1);
 | 
			
		||||
            m_push_todo_prs.push_back(in_pr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        unsigned sz2 = m_push_todo.size();
 | 
			
		||||
        for (unsigned j = 0; j < sz2; j++) {
 | 
			
		||||
            expr * e = m_push_todo.get(j);
 | 
			
		||||
            m_simp(e, r1, pr1);
 | 
			
		||||
            
 | 
			
		||||
            TRACE("preprocessor", tout << mk_ll_pp(r1, m_manager););
 | 
			
		||||
 | 
			
		||||
            if (m_manager.proofs_enabled())
 | 
			
		||||
                in_pr = m_manager.mk_modus_ponens(m_push_todo_prs.get(j), pr1);
 | 
			
		||||
            else
 | 
			
		||||
                in_pr = 0;
 | 
			
		||||
            push_assertion(m_manager, r1, in_pr, result, result_prs);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,51 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    preprocessor.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Preprocess AST before adding them to the logical context
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-01-17.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _PREPROCESSOR_H_
 | 
			
		||||
#define _PREPROCESSOR_H_
 | 
			
		||||
 | 
			
		||||
#include"preprocessor_params.h"
 | 
			
		||||
#include"simplifier.h"
 | 
			
		||||
#include"pattern_inference.h"
 | 
			
		||||
#include"nnf.h"
 | 
			
		||||
#include"cnf.h"
 | 
			
		||||
#include"der.h"
 | 
			
		||||
#include"push_app_ite.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Functor used to preprocess expressions before adding them to
 | 
			
		||||
   the logical context.
 | 
			
		||||
*/
 | 
			
		||||
class preprocessor {
 | 
			
		||||
    preprocessor_params & m_params;
 | 
			
		||||
    ast_manager &         m_manager;
 | 
			
		||||
    simplifier &          m_simp;
 | 
			
		||||
    nnf                   m_nnf;
 | 
			
		||||
    cnf                   m_cnf;
 | 
			
		||||
    der_star              m_der;                  
 | 
			
		||||
    push_app_ite          m_push_app_ite;
 | 
			
		||||
    expr_ref_vector       m_cnf_todo;
 | 
			
		||||
    proof_ref_vector      m_cnf_todo_prs;
 | 
			
		||||
    expr_ref_vector       m_push_todo;
 | 
			
		||||
    proof_ref_vector      m_push_todo_prs;
 | 
			
		||||
public:
 | 
			
		||||
    preprocessor(ast_manager & m, defined_names & d, simplifier & s, preprocessor_params & p);
 | 
			
		||||
    void operator()(expr * e, proof * in_pr, expr_ref_vector & result, proof_ref_vector & result_prs);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _PREPROCESSOR_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,107 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    sparse_use_list.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Sparse use list index.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-13.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPARSE_USE_LIST_H_
 | 
			
		||||
#define _SPARSE_USE_LIST_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"obj_hashtable.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief (Generic sparse) use-list data-structure.
 | 
			
		||||
*/
 | 
			
		||||
template<typename T, typename Set>
 | 
			
		||||
class sparse_use_list {
 | 
			
		||||
    typedef obj_map<T, Set *> use_list;
 | 
			
		||||
    use_list        m_use_list;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    typedef typename Set::iterator iterator;
 | 
			
		||||
    sparse_use_list() {}
 | 
			
		||||
    ~sparse_use_list() { 
 | 
			
		||||
        reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void insert(typename Set::data const & parent, T * child) {
 | 
			
		||||
        Set * parents = 0;
 | 
			
		||||
        if (!m_use_list.find(child, parents)) {
 | 
			
		||||
            parents = alloc(Set);
 | 
			
		||||
            m_use_list.insert(child, parents);
 | 
			
		||||
        }
 | 
			
		||||
        SASSERT(parents);
 | 
			
		||||
        parents->insert(parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return 0 if child did not contain any parents.
 | 
			
		||||
       Return 1, if child does not have more parents after 
 | 
			
		||||
       removing parent.
 | 
			
		||||
       Return 2 otherwise.
 | 
			
		||||
    */
 | 
			
		||||
    unsigned erase(typename Set::data const & parent, T * child) {
 | 
			
		||||
        Set * parents = 0;
 | 
			
		||||
        if (m_use_list.find(child, parents)) {
 | 
			
		||||
            parents->erase(parent);
 | 
			
		||||
            if (parents->empty()) {
 | 
			
		||||
                dealloc(parents);
 | 
			
		||||
                m_use_list.erase(child);
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
            return 2;
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() {
 | 
			
		||||
        typename use_list::iterator it  = m_use_list.begin();
 | 
			
		||||
        typename use_list::iterator end = m_use_list.end();
 | 
			
		||||
        for (; it != end; ++it)
 | 
			
		||||
            dealloc(it->m_value);
 | 
			
		||||
        m_use_list.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Set * get_parents(T * e) {
 | 
			
		||||
        Set * parents = 0;
 | 
			
		||||
        m_use_list.find(e, parents);
 | 
			
		||||
        return parents;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    iterator begin(T * e) {
 | 
			
		||||
        Set * parents = 0;
 | 
			
		||||
        m_use_list.find(e, parents);
 | 
			
		||||
        SASSERT(parents);
 | 
			
		||||
        return parents->begin();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iterator end(T * e) {
 | 
			
		||||
        Set * parents = 0;
 | 
			
		||||
        m_use_list.find(e, parents);
 | 
			
		||||
        SASSERT(parents);
 | 
			
		||||
        return parents->end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool empty(T * e) const {
 | 
			
		||||
        Set * parents = 0;
 | 
			
		||||
        if (m_use_list.find(e, parents))
 | 
			
		||||
            return parents->empty();
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPARSE_USE_LIST_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,170 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_asserted_literals.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include"spc_asserted_literals.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    asserted_literals::asserted_literals(ast_manager & m):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_subst(m),
 | 
			
		||||
        m_tmp_eq1(2),
 | 
			
		||||
        m_tmp_eq2(2) {
 | 
			
		||||
        for (unsigned i = 0; i < 2; i++) {
 | 
			
		||||
            m_st[i]           = alloc(substitution_tree, m_manager);
 | 
			
		||||
            m_expr2clause[i]  = alloc(expr2clause);
 | 
			
		||||
        }
 | 
			
		||||
        m_subst.reserve_offsets(3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    asserted_literals::~asserted_literals() {
 | 
			
		||||
        for (unsigned i = 0; i < 2; i++) {
 | 
			
		||||
            dealloc(m_st[i]);
 | 
			
		||||
            dealloc(m_expr2clause[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    void asserted_literals::insert(clause * cls) {
 | 
			
		||||
        if (cls->get_num_literals() == 1) {
 | 
			
		||||
            TRACE("asserted_literals", tout << "inserting clause into asserted_literals index:\n";
 | 
			
		||||
                  cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            literal const & l = cls->get_literal(0);
 | 
			
		||||
            unsigned neg = static_cast<unsigned>(l.sign());
 | 
			
		||||
            expr * atom  = l.atom();
 | 
			
		||||
            m_st[neg]->insert(to_app(atom));
 | 
			
		||||
            m_expr2clause[neg]->insert(atom, cls);
 | 
			
		||||
            m_subst.reserve_vars(m_st[neg]->get_approx_num_regs());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void asserted_literals::erase(clause * cls) {
 | 
			
		||||
        if (cls->get_num_literals() == 1) {
 | 
			
		||||
            literal const & l = cls->get_literal(0);
 | 
			
		||||
            unsigned neg = static_cast<unsigned>(l.sign());
 | 
			
		||||
            expr * atom  = l.atom();
 | 
			
		||||
            m_expr2clause[neg]->erase(atom);
 | 
			
		||||
            m_st[neg]->erase(to_app(atom));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void asserted_literals::reset() {
 | 
			
		||||
        for (unsigned i = 0; i < 2; i++) {
 | 
			
		||||
            m_st[i]->reset();
 | 
			
		||||
            m_expr2clause[i]->reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct asserted_literals_visitor : public st_visitor {
 | 
			
		||||
        expr * m_target;
 | 
			
		||||
        asserted_literals_visitor(substitution & s):st_visitor(s), m_target(0) {}
 | 
			
		||||
        virtual bool operator()(expr * e) {
 | 
			
		||||
            m_target = e;
 | 
			
		||||
            return false; // stop
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return an unit clause that is a generalization
 | 
			
		||||
       of the given literal.
 | 
			
		||||
       Return 0 if such clause does not exist.
 | 
			
		||||
    */
 | 
			
		||||
    clause * asserted_literals::gen(expr * atom, bool n) {
 | 
			
		||||
        if (is_app(atom)) {
 | 
			
		||||
            TRACE("asserted_literals", tout << "checking if there is generalizer for: " << n << "\n" << 
 | 
			
		||||
                  mk_pp(atom, m_manager) << "\n";);
 | 
			
		||||
            unsigned neg = static_cast<unsigned>(n);
 | 
			
		||||
            m_subst.reset_subst();
 | 
			
		||||
            asserted_literals_visitor visitor(m_subst); 
 | 
			
		||||
            TRACE("asserted_literals_bug", tout << "query: " << mk_pp(atom, m_manager) << "\n"; m_st[neg]->display(tout);
 | 
			
		||||
                  m_subst.display(tout););
 | 
			
		||||
            m_st[neg]->gen(to_app(atom), visitor);
 | 
			
		||||
            if (visitor.m_target != 0) {
 | 
			
		||||
                clause * cls = 0;
 | 
			
		||||
                m_expr2clause[neg]->find(visitor.m_target, cls);
 | 
			
		||||
                SASSERT(cls);
 | 
			
		||||
                return cls;
 | 
			
		||||
            }
 | 
			
		||||
            if (m_manager.is_eq(atom)) {
 | 
			
		||||
                m_subst.reset();
 | 
			
		||||
                m_tmp_eq1.copy_swapping_args(to_app(atom));
 | 
			
		||||
                m_st[neg]->gen(m_tmp_eq1.get_app(), visitor);
 | 
			
		||||
                if (visitor.m_target != 0) {
 | 
			
		||||
                    clause * cls = 0;
 | 
			
		||||
                    m_expr2clause[neg]->find(visitor.m_target, cls);
 | 
			
		||||
                    SASSERT(cls);
 | 
			
		||||
                    return cls;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return an unit clause that is a generalization
 | 
			
		||||
       of the equality (= lhs rhs)
 | 
			
		||||
       Return 0 if such clause does not exist.
 | 
			
		||||
    */
 | 
			
		||||
    clause * asserted_literals::gen_eq(expr * lhs, expr * rhs) {
 | 
			
		||||
        expr * args[2] = { lhs, rhs };
 | 
			
		||||
        func_decl_ref eq_decl(m_manager.mk_func_decl(m_manager.get_basic_family_id(), OP_EQ, 0, 0, 2, args), m_manager);
 | 
			
		||||
        m_tmp_eq2.set_decl(eq_decl);
 | 
			
		||||
        m_tmp_eq2.set_arg(0, lhs);
 | 
			
		||||
        m_tmp_eq2.set_arg(1, rhs);
 | 
			
		||||
        return gen(m_tmp_eq2.get_app(), false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return a unit equality clause (= s t) that (eq) subsumes (= lhs rhs).
 | 
			
		||||
       That is, lhs and rhs have the form u[s'] and u[t'] and there is 
 | 
			
		||||
       a substitution sigma s.t. sigma(s) = s' and sigma(t) = t'.
 | 
			
		||||
       Return 0 if such clause does not exist.
 | 
			
		||||
    */
 | 
			
		||||
    clause * asserted_literals::subsumes(expr * lhs, expr * rhs) {
 | 
			
		||||
        while (true) {
 | 
			
		||||
            TRACE("eq_subsumption", tout << "eq_subsumption loop:\n" << mk_pp(lhs, m_manager) << "\n" << 
 | 
			
		||||
                  mk_pp(rhs, m_manager) << "\n";);
 | 
			
		||||
            clause * subsumer = gen_eq(lhs, rhs);
 | 
			
		||||
            if (subsumer)
 | 
			
		||||
                return subsumer;
 | 
			
		||||
            if (!is_app(lhs) || !is_app(rhs) ||
 | 
			
		||||
                to_app(lhs)->get_decl() != to_app(rhs)->get_decl() || 
 | 
			
		||||
                to_app(lhs)->get_num_args() != to_app(rhs)->get_num_args())
 | 
			
		||||
                return 0;
 | 
			
		||||
            expr * d1 = 0;
 | 
			
		||||
            expr * d2 = 0;
 | 
			
		||||
            unsigned num_args = to_app(lhs)->get_num_args();
 | 
			
		||||
            for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
                expr * c1 = to_app(lhs)->get_arg(i);
 | 
			
		||||
                expr * c2 = to_app(rhs)->get_arg(i);
 | 
			
		||||
                if (c1 != c2) {
 | 
			
		||||
                    if (d1) 
 | 
			
		||||
                        return 0;
 | 
			
		||||
                    d1 = c1;
 | 
			
		||||
                    d2 = c2;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            SASSERT(d1);
 | 
			
		||||
            lhs = d1;
 | 
			
		||||
            rhs = d2;
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,69 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_asserted_literals.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_ASSERTED_LITERALS_H_
 | 
			
		||||
#define _SPC_ASSERTED_LITERALS_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"substitution_tree.h"
 | 
			
		||||
#include"obj_hashtable.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Index for the asserted literals in the logical context.
 | 
			
		||||
       
 | 
			
		||||
       This index is used to implement forward unit subsumption, 
 | 
			
		||||
       equality subsumption, positive simplify-reflect, and
 | 
			
		||||
       negative simplify-reflect.
 | 
			
		||||
    */
 | 
			
		||||
    class asserted_literals {
 | 
			
		||||
    protected:
 | 
			
		||||
        typedef obj_map<expr, clause*> expr2clause;
 | 
			
		||||
        ast_manager &       m_manager;
 | 
			
		||||
        substitution_tree * m_st[2];
 | 
			
		||||
        expr2clause *       m_expr2clause[2];
 | 
			
		||||
        substitution        m_subst;
 | 
			
		||||
        tmp_app             m_tmp_eq1;
 | 
			
		||||
        tmp_app             m_tmp_eq2;
 | 
			
		||||
    public:
 | 
			
		||||
        asserted_literals(ast_manager & m);
 | 
			
		||||
        ~asserted_literals();
 | 
			
		||||
 | 
			
		||||
        void insert(clause * cls);
 | 
			
		||||
        void erase(clause * cls);
 | 
			
		||||
        void reset();
 | 
			
		||||
        void reserve_vars(unsigned num_vars) { m_subst.reserve_vars(num_vars); }
 | 
			
		||||
 | 
			
		||||
        clause * gen(literal const & l) {
 | 
			
		||||
            return gen(l.atom(), l.sign());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        clause * gen(expr * atom, bool neg);
 | 
			
		||||
        clause * gen_eq(expr * lhs, expr * rhs);
 | 
			
		||||
        clause * subsumes(expr * lhs, expr * rhs);
 | 
			
		||||
 | 
			
		||||
        bool has_pos_literals() const { return !m_st[0]->empty(); }
 | 
			
		||||
        bool has_neg_literals() const { return !m_st[1]->empty(); }
 | 
			
		||||
        bool has_literals() const { return has_pos_literals() || has_neg_literals(); }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_ASSERTED_LITERALS_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,287 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_clause.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Clause
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"splay_tree_def.h"
 | 
			
		||||
 | 
			
		||||
template class splay_tree<spc::clause *, spc::clause::compare>;
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    clause::clause(ast_manager & m, unsigned num_lits, literal * lits, justification * p, unsigned scope_lvl):
 | 
			
		||||
        m_id(UINT_MAX),
 | 
			
		||||
        m_time(UINT_MAX),
 | 
			
		||||
        m_scope_lvl(scope_lvl),
 | 
			
		||||
        m_bidx(UINT_MAX),
 | 
			
		||||
        m_processed(false),
 | 
			
		||||
        m_indexed(false), 
 | 
			
		||||
        m_has_sel_lit(false), 
 | 
			
		||||
        m_justification(p) {
 | 
			
		||||
        
 | 
			
		||||
        set_fields(num_lits, lits);
 | 
			
		||||
 | 
			
		||||
        m_num_lits_capacity = m_num_lits[0] + m_num_lits[1];
 | 
			
		||||
        
 | 
			
		||||
        memcpy(m_lits, lits, sizeof(literal) * get_num_literals());
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++)
 | 
			
		||||
            m.inc_ref(m_lits[i].atom());
 | 
			
		||||
        m_justification->inc_ref();
 | 
			
		||||
        m_justification->set_owner(this);
 | 
			
		||||
        
 | 
			
		||||
        sort_literals();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clause * clause::mk(ast_manager & m, unsigned num_lits, literal * lits, justification * p, unsigned scope_lvl) {
 | 
			
		||||
        void * mem   = m.get_allocator().allocate(sizeof(clause) + num_lits * sizeof(literal));
 | 
			
		||||
        return new (mem) clause(m, num_lits, lits, p, scope_lvl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause::init(unsigned id, unsigned time) {
 | 
			
		||||
        SASSERT(m_id == UINT_MAX);
 | 
			
		||||
        SASSERT(m_time == UINT_MAX);
 | 
			
		||||
 | 
			
		||||
        m_id          = id;
 | 
			
		||||
        m_time        = time;
 | 
			
		||||
        m_proof_depth = 0;
 | 
			
		||||
 | 
			
		||||
        justification_stat j_stat;
 | 
			
		||||
        get_justification_stat(m_justification, j_stat);
 | 
			
		||||
 | 
			
		||||
        m_proof_depth = j_stat.m_proof_depth;
 | 
			
		||||
        
 | 
			
		||||
        if (j_stat.m_max_scope_lvl > m_scope_lvl) 
 | 
			
		||||
            m_scope_lvl = j_stat.m_max_scope_lvl;
 | 
			
		||||
        
 | 
			
		||||
        update_parents(j_stat.m_parent_clauses);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause::update_parents(ptr_buffer<clause> & parents) {
 | 
			
		||||
        ptr_buffer<clause>::iterator it  = parents.begin();
 | 
			
		||||
        ptr_buffer<clause>::iterator end = parents.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            clause * parent = *it;
 | 
			
		||||
            parent->add_child(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause::deallocate(ast_manager & m) {
 | 
			
		||||
 | 
			
		||||
        justification_stat j_stat;
 | 
			
		||||
        get_justification_stat(get_justification(), j_stat);
 | 
			
		||||
 | 
			
		||||
        ptr_buffer<clause>::iterator it  = j_stat.m_parent_clauses.begin();
 | 
			
		||||
        ptr_buffer<clause>::iterator end = j_stat.m_parent_clauses.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            clause * parent = *it;
 | 
			
		||||
            parent->del_child(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dec_ref(get_justification(), m);
 | 
			
		||||
        
 | 
			
		||||
        unsigned num_lits = get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++)
 | 
			
		||||
            m.dec_ref(get_literal(i).atom());
 | 
			
		||||
 | 
			
		||||
        unsigned capacity = get_num_literals_capacity();
 | 
			
		||||
        this->~clause();
 | 
			
		||||
        m.get_allocator().deallocate(sizeof(clause) +  capacity * sizeof(literal), this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause::select_literal(unsigned idx) {
 | 
			
		||||
        SASSERT(idx < get_num_literals());
 | 
			
		||||
        m_lits[idx].set_selected(true);
 | 
			
		||||
        m_has_sel_lit = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if l is maximal in the clause, given a substitution s.
 | 
			
		||||
       
 | 
			
		||||
       s(l) is considered maximal if there is no literal l' in the clause such s(l') is greater
 | 
			
		||||
       than s(l).
 | 
			
		||||
    */
 | 
			
		||||
    bool clause::is_maximal(order & o, literal const & l, unsigned offset, substitution * s) const {
 | 
			
		||||
        unsigned num_lits = get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l_prime = m_lits[i];
 | 
			
		||||
            if (l != l_prime && greater(o, l_prime, l, offset, s))
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if l is a maximal selected literal in the clause, given a substitution s.
 | 
			
		||||
       
 | 
			
		||||
       s(l) is considered maximal selected literal if there is no
 | 
			
		||||
       selected literal l' in the clause such s(l') is greater than s(l).
 | 
			
		||||
    */
 | 
			
		||||
    bool clause::is_sel_maximal(order & o, literal const & l, unsigned offset, substitution * s) const {
 | 
			
		||||
        if (!l.is_selected())
 | 
			
		||||
            return false;
 | 
			
		||||
        unsigned num_lits = get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l_prime = m_lits[i];
 | 
			
		||||
            if (l != l_prime && l_prime.is_selected() && greater(o, l_prime, l, offset, s))
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if l is eligible for resolution.
 | 
			
		||||
    */
 | 
			
		||||
    bool clause::is_eligible_for_resolution(order & o, literal const & l, unsigned offset, substitution * s) const {
 | 
			
		||||
        if (has_sel_lit()) 
 | 
			
		||||
            return is_sel_maximal(o, l, offset, s);
 | 
			
		||||
        else
 | 
			
		||||
            return is_maximal(o, l, offset, s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if l is eligible for paramodulation.
 | 
			
		||||
    */
 | 
			
		||||
    bool clause::is_eligible_for_paramodulation(order & o, literal const & l, unsigned offset, substitution * s) const {
 | 
			
		||||
        return !has_sel_lit() && is_maximal(o, l, offset, s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Try to orient literals.
 | 
			
		||||
    */
 | 
			
		||||
    void clause::try_to_orient_literals(order & o) {
 | 
			
		||||
        o.reserve_vars(get_num_vars());
 | 
			
		||||
        unsigned num_lits = get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal & l = m_lits[i];
 | 
			
		||||
            l.try_to_orient(o);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause::set_fields(unsigned num_lits, literal * lits) {
 | 
			
		||||
        clause_stat c_stat;
 | 
			
		||||
        get_clause_stat(num_lits, lits, c_stat);
 | 
			
		||||
 | 
			
		||||
        m_num_vars          = c_stat.m_max_var_idx + 1;
 | 
			
		||||
        m_sym_count         = c_stat.m_sym_count;
 | 
			
		||||
        m_const_count       = c_stat.m_const_count;
 | 
			
		||||
        m_depth             = c_stat.m_depth;
 | 
			
		||||
        m_num_lits[0]       = c_stat.m_num_lits[0];
 | 
			
		||||
        m_num_lits[1]       = c_stat.m_num_lits[1];
 | 
			
		||||
        m_ground            = c_stat.m_ground;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct lit_lt {
 | 
			
		||||
        bool operator()(literal const & l1, literal const & l2) const {
 | 
			
		||||
            if (l1.is_ground() > l2.is_ground())
 | 
			
		||||
                return true;
 | 
			
		||||
            if (l1.is_ground() != l2.is_ground())
 | 
			
		||||
                return false;
 | 
			
		||||
            if (l1.get_approx_depth() > l2.get_approx_depth())
 | 
			
		||||
                return true;
 | 
			
		||||
            if (l1.get_approx_depth() != l2.get_approx_depth())
 | 
			
		||||
                return false;
 | 
			
		||||
            if (l1.get_approx_sym_count() > l2.get_approx_sym_count())
 | 
			
		||||
                return true;
 | 
			
		||||
            if (l1.get_approx_sym_count() != l2.get_approx_sym_count())
 | 
			
		||||
                return false;
 | 
			
		||||
            if (l1.get_approx_const_count() > l2.get_approx_const_count())
 | 
			
		||||
                return true;
 | 
			
		||||
            if (l1.get_approx_const_count() != l2.get_approx_const_count())
 | 
			
		||||
                return false;
 | 
			
		||||
            return l1.get_id() < l2.get_id();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Sort literals to improve the performance of subsumption tests.
 | 
			
		||||
    */
 | 
			
		||||
    void clause::sort_literals() {
 | 
			
		||||
        DEBUG_CODE({
 | 
			
		||||
            unsigned num_lits = get_num_literals();
 | 
			
		||||
            for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
                SASSERT(m_lits[i].has_stats());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        std::sort(m_lits, m_lits + get_num_literals(), lit_lt());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Replace clause literal with the given literals.
 | 
			
		||||
       Use the given justification to justify the new clause.
 | 
			
		||||
    */
 | 
			
		||||
    void clause::update_lits(ast_manager & m, unsigned num_lits, literal * lits, justification * j) {
 | 
			
		||||
        unsigned old_num_lits = get_num_literals();
 | 
			
		||||
        SASSERT(num_lits <= old_num_lits);
 | 
			
		||||
     
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++)
 | 
			
		||||
            m.inc_ref(lits[i].atom());
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < old_num_lits; i++)
 | 
			
		||||
            m.dec_ref(m_lits[i].atom());
 | 
			
		||||
        
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) 
 | 
			
		||||
            m_lits[i] = lits[i];
 | 
			
		||||
        
 | 
			
		||||
        set_fields(num_lits, m_lits);
 | 
			
		||||
 | 
			
		||||
        SASSERT(get_num_literals() == num_lits);
 | 
			
		||||
 | 
			
		||||
        j->inc_ref();
 | 
			
		||||
        m_justification->set_owner(0); // release ownership
 | 
			
		||||
        dec_ref(m_justification, m);
 | 
			
		||||
        m_justification = j;
 | 
			
		||||
        m_justification->set_owner(this);
 | 
			
		||||
 | 
			
		||||
        sort_literals();
 | 
			
		||||
 | 
			
		||||
        justification_stat j_stat;
 | 
			
		||||
        get_justification_stat(m_justification, j_stat);
 | 
			
		||||
 | 
			
		||||
        m_proof_depth = j_stat.m_proof_depth;
 | 
			
		||||
        
 | 
			
		||||
        SASSERT(m_scope_lvl == j_stat.m_max_scope_lvl);
 | 
			
		||||
        
 | 
			
		||||
        update_parents(j_stat.m_parent_clauses);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause::display(std::ostream & out, ast_manager & m, bool detailed) {
 | 
			
		||||
        if (get_num_literals() == 0) {
 | 
			
		||||
            out << "empty-clause";
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        out << "#" << m_id << ": (clause ";
 | 
			
		||||
        spc::display(out, get_num_literals(), m_lits, m, detailed);
 | 
			
		||||
        out << ")";
 | 
			
		||||
        if (m_processed)
 | 
			
		||||
            out << "*";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void get_clause_stat(unsigned num_lits, literal * lits, clause_stat & stat) {
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal_stat c;
 | 
			
		||||
            lits[i].get_stat(c);
 | 
			
		||||
            stat.m_sym_count   += c.m_sym_count;
 | 
			
		||||
            stat.m_depth        = std::max(stat.m_depth, c.m_depth);
 | 
			
		||||
            stat.m_max_var_idx  = std::max(stat.m_max_var_idx, c.m_max_var_idx);
 | 
			
		||||
            stat.m_const_count += c.m_const_count;
 | 
			
		||||
            stat.m_ground      &= c.m_ground;
 | 
			
		||||
            stat.m_num_lits[static_cast<unsigned>(lits[i].sign())]++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,152 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_clause.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Clause
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_CLAUSE_H_
 | 
			
		||||
#define _SPC_CLAUSE_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"splay_tree.h"
 | 
			
		||||
#include"use_list.h"
 | 
			
		||||
#include"spc_literal.h"
 | 
			
		||||
#include"spc_justification.h"
 | 
			
		||||
#include"use_list.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    class context;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Superposition Calculus clause.
 | 
			
		||||
    */
 | 
			
		||||
    class clause {
 | 
			
		||||
        struct compare {
 | 
			
		||||
            // ignoring potential overflow/underflow
 | 
			
		||||
            int operator()(clause * c1, clause * c2) const {
 | 
			
		||||
                return static_cast<int>(c1->get_id()) - static_cast<int>(c2->get_id());
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    public:
 | 
			
		||||
        typedef splay_tree<clause *, compare> set;
 | 
			
		||||
    private:
 | 
			
		||||
        unsigned            m_id;           // clause unique id
 | 
			
		||||
        unsigned            m_time;         // how old is the clause. 
 | 
			
		||||
        unsigned            m_num_vars;     // approx. number of variables (i.e., max_var_id + 1)
 | 
			
		||||
        unsigned            m_sym_count;    // number of symbols
 | 
			
		||||
        unsigned            m_const_count;  // number of constants
 | 
			
		||||
        unsigned            m_depth;        // depth (i.e., max depth of a literal)
 | 
			
		||||
        unsigned            m_proof_depth;  
 | 
			
		||||
        unsigned            m_scope_lvl;    // which scope level owns the clause
 | 
			
		||||
        unsigned            m_num_lits[2];  // number of positive [0] and negative [1] literals. 
 | 
			
		||||
        unsigned            m_num_lits_capacity; // some of the clause literals can be simplified and removed, this field contains the original number of literals (used for GC).
 | 
			
		||||
        unsigned            m_bidx;         // position on the backtracking stack
 | 
			
		||||
        bool                m_ground:1;
 | 
			
		||||
        bool                m_processed:1;  
 | 
			
		||||
        bool                m_indexed:1;
 | 
			
		||||
        bool                m_has_sel_lit:1;
 | 
			
		||||
        justification *     m_justification;
 | 
			
		||||
        set                 m_children;
 | 
			
		||||
        literal             m_lits[0];
 | 
			
		||||
        friend class context;
 | 
			
		||||
 | 
			
		||||
        void set_fields(unsigned num_lits, literal * lits);
 | 
			
		||||
        unsigned get_bidx() const { return m_bidx; }
 | 
			
		||||
        void init(unsigned idx, unsigned time);
 | 
			
		||||
        void update_parents(ptr_buffer<clause> & parents);
 | 
			
		||||
        void set_bidx(unsigned idx) { SASSERT(m_bidx == UINT_MAX); m_bidx = idx; }
 | 
			
		||||
        void add_child(clause * c) { m_children.insert(c); }
 | 
			
		||||
        void del_child(clause * c) { m_children.erase(c); }
 | 
			
		||||
        void set_processed(bool f) { m_processed = f; }
 | 
			
		||||
        void set_indexed(bool f) { m_indexed = f; }
 | 
			
		||||
        void sort_literals();
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Release ownership of the justification.
 | 
			
		||||
        */
 | 
			
		||||
        justification * release_justification() { justification * r = m_justification; m_justification = 0; return r; }
 | 
			
		||||
 | 
			
		||||
        clause(ast_manager & m, unsigned num_lits, literal * lits, justification * p, unsigned scope_lvl);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        static clause * mk(ast_manager & m, unsigned num_lits, literal * lits, justification * p, unsigned scope_lvl);
 | 
			
		||||
        void deallocate(ast_manager & m);
 | 
			
		||||
 | 
			
		||||
        unsigned get_id() const { SASSERT(m_id != UINT_MAX); return m_id; }
 | 
			
		||||
        unsigned get_time() const { return m_time; }
 | 
			
		||||
        unsigned get_symbol_count() const { return m_sym_count; }
 | 
			
		||||
        unsigned get_proof_depth() const { return m_proof_depth; }
 | 
			
		||||
        unsigned get_num_literals() const { return m_num_lits[0] + m_num_lits[1]; }
 | 
			
		||||
        unsigned get_num_literals_capacity() const { return m_num_lits_capacity; }
 | 
			
		||||
        unsigned get_num_pos_literals() const { return m_num_lits[0]; }
 | 
			
		||||
        unsigned get_num_neg_literals() const { return m_num_lits[1]; }
 | 
			
		||||
        unsigned get_depth() const { return m_depth; }
 | 
			
		||||
        unsigned get_const_count() const { return m_const_count; }
 | 
			
		||||
        unsigned get_scope_lvl() const { return m_scope_lvl; }
 | 
			
		||||
        unsigned get_num_vars() const { return m_num_vars; }
 | 
			
		||||
        bool empty() const { return m_num_lits[0] == 0 && m_num_lits[1] == 0; }
 | 
			
		||||
        literal const & get_literal(unsigned idx) const { return m_lits[idx]; }
 | 
			
		||||
        literal & get_literal(unsigned idx) { return m_lits[idx]; }
 | 
			
		||||
        literal * get_literals() const { return const_cast<literal*>(m_lits); }
 | 
			
		||||
        justification * get_justification() const { return m_justification; }
 | 
			
		||||
        bool is_processed() const { return m_processed; }
 | 
			
		||||
        bool is_indexed() const { return m_indexed; }
 | 
			
		||||
        bool is_ground() const { return m_ground; }
 | 
			
		||||
        void select_literal(unsigned idx);
 | 
			
		||||
        bool is_maximal(order & o, literal const & l, unsigned offset = 0, substitution * s = 0) const;
 | 
			
		||||
        bool is_sel_maximal(order & o, literal const & l, unsigned offset = 0, substitution * s = 0) const ;
 | 
			
		||||
        bool is_eligible_for_resolution(order & o, literal const & l, unsigned offset = 0, substitution * s = 0) const;
 | 
			
		||||
        bool is_eligible_for_paramodulation(order & o, literal const & l, unsigned offset = 0, substitution * s = 0) const;
 | 
			
		||||
        bool has_sel_lit() const { return m_has_sel_lit; }
 | 
			
		||||
        void try_to_orient_literals(order & o);
 | 
			
		||||
        void update_lits(ast_manager & m, unsigned num_lits, literal * lits, justification * j);
 | 
			
		||||
 | 
			
		||||
        void display(std::ostream & out, ast_manager & m, bool detailed = false);
 | 
			
		||||
        unsigned hash() const { return m_id; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef ptr_vector<clause> clause_vector;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Clause Statistics (used to build clauses, subsumption, etc).
 | 
			
		||||
    */
 | 
			
		||||
    struct clause_stat : public expr_stat {
 | 
			
		||||
        unsigned m_num_lits[2];
 | 
			
		||||
        clause_stat() {
 | 
			
		||||
            m_num_lits[0] = 0;
 | 
			
		||||
            m_num_lits[1] = 0;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Compute the statistics for a clause with num_lits
 | 
			
		||||
       literals lits, and store the results in stat.
 | 
			
		||||
    */
 | 
			
		||||
    void get_clause_stat(unsigned num_lits, literal * lits, clause_stat & stat);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief A mapping from clause-id's to clauses
 | 
			
		||||
    */
 | 
			
		||||
    class id2clause {
 | 
			
		||||
        ptr_vector<clause> m_clauses;
 | 
			
		||||
    public:
 | 
			
		||||
        void insert(clause * c) { return m_clauses.setx(c->get_id(), c, 0); }
 | 
			
		||||
        void erase(clause * c) { unsigned id = c->get_id(); if (id < m_clauses.size()) m_clauses[id] = 0; }
 | 
			
		||||
        clause * operator()(unsigned id) const { return m_clauses.get(id, 0); }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_CLAUSE_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,58 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_clause_pos_set.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    A set of pairs (clause, index).
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-16.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_CLAUSE_POS_SET_H_
 | 
			
		||||
#define _SPC_CLAUSE_POS_SET_H_
 | 
			
		||||
 | 
			
		||||
#include"hashtable.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    typedef std::pair<clause *, unsigned> clause_pos_pair;
 | 
			
		||||
 | 
			
		||||
    class clause_pos_entry {
 | 
			
		||||
        clause_pos_pair m_data;
 | 
			
		||||
    public:
 | 
			
		||||
        typedef clause_pos_pair data;
 | 
			
		||||
        clause_pos_entry() { m_data.first = 0; }
 | 
			
		||||
        unsigned get_hash() const { return m_data.first->get_id(); }
 | 
			
		||||
        bool is_free() const { return m_data.first == 0; }
 | 
			
		||||
        bool is_deleted() const { return m_data.first == reinterpret_cast<clause *>(1); }
 | 
			
		||||
        bool is_used() const { 
 | 
			
		||||
            return m_data.first != reinterpret_cast<clause *>(0) && m_data.first != reinterpret_cast<clause *>(1);
 | 
			
		||||
        }
 | 
			
		||||
        clause_pos_pair const & get_data() const { return m_data; }
 | 
			
		||||
        clause_pos_pair & get_data() { return m_data; }
 | 
			
		||||
        void set_data(clause_pos_pair const & d) { 
 | 
			
		||||
            SASSERT(d.first != 0 && d.first != reinterpret_cast<clause*>(1));
 | 
			
		||||
            m_data = d; 
 | 
			
		||||
        }
 | 
			
		||||
        void set_hash(unsigned h) { SASSERT(m_data.first->get_id() == h); }
 | 
			
		||||
        void mark_as_deleted() { m_data.first = reinterpret_cast<clause *>(1); }
 | 
			
		||||
        void mark_as_free() { m_data.first = 0; }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    struct clause_pos_pair_hash {
 | 
			
		||||
        unsigned operator()(clause_pos_pair const & p) const { return p.first->get_id(); }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef core_hashtable<clause_pos_entry, clause_pos_pair_hash, default_eq<clause_pos_pair> > clause_pos_set;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_CLAUSE_POS_SET_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,121 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_clause_selection.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Clause Selection
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_clause_selection.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
  
 | 
			
		||||
    const unsigned default_heap_size = 1024;
 | 
			
		||||
 | 
			
		||||
    clause_selection::clause_selection(unsigned num_heaps, clause_eval * const * fs, unsigned * slot_size):
 | 
			
		||||
        m_curr_slot(0),
 | 
			
		||||
        m_counter(0),
 | 
			
		||||
        m_fs(num_heaps, fs) {
 | 
			
		||||
        SASSERT(num_heaps > 0);
 | 
			
		||||
        for (unsigned i = 0; i < num_heaps; i++) {
 | 
			
		||||
            m_heaps.push_back(alloc(heap<lt>, default_heap_size, lt(m_id2clause, *(fs[i]))));
 | 
			
		||||
            SASSERT(slot_size[i] > 0);
 | 
			
		||||
            m_slot_size.push_back(slot_size[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clause_selection::~clause_selection() {
 | 
			
		||||
        std::for_each(m_heaps.begin(), m_heaps.end(), delete_proc<heap<lt> >());
 | 
			
		||||
        std::for_each(m_fs.begin(), m_fs.end(), delete_proc<clause_eval>());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause_selection::reserve(unsigned cid) {
 | 
			
		||||
        unsigned capacity = m_heaps[0]->get_bounds();
 | 
			
		||||
        if (cid >= capacity) {
 | 
			
		||||
            unsigned new_capacity = 2 * cid + 1;
 | 
			
		||||
            SASSERT(cid < new_capacity);
 | 
			
		||||
            ptr_vector<heap<lt> >::iterator it  = m_heaps.begin();
 | 
			
		||||
            ptr_vector<heap<lt> >::iterator end = m_heaps.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                heap<lt> * h = *it;
 | 
			
		||||
                h->reserve(new_capacity);;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clause_selection::reset() {
 | 
			
		||||
        ptr_vector<heap<lt> >::iterator it  = m_heaps.begin();
 | 
			
		||||
        ptr_vector<heap<lt> >::iterator end = m_heaps.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            heap<lt> * h = *it;
 | 
			
		||||
            h->reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void clause_selection::insert(clause * c) {
 | 
			
		||||
        reserve(c->get_id());
 | 
			
		||||
        m_id2clause.insert(c);
 | 
			
		||||
        ptr_vector<heap<lt> >::iterator it  = m_heaps.begin();
 | 
			
		||||
        ptr_vector<heap<lt> >::iterator end = m_heaps.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            heap<lt> * h = *it;
 | 
			
		||||
            h->insert(c->get_id());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void clause_selection::erase(clause * c) {
 | 
			
		||||
        // remark: it is not necessary to remove c from m_id2clause
 | 
			
		||||
        ptr_vector<heap<lt> >::iterator it  = m_heaps.begin();
 | 
			
		||||
        ptr_vector<heap<lt> >::iterator end = m_heaps.end();
 | 
			
		||||
        SASSERT(it != end);
 | 
			
		||||
        if (!(*it)->contains(c->get_id()))
 | 
			
		||||
            return;
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            heap<lt> * h = *it;
 | 
			
		||||
            h->erase(c->get_id());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool clause_selection::empty() const {
 | 
			
		||||
        ptr_vector<heap<lt> >::const_iterator it  = m_heaps.begin();
 | 
			
		||||
        ptr_vector<heap<lt> >::const_iterator end = m_heaps.end();
 | 
			
		||||
        for (; it != end; ++it)
 | 
			
		||||
            if (!(*it)->empty())
 | 
			
		||||
                return false;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    clause * clause_selection::get_best() {
 | 
			
		||||
        heap<lt> * h = m_heaps[m_curr_slot];
 | 
			
		||||
        if (h->empty())
 | 
			
		||||
            return 0;
 | 
			
		||||
        unsigned cid = m_heaps[m_curr_slot]->erase_min();
 | 
			
		||||
        clause * c = m_id2clause(cid);
 | 
			
		||||
        SASSERT(c);
 | 
			
		||||
        // remove clause from the other heaps
 | 
			
		||||
        unsigned num_heaps = m_heaps.size();
 | 
			
		||||
        for (unsigned i = 0; i < num_heaps; i++) {
 | 
			
		||||
            if (m_curr_slot != i)
 | 
			
		||||
                m_heaps[i]->erase(cid);
 | 
			
		||||
        }
 | 
			
		||||
        // remark: it is not necessary to remove c from m_id2clause
 | 
			
		||||
        m_counter++;
 | 
			
		||||
        if (m_counter >= m_slot_size[m_curr_slot]) {
 | 
			
		||||
            m_counter = 0;
 | 
			
		||||
            m_curr_slot++;
 | 
			
		||||
            if (m_curr_slot >= m_slot_size.size()) 
 | 
			
		||||
                m_curr_slot = 0;
 | 
			
		||||
        }
 | 
			
		||||
        return c;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,85 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_clause_selection.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Clause Selection
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_CLAUSE_SELECTION_H_
 | 
			
		||||
#define _SPC_CLAUSE_SELECTION_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"heap.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Abstract functor for evaluating how 'good' a clause is.
 | 
			
		||||
       Smaller values mean better clauses.
 | 
			
		||||
    */
 | 
			
		||||
    struct clause_eval {
 | 
			
		||||
        virtual ~clause_eval() {}
 | 
			
		||||
        virtual unsigned operator()(clause * c) const = 0;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Clause selection heuristic. It supports different priority queues.
 | 
			
		||||
    */
 | 
			
		||||
    class clause_selection {
 | 
			
		||||
        class lt {
 | 
			
		||||
            id2clause &   m_id2clause;
 | 
			
		||||
            clause_eval & m_func;
 | 
			
		||||
        public:
 | 
			
		||||
            lt(id2clause & m, clause_eval & f):
 | 
			
		||||
                m_id2clause(m), m_func(f) {}
 | 
			
		||||
            bool operator()(int cidx1, int cidx2) const {
 | 
			
		||||
                return m_func(m_id2clause(cidx1)) < m_func(m_id2clause(cidx2));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        id2clause                m_id2clause;
 | 
			
		||||
        ptr_vector<heap<lt> >    m_heaps;
 | 
			
		||||
        unsigned_vector          m_slot_size;
 | 
			
		||||
        unsigned                 m_curr_slot;
 | 
			
		||||
        unsigned                 m_counter;
 | 
			
		||||
        ptr_vector<clause_eval>  m_fs;
 | 
			
		||||
        void reserve(unsigned cid);
 | 
			
		||||
    public:
 | 
			
		||||
        clause_selection(unsigned num_heaps, clause_eval * const * fs, unsigned * slots);
 | 
			
		||||
        ~clause_selection();
 | 
			
		||||
        void insert(clause * c);
 | 
			
		||||
        void erase(clause * c);
 | 
			
		||||
        bool empty() const;
 | 
			
		||||
        void reset();
 | 
			
		||||
        clause * get_best();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct symbol_count_clause_eval : public clause_eval {
 | 
			
		||||
        virtual ~symbol_count_clause_eval() {}
 | 
			
		||||
        virtual unsigned operator()(clause * c) const { return c->get_symbol_count(); }
 | 
			
		||||
    };
 | 
			
		||||
     
 | 
			
		||||
    struct time_clause_eval : public clause_eval {
 | 
			
		||||
        virtual ~time_clause_eval() {}
 | 
			
		||||
        virtual unsigned operator()(clause * c) const { return c->get_time(); }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    struct proof_depth_clause_eval : public clause_eval {
 | 
			
		||||
        virtual ~proof_depth_clause_eval() {}
 | 
			
		||||
        virtual unsigned operator()(clause * c) const { return c->get_proof_depth(); }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_CLAUSE_SELECTION_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,504 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_context.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Engine
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_context.h"
 | 
			
		||||
#include"buffer.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
#include"ast_ll_pp.h"
 | 
			
		||||
#include"ast_smt2_pp.h"
 | 
			
		||||
#include"warning.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    context::context(ast_manager & m, order & o, clause_selection & cs, literal_selection & ls, simplifier & s, spc_params & params):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_params(params),
 | 
			
		||||
        m_alloc(m.get_allocator()),
 | 
			
		||||
        m_order(o),
 | 
			
		||||
        m_cls_sel(cs),
 | 
			
		||||
        m_lit_sel(ls),
 | 
			
		||||
        m_simplifier(s),
 | 
			
		||||
        m_time(0),
 | 
			
		||||
        m_scope_lvl(0),
 | 
			
		||||
        m_sem_taut(m),
 | 
			
		||||
        m_asserted_literals(m),
 | 
			
		||||
        m_rewriter(m, s, m_order, m_asserted_literals),
 | 
			
		||||
        m_der(m), 
 | 
			
		||||
        m_subsumption(m, m_asserted_literals, params),
 | 
			
		||||
        m_eq_resolution(m, m_order, m_stats),
 | 
			
		||||
        m_factoring(m, m_order, m_stats),
 | 
			
		||||
        m_superposition(m, m_order, m_stats),
 | 
			
		||||
        m_unsat(0) {
 | 
			
		||||
        m_order.reserve_offsets(3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    context::~context() {
 | 
			
		||||
        reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::reset() {
 | 
			
		||||
        m_cls_sel.reset();
 | 
			
		||||
        m_time      = 0;
 | 
			
		||||
        m_scope_lvl = 0;
 | 
			
		||||
 | 
			
		||||
        if (m_unsat)
 | 
			
		||||
            m_unsat = 0;
 | 
			
		||||
        for (unsigned i = 0; i <= m_scope_lvl; i++) {
 | 
			
		||||
            del_clauses(i);
 | 
			
		||||
            if (i < m_clauses_to_unfreeze.size())
 | 
			
		||||
                m_clauses_to_unfreeze[i].reset();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_asserted_literals.reset();
 | 
			
		||||
        m_rewriter.reset();
 | 
			
		||||
        m_subsumption.reset();
 | 
			
		||||
        m_superposition.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Insert the given clause into the indexes of processed clauses.
 | 
			
		||||
    */
 | 
			
		||||
    void context::insert_index(clause * cls) {
 | 
			
		||||
        TRACE("insert_index", tout << "indexing clause, num_vars: " << cls->get_num_vars() << "\n"; 
 | 
			
		||||
              cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        m_order.reserve_vars(cls->get_num_vars());
 | 
			
		||||
        m_lit_sel(cls);
 | 
			
		||||
        m_asserted_literals.insert(cls);
 | 
			
		||||
        m_rewriter.insert(cls);
 | 
			
		||||
        m_subsumption.insert(cls);
 | 
			
		||||
        m_superposition.insert(cls);
 | 
			
		||||
        cls->set_indexed(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::erase_index(clause * cls) {
 | 
			
		||||
        if (cls->is_indexed()) {
 | 
			
		||||
            m_asserted_literals.erase(cls);
 | 
			
		||||
            m_rewriter.erase(cls);
 | 
			
		||||
            m_subsumption.erase(cls);
 | 
			
		||||
            m_superposition.erase(cls);
 | 
			
		||||
            cls->set_indexed(false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::set_conflict(clause * cls) {
 | 
			
		||||
        SASSERT(cls->get_num_literals() == 0);
 | 
			
		||||
        m_unsat = cls;
 | 
			
		||||
        if (m_params.m_spc_trace) {
 | 
			
		||||
            cls->display(std::cout, m_manager); std::cout << " "; 
 | 
			
		||||
            cls->get_justification()->display(std::cout);
 | 
			
		||||
            std::cout << "\n";
 | 
			
		||||
            std::cout.flush();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::del_clause(clause * cls) {
 | 
			
		||||
        TRACE("context", tout << "deleting clause:\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        m_stats.m_num_del_clause++;
 | 
			
		||||
 | 
			
		||||
        erase_index(cls);
 | 
			
		||||
        if (!cls->is_processed())
 | 
			
		||||
            m_cls_sel.erase(cls);
 | 
			
		||||
 | 
			
		||||
        unsigned scope_lvl = cls->get_scope_lvl();
 | 
			
		||||
        unsigned bidx      = cls->get_bidx();
 | 
			
		||||
        m_clauses_to_delete[scope_lvl][bidx] = 0;
 | 
			
		||||
 | 
			
		||||
        cls->deallocate(m_manager);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::freeze_clause_until(clause * cls, unsigned scope_lvl) {
 | 
			
		||||
        if (cls->get_scope_lvl() >= scope_lvl) {
 | 
			
		||||
            del_clause(cls);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        TRACE("context", tout << "freezing clause until: " << scope_lvl << ":\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        if (scope_lvl >= m_clauses_to_unfreeze.size())
 | 
			
		||||
            m_clauses_to_unfreeze.resize(scope_lvl+1, clause_vector());
 | 
			
		||||
 | 
			
		||||
        erase_index(cls);
 | 
			
		||||
        cls->set_processed(false);
 | 
			
		||||
 | 
			
		||||
        m_clauses_to_unfreeze[scope_lvl].push_back(cls);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::unfreeze_clause(clause * cls) {
 | 
			
		||||
        TRACE("context", tout << "unfreezing clausel: "; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        SASSERT(!cls->is_processed());
 | 
			
		||||
        m_cls_sel.insert(cls);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::init_clause(clause * cls) {
 | 
			
		||||
        m_stats.m_num_mk_clause++;
 | 
			
		||||
 | 
			
		||||
        cls->init(m_cls_id_gen.mk(), m_time);
 | 
			
		||||
        m_time++;
 | 
			
		||||
        unsigned scope_lvl = cls->get_scope_lvl();
 | 
			
		||||
 | 
			
		||||
        if (scope_lvl >= m_clauses_to_delete.size())
 | 
			
		||||
            m_clauses_to_delete.resize(scope_lvl+1, clause_vector());
 | 
			
		||||
        
 | 
			
		||||
        clause_vector & cv = m_clauses_to_delete[scope_lvl];
 | 
			
		||||
        unsigned bidx = cv.size();
 | 
			
		||||
        cv.push_back(cls);
 | 
			
		||||
        cls->set_bidx(bidx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clause * context::mk_clause(unsigned num_lits, literal * lits, justification * p, unsigned scope_lvl) {
 | 
			
		||||
        clause * cls = clause::mk(m_manager, num_lits, lits, p, scope_lvl);
 | 
			
		||||
        init_clause(cls);
 | 
			
		||||
        return cls;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::assert_expr(expr * n, proof * p, unsigned scope_lvl) {
 | 
			
		||||
        TRACE("spc_assert_expr", tout << mk_ismt2_pp(n, m_manager) << "\n";);
 | 
			
		||||
        SASSERT(scope_lvl <= m_scope_lvl);
 | 
			
		||||
        justification_ref ref(m_manager);
 | 
			
		||||
        ref = justification_proof_wrapper::mk(p, m_manager);
 | 
			
		||||
        assert_expr(n, ref, scope_lvl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void invalid_clause(expr * n) {
 | 
			
		||||
        warning_msg("ignoring formula containing an universally quantified boolean variable.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::assert_expr(expr * n, justification * p, unsigned scope_lvl) {
 | 
			
		||||
        SASSERT(scope_lvl <= m_scope_lvl);
 | 
			
		||||
        buffer<literal> lits;
 | 
			
		||||
        if (is_forall(n))
 | 
			
		||||
            n = to_quantifier(n)->get_expr();
 | 
			
		||||
        if (m_manager.is_or(n)) {
 | 
			
		||||
            unsigned num = to_app(n)->get_num_args();
 | 
			
		||||
            for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
                expr * c    = to_app(n)->get_arg(i);
 | 
			
		||||
                bool is_neg = m_manager.is_not(c);
 | 
			
		||||
                if (is_var(c) || (is_neg && is_var(to_app(c)->get_arg(0)))) {
 | 
			
		||||
                    invalid_clause(n);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (is_neg)
 | 
			
		||||
                    lits.push_back(literal(to_app(c)->get_arg(0), true));
 | 
			
		||||
                else 
 | 
			
		||||
                    lits.push_back(literal(c, false));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (m_manager.is_false(n)) {
 | 
			
		||||
            // skip
 | 
			
		||||
        }
 | 
			
		||||
        else if (m_manager.is_not(n)) {
 | 
			
		||||
            if (is_var(to_app(n)->get_arg(0))) {
 | 
			
		||||
                invalid_clause(n);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            lits.push_back(literal(to_app(n)->get_arg(0), true));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            if (is_var(n)) {
 | 
			
		||||
                invalid_clause(n);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            lits.push_back(literal(n, false));
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (trivial(lits.size(), lits.c_ptr()))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        clause * cls = mk_clause(lits.size(), lits.c_ptr(), p, scope_lvl);
 | 
			
		||||
        m_cls_sel.insert(cls);
 | 
			
		||||
        if (cls->get_num_literals() == 0)
 | 
			
		||||
            set_conflict(cls);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if the given clause (set of literals) is trivial.
 | 
			
		||||
       That is, it contains the literal s = s or complementary literals.
 | 
			
		||||
    */
 | 
			
		||||
    bool context::trivial(unsigned num_lits, literal * lits) {
 | 
			
		||||
        SASSERT(m_found_literals.empty());
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal l       = lits[i];
 | 
			
		||||
            if (m_found_literals.contains_neg(l) || l.is_true(m_manager)) {
 | 
			
		||||
                m_found_literals.reset();
 | 
			
		||||
                m_stats.m_num_trivial++;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            m_found_literals.insert(l);
 | 
			
		||||
        }
 | 
			
		||||
        m_found_literals.reset();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool context::trivial(clause * cls) {
 | 
			
		||||
        return trivial(cls->get_num_literals(), cls->get_literals());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Simplify the given clause using the set of processed clauses.
 | 
			
		||||
       Return the simplified clause.
 | 
			
		||||
    */
 | 
			
		||||
    clause * context::simplify(clause * cls) {
 | 
			
		||||
        clause * old_cls = cls;
 | 
			
		||||
        m_der(cls);
 | 
			
		||||
        cls = m_rewriter(old_cls);
 | 
			
		||||
        if (cls != old_cls) {
 | 
			
		||||
            // freeze old clause until simplified clause is deleted.
 | 
			
		||||
            freeze_clause_until(old_cls, cls->get_scope_lvl());
 | 
			
		||||
            init_clause(cls);
 | 
			
		||||
            m_stats.m_num_simplified++;
 | 
			
		||||
        }
 | 
			
		||||
        m_der(cls);
 | 
			
		||||
        return cls;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Use the given clause to simplify the set of processed clauses.
 | 
			
		||||
       
 | 
			
		||||
       \remark: processed clauses that can be simplified, are moved to the
 | 
			
		||||
       set of unprocessed clauses.
 | 
			
		||||
    */
 | 
			
		||||
    void context::simplify_processed(clause * cls) {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if the clause is redundant. 
 | 
			
		||||
    */
 | 
			
		||||
    bool context::redundant(clause * cls) {
 | 
			
		||||
        int r_scope_lvl = -1;
 | 
			
		||||
        if (trivial(cls)) {
 | 
			
		||||
            TRACE("redundant", tout << "clause is trivial:\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            r_scope_lvl = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if (m_sem_taut(cls->get_num_literals(), cls->get_literals())) {
 | 
			
		||||
            TRACE("redundant", tout << "clause is a semantic tautology:\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            r_scope_lvl = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            clause * subsumer = m_subsumption.forward(cls);
 | 
			
		||||
            if (subsumer != 0) {
 | 
			
		||||
                TRACE("redundant", tout << "clause was subsumed: "; cls->display(tout, m_manager);
 | 
			
		||||
                      tout << "\nsubsumer:\n"; subsumer->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
                r_scope_lvl = subsumer->get_scope_lvl();
 | 
			
		||||
                m_stats.m_num_subsumed++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (r_scope_lvl >= 0) {
 | 
			
		||||
            m_stats.m_num_redundant++;
 | 
			
		||||
            TRACE("spc_saturate", tout << "clause is redundant until level: " << r_scope_lvl << " ...\n";);
 | 
			
		||||
            freeze_clause_until(cls, r_scope_lvl);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Process a newly generated clause.
 | 
			
		||||
    */
 | 
			
		||||
    void context::process_new_clause(clause * cls) {
 | 
			
		||||
        if (cls) {
 | 
			
		||||
            SASSERT(cls->get_justification() != 0);
 | 
			
		||||
            init_clause(cls);
 | 
			
		||||
            if (trivial(cls)) {
 | 
			
		||||
                del_clause(cls);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            cls = simplify(cls);
 | 
			
		||||
            if (trivial(cls)) {
 | 
			
		||||
                del_clause(cls);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // if (!redundant(cls)) {
 | 
			
		||||
            m_cls_sel.insert(cls);
 | 
			
		||||
            if (cls->get_num_literals() == 0)
 | 
			
		||||
                set_conflict(cls);
 | 
			
		||||
            // }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Apply superposition (left&right), resolution, (equality) factoring, and equality resolution
 | 
			
		||||
       with the given clause and the set of processed clauses.
 | 
			
		||||
    */
 | 
			
		||||
    void context::generate(clause * cls) {
 | 
			
		||||
        m_new_clauses.reset();
 | 
			
		||||
        m_eq_resolution(cls, m_new_clauses);
 | 
			
		||||
        m_factoring(cls, m_new_clauses);
 | 
			
		||||
        m_superposition(cls, m_new_clauses);
 | 
			
		||||
 | 
			
		||||
        ptr_vector<clause>::iterator it  = m_new_clauses.begin();
 | 
			
		||||
        ptr_vector<clause>::iterator end = m_new_clauses.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            TRACE("spc_generate", tout << "new generated clause:\n"; (*it)->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            process_new_clause(*it);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::saturate(unsigned threshold) {
 | 
			
		||||
        if (inconsistent())
 | 
			
		||||
            return;
 | 
			
		||||
        TRACE("spc_saturate", tout << "initial state:\n"; display(tout););
 | 
			
		||||
        unsigned i = 0;
 | 
			
		||||
        ptr_buffer<clause> to_simplify;
 | 
			
		||||
        while (i < threshold && !processed_all()) {
 | 
			
		||||
            i++;
 | 
			
		||||
            m_stats.m_num_processed++;
 | 
			
		||||
            clause * cls = m_cls_sel.get_best();
 | 
			
		||||
            if (m_params.m_spc_trace) {
 | 
			
		||||
                cls->display(std::cout, m_manager); std::cout << " "; 
 | 
			
		||||
                cls->get_justification()->display(std::cout);
 | 
			
		||||
                std::cout << "\n";
 | 
			
		||||
                std::cout.flush();
 | 
			
		||||
            }
 | 
			
		||||
            cls->set_processed(true);
 | 
			
		||||
            TRACE("spc_saturate", tout << "get best: "; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            cls = simplify(cls);
 | 
			
		||||
            
 | 
			
		||||
            TRACE("spc_saturate", tout << "clause after simplification: "; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            if (redundant(cls))
 | 
			
		||||
                continue;
 | 
			
		||||
            if (cls->empty()) {
 | 
			
		||||
                set_conflict(cls);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            cls->try_to_orient_literals(m_order);
 | 
			
		||||
            simplify_processed(cls);
 | 
			
		||||
            insert_index(cls);
 | 
			
		||||
            generate(cls);
 | 
			
		||||
            if (inconsistent())
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TRACE("spc_saturate", tout << "final state:\n"; display(tout););
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
        IF_VERBOSE(10000, 
 | 
			
		||||
                   display(std::cout););
 | 
			
		||||
        display_statistics(std::cout);
 | 
			
		||||
        if (m_unsat && m_manager.fine_grain_proofs()) {
 | 
			
		||||
            std::cout << mk_ll_pp(m_unsat->get_justification()->get_proof(), m_manager);
 | 
			
		||||
        }
 | 
			
		||||
#endif 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::push_scope() {
 | 
			
		||||
        m_scope_lvl++;
 | 
			
		||||
        m_time_trail.push_back(m_time);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::del_clauses(unsigned scope_lvl) {
 | 
			
		||||
        if (scope_lvl < m_clauses_to_delete.size()) {
 | 
			
		||||
            clause_vector & cv = m_clauses_to_delete[m_scope_lvl];
 | 
			
		||||
            clause_vector::iterator it  = cv.begin();
 | 
			
		||||
            clause_vector::iterator end = cv.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                clause * cls = *it;
 | 
			
		||||
                if (cls)
 | 
			
		||||
                    del_clause(cls);
 | 
			
		||||
            }
 | 
			
		||||
            cv.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::unfreeze_clauses(unsigned scope_lvl) {
 | 
			
		||||
        if (scope_lvl < m_clauses_to_unfreeze.size()) {
 | 
			
		||||
            clause_vector & cv = m_clauses_to_unfreeze[m_scope_lvl];
 | 
			
		||||
            clause_vector::iterator it  = cv.begin();
 | 
			
		||||
            clause_vector::iterator end = cv.end();
 | 
			
		||||
            for (; it != end; ++it)
 | 
			
		||||
                unfreeze_clause(*it);
 | 
			
		||||
            cv.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::pop_scope(unsigned num_scopes) {
 | 
			
		||||
        SASSERT(num_scopes >= m_scope_lvl);
 | 
			
		||||
        unsigned new_lvl = m_scope_lvl - num_scopes;
 | 
			
		||||
        m_time = m_time_trail[new_lvl];
 | 
			
		||||
        m_time_trail.shrink(new_lvl);
 | 
			
		||||
 | 
			
		||||
        if (m_unsat && new_lvl < m_unsat->get_scope_lvl()) 
 | 
			
		||||
            m_unsat = 0;
 | 
			
		||||
        
 | 
			
		||||
        while (m_scope_lvl > new_lvl) {
 | 
			
		||||
            del_clauses(m_scope_lvl);
 | 
			
		||||
            unfreeze_clauses(m_scope_lvl);
 | 
			
		||||
            m_scope_lvl --;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::display(std::ostream & out, vector<clause_vector> const & cvs, unsigned scope_lvl, bool frozen) const {
 | 
			
		||||
        if (scope_lvl < cvs.size()) {
 | 
			
		||||
            bool first = true;
 | 
			
		||||
            clause_vector const & cv = cvs[scope_lvl];
 | 
			
		||||
            clause_vector::const_iterator it  = cv.begin();
 | 
			
		||||
            clause_vector::const_iterator end = cv.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                clause * cls = *it;
 | 
			
		||||
                if (cls) {
 | 
			
		||||
                    if (first) {
 | 
			
		||||
                        out << "level " << scope_lvl << ":\n";
 | 
			
		||||
                        first = false;
 | 
			
		||||
                    }
 | 
			
		||||
                    cls->display(out, m_manager);
 | 
			
		||||
                    if (frozen)
 | 
			
		||||
                        out << " [frozen]";
 | 
			
		||||
                    out << "\n";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void context::display(std::ostream & out) const {
 | 
			
		||||
        for (unsigned i = 0; i <= m_scope_lvl; i++) {
 | 
			
		||||
            display(out, m_clauses_to_delete, i, false);
 | 
			
		||||
            display(out, m_clauses_to_unfreeze, i, true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::display_statistics(std::ostream & out) const {
 | 
			
		||||
        m_stats.display(out);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   Generate new clauses
 | 
			
		||||
 | 
			
		||||
   5) Object equality resolution 1
 | 
			
		||||
   
 | 
			
		||||
   (R or X = i)  
 | 
			
		||||
   ==>
 | 
			
		||||
   sigma(R)
 | 
			
		||||
 | 
			
		||||
   sigma = { X -> j }
 | 
			
		||||
   where i and j are distinct objects
 | 
			
		||||
   sigma(X = i) is not smaller or equal than any other literal in the clause
 | 
			
		||||
 | 
			
		||||
   6) Object equality resolution 2
 | 
			
		||||
   
 | 
			
		||||
   (R or X = Y)
 | 
			
		||||
   ==>
 | 
			
		||||
   sigma(R)
 | 
			
		||||
 | 
			
		||||
   sigma = { X -> i, Y -> j }
 | 
			
		||||
   For every pair of distinct objects i and j
 | 
			
		||||
   sigma(X = Y) is not smaller or equal than any other literal in the clause
 | 
			
		||||
   
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,122 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_context.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Engine
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_CONTEXT_H_
 | 
			
		||||
#define _SPC_CONTEXT_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_params.h"
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"spc_clause_selection.h"
 | 
			
		||||
#include"spc_literal_selection.h"
 | 
			
		||||
#include"spc_semantic_tautology.h"
 | 
			
		||||
#include"spc_rewriter.h"
 | 
			
		||||
#include"spc_asserted_literals.h"
 | 
			
		||||
#include"spc_subsumption.h"
 | 
			
		||||
#include"spc_eq_resolution.h"
 | 
			
		||||
#include"spc_factoring.h"
 | 
			
		||||
#include"spc_superposition.h"
 | 
			
		||||
#include"spc_statistics.h"
 | 
			
		||||
#include"spc_der.h"
 | 
			
		||||
#include"substitution_tree.h"
 | 
			
		||||
#include"order.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Logical context of the superposition calculus engine.
 | 
			
		||||
    */
 | 
			
		||||
    class context {
 | 
			
		||||
    public:
 | 
			
		||||
        statistics                  m_stats;
 | 
			
		||||
    protected:
 | 
			
		||||
        typedef clause::set clause_set;
 | 
			
		||||
        
 | 
			
		||||
        ast_manager &               m_manager;
 | 
			
		||||
        spc_params &                m_params;
 | 
			
		||||
        small_object_allocator &    m_alloc;
 | 
			
		||||
        order &                     m_order;
 | 
			
		||||
        clause_selection &          m_cls_sel;
 | 
			
		||||
        literal_selection &         m_lit_sel;
 | 
			
		||||
        simplifier &                m_simplifier;
 | 
			
		||||
        unsigned                    m_time;
 | 
			
		||||
        unsigned                    m_scope_lvl;
 | 
			
		||||
        id_gen                      m_cls_id_gen;
 | 
			
		||||
        found_literals              m_found_literals;
 | 
			
		||||
        semantic_tautology          m_sem_taut;
 | 
			
		||||
        asserted_literals           m_asserted_literals;
 | 
			
		||||
        rewriter                    m_rewriter;
 | 
			
		||||
        der                         m_der;
 | 
			
		||||
        subsumption                 m_subsumption;
 | 
			
		||||
        eq_resolution               m_eq_resolution;
 | 
			
		||||
        factoring                   m_factoring;
 | 
			
		||||
        superposition               m_superposition;
 | 
			
		||||
        vector<clause_vector>       m_clauses_to_unfreeze;
 | 
			
		||||
        vector<clause_vector>       m_clauses_to_delete;
 | 
			
		||||
        unsigned_vector             m_time_trail;
 | 
			
		||||
        clause *                    m_unsat;
 | 
			
		||||
        ptr_vector<clause>          m_new_clauses;
 | 
			
		||||
 | 
			
		||||
        void insert_index(clause * cls);
 | 
			
		||||
        void erase_index(clause * cls);
 | 
			
		||||
 | 
			
		||||
        void init_clause(clause * cls);
 | 
			
		||||
        clause * mk_clause(unsigned num_lits, literal * lits, justification * p, unsigned scope_lvl);
 | 
			
		||||
 | 
			
		||||
        void del_clause(clause * cls);
 | 
			
		||||
        void del_clauses(unsigned scope_lvl);
 | 
			
		||||
 | 
			
		||||
        void freeze_clause_until(clause * cls, unsigned scope_lvl);
 | 
			
		||||
        void unfreeze_clause(clause * cls);
 | 
			
		||||
        void unfreeze_clauses(unsigned scope_lvl);
 | 
			
		||||
 | 
			
		||||
        bool trivial(unsigned num_lits, literal * lits);
 | 
			
		||||
        bool trivial(clause * cls);
 | 
			
		||||
        clause * simplify(clause * cls);
 | 
			
		||||
        void simplify_processed(clause * cls);
 | 
			
		||||
        bool redundant(clause * cls);
 | 
			
		||||
        void generate(clause * cls);
 | 
			
		||||
        void process_new_clause(clause * cls);
 | 
			
		||||
 | 
			
		||||
        void display(std::ostream & out, vector<clause_vector> const & cvs, unsigned scope_lvl, bool frozen) const;
 | 
			
		||||
        
 | 
			
		||||
        void set_conflict(clause * cls);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        context(ast_manager & m, order & o, clause_selection & cs, literal_selection & ls, simplifier & s, spc_params & params);
 | 
			
		||||
        ~context();
 | 
			
		||||
        
 | 
			
		||||
        simplifier & get_simplifier() { return m_simplifier; }
 | 
			
		||||
        order & get_order() { return m_order; }
 | 
			
		||||
        ast_manager & get_manager() { return m_manager; }
 | 
			
		||||
 | 
			
		||||
        unsigned get_scope_lvl() const { return m_scope_lvl; }
 | 
			
		||||
 | 
			
		||||
        void assert_expr(expr * n, proof * p, unsigned scope_lvl = 0);
 | 
			
		||||
        void assert_expr(expr * n, justification * p, unsigned scope_lvl = 0);
 | 
			
		||||
        void saturate(unsigned threshold);
 | 
			
		||||
        bool inconsistent() const { return m_unsat != 0; }
 | 
			
		||||
        bool processed_all() const { return m_cls_sel.empty(); }
 | 
			
		||||
        void push_scope();
 | 
			
		||||
        void pop_scope(unsigned num_scopes);
 | 
			
		||||
        void reset();
 | 
			
		||||
        void display(std::ostream & out) const;
 | 
			
		||||
        void display_statistics(std::ostream & out) const;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_CONTEXT_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,135 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_decl_plugin.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-12.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_decl_plugin.h"
 | 
			
		||||
 | 
			
		||||
std::ostream & operator<<(std::ostream & out, spc_op_kind k) {
 | 
			
		||||
    switch (k) {
 | 
			
		||||
    case PR_DEMODULATION:              out << "demod"; break;
 | 
			
		||||
    case PR_SPC_REWRITE:               out << "rewrite"; break;
 | 
			
		||||
    case PR_SPC_RESOLUTION:            out << "res"; break;
 | 
			
		||||
    case PR_SUPERPOSITION:             out << "sup"; break;
 | 
			
		||||
    case PR_EQUALITY_RESOLUTION:       out << "eq_res"; break;
 | 
			
		||||
    case PR_FACTORING:                 out << "fact"; break;
 | 
			
		||||
    case PR_SPC_DER:                   out << "der"; break;
 | 
			
		||||
    case PR_SPC_ASSERTED:              out << "asserted"; break;
 | 
			
		||||
    default:                           out << "unknown"; break;
 | 
			
		||||
    }
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
spc_decl_plugin::spc_decl_plugin() :
 | 
			
		||||
    m_demodulation("demod"),
 | 
			
		||||
    m_spc_rewrite("sp-rw"),
 | 
			
		||||
    m_spc_resolution("sp-res"),
 | 
			
		||||
    m_superposition("sp"),
 | 
			
		||||
    m_equality_resolution("eq-res"),
 | 
			
		||||
    m_factoring("fact"),
 | 
			
		||||
    m_spc_der("spc-der") {
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
spc_decl_plugin::~spc_decl_plugin() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sort * spc_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const* parameters) {
 | 
			
		||||
    UNREACHABLE();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func_decl * spc_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, 
 | 
			
		||||
                                          unsigned arity, sort * const * domain, sort * range) {
 | 
			
		||||
    
 | 
			
		||||
#define MK_PROOF(SYM) m_manager->mk_func_decl(SYM, arity, domain, m_manager->mk_proof_sort(), func_decl_info(m_family_id, k))
 | 
			
		||||
    
 | 
			
		||||
    SASSERT(num_parameters == 0);
 | 
			
		||||
    switch (k) {
 | 
			
		||||
        /*
 | 
			
		||||
          #1: (forall (x) (= t[x] s[x]))
 | 
			
		||||
          [demod #1] (= t[a] s[a])
 | 
			
		||||
        */
 | 
			
		||||
    case PR_DEMODULATION:           return MK_PROOF(m_demodulation);
 | 
			
		||||
        /*
 | 
			
		||||
          Justifies a rewriting (simplification step) in the superposition engine.
 | 
			
		||||
          It has n+1 antecedents. The first antecedent is the clause being simplified.
 | 
			
		||||
          The other antecedents are demodulators.
 | 
			
		||||
          The consequent is the simplied clause.
 | 
			
		||||
        */
 | 
			
		||||
    case PR_SPC_REWRITE:            return MK_PROOF(m_spc_rewrite);
 | 
			
		||||
        /*
 | 
			
		||||
          Resolution proof:
 | 
			
		||||
 | 
			
		||||
          #1: (or C l)
 | 
			
		||||
          #2: (or D (not l'))
 | 
			
		||||
          [sp-res #1 #2]: sigma(or C D)
 | 
			
		||||
 | 
			
		||||
          where sigma is the mgu of l and l'
 | 
			
		||||
 | 
			
		||||
        */
 | 
			
		||||
    case PR_SPC_RESOLUTION:         return MK_PROOF(m_spc_resolution);
 | 
			
		||||
        /*
 | 
			
		||||
          Superposition proof:
 | 
			
		||||
 | 
			
		||||
          #1: (or (= s t) R)
 | 
			
		||||
          #2: D[u]
 | 
			
		||||
          [sp #1 #2]: sigma(or R D[t])
 | 
			
		||||
 | 
			
		||||
          where sigma is the mgu(u, s)
 | 
			
		||||
        */
 | 
			
		||||
    case PR_SUPERPOSITION:          return MK_PROOF(m_superposition);
 | 
			
		||||
        /*
 | 
			
		||||
          Equality resolution proof:
 | 
			
		||||
 | 
			
		||||
          #1: (or (not (= s t)) R)
 | 
			
		||||
          [eq-res #1]: sigma R
 | 
			
		||||
 | 
			
		||||
          where sigma is the mgu of s and t.
 | 
			
		||||
        */
 | 
			
		||||
    case PR_EQUALITY_RESOLUTION:    return MK_PROOF(m_equality_resolution);
 | 
			
		||||
        /*
 | 
			
		||||
          Proof object for factoring and equality-factoring:
 | 
			
		||||
 | 
			
		||||
          #1: (or P[t] P[s] R)
 | 
			
		||||
          [fact #1]: sigma(or P[t] R)
 | 
			
		||||
 | 
			
		||||
          where sigma is the mgu(t,s)
 | 
			
		||||
 | 
			
		||||
          #1: (or (= s t) (= u v) R)
 | 
			
		||||
          [fact #1]: sigma(or (not (= t v)) (= u v) R)
 | 
			
		||||
 | 
			
		||||
          where sigma = mgu(s, u)
 | 
			
		||||
        */
 | 
			
		||||
    case PR_FACTORING:              return MK_PROOF(m_factoring);
 | 
			
		||||
        /*
 | 
			
		||||
          Proof object for destructive equality resolution:
 | 
			
		||||
 | 
			
		||||
          #1: (or (not (= x t)) C[x])
 | 
			
		||||
          [spc-der #1]: C[t]
 | 
			
		||||
 | 
			
		||||
          t does not contain x.
 | 
			
		||||
          
 | 
			
		||||
          Several variables may be eliminated simultaneously.
 | 
			
		||||
        */
 | 
			
		||||
    case PR_SPC_DER:                return MK_PROOF(m_spc_der);
 | 
			
		||||
    default:
 | 
			
		||||
        UNREACHABLE();
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,61 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_decl_plugin.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Proof declarations for Superposition Calculus Engine.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-12.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_DECL_PLUGIN_H_
 | 
			
		||||
#define _SPC_DECL_PLUGIN_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
 | 
			
		||||
enum spc_op_kind {
 | 
			
		||||
    PR_DEMODULATION,
 | 
			
		||||
    PR_SPC_REWRITE,
 | 
			
		||||
    PR_SPC_RESOLUTION,
 | 
			
		||||
    PR_SUPERPOSITION,
 | 
			
		||||
    PR_EQUALITY_RESOLUTION,
 | 
			
		||||
    PR_FACTORING,
 | 
			
		||||
    PR_SPC_DER,
 | 
			
		||||
    PR_SPC_ASSERTED,
 | 
			
		||||
    PR_SPC_LAST_ID
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::ostream & operator<<(std::ostream & out, spc_op_kind k);
 | 
			
		||||
  
 | 
			
		||||
class spc_decl_plugin : public decl_plugin {
 | 
			
		||||
    symbol m_demodulation;
 | 
			
		||||
    symbol m_spc_rewrite;
 | 
			
		||||
    symbol m_spc_resolution;
 | 
			
		||||
    symbol m_superposition;
 | 
			
		||||
    symbol m_equality_resolution;
 | 
			
		||||
    symbol m_factoring;
 | 
			
		||||
    symbol m_spc_der;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    spc_decl_plugin();
 | 
			
		||||
    
 | 
			
		||||
    virtual ~spc_decl_plugin();
 | 
			
		||||
 | 
			
		||||
    virtual decl_plugin * mk_fresh() { return alloc(spc_decl_plugin); }
 | 
			
		||||
    
 | 
			
		||||
    virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const* parameters);
 | 
			
		||||
    
 | 
			
		||||
    virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, 
 | 
			
		||||
                                     unsigned arity, sort * const * domain, sort * range);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_DECL_PLUGIN_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,80 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_der.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-17.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_der.h"
 | 
			
		||||
#include"occurs.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    der::der(ast_manager & m):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_subst(m),
 | 
			
		||||
        m_spc_fid(m.get_family_id("spc")) {
 | 
			
		||||
        m_subst.reserve_offsets(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void der::apply(clause * cls, unsigned j, expr * lhs, expr * rhs) {
 | 
			
		||||
        TRACE("der", tout << "applying der at: " << j << "\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        m_subst.reserve_vars(cls->get_num_vars());
 | 
			
		||||
        m_subst.reset();
 | 
			
		||||
        m_subst.insert(expr_offset(lhs, 0), expr_offset(rhs, 0));
 | 
			
		||||
        literal_buffer new_lits(m_manager);
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            if (i != j) {
 | 
			
		||||
                literal const & l = cls->get_literal(i);
 | 
			
		||||
                expr_ref new_atom(m_manager);
 | 
			
		||||
                m_subst.apply(l.atom(), new_atom);
 | 
			
		||||
                new_lits.push_back(literal(new_atom, l.sign()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        justification * js = mk_der_justification(m_manager, m_spc_fid, cls->get_justification(), new_lits.size(), new_lits.c_ptr());
 | 
			
		||||
        cls->update_lits(m_manager, new_lits.size(), new_lits.c_ptr(), js);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool der::apply(clause * cls) {
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = cls->get_literal(i);
 | 
			
		||||
            if (l.sign() && m_manager.is_eq(l.atom())) {
 | 
			
		||||
                expr * lhs = l.lhs();
 | 
			
		||||
                expr * rhs = l.rhs();
 | 
			
		||||
                if (is_var(lhs) && !occurs(lhs, rhs)) {
 | 
			
		||||
                    apply(cls, i, lhs, rhs);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                else if (is_var(rhs) && !occurs(rhs, lhs)) {
 | 
			
		||||
                    apply(cls, i, rhs, lhs);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Clause cls is destructively updated.
 | 
			
		||||
    */
 | 
			
		||||
    void der::operator()(clause * cls) {
 | 
			
		||||
        while(apply(cls))
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,52 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_der.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-17.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_DER_H_
 | 
			
		||||
#define _SPC_DER_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Functor for applying destructive equality resolution.
 | 
			
		||||
       This is similar to the Functor in der.h, but this one applies
 | 
			
		||||
       the simplification on clauses instead of ast's.
 | 
			
		||||
 | 
			
		||||
       x != s or R
 | 
			
		||||
       ==>
 | 
			
		||||
       sigma(R)
 | 
			
		||||
       
 | 
			
		||||
       where
 | 
			
		||||
       sigma = mgu(x, s)
 | 
			
		||||
    */
 | 
			
		||||
    class der { 
 | 
			
		||||
        ast_manager &   m_manager;
 | 
			
		||||
        substitution    m_subst;
 | 
			
		||||
        unsigned_vector m_to_keep;
 | 
			
		||||
        family_id       m_spc_fid;
 | 
			
		||||
        void apply(clause * cls, unsigned j, expr * lhs, expr * rhs);
 | 
			
		||||
        bool apply(clause * cls);
 | 
			
		||||
    public:
 | 
			
		||||
        der(ast_manager & m);
 | 
			
		||||
        void operator()(clause * cls);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_DER_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,44 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_eq_resolution.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_eq_resolution.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Apply equality resolution rule on the given clause.
 | 
			
		||||
       Store the produced clauses in new_clauses.
 | 
			
		||||
    */
 | 
			
		||||
    void eq_resolution::operator()(clause * cls, ptr_vector<clause> & new_clauses) {
 | 
			
		||||
        m_subst.reserve_vars(cls->get_num_vars());
 | 
			
		||||
        unsigned num = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            literal const & l = cls->get_literal(i);
 | 
			
		||||
            expr * atom = l.atom();
 | 
			
		||||
            if (l.sign() && m_manager.is_eq(atom)) {
 | 
			
		||||
                expr * lhs = to_app(atom)->get_arg(0);
 | 
			
		||||
                expr * rhs = to_app(atom)->get_arg(1);
 | 
			
		||||
                m_subst.reset();
 | 
			
		||||
                if (m_unifier(lhs, rhs, m_subst, false) && cls->is_eligible_for_resolution(m_order, l, 0, &m_subst)) {
 | 
			
		||||
                    m_stats.m_num_eq_resolution++;
 | 
			
		||||
                    new_clauses.push_back(mk_result(cls, i));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,50 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_eq_resolution.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_EQ_RESOLUTION_H_
 | 
			
		||||
#define _SPC_EQ_RESOLUTION_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_unary_inference.h"
 | 
			
		||||
#include"spc_statistics.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Functor for applying equality resolution.
 | 
			
		||||
 | 
			
		||||
       s != t or R
 | 
			
		||||
       ==>
 | 
			
		||||
       sigma(R)
 | 
			
		||||
    */
 | 
			
		||||
    class eq_resolution : public unary_inference { 
 | 
			
		||||
    protected:
 | 
			
		||||
        statistics & m_stats;
 | 
			
		||||
        family_id    m_spc_fid;
 | 
			
		||||
        virtual justification * mk_justification(justification * parent, unsigned num_lits, literal * new_lits) {
 | 
			
		||||
            return mk_eq_res_justification(m_manager, m_spc_fid, parent, num_lits, new_lits);
 | 
			
		||||
        }
 | 
			
		||||
    public:
 | 
			
		||||
        eq_resolution(ast_manager & m, order & ord, statistics & stats):unary_inference(m, ord), m_stats(stats), m_spc_fid(m.get_family_id("spc")) {}
 | 
			
		||||
        virtual ~eq_resolution() {}
 | 
			
		||||
        void operator()(clause * cls, ptr_vector<clause> & new_clauses);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_EQ_RESOLUTION_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,156 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_factoring.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_factoring.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Create a new clause by removing literal at position j, apply substitution m_subst,
 | 
			
		||||
       and adding a disequality lhs != rhs.
 | 
			
		||||
    */
 | 
			
		||||
    clause * factoring::mk_eq_fact_result(clause * cls, unsigned j, expr * lhs, expr * rhs) {
 | 
			
		||||
        sbuffer<literal> new_literals;
 | 
			
		||||
 | 
			
		||||
        expr_ref new_eq(m_manager.mk_eq(lhs, rhs), m_manager);
 | 
			
		||||
        expr_ref new_eq_after_subst(m_manager);
 | 
			
		||||
        m_subst.apply(new_eq, new_eq_after_subst);
 | 
			
		||||
        new_literals.push_back(literal(new_eq_after_subst, true));
 | 
			
		||||
 | 
			
		||||
        unsigned num = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            if (i != j) {
 | 
			
		||||
                literal const & l = cls->get_literal(i);
 | 
			
		||||
                expr_ref new_atom(m_manager);
 | 
			
		||||
                m_subst.apply(l.atom(), new_atom);
 | 
			
		||||
                new_literals.push_back(literal(new_atom, l.sign()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        justification * js = mk_factoring_justification(m_manager, m_spc_fid, cls->get_justification(), new_literals.size(), 
 | 
			
		||||
                                                        new_literals.c_ptr());
 | 
			
		||||
        clause * new_cls = clause::mk(m_manager, new_literals.size(), new_literals.c_ptr(), js, cls->get_scope_lvl());
 | 
			
		||||
        m_stats.m_num_eq_factoring++;
 | 
			
		||||
        return new_cls;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Try to apply equality factoring using the eq literal stored at position j.
 | 
			
		||||
       Assume lhs and rhs are the left hand side of this equality (they may be swapped).
 | 
			
		||||
    */
 | 
			
		||||
    void factoring::try_eq_factoring(clause * cls, unsigned j, expr * lhs, expr * rhs, ptr_vector<clause> & new_clauses) {
 | 
			
		||||
        literal const & l1 = cls->get_literal(j);
 | 
			
		||||
        sort * s = m_manager.get_sort(lhs);
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l2 = cls->get_literal(i);
 | 
			
		||||
            if (i == j)
 | 
			
		||||
                continue;
 | 
			
		||||
            if (l2.sign())
 | 
			
		||||
                continue;
 | 
			
		||||
            expr * atom = l2.atom();
 | 
			
		||||
            if (!m_manager.is_eq(atom))
 | 
			
		||||
                continue;
 | 
			
		||||
            expr * lhs2 = to_app(atom)->get_arg(0);
 | 
			
		||||
            if (m_manager.get_sort(lhs2) != s)
 | 
			
		||||
                continue;
 | 
			
		||||
            expr * rhs2 = to_app(atom)->get_arg(1);
 | 
			
		||||
            m_subst.reset();
 | 
			
		||||
            if (m_unifier(lhs, lhs2, m_subst, false) && 
 | 
			
		||||
                (l1.is_oriented() || !m_order.greater(rhs, lhs, &m_subst)) && 
 | 
			
		||||
                cls->is_eligible_for_paramodulation(m_order, l1, 0, &m_subst)) {
 | 
			
		||||
                new_clauses.push_back(mk_eq_fact_result(cls, j, rhs, rhs2));
 | 
			
		||||
            }
 | 
			
		||||
            m_subst.reset();
 | 
			
		||||
            if (m_unifier(lhs, rhs2, m_subst, false) &&
 | 
			
		||||
                (l1.is_oriented() || !m_order.greater(rhs, lhs, &m_subst)) && 
 | 
			
		||||
                cls->is_eligible_for_paramodulation(m_order, l1, 0, &m_subst)) {
 | 
			
		||||
                new_clauses.push_back(mk_eq_fact_result(cls, j, rhs, lhs2));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Try to apply equality factoring using the eq literal stored at position i.
 | 
			
		||||
    */
 | 
			
		||||
    void factoring::try_eq_factoring(clause * cls, unsigned i, ptr_vector<clause> & new_clauses) {
 | 
			
		||||
        if (cls->get_num_pos_literals() <= 1)
 | 
			
		||||
            return;
 | 
			
		||||
        literal const & l = cls->get_literal(i);
 | 
			
		||||
        app * eq   = to_app(l.atom());
 | 
			
		||||
        expr * lhs = eq->get_arg(0);
 | 
			
		||||
        expr * rhs = eq->get_arg(1);
 | 
			
		||||
        if (l.is_oriented()) {
 | 
			
		||||
            if (!l.is_left()) 
 | 
			
		||||
                std::swap(lhs, rhs);
 | 
			
		||||
            try_eq_factoring(cls, i, lhs, rhs, new_clauses);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            try_eq_factoring(cls, i, lhs, rhs, new_clauses);
 | 
			
		||||
            try_eq_factoring(cls, i, rhs, lhs, new_clauses);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Try to apply (ordering) factoring rule.
 | 
			
		||||
    */
 | 
			
		||||
    void factoring::try_factoring(clause * cls, unsigned j, ptr_vector<clause> & new_clauses) {
 | 
			
		||||
        literal const & l1 = cls->get_literal(j);
 | 
			
		||||
        if (l1.sign() && cls->get_num_neg_literals() <= 1)
 | 
			
		||||
            return;
 | 
			
		||||
        if (!l1.sign() && cls->get_num_pos_literals() <= 1)
 | 
			
		||||
            return;
 | 
			
		||||
        unsigned num = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            if (i == j)
 | 
			
		||||
                continue;
 | 
			
		||||
            literal const & l2 = cls->get_literal(i);
 | 
			
		||||
            if (l1.sign() != l2.sign())
 | 
			
		||||
                continue;
 | 
			
		||||
            m_subst.reset();
 | 
			
		||||
            if (m_unifier(l1.atom(), l2.atom(), m_subst, false) &&
 | 
			
		||||
                cls->is_eligible_for_resolution(m_order, l1, 0, &m_subst)) {
 | 
			
		||||
                new_clauses.push_back(mk_result(cls, i));
 | 
			
		||||
                m_stats.m_num_factoring++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Apply factoring rule on the given clause.
 | 
			
		||||
       Store the produced clauses into new_clauses.
 | 
			
		||||
    */
 | 
			
		||||
    void factoring::operator()(clause * cls, ptr_vector<clause> & new_clauses) {
 | 
			
		||||
        if (cls->get_num_pos_literals() <= 1 && cls->get_num_neg_literals() <= 1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        m_subst.reserve_vars(cls->get_num_vars());
 | 
			
		||||
        unsigned num = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            literal const & l = cls->get_literal(i);
 | 
			
		||||
            expr * atom = l.atom();
 | 
			
		||||
            // remark: if the clause has selected literals then the literal will not be eligible
 | 
			
		||||
            // for paramodulation and eq_resolution will not be applied.
 | 
			
		||||
            if (!l.sign() && m_manager.is_eq(atom) && !cls->has_sel_lit()) 
 | 
			
		||||
                try_eq_factoring(cls, i, new_clauses);
 | 
			
		||||
            if (l.is_selected() || !cls->has_sel_lit())
 | 
			
		||||
                try_factoring(cls, i, new_clauses);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,66 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_factoring.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_FACTORING_H_
 | 
			
		||||
#define _SPC_FACTORING_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_unary_inference.h"
 | 
			
		||||
#include"spc_statistics.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Functor for applying factoring.
 | 
			
		||||
 | 
			
		||||
       - Equality Factoring
 | 
			
		||||
       s = t or u = v or R
 | 
			
		||||
       ==>
 | 
			
		||||
       sigma(t != v or u = v or R)
 | 
			
		||||
       
 | 
			
		||||
       sigma = mgu(s, u)
 | 
			
		||||
       sigma(s) not greater than sigma(t)
 | 
			
		||||
       sigma(s = t) is eligible for paramodulation.
 | 
			
		||||
       
 | 
			
		||||
       - Factoring
 | 
			
		||||
       P(t) or P(s) or R
 | 
			
		||||
       ==>
 | 
			
		||||
       sigma(P(t) or R)
 | 
			
		||||
 | 
			
		||||
       sigma = mgu(t,s)
 | 
			
		||||
       sigma(P(t)) is eligible for resolution.
 | 
			
		||||
    */
 | 
			
		||||
    class factoring : public unary_inference {
 | 
			
		||||
    protected:
 | 
			
		||||
        statistics & m_stats;
 | 
			
		||||
        family_id    m_spc_fid;
 | 
			
		||||
        virtual justification * mk_justification(justification * parent, unsigned num_lits, literal * new_lits) {
 | 
			
		||||
            return mk_factoring_justification(m_manager, m_spc_fid, parent, num_lits, new_lits);
 | 
			
		||||
        }
 | 
			
		||||
        clause * mk_eq_fact_result(clause * cls, unsigned j, expr * lhs, expr * rhs);
 | 
			
		||||
        void try_eq_factoring(clause * cls, unsigned j, expr * lhs, expr * rhs, ptr_vector<clause> & new_clauses);
 | 
			
		||||
        void try_eq_factoring(clause * cls, unsigned i, ptr_vector<clause> & new_clauses);
 | 
			
		||||
        void try_factoring(clause * cls, unsigned j, ptr_vector<clause> & new_clauses);
 | 
			
		||||
    public:
 | 
			
		||||
        factoring(ast_manager & m, order & ord, statistics & stats):unary_inference(m, ord), m_stats(stats), m_spc_fid(m.get_family_id("spc")) {}
 | 
			
		||||
        virtual ~factoring() {}
 | 
			
		||||
        void operator()(clause * cls, ptr_vector<clause> & new_clauses);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_FACTORING_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,184 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_justification.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-08.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_justification.h"
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"marker.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    void get_justification_stat(justification * p, justification_stat & stat) {
 | 
			
		||||
        // Remark: justification objects that are not associated
 | 
			
		||||
        // with clauses may be shared. That is, they may be parent of
 | 
			
		||||
        // several different justification objects.
 | 
			
		||||
        marker<justification> m;
 | 
			
		||||
        ptr_buffer<justification> todo;
 | 
			
		||||
        todo.push_back(p);
 | 
			
		||||
        while (!todo.empty()) {
 | 
			
		||||
            justification * p = todo.back();
 | 
			
		||||
            todo.pop_back();
 | 
			
		||||
            if (!m.is_marked(p)) {
 | 
			
		||||
                m.mark(p);
 | 
			
		||||
                clause * cls = p->get_clause();
 | 
			
		||||
                if (cls) {
 | 
			
		||||
                    if (cls->get_proof_depth() > stat.m_proof_depth)
 | 
			
		||||
                        stat.m_proof_depth = cls->get_proof_depth();
 | 
			
		||||
                    if (cls->get_scope_lvl() > stat.m_max_scope_lvl)
 | 
			
		||||
                        stat.m_max_scope_lvl = cls->get_scope_lvl();
 | 
			
		||||
                    stat.m_parent_clauses.push_back(cls);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    p->get_parents(todo);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void justification::display(std::ostream & out) {
 | 
			
		||||
        out << "[" << get_rule_id();
 | 
			
		||||
        ptr_buffer<justification> ps;
 | 
			
		||||
        get_parents(ps);
 | 
			
		||||
        unsigned sz = ps.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
            out << " ";
 | 
			
		||||
            justification * js = ps[i];
 | 
			
		||||
            clause * cls = js->get_clause();
 | 
			
		||||
            if (cls)
 | 
			
		||||
                out << "#" << cls->get_id();
 | 
			
		||||
            else
 | 
			
		||||
                js->display(out);
 | 
			
		||||
        }
 | 
			
		||||
        out << "]";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    justification * justification_proof_wrapper::mk(proof * p, ast_manager & m) {
 | 
			
		||||
        void * mem = m.get_allocator().allocate(sizeof(justification_proof_wrapper));
 | 
			
		||||
        return new (mem) justification_proof_wrapper(p, m);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    proof * justification_proof_wrapper::get_proof() const { 
 | 
			
		||||
        return m_proof; 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned justification_proof_wrapper::del_eh(ast_manager & m) { 
 | 
			
		||||
        m.dec_ref(m_proof); 
 | 
			
		||||
        return sizeof(justification_proof_wrapper);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void dec_ref(justification * p, ast_manager & m) {
 | 
			
		||||
        if (p->dec_ref()) {
 | 
			
		||||
            ptr_buffer<justification> to_delete;
 | 
			
		||||
            ptr_buffer<justification> parents;
 | 
			
		||||
            to_delete.push_back(p);
 | 
			
		||||
            while (!to_delete.empty()) {
 | 
			
		||||
                justification * p = to_delete.back();
 | 
			
		||||
                to_delete.pop_back();
 | 
			
		||||
                SASSERT(p->get_ref_count() == 0);
 | 
			
		||||
                parents.reset();
 | 
			
		||||
                p->get_parents(parents);
 | 
			
		||||
                ptr_buffer<justification>::iterator it  = parents.begin();
 | 
			
		||||
                ptr_buffer<justification>::iterator end = parents.end();
 | 
			
		||||
                for (; it != end; ++it) {
 | 
			
		||||
                    justification * parent = *it;
 | 
			
		||||
                    if (parent->dec_ref())
 | 
			
		||||
                        to_delete.push_back(parent);
 | 
			
		||||
                }
 | 
			
		||||
                unsigned sz = p->del_eh(m);
 | 
			
		||||
                p->~justification();
 | 
			
		||||
                m.get_allocator().deallocate(sz, p);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return a proof for a new clause formed by the literals lits[0] ... lits[num_lits - 1].
 | 
			
		||||
       This clause was produced using a main clause C, where the proof of C is \c main_pr,
 | 
			
		||||
       and the auxiliary proofs auxs[0] ... aux[num_auxs-1].
 | 
			
		||||
       
 | 
			
		||||
       \remark If fine_grain_proofs() is false, then 0 is returned.
 | 
			
		||||
    */
 | 
			
		||||
    proof * mk_proof(ast_manager & m, family_id spc_fid, spc_op_kind pid, unsigned num_lits, literal * lits, proof * main_pr, 
 | 
			
		||||
                     unsigned num_auxs, proof * const * auxs) {
 | 
			
		||||
        if (m.fine_grain_proofs()) {
 | 
			
		||||
            expr * new_fact_body = mk_or(m, num_lits, lits);
 | 
			
		||||
            
 | 
			
		||||
            SASSERT(main_pr);
 | 
			
		||||
            SASSERT(m.has_fact(main_pr));
 | 
			
		||||
            expr * fact     = m.get_fact(main_pr);
 | 
			
		||||
            expr * new_fact = 0;
 | 
			
		||||
            if (is_quantifier(fact))
 | 
			
		||||
                new_fact = m.update_quantifier(to_quantifier(fact), new_fact_body);
 | 
			
		||||
            else 
 | 
			
		||||
                new_fact = new_fact_body;
 | 
			
		||||
 | 
			
		||||
            ptr_buffer<expr> args;
 | 
			
		||||
            args.push_back(main_pr);
 | 
			
		||||
            args.append(num_auxs, (expr**) auxs);
 | 
			
		||||
            args.push_back(new_fact);
 | 
			
		||||
            
 | 
			
		||||
            return m.mk_app(spc_fid, pid, args.size(), args.c_ptr());
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    justification * rewrite_justification::mk(ast_manager & m, justification * head, 
 | 
			
		||||
                                              unsigned num_demodulators, justification * const * demodulators, proof * pr) {
 | 
			
		||||
        void * mem = m.get_allocator().allocate(get_obj_size(num_demodulators, m.fine_grain_proofs()));
 | 
			
		||||
        return new (mem) rewrite_justification(m, head, num_demodulators, demodulators, pr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rewrite_justification::rewrite_justification(ast_manager & m, justification * head, 
 | 
			
		||||
                                                 unsigned num_demodulators, justification * const * demodulators, proof * pr):
 | 
			
		||||
        m_num_demodulators(num_demodulators) {
 | 
			
		||||
        SASSERT(m.fine_grain_proofs() == (pr != 0));
 | 
			
		||||
        m_fields[0] = head;
 | 
			
		||||
        head->inc_ref();
 | 
			
		||||
        for (unsigned i = 0; i < num_demodulators; i++) {
 | 
			
		||||
            m_fields[i+1] = demodulators[i];
 | 
			
		||||
            demodulators[i]->inc_ref();
 | 
			
		||||
        }
 | 
			
		||||
        if (m.fine_grain_proofs()) {
 | 
			
		||||
            SASSERT(pr);
 | 
			
		||||
            m_fields[num_demodulators+1] = pr;
 | 
			
		||||
            m.inc_ref(pr);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
            
 | 
			
		||||
    void rewrite_justification::get_parents(ptr_buffer<justification> & parents) {
 | 
			
		||||
        unsigned num_parents = m_num_demodulators+1;
 | 
			
		||||
        for (unsigned i = 0; i < num_parents; i++)
 | 
			
		||||
            parents.push_back(reinterpret_cast<justification*>(m_fields[i]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    proof * rewrite_justification::get_proof() const {
 | 
			
		||||
        return reinterpret_cast<proof*>(m_fields[m_num_demodulators+1]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned rewrite_justification::del_eh(ast_manager & m) {
 | 
			
		||||
        if (m.fine_grain_proofs()) {
 | 
			
		||||
            m.dec_ref(reinterpret_cast<proof*>(m_fields[m_num_demodulators+1]));
 | 
			
		||||
            return get_obj_size(m_num_demodulators, true);
 | 
			
		||||
        }
 | 
			
		||||
        return get_obj_size(m_num_demodulators, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    proof * mk_rewrite_proof(ast_manager & m, family_id spc_fid, unsigned num_lits, literal * lits, proof * main_pr, 
 | 
			
		||||
                             unsigned num_auxs, proof * const * auxs) {
 | 
			
		||||
        return mk_proof(m, spc_fid, PR_SPC_REWRITE, num_lits, lits, main_pr, num_auxs, auxs);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,337 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_justification.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Proof-like objects for tracking dependencies in the superposition
 | 
			
		||||
    calculus engine, and generating proofs.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_JUSTIFICATION_H_
 | 
			
		||||
#define _SPC_JUSTIFICATION_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"spc_literal.h"
 | 
			
		||||
#include"spc_decl_plugin.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    class clause;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Proof-like object use to track dependencies and produce
 | 
			
		||||
       proofs.
 | 
			
		||||
 | 
			
		||||
       \remark All justification objects must be allocated using the
 | 
			
		||||
       small_object_allocator in ast_manager.
 | 
			
		||||
    */
 | 
			
		||||
    class justification {
 | 
			
		||||
        clause * m_owner;
 | 
			
		||||
        unsigned m_ref_count:30;
 | 
			
		||||
        unsigned m_mark:1;
 | 
			
		||||
        unsigned m_assumption:1;
 | 
			
		||||
        
 | 
			
		||||
        friend class clause;
 | 
			
		||||
        void set_owner(clause * cls) { m_owner = cls; }
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        justification(bool assumption = false):
 | 
			
		||||
            m_owner(0),
 | 
			
		||||
            m_ref_count(0),
 | 
			
		||||
            m_mark(false), 
 | 
			
		||||
            m_assumption(assumption) {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual ~justification() {}
 | 
			
		||||
 | 
			
		||||
        void inc_ref() { 
 | 
			
		||||
            m_ref_count++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool dec_ref() {
 | 
			
		||||
            SASSERT(m_ref_count > 0);
 | 
			
		||||
            m_ref_count--;
 | 
			
		||||
            return m_ref_count == 0;
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
        unsigned get_ref_count() {
 | 
			
		||||
            return m_ref_count;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void set_mark(bool f) { m_mark = f; }
 | 
			
		||||
     
 | 
			
		||||
        bool is_marked() const { return m_mark; }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return the clause justified by this object. 
 | 
			
		||||
           
 | 
			
		||||
           \remark for some justification objects that clause is
 | 
			
		||||
           supressed. Example: intermediate steps.
 | 
			
		||||
        */
 | 
			
		||||
        clause * get_clause() { return m_owner; }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return the expr justified by this object. 
 | 
			
		||||
           This method returns a non null value only when
 | 
			
		||||
           proof generation is enabled. 
 | 
			
		||||
        */
 | 
			
		||||
        virtual expr * get_expr(ast_manager & m) { return 0; }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return a non-zero value if the justification
 | 
			
		||||
           is wrapping a proof object.
 | 
			
		||||
        */
 | 
			
		||||
        virtual proof * get_proof() const { return 0; }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return the parent justifications.
 | 
			
		||||
        */
 | 
			
		||||
        virtual void get_parents(ptr_buffer<justification> & parents) {}
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return the name of the rule used.
 | 
			
		||||
        */
 | 
			
		||||
        virtual spc_op_kind get_rule_id() = 0;
 | 
			
		||||
        
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return true if the justification is an external assumption.
 | 
			
		||||
        */
 | 
			
		||||
        bool assumption() const { return m_assumption; }
 | 
			
		||||
 | 
			
		||||
        void display(std::ostream & out);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief This method is invoked before the object is deleted.
 | 
			
		||||
           Return the amount of memory consumed by this object.
 | 
			
		||||
        */
 | 
			
		||||
        virtual unsigned del_eh(ast_manager & m) = 0;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct justification_stat {
 | 
			
		||||
        unsigned           m_proof_depth;
 | 
			
		||||
        unsigned           m_max_scope_lvl;
 | 
			
		||||
        ptr_buffer<clause> m_parent_clauses;
 | 
			
		||||
        justification_stat():
 | 
			
		||||
            m_proof_depth(0),
 | 
			
		||||
            m_max_scope_lvl(0) {
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    void get_justification_stat(justification * p, justification_stat & stat);
 | 
			
		||||
 | 
			
		||||
    void dec_ref(justification * p, ast_manager & m);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Smart pointer for justification objects.
 | 
			
		||||
    */
 | 
			
		||||
    class justification_ref {
 | 
			
		||||
        justification * m_obj;
 | 
			
		||||
        ast_manager &   m_manager;
 | 
			
		||||
        void inc_ref() { if (m_obj) m_obj->inc_ref(); }
 | 
			
		||||
        void dec_ref() { if (m_obj) spc::dec_ref(m_obj, m_manager); }
 | 
			
		||||
    public:
 | 
			
		||||
        justification_ref(ast_manager & m):m_obj(0), m_manager(m) {}
 | 
			
		||||
        justification_ref(justification * j, ast_manager & m):
 | 
			
		||||
            m_obj(j), m_manager(m) {
 | 
			
		||||
            inc_ref();
 | 
			
		||||
        }
 | 
			
		||||
        ~justification_ref() {
 | 
			
		||||
            dec_ref();
 | 
			
		||||
        }
 | 
			
		||||
        operator justification*() const { return m_obj; }
 | 
			
		||||
        operator bool() const { return m_obj != 0; }
 | 
			
		||||
        bool operator!() const { return m_obj == 0; }
 | 
			
		||||
        justification * operator->() const { return m_obj; }
 | 
			
		||||
        justification const & operator*() const { return *m_obj; }
 | 
			
		||||
        justification_ref & operator=(justification * n) {
 | 
			
		||||
            if (n)
 | 
			
		||||
                n->inc_ref();
 | 
			
		||||
            dec_ref();
 | 
			
		||||
            m_obj = n;
 | 
			
		||||
            return *this;
 | 
			
		||||
        }
 | 
			
		||||
        justification_ref & operator=(justification_ref & n) {
 | 
			
		||||
            SASSERT(&m_manager == &n.m_manager);
 | 
			
		||||
            n.inc_ref();
 | 
			
		||||
            dec_ref();
 | 
			
		||||
            m_obj = n.m_obj;
 | 
			
		||||
            return *this;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    class justification_proof_wrapper : public justification {
 | 
			
		||||
        proof * m_proof;
 | 
			
		||||
        justification_proof_wrapper(proof * p, ast_manager & m):m_proof(p) { m.inc_ref(m_proof); }
 | 
			
		||||
    public:
 | 
			
		||||
        static justification * mk(proof * p, ast_manager & m);
 | 
			
		||||
        virtual ~justification_proof_wrapper() {}
 | 
			
		||||
        virtual proof * get_proof() const;
 | 
			
		||||
        virtual spc_op_kind get_rule_id() { return PR_SPC_ASSERTED; };
 | 
			
		||||
        virtual unsigned del_eh(ast_manager & m);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    proof * mk_proof(ast_manager & m, family_id spc_fid, spc_op_kind pid, unsigned num_lits, literal * lits, proof * main_pr, unsigned num_auxs, 
 | 
			
		||||
                     proof * const * auxs);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Justification for rewriting steps: demodulation, duplicate literal deletion, resolved literal deletion.
 | 
			
		||||
    */
 | 
			
		||||
    class rewrite_justification : public justification {
 | 
			
		||||
        unsigned m_num_demodulators;
 | 
			
		||||
        void *   m_fields[0];
 | 
			
		||||
        static unsigned get_obj_size(unsigned num_demodulators, bool fine_grain) { 
 | 
			
		||||
            return sizeof(rewrite_justification) + (num_demodulators + (fine_grain ? 2 : 1)) * sizeof(void *); 
 | 
			
		||||
        }
 | 
			
		||||
        rewrite_justification(ast_manager & m, justification * head, 
 | 
			
		||||
                              unsigned num_demodulators, justification * const * demodulators, proof * pr);
 | 
			
		||||
    public:
 | 
			
		||||
        static justification * mk(ast_manager & m, justification * head, 
 | 
			
		||||
                                  unsigned num_demodulators, justification * const * demodulators, proof * pr = 0);
 | 
			
		||||
        virtual ~rewrite_justification() {}
 | 
			
		||||
        virtual proof * get_proof() const;
 | 
			
		||||
        virtual spc_op_kind get_rule_id() { return PR_SPC_REWRITE; }
 | 
			
		||||
        virtual void get_parents(ptr_buffer<justification> & parents);
 | 
			
		||||
        virtual unsigned del_eh(ast_manager & m);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    proof * mk_rewrite_proof(ast_manager & m, family_id spc_fid, unsigned num_lits, literal * lits, proof * main_pr, unsigned num_auxs, 
 | 
			
		||||
                             proof * const * auxs);
 | 
			
		||||
 | 
			
		||||
    template<spc_op_kind Kind> 
 | 
			
		||||
    class unary_justification : public justification {
 | 
			
		||||
    protected:
 | 
			
		||||
        justification * m_parent;
 | 
			
		||||
        proof *         m_proof; 
 | 
			
		||||
 | 
			
		||||
        unary_justification(ast_manager & m, justification * p, proof * pr):
 | 
			
		||||
            m_parent(p),
 | 
			
		||||
            m_proof(pr) {
 | 
			
		||||
            p->inc_ref();
 | 
			
		||||
            SASSERT(m.fine_grain_proofs() == (pr != 0));
 | 
			
		||||
            if (m.fine_grain_proofs())
 | 
			
		||||
                m.inc_ref(pr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        virtual proof * get_proof() const {
 | 
			
		||||
            return m_proof;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void get_parents(ptr_buffer<justification> & parents) {
 | 
			
		||||
            parents.push_back(m_parent);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual unsigned del_eh(ast_manager & m) {
 | 
			
		||||
            if (m.fine_grain_proofs()) 
 | 
			
		||||
                m.dec_ref(m_proof);
 | 
			
		||||
            return sizeof(unary_justification);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual spc_op_kind get_rule_id() {
 | 
			
		||||
            return Kind;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        static justification * mk(ast_manager & m, family_id spc_fid, justification * p, unsigned num_lits, literal * lits) {
 | 
			
		||||
            proof * pr = 0;
 | 
			
		||||
            if (m.fine_grain_proofs())
 | 
			
		||||
                pr = mk_proof(m, spc_fid, Kind, num_lits, lits, p->get_proof(), 0, 0);
 | 
			
		||||
            void * mem = m.get_allocator().allocate(sizeof(unary_justification));
 | 
			
		||||
            return new (mem) unary_justification(m, p, pr);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    inline justification * mk_eq_res_justification(ast_manager & m, family_id spc_fid, justification * p, unsigned num_lits, literal * lits) {
 | 
			
		||||
        return unary_justification<PR_EQUALITY_RESOLUTION>::mk(m, spc_fid, p, num_lits, lits);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline justification * mk_factoring_justification(ast_manager & m, family_id spc_fid, justification * p, unsigned num_lits, literal * lits) {
 | 
			
		||||
        return unary_justification<PR_FACTORING>::mk(m, spc_fid, p, num_lits, lits);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline justification * mk_der_justification(ast_manager & m, family_id spc_fid, justification * p, unsigned num_lits, literal * lits) {
 | 
			
		||||
        return unary_justification<PR_SPC_DER>::mk(m, spc_fid, p, num_lits, lits);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<spc_op_kind Kind> 
 | 
			
		||||
    class binary_justification : public justification {
 | 
			
		||||
    protected:
 | 
			
		||||
        justification * m_parent1;
 | 
			
		||||
        justification * m_parent2;
 | 
			
		||||
        proof *         m_proof; 
 | 
			
		||||
 | 
			
		||||
        binary_justification(ast_manager & m, justification * p1, justification * p2, proof * pr):
 | 
			
		||||
            m_parent1(p1),
 | 
			
		||||
            m_parent2(p2),
 | 
			
		||||
            m_proof(pr) {
 | 
			
		||||
            p1->inc_ref();
 | 
			
		||||
            p2->inc_ref();
 | 
			
		||||
            SASSERT(m.fine_grain_proofs() == (pr != 0));
 | 
			
		||||
            if (m.fine_grain_proofs())
 | 
			
		||||
                m.inc_ref(pr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        virtual proof * get_proof() const {
 | 
			
		||||
            return m_proof;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void get_parents(ptr_buffer<justification> & parents) {
 | 
			
		||||
            parents.push_back(m_parent1);
 | 
			
		||||
            parents.push_back(m_parent2);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual unsigned del_eh(ast_manager & m) {
 | 
			
		||||
            if (m.fine_grain_proofs()) 
 | 
			
		||||
                m.dec_ref(m_proof);
 | 
			
		||||
            return sizeof(binary_justification);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual spc_op_kind get_rule_id() {
 | 
			
		||||
            return Kind;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        static justification * mk(ast_manager & m, family_id spc_fid, justification * p1, justification * p2, unsigned num_lits, literal * lits,
 | 
			
		||||
                                  unsigned num_vars, var * const * vars) {
 | 
			
		||||
            proof * pr = 0;
 | 
			
		||||
            if (m.fine_grain_proofs()) {
 | 
			
		||||
                ptr_buffer<sort> sorts;
 | 
			
		||||
                sbuffer<symbol>  names;
 | 
			
		||||
                for (unsigned i = 0; i < num_vars; i++) {
 | 
			
		||||
                    sorts.push_back(vars[num_vars - i - 1]->get_sort());
 | 
			
		||||
                    names.push_back(symbol(num_vars - i - 1));
 | 
			
		||||
                }
 | 
			
		||||
                expr * body = mk_or(m, num_lits, lits);
 | 
			
		||||
                expr * new_fact = 0;
 | 
			
		||||
                if (num_vars == 0)
 | 
			
		||||
                    new_fact = body;
 | 
			
		||||
                else
 | 
			
		||||
                    new_fact = m.mk_forall(sorts.size(), sorts.c_ptr(), names.c_ptr(), body);
 | 
			
		||||
                pr = m.mk_app(spc_fid, Kind, p1->get_proof(), p2->get_proof(), new_fact); 
 | 
			
		||||
            }
 | 
			
		||||
            void * mem = m.get_allocator().allocate(sizeof(binary_justification));
 | 
			
		||||
            return new (mem) binary_justification(m, p1, p2, pr);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    inline justification * mk_superposition_justification(ast_manager & m, family_id spc_fid, justification * p1, justification * p2,
 | 
			
		||||
                                                          unsigned num_lits, literal * lits, unsigned num_vars, var * const * vars) {
 | 
			
		||||
        return binary_justification<PR_SUPERPOSITION>::mk(m, spc_fid, p1, p2, num_lits, lits, num_vars, vars);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline justification * mk_resolution_justification(ast_manager & m, family_id spc_fid, justification * p1, justification * p2,
 | 
			
		||||
                                                          unsigned num_lits, literal * lits, unsigned num_vars, var * const * vars) {
 | 
			
		||||
        return binary_justification<PR_SPC_RESOLUTION>::mk(m, spc_fid, p1, p2, num_lits, lits, num_vars, vars);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_JUSTIFICATION_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,432 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_literal.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus literal
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_literal.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    void literal::try_to_orient(order & o) {
 | 
			
		||||
        ast_manager & m = o.get_manager();
 | 
			
		||||
        if (!m_sign && m.is_eq(m_atom)) {
 | 
			
		||||
            expr * lhs = to_app(m_atom)->get_arg(0);
 | 
			
		||||
            expr * rhs = to_app(m_atom)->get_arg(1);
 | 
			
		||||
            TRACE("spc_orient", tout << "trying to orient:\n" << mk_pp(lhs, m) << "\n" << mk_pp(rhs, m) << "\n";);
 | 
			
		||||
            switch (o.compare(lhs, rhs)) {
 | 
			
		||||
            case order::GREATER:
 | 
			
		||||
                m_oriented = true;
 | 
			
		||||
                m_left     = true;
 | 
			
		||||
                TRACE("spc_orient", tout << "greater\n";);
 | 
			
		||||
                return;
 | 
			
		||||
            case order::LESSER:
 | 
			
		||||
                m_oriented = true;
 | 
			
		||||
                m_left     = false;
 | 
			
		||||
                TRACE("spc_orient", tout << "smaller\n";);
 | 
			
		||||
                return;
 | 
			
		||||
            default:
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    void literal::get_stat(literal_stat & stat) {
 | 
			
		||||
        get_expr_stat(m_atom, stat);
 | 
			
		||||
        m_stats       = true;
 | 
			
		||||
        m_ground      = stat.m_ground;
 | 
			
		||||
        m_sym_count   = stat.m_sym_count   > SYM_COUNT_MAX   ? SYM_COUNT_MAX   : stat.m_sym_count;
 | 
			
		||||
        m_depth       = stat.m_depth       > DEPTH_MAX       ? DEPTH_MAX       : stat.m_depth;
 | 
			
		||||
        m_const_count = stat.m_const_count > CONST_COUNT_MAX ? CONST_COUNT_MAX : stat.m_const_count;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    expr * literal::to_expr(ast_manager & m) const {
 | 
			
		||||
        if (is_true(m)) 
 | 
			
		||||
            return m.mk_true();
 | 
			
		||||
        else if (is_false(m))
 | 
			
		||||
            return m.mk_false();
 | 
			
		||||
        else if (m_sign)
 | 
			
		||||
            return m.mk_not(m_atom);
 | 
			
		||||
        else
 | 
			
		||||
            return m_atom;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void literal::display(std::ostream & out, ast_manager & m, bool detailed) const {
 | 
			
		||||
        pp_params p;
 | 
			
		||||
        p.m_pp_single_line = true;
 | 
			
		||||
        
 | 
			
		||||
        if (m_sign) 
 | 
			
		||||
            out << "(not ";
 | 
			
		||||
        
 | 
			
		||||
        if (m_oriented) {
 | 
			
		||||
            expr * lhs = to_app(m_atom)->get_arg(0);
 | 
			
		||||
            expr * rhs = to_app(m_atom)->get_arg(1);
 | 
			
		||||
            if (!m_left)
 | 
			
		||||
                std::swap(lhs, rhs);
 | 
			
		||||
            out << "(-> ";
 | 
			
		||||
            ast_pp(out, lhs, m, p);
 | 
			
		||||
            out << " ";
 | 
			
		||||
            ast_pp(out, rhs, m, p);
 | 
			
		||||
            out << ")";
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            ast_pp(out, m_atom, m, p);            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (m_sign) 
 | 
			
		||||
            out << ")";
 | 
			
		||||
    
 | 
			
		||||
        if (detailed && m_stats) {
 | 
			
		||||
            out << "[" << m_ground << ", " << m_depth << ", " << m_sym_count << ", " << m_const_count << "]";
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        if (m_selected)
 | 
			
		||||
            out << "$";
 | 
			
		||||
        if (m_p_indexed)
 | 
			
		||||
            out << "!";
 | 
			
		||||
        if (m_r_indexed)
 | 
			
		||||
            out << "@";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void display(std::ostream & out, unsigned num_lists, literal * lits, ast_manager & m, bool detailed) {
 | 
			
		||||
        for (unsigned i = 0; i < num_lists; i++) {
 | 
			
		||||
            if (i > 0) out << " ";
 | 
			
		||||
            lits[i].display(out, m, detailed);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Given an eq literal store in lhs and rhs the left and right hand sides. If they can be oriented
 | 
			
		||||
       given the substitution s, then return true, and make lhs the maximal one.
 | 
			
		||||
    */
 | 
			
		||||
    bool can_orient(order & o, literal const & l, unsigned offset, substitution * s, expr * & lhs, expr * & rhs) {
 | 
			
		||||
        SASSERT(o.get_manager().is_eq(l.atom()));
 | 
			
		||||
        lhs = l.lhs();
 | 
			
		||||
        rhs = l.rhs();
 | 
			
		||||
        if (l.is_oriented()) {
 | 
			
		||||
            if (!l.is_left())
 | 
			
		||||
                std::swap(lhs, rhs);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            order::result comp = o.compare(lhs, rhs, offset, s);
 | 
			
		||||
            if (comp == order::GREATER)
 | 
			
		||||
                return true;
 | 
			
		||||
            else if (comp == order::LESSER) {
 | 
			
		||||
                std::swap(lhs, rhs);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Compare literal signs. Negative sign is bigger than the positive one.
 | 
			
		||||
    */
 | 
			
		||||
    inline order::result compare_signs(bool sign1, bool sign2) {
 | 
			
		||||
        if (sign1 && !sign2)
 | 
			
		||||
            return order::GREATER;
 | 
			
		||||
        else if (!sign1 && sign2)
 | 
			
		||||
            return order::LESSER;
 | 
			
		||||
        else
 | 
			
		||||
            return order::EQUAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Compare two literals (modulo a substitution) using the given term ordering.
 | 
			
		||||
    */
 | 
			
		||||
    order::result compare(order & o, literal const & l1, literal const & l2, unsigned offset, substitution * s) {
 | 
			
		||||
        ast_manager & m = o.get_manager();
 | 
			
		||||
        expr * n1 = l1.atom();
 | 
			
		||||
        expr * n2 = l2.atom();
 | 
			
		||||
        bool is_eq1 = m.is_eq(n1);
 | 
			
		||||
        bool is_eq2 = m.is_eq(n2);
 | 
			
		||||
        if (is_eq1 && is_eq2) {
 | 
			
		||||
            expr * lhs1 = 0;
 | 
			
		||||
            expr * rhs1 = 0;
 | 
			
		||||
            expr * lhs2 = 0;
 | 
			
		||||
            expr * rhs2 = 0;
 | 
			
		||||
            bool oriented1 = can_orient(o, l1, offset, s, lhs1, rhs1);
 | 
			
		||||
            bool oriented2 = can_orient(o, l2, offset, s, lhs2, rhs2);
 | 
			
		||||
            if (oriented1) {
 | 
			
		||||
                // equation 1 can be oriented
 | 
			
		||||
                if (oriented2) {
 | 
			
		||||
                    // equation 2 can be oriented
 | 
			
		||||
                    // both equations are oriented
 | 
			
		||||
                    SASSERT(oriented1);
 | 
			
		||||
                    SASSERT(oriented2);
 | 
			
		||||
                    order::result r = o.compare(lhs1, lhs2, offset, s);
 | 
			
		||||
                    if (r == order::EQUAL) {
 | 
			
		||||
                        if (l1.pos()) {
 | 
			
		||||
                            if (l2.pos()) 
 | 
			
		||||
                                return o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                            else
 | 
			
		||||
                                return order::LESSER;
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            if (l2.pos())
 | 
			
		||||
                                return order::GREATER;
 | 
			
		||||
                            else
 | 
			
		||||
                                return o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    return r;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    // equation 2 cannot be oriented
 | 
			
		||||
                    SASSERT(oriented1);
 | 
			
		||||
                    SASSERT(!oriented2);
 | 
			
		||||
                    SASSERT(o.compare(lhs1, rhs1, offset, s) == order::GREATER);
 | 
			
		||||
                    if (o.equal(lhs1, lhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (o.equal(lhs1, rhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(rhs1, lhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    order::result lhs1_lhs2 = o.compare(lhs1, lhs2, offset, s);
 | 
			
		||||
                    order::result lhs1_rhs2 = o.compare(lhs1, rhs2, offset, s);
 | 
			
		||||
                    if (lhs1_lhs2 == lhs1_rhs2) 
 | 
			
		||||
                        return lhs1_lhs2;
 | 
			
		||||
                    order::result rhs1_rhs2 = o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                    if (lhs1_lhs2 == rhs1_rhs2)
 | 
			
		||||
                        return lhs1_lhs2;
 | 
			
		||||
                    if (lhs1_rhs2 == order::LESSER && rhs1_rhs2 == order::LESSER)
 | 
			
		||||
                        return order::LESSER;
 | 
			
		||||
                    order::result rhs1_lhs2 = o.compare(rhs1, lhs2, offset, s);
 | 
			
		||||
                    if (lhs1_lhs2 == order::LESSER && rhs1_lhs2 == order::LESSER)
 | 
			
		||||
                        return order::LESSER;
 | 
			
		||||
                    return order::UNCOMPARABLE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                // equation 1 cannot be oriented
 | 
			
		||||
                if (oriented2) {
 | 
			
		||||
                    SASSERT(!oriented1);
 | 
			
		||||
                    SASSERT(oriented2);
 | 
			
		||||
                    // equation 2 can be oriented
 | 
			
		||||
                    if (o.equal(lhs1, lhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (o.equal(rhs1, lhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(lhs1, rhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    order::result lhs1_lhs2 = o.compare(lhs1, lhs2, offset, s);
 | 
			
		||||
                    order::result rhs1_lhs2 = o.compare(rhs1, lhs2, offset, s);
 | 
			
		||||
                    if (lhs1_lhs2 == rhs1_lhs2)
 | 
			
		||||
                        return lhs1_lhs2;
 | 
			
		||||
                    order::result rhs1_rhs2 = o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                    if (lhs1_lhs2 == rhs1_rhs2)
 | 
			
		||||
                        return lhs1_lhs2;
 | 
			
		||||
                    if (rhs1_lhs2 == order::GREATER && rhs1_rhs2 == order::GREATER)
 | 
			
		||||
                        return order::GREATER;
 | 
			
		||||
                    order::result lhs1_rhs2 = o.compare(lhs1, rhs2, offset, s);
 | 
			
		||||
                    if (lhs1_lhs2 == order::GREATER && lhs1_rhs2 == order::GREATER)
 | 
			
		||||
                        return order::GREATER;
 | 
			
		||||
                    return order::UNCOMPARABLE;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    SASSERT(!oriented1);
 | 
			
		||||
                    SASSERT(!oriented2);
 | 
			
		||||
                    if (o.equal(lhs1, lhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (o.equal(rhs1, lhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(lhs1, rhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (o.equal(lhs1, rhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(rhs1, lhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (o.equal(rhs1, rhs2, offset, s)) {
 | 
			
		||||
                        order::result r = o.compare(lhs1, lhs2, offset, s);
 | 
			
		||||
                        if (r == order::EQUAL)
 | 
			
		||||
                            return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    order::result r;
 | 
			
		||||
                    order::result aux;
 | 
			
		||||
                    switch (o.compare(lhs1, lhs2, offset, s)) {
 | 
			
		||||
                    case order::GREATER:
 | 
			
		||||
                        r   = o.compare(lhs1, rhs2, offset, s);
 | 
			
		||||
                        if (r == order::GREATER)
 | 
			
		||||
                            return order::GREATER;
 | 
			
		||||
                        aux = o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                        if (aux == order::GREATER)
 | 
			
		||||
                            return order::GREATER;
 | 
			
		||||
                        if (r == order::LESSER && aux == order::LESSER)
 | 
			
		||||
                            return order::LESSER;
 | 
			
		||||
                        SASSERT(r   != order::EQUAL);
 | 
			
		||||
                        SASSERT(aux != order::EQUAL);
 | 
			
		||||
                        return order::UNCOMPARABLE;
 | 
			
		||||
                    case order::LESSER:
 | 
			
		||||
                        r   = o.compare(rhs1, lhs2, offset, s);
 | 
			
		||||
                        if (r == order::LESSER)
 | 
			
		||||
                            return order::LESSER;
 | 
			
		||||
                        aux = o.compare(rhs1, rhs2, offset, s);
 | 
			
		||||
                        if (aux == order::LESSER)
 | 
			
		||||
                            return order::LESSER;
 | 
			
		||||
                        if (r == order::GREATER && aux == order::GREATER)
 | 
			
		||||
                            return order::GREATER;
 | 
			
		||||
                        SASSERT(r   != order::EQUAL);
 | 
			
		||||
                        SASSERT(aux != order::EQUAL);
 | 
			
		||||
                        return order::UNCOMPARABLE;
 | 
			
		||||
                    case order::EQUAL:
 | 
			
		||||
                        UNREACHABLE();
 | 
			
		||||
                        return order::UNKNOWN;
 | 
			
		||||
                    default:
 | 
			
		||||
                        switch (o.compare(lhs1, rhs2, offset, s)) {
 | 
			
		||||
                        case order::GREATER:
 | 
			
		||||
                            if (o.compare(rhs1, lhs2, offset, s) == order::GREATER)
 | 
			
		||||
                                return order::GREATER;
 | 
			
		||||
                            return order::UNCOMPARABLE;
 | 
			
		||||
                        case order::LESSER:
 | 
			
		||||
                            if (o.compare(rhs1, lhs2, offset, s) == order::LESSER ||
 | 
			
		||||
                                o.compare(rhs1, rhs2, offset, s) == order::LESSER)
 | 
			
		||||
                                return order::LESSER;
 | 
			
		||||
                            return order::UNCOMPARABLE;
 | 
			
		||||
                        case order::EQUAL:
 | 
			
		||||
                            UNREACHABLE();
 | 
			
		||||
                            return order::UNKNOWN;
 | 
			
		||||
                        default:
 | 
			
		||||
                            if (o.compare(rhs1, lhs2, offset, s) == order::GREATER &&
 | 
			
		||||
                                o.compare(rhs1, rhs2, offset, s) == order::GREATER)
 | 
			
		||||
                                return order::GREATER;
 | 
			
		||||
                            return order::UNCOMPARABLE;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (is_eq1) {
 | 
			
		||||
            expr * lhs1 = l1.lhs();
 | 
			
		||||
            expr * rhs1 = l1.rhs();
 | 
			
		||||
            if (l1.is_oriented() && !l1.is_left())
 | 
			
		||||
                std::swap(lhs1, rhs1);
 | 
			
		||||
            order::result r = o.compare(lhs1, n2, offset, s);
 | 
			
		||||
            if (!l1.is_oriented() || r != order::GREATER) {
 | 
			
		||||
                order::result r2 = o.compare(rhs1, n2, offset, s);
 | 
			
		||||
                if (r2 == order::GREATER)
 | 
			
		||||
                    return order::GREATER;
 | 
			
		||||
                else if (r != r2)
 | 
			
		||||
                    return order::UNCOMPARABLE;
 | 
			
		||||
            }
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
        else if (is_eq2) {
 | 
			
		||||
            expr * lhs2 = l2.lhs();
 | 
			
		||||
            expr * rhs2 = l2.rhs();
 | 
			
		||||
            if (l2.is_oriented() && !l2.is_left())
 | 
			
		||||
                std::swap(lhs2, rhs2);
 | 
			
		||||
            order::result r = o.compare(n1, lhs2, offset, s);
 | 
			
		||||
            if (!l1.is_oriented() || r != order::LESSER) {
 | 
			
		||||
                order::result r2 = o.compare(n1, rhs2, offset, s);
 | 
			
		||||
                if (r2 == order::LESSER)
 | 
			
		||||
                    return order::LESSER;
 | 
			
		||||
                else if (r != r2)
 | 
			
		||||
                    return order::UNCOMPARABLE;
 | 
			
		||||
            }
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            order::result r = o.compare(n1, n2, offset, s);
 | 
			
		||||
            if (r == order::EQUAL)
 | 
			
		||||
                return compare_signs(l1.sign(), l2.sign());
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool greater(order & o, literal const & l1, literal const & l2, unsigned offset, substitution * s) {
 | 
			
		||||
        order::result r = compare(o, l1, l2, offset, s);
 | 
			
		||||
        TRACE("literal_order", ast_manager & m = o.get_manager();
 | 
			
		||||
              tout << "comparing ";
 | 
			
		||||
              l1.display(tout, m);
 | 
			
		||||
              tout << " ";
 | 
			
		||||
              l2.display(tout, m);
 | 
			
		||||
              tout << " : " << r << "\n";);
 | 
			
		||||
        return r == order::GREATER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void found_literals::insert(literal const & l) {
 | 
			
		||||
        unsigned id = l.get_id();
 | 
			
		||||
        m_marks.reserve(id+1);
 | 
			
		||||
        if (!m_marks.get(id)) {
 | 
			
		||||
            m_marks.set(id);
 | 
			
		||||
            m_lit_ids.push_back(id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool found_literals::contains(literal const & l) const {
 | 
			
		||||
        unsigned id = l.get_id();
 | 
			
		||||
        return id < m_marks.size() && m_marks.get(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool found_literals::contains_neg(literal const & l) const {
 | 
			
		||||
        unsigned id = l.get_neg_id();
 | 
			
		||||
        return id < m_marks.size() && m_marks.get(id);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void found_literals::reset() {
 | 
			
		||||
        unsigned_vector::iterator it  = m_lit_ids.begin();
 | 
			
		||||
        unsigned_vector::iterator end = m_lit_ids.end();
 | 
			
		||||
        for (; it != end; ++it) 
 | 
			
		||||
            m_marks.unset(*it);
 | 
			
		||||
        m_lit_ids.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void literal_buffer::reset() { 
 | 
			
		||||
        buffer<literal>::iterator it  = m_lits.begin();
 | 
			
		||||
        buffer<literal>::iterator end = m_lits.end();
 | 
			
		||||
        for (; it != end; ++it) 
 | 
			
		||||
            m_manager.dec_ref(it->atom());
 | 
			
		||||
        m_lits.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    expr * mk_or(ast_manager & m, unsigned num_lists, literal * lits) {
 | 
			
		||||
        if (num_lists == 0) 
 | 
			
		||||
            return m.mk_false();
 | 
			
		||||
        else if (num_lists == 1)
 | 
			
		||||
            return lits[0].to_expr(m);
 | 
			
		||||
        else {
 | 
			
		||||
            ptr_buffer<expr> new_exprs;
 | 
			
		||||
            for (unsigned i = 0; i < num_lists; i++)
 | 
			
		||||
                new_exprs.push_back(lits[i].to_expr(m));
 | 
			
		||||
            return m.mk_or(new_exprs.size(), new_exprs.c_ptr());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,212 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_literal.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus literal
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_LITERAL_H_
 | 
			
		||||
#define _SPC_LITERAL_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"order.h"
 | 
			
		||||
#include"expr_stat.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    typedef expr_stat literal_stat;
 | 
			
		||||
 | 
			
		||||
#define DEPTH_NUM_BITS 4
 | 
			
		||||
#define DEPTH_MAX ((1 << DEPTH_NUM_BITS) - 1)
 | 
			
		||||
#define CONST_COUNT_NUM_BITS 4    
 | 
			
		||||
#define CONST_COUNT_MAX ((1 << CONST_COUNT_NUM_BITS) - 1)
 | 
			
		||||
#define SYM_COUNT_NUM_BITS 16
 | 
			
		||||
#define SYM_COUNT_MAX ((1 << SYM_COUNT_NUM_BITS) - 1)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Superposition Calculus literal.
 | 
			
		||||
    */
 | 
			
		||||
    class literal {
 | 
			
		||||
        expr * m_atom;
 | 
			
		||||
        unsigned  m_sign:1;                           // true if a negative literal.
 | 
			
		||||
        unsigned  m_oriented:1;                       // true if it is an oriented equality.
 | 
			
		||||
        unsigned  m_left:1;                           // true if the largest term is on the left-hand-side of the equality (only meaningful if m_oriented == true).
 | 
			
		||||
        unsigned  m_selected:1;                       // true if it is a selected literal.
 | 
			
		||||
        unsigned  m_stats:1;                          // true if the following fields were initialized.
 | 
			
		||||
        unsigned  m_ground:1;                         // true if it is a ground literal
 | 
			
		||||
        unsigned  m_p_indexed:1;                      // true if the literal was inserted into the p (paramodulation) superposition index.
 | 
			
		||||
        unsigned  m_r_indexed:1;                      // true if the literal was inserted into the r (resolution) superposition index.
 | 
			
		||||
        unsigned  m_depth:DEPTH_NUM_BITS;             // approx. depth
 | 
			
		||||
        unsigned  m_const_count:CONST_COUNT_NUM_BITS; // approx. number of constants 
 | 
			
		||||
        unsigned  m_sym_count:SYM_COUNT_NUM_BITS;     // approx. size
 | 
			
		||||
 | 
			
		||||
        friend class clause;
 | 
			
		||||
        
 | 
			
		||||
        void set_selected(bool f) { 
 | 
			
		||||
            m_selected = f; 
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    public:
 | 
			
		||||
        literal():
 | 
			
		||||
            m_atom(0), 
 | 
			
		||||
            m_sign(false), 
 | 
			
		||||
            m_oriented(false), 
 | 
			
		||||
            m_left(false), 
 | 
			
		||||
            m_selected(false), 
 | 
			
		||||
            m_stats(false),
 | 
			
		||||
            m_ground(false),
 | 
			
		||||
            m_p_indexed(false),
 | 
			
		||||
            m_r_indexed(false),
 | 
			
		||||
            m_depth(0),
 | 
			
		||||
            m_const_count(0),
 | 
			
		||||
            m_sym_count(0) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        literal(expr * atom, bool sign = false):
 | 
			
		||||
            m_atom(atom), 
 | 
			
		||||
            m_sign(sign), 
 | 
			
		||||
            m_oriented(false), 
 | 
			
		||||
            m_left(false), 
 | 
			
		||||
            m_selected(false), 
 | 
			
		||||
            m_stats(false),    
 | 
			
		||||
            m_ground(false),
 | 
			
		||||
            m_p_indexed(false),
 | 
			
		||||
            m_r_indexed(false),
 | 
			
		||||
            m_depth(0),
 | 
			
		||||
            m_const_count(0),
 | 
			
		||||
            m_sym_count(0) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool sign() const { return m_sign; }
 | 
			
		||||
        bool pos() const { return !m_sign; }
 | 
			
		||||
        bool neg() const { return m_sign; }
 | 
			
		||||
        bool is_oriented() const { return m_oriented; }
 | 
			
		||||
        bool is_left() const { return m_left; }
 | 
			
		||||
        bool is_selected() const { return m_selected; }
 | 
			
		||||
        expr * atom() const { return m_atom; }
 | 
			
		||||
        expr * lhs() const { return to_app(m_atom)->get_arg(0); }
 | 
			
		||||
        expr * rhs() const { return to_app(m_atom)->get_arg(1); }
 | 
			
		||||
        unsigned get_id() const { return m_sign ? (to_app(m_atom)->get_id() << 1) + 1 : (to_app(m_atom)->get_id() << 1); }
 | 
			
		||||
        unsigned get_neg_id() const { return m_sign ? (to_app(m_atom)->get_id() << 1) : (to_app(m_atom)->get_id() << 1) + 1; }
 | 
			
		||||
 | 
			
		||||
        bool operator==(literal const & other) const { return m_atom == other.m_atom && m_sign == other.m_sign; }
 | 
			
		||||
        bool operator!=(literal const & other) const { return !operator==(other); }
 | 
			
		||||
 | 
			
		||||
        void set_p_indexed(bool f) { m_p_indexed = f; }
 | 
			
		||||
        void set_r_indexed(bool f) { m_r_indexed = f; }
 | 
			
		||||
        bool is_p_indexed() const { return m_p_indexed; }
 | 
			
		||||
        bool is_r_indexed() const { return m_r_indexed; }
 | 
			
		||||
 | 
			
		||||
        void try_to_orient(order & o);
 | 
			
		||||
        bool is_true(ast_manager & m) const {
 | 
			
		||||
            return 
 | 
			
		||||
                (!m_sign && m.is_true(m_atom)) || 
 | 
			
		||||
                (!m_sign && m.is_eq(m_atom) && to_app(m_atom)->get_arg(0) == to_app(m_atom)->get_arg(1)) ||
 | 
			
		||||
                (m_sign && m.is_false(m_atom));
 | 
			
		||||
        }
 | 
			
		||||
        bool is_false(ast_manager & m) const {
 | 
			
		||||
            return
 | 
			
		||||
                (m_sign && m.is_true(m_atom)) || 
 | 
			
		||||
                (m_sign && m.is_eq(m_atom) && to_app(m_atom)->get_arg(0) == to_app(m_atom)->get_arg(1)) ||
 | 
			
		||||
                (!m_sign && m.is_false(m_atom));
 | 
			
		||||
        }
 | 
			
		||||
        expr * to_expr(ast_manager & m) const;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Collect literal statistics
 | 
			
		||||
        */
 | 
			
		||||
        void get_stat(literal_stat & stat);
 | 
			
		||||
        void init_stat() { literal_stat st; get_stat(st); }
 | 
			
		||||
        bool has_stats() const { return m_stats; }
 | 
			
		||||
        bool is_ground() const { SASSERT(m_stats); return m_ground; }
 | 
			
		||||
        unsigned get_approx_depth() const { SASSERT(m_stats); return m_depth; }
 | 
			
		||||
        unsigned get_approx_const_count() const { SASSERT(m_stats); return m_const_count; }
 | 
			
		||||
        unsigned get_approx_sym_count() const { SASSERT(m_stats); return m_sym_count; }
 | 
			
		||||
 | 
			
		||||
        void display(std::ostream & out, ast_manager & m, bool detailed = false) const;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    COMPILE_TIME_ASSERT(sizeof(expr*) != 4 || sizeof(literal) == sizeof(expr *) + sizeof(unsigned)); // 32 bit machine
 | 
			
		||||
    COMPILE_TIME_ASSERT(sizeof(expr*) != 8 || sizeof(literal) == sizeof(expr *) + sizeof(unsigned) + /* a structure must be aligned */ sizeof(unsigned)); // 64 bit machine
 | 
			
		||||
 | 
			
		||||
    void display(std::ostream & out, unsigned num_lists, literal * lits, ast_manager & m, bool detailed = false);
 | 
			
		||||
 | 
			
		||||
    order::result compare(order & o, literal const & l1, literal const & l2, unsigned offset = 0, substitution * s = 0);
 | 
			
		||||
    bool greater(order & o, literal const & l1, literal const & l2, unsigned offset = 0, substitution * s = 0);
 | 
			
		||||
    bool is_maximal(order & o, unsigned num_lists, literal * lits, literal const & l, unsigned offset = 0, substitution * s = 0);
 | 
			
		||||
    bool is_sel_maximal(order & o, unsigned num_lists, literal * lits, literal const & l, unsigned offset = 0, substitution * s = 0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Set of found literals.
 | 
			
		||||
 | 
			
		||||
       This object is used to implement duplicate literal elimination, ans syntatic tautology.
 | 
			
		||||
    */
 | 
			
		||||
    class found_literals {
 | 
			
		||||
        bit_vector        m_marks;
 | 
			
		||||
        unsigned_vector   m_lit_ids;
 | 
			
		||||
    public:
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Insert the given literal into the set.
 | 
			
		||||
        */
 | 
			
		||||
        void insert(literal const & l);
 | 
			
		||||
        
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return true if the set contains \c l.
 | 
			
		||||
        */
 | 
			
		||||
        bool contains(literal const & l) const;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return true if the set contains the negation of \c l.
 | 
			
		||||
        */
 | 
			
		||||
        bool contains_neg(literal const & l) const;
 | 
			
		||||
 | 
			
		||||
        bool empty() const { return m_lit_ids.empty(); }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Remove all literals from the set.
 | 
			
		||||
        */
 | 
			
		||||
        void reset();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class literal_buffer {
 | 
			
		||||
        ast_manager &   m_manager;
 | 
			
		||||
        buffer<literal> m_lits;
 | 
			
		||||
    public:
 | 
			
		||||
        literal_buffer(ast_manager & m):
 | 
			
		||||
            m_manager(m) {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        ~literal_buffer() {
 | 
			
		||||
            reset();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        void push_back(literal const & l) { 
 | 
			
		||||
            m_manager.inc_ref(l.atom()); 
 | 
			
		||||
            m_lits.push_back(l); 
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        void reset();
 | 
			
		||||
 | 
			
		||||
        unsigned size() const {
 | 
			
		||||
            return m_lits.size();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        literal * c_ptr() const {
 | 
			
		||||
            return m_lits.c_ptr();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    expr * mk_or(ast_manager & m, unsigned num_lists, literal * lits);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_LITERAL_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,107 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_literal_selection.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Literal Selection
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-05.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_literal_selection.h"
 | 
			
		||||
#include"expr_stat.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    void diff_literal_selection::operator()(clause * cls) { 
 | 
			
		||||
        bool found = false;
 | 
			
		||||
        unsigned target = UINT_MAX;
 | 
			
		||||
        unsigned best_count = 0;
 | 
			
		||||
        unsigned num = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            literal & l = cls->get_literal(i);
 | 
			
		||||
            if (l.sign()) {
 | 
			
		||||
                unsigned count;
 | 
			
		||||
                if (m_manager.is_eq(l.atom())) {
 | 
			
		||||
                    unsigned c1 = get_symbol_count(to_app(l.atom())->get_arg(0));
 | 
			
		||||
                    unsigned c2 = get_symbol_count(to_app(l.atom())->get_arg(1));
 | 
			
		||||
                    count = c1 >= c2 ? c1 - c2 : c2 - c1;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    count = get_symbol_count(l.atom());
 | 
			
		||||
                }
 | 
			
		||||
                if (count > best_count) {
 | 
			
		||||
                    found      = true;
 | 
			
		||||
                    target     = i;
 | 
			
		||||
                    best_count = count;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (found)
 | 
			
		||||
            cls->select_literal(target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void complex_literal_selection::operator()(clause * cls) { 
 | 
			
		||||
        // look for x != y
 | 
			
		||||
        unsigned num = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            literal & l = cls->get_literal(i);
 | 
			
		||||
            if (l.sign() && m_manager.is_eq(l.atom()) && is_var(to_app(l.atom())->get_arg(0)) && is_var(to_app(l.atom())->get_arg(1))) {
 | 
			
		||||
                cls->select_literal(i);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // look for min ground neg literal
 | 
			
		||||
        bool found = false;
 | 
			
		||||
        unsigned target = UINT_MAX;
 | 
			
		||||
        unsigned  best_count = UINT_MAX;
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            literal & l = cls->get_literal(i);
 | 
			
		||||
            if (l.sign() && is_ground(l.atom())) {
 | 
			
		||||
                unsigned count = get_symbol_count(l.atom());
 | 
			
		||||
                if (count < best_count) {
 | 
			
		||||
                    found      = true;
 | 
			
		||||
                    target     = i;
 | 
			
		||||
                    best_count = count;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (found) {
 | 
			
		||||
            cls->select_literal(target);
 | 
			
		||||
            return;
 | 
			
		||||
        }        
 | 
			
		||||
        
 | 
			
		||||
        diff_literal_selection::operator()(cls);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void max_no_selection::operator()(clause * cls) {
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l1 = cls->get_literal(i);
 | 
			
		||||
            if (!l1.sign()) {
 | 
			
		||||
                unsigned j = 0;
 | 
			
		||||
                for (; j < num_lits; j++) {
 | 
			
		||||
                    if (i != j) {
 | 
			
		||||
                        literal const & l2 = cls->get_literal(j);
 | 
			
		||||
                        if (!greater(m_order, l1, l2))
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (j == num_lits)
 | 
			
		||||
                    return; // clause has maximal positive literal.
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        diff_literal_selection::operator()(cls);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,95 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_literal_selection.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Superposition Calculus Literal Selection
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-05.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_LITERAL_SELECTION_H_
 | 
			
		||||
#define _SPC_LITERAL_SELECTION_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"order.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Abstract functor for literal selection.
 | 
			
		||||
    */
 | 
			
		||||
    class literal_selection {
 | 
			
		||||
    public:
 | 
			
		||||
        virtual ~literal_selection() {}
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Updates the selected status flag of the literals of the given clause.
 | 
			
		||||
        */
 | 
			
		||||
        virtual void operator()(clause * cls) = 0;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Never selects a literal. This strategy is supposed to be good for planning problems 
 | 
			
		||||
       of TPTP.
 | 
			
		||||
    */
 | 
			
		||||
    class no_literal_selection : public literal_selection {
 | 
			
		||||
    public:
 | 
			
		||||
        virtual void operator()(clause * cls) {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Selects a negative literal l with the largest V(l)
 | 
			
		||||
       where V is defined as:
 | 
			
		||||
 | 
			
		||||
       - difference in symbol count for the left-right hand sides of equalities, .
 | 
			
		||||
 | 
			
		||||
       - symbol count for other predicates
 | 
			
		||||
       
 | 
			
		||||
    */
 | 
			
		||||
    class diff_literal_selection : public literal_selection {
 | 
			
		||||
    protected:
 | 
			
		||||
        ast_manager & m_manager;
 | 
			
		||||
    public:
 | 
			
		||||
        diff_literal_selection(ast_manager & m):m_manager(m) {}
 | 
			
		||||
        virtual void operator()(clause * cls);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
      \brief Selects a negative literal using the following algo:
 | 
			
		||||
 | 
			
		||||
      - if there is x != y, select it.
 | 
			
		||||
 | 
			
		||||
      - else if there is negative ground literal, select the smallest one.
 | 
			
		||||
 | 
			
		||||
      - else if use the approach in diff_literal_selection.
 | 
			
		||||
    */
 | 
			
		||||
    class complex_literal_selection : public diff_literal_selection {
 | 
			
		||||
    public:
 | 
			
		||||
        complex_literal_selection(ast_manager & m):diff_literal_selection(m) {}
 | 
			
		||||
        virtual void operator()(clause * cls);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Similar to diff_literal_selection, but a literal
 | 
			
		||||
       is not selected if the clause contains a positive literal
 | 
			
		||||
       greater than all other literals.
 | 
			
		||||
    */
 | 
			
		||||
    class max_no_selection : public diff_literal_selection {
 | 
			
		||||
        order & m_order;
 | 
			
		||||
    public:
 | 
			
		||||
        max_no_selection(order & o):diff_literal_selection(o.get_manager()), m_order(o) {}
 | 
			
		||||
        virtual void operator()(clause * cls);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_LITERAL_SELECTION_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,132 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_prover.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Stand-alone SPC prover (it is mainly for debugging purposes).
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-08.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_prover.h"
 | 
			
		||||
#include"spc_decl_plugin.h"
 | 
			
		||||
#include"for_each_expr.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    prover::prover(ast_manager & m, front_end_params & params):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_params(params),
 | 
			
		||||
        m_simplifier(m),
 | 
			
		||||
        m_defined_names(m),
 | 
			
		||||
        m_preprocessor(m, m_defined_names, m_simplifier, params),
 | 
			
		||||
        m_order(0),
 | 
			
		||||
        m_cls_sel(0),
 | 
			
		||||
        m_lit_sel(0),
 | 
			
		||||
        m_context(0),
 | 
			
		||||
        m_exprs(m),
 | 
			
		||||
        m_expr_proofs(m),
 | 
			
		||||
        m_has_theories(false) {
 | 
			
		||||
 | 
			
		||||
        family_id fid = m_manager.get_family_id("spc");
 | 
			
		||||
        if (!m_manager.has_plugin(fid)) 
 | 
			
		||||
            m_manager.register_plugin(fid, alloc(spc_decl_plugin));
 | 
			
		||||
 | 
			
		||||
        // This piece of code shows why the old model for passing parameters is broken.
 | 
			
		||||
        // spc::prover must overwrite some parameters, but this modification affects other
 | 
			
		||||
        // components. :-( 
 | 
			
		||||
        // TODO: move everything to the new params_ref object
 | 
			
		||||
        params.m_nnf_mode = NNF_FULL;
 | 
			
		||||
        params.m_cnf_mode = CNF_FULL;
 | 
			
		||||
        params.m_lift_ite = LI_CONSERVATIVE;
 | 
			
		||||
 | 
			
		||||
        basic_simplifier_plugin * basic = alloc(basic_simplifier_plugin, m_manager);
 | 
			
		||||
        m_simplifier.register_plugin(basic);
 | 
			
		||||
        m_simplifier.register_plugin(alloc(arith_simplifier_plugin, m_manager, *basic, params));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    prover::~prover() {
 | 
			
		||||
        if (m_context) {
 | 
			
		||||
            dealloc(m_context);
 | 
			
		||||
            dealloc(m_lit_sel);
 | 
			
		||||
            dealloc(m_cls_sel);
 | 
			
		||||
            dealloc(m_order);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void prover::init() {
 | 
			
		||||
        if (m_context)
 | 
			
		||||
            return;
 | 
			
		||||
        precedence * p = mk_precedence(m_manager, m_params);
 | 
			
		||||
 | 
			
		||||
        // TODO use params to configure the following functors.
 | 
			
		||||
        m_order    = alloc(kbo, m_manager, p); 
 | 
			
		||||
        
 | 
			
		||||
        clause_eval * evals[2]  = { alloc(symbol_count_clause_eval), alloc(time_clause_eval) };
 | 
			
		||||
        unsigned      slots[2] = { 10, 1 };
 | 
			
		||||
        m_cls_sel  = alloc(clause_selection, 2, evals, slots);
 | 
			
		||||
        
 | 
			
		||||
        m_lit_sel  = alloc(max_no_selection, *m_order);
 | 
			
		||||
        // m_lit_sel  = new complex_literal_selection(m_manager);
 | 
			
		||||
        // m_lit_sel  = new diff_literal_selection(m_manager);
 | 
			
		||||
        // m_lit_sel  = new no_literal_selection(); // new diff_literal_selection(m_manager);
 | 
			
		||||
        // END TODO
 | 
			
		||||
        
 | 
			
		||||
        m_context  = alloc(context, m_manager, *m_order, *m_cls_sel, *m_lit_sel, m_simplifier, m_params);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct has_theories_proc {
 | 
			
		||||
        ast_manager & m_manager;
 | 
			
		||||
        has_theories_proc(ast_manager & m):m_manager(m) {}
 | 
			
		||||
        struct found {}; 
 | 
			
		||||
        void operator()(var * n) {}
 | 
			
		||||
        void operator()(app * n) { if (!m_manager.is_builtin_family_id(n->get_family_id())) throw found(); }
 | 
			
		||||
        void operator()(quantifier * n) {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    bool has_theories(ast_manager & m, expr * e) {
 | 
			
		||||
        has_theories_proc p(m);
 | 
			
		||||
        try {
 | 
			
		||||
            for_each_expr(p, e);
 | 
			
		||||
        }
 | 
			
		||||
        catch (has_theories_proc::found) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    void prover::assert_expr(expr * e) {
 | 
			
		||||
        if (!m_has_theories && has_theories(m_manager, e))
 | 
			
		||||
            m_has_theories = true;
 | 
			
		||||
        TRACE("spc_assert", tout << mk_pp(e, m_manager) << "\nhas_theories: " << m_has_theories << "\n";);
 | 
			
		||||
        m_preprocessor(e, m_manager.mk_asserted(e), m_exprs, m_expr_proofs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lbool prover::check() {
 | 
			
		||||
        init();
 | 
			
		||||
        unsigned sz = m_exprs.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
            expr * curr = m_exprs.get(i);
 | 
			
		||||
            proof * p   = m_manager.proofs_enabled() ? m_expr_proofs.get(i) : m_manager.mk_undef_proof();
 | 
			
		||||
            m_context->assert_expr(curr, p);
 | 
			
		||||
        }
 | 
			
		||||
        m_exprs.reset();
 | 
			
		||||
        m_expr_proofs.reset();
 | 
			
		||||
 | 
			
		||||
        m_context->saturate(m_params.m_spc_num_iterations);
 | 
			
		||||
        if (m_context->inconsistent())
 | 
			
		||||
            return l_false;
 | 
			
		||||
        else if (m_context->processed_all())
 | 
			
		||||
            return m_has_theories ? l_undef : l_true;
 | 
			
		||||
        else
 | 
			
		||||
            return l_undef;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,59 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_prover.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Stand-alone SPC prover (it is mainly for debugging purposes).
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-08.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_PROVER_H_
 | 
			
		||||
#define _SPC_PROVER_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_context.h"
 | 
			
		||||
#include"front_end_params.h"
 | 
			
		||||
#include"kbo.h"
 | 
			
		||||
#include"lpo.h"
 | 
			
		||||
#include"basic_simplifier_plugin.h"
 | 
			
		||||
#include"arith_simplifier_plugin.h"
 | 
			
		||||
#include"preprocessor.h"
 | 
			
		||||
#include"defined_names.h"
 | 
			
		||||
#include"lbool.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    class prover {
 | 
			
		||||
        ast_manager &           m_manager;
 | 
			
		||||
        front_end_params &      m_params;
 | 
			
		||||
        simplifier              m_simplifier;
 | 
			
		||||
        defined_names           m_defined_names;
 | 
			
		||||
        preprocessor            m_preprocessor;
 | 
			
		||||
        order *                 m_order;
 | 
			
		||||
        clause_selection *      m_cls_sel;
 | 
			
		||||
        literal_selection *     m_lit_sel;
 | 
			
		||||
        context *               m_context;
 | 
			
		||||
        expr_ref_vector         m_exprs;
 | 
			
		||||
        proof_ref_vector        m_expr_proofs;
 | 
			
		||||
        bool                    m_has_theories;
 | 
			
		||||
 | 
			
		||||
        void init();
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        prover(ast_manager & m, front_end_params & params);
 | 
			
		||||
        ~prover();
 | 
			
		||||
        void assert_expr(expr * e);
 | 
			
		||||
        lbool check();
 | 
			
		||||
        void display_statistics(std::ostream & out) const { if (m_context) m_context->display_statistics(out); }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_PROVER_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,269 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_rewrite.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-12.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_rewriter.h"
 | 
			
		||||
#include"spc_decl_plugin.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    rewriter::rewriter(ast_manager & m, simplifier & simp, order & ord, asserted_literals & al):
 | 
			
		||||
        simplifier(m),
 | 
			
		||||
        m_asserted_literals(al),
 | 
			
		||||
        m_order(ord),
 | 
			
		||||
        m_spc_fid(m.get_family_id("spc")),
 | 
			
		||||
        m_subst(m),
 | 
			
		||||
        m_st(m),
 | 
			
		||||
        m_visitor(m_order, m_subst, m_cls_use_list) {
 | 
			
		||||
 | 
			
		||||
        reserve_offsets(3);
 | 
			
		||||
 | 
			
		||||
        borrow_plugins(simp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rewriter::~rewriter() {
 | 
			
		||||
        release_plugins();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    inline void rewriter::reserve_vars(unsigned num_vars) {
 | 
			
		||||
        m_subst.reserve_vars(num_vars);
 | 
			
		||||
        m_order.reserve_vars(num_vars);
 | 
			
		||||
        m_asserted_literals.reserve_vars(num_vars);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void rewriter::reserve_offsets(unsigned num_offsets) {
 | 
			
		||||
        m_subst.reserve_offsets(num_offsets);
 | 
			
		||||
        m_order.reserve_offsets(num_offsets);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline bool rewriter::demodulator(clause * cls) const {
 | 
			
		||||
        if (cls->get_num_literals() != 1)
 | 
			
		||||
            return false;
 | 
			
		||||
        literal const & l = cls->get_literal(0);
 | 
			
		||||
        return !l.sign() && m_manager.is_eq(l.atom());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void rewriter::insert(clause * cls, expr * source) {
 | 
			
		||||
        if (!is_var(source)) {
 | 
			
		||||
            TRACE("rewriter_detail", tout << "inserting into rewriter index:\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            flush_cache();
 | 
			
		||||
            m_st.insert(to_app(source));
 | 
			
		||||
            m_cls_use_list.insert(cls, source);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void rewriter::insert(clause * cls) {
 | 
			
		||||
        if (demodulator(cls)) {
 | 
			
		||||
            reserve_vars(cls->get_num_vars());
 | 
			
		||||
            literal const & l = cls->get_literal(0);
 | 
			
		||||
            app * eq = to_app(l.atom());
 | 
			
		||||
            if (l.is_oriented()) {
 | 
			
		||||
                expr * source = l.is_left() ? eq->get_arg(0) : eq->get_arg(1);
 | 
			
		||||
                insert(cls, source);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                insert(cls, eq->get_arg(0));
 | 
			
		||||
                insert(cls, eq->get_arg(1));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void rewriter::erase(clause * cls, expr * source) {
 | 
			
		||||
        if (!is_var(source)) {
 | 
			
		||||
            flush_cache();
 | 
			
		||||
            m_cls_use_list.erase(cls, source);
 | 
			
		||||
            if (m_cls_use_list.empty(source))
 | 
			
		||||
                m_st.erase(to_app(source));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void rewriter::erase(clause * cls) {
 | 
			
		||||
        if (demodulator(cls)) {
 | 
			
		||||
            literal const & l = cls->get_literal(0);
 | 
			
		||||
            app * eq = to_app(l.atom());
 | 
			
		||||
            if (l.is_oriented()) {
 | 
			
		||||
                expr * source = l.is_left() ? eq->get_arg(0) : eq->get_arg(1);
 | 
			
		||||
                erase(cls, source);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                erase(cls, eq->get_arg(0));
 | 
			
		||||
                erase(cls, eq->get_arg(1));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool rewriter::visitor::operator()(expr * e) {
 | 
			
		||||
        if (m_cls_use_list.empty(e)) 
 | 
			
		||||
            return true; // continue;
 | 
			
		||||
        clause_use_list::iterator it  = m_cls_use_list.begin(e);
 | 
			
		||||
        clause_use_list::iterator end = m_cls_use_list.end(e);
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            m_clause = *it;
 | 
			
		||||
            SASSERT(m_clause->get_num_literals() == 1);
 | 
			
		||||
            literal & l = m_clause->get_literal(0);
 | 
			
		||||
            expr * atom = l.atom();
 | 
			
		||||
            SASSERT(!l.sign() && m_manager.is_eq(atom));
 | 
			
		||||
            SASSERT(to_app(atom)->get_arg(0) == e || to_app(atom)->get_arg(1) == e);
 | 
			
		||||
            m_source = to_app(atom)->get_arg(0);
 | 
			
		||||
            m_target = to_app(atom)->get_arg(1);
 | 
			
		||||
            if (m_source != e)
 | 
			
		||||
                std::swap(m_source, m_target);
 | 
			
		||||
            SASSERT(m_source == e);
 | 
			
		||||
            TRACE("rewriter", tout << "found generalization:\n" << mk_pp(m_source, m_manager) << "\n" << 
 | 
			
		||||
                  mk_pp(m_target, m_manager) << "\nsubstitution\n";
 | 
			
		||||
                  m_subst.display(tout); tout << "m_subst: " << &m_subst << "\n";
 | 
			
		||||
                  tout << "checking ordering constraints...\n";);
 | 
			
		||||
            if (l.is_oriented() || m_order.greater(expr_offset(m_source, 1), expr_offset(m_target, 1), &m_subst)) {
 | 
			
		||||
                m_found = true;
 | 
			
		||||
                return false; // stop
 | 
			
		||||
            }
 | 
			
		||||
            TRACE("rewriter", tout << "failed ordering constraints...\n";);
 | 
			
		||||
        }
 | 
			
		||||
        return true; // continue
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void rewriter::save_justification(justification * j) {
 | 
			
		||||
        if (std::find(m_justifications.begin(), m_justifications.end(), j) == m_justifications.end())
 | 
			
		||||
            m_justifications.push_back(j);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    proof * rewriter::mk_demodulation_proof(expr * old_expr, expr * new_expr, proof * parent) {
 | 
			
		||||
        if (m_manager.fine_grain_proofs()) {
 | 
			
		||||
            SASSERT(parent);
 | 
			
		||||
            return m_manager.mk_app(m_spc_fid, PR_DEMODULATION, parent, m_manager.mk_eq(old_expr, new_expr));
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void rewriter::reset() {
 | 
			
		||||
        m_st.reset();
 | 
			
		||||
        m_cls_use_list.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void rewriter::reduce_literal(literal const & l, literal & l_r, proof * & l_pr) {
 | 
			
		||||
        if (m_st.empty()) {
 | 
			
		||||
            l_r = l;
 | 
			
		||||
            l_pr = 0;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        expr * atom = l.atom();
 | 
			
		||||
        expr *  r;
 | 
			
		||||
        proof * r_pr;
 | 
			
		||||
        m_proofs.reset();
 | 
			
		||||
        while (true) {
 | 
			
		||||
            reduce_core(atom);
 | 
			
		||||
            get_cached(atom, r, r_pr);
 | 
			
		||||
            if (m_manager.fine_grain_proofs() && r_pr)
 | 
			
		||||
                m_proofs.push_back(r_pr);
 | 
			
		||||
            if (atom == r)
 | 
			
		||||
                break;
 | 
			
		||||
            atom = r;
 | 
			
		||||
        }
 | 
			
		||||
        l_r = literal(atom, l.sign());
 | 
			
		||||
        if (m_manager.fine_grain_proofs())
 | 
			
		||||
            l_pr = m_proofs.empty() ? 0 : m_manager.mk_transitivity(m_proofs.size(), m_proofs.c_ptr());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clause * rewriter::operator()(clause * cls) {
 | 
			
		||||
        reserve_vars(cls->get_num_vars());
 | 
			
		||||
        SASSERT(m_found_literals.empty());
 | 
			
		||||
        m_justifications.reset();
 | 
			
		||||
        m_max_scope_lvl = cls->get_scope_lvl();
 | 
			
		||||
        
 | 
			
		||||
        literal_buffer    new_literals(m_manager);
 | 
			
		||||
        proof_ref_buffer  new_proofs(m_manager);
 | 
			
		||||
        bool              changed = false;
 | 
			
		||||
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal & l = cls->get_literal(i);
 | 
			
		||||
            literal l_r;
 | 
			
		||||
            proof * l_pr = 0;
 | 
			
		||||
            reduce_literal(l, l_r, l_pr);
 | 
			
		||||
         
 | 
			
		||||
            if (l != l_r) {
 | 
			
		||||
                changed = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!l_r.is_false(m_manager) && !m_found_literals.contains(l_r)) {
 | 
			
		||||
                m_found_literals.insert(l_r);
 | 
			
		||||
 | 
			
		||||
                // apply simplify reflect rules
 | 
			
		||||
                expr * atom     = l_r.atom();
 | 
			
		||||
                clause * unit = 0;
 | 
			
		||||
                TRACE("rewriter", tout << "adding literal: " << mk_pp(atom, m_manager) << "\n";);
 | 
			
		||||
                if (l_r.sign()) {
 | 
			
		||||
                    if (m_manager.is_eq(atom))
 | 
			
		||||
                        unit = m_asserted_literals.subsumes(to_app(atom)->get_arg(0), to_app(atom)->get_arg(1));
 | 
			
		||||
                    else
 | 
			
		||||
                        unit = m_asserted_literals.gen(atom, false);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    // check if there is a generalization of the negation of the current literal.
 | 
			
		||||
                    unit = m_asserted_literals.gen(atom, true);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (unit) {
 | 
			
		||||
                    // new literal was resolved
 | 
			
		||||
                    justification * j = unit->get_justification();
 | 
			
		||||
                    m_justifications.push_back(j);
 | 
			
		||||
                    changed = true;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    // keep new literal
 | 
			
		||||
                    new_literals.push_back(l_r);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                // removed duplicate or resolved literal.
 | 
			
		||||
                changed = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (m_manager.fine_grain_proofs() && l_pr != 0) {
 | 
			
		||||
                new_proofs.push_back(l_pr);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_found_literals.reset();
 | 
			
		||||
 | 
			
		||||
        if (!changed) {
 | 
			
		||||
            m_found_literals.reset();
 | 
			
		||||
            return cls;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        proof * new_pr = mk_rewrite_proof(m_manager, m_spc_fid, new_literals.size(), new_literals.c_ptr(), cls->get_justification()->get_proof(), 
 | 
			
		||||
                                          new_proofs.size(), new_proofs.c_ptr());
 | 
			
		||||
 | 
			
		||||
        justification * new_j = rewrite_justification::mk(m_manager, cls->get_justification(), m_justifications.size(), m_justifications.c_ptr(), new_pr);
 | 
			
		||||
        
 | 
			
		||||
        if (m_max_scope_lvl == cls->get_scope_lvl()) {
 | 
			
		||||
            // peform destructive update
 | 
			
		||||
            cls->update_lits(m_manager, new_literals.size(), new_literals.c_ptr(), new_j);
 | 
			
		||||
            return cls;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            SASSERT(m_max_scope_lvl > cls->get_scope_lvl());
 | 
			
		||||
            // create new clause
 | 
			
		||||
            // the old clause will be frozen
 | 
			
		||||
            return clause::mk(m_manager, new_literals.size(), new_literals.c_ptr(), new_j, m_max_scope_lvl);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,122 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_rewriter.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-11.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_REWRITER_H_
 | 
			
		||||
#define _SPC_REWRITER_H_
 | 
			
		||||
 | 
			
		||||
#include"simplifier.h"
 | 
			
		||||
#include"order.h"
 | 
			
		||||
#include"substitution_tree.h"
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"spc_asserted_literals.h"
 | 
			
		||||
#include"sparse_use_list.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Apply rewriting steps using demodulation rule:
 | 
			
		||||
 | 
			
		||||
       C[s] ==> C[sigma(r)]
 | 
			
		||||
       when 
 | 
			
		||||
       
 | 
			
		||||
       l = r is a known equality (demodulator)
 | 
			
		||||
       sigma(l) = s
 | 
			
		||||
       sigma(l) > sigma(r)
 | 
			
		||||
 | 
			
		||||
       It also applies the following rules:
 | 
			
		||||
       
 | 
			
		||||
       - Duplicate literal deletion
 | 
			
		||||
 | 
			
		||||
       - Resolved literal deletion
 | 
			
		||||
 | 
			
		||||
       - Positive simplify reflect
 | 
			
		||||
       s = t,  (u[p <- sigma(s)] != u[p <- sigma(t)] or R)
 | 
			
		||||
       ==>
 | 
			
		||||
       R
 | 
			
		||||
   
 | 
			
		||||
       - Negative simplify reflect
 | 
			
		||||
       s != t  (sigma(s = t) or R)
 | 
			
		||||
       ===>
 | 
			
		||||
       R
 | 
			
		||||
    */
 | 
			
		||||
    class rewriter : public simplifier {
 | 
			
		||||
    protected:
 | 
			
		||||
        typedef sparse_use_list<expr, ptr_vector<clause> > clause_use_list;
 | 
			
		||||
        asserted_literals &       m_asserted_literals;
 | 
			
		||||
        order &                   m_order;
 | 
			
		||||
        family_id                 m_spc_fid;
 | 
			
		||||
 | 
			
		||||
        substitution              m_subst;
 | 
			
		||||
        substitution_tree         m_st; // index for potential demodulators left-hand-side
 | 
			
		||||
        clause_use_list           m_cls_use_list; // index for demodulators left-hand-side to equation.
 | 
			
		||||
        found_literals            m_found_literals;
 | 
			
		||||
 | 
			
		||||
        ptr_vector<justification> m_justifications;
 | 
			
		||||
 | 
			
		||||
        struct visitor : public st_visitor {
 | 
			
		||||
            ast_manager &     m_manager;
 | 
			
		||||
            order &           m_order;
 | 
			
		||||
            clause_use_list & m_cls_use_list;
 | 
			
		||||
            bool              m_found;
 | 
			
		||||
            clause *          m_clause;
 | 
			
		||||
            expr *            m_source;
 | 
			
		||||
            expr *            m_target;
 | 
			
		||||
 | 
			
		||||
            visitor(order & ord, substitution & subst, clause_use_list & ul):
 | 
			
		||||
                st_visitor(subst), m_manager(ord.get_manager()), m_order(ord), m_cls_use_list(ul) {
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            virtual bool operator()(expr * e);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        unsigned                  m_max_scope_lvl; // maximal scope level used during rewrite.
 | 
			
		||||
        visitor                   m_visitor;
 | 
			
		||||
 | 
			
		||||
        proof * mk_demodulation_proof(expr * old_expr, expr * new_expr, proof * parent);
 | 
			
		||||
 | 
			
		||||
        bool demodulator(clause * cls) const;
 | 
			
		||||
        void insert(clause * cls, expr * source);
 | 
			
		||||
        void erase(clause * cls, expr * source);
 | 
			
		||||
        void reserve_vars(unsigned num_vars);
 | 
			
		||||
        void reserve_offsets(unsigned num_offsets);
 | 
			
		||||
        void save_justification(justification * j);
 | 
			
		||||
 | 
			
		||||
        void reduce_literal(literal const & l, literal & l_r, proof * & l_pr);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        rewriter(ast_manager & m, simplifier & s, order & ord, asserted_literals & al);
 | 
			
		||||
        virtual ~rewriter();
 | 
			
		||||
        
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Insert clause into rewriter indexes
 | 
			
		||||
        */
 | 
			
		||||
        void insert(clause * cls);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Remove clause from rewriter indexes
 | 
			
		||||
        */
 | 
			
		||||
        void erase(clause * cls);
 | 
			
		||||
        
 | 
			
		||||
        clause * operator()(clause * cls);
 | 
			
		||||
 | 
			
		||||
        void reset();
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_REWRITER_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,234 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_semantic_tautology.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-11.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_semantic_tautology.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    expr * find(expr2expr & f, expr * n) {
 | 
			
		||||
#ifdef _TRACE
 | 
			
		||||
        expr * _n = n;
 | 
			
		||||
#endif
 | 
			
		||||
        ptr_buffer<expr> path;
 | 
			
		||||
        expr * next;
 | 
			
		||||
        while (f.find(n, next)) {
 | 
			
		||||
            path.push_back(n);
 | 
			
		||||
            n = next;
 | 
			
		||||
        }
 | 
			
		||||
        ptr_buffer<expr>::iterator it  = path.begin();
 | 
			
		||||
        ptr_buffer<expr>::iterator end = path.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            expr * prev = *it;
 | 
			
		||||
            f.insert(prev, n);
 | 
			
		||||
        }
 | 
			
		||||
        SASSERT(n);
 | 
			
		||||
        TRACE("semantic_tautology_detail", tout << "find(#" << _n->get_id() << ") = #" << n->get_id() << "\n";);
 | 
			
		||||
        return n;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    semantic_tautology::semantic_tautology(ast_manager & m):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_cg_table(DEFAULT_HASHTABLE_INITIAL_CAPACITY, cg_hash(m_manager, m_find), cg_eq(m_find)) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned semantic_tautology::cg_hash::operator()(app * n) const { 
 | 
			
		||||
        TRACE("semantic_tautology_detail", tout << "hash code of:\n" << mk_pp(n, m_manager) << "\n";);
 | 
			
		||||
        unsigned r = get_composite_hash<app *, k_hash, c_hash>(n, n->get_num_args(), m_k_hash, m_c_hash); 
 | 
			
		||||
        TRACE("semantic_tautology_detail", tout << "result: " << r << "\n";);
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool semantic_tautology::cg_eq::operator()(app * n1, app * n2) const {
 | 
			
		||||
        if (n1->get_decl() != n2->get_decl() || n1->get_num_args() != n2->get_num_args())
 | 
			
		||||
            return false;
 | 
			
		||||
        unsigned num_args = n1->get_num_args();
 | 
			
		||||
        for (unsigned i = 0; i < num_args; i++)
 | 
			
		||||
            if (spc::find(m_find, n1->get_arg(i)) != spc::find(m_find, n2->get_arg(i)))
 | 
			
		||||
                return false;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    bool semantic_tautology::is_target(unsigned num_lits, literal * lits) {
 | 
			
		||||
        bool has_diseq     = false;
 | 
			
		||||
        bool has_non_diseq = false;
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = lits[i];
 | 
			
		||||
            if (l.sign() && m_manager.is_eq(l.atom())) 
 | 
			
		||||
                has_diseq = true;
 | 
			
		||||
            else 
 | 
			
		||||
                has_non_diseq = true;
 | 
			
		||||
        }
 | 
			
		||||
        return has_diseq && has_non_diseq;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::reset() {
 | 
			
		||||
        m_region.reset();
 | 
			
		||||
        m_init_todo.reset();
 | 
			
		||||
        m_todo.reset();
 | 
			
		||||
        m_already_found.reset();
 | 
			
		||||
        m_use_list.reset();
 | 
			
		||||
        m_find.reset();
 | 
			
		||||
        m_size.reset();
 | 
			
		||||
        m_cg_table.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::update_use_list(app * parent, expr * child) {
 | 
			
		||||
        list<app*> * use_list = 0;
 | 
			
		||||
        m_use_list.find(child, use_list);
 | 
			
		||||
        use_list = new (m_region) list<app*>(parent, use_list);
 | 
			
		||||
        m_use_list.insert(child, use_list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void semantic_tautology::push_init_core(expr * n) {
 | 
			
		||||
        if (is_app(n) && to_app(n)->get_num_args() > 0)
 | 
			
		||||
            m_init_todo.push_back(to_app(n));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void semantic_tautology::push_init(expr * atom) {
 | 
			
		||||
        if (m_manager.is_eq(atom)) {
 | 
			
		||||
            push_init_core(to_app(atom)->get_arg(0));
 | 
			
		||||
            push_init_core(to_app(atom)->get_arg(1));
 | 
			
		||||
        }
 | 
			
		||||
        else 
 | 
			
		||||
            push_init_core(atom);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::init_use_list() {
 | 
			
		||||
        while (!m_init_todo.empty()) {
 | 
			
		||||
            app * n = m_init_todo.back();
 | 
			
		||||
            m_init_todo.pop_back();
 | 
			
		||||
            if (!m_already_found.contains(n)) {
 | 
			
		||||
                unsigned num_args = n->get_num_args();
 | 
			
		||||
                SASSERT(num_args > 0);
 | 
			
		||||
                m_cg_table.insert(n);
 | 
			
		||||
                m_already_found.insert(n);
 | 
			
		||||
                for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
                    expr * c = n->get_arg(i);
 | 
			
		||||
                    update_use_list(n, c);
 | 
			
		||||
                    push_init_core(c);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::init(unsigned num_lits, literal * lits) {
 | 
			
		||||
        reset();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = lits[i];
 | 
			
		||||
            expr * atom = l.atom();
 | 
			
		||||
            push_init(atom);
 | 
			
		||||
            if (l.sign() && m_manager.is_eq(atom))
 | 
			
		||||
                m_todo.push_back(expr_pair(to_app(atom)->get_arg(0), to_app(atom)->get_arg(1)));
 | 
			
		||||
        }
 | 
			
		||||
        init_use_list();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::remove_parents(expr * n1) {
 | 
			
		||||
        list<app*> * use_list = 0;
 | 
			
		||||
        m_use_list.find(n1, use_list);
 | 
			
		||||
        while (use_list) {
 | 
			
		||||
            TRACE("semantic_tautology", tout << "removing parent from cg_table:\n" << mk_pp(use_list->head(), m_manager) << "\n";);
 | 
			
		||||
            m_cg_table.erase(use_list->head());
 | 
			
		||||
            use_list = use_list->tail();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::restore_parents(expr * n1, expr * n2) {
 | 
			
		||||
        list<app*> * use_list = 0;
 | 
			
		||||
        m_use_list.find(n1, use_list);
 | 
			
		||||
        while (use_list) {
 | 
			
		||||
            app * parent = use_list->head();
 | 
			
		||||
            app * other  = 0;
 | 
			
		||||
            if (m_cg_table.find(parent, other)) {
 | 
			
		||||
                TRACE("semantic_tautology", tout << "new congruence:\n" << mk_pp(parent, m_manager) << "\n" << mk_pp(other, m_manager) << "\n";);
 | 
			
		||||
                if (parent != other)
 | 
			
		||||
                    m_todo.push_back(expr_pair(parent, other));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                TRACE("semantic_tautology", tout << "restoring parent to cg_table:\n" << mk_pp(parent, m_manager) << "\n";);
 | 
			
		||||
                m_cg_table.insert(parent);
 | 
			
		||||
                update_use_list(parent, n2);
 | 
			
		||||
            }
 | 
			
		||||
            use_list = use_list->tail();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::assert_eq(expr * n1, expr * n2) {
 | 
			
		||||
        n1 = find(n1);
 | 
			
		||||
        n2 = find(n2);
 | 
			
		||||
        if (n1 == n2)
 | 
			
		||||
            return;
 | 
			
		||||
        TRACE("semantic_tautology", tout << "processing equality:\n" << mk_pp(n1, m_manager) << " " << n1->get_id() << "\n" << 
 | 
			
		||||
              mk_pp(n2, m_manager) << " " << n2->get_id() << "\n";);
 | 
			
		||||
        unsigned sz1 = 1;
 | 
			
		||||
        unsigned sz2 = 1;
 | 
			
		||||
        m_size.find(n1, sz1);
 | 
			
		||||
        m_size.find(n2, sz2);
 | 
			
		||||
        if (sz1 > sz2)
 | 
			
		||||
            std::swap(n1, n2);
 | 
			
		||||
        remove_parents(n1);
 | 
			
		||||
        TRACE("semantic_tautology", tout << "merging equivalence classes\n";);
 | 
			
		||||
        m_find.insert(n1, n2);
 | 
			
		||||
        m_size.insert(n2, sz1 + sz2);
 | 
			
		||||
        restore_parents(n1, n2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void semantic_tautology::process_eqs() {
 | 
			
		||||
        while (!m_todo.empty()) {
 | 
			
		||||
            expr_pair const & p = m_todo.back();
 | 
			
		||||
            expr * lhs = p.first;
 | 
			
		||||
            expr * rhs = p.second;
 | 
			
		||||
            m_todo.pop_back();
 | 
			
		||||
            assert_eq(lhs, rhs);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    bool semantic_tautology::contains_complement(unsigned num_lits, literal * lits, unsigned i, bool sign, expr * atom) {
 | 
			
		||||
        atom = find(atom);
 | 
			
		||||
        for (unsigned j = i + 1; j < num_lits; j++) {
 | 
			
		||||
            literal const & l = lits[j];
 | 
			
		||||
            if (l.sign() != sign && find(l.atom()) == atom)
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    bool semantic_tautology::is_tautology(unsigned num_lits, literal * lits) {
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = lits[i];
 | 
			
		||||
            expr * atom       = l.atom();
 | 
			
		||||
            if (!l.sign() && m_manager.is_eq(atom) && find(to_app(atom)->get_arg(0)) == find(to_app(atom)->get_arg(1))) 
 | 
			
		||||
                return true;
 | 
			
		||||
            if (!m_manager.is_eq(atom) && contains_complement(num_lits, lits, i, l.sign(), atom))
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    bool semantic_tautology::operator()(unsigned num_lits, literal * lits) {
 | 
			
		||||
        if (!is_target(num_lits, lits))
 | 
			
		||||
            return false;
 | 
			
		||||
        init(num_lits, lits);
 | 
			
		||||
        process_eqs();
 | 
			
		||||
        bool r = is_tautology(num_lits, lits);
 | 
			
		||||
        TRACE("semantic_tautology", display(tout, num_lits, lits, m_manager); tout << "\nis semantic tautology: " << r << "\n";);
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,114 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_semantic_tautology.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Semantic tautology detection
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-11.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_SEMANTIC_TAUTOLOGY_H_
 | 
			
		||||
#define _SPC_SEMANTIC_TAUTOLOGY_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_literal.h"
 | 
			
		||||
#include"list.h"
 | 
			
		||||
#include"obj_hashtable.h"
 | 
			
		||||
#include"map.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    typedef obj_map<expr, expr *> expr2expr;
 | 
			
		||||
 | 
			
		||||
    expr * find(expr2expr & f, expr * e);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Functor for detecting semantic tautology.
 | 
			
		||||
       A clause C is a semantic tautology if it has the following form:
 | 
			
		||||
 | 
			
		||||
       s_1 != t_1 or ... or s_n != t_n or s = t or R
 | 
			
		||||
 | 
			
		||||
       sigma(s_1 = t_1), ..., sigma(s_n t_n) |= sigma(s = t)
 | 
			
		||||
       where sigma maps variables to constants.
 | 
			
		||||
    */
 | 
			
		||||
    class semantic_tautology {
 | 
			
		||||
        typedef std::pair<expr *, expr *> expr_pair;
 | 
			
		||||
        
 | 
			
		||||
        typedef obj_hashtable<expr> already_found;
 | 
			
		||||
        typedef expr2expr find_map;
 | 
			
		||||
        typedef obj_map<expr, list<app*> *> use_list;
 | 
			
		||||
        typedef obj_map<expr, unsigned> size_map;        
 | 
			
		||||
 | 
			
		||||
        struct k_hash {
 | 
			
		||||
            unsigned operator()(app * n) const { return n->get_decl()->get_id(); }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct c_hash {
 | 
			
		||||
            find_map & m_find;
 | 
			
		||||
            c_hash(find_map & f):m_find(f) {}
 | 
			
		||||
            unsigned operator()(app * n, unsigned i) const { 
 | 
			
		||||
                unsigned id = spc::find(m_find, n->get_arg(i))->get_id();
 | 
			
		||||
                TRACE("semantic_tautology_detail", tout << "child(" << i << ") = #" << id << "\n";);
 | 
			
		||||
                return id;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct cg_hash {
 | 
			
		||||
            ast_manager & m_manager;
 | 
			
		||||
            k_hash     m_k_hash;
 | 
			
		||||
            c_hash     m_c_hash;
 | 
			
		||||
            cg_hash(ast_manager & m, find_map & f):m_manager(m), m_c_hash(f) {}
 | 
			
		||||
            unsigned operator()(app * n) const;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct cg_eq {
 | 
			
		||||
            find_map & m_find;
 | 
			
		||||
            cg_eq(find_map & f):m_find(f) {}
 | 
			
		||||
            bool operator()(app * n1, app * n2) const;
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        typedef ptr_hashtable<app, cg_hash, cg_eq> cg_table;
 | 
			
		||||
 | 
			
		||||
        ast_manager &      m_manager;
 | 
			
		||||
        region             m_region;
 | 
			
		||||
        ptr_vector<app>    m_init_todo;
 | 
			
		||||
        svector<expr_pair> m_todo;
 | 
			
		||||
        already_found      m_already_found;
 | 
			
		||||
        use_list           m_use_list;
 | 
			
		||||
        find_map           m_find;
 | 
			
		||||
        size_map           m_size;
 | 
			
		||||
        cg_table           m_cg_table;
 | 
			
		||||
 | 
			
		||||
        bool is_target(unsigned num_lits, literal * lits);
 | 
			
		||||
        void reset();
 | 
			
		||||
        void update_use_list(app * parent, expr * child);
 | 
			
		||||
        void push_init_core(expr * n);
 | 
			
		||||
        void push_init(expr * atom);
 | 
			
		||||
        void init_use_list();
 | 
			
		||||
        void init(unsigned num_lits, literal * lits);
 | 
			
		||||
        expr * find(expr * n) { return spc::find(m_find, n); }
 | 
			
		||||
        void remove_parents(expr * n1);
 | 
			
		||||
        void restore_parents(expr * n1, expr * n2);
 | 
			
		||||
        void assert_eq(expr * n1, expr * n2);
 | 
			
		||||
        void process_eqs();
 | 
			
		||||
        bool contains_complement(unsigned num_lits, literal * lits, unsigned i, bool sign, expr * atom);
 | 
			
		||||
        bool is_tautology(unsigned num_lits, literal * lits);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        semantic_tautology(ast_manager & m);
 | 
			
		||||
        
 | 
			
		||||
        bool operator()(unsigned num_lits, literal * lits);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_SEMANTIC_TAUTOLOGY_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_statistics.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-17.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_statistics.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
    
 | 
			
		||||
    void statistics::reset() {
 | 
			
		||||
        m_num_mk_clause = 0;
 | 
			
		||||
        m_num_del_clause = 0;
 | 
			
		||||
        m_num_processed = 0;
 | 
			
		||||
        m_num_superposition = 0;
 | 
			
		||||
        m_num_resolution = 0;
 | 
			
		||||
        m_num_eq_factoring = 0;
 | 
			
		||||
        m_num_factoring = 0;
 | 
			
		||||
        m_num_eq_resolution = 0;
 | 
			
		||||
        m_num_trivial = 0;
 | 
			
		||||
        m_num_simplified = 0;
 | 
			
		||||
        m_num_subsumed = 0;
 | 
			
		||||
        m_num_redundant = 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void statistics::display(std::ostream & out) const {
 | 
			
		||||
        out << "num. mk. clause:    " << m_num_mk_clause << "\n";
 | 
			
		||||
        out << "num. del. clause:   " << m_num_del_clause << "\n";
 | 
			
		||||
        out << "num. processed:     " << m_num_processed << "\n";
 | 
			
		||||
        out << "num. superposition: " << m_num_superposition << "\n";
 | 
			
		||||
        out << "num. resolution:    " << m_num_resolution << "\n";
 | 
			
		||||
        out << "num. eq. factoring: " << m_num_eq_factoring << "\n";
 | 
			
		||||
        out << "num. factoring:     " << m_num_factoring << "\n";
 | 
			
		||||
        out << "num. eq. resol.:    " << m_num_eq_resolution << "\n";
 | 
			
		||||
        out << "num. simplified:    " << m_num_simplified << "\n";
 | 
			
		||||
        out << "num. redundant:     " << m_num_redundant << "\n";
 | 
			
		||||
        out << "  num. trivial:     " << m_num_trivial << "\n";
 | 
			
		||||
        out << "  num. subsumed:    " << m_num_subsumed << "\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_statistics.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-17.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_STATISTICS_H_
 | 
			
		||||
#define _SPC_STATISTICS_H_
 | 
			
		||||
 | 
			
		||||
#include<iostream>
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    struct statistics {
 | 
			
		||||
        unsigned m_num_mk_clause;
 | 
			
		||||
        unsigned m_num_del_clause;
 | 
			
		||||
        unsigned m_num_processed;
 | 
			
		||||
        unsigned m_num_superposition;
 | 
			
		||||
        unsigned m_num_resolution;
 | 
			
		||||
        unsigned m_num_eq_factoring;
 | 
			
		||||
        unsigned m_num_factoring;
 | 
			
		||||
        unsigned m_num_eq_resolution;
 | 
			
		||||
        unsigned m_num_trivial;
 | 
			
		||||
        unsigned m_num_simplified;
 | 
			
		||||
        unsigned m_num_subsumed;
 | 
			
		||||
        unsigned m_num_redundant;
 | 
			
		||||
        statistics() {
 | 
			
		||||
            reset();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        void reset();
 | 
			
		||||
        void display(std::ostream & out) const;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_STATISTICS_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,698 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_subsumption.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-13.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_subsumption.h"
 | 
			
		||||
#include"fvi_def.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if literal l2 is an instance of l1.
 | 
			
		||||
       
 | 
			
		||||
       When ResetSubst == true, m_subst is reset before trying to match l1 and l2.
 | 
			
		||||
 | 
			
		||||
       When ResetSubst == false, it is assumed that m_subst.push_scope was invoked
 | 
			
		||||
       before invoking match_literal. 
 | 
			
		||||
    */
 | 
			
		||||
    template<bool ResetSubst>
 | 
			
		||||
    bool subsumption::match_literal(literal const & l1, literal const & l2) {
 | 
			
		||||
        if (l1.sign() == l2.sign()) {
 | 
			
		||||
            expr * atom1 = l1.atom();
 | 
			
		||||
            expr * atom2 = l2.atom();
 | 
			
		||||
            bool is_eq1  = m_manager.is_eq(atom1);
 | 
			
		||||
            bool is_eq2  = m_manager.is_eq(atom2);
 | 
			
		||||
            if (is_eq1 && is_eq2) {
 | 
			
		||||
                expr * lhs1 = to_app(atom1)->get_arg(0);
 | 
			
		||||
                expr * rhs1 = to_app(atom1)->get_arg(1);
 | 
			
		||||
                expr * lhs2 = to_app(atom2)->get_arg(0);
 | 
			
		||||
                expr * rhs2 = to_app(atom2)->get_arg(1);
 | 
			
		||||
                if (ResetSubst) 
 | 
			
		||||
                    m_subst.reset_subst();
 | 
			
		||||
                
 | 
			
		||||
                if (m_matcher(lhs1, lhs2, m_subst) && m_matcher(rhs1, rhs2, m_subst))
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                if (ResetSubst)
 | 
			
		||||
                    m_subst.reset_subst();
 | 
			
		||||
                else {
 | 
			
		||||
                    // I'm assuming push_scope was invoked before executing match_literal
 | 
			
		||||
                    // So, pop_scope is equivalent to a local reset.
 | 
			
		||||
                    m_subst.pop_scope();
 | 
			
		||||
                    m_subst.push_scope();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return (m_matcher(lhs1, rhs2, m_subst) && m_matcher(rhs1, lhs2, m_subst));
 | 
			
		||||
            }
 | 
			
		||||
            else if (!is_eq1 && !is_eq2) {
 | 
			
		||||
                if (ResetSubst) 
 | 
			
		||||
                    m_subst.reset_subst();
 | 
			
		||||
                return m_matcher(atom1, atom2, m_subst);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if for every literal l1 in lits1 there is a
 | 
			
		||||
       literal l2 in lits2 such that l2 is an instance of l1.
 | 
			
		||||
    */
 | 
			
		||||
    bool subsumption::can_subsume(unsigned num_lits1, literal * lits1, unsigned num_lits2, literal * lits2) {
 | 
			
		||||
        for (unsigned i = 0; i < num_lits1; i++) {
 | 
			
		||||
            literal const & l1 = lits1[i];
 | 
			
		||||
            unsigned j = 0;
 | 
			
		||||
            for (; j < num_lits2; j++) {
 | 
			
		||||
                literal const & l2 = lits2[j];
 | 
			
		||||
                if (match_literal<true>(l1, l2))
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            if (j == num_lits2)
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if cls1 can subsume cls2. It performs a series of quick checks.
 | 
			
		||||
    */
 | 
			
		||||
    bool subsumption::quick_check(clause * cls1, clause * cls2) {
 | 
			
		||||
        return 
 | 
			
		||||
            cls1->get_symbol_count() <= cls2->get_symbol_count() &&
 | 
			
		||||
            cls1->get_const_count() <= cls2->get_const_count() &&
 | 
			
		||||
            cls1->get_depth() <= cls2->get_depth() &&
 | 
			
		||||
            cls1->get_num_pos_literals() <= cls2->get_num_pos_literals() &&
 | 
			
		||||
            cls1->get_num_neg_literals() <= cls2->get_num_neg_literals() &&
 | 
			
		||||
            (!cls1->is_ground() || cls2->is_ground());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if the set of literals lits1 subsumes the set of literals lits2.
 | 
			
		||||
    */
 | 
			
		||||
    bool subsumption::subsumes_core(unsigned num_lits1, literal * lits1, unsigned num_lits2, literal * lits2) {
 | 
			
		||||
        enum state {
 | 
			
		||||
            INVOKE, DECIDE, BACKTRACK, RETURN
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (num_lits1 == 0)
 | 
			
		||||
            return true;
 | 
			
		||||
        
 | 
			
		||||
        m_stack.reset();
 | 
			
		||||
        m_subst.reset();
 | 
			
		||||
 | 
			
		||||
        m_stack.push_back(assoc(0, 0));
 | 
			
		||||
        state st = DECIDE;
 | 
			
		||||
 | 
			
		||||
        unsigned i;
 | 
			
		||||
        assoc * top;
 | 
			
		||||
        unsigned counter = 0;
 | 
			
		||||
#ifdef _TRACE
 | 
			
		||||
        unsigned opt  = 0;
 | 
			
		||||
        unsigned nopt = 0;
 | 
			
		||||
#endif
 | 
			
		||||
        while (true && counter < 5000000) {
 | 
			
		||||
            counter++;
 | 
			
		||||
            switch (st) {
 | 
			
		||||
            case INVOKE:
 | 
			
		||||
                SASSERT(!m_stack.empty());
 | 
			
		||||
                i = m_stack.back().first + 1;
 | 
			
		||||
                if (i >= num_lits1) {
 | 
			
		||||
                    TRACE("subsumption", tout << "subsumption result: YES.\n";);
 | 
			
		||||
                    TRACE_CODE({
 | 
			
		||||
                        if (counter > 10000) {
 | 
			
		||||
                            TRACE("subsumption_perf", 
 | 
			
		||||
                                  tout << "subsumption succeeded: " << counter << " " << opt << " " << nopt << "\n";
 | 
			
		||||
                                  tout << "literals1:\n"; display(tout, num_lits1, lits1, m_manager); tout << "\n";
 | 
			
		||||
                                  tout << "literals2:\n"; display(tout, num_lits2, lits2, m_manager); tout << "\n";);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    m_stack.push_back(assoc(i, 0));
 | 
			
		||||
                    st = DECIDE;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DECIDE:
 | 
			
		||||
                top = &(m_stack.back());
 | 
			
		||||
                m_subst.push_scope();
 | 
			
		||||
                if (match_literal<false>(lits1[top->first], lits2[top->second]))
 | 
			
		||||
                    st = INVOKE;
 | 
			
		||||
                else
 | 
			
		||||
                    st = BACKTRACK;
 | 
			
		||||
                break;
 | 
			
		||||
            case BACKTRACK: 
 | 
			
		||||
                top = &(m_stack.back());
 | 
			
		||||
                top->second++;
 | 
			
		||||
                m_subst.pop_scope();
 | 
			
		||||
                if (top->second >= num_lits2) 
 | 
			
		||||
                    st = RETURN;
 | 
			
		||||
                else
 | 
			
		||||
                    st = DECIDE;
 | 
			
		||||
                break;
 | 
			
		||||
            case RETURN:
 | 
			
		||||
                top = &(m_stack.back());
 | 
			
		||||
                m_stack.pop_back();
 | 
			
		||||
                if (m_stack.empty()) {
 | 
			
		||||
                    // no more alternatives
 | 
			
		||||
                    TRACE("subsumption", tout << "subsumption result: NO\n";);
 | 
			
		||||
                    TRACE_CODE({
 | 
			
		||||
                        if (counter > 10000) {
 | 
			
		||||
                            TRACE("subsumption_perf",
 | 
			
		||||
                                  tout << "subsumption failed: " << counter << " " << opt << " " << nopt << "\n";
 | 
			
		||||
                                  tout << "literals1:\n"; display(tout, num_lits1, lits1, m_manager); tout << "\n";
 | 
			
		||||
                                  tout << "literals2:\n"; display(tout, num_lits2, lits2, m_manager); tout << "\n";);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (m_subst.top_scope_has_bindings()) {
 | 
			
		||||
                    TRACE_CODE(nopt++;);
 | 
			
		||||
                    st  = BACKTRACK;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    TRACE_CODE(opt++;);
 | 
			
		||||
#ifdef Z3DEBUG
 | 
			
		||||
                    unsigned num_bindings = m_subst.get_num_bindings();
 | 
			
		||||
#endif
 | 
			
		||||
                    m_subst.pop_scope();
 | 
			
		||||
                    SASSERT(num_bindings == m_subst.get_num_bindings());
 | 
			
		||||
                    st = RETURN;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if the set of ground literals lits1 subsumes the set of ground literals lits2.
 | 
			
		||||
    */
 | 
			
		||||
    bool subsumption::ground_subsumes_core(unsigned num_lits1, literal * lits1, unsigned num_lits2, literal * lits2) {
 | 
			
		||||
        for (unsigned i = 0; i < num_lits1; i++) {
 | 
			
		||||
            literal const & l1 = lits1[i];
 | 
			
		||||
            unsigned j = 0;
 | 
			
		||||
            for (; j < num_lits2; j++) {
 | 
			
		||||
                literal const & l2 = lits2[j];
 | 
			
		||||
                if (l1 == l2)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            if (j == num_lits2)
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if the literal l1 subsumes the set of literals lits2.
 | 
			
		||||
    */
 | 
			
		||||
    bool subsumption::subsumes_core(literal const & l1, unsigned num_lits2, literal * lits2) {
 | 
			
		||||
        for (unsigned i = 0; i < num_lits2; i++) {
 | 
			
		||||
            if (match_literal<true>(l1, lits2[i]))
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    subsumption::subsumption(ast_manager & m, asserted_literals & al, spc_params & params):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_params(params),
 | 
			
		||||
        m_asserted_literals(al),
 | 
			
		||||
        m_subst(m),
 | 
			
		||||
        m_matcher(m),
 | 
			
		||||
        m_found_decls(m), 
 | 
			
		||||
        m_index(0),
 | 
			
		||||
        m_num_processed_clauses(0),
 | 
			
		||||
        m_opt_threshold(params.m_initial_subsumption_index_opt) {
 | 
			
		||||
 | 
			
		||||
        m_subst.reserve_offsets(1);
 | 
			
		||||
        
 | 
			
		||||
        init_indexes();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    subsumption::~subsumption() {
 | 
			
		||||
        if (m_index) 
 | 
			
		||||
            dealloc(m_index);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return true if cls1 subsumes cls2
 | 
			
		||||
    */
 | 
			
		||||
    bool subsumption::operator()(clause * cls1, clause * cls2) {
 | 
			
		||||
        TRACE("subsumption_detail", tout << "checking if:\n"; cls1->display(tout, m_manager); tout << "\nsubsumes\n";
 | 
			
		||||
              cls2->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        if (!quick_check(cls1, cls2)) {
 | 
			
		||||
            TRACE("subsumption_detail", tout << "failed quick check\n";);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
       
 | 
			
		||||
        m_subst.reserve_vars(std::max(cls1->get_num_vars(), cls2->get_num_vars()));
 | 
			
		||||
        unsigned num_lits1 = cls1->get_num_literals();
 | 
			
		||||
        unsigned num_lits2 = cls2->get_num_literals();
 | 
			
		||||
        literal * lits1    = cls1->get_literals();
 | 
			
		||||
        literal * lits2    = cls2->get_literals();
 | 
			
		||||
        if (cls1->is_ground() && cls2->is_ground())
 | 
			
		||||
            return ground_subsumes_core(num_lits1, lits1, num_lits2, lits2);
 | 
			
		||||
        if (num_lits1 == 1)
 | 
			
		||||
            return subsumes_core(lits1[0], num_lits2, lits2);
 | 
			
		||||
        // TODO: REMOVE true below... using it for debugging purposes.
 | 
			
		||||
        if (true || cls1->get_num_neg_literals() >= 3 || cls1->get_num_pos_literals() >= 3)
 | 
			
		||||
            if (!can_subsume(num_lits1, lits1, num_lits2, lits2)) {
 | 
			
		||||
                TRACE("subsumption_detail", tout << "failed can_subsume\n";);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        return subsumes_core(num_lits1, lits1, num_lits2, lits2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Update the set of function symbols found in the clause being inserted into the index,
 | 
			
		||||
       and the set of clauses found since the index started to be built.
 | 
			
		||||
       
 | 
			
		||||
       Return true if the function symbol should be tracked.
 | 
			
		||||
    */
 | 
			
		||||
    bool subsumption::mark_func_decl(func_decl * f) {
 | 
			
		||||
        if (m_refining_index) {
 | 
			
		||||
            if (!m_cls_found_decl_set.contains(f)) {
 | 
			
		||||
                // update set of func_decls in the curr clause
 | 
			
		||||
                m_cls_found_decl_set.insert(f);
 | 
			
		||||
                m_cls_found_decls.push_back(f);
 | 
			
		||||
                // update global set of founf func_decls
 | 
			
		||||
                unsigned id = f->get_decl_id();
 | 
			
		||||
                m_found_decl_set.reserve(id+1);
 | 
			
		||||
                if (!m_found_decl_set.get(id)) {
 | 
			
		||||
                    m_found_decl_set.set(id);
 | 
			
		||||
                    m_found_decls.push_back(f);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            unsigned id = f->get_decl_id();
 | 
			
		||||
            // if func_decl was not found yet, then ignore it.
 | 
			
		||||
            if (id < m_found_decl_set.size() && m_found_decl_set.get(id)) {
 | 
			
		||||
                if (!m_cls_found_decl_set.contains(f)) {
 | 
			
		||||
                    // update set of func_decls in the curr clause
 | 
			
		||||
                    m_cls_found_decl_set.insert(f);
 | 
			
		||||
                    m_cls_found_decls.push_back(f);
 | 
			
		||||
                }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Increment the number of occurrences of a function symbol in the clause being
 | 
			
		||||
       inserted into the index.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::inc_f_count(func_decl * f, bool neg) {
 | 
			
		||||
        decl2nat & f_count = m_f_count[static_cast<unsigned>(neg)];
 | 
			
		||||
        unsigned val;
 | 
			
		||||
        if (f_count.find(f, val)) {
 | 
			
		||||
            f_count.insert(f, val + 1);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            f_count.insert(f, 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Update the min/max num. of occurrences of func symbol in a clause.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::update_min_max(func_decl * f) {
 | 
			
		||||
        for (unsigned is_neg = 0; is_neg < 1; is_neg++) {
 | 
			
		||||
            decl2nat & f_count = m_f_count[is_neg];
 | 
			
		||||
            decl2nat & f_min   = m_f_min[is_neg];
 | 
			
		||||
            decl2nat & f_max   = m_f_max[is_neg];
 | 
			
		||||
            unsigned count;
 | 
			
		||||
            if (f_count.find(f, count)) {
 | 
			
		||||
                unsigned old_count;
 | 
			
		||||
                if (!f_min.find(f, old_count) || old_count > count) {
 | 
			
		||||
                    f_min.insert(f, count);
 | 
			
		||||
                }
 | 
			
		||||
                if (!f_max.find(f, old_count) || old_count < count) {
 | 
			
		||||
                    f_max.insert(f, count);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Compute the number of occurences of function symbols in
 | 
			
		||||
       a clause.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::update_neg_pos_func_counts(clause * cls) {
 | 
			
		||||
        m_f_count[0].reset();
 | 
			
		||||
        m_f_count[1].reset();
 | 
			
		||||
        m_cls_found_decl_set.reset();
 | 
			
		||||
        m_cls_found_decls.reset();
 | 
			
		||||
        ptr_buffer<expr> todo;
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = cls->get_literal(i);
 | 
			
		||||
            bool is_neg       = l.sign();
 | 
			
		||||
            expr * n          = l.atom();
 | 
			
		||||
            todo.push_back(n);
 | 
			
		||||
            while (!todo.empty()) {
 | 
			
		||||
                n = todo.back();
 | 
			
		||||
                todo.pop_back();
 | 
			
		||||
                if (is_app(n)) {
 | 
			
		||||
                    func_decl * f = to_app(n)->get_decl();
 | 
			
		||||
                    if (fvi_candidate(f) && mark_func_decl(f)) 
 | 
			
		||||
                        inc_f_count(f, is_neg);
 | 
			
		||||
                    unsigned num = to_app(n)->get_num_args();
 | 
			
		||||
                    for (unsigned i = 0; i < num; i++) 
 | 
			
		||||
                        todo.push_back(to_app(n)->get_arg(i));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (m_refining_index) {
 | 
			
		||||
            ptr_vector<func_decl>::iterator it  = m_cls_found_decls.begin();
 | 
			
		||||
            ptr_vector<func_decl>::iterator end = m_cls_found_decls.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                func_decl * f = *it;
 | 
			
		||||
                update_min_max(f);
 | 
			
		||||
                unsigned val;
 | 
			
		||||
                if (m_f_freq.find(f, val))
 | 
			
		||||
                    m_f_freq.insert(f, val + 1);
 | 
			
		||||
                else
 | 
			
		||||
                    m_f_freq.insert(f, 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Store in m_feature_vector the value for the features of cls.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::compute_features(clause * cls, unsigned * fvector) {
 | 
			
		||||
        unsigned num = m_features.size();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            feature & f = m_features[i];
 | 
			
		||||
            switch (f.m_kind) {
 | 
			
		||||
            case F_GROUND:
 | 
			
		||||
                fvector[i] = cls->is_ground();
 | 
			
		||||
                break;
 | 
			
		||||
            case F_NUM_POS_LITS:
 | 
			
		||||
                fvector[i] = cls->get_num_pos_literals();
 | 
			
		||||
                break;
 | 
			
		||||
            case F_NUM_NEG_LITS:
 | 
			
		||||
                fvector[i] = cls->get_num_neg_literals();
 | 
			
		||||
                break;
 | 
			
		||||
            case F_DEPTH:
 | 
			
		||||
                fvector[i] = cls->get_depth();
 | 
			
		||||
                break;
 | 
			
		||||
            case F_CONST_COUNT:
 | 
			
		||||
                fvector[i] = cls->get_const_count();
 | 
			
		||||
                break;
 | 
			
		||||
            case F_SYM_COUNT:
 | 
			
		||||
                fvector[i] = cls->get_symbol_count();
 | 
			
		||||
                break;
 | 
			
		||||
            case F_NUM_NEG_FUNCS: {
 | 
			
		||||
                unsigned val;
 | 
			
		||||
                if (m_f_count[1].find(f.m_decl, val)) 
 | 
			
		||||
                    fvector[i] = val;
 | 
			
		||||
                else
 | 
			
		||||
                    fvector[i] = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case F_NUM_POS_FUNCS: {
 | 
			
		||||
                unsigned val;
 | 
			
		||||
                if (m_f_count[0].find(f.m_decl, val)) 
 | 
			
		||||
                    fvector[i] = val;
 | 
			
		||||
                else
 | 
			
		||||
                    fvector[i] = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                UNREACHABLE();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        TRACE("subsumption_features",
 | 
			
		||||
              tout << "features of: "; cls->display(tout, m_manager); tout << "\n";
 | 
			
		||||
              for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
                  tout << fvector[i] << " ";
 | 
			
		||||
              }
 | 
			
		||||
              tout << "\n";);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Initialise indexes for forward/backward subsumption.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::init_indexes() {
 | 
			
		||||
        // index for forward/backward subsumption
 | 
			
		||||
        // start with simple set of features
 | 
			
		||||
        m_features.push_back(feature(F_GROUND));
 | 
			
		||||
        m_features.push_back(feature(F_NUM_POS_LITS));
 | 
			
		||||
        m_features.push_back(feature(F_NUM_NEG_LITS));
 | 
			
		||||
        m_features.push_back(feature(F_DEPTH));
 | 
			
		||||
        m_features.push_back(feature(F_CONST_COUNT));
 | 
			
		||||
        m_features.push_back(feature(F_SYM_COUNT));
 | 
			
		||||
        m_index = alloc(index, m_features.size(), to_feature_vector(*this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned subsumption::get_value_range(func_decl * f, bool neg) const {
 | 
			
		||||
        unsigned i = static_cast<unsigned>(neg);
 | 
			
		||||
        unsigned min;
 | 
			
		||||
        unsigned max;
 | 
			
		||||
        if (!m_f_min[i].find(f, min))
 | 
			
		||||
            min = 0;
 | 
			
		||||
        if (!m_f_max[i].find(f, max))
 | 
			
		||||
            max = 0;
 | 
			
		||||
        SASSERT(min <= max);
 | 
			
		||||
        return max - min;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline unsigned subsumption::get_value_range(func_decl * f) const {
 | 
			
		||||
        return std::max(get_value_range(f, false), get_value_range(f, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool subsumption::f_lt::operator()(func_decl * f1, func_decl * f2) const {
 | 
			
		||||
        unsigned vrange1 = m_owner.get_value_range(f1);
 | 
			
		||||
        unsigned vrange2 = m_owner.get_value_range(f2);
 | 
			
		||||
        if (vrange1 < vrange2)
 | 
			
		||||
            return true;
 | 
			
		||||
        if (vrange1 == vrange2)
 | 
			
		||||
            return f1->get_id() < f2->get_id();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Optimize the index for (non unit) forward subsumption and 
 | 
			
		||||
       backward subsumption.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::optimize_feature_index() {
 | 
			
		||||
        ptr_vector<clause> clauses;
 | 
			
		||||
        m_index->collect(clauses);
 | 
			
		||||
 | 
			
		||||
        dealloc(m_index);
 | 
			
		||||
        m_features.reset();
 | 
			
		||||
 | 
			
		||||
        ptr_vector<func_decl> targets;
 | 
			
		||||
        unsigned sz = m_found_decls.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
            func_decl * f = m_found_decls.get(i);
 | 
			
		||||
            unsigned val;
 | 
			
		||||
            if (m_f_freq.find(f, val) && val > m_params.m_min_func_freq_subsumption_index && get_value_range(f) > 0) 
 | 
			
		||||
                targets.push_back(f);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        f_lt lt(*this);
 | 
			
		||||
        std::sort(targets.begin(), targets.end(), lt);
 | 
			
		||||
        
 | 
			
		||||
        m_features.push_back(feature(F_GROUND));
 | 
			
		||||
        m_features.push_back(feature(F_NUM_POS_LITS));
 | 
			
		||||
        m_features.push_back(feature(F_NUM_NEG_LITS));
 | 
			
		||||
        m_features.push_back(feature(F_DEPTH));
 | 
			
		||||
       
 | 
			
		||||
        ptr_vector<func_decl>::iterator it  = targets.begin();
 | 
			
		||||
        ptr_vector<func_decl>::iterator end = targets.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            func_decl * f = *it;
 | 
			
		||||
            if (get_value_range(f, false) > 1)
 | 
			
		||||
                m_features.push_back(feature(f, false));
 | 
			
		||||
            if (get_value_range(f, true) > 1)
 | 
			
		||||
                m_features.push_back(feature(f, true));
 | 
			
		||||
            if (m_features.size() > m_params.m_max_subsumption_index_features)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        m_features.push_back(feature(F_CONST_COUNT));
 | 
			
		||||
        m_features.push_back(feature(F_SYM_COUNT));
 | 
			
		||||
        m_index = alloc(index, m_features.size(), to_feature_vector(*this));
 | 
			
		||||
        m_num_processed_clauses = 0;
 | 
			
		||||
        unsigned new_threshold = static_cast<unsigned>(m_opt_threshold * m_params.m_factor_subsumption_index_opt);
 | 
			
		||||
        if (new_threshold > m_opt_threshold)
 | 
			
		||||
            m_opt_threshold = new_threshold;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Insert cls into the indexes used for forward/backward subsumption.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::insert(clause * cls) {
 | 
			
		||||
        TRACE("subsumption", tout << "adding clause to subsumption index: " << cls << "\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        if (num_lits > 1 || m_params.m_backward_subsumption) {
 | 
			
		||||
            m_index->insert(cls);
 | 
			
		||||
            SASSERT(m_index->contains(cls));
 | 
			
		||||
            m_num_processed_clauses++;
 | 
			
		||||
            if (m_num_processed_clauses > m_opt_threshold)
 | 
			
		||||
                optimize_feature_index();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Remove cls from the indexes used for forward/backward subsumption.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::erase(clause * cls) {
 | 
			
		||||
        TRACE("subsumption", tout << "removing clause from subsumption index:" << cls << "\n"; cls->display(tout, m_manager); tout << "\n";
 | 
			
		||||
              tout << "num lits.: " << cls->get_num_literals() << ", backward_sub: " << m_params.m_backward_subsumption << "\n";);
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        if (num_lits > 1 || m_params.m_backward_subsumption)
 | 
			
		||||
            m_index->erase(cls);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Reset the indexes used for forward/backward subsumption.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::reset() {
 | 
			
		||||
        if (m_index)
 | 
			
		||||
            m_index->reset();
 | 
			
		||||
        m_num_processed_clauses = 0;
 | 
			
		||||
        m_opt_threshold = m_params.m_initial_subsumption_index_opt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return an unit clause C in the index that subsumes cls.
 | 
			
		||||
       Return 0 if such clause does not exist.
 | 
			
		||||
    */
 | 
			
		||||
    clause * subsumption::unit_forward(clause * cls) {
 | 
			
		||||
        if (!m_asserted_literals.has_literals())
 | 
			
		||||
            return 0;
 | 
			
		||||
        m_asserted_literals.reserve_vars(cls->get_num_vars());
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = cls->get_literal(i);
 | 
			
		||||
            clause * subsumer = m_asserted_literals.gen(l);
 | 
			
		||||
            if (subsumer)
 | 
			
		||||
                return subsumer;
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct non_unit_subsumption_visitor {
 | 
			
		||||
        subsumption & m_owner;
 | 
			
		||||
        clause *      m_new_clause;
 | 
			
		||||
        clause *      m_subsumer;
 | 
			
		||||
        non_unit_subsumption_visitor(subsumption & owner, clause * new_clause):
 | 
			
		||||
            m_owner(owner),
 | 
			
		||||
            m_new_clause(new_clause),
 | 
			
		||||
            m_subsumer(0) {
 | 
			
		||||
        }
 | 
			
		||||
        bool operator()(clause * candidate) {
 | 
			
		||||
            TRACE("subsumption_index", tout << "considering candidate:\n"; candidate->display(tout, m_owner.get_manager()); tout << "\n";);
 | 
			
		||||
            if (candidate->get_num_literals() > 1 && m_owner(candidate, m_new_clause)) {
 | 
			
		||||
                m_subsumer = candidate;
 | 
			
		||||
                return false; // stop subsumer was found
 | 
			
		||||
            }
 | 
			
		||||
            return true; // continue;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return a non unit clause C in the index that subsumes cls.
 | 
			
		||||
       Return 0 if such clause does not exist.
 | 
			
		||||
    */
 | 
			
		||||
    clause * subsumption::non_unit_forward(clause * cls) {
 | 
			
		||||
        non_unit_subsumption_visitor visitor(*this, cls);
 | 
			
		||||
        m_index->visit(cls, visitor, true);
 | 
			
		||||
        return visitor.m_subsumer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return a unit equality clause (= s t) that (eq) subsumes cls.
 | 
			
		||||
       That is, cls contains a literal (= u[s'] u[t']) and there is 
 | 
			
		||||
       a substitution sigma s.t. sigma(s) = s' and sigma(t) = t'.
 | 
			
		||||
       Return 0 if such clause does not exist.
 | 
			
		||||
    */
 | 
			
		||||
    clause * subsumption::eq_subsumption(clause * cls) {
 | 
			
		||||
        if (!m_asserted_literals.has_pos_literals())
 | 
			
		||||
            return 0;
 | 
			
		||||
        m_asserted_literals.reserve_vars(cls->get_num_vars());
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = cls->get_literal(i);
 | 
			
		||||
            expr * atom = l.atom();
 | 
			
		||||
            if (!l.sign() && m_manager.is_eq(atom)) {
 | 
			
		||||
                expr * lhs = to_app(atom)->get_arg(0);
 | 
			
		||||
                expr * rhs = to_app(atom)->get_arg(1);
 | 
			
		||||
                clause * subsumer = m_asserted_literals.subsumes(lhs, rhs);
 | 
			
		||||
                if (subsumer) {
 | 
			
		||||
                    TRACE("eq_subsumption", tout << "equality subsumption:\n"; cls->display(tout, m_manager); 
 | 
			
		||||
                          tout << "\nis subsumed by:\n"; subsumer->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
                    return subsumer;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Return a clause C in the index (i.e., insert(C) was invoked) that subsumes cls.
 | 
			
		||||
       Return 0 if such clause does not exist.
 | 
			
		||||
    */
 | 
			
		||||
    clause * subsumption::forward(clause * cls) {
 | 
			
		||||
        TRACE("subsumption", tout << "trying forward subsumption:\n"; cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        clause * subsumer = unit_forward(cls);
 | 
			
		||||
        if (subsumer)
 | 
			
		||||
            return subsumer;
 | 
			
		||||
        subsumer = non_unit_forward(cls);
 | 
			
		||||
        if (subsumer)
 | 
			
		||||
            return subsumer;
 | 
			
		||||
        if (m_params.m_equality_subsumption) 
 | 
			
		||||
            return eq_subsumption(cls);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct backward_subsumption_visitor {
 | 
			
		||||
        subsumption &        m_owner;
 | 
			
		||||
        clause *             m_new_clause;
 | 
			
		||||
        ptr_buffer<clause> & m_result;
 | 
			
		||||
        backward_subsumption_visitor(subsumption & owner, clause * new_clause, ptr_buffer<clause> & result):
 | 
			
		||||
            m_owner(owner),
 | 
			
		||||
            m_new_clause(new_clause),
 | 
			
		||||
            m_result(result) {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        bool operator()(clause * candidate) {
 | 
			
		||||
            if (m_owner(m_new_clause, candidate))
 | 
			
		||||
                m_result.push_back(candidate); 
 | 
			
		||||
            return true; // always continue in backward subsumption
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Store in result the set of clauses in the index that are subsumes by cls.
 | 
			
		||||
    */
 | 
			
		||||
    void subsumption::backward(clause * cls, ptr_buffer<clause> & result) {
 | 
			
		||||
        if (m_params.m_backward_subsumption) {
 | 
			
		||||
            backward_subsumption_visitor visitor(*this, cls, result);
 | 
			
		||||
            m_index->visit(cls, visitor, false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,156 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_subsumption.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-13.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_SUBSUMPTION_H_
 | 
			
		||||
#define _SPC_SUBSUMPTION_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_asserted_literals.h"
 | 
			
		||||
#include"matcher.h"
 | 
			
		||||
#include"fvi.h"
 | 
			
		||||
#include"spc_params.h"
 | 
			
		||||
#include"obj_hashtable.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    class subsumption {
 | 
			
		||||
        ast_manager &         m_manager;
 | 
			
		||||
        spc_params &          m_params;
 | 
			
		||||
        asserted_literals &   m_asserted_literals;
 | 
			
		||||
        substitution          m_subst;
 | 
			
		||||
        matcher               m_matcher;
 | 
			
		||||
 | 
			
		||||
        // A pair representing the association between l1 and l2 where
 | 
			
		||||
        // first is the position of l1 in lits1 and second the position of l2 in
 | 
			
		||||
        // lits2.
 | 
			
		||||
        typedef std::pair<unsigned, unsigned> assoc; 
 | 
			
		||||
        typedef vector<assoc> stack;
 | 
			
		||||
        stack m_stack;
 | 
			
		||||
 | 
			
		||||
        template<bool ResetSubst>
 | 
			
		||||
        bool match_literal(literal const & l1, literal const & l2);
 | 
			
		||||
 | 
			
		||||
        bool can_subsume(unsigned num_lits1, literal * lits1, unsigned num_lits2, literal * lits2);
 | 
			
		||||
        bool quick_check(clause * cls1, clause * cls2);
 | 
			
		||||
        bool subsumes_core(unsigned num_lits1, literal * lits1, unsigned num_lits2, literal * lits2);
 | 
			
		||||
        bool subsumes_core(literal const & l1, unsigned num_lits2, literal * lits2);
 | 
			
		||||
        bool ground_subsumes_core(unsigned num_lits1, literal * lits1, unsigned num_lits2, literal * lits2);
 | 
			
		||||
 | 
			
		||||
        enum feature_kind {
 | 
			
		||||
            F_GROUND,
 | 
			
		||||
            F_NUM_POS_LITS,
 | 
			
		||||
            F_NUM_NEG_LITS,
 | 
			
		||||
            F_DEPTH,
 | 
			
		||||
            F_CONST_COUNT,
 | 
			
		||||
            F_SYM_COUNT,
 | 
			
		||||
            F_NUM_NEG_FUNCS,
 | 
			
		||||
            F_NUM_POS_FUNCS
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct feature {
 | 
			
		||||
            feature_kind m_kind;
 | 
			
		||||
            func_decl *  m_decl;
 | 
			
		||||
            feature(feature_kind k = F_GROUND):m_kind(k) {}
 | 
			
		||||
            feature(func_decl * decl, bool neg):m_kind(neg ? F_NUM_NEG_FUNCS : F_NUM_POS_FUNCS), m_decl(decl) {}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        vector<feature> m_features;
 | 
			
		||||
 | 
			
		||||
        bit_vector            m_found_decl_set;
 | 
			
		||||
        func_decl_ref_vector  m_found_decls; // domain of m_found_decl_set;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
           \brief Return true if the function symbol is considered for feature vector indexing.
 | 
			
		||||
        */
 | 
			
		||||
        bool fvi_candidate(func_decl * f) {
 | 
			
		||||
            return f->get_family_id() == null_family_id || f->get_arity() > 0;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        typedef obj_hashtable<func_decl> found_func_decl_set;
 | 
			
		||||
        found_func_decl_set   m_cls_found_decl_set; // temporary set used to track the func_decl's found in a clause
 | 
			
		||||
        ptr_vector<func_decl> m_cls_found_decls;
 | 
			
		||||
 | 
			
		||||
        bool mark_func_decl(func_decl * f);
 | 
			
		||||
 | 
			
		||||
        typedef obj_map<func_decl, unsigned> decl2nat;
 | 
			
		||||
        bool        m_refining_index; // if true keep collecting data to refine index.
 | 
			
		||||
        decl2nat    m_f_count[2];     // temporary field used to track the num. of occurs. of function symbols in neg/pos literals.
 | 
			
		||||
        decl2nat    m_f_min[2];
 | 
			
		||||
        decl2nat    m_f_max[2];
 | 
			
		||||
        decl2nat    m_f_freq;
 | 
			
		||||
        
 | 
			
		||||
        void inc_f_count(func_decl * f, bool neg);
 | 
			
		||||
        void update_min_max(func_decl * f);
 | 
			
		||||
        void update_neg_pos_func_counts(clause * cls);
 | 
			
		||||
        
 | 
			
		||||
        void compute_features(clause * cls, unsigned * fvector);
 | 
			
		||||
        
 | 
			
		||||
        struct to_feature_vector;
 | 
			
		||||
        friend struct to_feature_vector;
 | 
			
		||||
 | 
			
		||||
        struct to_feature_vector {
 | 
			
		||||
            subsumption & m_owner;
 | 
			
		||||
            to_feature_vector(subsumption & o):m_owner(o) {}
 | 
			
		||||
            void operator()(clause * cls, unsigned * fvector) {
 | 
			
		||||
                m_owner.compute_features(cls, fvector);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        typedef fvi<clause, to_feature_vector, obj_ptr_hash<clause>, ptr_eq<clause> > index;
 | 
			
		||||
        index *    m_index;
 | 
			
		||||
        unsigned   m_num_processed_clauses;
 | 
			
		||||
        unsigned   m_opt_threshold;
 | 
			
		||||
 | 
			
		||||
        void init_indexes();
 | 
			
		||||
 | 
			
		||||
        struct f_lt;
 | 
			
		||||
        friend struct f_lt;
 | 
			
		||||
 | 
			
		||||
        unsigned get_value_range(func_decl * f, bool neg) const;
 | 
			
		||||
        unsigned get_value_range(func_decl * f) const;
 | 
			
		||||
 | 
			
		||||
        struct f_lt {
 | 
			
		||||
            subsumption & m_owner;
 | 
			
		||||
            f_lt(subsumption & o):m_owner(o) {}
 | 
			
		||||
            bool operator()(func_decl * f1, func_decl * f2) const;
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        void optimize_feature_index();
 | 
			
		||||
 | 
			
		||||
        clause * unit_forward(clause * cls);
 | 
			
		||||
        clause * non_unit_forward(clause * cls);
 | 
			
		||||
        clause * eq_subsumption(expr * lhs, expr * rhs);
 | 
			
		||||
        clause * eq_subsumption(clause * cls);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        subsumption(ast_manager & m, asserted_literals & al, spc_params & params);
 | 
			
		||||
        ~subsumption();
 | 
			
		||||
 | 
			
		||||
        bool operator()(clause * cls1, clause * cls2);
 | 
			
		||||
        void insert(clause * cls);
 | 
			
		||||
        void erase(clause * cls);
 | 
			
		||||
        void reset();
 | 
			
		||||
        clause * forward(clause * cls);
 | 
			
		||||
        void backward(clause * cls, ptr_buffer<clause> & result);
 | 
			
		||||
 | 
			
		||||
        ast_manager & get_manager() { return m_manager; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_SUBSUMPTION_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,531 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_superposition.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-15.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_superposition.h"
 | 
			
		||||
#include"ast_pp.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    superposition::superposition(ast_manager & m, order & o, statistics & s):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_order(o),
 | 
			
		||||
        m_stats(s),
 | 
			
		||||
        m_subst(m),
 | 
			
		||||
        m_p(m),
 | 
			
		||||
        m_r(m),
 | 
			
		||||
        m_normalize_vars(m),
 | 
			
		||||
        m_spc_fid(m.get_family_id("spc")) {
 | 
			
		||||
        m_subst.reserve_offsets(3);
 | 
			
		||||
        m_deltas[0] = 0;
 | 
			
		||||
        m_deltas[1] = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    superposition::~superposition() {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void superposition::insert_p(clause * cls, expr * lhs, unsigned i) {
 | 
			
		||||
        m_p.insert(lhs);
 | 
			
		||||
        m_subst.reserve_vars(m_p.get_approx_num_regs());
 | 
			
		||||
        m_p2clause_set.insert(clause_pos_pair(cls, i), lhs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::insert_p(clause * cls, literal & l, unsigned i) {
 | 
			
		||||
        l.set_p_indexed(true);
 | 
			
		||||
        expr * atom = l.atom();
 | 
			
		||||
        if (!m_manager.is_eq(atom))
 | 
			
		||||
            return;
 | 
			
		||||
        if (l.is_oriented())
 | 
			
		||||
            insert_p(cls, l.is_left() ? l.lhs() : l.rhs(), i);
 | 
			
		||||
        else {
 | 
			
		||||
            insert_p(cls, l.lhs(), i);
 | 
			
		||||
            insert_p(cls, l.rhs(), i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::insert_r(clause * cls, expr * n, unsigned i, bool lhs) {
 | 
			
		||||
        if (is_app(n)) {
 | 
			
		||||
            unsigned idx = (i << 1) | static_cast<unsigned>(lhs);
 | 
			
		||||
            
 | 
			
		||||
            clause_pos_pair new_pair(cls, idx);
 | 
			
		||||
            SASSERT(m_todo.empty());
 | 
			
		||||
            m_todo.push_back(to_app(n));
 | 
			
		||||
            while (!m_todo.empty()) {
 | 
			
		||||
                app * n = m_todo.back();
 | 
			
		||||
                m_todo.pop_back();
 | 
			
		||||
                clause_pos_set * s = m_r2clause_set.get_parents(n);
 | 
			
		||||
                if (s == 0 || !s->contains(new_pair)) {
 | 
			
		||||
                    m_r.insert(n);
 | 
			
		||||
                    m_r2clause_set.insert(new_pair, n);
 | 
			
		||||
                    unsigned num_args = n->get_num_args();
 | 
			
		||||
                    for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
                        expr * c = n->get_arg(i);
 | 
			
		||||
                        if (is_app(c))
 | 
			
		||||
                            m_todo.push_back(to_app(c));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::insert_r(clause * cls, literal & l, unsigned i) {
 | 
			
		||||
        l.set_r_indexed(true);
 | 
			
		||||
        expr * atom = l.atom();
 | 
			
		||||
        if (m_manager.is_eq(atom)) {
 | 
			
		||||
            expr * lhs = l.lhs();
 | 
			
		||||
            expr * rhs = l.rhs();
 | 
			
		||||
            if (l.is_oriented()) {
 | 
			
		||||
                bool left = true;
 | 
			
		||||
                if (!l.is_left()) {
 | 
			
		||||
                    left  = false;
 | 
			
		||||
                    std::swap(lhs, rhs);
 | 
			
		||||
                }
 | 
			
		||||
                insert_r(cls, lhs, i, left);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                insert_r(cls, lhs, i, true);
 | 
			
		||||
                insert_r(cls, rhs, i, false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            insert_r(cls, atom, i, false);
 | 
			
		||||
        }
 | 
			
		||||
        m_subst.reserve_vars(m_r.get_approx_num_regs());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::insert(clause * cls) {
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal & l = cls->get_literal(i);
 | 
			
		||||
            if (l.is_p_indexed() || cls->is_eligible_for_paramodulation(m_order, l)) {
 | 
			
		||||
                if (!l.sign() && m_manager.is_eq(l.atom()))
 | 
			
		||||
                    insert_p(cls, l, i);
 | 
			
		||||
                insert_r(cls, l, i);
 | 
			
		||||
            }
 | 
			
		||||
            else if (l.is_r_indexed() || cls->is_eligible_for_resolution(m_order, l)) {
 | 
			
		||||
                insert_r(cls, l, i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        TRACE("superposition_detail",
 | 
			
		||||
              tout << "adding clause: "; cls->display(tout, m_manager); tout << "\n";
 | 
			
		||||
              tout << "p index:\n";
 | 
			
		||||
              m_p.display(tout);
 | 
			
		||||
              tout << "r index:\n";
 | 
			
		||||
              m_r.display(tout););
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::erase_p(clause * cls, expr * lhs, unsigned i) {
 | 
			
		||||
        m_p2clause_set.erase(clause_pos_pair(cls, i), lhs);
 | 
			
		||||
        if (m_p2clause_set.empty(lhs))
 | 
			
		||||
            m_p.erase(lhs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::erase_p(clause * cls, literal & l, unsigned i) {
 | 
			
		||||
        expr * atom = l.atom();
 | 
			
		||||
        if (!m_manager.is_eq(atom))
 | 
			
		||||
            return;
 | 
			
		||||
        if (l.is_oriented()) 
 | 
			
		||||
            erase_p(cls, l.is_left() ? l.lhs() : l.rhs(), i);
 | 
			
		||||
        else {
 | 
			
		||||
            erase_p(cls, l.lhs(), i);
 | 
			
		||||
            erase_p(cls, l.rhs(), i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::erase_r(clause * cls, literal & l, unsigned i) {
 | 
			
		||||
        clause_pos_pair pair(cls, i);
 | 
			
		||||
 | 
			
		||||
        expr * atom = l.atom();
 | 
			
		||||
        SASSERT(is_app(atom));
 | 
			
		||||
        SASSERT(m_todo.empty());
 | 
			
		||||
        m_todo.push_back(to_app(atom));
 | 
			
		||||
 | 
			
		||||
        while (!m_todo.empty()) {
 | 
			
		||||
            app * n = m_todo.back();
 | 
			
		||||
            m_todo.pop_back();
 | 
			
		||||
            switch (m_r2clause_set.erase(pair, n)) {
 | 
			
		||||
            case 0: // pair is not a parent of n
 | 
			
		||||
                break;
 | 
			
		||||
            case 1: // pair is the last parent of n
 | 
			
		||||
                m_r.erase(n);
 | 
			
		||||
            default:
 | 
			
		||||
                unsigned num_args = n->get_num_args();
 | 
			
		||||
                for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
                    expr * c = n->get_arg(i);
 | 
			
		||||
                    if (is_app(c))
 | 
			
		||||
                        m_todo.push_back(to_app(c));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::erase(clause * cls) {
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal & l = cls->get_literal(i);
 | 
			
		||||
            if (l.is_p_indexed())
 | 
			
		||||
                erase_p(cls, l, i);
 | 
			
		||||
            if (l.is_r_indexed())
 | 
			
		||||
                erase_r(cls, l, i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::reset() {
 | 
			
		||||
        m_p.reset();
 | 
			
		||||
        m_p2clause_set.reset();
 | 
			
		||||
        m_r.reset();
 | 
			
		||||
        m_r2clause_set.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Copy to result the literals of s except literal at position idx. Apply the substitution m_subst,
 | 
			
		||||
       assuming that the variables of s are in the variable bank offset. The deltas for each bank are
 | 
			
		||||
       stored in m_deltas.
 | 
			
		||||
    */
 | 
			
		||||
    void superposition::copy_literals(clause * s, unsigned idx, unsigned offset, literal_buffer & result) {
 | 
			
		||||
        unsigned num_lits = s->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++)
 | 
			
		||||
            if (i != idx) {
 | 
			
		||||
                literal const & l = s->get_literal(i);
 | 
			
		||||
                expr_ref new_atom(m_manager);
 | 
			
		||||
                m_subst.apply(2, m_deltas, expr_offset(l.atom(), offset), new_atom);
 | 
			
		||||
                TRACE("superposition_copy", tout << "i: " << i << ", idx: " << idx << ", offset: " << offset << "\natom:\n";
 | 
			
		||||
                      tout << mk_pp(l.atom(), m_manager) << "\nnew_atom:\n" << mk_pp(new_atom, m_manager) << "\n";);
 | 
			
		||||
                result.push_back(literal(new_atom, l.sign()));
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::normalize_literals(unsigned num_lits, literal * lits, literal_buffer & result) {
 | 
			
		||||
        m_normalize_vars.reset();
 | 
			
		||||
        for (unsigned i = 0; i < num_lits; i++) {
 | 
			
		||||
            literal const & l = lits[i];
 | 
			
		||||
            result.push_back(literal(m_normalize_vars(l.atom()), l.sign()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::mk_sp_clause(unsigned num_lits, literal * lits, justification * p1, justification * p2) {
 | 
			
		||||
        literal_buffer new_literals(m_manager);
 | 
			
		||||
        normalize_literals(num_lits, lits, new_literals);
 | 
			
		||||
        justification * js = mk_superposition_justification(m_manager, m_spc_fid, p1, p2, 
 | 
			
		||||
                                                            new_literals.size(), new_literals.c_ptr(),
 | 
			
		||||
                                                            m_normalize_vars.get_num_vars(), m_normalize_vars.get_vars());
 | 
			
		||||
        clause * new_cls = clause::mk(m_manager, new_literals.size(), new_literals.c_ptr(), js, 0);
 | 
			
		||||
        m_new_clauses->push_back(new_cls);
 | 
			
		||||
        TRACE("superposition", tout << "new superposition clause:\n"; new_cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        m_stats.m_num_superposition++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::mk_res_clause(unsigned num_lits, literal * lits, justification * p1, justification * p2) {
 | 
			
		||||
        literal_buffer new_literals(m_manager);
 | 
			
		||||
        normalize_literals(num_lits, lits, new_literals);
 | 
			
		||||
        justification * js = mk_resolution_justification(m_manager, m_spc_fid, p1, p2, 
 | 
			
		||||
                                                         new_literals.size(), new_literals.c_ptr(),
 | 
			
		||||
                                                         m_normalize_vars.get_num_vars(), m_normalize_vars.get_vars());
 | 
			
		||||
        clause * new_cls = clause::mk(m_manager, new_literals.size(), new_literals.c_ptr(), js, 0);
 | 
			
		||||
        m_new_clauses->push_back(new_cls);
 | 
			
		||||
        TRACE("superposition", tout << "new resolution clause:\n"; new_cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
        m_stats.m_num_resolution++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Given the equation (= lhs rhs) of the clause being
 | 
			
		||||
       added, try to apply resolution where the clause being added
 | 
			
		||||
       is the main clause in the superposition rule.
 | 
			
		||||
    */
 | 
			
		||||
    void superposition::try_superposition_main(expr * lhs, expr * rhs) {
 | 
			
		||||
        m_lhs    = lhs;
 | 
			
		||||
        m_rhs    = rhs;
 | 
			
		||||
        m_subst.reset_subst();
 | 
			
		||||
        TRACE("spc_superposition", tout << "try_superposition_main, lhs:\n" << mk_pp(m_lhs, m_manager) << "\nrhs:\n" << mk_pp(m_rhs, m_manager) << "\n";
 | 
			
		||||
              tout << "substitution:\n"; m_subst.display(tout););
 | 
			
		||||
        r_visitor v(*this, m_subst);
 | 
			
		||||
        m_r.unify(lhs, v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Try to apply superposition rule using the clause
 | 
			
		||||
       being added (m_clause) as main clause, and its literal m_lit
 | 
			
		||||
       as the equation.
 | 
			
		||||
    */
 | 
			
		||||
    void superposition::try_superposition_main() {
 | 
			
		||||
        expr * lhs = m_lit->lhs();
 | 
			
		||||
        expr * rhs = m_lit->rhs();
 | 
			
		||||
        TRACE("spc_superposition", tout << "trying superposition:\n" << mk_pp(lhs, m_manager) << "\n" << mk_pp(rhs, m_manager) << "\nis_oriented: " << m_lit->is_oriented() << "\n";);
 | 
			
		||||
        if (m_lit->is_oriented()) {
 | 
			
		||||
            if (!m_lit->is_left())
 | 
			
		||||
                std::swap(lhs, rhs);
 | 
			
		||||
            try_superposition_main(lhs, rhs);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            try_superposition_main(lhs, rhs);
 | 
			
		||||
            try_superposition_main(rhs, lhs);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::found_r(expr * r) {
 | 
			
		||||
        TRACE("spc_superposition", tout << "found_r:\n" << mk_pp(r, m_manager) << "\n";
 | 
			
		||||
              tout << "substitution:\n"; m_subst.display(tout););
 | 
			
		||||
        if (m_r2clause_set.empty(r))
 | 
			
		||||
            return;
 | 
			
		||||
        TRACE("spc_superposition", tout << "r2clause is not empty.\n";);
 | 
			
		||||
        if (!m_lit->is_oriented() && m_order.greater(m_rhs, m_lhs, &m_subst))
 | 
			
		||||
            return;
 | 
			
		||||
        TRACE("spc_superposition", tout << "order restriction was met.\n";);
 | 
			
		||||
        if (!m_clause->is_eligible_for_paramodulation(m_order, *m_lit, 0, &m_subst))
 | 
			
		||||
            return;
 | 
			
		||||
        TRACE("spc_superposition", tout << "literal is eligible for paramodulation.\n";);
 | 
			
		||||
        r2clause_set::iterator it  = m_r2clause_set.begin(r);
 | 
			
		||||
        r2clause_set::iterator end = m_r2clause_set.end(r);
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            clause_pos_pair & p = *it;
 | 
			
		||||
            clause * aux_cls    = p.first;
 | 
			
		||||
            unsigned aux_idx    = p.second >> 1;
 | 
			
		||||
            //
 | 
			
		||||
            // The following optimization is incorrect (if statement).
 | 
			
		||||
            // For example, it prevents the Z3 from proving the trivial benchmark
 | 
			
		||||
            // c = X, 
 | 
			
		||||
            // a != b
 | 
			
		||||
            // using the order a < b < c
 | 
			
		||||
            //
 | 
			
		||||
            // To prove, this example we need to generate the clause Y = X by applying superposition of c = X on itself.
 | 
			
		||||
            // We can see that by renaming the first clause to c = Y, and then, substituting c in the original by Y.
 | 
			
		||||
            //
 | 
			
		||||
            // Actually, this optimization is correct when the set of variables in m_lhs is a superset of the set of variables in m_rhs, 
 | 
			
		||||
            // because in this case, the new literal will be equivalent to true. In the example above, this is not the case,
 | 
			
		||||
            // since m_lhs does not contain any variable, and m_rhs contains one.
 | 
			
		||||
            // 
 | 
			
		||||
            
 | 
			
		||||
            //
 | 
			
		||||
            // if (r == m_lhs && m_clause == aux_cls && m_idx == aux_idx)
 | 
			
		||||
            //    continue;
 | 
			
		||||
            //
 | 
			
		||||
            bool     in_lhs     = (p.second & 1) != 0;
 | 
			
		||||
            TRACE("spc_superposition", tout << "aux_cls:\n"; aux_cls->display(tout, m_manager); tout << "\naux_idx: " << aux_cls << ", in_lhs: " << in_lhs << "\n";);
 | 
			
		||||
            literal & aux_lit   = aux_cls->get_literal(aux_idx);
 | 
			
		||||
            if (!aux_cls->is_eligible_for_resolution(m_order, aux_lit, 1, &m_subst))
 | 
			
		||||
                continue;
 | 
			
		||||
            literal_buffer new_literals(m_manager);
 | 
			
		||||
            m_subst.reset_cache();
 | 
			
		||||
            if (m_manager.is_eq(aux_lit.atom())) {
 | 
			
		||||
                expr * lhs = aux_lit.lhs();
 | 
			
		||||
                expr * rhs = aux_lit.rhs();
 | 
			
		||||
                TRACE("spc_superposition", tout << "aux_lit lhs:\n" << mk_pp(lhs, m_manager) << "\nrhs:\n" << mk_pp(rhs, m_manager) << "\n";);
 | 
			
		||||
                if (!in_lhs)
 | 
			
		||||
                    std::swap(lhs, rhs);
 | 
			
		||||
                if (!aux_lit.is_oriented() && m_order.greater(rhs, lhs, 1, &m_subst)) {
 | 
			
		||||
                    TRACE("spc_superposition", tout << "failed order constraint.\n";);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                expr_ref new_lhs(m_manager), new_rhs(m_manager);
 | 
			
		||||
                m_subst.apply(2, m_deltas, expr_offset(lhs, 1), expr_offset(r, 1), expr_offset(m_rhs, 0), new_lhs);
 | 
			
		||||
                m_subst.apply(2, m_deltas, expr_offset(rhs, 1), new_rhs);
 | 
			
		||||
                TRACE("spc_superposition", tout << "aux_lit new_lhs:\n" << mk_pp(new_lhs, m_manager) << "\nnew_rhs:\n" << mk_pp(new_rhs, m_manager) << "\n";);
 | 
			
		||||
                expr * new_eq  = m_manager.mk_eq(new_lhs, new_rhs);
 | 
			
		||||
                new_literals.push_back(literal(new_eq, aux_lit.sign()));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                expr_ref new_atom(m_manager);
 | 
			
		||||
                m_subst.apply(2, m_deltas, expr_offset(aux_lit.atom(), 1), new_atom);
 | 
			
		||||
                new_literals.push_back(literal(new_atom, aux_lit.sign()));
 | 
			
		||||
            }
 | 
			
		||||
            copy_literals(m_clause, m_idx, 0,   new_literals);
 | 
			
		||||
            copy_literals(aux_cls,  aux_idx, 1, new_literals);
 | 
			
		||||
            TRACE("superposition", tout << "found r target: " << mk_pp(r, m_manager) << " for \n" <<
 | 
			
		||||
                  mk_pp(m_lhs, m_manager) << "\nmain clause: "; m_clause->display(tout, m_manager);
 | 
			
		||||
                  tout << "\naux clause: "; aux_cls->display(tout, m_manager); tout << "\nat pos: " <<
 | 
			
		||||
                  aux_idx << "\n";);
 | 
			
		||||
            mk_sp_clause(new_literals.size(), new_literals.c_ptr(), m_clause->get_justification(), aux_cls->get_justification());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Try to apply superposition rule using the clause
 | 
			
		||||
       being added (m_clause) as the aux clause, and its literal m_lit
 | 
			
		||||
       as the target.
 | 
			
		||||
    */
 | 
			
		||||
    void superposition::try_superposition_aux() {
 | 
			
		||||
        TRACE("superposition_aux", tout << "superposition aux:\n"; m_clause->display(tout, m_manager); 
 | 
			
		||||
              tout << "\nusing literal: " << m_idx << "\n";);
 | 
			
		||||
        if (m_manager.is_eq(m_lit->atom())) {
 | 
			
		||||
            expr * lhs = m_lit->lhs();
 | 
			
		||||
            expr * rhs = m_lit->rhs();
 | 
			
		||||
            if (m_lit->is_oriented()) {
 | 
			
		||||
                if (!m_lit->is_left())
 | 
			
		||||
                    std::swap(lhs, rhs);
 | 
			
		||||
                try_superposition_aux(lhs, rhs);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                try_superposition_aux(lhs, rhs);
 | 
			
		||||
                try_superposition_aux(rhs, lhs);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            try_superposition_aux(m_lit->atom(), 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Use the clause being added as the auxiliary clause in the superposition rule.
 | 
			
		||||
    */
 | 
			
		||||
    void superposition::try_superposition_aux(expr * lhs, expr * rhs) {
 | 
			
		||||
        TRACE("superposition_aux", tout << "try_superposition_aux\n" << mk_pp(lhs, m_manager) << "\n" << mk_pp(rhs, m_manager) << "\n";);
 | 
			
		||||
        if (is_var(lhs))
 | 
			
		||||
            return;
 | 
			
		||||
        m_lhs = lhs;
 | 
			
		||||
        m_rhs = rhs;
 | 
			
		||||
        SASSERT(m_todo.empty());
 | 
			
		||||
        m_todo.push_back(to_app(lhs));
 | 
			
		||||
        while (!m_todo.empty()) {
 | 
			
		||||
            m_target = m_todo.back();
 | 
			
		||||
            m_todo.pop_back();
 | 
			
		||||
            m_subst.reset_subst();
 | 
			
		||||
            p_visitor v(*this, m_subst);
 | 
			
		||||
            TRACE("superposition_aux", tout << "trying to find unifier for:\n" << mk_pp(m_target, m_manager) << "\n";);
 | 
			
		||||
            m_p.unify(m_target, v);
 | 
			
		||||
            unsigned j = m_target->get_num_args();
 | 
			
		||||
            while (j > 0) {
 | 
			
		||||
                --j;
 | 
			
		||||
                expr * arg = m_target->get_arg(j);
 | 
			
		||||
                if (is_app(arg))
 | 
			
		||||
                    m_todo.push_back(to_app(arg));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::found_p(expr * p) {
 | 
			
		||||
        TRACE("superposition_found_p", tout << "found p:\n" << mk_pp(p, m_manager) << "\n";);
 | 
			
		||||
        if (m_p2clause_set.empty(p)) {
 | 
			
		||||
            TRACE("superposition_found_p", tout << "clause set is empty.\n";);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (m_rhs && !m_lit->is_oriented() && m_order.greater(m_rhs, m_lhs, &m_subst)) {
 | 
			
		||||
            TRACE("superposition_found_p", tout << "aux clause failed not rhs > lhs constraint.\n";);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (!m_clause->is_eligible_for_resolution(m_order, *m_lit, 0, &m_subst)) {
 | 
			
		||||
            TRACE("superposition_found_p", tout << "aux literal is not eligible for resolution.\n";);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        p2clause_set::iterator it  = m_p2clause_set.begin(p);
 | 
			
		||||
        p2clause_set::iterator end = m_p2clause_set.end(p);
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            clause_pos_pair & pair   = *it;
 | 
			
		||||
            clause * main_cls        = pair.first;
 | 
			
		||||
            TRACE("superposition_found_p", tout << "p clause:\n"; main_cls->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            unsigned lit_idx         = pair.second;
 | 
			
		||||
            if (p == m_lhs && m_clause == main_cls && m_idx == lit_idx)
 | 
			
		||||
                continue;
 | 
			
		||||
            literal const & main_lit = main_cls->get_literal(lit_idx);
 | 
			
		||||
            SASSERT(m_manager.is_eq(main_lit.atom()));
 | 
			
		||||
            expr * lhs               = main_lit.lhs();
 | 
			
		||||
            expr * rhs               = main_lit.rhs();
 | 
			
		||||
            if (rhs == p)
 | 
			
		||||
                std::swap(lhs, rhs);
 | 
			
		||||
            SASSERT(lhs == p);
 | 
			
		||||
            TRACE("superposition_found_p", tout << "lhs: " << mk_pp(lhs, m_manager) << "\nrhs: " << mk_pp(rhs, m_manager) << "\n";);
 | 
			
		||||
            if (!main_lit.is_oriented() && m_order.greater(rhs, lhs, 1, &m_subst))
 | 
			
		||||
                continue;
 | 
			
		||||
            if (!main_cls->is_eligible_for_paramodulation(m_order, main_lit, 1, &m_subst))
 | 
			
		||||
                continue;
 | 
			
		||||
            literal_buffer new_literals(m_manager);
 | 
			
		||||
            m_subst.reset_cache();
 | 
			
		||||
            TRACE("superposition_found_p", tout << "creating new_lhs\n";);
 | 
			
		||||
            expr_ref new_lhs(m_manager);
 | 
			
		||||
            m_subst.apply(2, m_deltas, expr_offset(m_lhs, 0), expr_offset(m_target, 0), expr_offset(rhs, 1), new_lhs);
 | 
			
		||||
            // FIX: m_subst.reset_cache();
 | 
			
		||||
            TRACE("superposition_found_p", tout << "new_lhs: " << mk_pp(new_lhs, m_manager) << "\n";
 | 
			
		||||
                  m_subst.display(tout););
 | 
			
		||||
            expr * new_atom = 0;
 | 
			
		||||
            if (m_rhs) {
 | 
			
		||||
                TRACE("superposition_found_p", tout << "creating new_rhs\n";);
 | 
			
		||||
                expr_ref new_rhs(m_manager);
 | 
			
		||||
                m_subst.apply(2, m_deltas, expr_offset(m_rhs, 0), new_rhs);
 | 
			
		||||
                TRACE("superposition_found_p", tout << "new_rhs: " << mk_pp(new_rhs, m_manager) << "\n";);
 | 
			
		||||
                new_atom = m_manager.mk_eq(new_lhs, new_rhs);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                new_atom = new_lhs;
 | 
			
		||||
            TRACE("superposition_found_p", tout << "new_atom: " << mk_pp(new_atom, m_manager) << "\n"; m_subst.display(tout););
 | 
			
		||||
            new_literals.push_back(literal(new_atom, m_lit->sign()));
 | 
			
		||||
            TRACE("superposition_found_p", tout << "copying literals\n";);
 | 
			
		||||
            copy_literals(main_cls, lit_idx, 1, new_literals);
 | 
			
		||||
            copy_literals(m_clause, m_idx, 0, new_literals);
 | 
			
		||||
            TRACE("superposition", tout << "found p target: " << mk_pp(p, m_manager) << " for \n" <<
 | 
			
		||||
                  mk_pp(m_lhs, m_manager) << "\nmain clause: "; main_cls->display(tout, m_manager);
 | 
			
		||||
                  tout << "\naux clause: "; m_clause->display(tout, m_manager); tout << "\n";);
 | 
			
		||||
            mk_sp_clause(new_literals.size(), new_literals.c_ptr(), main_cls->get_justification(), m_clause->get_justification());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Try to apply resolution rule using the clause being added (m_clause).
 | 
			
		||||
    */
 | 
			
		||||
    void superposition::try_resolution() {
 | 
			
		||||
        m_subst.reset_subst();
 | 
			
		||||
        res_visitor v(*this, m_subst);
 | 
			
		||||
        m_r.unify(m_lit->atom(), v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void superposition::found_res(expr * r) {
 | 
			
		||||
        if (m_r2clause_set.empty(r))
 | 
			
		||||
            return;
 | 
			
		||||
        if (!m_clause->is_eligible_for_resolution(m_order, *m_lit, 0, &m_subst))
 | 
			
		||||
            return;
 | 
			
		||||
        r2clause_set::iterator it  = m_r2clause_set.begin(r);
 | 
			
		||||
        r2clause_set::iterator end = m_r2clause_set.end(r);
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            clause_pos_pair & pair  = *it;
 | 
			
		||||
            clause * aux_cls        = pair.first;
 | 
			
		||||
            unsigned aux_idx        = pair.second >> 1;
 | 
			
		||||
            literal const & aux_lit = aux_cls->get_literal(aux_idx);
 | 
			
		||||
            if (aux_lit.sign() == m_lit->sign())
 | 
			
		||||
                continue;
 | 
			
		||||
            if (aux_lit.atom() != r)
 | 
			
		||||
                continue;
 | 
			
		||||
            if (!aux_cls->is_eligible_for_resolution(m_order, aux_lit, 1, &m_subst))
 | 
			
		||||
                continue;
 | 
			
		||||
            literal_buffer new_literals(m_manager);
 | 
			
		||||
            m_subst.reset_cache();
 | 
			
		||||
            copy_literals(m_clause, m_idx, 0, new_literals);
 | 
			
		||||
            copy_literals(aux_cls, aux_idx, 1, new_literals);
 | 
			
		||||
            mk_res_clause(new_literals.size(), new_literals.c_ptr(), m_clause->get_justification(), aux_cls->get_justification());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    void superposition::operator()(clause * cls, ptr_vector<clause> & new_clauses) {
 | 
			
		||||
        m_subst.reserve_vars(cls->get_num_vars());
 | 
			
		||||
        m_clause      = cls;
 | 
			
		||||
        m_new_clauses = &new_clauses;
 | 
			
		||||
        SASSERT(m_deltas[0] == 0);
 | 
			
		||||
        m_deltas[1]   = m_clause->get_num_vars();
 | 
			
		||||
        unsigned num_lits = cls->get_num_literals();
 | 
			
		||||
        for (m_idx = 0; m_idx < num_lits; m_idx++) {
 | 
			
		||||
            m_lit      = &(cls->get_literal(m_idx));
 | 
			
		||||
            bool is_eq = m_manager.is_eq(m_lit->atom());
 | 
			
		||||
            if (!m_lit->sign() && m_lit->is_p_indexed() && is_eq)
 | 
			
		||||
                try_superposition_main();
 | 
			
		||||
            if (m_lit->is_r_indexed()) {
 | 
			
		||||
                try_superposition_aux();
 | 
			
		||||
                if (!is_eq)
 | 
			
		||||
                    try_resolution();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,147 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_superposition.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-15.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_SUPERPOSITION_H_
 | 
			
		||||
#define _SPC_SUPERPOSITION_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"spc_clause_pos_set.h"
 | 
			
		||||
#include"substitution_tree.h"
 | 
			
		||||
#include"obj_hashtable.h"
 | 
			
		||||
#include"sparse_use_list.h"
 | 
			
		||||
#include"normalize_vars.h"
 | 
			
		||||
#include"spc_statistics.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Functor for applying the superposition right/left rules.
 | 
			
		||||
 | 
			
		||||
       - Superposition Left
 | 
			
		||||
       s = t or S,  u != v or R
 | 
			
		||||
       ==>
 | 
			
		||||
       sigma(u[p<-t] != v or S or R)
 | 
			
		||||
       
 | 
			
		||||
       sigma is the mgu(u|p, s)
 | 
			
		||||
       sigma(s) not greater than sigma(t)
 | 
			
		||||
       sigma(u) not greater than sigma(v)
 | 
			
		||||
       sigma(s = t) is eligible for paramodulation
 | 
			
		||||
       sigma(u != v) is eligible for resolution
 | 
			
		||||
       u|p is not a variable
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
       - Superposition Right
 | 
			
		||||
       s = t or S,  u = v or R
 | 
			
		||||
       ==>
 | 
			
		||||
       sigma(u[p<-t] != v or S or R)
 | 
			
		||||
       
 | 
			
		||||
       Same restrictions of Superposition Left
 | 
			
		||||
    
 | 
			
		||||
       This functor also applied binary resolution rule.
 | 
			
		||||
 | 
			
		||||
       We say the left clause is the main clause in the superposition.
 | 
			
		||||
    */
 | 
			
		||||
    class superposition {
 | 
			
		||||
        ast_manager &     m_manager;
 | 
			
		||||
        order &           m_order;
 | 
			
		||||
        statistics &      m_stats;
 | 
			
		||||
        substitution      m_subst;
 | 
			
		||||
 | 
			
		||||
        // indexes for left clause
 | 
			
		||||
        substitution_tree m_p; // potential left hand sides for superposition
 | 
			
		||||
        typedef sparse_use_list<expr, svector<clause_pos_pair> > p2clause_set;
 | 
			
		||||
        p2clause_set      m_p2clause_set;
 | 
			
		||||
 | 
			
		||||
        void insert_p(clause * cls, expr * lhs, unsigned i);
 | 
			
		||||
        void insert_p(clause * cls, literal & l, unsigned i);
 | 
			
		||||
 | 
			
		||||
        void erase_p(clause * cls, expr * lhs, unsigned i);
 | 
			
		||||
        void erase_p(clause * cls, literal & l, unsigned i);
 | 
			
		||||
 | 
			
		||||
        // indexes for right clause
 | 
			
		||||
        substitution_tree m_r; // potential targets for superposition 
 | 
			
		||||
        typedef sparse_use_list<expr, clause_pos_set> r2clause_set;
 | 
			
		||||
        r2clause_set      m_r2clause_set;
 | 
			
		||||
        ptr_vector<app>   m_todo;
 | 
			
		||||
 | 
			
		||||
        void insert_r(clause * cls, expr * n, unsigned i, bool lhs);
 | 
			
		||||
        void insert_r(clause * cls, literal & l, unsigned i);
 | 
			
		||||
        void erase_r(clause * cls, literal & l, unsigned i);
 | 
			
		||||
 | 
			
		||||
        normalize_vars       m_normalize_vars;
 | 
			
		||||
        
 | 
			
		||||
        // temporary fields...
 | 
			
		||||
        ptr_vector<clause> * m_new_clauses;
 | 
			
		||||
        clause *             m_clause;
 | 
			
		||||
        literal *            m_lit;
 | 
			
		||||
        expr *               m_lhs;
 | 
			
		||||
        expr *               m_rhs;
 | 
			
		||||
        app *                m_target;
 | 
			
		||||
        unsigned             m_idx;
 | 
			
		||||
        unsigned             m_deltas[2];
 | 
			
		||||
        family_id            m_spc_fid;
 | 
			
		||||
 | 
			
		||||
        void normalize_literals(unsigned num_lits, literal * lits, literal_buffer & result);
 | 
			
		||||
        void copy_literals(clause * s, unsigned idx, unsigned offset, literal_buffer & result);
 | 
			
		||||
        void mk_sp_clause(unsigned num_lits, literal * lits, justification * p1, justification * p2);
 | 
			
		||||
        void mk_res_clause(unsigned num_lits, literal * lits, justification * p1, justification * p2);
 | 
			
		||||
        void try_superposition_main(expr * lhs, expr * rhs);
 | 
			
		||||
        void try_superposition_main();
 | 
			
		||||
        void found_r(expr * r);
 | 
			
		||||
        void try_superposition_aux(expr * lhs, expr * rhs);
 | 
			
		||||
        void try_superposition_aux();
 | 
			
		||||
        void found_p(expr * p);
 | 
			
		||||
        void try_resolution();
 | 
			
		||||
        void found_res(expr * r);
 | 
			
		||||
 | 
			
		||||
        friend struct r_visitor;
 | 
			
		||||
        struct r_visitor : public st_visitor {
 | 
			
		||||
            superposition & m_owner;
 | 
			
		||||
            r_visitor(superposition & o, substitution & s):st_visitor(s), m_owner(o) {}
 | 
			
		||||
            virtual bool operator()(expr * e) { m_owner.found_r(e); return true; /* continue */ }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        friend struct p_visitor;
 | 
			
		||||
        struct p_visitor : public st_visitor {
 | 
			
		||||
            superposition & m_owner;
 | 
			
		||||
            p_visitor(superposition & o, substitution & s):st_visitor(s), m_owner(o) {}
 | 
			
		||||
            virtual bool operator()(expr * e) { m_owner.found_p(e); return true; /* continue */ }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        friend struct res_visitor;
 | 
			
		||||
        struct res_visitor : public st_visitor {
 | 
			
		||||
            superposition & m_owner;
 | 
			
		||||
            res_visitor(superposition & o, substitution & s):st_visitor(s), m_owner(o) {}
 | 
			
		||||
            virtual bool operator()(expr * e) { m_owner.found_res(e); return true; /* continue */ }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        superposition(ast_manager & m, order & o, statistics & stats);
 | 
			
		||||
        ~superposition();
 | 
			
		||||
 | 
			
		||||
        void insert(clause * cls);
 | 
			
		||||
        void erase(clause * cls);
 | 
			
		||||
        void reset();
 | 
			
		||||
        
 | 
			
		||||
        void operator()(clause * cls, ptr_vector<clause> & new_clauses);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_SUPERPOSITION_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,52 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_unary_inference.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"spc_unary_inference.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    unary_inference::unary_inference(ast_manager & m, order & ord):
 | 
			
		||||
        m_manager(m),
 | 
			
		||||
        m_order(ord),
 | 
			
		||||
        m_subst(m),
 | 
			
		||||
        m_unifier(m) {
 | 
			
		||||
        m_subst.reserve_offsets(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Create the result clause. The literal at position j of \c cls in removed,
 | 
			
		||||
       and the substitution m_subst is applied to the resultant clause.
 | 
			
		||||
    */
 | 
			
		||||
    clause * unary_inference::mk_result(clause * cls, unsigned j) {
 | 
			
		||||
        sbuffer<literal> new_literals;
 | 
			
		||||
        unsigned num = cls->get_num_literals();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            if (i != j) {
 | 
			
		||||
                literal const & l = cls->get_literal(i);
 | 
			
		||||
                expr_ref new_atom(m_manager);
 | 
			
		||||
                m_subst.apply(l.atom(), new_atom);
 | 
			
		||||
                new_literals.push_back(literal(new_atom, l.sign()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        justification * js = mk_justification(cls->get_justification(), new_literals.size(), new_literals.c_ptr());
 | 
			
		||||
        clause * new_cls = clause::mk(m_manager, new_literals.size(), new_literals.c_ptr(), js, cls->get_scope_lvl());
 | 
			
		||||
        return new_cls;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,48 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    spc_unary_inference.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-14.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPC_UNARY_INFERENCE_H_
 | 
			
		||||
#define _SPC_UNARY_INFERENCE_H_
 | 
			
		||||
 | 
			
		||||
#include"spc_clause.h"
 | 
			
		||||
#include"unifier.h"
 | 
			
		||||
 | 
			
		||||
namespace spc {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Superclass for eq_resolution and factoring.
 | 
			
		||||
    */
 | 
			
		||||
    class unary_inference {
 | 
			
		||||
    protected:
 | 
			
		||||
        ast_manager & m_manager;
 | 
			
		||||
        order &       m_order;
 | 
			
		||||
        substitution  m_subst;
 | 
			
		||||
        unifier       m_unifier; 
 | 
			
		||||
        
 | 
			
		||||
        clause * mk_result(clause * cls, unsigned j);
 | 
			
		||||
        virtual justification * mk_justification(justification * parent, unsigned num_lits, literal * new_lits) = 0;
 | 
			
		||||
    public:
 | 
			
		||||
        unary_inference(ast_manager & m, order & ord);
 | 
			
		||||
        virtual ~unary_inference() {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* _SPC_UNARY_INFERENCE_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,180 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    splay_tree.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Splay trees
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-01-31.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPLAY_TREE_H_
 | 
			
		||||
#define _SPLAY_TREE_H_
 | 
			
		||||
 | 
			
		||||
#include"util.h"
 | 
			
		||||
#include"buffer.h"
 | 
			
		||||
 | 
			
		||||
template<typename Key, typename Compare>
 | 
			
		||||
class splay_tree : private Compare {
 | 
			
		||||
    struct cell {
 | 
			
		||||
        Key    m_key;
 | 
			
		||||
        cell * m_left;
 | 
			
		||||
        cell * m_right;
 | 
			
		||||
 | 
			
		||||
        cell():m_left(0), m_right(0) {}
 | 
			
		||||
        cell(Key const & k, cell * l = 0, cell * r = 0):
 | 
			
		||||
            m_key(k), m_left(l), m_right(r) {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    cell * m_root;
 | 
			
		||||
    int compare(Key const & k1, Key const & k2) const { return Compare::operator()(k1, k2); }
 | 
			
		||||
    cell * splay(cell * c, Key const & k);
 | 
			
		||||
 | 
			
		||||
    void display_core(std::ostream & out, cell * c) const {
 | 
			
		||||
        if (c) {
 | 
			
		||||
            out << "(" << c->m_key << " ";
 | 
			
		||||
            display_core(out, c->m_left);
 | 
			
		||||
            out << " ";
 | 
			
		||||
            display_core(out, c->m_right);
 | 
			
		||||
            out << ")";
 | 
			
		||||
        }
 | 
			
		||||
        else 
 | 
			
		||||
            out << "null";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    splay_tree(Compare const & c = Compare()):
 | 
			
		||||
        Compare(c),
 | 
			
		||||
        m_root(0) {}
 | 
			
		||||
    
 | 
			
		||||
    ~splay_tree() {
 | 
			
		||||
        m_root = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void insert(Key const & k);
 | 
			
		||||
 | 
			
		||||
    bool find(Key const & k, Key & r) const;
 | 
			
		||||
 | 
			
		||||
    void erase(Key const & k);
 | 
			
		||||
 | 
			
		||||
    void reset();
 | 
			
		||||
 | 
			
		||||
    bool empty() const { return m_root == 0; }
 | 
			
		||||
 | 
			
		||||
    bool singleton() const { return m_root != 0 && m_root->m_left == 0 && m_root->m_right == 0; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Visit nodes in the splay tree in ascending order.
 | 
			
		||||
       The Visitor functor should provide the following methods:
 | 
			
		||||
       
 | 
			
		||||
       - bool visit_left(Key const & k)
 | 
			
		||||
         return true if the left child should be visited
 | 
			
		||||
 | 
			
		||||
       - bool visit_right(Key const & k)
 | 
			
		||||
         return true if the right child should be visited
 | 
			
		||||
 | 
			
		||||
       - void operator()(Key const & k)
 | 
			
		||||
         do something with the key.
 | 
			
		||||
    */
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_core(Visitor & v) {
 | 
			
		||||
        typedef std::pair<cell *, bool> entry;
 | 
			
		||||
        if (m_root) {
 | 
			
		||||
            buffer<entry> todo;
 | 
			
		||||
            todo.push_back(entry(m_root, false));
 | 
			
		||||
            while (!todo.empty()) {
 | 
			
		||||
                entry & curr = todo.back();
 | 
			
		||||
                cell * c = curr.first;
 | 
			
		||||
                if (!curr.second) {
 | 
			
		||||
                    curr.second = true;
 | 
			
		||||
                    if (c->m_left && v.visit_left(c->m_key))
 | 
			
		||||
                        todo.push_back(entry(c->m_left, false));
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    v(c->m_key);
 | 
			
		||||
                    todo.pop_back();
 | 
			
		||||
                    if (c->m_right && v.visit_right(c->m_key))
 | 
			
		||||
                        todo.push_back(entry(c->m_right, false));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    struct all_visitor_wrapper {
 | 
			
		||||
        Visitor & m_visitor;
 | 
			
		||||
        all_visitor_wrapper(Visitor & v):m_visitor(v) {}
 | 
			
		||||
        bool visit_right(Key const & k) { return true; }
 | 
			
		||||
        bool visit_left(Key const & k) { return true; }
 | 
			
		||||
        void operator()(Key const & k) { m_visitor.operator()(k); }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Visit all nodes in the splay tree in ascending order.
 | 
			
		||||
 | 
			
		||||
       - void operator()(Key const & k)
 | 
			
		||||
         do something with the key pair.
 | 
			
		||||
    */
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit(Visitor & v) {
 | 
			
		||||
        all_visitor_wrapper<Visitor> w(v);
 | 
			
		||||
        visit_core(w);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor, bool LE>
 | 
			
		||||
    struct visitor_wrapper {
 | 
			
		||||
        Visitor &    m_visitor;
 | 
			
		||||
        splay_tree & m_tree;
 | 
			
		||||
        Key          m_key;
 | 
			
		||||
        visitor_wrapper(Visitor & v, splay_tree & t, Key const & k):m_visitor(v), m_tree(t), m_key(k) {}
 | 
			
		||||
        bool visit_left(Key const & k) { 
 | 
			
		||||
            return LE || m_tree.compare(k, m_key) > 0;
 | 
			
		||||
        }
 | 
			
		||||
        bool visit_right(Key const & k) { 
 | 
			
		||||
            return !LE || m_tree.compare(k, m_key) < 0;
 | 
			
		||||
        }
 | 
			
		||||
        void operator()(Key const & k) {
 | 
			
		||||
            if ((LE  && m_tree.compare(k, m_key) <= 0) ||
 | 
			
		||||
                (!LE && m_tree.compare(k, m_key) >= 0)) 
 | 
			
		||||
                m_visitor.operator()(k);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Visit all nodes with keys less than or equal to k.
 | 
			
		||||
 | 
			
		||||
       - void operator()(Key const & k)
 | 
			
		||||
         do something with the key.
 | 
			
		||||
    */
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_le(Visitor & v, Key const & k) {
 | 
			
		||||
        visitor_wrapper<Visitor, true> w(v, *this, k);
 | 
			
		||||
        visit_core(w);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Visit all nodes with keys greater than or equal to k.
 | 
			
		||||
 | 
			
		||||
       - void operator()(Key const & k)
 | 
			
		||||
         do something with the key.
 | 
			
		||||
    */
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_ge(Visitor & v, Key const & k) {
 | 
			
		||||
        visitor_wrapper<Visitor, false> w(v, *this, k);
 | 
			
		||||
        visit_core(w);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void display(std::ostream & out) const {
 | 
			
		||||
        display_core(out, m_root);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,152 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    splay_tree_def.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Splay trees
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-01-31.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPLAY_TREE_DEF_H_
 | 
			
		||||
#define _SPLAY_TREE_DEF_H_
 | 
			
		||||
 | 
			
		||||
#include"splay_tree.h"
 | 
			
		||||
 | 
			
		||||
template<typename Key, typename Compare>
 | 
			
		||||
typename splay_tree<Key, Compare>::cell * splay_tree<Key, Compare>::splay(cell * root, Key const & k) {
 | 
			
		||||
    if (!root) 
 | 
			
		||||
        return 0;
 | 
			
		||||
    
 | 
			
		||||
    cell aux;
 | 
			
		||||
    cell * tmp;
 | 
			
		||||
    cell * left  = &aux;
 | 
			
		||||
    cell * right = &aux;
 | 
			
		||||
    cell * t     = root;
 | 
			
		||||
    
 | 
			
		||||
    while (true) {
 | 
			
		||||
        int r = compare(k, t->m_key);
 | 
			
		||||
        if (r < 0) {
 | 
			
		||||
            if (!t->m_left)
 | 
			
		||||
                break;
 | 
			
		||||
            if (compare(k, t->m_left->m_key) < 0) {
 | 
			
		||||
                tmp          = t->m_left;
 | 
			
		||||
                t->m_left    = tmp->m_right;
 | 
			
		||||
                tmp->m_right = t;
 | 
			
		||||
                t            = tmp;
 | 
			
		||||
                if (!t->m_left)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            right->m_left = t;
 | 
			
		||||
            right         = t;
 | 
			
		||||
            t             = t->m_left;
 | 
			
		||||
        }
 | 
			
		||||
        else if (r > 0) {
 | 
			
		||||
            if (!t->m_right)
 | 
			
		||||
                break;
 | 
			
		||||
            if (compare(k, t->m_right->m_key) > 0) {
 | 
			
		||||
                tmp          = t->m_right;
 | 
			
		||||
                t->m_right   = tmp->m_left;
 | 
			
		||||
                tmp->m_left  = t;
 | 
			
		||||
                t            = tmp;
 | 
			
		||||
                if (!t->m_right)
 | 
			
		||||
                    break;
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
            left->m_right = t;
 | 
			
		||||
            left          = t;
 | 
			
		||||
            t             = t->m_right;
 | 
			
		||||
        }
 | 
			
		||||
        else 
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    left->m_right = t->m_left;
 | 
			
		||||
    right->m_left = t->m_right;
 | 
			
		||||
    t->m_left     = aux.m_right;
 | 
			
		||||
    t->m_right    = aux.m_left;
 | 
			
		||||
    
 | 
			
		||||
    return t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Key, typename Compare>
 | 
			
		||||
void splay_tree<Key, Compare>::insert(Key const & k) {
 | 
			
		||||
    if (!m_root) 
 | 
			
		||||
        m_root = alloc(cell, k);
 | 
			
		||||
    else {
 | 
			
		||||
        m_root = splay(m_root, k);
 | 
			
		||||
        int r = compare(k, m_root->m_key);
 | 
			
		||||
        if (r < 0) {
 | 
			
		||||
            cell * new_cell   = alloc(cell, k, m_root->m_left, m_root);
 | 
			
		||||
            m_root->m_left    = 0;
 | 
			
		||||
            m_root            = new_cell;
 | 
			
		||||
        }
 | 
			
		||||
        else if (r > 0) {
 | 
			
		||||
            cell * new_cell   = alloc(cell, k, m_root, m_root->m_right);
 | 
			
		||||
            m_root->m_right   = 0;
 | 
			
		||||
            m_root            = new_cell;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            m_root->m_key     = k;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Key, typename Compare>
 | 
			
		||||
bool splay_tree<Key, Compare>::find(Key const & k, Key & r) const {
 | 
			
		||||
    if (m_root) {
 | 
			
		||||
        splay_tree<Key, Compare> * _this = const_cast<splay_tree<Key, Compare> *>(this);
 | 
			
		||||
        _this->m_root = _this->splay(m_root, k);
 | 
			
		||||
        if (compare(k, m_root->m_key) == 0) {
 | 
			
		||||
            r = m_root->m_key;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Key, typename Compare>
 | 
			
		||||
void splay_tree<Key, Compare>::erase(Key const & k) {
 | 
			
		||||
    if (m_root) {
 | 
			
		||||
        m_root = splay(m_root, k);
 | 
			
		||||
        if (compare(k, m_root->m_key) == 0) {
 | 
			
		||||
            cell * to_delete = m_root;
 | 
			
		||||
            if (m_root->m_left) {
 | 
			
		||||
                cell * aux = splay(m_root->m_left, k);
 | 
			
		||||
                SASSERT(!aux->m_right);
 | 
			
		||||
                aux->m_right = m_root->m_right;
 | 
			
		||||
                m_root       = aux;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                m_root = m_root->m_right;
 | 
			
		||||
 | 
			
		||||
            dealloc(to_delete);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Key, typename Compare>
 | 
			
		||||
void splay_tree<Key, Compare>::reset() {
 | 
			
		||||
    ptr_buffer<cell> todo;
 | 
			
		||||
    if (m_root) 
 | 
			
		||||
        todo.push_back(m_root);
 | 
			
		||||
    while (!todo.empty()) {
 | 
			
		||||
        cell * c = todo.back();
 | 
			
		||||
        todo.pop_back();
 | 
			
		||||
        if (c->m_left)
 | 
			
		||||
            todo.push_back(c->m_left);
 | 
			
		||||
        if (c->m_right)
 | 
			
		||||
            todo.push_back(c->m_right);
 | 
			
		||||
        dealloc(c);
 | 
			
		||||
    }
 | 
			
		||||
    m_root = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* _SPLAY_TREE_DEF_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,114 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    splay_tree_map.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    A mapping as a splay tree.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-02.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SPLAY_TREE_MAP_H_
 | 
			
		||||
#define _SPLAY_TREE_MAP_H_
 | 
			
		||||
 | 
			
		||||
#include"splay_tree.h"
 | 
			
		||||
 | 
			
		||||
template<typename Key, typename Data, typename Compare>
 | 
			
		||||
class splay_tree_map {
 | 
			
		||||
    typedef std::pair<Key, Data> entry;
 | 
			
		||||
 | 
			
		||||
    struct entry_compare : private Compare {
 | 
			
		||||
        entry_compare(Compare const & c):Compare(c) {}
 | 
			
		||||
        int operator()(entry const & e1, entry const & e2) const {
 | 
			
		||||
            return Compare::operator()(e1.first, e2.first);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef splay_tree<entry, entry_compare> tree;
 | 
			
		||||
    
 | 
			
		||||
    tree m_tree;
 | 
			
		||||
    
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    struct core_visitor_wrapper {
 | 
			
		||||
        Visitor & m_visitor;
 | 
			
		||||
        core_visitor_wrapper(Visitor & v):m_visitor(v) {}
 | 
			
		||||
        bool visit_right(entry const & k) { return m_visitor.visit_right(k.first); }
 | 
			
		||||
        bool visit_left(entry const & k) {  return m_visitor.visit_left(k.first); }
 | 
			
		||||
        void operator()(entry const & k) { m_visitor.operator()(k.first, k.second); }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    struct visitor_wrapper {
 | 
			
		||||
        Visitor & m_visitor;
 | 
			
		||||
        visitor_wrapper(Visitor & v):m_visitor(v) {}
 | 
			
		||||
        void operator()(entry const & k) { m_visitor.operator()(k.first, k.second); }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    splay_tree_map(Compare const & c = Compare()):
 | 
			
		||||
        m_tree(entry_compare(c)) {}
 | 
			
		||||
 | 
			
		||||
    void insert(Key const & k, Data const & d) {
 | 
			
		||||
        m_tree.insert(entry(k, d));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool find(Key const & k, Data & r) const {
 | 
			
		||||
        entry e(k, r);
 | 
			
		||||
        if (m_tree.find(e, e)) {
 | 
			
		||||
            r = e.second;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void erase(Key const & k) {
 | 
			
		||||
        entry e;
 | 
			
		||||
        e.first = k;
 | 
			
		||||
        m_tree.erase(e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() { m_tree.reset(); }
 | 
			
		||||
 | 
			
		||||
    bool empty() const { return m_tree.empty(); }
 | 
			
		||||
 | 
			
		||||
    void display(std::ostream & out) const { m_tree.display(out); }
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_core(Visitor & v) {
 | 
			
		||||
        core_visitor_wrapper<Visitor> w(v);
 | 
			
		||||
        m_tree.visit_core(w);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit(Visitor & v) {
 | 
			
		||||
        visitor_wrapper<Visitor> w(v);
 | 
			
		||||
        m_tree.visit(w);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_le(Visitor & v, Key const & k) {
 | 
			
		||||
        visitor_wrapper<Visitor> w(v);
 | 
			
		||||
        entry e;
 | 
			
		||||
        e.first = k;
 | 
			
		||||
        m_tree.visit_le(w, e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Visitor>
 | 
			
		||||
    void visit_ge(Visitor & v, Key const & k) {
 | 
			
		||||
        visitor_wrapper<Visitor> w(v);
 | 
			
		||||
        entry e;
 | 
			
		||||
        e.first = k;
 | 
			
		||||
        m_tree.visit_ge(w, e);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _SPLAY_TREE_MAP_H_ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,90 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    use_list.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Use list term index.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-04.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"use_list.h"
 | 
			
		||||
 | 
			
		||||
void app_use_list::inc_ref(app * n) {
 | 
			
		||||
    if (n->get_num_args() == 0)
 | 
			
		||||
        return; // ignore constants
 | 
			
		||||
    unsigned id = n->get_id();
 | 
			
		||||
    unsigned c  = m_ref_counter.get(id, 0);
 | 
			
		||||
    m_ref_counter.setx(id, c+1, 0);
 | 
			
		||||
    if (c == 0)
 | 
			
		||||
        m_todo.push_back(n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_use_list::dec_ref(app * n) {
 | 
			
		||||
    if (n->get_num_args() == 0)
 | 
			
		||||
        return; // ignore constants
 | 
			
		||||
    unsigned id = n->get_id();
 | 
			
		||||
    SASSERT(m_ref_counter[id] > 0);
 | 
			
		||||
    m_ref_counter[id]--;
 | 
			
		||||
    if (m_ref_counter[id] == 0) 
 | 
			
		||||
        m_todo.push_back(n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_use_list::insert(expr * n) {
 | 
			
		||||
    if (is_var(n)) 
 | 
			
		||||
        return; // nothing to index
 | 
			
		||||
    SASSERT(m_todo.empty());
 | 
			
		||||
    inc_ref(to_app(n));
 | 
			
		||||
    while (!m_todo.empty()) {
 | 
			
		||||
        app * n = m_todo.back();
 | 
			
		||||
        unsigned num_args = n->get_num_args();
 | 
			
		||||
        for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
            expr * c = n->get_arg(i);
 | 
			
		||||
            if (is_var(c)) {
 | 
			
		||||
                if (!m_ignore_vars) 
 | 
			
		||||
                    use_list<app*>::insert(n, c);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                SASSERT(is_app(c));
 | 
			
		||||
                use_list<app*>::insert(n, c);
 | 
			
		||||
                inc_ref(to_app(c));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_use_list::erase(expr * n) {
 | 
			
		||||
    if (is_var(n)) 
 | 
			
		||||
        return; // nothing to index
 | 
			
		||||
    SASSERT(m_todo.empty());
 | 
			
		||||
    dec_ref(to_app(n));
 | 
			
		||||
    while (!m_todo.empty()) {
 | 
			
		||||
        app * n = m_todo.back();
 | 
			
		||||
        unsigned num_args = n->get_num_args();
 | 
			
		||||
        for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
            expr * c = n->get_arg(i);
 | 
			
		||||
            if (is_var(c)) {
 | 
			
		||||
                if (!m_ignore_vars) 
 | 
			
		||||
                    use_list<app*>::erase(n, c);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                SASSERT(is_app(c));
 | 
			
		||||
                use_list<app*>::erase(n, c);
 | 
			
		||||
                dec_ref(to_app(c));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
void app_use_list::reset() {
 | 
			
		||||
    use_list<app*>::reset();
 | 
			
		||||
    m_ref_counter.reset();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,120 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    use_list.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Use list expression index.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2008-02-04.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _USE_LIST_H_
 | 
			
		||||
#define _USE_LIST_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"vector.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Generic use-list data-structure.
 | 
			
		||||
*/
 | 
			
		||||
template<typename T>
 | 
			
		||||
class use_list {
 | 
			
		||||
    typedef vector<T> set;
 | 
			
		||||
    vector<set> m_use_list;
 | 
			
		||||
public:
 | 
			
		||||
    typedef typename set::const_iterator iterator;
 | 
			
		||||
    use_list() {}
 | 
			
		||||
    
 | 
			
		||||
    void insert(T const & parent, expr * child) {
 | 
			
		||||
        unsigned id  = child->get_id();
 | 
			
		||||
        if (id >= m_use_list.size())
 | 
			
		||||
            m_use_list.resize(id+1, set());
 | 
			
		||||
        set & s = m_use_list[id];
 | 
			
		||||
        s.push_back(parent);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void erase(T const & parent, expr * child) {
 | 
			
		||||
        unsigned id  = child->get_id();
 | 
			
		||||
        if (id >= m_use_list.size())
 | 
			
		||||
            return;
 | 
			
		||||
        set & s = m_use_list[id];
 | 
			
		||||
        s.erase(parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() {
 | 
			
		||||
        m_use_list.reset();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    iterator begin(expr * e) const {
 | 
			
		||||
        unsigned id = e->get_id();
 | 
			
		||||
        if (id >= m_use_list.size())
 | 
			
		||||
            return 0;
 | 
			
		||||
        return m_use_list[id].begin();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    iterator end(expr * e) const {
 | 
			
		||||
        unsigned id = e->get_id();
 | 
			
		||||
        if (id >= m_use_list.size())
 | 
			
		||||
            return 0;
 | 
			
		||||
        return m_use_list[id].end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool empty(expr * e) const {
 | 
			
		||||
        unsigned id = e->get_id();
 | 
			
		||||
        if (id >= m_use_list.size())
 | 
			
		||||
            return true;
 | 
			
		||||
        return m_use_list[id].empty();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Index for tracking the uses of an expression. It is a
 | 
			
		||||
   mapping from expressions to expressions. For example, consider the
 | 
			
		||||
   term (f a (g a)), the constant a is used by f and g applications.
 | 
			
		||||
   
 | 
			
		||||
   \remark The expressions inserted in this index should not contain
 | 
			
		||||
   quantifiers.
 | 
			
		||||
 | 
			
		||||
   \warning This index will not increase the reference counter of the
 | 
			
		||||
   indexed expressions.
 | 
			
		||||
*/
 | 
			
		||||
class app_use_list : use_list<app*> {
 | 
			
		||||
    
 | 
			
		||||
    bool m_ignore_vars; //!< when true, variables are not indexed
 | 
			
		||||
    unsigned_vector  m_ref_counter;
 | 
			
		||||
    ptr_vector<app> m_todo;
 | 
			
		||||
 | 
			
		||||
    void inc_ref(app * n);
 | 
			
		||||
    void dec_ref(app * n);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /**
 | 
			
		||||
       \brief If ignore_vars = true, then the index will not track
 | 
			
		||||
       the use of variables.
 | 
			
		||||
    */
 | 
			
		||||
    app_use_list(bool ignore_vars = true):
 | 
			
		||||
        m_ignore_vars(ignore_vars) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Update the use list of all direct/indirect children of n.
 | 
			
		||||
    */
 | 
			
		||||
    void insert(expr * n);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Remove n (and its unreachable direct/indirect children) from the index.
 | 
			
		||||
    */
 | 
			
		||||
    void erase(expr * n);
 | 
			
		||||
    
 | 
			
		||||
    void reset();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _USE_LIST_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,26 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    st_cmds.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Commands for testing strategies.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2011-04-27
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _ST_CMD_H_
 | 
			
		||||
#define _ST_CMD_H_
 | 
			
		||||
 | 
			
		||||
class cmd_context;
 | 
			
		||||
 | 
			
		||||
void install_st_cmds(cmd_context & ctx);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,46 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2006 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    value_compiler_extension.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Compiler extension for creating values (i.e., "interpreted" constants that
 | 
			
		||||
    are different any other constant).
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2006-10-31.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _VALUE_COMPILER_EXTENSION_H_
 | 
			
		||||
#define _VALUE_COMPILER_EXTENSION_H_
 | 
			
		||||
 | 
			
		||||
#include"ast_compiler.h"
 | 
			
		||||
 | 
			
		||||
class value_compiler_extension : public ast_compiler_plugin {
 | 
			
		||||
    context & m_context;
 | 
			
		||||
public:
 | 
			
		||||
    value_compiler_extension(ast_manager & m, context & ctx):
 | 
			
		||||
        ast_compiler_plugin(m.get_family_id(symbol("interpreted_value"))),
 | 
			
		||||
        m_context(ctx) {
 | 
			
		||||
        ctx.register_plugin(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~value_compiler_extension() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual bool compile_term(ast_compiler & c, const_ast * a, enode * & r) {
 | 
			
		||||
        SASSERT(a->get_decl()->get_family_id() == m_fid);
 | 
			
		||||
        const_decl_ast * d = a->get_decl();
 | 
			
		||||
        r = m_context.mk_interpreted_const(d);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _VALUE_COMPILER_EXTENSION_H_ */
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,404 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    lu.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Simple LU factorization module based on the paper:
 | 
			
		||||
    
 | 
			
		||||
    "Maintaining LU factors of a General Sparse Matrix"
 | 
			
		||||
    P. E. Gill, W. Murray, M. Saunders, M. Wright
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2011-06-09
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _LU_H_
 | 
			
		||||
#define _LU_H_
 | 
			
		||||
 | 
			
		||||
#include"vector.h"
 | 
			
		||||
#include"mpq.h"
 | 
			
		||||
#include"double_manager.h"
 | 
			
		||||
#include"permutation.h"
 | 
			
		||||
#include"params.h"
 | 
			
		||||
#include"strategy_exception.h"
 | 
			
		||||
 | 
			
		||||
MK_ST_EXCEPTION(lu_exception);
 | 
			
		||||
 | 
			
		||||
template<typename NumManager>
 | 
			
		||||
class lu {
 | 
			
		||||
public:
 | 
			
		||||
    typedef NumManager manager;
 | 
			
		||||
    typedef typename NumManager::numeral numeral;
 | 
			
		||||
    typedef svector<numeral> numeral_vector;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    manager &        m_manager;
 | 
			
		||||
    
 | 
			
		||||
    // Configuration
 | 
			
		||||
    numeral          m_mu;  // maximum multiplier when selecting a pivot
 | 
			
		||||
    unsigned         m_selection_cutoff;
 | 
			
		||||
    
 | 
			
		||||
    // Matrix size
 | 
			
		||||
    unsigned         m_sz; // supporting only square matrices
 | 
			
		||||
 | 
			
		||||
    // Permutations
 | 
			
		||||
    permutation      P;  
 | 
			
		||||
    permutation      Q;
 | 
			
		||||
    
 | 
			
		||||
    // L 
 | 
			
		||||
    //
 | 
			
		||||
    // It is 3 parallel vectors representing the sequence (product) of matrices
 | 
			
		||||
    //            L[0] L[1] ... L[m-1]
 | 
			
		||||
    // where each L[i] is a tuple (A[i], indc[i], indr[i]).
 | 
			
		||||
    // Each tuple represents a triangular factor. That is, an identity matrix
 | 
			
		||||
    // where the position at row indc[i], and column indr[i] contains the value A[i].
 | 
			
		||||
    // Remark: The product L[0] L[1] ... L[n-1] is not really a triangular matrix.
 | 
			
		||||
    struct L_file {
 | 
			
		||||
        numeral_vector   A;
 | 
			
		||||
        unsigned_vector  indc;
 | 
			
		||||
        unsigned_vector  indr;
 | 
			
		||||
    };
 | 
			
		||||
    L_file L;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // U
 | 
			
		||||
    //
 | 
			
		||||
    // It is not really upper triangular, but the product PUQ is.
 | 
			
		||||
    // The rows of U are stored in the parallel vectors (A, indr)
 | 
			
		||||
    // Only the non-zero values are stored at U.
 | 
			
		||||
    // The non-zeros of row i start at position begr[i] and end at 
 | 
			
		||||
    // position endr[i] of the parallel vectors (A, indr). 
 | 
			
		||||
    // The length of the row is endr[i] - begr[i].
 | 
			
		||||
    // The coefficients are stored in A, and the column ids at indr.
 | 
			
		||||
    //
 | 
			
		||||
    // The factorization of a matrix A is represented as:
 | 
			
		||||
    //    L[0] L[1] ... L[m-1] P U Q
 | 
			
		||||
    struct U_file {
 | 
			
		||||
        numeral_vector  A;
 | 
			
		||||
        unsigned_vector indr;
 | 
			
		||||
        unsigned_vector begr;
 | 
			
		||||
        unsigned_vector endr;
 | 
			
		||||
        
 | 
			
		||||
        unsigned num_entries;
 | 
			
		||||
        U_file():num_entries(0) {}
 | 
			
		||||
    };
 | 
			
		||||
    U_file U;
 | 
			
		||||
    
 | 
			
		||||
    // The actual factorization
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    // T_file: temporary file used for factorization
 | 
			
		||||
    struct T_file {
 | 
			
		||||
        // row list
 | 
			
		||||
        unsigned_vector indr;
 | 
			
		||||
        unsigned_vector begr;
 | 
			
		||||
        unsigned_vector endr;
 | 
			
		||||
        
 | 
			
		||||
        // column list
 | 
			
		||||
        numeral_vector  A;
 | 
			
		||||
        unsigned_vector indc;
 | 
			
		||||
        unsigned_vector begc;
 | 
			
		||||
        unsigned_vector endc;
 | 
			
		||||
 | 
			
		||||
        unsigned        num_entries;
 | 
			
		||||
        T_file():num_entries(0) {}
 | 
			
		||||
    };
 | 
			
		||||
    T_file T;
 | 
			
		||||
    
 | 
			
		||||
    // Auxiliary fields
 | 
			
		||||
    unsigned_vector locw;
 | 
			
		||||
    
 | 
			
		||||
    // -----------------------
 | 
			
		||||
    //
 | 
			
		||||
    // Main
 | 
			
		||||
    //
 | 
			
		||||
    // -----------------------
 | 
			
		||||
public:
 | 
			
		||||
    lu(manager & m, params_ref const & p);
 | 
			
		||||
    ~lu();
 | 
			
		||||
 | 
			
		||||
    manager & m() const { return m_manager; }
 | 
			
		||||
 | 
			
		||||
    void updt_params(params_ref const & p);
 | 
			
		||||
 | 
			
		||||
    void reset();
 | 
			
		||||
 | 
			
		||||
    unsigned size() const { return m_sz; }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    void del_nums(numeral_vector & nums);
 | 
			
		||||
 | 
			
		||||
    // -----------------------
 | 
			
		||||
    //
 | 
			
		||||
    // Initialization
 | 
			
		||||
    //
 | 
			
		||||
    // -----------------------
 | 
			
		||||
public:
 | 
			
		||||
    // Contract for setting up the initial matrix:
 | 
			
		||||
    //   lu.init(size)
 | 
			
		||||
    //   - for each row r in the matrix
 | 
			
		||||
    //     - for each non-zero (a,x) in the row
 | 
			
		||||
    //        lu.add_entry(a, x)
 | 
			
		||||
    //     lu.end_row()
 | 
			
		||||
    void init(unsigned size);
 | 
			
		||||
    void add_entry(numeral const & a, unsigned x);
 | 
			
		||||
    void end_row();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    // auxiliary fields used during initialization
 | 
			
		||||
    bool     ini; // try if the matrix T is being setup using the protocol above
 | 
			
		||||
    unsigned ini_irow;
 | 
			
		||||
    unsigned fillin_for(unsigned sz);
 | 
			
		||||
    void move_col_to_end(unsigned x);
 | 
			
		||||
    void move_row_to_end(unsigned x);
 | 
			
		||||
 | 
			
		||||
    // -----------------------
 | 
			
		||||
    //
 | 
			
		||||
    // Factorization
 | 
			
		||||
    //
 | 
			
		||||
    // -----------------------
 | 
			
		||||
public:
 | 
			
		||||
    void fact();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    class todo {
 | 
			
		||||
        unsigned_vector          m_elem2len;
 | 
			
		||||
        unsigned_vector          m_elem2pos;
 | 
			
		||||
        vector<unsigned_vector>  m_elems_per_len;
 | 
			
		||||
        unsigned                 m_size;
 | 
			
		||||
    public:
 | 
			
		||||
        todo():m_size(0) {}
 | 
			
		||||
        bool contains(unsigned elem) const { return m_elem2pos[elem] != UINT_MAX; }
 | 
			
		||||
        void init(unsigned capacity);
 | 
			
		||||
        void updt_len(unsigned elem, unsigned len);
 | 
			
		||||
        unsigned len(unsigned elem) const { return m_elem2len[elem]; }
 | 
			
		||||
        void erase(unsigned elem);
 | 
			
		||||
        unsigned size() const { return m_size; }
 | 
			
		||||
        void display(std::ostream & out) const;
 | 
			
		||||
        class iterator {
 | 
			
		||||
            todo const & m_todo;
 | 
			
		||||
            unsigned     m_i;
 | 
			
		||||
            unsigned     m_j;
 | 
			
		||||
            unsigned     m_c;
 | 
			
		||||
            void find_next();
 | 
			
		||||
        public:
 | 
			
		||||
            iterator(todo const & t):m_todo(t), m_i(0), m_j(0), m_c(0) { if (!at_end()) find_next(); }
 | 
			
		||||
            bool at_end() const { return m_c == m_todo.m_size; }
 | 
			
		||||
            unsigned curr() const { 
 | 
			
		||||
                unsigned_vector const & v_i = m_todo.m_elems_per_len[m_i];
 | 
			
		||||
                return v_i[m_j]; 
 | 
			
		||||
            }
 | 
			
		||||
            void next() { SASSERT(!at_end()); m_j++; m_c++; find_next(); }
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    todo          m_todo_rows;
 | 
			
		||||
    todo          m_todo_cols;
 | 
			
		||||
    svector<bool> m_enabled_rows;
 | 
			
		||||
    svector<bool> m_enabled_cols;
 | 
			
		||||
 | 
			
		||||
    bool enabled_row(unsigned r) const { return m_enabled_rows[r]; }
 | 
			
		||||
    bool enabled_col(unsigned c) const { return m_enabled_cols[c]; }
 | 
			
		||||
 | 
			
		||||
    unsigned_vector m_toadd_rows;
 | 
			
		||||
    svector<bool>   m_marked_rows;
 | 
			
		||||
 | 
			
		||||
    // Temporary numerals
 | 
			
		||||
    // I do not use local numerals to avoid memory leaks
 | 
			
		||||
    numeral         tol;
 | 
			
		||||
    numeral         C_max;
 | 
			
		||||
    numeral         A_ij;
 | 
			
		||||
    numeral         A_best;
 | 
			
		||||
    numeral         A_aux;
 | 
			
		||||
    numeral         tmp;
 | 
			
		||||
    numeral         mu_best;
 | 
			
		||||
    numeral         mu_1;
 | 
			
		||||
 | 
			
		||||
    void init_fact();
 | 
			
		||||
    bool stability_test(unsigned rin, unsigned cin, bool improvingM);
 | 
			
		||||
    void select_pivot(unsigned & r_out, unsigned & c_out);
 | 
			
		||||
    void process_pivot_core(unsigned r, unsigned c);
 | 
			
		||||
    void process_pivot(unsigned i, unsigned r, unsigned c);
 | 
			
		||||
    bool check_locw() const;
 | 
			
		||||
    void dec_lenr(unsigned r);
 | 
			
		||||
    void inc_lenr(unsigned r);
 | 
			
		||||
    void dec_lenc(unsigned c);
 | 
			
		||||
    void inc_lenc(unsigned c);
 | 
			
		||||
    void del_row_entry(unsigned r, unsigned c);
 | 
			
		||||
    void del_disabled_cols(unsigned r);
 | 
			
		||||
    void add_row_entry(unsigned r, unsigned c);
 | 
			
		||||
    void add_col_entry(unsigned r, unsigned c, numeral const & a);
 | 
			
		||||
    void compress_rows();
 | 
			
		||||
    void compress_columns();
 | 
			
		||||
    void compress_if_needed();
 | 
			
		||||
    void copy_T_to_U();
 | 
			
		||||
 | 
			
		||||
    bool check_lenr() const;
 | 
			
		||||
    bool check_lenc() const;
 | 
			
		||||
 | 
			
		||||
    // -----------------------
 | 
			
		||||
    //
 | 
			
		||||
    // Solving
 | 
			
		||||
    //
 | 
			
		||||
    // -----------------------
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
    // Temporary vector used to interact with different solvers.
 | 
			
		||||
    // The vector has support for tracking non-zeros.
 | 
			
		||||
    class dense_vector {
 | 
			
		||||
    public:
 | 
			
		||||
        typedef typename lu<NumManager>::manager manager;
 | 
			
		||||
        typedef typename lu<NumManager>::numeral numeral;
 | 
			
		||||
    private:
 | 
			
		||||
        friend class lu;
 | 
			
		||||
        manager &       m_manager;
 | 
			
		||||
        unsigned_vector m_non_zeros; // positions that may contain non-zeros. if a position is not here, then it must contain a zero
 | 
			
		||||
        char_vector     m_in_non_zeros; // m_in_non_zeros[i] == true if m_non_zeros contains i.
 | 
			
		||||
        numeral_vector  m_values;
 | 
			
		||||
    public:
 | 
			
		||||
        dense_vector(manager & m, unsigned sz);
 | 
			
		||||
        ~dense_vector();
 | 
			
		||||
 | 
			
		||||
        manager & m() const { return m_manager; }
 | 
			
		||||
        
 | 
			
		||||
        void reset();
 | 
			
		||||
        void reset(unsigned new_sz);
 | 
			
		||||
        
 | 
			
		||||
        unsigned size() const { return m_values.size(); }
 | 
			
		||||
        numeral const & operator[](unsigned idx) const { return m_values[idx]; }
 | 
			
		||||
        
 | 
			
		||||
        void swap(dense_vector & other) {
 | 
			
		||||
            m_non_zeros.swap(other.m_non_zeros);
 | 
			
		||||
            m_in_non_zeros.swap(other.m_in_non_zeros);
 | 
			
		||||
            m_values.swap(other.m_values);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get a given position for performing an update.
 | 
			
		||||
        // idx is inserted into m_non_zeros.
 | 
			
		||||
        numeral & get(unsigned idx) {
 | 
			
		||||
            if (!m_in_non_zeros[idx]) {
 | 
			
		||||
                m_in_non_zeros[idx] = true;
 | 
			
		||||
                m_non_zeros.push_back(idx);
 | 
			
		||||
            }
 | 
			
		||||
            return m_values[idx];
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        typedef unsigned_vector::const_iterator iterator;
 | 
			
		||||
        
 | 
			
		||||
        // iterator for positions that may contain non-zeros
 | 
			
		||||
        iterator begin_non_zeros() const { return m_non_zeros.begin(); }
 | 
			
		||||
        iterator end_non_zeros() const { return m_non_zeros.end(); }
 | 
			
		||||
        
 | 
			
		||||
        void display(std::ostream & out) const;
 | 
			
		||||
        void display_non_zeros(std::ostream & out) const;
 | 
			
		||||
        void display_pol(std::ostream & out) const;
 | 
			
		||||
 | 
			
		||||
        void elim_zeros();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Solve: Lx = y
 | 
			
		||||
    // The result is stored in y.
 | 
			
		||||
    void solve_Lx_eq_y(dense_vector & y);
 | 
			
		||||
    
 | 
			
		||||
    // Solve: PUQx = y  
 | 
			
		||||
    // The result is stored in y.
 | 
			
		||||
    void solve_Ux_eq_y(dense_vector & y);
 | 
			
		||||
    
 | 
			
		||||
    // Solve: LPUQx = y
 | 
			
		||||
    // The result is stored in y.
 | 
			
		||||
    void solve_Ax_eq_y(dense_vector & y) {
 | 
			
		||||
        solve_Lx_eq_y(y); 
 | 
			
		||||
        solve_Ux_eq_y(y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Solve: xL = y
 | 
			
		||||
    // The result is stored in y.
 | 
			
		||||
    void solve_xL_eq_y(dense_vector & y);
 | 
			
		||||
    
 | 
			
		||||
    // Solve: xPUQ = y
 | 
			
		||||
    // The result is stored in y.
 | 
			
		||||
    void solve_xU_eq_y(dense_vector & y);
 | 
			
		||||
 | 
			
		||||
    // Solve: xA = y
 | 
			
		||||
    // The result is stored in y.
 | 
			
		||||
    void solve_xA_eq_y(dense_vector & y) {
 | 
			
		||||
        solve_xU_eq_y(y);
 | 
			
		||||
        solve_xL_eq_y(y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    dense_vector m_tmp_xU_vector;
 | 
			
		||||
    dense_vector m_tmp_replace_column_vector;
 | 
			
		||||
    dense_vector m_tmp_vector;
 | 
			
		||||
    dense_vector m_tmp_row;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    dense_vector & get_tmp_vector() { return m_tmp_vector; }
 | 
			
		||||
    dense_vector & get_tmp_row(unsigned size) { m_tmp_row.reset(size); return m_tmp_row; }
 | 
			
		||||
 | 
			
		||||
    // -----------------------
 | 
			
		||||
    //
 | 
			
		||||
    // Column replacement
 | 
			
		||||
    //
 | 
			
		||||
    // -----------------------
 | 
			
		||||
public:
 | 
			
		||||
    void replace_column(unsigned j, dense_vector & new_col);
 | 
			
		||||
    void replace_U_column(unsigned j, dense_vector & new_col);
 | 
			
		||||
    unsigned get_num_replacements() const { return m_num_replacements; }
 | 
			
		||||
    dense_vector & get_tmp_col() { return m_tmp_col; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    unsigned        m_num_replacements;
 | 
			
		||||
    dense_vector    m_tmp_col;
 | 
			
		||||
 | 
			
		||||
    void del_U_row_entry(unsigned r, unsigned c);
 | 
			
		||||
    void compress_U_rows();
 | 
			
		||||
    void compress_U_if_needed();
 | 
			
		||||
    void move_U_row_to_end(unsigned r);
 | 
			
		||||
    void add_U_row_entry(unsigned r, unsigned c, numeral const & a);
 | 
			
		||||
    void add_replace_U_row_entry(unsigned r, unsigned c, numeral const & a);
 | 
			
		||||
    unsigned replace_U_column_core(unsigned j, dense_vector & new_col);
 | 
			
		||||
    bool check_U_except_col(unsigned c) const;
 | 
			
		||||
    bool check_U_except_row(unsigned r) const;
 | 
			
		||||
    
 | 
			
		||||
    // -----------------------
 | 
			
		||||
    //
 | 
			
		||||
    // Invariants
 | 
			
		||||
    //
 | 
			
		||||
    // -----------------------
 | 
			
		||||
public:
 | 
			
		||||
    bool check_P() const;    
 | 
			
		||||
    bool check_Q() const;    
 | 
			
		||||
    bool check_L() const;
 | 
			
		||||
    bool check_U() const;
 | 
			
		||||
    bool T_col_contains(unsigned c, unsigned r) const;
 | 
			
		||||
    bool T_row_contains(unsigned r, unsigned c) const;
 | 
			
		||||
    bool check_T() const;
 | 
			
		||||
    bool check_invariant() const;
 | 
			
		||||
 | 
			
		||||
    void display_T(std::ostream & out) const;
 | 
			
		||||
    void display_U(std::ostream & out, unsigned_vector const * var_ids = 0) const;
 | 
			
		||||
    void display_L(std::ostream & out) const;
 | 
			
		||||
    void display(std::ostream & out, unsigned_vector const * var_ids = 0) const;
 | 
			
		||||
 | 
			
		||||
    // -----------------------
 | 
			
		||||
    //
 | 
			
		||||
    // Info
 | 
			
		||||
    //
 | 
			
		||||
    // -----------------------
 | 
			
		||||
public:
 | 
			
		||||
    unsigned L_size() const { return L.indc.size(); }
 | 
			
		||||
    unsigned U_size() const { return U.num_entries; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef lu<unsynch_mpq_manager> rational_lu;
 | 
			
		||||
typedef lu<double_manager>      double_lu;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,135 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2012 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    mip_tactic.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Tactic for solvig MIP (mixed integer) problem.
 | 
			
		||||
    This is a temporary tactic. It should be deleted
 | 
			
		||||
    after theory_arith is upgraded.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo (leonardo) 2012-02-26
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"tactical.h"
 | 
			
		||||
#include"smt_solver_exp.h"
 | 
			
		||||
 | 
			
		||||
class mip_tactic : public tactic {
 | 
			
		||||
    struct imp;
 | 
			
		||||
    ast_manager &               m;
 | 
			
		||||
    params_ref                  m_params;
 | 
			
		||||
    statistics                  m_stats;
 | 
			
		||||
    scoped_ptr<smt::solver_exp> m_solver;
 | 
			
		||||
 | 
			
		||||
    void init_solver() {
 | 
			
		||||
        smt::solver_exp * new_solver = alloc(smt::solver_exp, m, m_params);
 | 
			
		||||
        #pragma omp critical (tactic_cancel)
 | 
			
		||||
        {
 | 
			
		||||
            m_solver = new_solver;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    mip_tactic(ast_manager & _m, params_ref const & p):
 | 
			
		||||
        m(_m),
 | 
			
		||||
        m_params(p) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual tactic * translate(ast_manager & m) {
 | 
			
		||||
        return alloc(mip_tactic, m, m_params);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~mip_tactic() {}
 | 
			
		||||
 | 
			
		||||
    virtual void updt_params(params_ref const & p) {
 | 
			
		||||
        m_params = p;
 | 
			
		||||
    }
 | 
			
		||||
    virtual void collect_param_descrs(param_descrs & r) {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    virtual void operator()(goal_ref const & g, 
 | 
			
		||||
                            goal_ref_buffer & result, 
 | 
			
		||||
                            model_converter_ref & mc, 
 | 
			
		||||
                            proof_converter_ref & pc,
 | 
			
		||||
                            expr_dependency_ref & core) {
 | 
			
		||||
        SASSERT(g->is_well_sorted());
 | 
			
		||||
        bool produce_models = g->models_enabled();
 | 
			
		||||
        mc = 0; pc = 0; core = 0; result.reset();
 | 
			
		||||
        tactic_report report("mip", *g);
 | 
			
		||||
        fail_if_proof_generation("mip", g);
 | 
			
		||||
        fail_if_unsat_core_generation("mip", g);
 | 
			
		||||
 | 
			
		||||
        g->elim_redundancies();
 | 
			
		||||
        if (g->inconsistent()) {
 | 
			
		||||
            result.push_back(g.get());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        init_solver();
 | 
			
		||||
        m_solver->assert_goal(*g);
 | 
			
		||||
        
 | 
			
		||||
        lbool r;
 | 
			
		||||
        try {
 | 
			
		||||
            r = m_solver->check();
 | 
			
		||||
        }
 | 
			
		||||
        catch (strategy_exception & ex) {
 | 
			
		||||
            // solver_exp uses assertion_sets and strategy_exception's
 | 
			
		||||
            throw tactic_exception(ex.msg());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_solver->collect_statistics(m_stats);
 | 
			
		||||
 | 
			
		||||
        if (r == l_false) {
 | 
			
		||||
            g->reset();
 | 
			
		||||
            g->assert_expr(m.mk_false());
 | 
			
		||||
        }
 | 
			
		||||
        else if (r == l_true) {
 | 
			
		||||
            g->reset();
 | 
			
		||||
            if (produce_models) {
 | 
			
		||||
                model_ref md;
 | 
			
		||||
                m_solver->get_model(md);
 | 
			
		||||
                mc = model2model_converter(md.get());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            // failed
 | 
			
		||||
        }
 | 
			
		||||
        g->inc_depth();
 | 
			
		||||
        result.push_back(g.get());
 | 
			
		||||
        TRACE("mip", g->display(tout););
 | 
			
		||||
        SASSERT(g->is_well_sorted());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void cleanup() {
 | 
			
		||||
        if (m_solver)
 | 
			
		||||
            m_solver->collect_statistics(m_stats);
 | 
			
		||||
        #pragma omp critical (tactic_cancel)
 | 
			
		||||
        {
 | 
			
		||||
            m_solver = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    virtual void collect_statistics(statistics & st) const {
 | 
			
		||||
        st.copy(m_stats);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void reset_statistics() {
 | 
			
		||||
        m_stats.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void set_cancel(bool f) {
 | 
			
		||||
        if (m_solver)
 | 
			
		||||
            m_solver->set_cancel(f);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
tactic * mk_mip_tactic(ast_manager & m, params_ref const & p) {
 | 
			
		||||
    return clean(alloc(mip_tactic, m, p));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,30 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2012 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    mip_tactic.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Tactic for solvig MIP (mixed integer) problem.
 | 
			
		||||
    This is a temporary tactic. It should be deleted
 | 
			
		||||
    after theory_arith is upgraded.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo (leonardo) 2012-02-26
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _MIP_TACTIC_H_
 | 
			
		||||
#define _MIP_TACTIC_H_
 | 
			
		||||
 | 
			
		||||
#include"params.h"
 | 
			
		||||
class ast_manager;
 | 
			
		||||
class tactic;
 | 
			
		||||
 | 
			
		||||
tactic * mk_mip_tactic(ast_manager & m, params_ref const & p = params_ref());
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,56 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    smt_arith.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Arithmetic solver for smt::solver
 | 
			
		||||
    
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2011-06-25.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SMT_ARITH_H_
 | 
			
		||||
#define _SMT_ARITH_H_
 | 
			
		||||
 | 
			
		||||
#include"ast.h"
 | 
			
		||||
#include"smt_solver_types.h"
 | 
			
		||||
#include"params.h"
 | 
			
		||||
#include"statistics.h"
 | 
			
		||||
class model;
 | 
			
		||||
 | 
			
		||||
namespace smt {
 | 
			
		||||
 | 
			
		||||
    class arith {
 | 
			
		||||
        struct imp;
 | 
			
		||||
        imp *       m_imp;
 | 
			
		||||
        params_ref  m_params;  
 | 
			
		||||
    public:
 | 
			
		||||
        arith(ast_manager & m, params_ref const & p);
 | 
			
		||||
        ~arith();
 | 
			
		||||
        void updt_params(params_ref const & p);
 | 
			
		||||
        void assert_axiom(expr * t, bool neg);
 | 
			
		||||
        void mk_atom(expr * t, atom_id id);
 | 
			
		||||
        void asserted(atom_id id, bool is_true);
 | 
			
		||||
        bool inconsistent() const;
 | 
			
		||||
        void push();
 | 
			
		||||
        void pop(unsigned num_scopes);
 | 
			
		||||
        void set_cancel(bool f);
 | 
			
		||||
        void simplify();
 | 
			
		||||
        void display(std::ostream & out) const;
 | 
			
		||||
        void reset();
 | 
			
		||||
        void preprocess();
 | 
			
		||||
        void collect_statistics(statistics & st) const;
 | 
			
		||||
        void reset_statistics();
 | 
			
		||||
        lbool check();
 | 
			
		||||
        void mk_model(model * md);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,218 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    smt_formula_compiler.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Auxiliary class for smt::solver
 | 
			
		||||
    Convert Exprs into Internal data-structures.    
 | 
			
		||||
    
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2011-06-25.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
    This was an experiment to rewrite Z3 kernel.
 | 
			
		||||
    It will be deleted after we finish revamping Z3 kernel.
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include"smt_formula_compiler.h"
 | 
			
		||||
#include"smt_solver_exp.h"
 | 
			
		||||
#include"assertion_set_util.h"
 | 
			
		||||
#include"assertion_set2sat.h"
 | 
			
		||||
#include"for_each_expr.h"
 | 
			
		||||
 | 
			
		||||
namespace smt {
 | 
			
		||||
 | 
			
		||||
    formula_compiler::formula_compiler(solver_exp & _s, params_ref const & p):
 | 
			
		||||
        s(_s),
 | 
			
		||||
        m_a_util(s.m),
 | 
			
		||||
        m_normalizer(s.m),
 | 
			
		||||
        m_elim_ite(s.m) {
 | 
			
		||||
        updt_params(p);
 | 
			
		||||
     
 | 
			
		||||
        params_ref s_p;
 | 
			
		||||
        s_p.set_bool(":elim-and", true);
 | 
			
		||||
        s_p.set_bool(":blast-distinct", true);
 | 
			
		||||
        s_p.set_bool(":eq2ineq", true);
 | 
			
		||||
        s_p.set_bool(":arith-lhs", true);
 | 
			
		||||
        s_p.set_bool(":gcd-rounding", true);
 | 
			
		||||
        s_p.set_bool(":sort-sums", true);
 | 
			
		||||
        s_p.set_bool(":som", true);
 | 
			
		||||
        m_normalizer.updt_params(s_p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    formula_compiler::~formula_compiler() {
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // mark theory axioms: literals that do not occur in the boolean structure
 | 
			
		||||
    void formula_compiler::mark_axioms(assertion_set const & s, expr_fast_mark2 & axioms) {
 | 
			
		||||
        ast_manager & m = s.m();
 | 
			
		||||
        unsigned sz = s.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
            expr * f = s.form(i);
 | 
			
		||||
            while (m.is_not(f, f));
 | 
			
		||||
            if (!is_app(f) || to_app(f)->get_family_id() != m.get_basic_family_id()) {
 | 
			
		||||
                axioms.mark(f);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            SASSERT(is_app(f));
 | 
			
		||||
            SASSERT(to_app(f)->get_family_id() == m.get_basic_family_id());
 | 
			
		||||
            switch (to_app(f)->get_decl_kind()) {
 | 
			
		||||
            case OP_OR:
 | 
			
		||||
            case OP_IFF:
 | 
			
		||||
                break;
 | 
			
		||||
            case OP_ITE:
 | 
			
		||||
                SASSERT(m.is_bool(to_app(f)->get_arg(1)));
 | 
			
		||||
                break;
 | 
			
		||||
            case OP_EQ:
 | 
			
		||||
                if (!m.is_bool(to_app(f)->get_arg(1)))
 | 
			
		||||
                    axioms.mark(f);
 | 
			
		||||
                break;
 | 
			
		||||
            case OP_AND:
 | 
			
		||||
            case OP_XOR:
 | 
			
		||||
            case OP_IMPLIES:
 | 
			
		||||
            case OP_DISTINCT:
 | 
			
		||||
                UNREACHABLE();
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct unmark_axioms_proc {
 | 
			
		||||
        expr_fast_mark2 & m_axioms;
 | 
			
		||||
        unmark_axioms_proc(expr_fast_mark2 & axioms):m_axioms(axioms) {}
 | 
			
		||||
        void operator()(quantifier *) {}
 | 
			
		||||
        void operator()(var *) {}
 | 
			
		||||
        void operator()(app * t) { 
 | 
			
		||||
            m_axioms.reset_mark(t); 
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Unmark atoms that occur in the boolean structure.
 | 
			
		||||
    */
 | 
			
		||||
    void formula_compiler::unmark_nested_atoms(assertion_set const & s, expr_fast_mark2 & axioms) {
 | 
			
		||||
        ast_manager & m = s.m();
 | 
			
		||||
        expr_fast_mark1 visited;
 | 
			
		||||
        unmark_axioms_proc proc(axioms);
 | 
			
		||||
        unsigned sz = s.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
            expr * f = s.form(i);
 | 
			
		||||
            while (m.is_not(f, f));
 | 
			
		||||
            if (axioms.is_marked(f))
 | 
			
		||||
                continue;
 | 
			
		||||
            quick_for_each_expr(proc, visited, f);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void formula_compiler::assert_axiom(expr * f, bool neg) {
 | 
			
		||||
        if (is_app(f)) {
 | 
			
		||||
            if (to_app(f)->get_family_id() == m_a_util.get_family_id())
 | 
			
		||||
                s.m_arith.assert_axiom(f, neg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void formula_compiler::register_atom(expr * f, sat::bool_var p) {
 | 
			
		||||
        if (is_app(f)) {
 | 
			
		||||
            if (to_app(f)->get_family_id() == m_a_util.get_family_id())
 | 
			
		||||
                s.m_arith.mk_atom(f, p);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void formula_compiler::compile_formulas(assertion_set const & assertions) {
 | 
			
		||||
        ast_manager & m = assertions.m();
 | 
			
		||||
        expr_fast_mark2 axioms;
 | 
			
		||||
        mark_axioms(assertions, axioms);
 | 
			
		||||
        unmark_nested_atoms(assertions, axioms);
 | 
			
		||||
        ptr_vector<expr> formulas;
 | 
			
		||||
 | 
			
		||||
        // send axioms to theories, and save formulas to compile
 | 
			
		||||
        unsigned sz = assertions.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
            expr * f = assertions.form(i);
 | 
			
		||||
            bool neg = false;
 | 
			
		||||
            while (m.is_not(f, f))
 | 
			
		||||
                neg = !neg;
 | 
			
		||||
            if (axioms.is_marked(f)) {
 | 
			
		||||
                assert_axiom(f, neg);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                formulas.push_back(f);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // compile formulas into sat::solver
 | 
			
		||||
        m_to_sat(m, formulas.size(), formulas.c_ptr(), s.m_params, *(s.m_sat), s.m_atom2bvar);
 | 
			
		||||
 | 
			
		||||
        // register atoms nested in the boolean structure in the theories  
 | 
			
		||||
        atom2bool_var::recent_iterator it  = s.m_atom2bvar.begin_recent();
 | 
			
		||||
        atom2bool_var::recent_iterator end = s.m_atom2bvar.end_recent();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            expr * atom = *it;
 | 
			
		||||
            register_atom(atom, s.m_atom2bvar.to_bool_var(atom));
 | 
			
		||||
        }
 | 
			
		||||
        s.m_atom2bvar.reset_recent();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void formula_compiler::normalize() {
 | 
			
		||||
        // make sure that the assertions are in the right format.
 | 
			
		||||
        m_normalizer(s.m_assertions);
 | 
			
		||||
        m_normalizer.cleanup();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void formula_compiler::elim_term_ite() {
 | 
			
		||||
        if (has_term_ite(s.m_assertions)) {
 | 
			
		||||
            model_converter_ref mc;
 | 
			
		||||
            m_elim_ite(s.m_assertions, mc);
 | 
			
		||||
            s.m_mc = concat(s.m_mc.get(), mc.get());
 | 
			
		||||
            m_elim_ite.cleanup();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void formula_compiler::operator()() {
 | 
			
		||||
        if (s.m_assertions.inconsistent())
 | 
			
		||||
            return;
 | 
			
		||||
        // normalization
 | 
			
		||||
        elim_term_ite();
 | 
			
		||||
        normalize();
 | 
			
		||||
 | 
			
		||||
        TRACE("before_formula_compiler", s.m_assertions.display(tout););
 | 
			
		||||
        
 | 
			
		||||
        s.init();
 | 
			
		||||
 | 
			
		||||
        compile_formulas(s.m_assertions);
 | 
			
		||||
        
 | 
			
		||||
        s.m_arith.preprocess();
 | 
			
		||||
        TRACE("after_formula_compiler", s.display_state(tout););
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void formula_compiler::updt_params(params_ref const & p) {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void formula_compiler::collect_param_descrs(param_descrs & d) {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void formula_compiler::collect_statistics(statistics & st) {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void formula_compiler::reset_statistics() {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void formula_compiler::set_cancel(bool f) {
 | 
			
		||||
        m_normalizer.set_cancel(f);
 | 
			
		||||
        m_elim_ite.set_cancel(f);
 | 
			
		||||
        m_to_sat.set_cancel(f);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,63 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    smt_formula_compiler.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Auxiliary class for smt::solver
 | 
			
		||||
    Convert Exprs into Internal data-structures.    
 | 
			
		||||
    
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Leonardo de Moura (leonardo) 2011-06-25.
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#ifndef _SMT_FORMULA_COMPILER_H_
 | 
			
		||||
#define _SMT_FORMULA_COMPILER_H_
 | 
			
		||||
 | 
			
		||||
#include"smt_solver_types.h"
 | 
			
		||||
#include"assertion_set_rewriter.h"
 | 
			
		||||
#include"elim_term_ite_strategy.h"
 | 
			
		||||
#include"arith_decl_plugin.h"
 | 
			
		||||
#include"assertion_set2sat.h"
 | 
			
		||||
 | 
			
		||||
namespace smt {
 | 
			
		||||
    
 | 
			
		||||
    class formula_compiler {
 | 
			
		||||
        solver_exp &           s;
 | 
			
		||||
        arith_util             m_a_util;
 | 
			
		||||
        assertion_set_rewriter m_normalizer;
 | 
			
		||||
        elim_term_ite_strategy m_elim_ite;
 | 
			
		||||
        assertion_set2sat      m_to_sat;
 | 
			
		||||
 | 
			
		||||
        void normalize();
 | 
			
		||||
        void elim_term_ite();
 | 
			
		||||
        void mark_axioms(assertion_set const & s, expr_fast_mark2 & axioms);
 | 
			
		||||
        void unmark_nested_atoms(assertion_set const & s, expr_fast_mark2 & axioms);
 | 
			
		||||
        void assert_axiom(expr * f, bool neg);
 | 
			
		||||
        void register_atom(expr * f, sat::bool_var p);
 | 
			
		||||
        void compile_formulas(assertion_set const & assertions);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        formula_compiler(solver_exp & s, params_ref const & p);
 | 
			
		||||
        ~formula_compiler();
 | 
			
		||||
 | 
			
		||||
        void updt_params(params_ref const & p);
 | 
			
		||||
        static void collect_param_descrs(param_descrs & d);
 | 
			
		||||
        
 | 
			
		||||
        void operator()(); 
 | 
			
		||||
        
 | 
			
		||||
        void set_cancel(bool f);
 | 
			
		||||
 | 
			
		||||
        void collect_statistics(statistics & st);
 | 
			
		||||
        void reset_statistics();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
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