mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	merged with unstable
This commit is contained in:
		
							parent
							
								
									7bf87e76ea
								
							
						
					
					
						commit
						c007a5e5bd
					
				
					 48 changed files with 537 additions and 256 deletions
				
			
		| 
						 | 
					@ -1630,9 +1630,7 @@ public:
 | 
				
			||||||
                unsigned parent_id = Z3_get_ast_id(ctx, p.arg(0));
 | 
					                unsigned parent_id = Z3_get_ast_id(ctx, p.arg(0));
 | 
				
			||||||
                std::set<unsigned> const& hyps = m_proof_hypotheses.find(parent_id)->second;
 | 
					                std::set<unsigned> const& hyps = m_proof_hypotheses.find(parent_id)->second;
 | 
				
			||||||
                print_hypotheses(out, hyps);
 | 
					                print_hypotheses(out, hyps);
 | 
				
			||||||
                out << ").\n";
 | 
					                out << "))).\n";
 | 
				
			||||||
                break;                
 | 
					 | 
				
			||||||
                display_inference(out, "lemma", "thm", p);
 | 
					 | 
				
			||||||
                break;                
 | 
					                break;                
 | 
				
			||||||
            }     
 | 
					            }     
 | 
				
			||||||
            case Z3_OP_PR_UNIT_RESOLUTION:                                 
 | 
					            case Z3_OP_PR_UNIT_RESOLUTION:                                 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@ GPROF=False
 | 
				
			||||||
GIT_HASH=False
 | 
					GIT_HASH=False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_output(cmd):
 | 
					def check_output(cmd):
 | 
				
			||||||
    return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].rstrip('\r\n')
 | 
					    return str(subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]).rstrip('\r\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def git_hash():
 | 
					def git_hash():
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
| 
						 | 
					@ -764,7 +764,7 @@ class Component:
 | 
				
			||||||
        out.write('\n')
 | 
					        out.write('\n')
 | 
				
			||||||
        mk_dir(os.path.join(BUILD_DIR, self.build_dir))
 | 
					        mk_dir(os.path.join(BUILD_DIR, self.build_dir))
 | 
				
			||||||
        if VS_PAR and IS_WINDOWS:
 | 
					        if VS_PAR and IS_WINDOWS:
 | 
				
			||||||
            cppfiles = get_cpp_files(self.src_dir)
 | 
					            cppfiles = list(get_cpp_files(self.src_dir))
 | 
				
			||||||
            dependencies = set()
 | 
					            dependencies = set()
 | 
				
			||||||
            for cppfile in cppfiles:
 | 
					            for cppfile in cppfiles:
 | 
				
			||||||
                dependencies.add(os.path.join(self.to_src_dir, cppfile))
 | 
					                dependencies.add(os.path.join(self.to_src_dir, cppfile))
 | 
				
			||||||
| 
						 | 
					@ -810,6 +810,9 @@ class Component:
 | 
				
			||||||
    def require_mem_initializer(self):
 | 
					    def require_mem_initializer(self):
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mk_install_deps(self, out):
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def mk_install(self, out):
 | 
					    def mk_install(self, out):
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -853,6 +856,9 @@ class LibComponent(Component):
 | 
				
			||||||
        out.write('\n')
 | 
					        out.write('\n')
 | 
				
			||||||
        out.write('%s: %s\n\n' % (self.name, libfile))
 | 
					        out.write('%s: %s\n\n' % (self.name, libfile))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mk_install_dep(self, out):
 | 
				
			||||||
 | 
					        out.write('%s' % libfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def mk_install(self, out):
 | 
					    def mk_install(self, out):
 | 
				
			||||||
        for include in self.includes2install:
 | 
					        for include in self.includes2install:
 | 
				
			||||||
            out.write('\t@cp %s %s\n' % (os.path.join(self.to_src_dir, include), os.path.join('$(PREFIX)', 'include', include)))
 | 
					            out.write('\t@cp %s %s\n' % (os.path.join(self.to_src_dir, include), os.path.join('$(PREFIX)', 'include', include)))
 | 
				
			||||||
| 
						 | 
					@ -935,6 +941,9 @@ class ExeComponent(Component):
 | 
				
			||||||
    def main_component(self):
 | 
					    def main_component(self):
 | 
				
			||||||
        return self.install
 | 
					        return self.install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mk_install_dep(self, out):
 | 
				
			||||||
 | 
					        out.write('%s' % exefile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def mk_install(self, out):
 | 
					    def mk_install(self, out):
 | 
				
			||||||
        if self.install:
 | 
					        if self.install:
 | 
				
			||||||
            exefile = '%s$(EXE_EXT)' % self.exe_name
 | 
					            exefile = '%s$(EXE_EXT)' % self.exe_name
 | 
				
			||||||
| 
						 | 
					@ -1076,6 +1085,11 @@ class DLLComponent(Component):
 | 
				
			||||||
    def require_def_file(self):
 | 
					    def require_def_file(self):
 | 
				
			||||||
        return IS_WINDOWS and self.export_files
 | 
					        return IS_WINDOWS and self.export_files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mk_install_dep(self, out):
 | 
				
			||||||
 | 
					        out.write('%s$(SO_EXT)' % self.dll_name)
 | 
				
			||||||
 | 
					        if self.static:
 | 
				
			||||||
 | 
					            out.write(' %s$(LIB_EXT)' % self.dll_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def mk_install(self, out):
 | 
					    def mk_install(self, out):
 | 
				
			||||||
        if self.install:
 | 
					        if self.install:
 | 
				
			||||||
            dllfile = '%s$(SO_EXT)' % self.dll_name
 | 
					            dllfile = '%s$(SO_EXT)' % self.dll_name
 | 
				
			||||||
| 
						 | 
					@ -1611,7 +1625,11 @@ def mk_config():
 | 
				
			||||||
                print('Java Compiler:  %s' % JAVAC)
 | 
					                print('Java Compiler:  %s' % JAVAC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mk_install(out):
 | 
					def mk_install(out):
 | 
				
			||||||
    out.write('install:\n')
 | 
					    out.write('install: ')
 | 
				
			||||||
 | 
					    for c in get_components():
 | 
				
			||||||
 | 
					        c.mk_install_deps(out)
 | 
				
			||||||
 | 
					        out.write(' ')
 | 
				
			||||||
 | 
					    out.write('\n')
 | 
				
			||||||
    out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'bin'))
 | 
					    out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'bin'))
 | 
				
			||||||
    out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'include'))
 | 
					    out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'include'))
 | 
				
			||||||
    out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'lib'))
 | 
					    out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'lib'))
 | 
				
			||||||
| 
						 | 
					@ -2573,16 +2591,17 @@ def mk_vs_proj(name, components):
 | 
				
			||||||
def mk_win_dist(build_path, dist_path):
 | 
					def mk_win_dist(build_path, dist_path):
 | 
				
			||||||
    for c in get_components():
 | 
					    for c in get_components():
 | 
				
			||||||
        c.mk_win_dist(build_path, dist_path)
 | 
					        c.mk_win_dist(build_path, dist_path)
 | 
				
			||||||
    # Add Z3Py to lib directory
 | 
					    # Add Z3Py to bin directory
 | 
				
			||||||
    for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(build_path)):
 | 
					    print("Adding to %s\n" % dist_path)
 | 
				
			||||||
 | 
					    for pyc in filter(lambda f: f.endswith('.pyc') or f.endswith('.py'), os.listdir(build_path)):
 | 
				
			||||||
        shutil.copy(os.path.join(build_path, pyc),
 | 
					        shutil.copy(os.path.join(build_path, pyc),
 | 
				
			||||||
                    os.path.join(dist_path, 'bin', pyc))
 | 
					                    os.path.join(dist_path, 'bin', pyc))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mk_unix_dist(build_path, dist_path):
 | 
					def mk_unix_dist(build_path, dist_path):
 | 
				
			||||||
    for c in get_components():
 | 
					    for c in get_components():
 | 
				
			||||||
        c.mk_unix_dist(build_path, dist_path)
 | 
					        c.mk_unix_dist(build_path, dist_path)
 | 
				
			||||||
    # Add Z3Py to lib directory
 | 
					    # Add Z3Py to bin directory
 | 
				
			||||||
    for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(build_path)):
 | 
					    for pyc in filter(lambda f: f.endswith('.pyc') or f.endswith('.py'), os.listdir(build_path)):
 | 
				
			||||||
        shutil.copy(os.path.join(build_path, pyc),
 | 
					        shutil.copy(os.path.join(build_path, pyc),
 | 
				
			||||||
                    os.path.join(dist_path, 'bin', pyc))
 | 
					                    os.path.join(dist_path, 'bin', pyc))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -269,6 +269,14 @@ namespace Microsoft.Z3
 | 
				
			||||||
                             AST.ArrayLength(queries), AST.ArrayToNative(queries));
 | 
					                             AST.ArrayLength(queries), AST.ArrayToNative(queries));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BoolExpr[] ToBoolExprs(ASTVector v) {
 | 
				
			||||||
 | 
					            uint n = v.Size;
 | 
				
			||||||
 | 
					            BoolExpr[] res = new BoolExpr[n];
 | 
				
			||||||
 | 
					            for (uint i = 0; i < n; i++)
 | 
				
			||||||
 | 
					                res[i] = new BoolExpr(Context, v[i].NativeObject);
 | 
				
			||||||
 | 
					            return res;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Retrieve set of rules added to fixedpoint context.
 | 
					        /// Retrieve set of rules added to fixedpoint context.
 | 
				
			||||||
        /// </summary>                
 | 
					        /// </summary>                
 | 
				
			||||||
| 
						 | 
					@ -278,12 +286,7 @@ namespace Microsoft.Z3
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
 | 
					                Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                ASTVector v = new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject));
 | 
					                return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject)));
 | 
				
			||||||
                uint n = v.Size;
 | 
					 | 
				
			||||||
                BoolExpr[] res = new BoolExpr[n];
 | 
					 | 
				
			||||||
                for (uint i = 0; i < n; i++)
 | 
					 | 
				
			||||||
                    res[i] = new BoolExpr(Context, v[i].NativeObject);
 | 
					 | 
				
			||||||
                return res;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,15 +299,27 @@ namespace Microsoft.Z3
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
 | 
					                Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                ASTVector v = new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject));
 | 
					                return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject)));
 | 
				
			||||||
                uint n = v.Size;
 | 
					 | 
				
			||||||
                BoolExpr[] res = new BoolExpr[n];
 | 
					 | 
				
			||||||
                for (uint i = 0; i < n; i++)
 | 
					 | 
				
			||||||
                    res[i] = new BoolExpr(Context, v[i].NativeObject);
 | 
					 | 
				
			||||||
                return res;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Parse an SMT-LIB2 file with fixedpoint rules. 
 | 
				
			||||||
 | 
					        /// Add the rules to the current fixedpoint context. 
 | 
				
			||||||
 | 
					        /// Return the set of queries in the file.
 | 
				
			||||||
 | 
					        /// </summary>                
 | 
				
			||||||
 | 
						public BoolExpr[] ParseFile(string file) {
 | 
				
			||||||
 | 
					            return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Similar to ParseFile. Instead it takes as argument a string.
 | 
				
			||||||
 | 
					        /// </summary>                
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public BoolExpr[] ParseString(string s) {
 | 
				
			||||||
 | 
					            return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_string(Context.nCtx, NativeObject, s)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region Internal
 | 
					        #region Internal
 | 
				
			||||||
        internal Fixedpoint(Context ctx, IntPtr obj)
 | 
					        internal Fixedpoint(Context ctx, IntPtr obj)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -899,6 +899,7 @@ def _coerce_expr_merge(s, a):
 | 
				
			||||||
            return s
 | 
					            return s
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            if __debug__:
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                _z3_assert(s1.ctx == s.ctx, "context mismatch")
 | 
				
			||||||
                _z3_assert(False, "sort mismatch")
 | 
					                _z3_assert(False, "sort mismatch")
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return s
 | 
					        return s
 | 
				
			||||||
| 
						 | 
					@ -1459,9 +1460,18 @@ def And(*args):
 | 
				
			||||||
    >>> And(P)
 | 
					    >>> And(P)
 | 
				
			||||||
    And(p__0, p__1, p__2, p__3, p__4)
 | 
					    And(p__0, p__1, p__2, p__3, p__4)
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					    last_arg = None
 | 
				
			||||||
 | 
					    if len(args) > 0:
 | 
				
			||||||
 | 
					        last_arg = args[len(args)-1]
 | 
				
			||||||
 | 
					    if isinstance(last_arg, Context):
 | 
				
			||||||
 | 
					        ctx = args[len(args)-1]
 | 
				
			||||||
 | 
					        args = args[:len(args)-1]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        ctx = main_ctx()
 | 
				
			||||||
    args = _get_args(args)
 | 
					    args = _get_args(args)
 | 
				
			||||||
    ctx   = _ctx_from_ast_arg_list(args)
 | 
					    ctx_args  = _ctx_from_ast_arg_list(args, ctx)
 | 
				
			||||||
    if __debug__:
 | 
					    if __debug__:
 | 
				
			||||||
 | 
					        _z3_assert(ctx_args == None or ctx_args == ctx, "context mismatch")
 | 
				
			||||||
        _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
 | 
					        _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
 | 
				
			||||||
    if _has_probe(args):
 | 
					    if _has_probe(args):
 | 
				
			||||||
        return _probe_and(args, ctx)
 | 
					        return _probe_and(args, ctx)
 | 
				
			||||||
| 
						 | 
					@ -1480,9 +1490,18 @@ def Or(*args):
 | 
				
			||||||
    >>> Or(P)
 | 
					    >>> Or(P)
 | 
				
			||||||
    Or(p__0, p__1, p__2, p__3, p__4)
 | 
					    Or(p__0, p__1, p__2, p__3, p__4)
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					    last_arg = None
 | 
				
			||||||
 | 
					    if len(args) > 0:
 | 
				
			||||||
 | 
					        last_arg = args[len(args)-1]
 | 
				
			||||||
 | 
					    if isinstance(last_arg, Context):
 | 
				
			||||||
 | 
					        ctx = args[len(args)-1]
 | 
				
			||||||
 | 
					        args = args[:len(args)-1]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        ctx = main_ctx()
 | 
				
			||||||
    args = _get_args(args)
 | 
					    args = _get_args(args)
 | 
				
			||||||
    ctx   = _ctx_from_ast_arg_list(args)
 | 
					    ctx_args  = _ctx_from_ast_arg_list(args, ctx)
 | 
				
			||||||
    if __debug__:
 | 
					    if __debug__:
 | 
				
			||||||
 | 
					        _z3_assert(ctx_args == None or ctx_args == ctx, "context mismatch")
 | 
				
			||||||
        _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
 | 
					        _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
 | 
				
			||||||
    if _has_probe(args):
 | 
					    if _has_probe(args):
 | 
				
			||||||
        return _probe_or(args, ctx)
 | 
					        return _probe_or(args, ctx)
 | 
				
			||||||
| 
						 | 
					@ -4128,6 +4147,7 @@ class Datatype:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if __debug__:
 | 
					        if __debug__:
 | 
				
			||||||
            _z3_assert(isinstance(name, str), "String expected")
 | 
					            _z3_assert(isinstance(name, str), "String expected")
 | 
				
			||||||
 | 
					            _z3_assert(name != "", "Constructor name cannot be empty")
 | 
				
			||||||
        return self.declare_core(name, "is_" + name, *args)
 | 
					        return self.declare_core(name, "is_" + name, *args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5668,7 +5668,8 @@ END_MLAPI_EXCLUDE
 | 
				
			||||||
       Each conjunct encodes values of the bound variables of the query that are satisfied.
 | 
					       Each conjunct encodes values of the bound variables of the query that are satisfied.
 | 
				
			||||||
       In PDR mode, the returned answer is a single conjunction.
 | 
					       In PDR mode, the returned answer is a single conjunction.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
       The previous call to Z3_fixedpoint_query must have returned Z3_L_TRUE.
 | 
					       When used in Datalog mode the previous call to Z3_fixedpoint_query must have returned Z3_L_TRUE.
 | 
				
			||||||
 | 
					       When used with the PDR engine, the previous call must have been either Z3_L_TRUE or Z3_L_FALSE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
       def_API('Z3_fixedpoint_get_answer', AST, (_in(CONTEXT), _in(FIXEDPOINT)))
 | 
					       def_API('Z3_fixedpoint_get_answer', AST, (_in(CONTEXT), _in(FIXEDPOINT)))
 | 
				
			||||||
    */    
 | 
					    */    
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -569,8 +569,8 @@ class smt_printer {
 | 
				
			||||||
            m_out << ")";
 | 
					            m_out << ")";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (m_is_smt2 && q->get_num_patterns() > 0) {
 | 
					        if (m_is_smt2 && (q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) {
 | 
				
			||||||
            m_out << "(!";
 | 
					            m_out << "(! ";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, false, m_is_smt2, m_simplify_implies, m_indent, m_num_var_names, m_var_names);        
 | 
					            smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, false, m_is_smt2, m_simplify_implies, m_indent, m_num_var_names, m_var_names);        
 | 
				
			||||||
| 
						 | 
					@ -609,7 +609,11 @@ class smt_printer {
 | 
				
			||||||
                m_out << "}";
 | 
					                m_out << "}";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (m_is_smt2 && q->get_num_patterns() > 0) {
 | 
					
 | 
				
			||||||
 | 
					        if (q->get_qid() != symbol::null)
 | 
				
			||||||
 | 
					            m_out << " :qid " << q->get_qid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (m_is_smt2 && (q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) {
 | 
				
			||||||
            m_out << ")";
 | 
					            m_out << ")";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        m_out << ")";
 | 
					        m_out << ")";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -601,6 +601,22 @@ namespace datalog {
 | 
				
			||||||
                result = mk_compare(OP_DL_LT, m_lt_sym, domain);
 | 
					                result = mk_compare(OP_DL_LT, m_lt_sym, domain);
 | 
				
			||||||
                break;   
 | 
					                break;   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case OP_DL_REP: {
 | 
				
			||||||
 | 
					                if (!check_domain(0, 0, num_parameters) ||
 | 
				
			||||||
 | 
					                    !check_domain(1, 1, arity)) return 0;
 | 
				
			||||||
 | 
					                func_decl_info info(m_family_id, k, 0, 0);
 | 
				
			||||||
 | 
					                result = m_manager->mk_func_decl(symbol("rep"), 1, domain, range, info);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            case OP_DL_ABS: {
 | 
				
			||||||
 | 
					                if (!check_domain(0, 0, num_parameters) ||
 | 
				
			||||||
 | 
					                    !check_domain(1, 1, arity)) return 0;
 | 
				
			||||||
 | 
					                func_decl_info info(m_family_id, k, 0, 0);
 | 
				
			||||||
 | 
					                result = m_manager->mk_func_decl(symbol("abs"), 1, domain, range, info);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                m_manager->raise_exception("operator not recognized");
 | 
					                m_manager->raise_exception("operator not recognized");
 | 
				
			||||||
                return 0;
 | 
					                return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,8 @@ namespace datalog {
 | 
				
			||||||
        OP_RA_CLONE,
 | 
					        OP_RA_CLONE,
 | 
				
			||||||
        OP_DL_CONSTANT,
 | 
					        OP_DL_CONSTANT,
 | 
				
			||||||
        OP_DL_LT,
 | 
					        OP_DL_LT,
 | 
				
			||||||
 | 
					        OP_DL_REP,
 | 
				
			||||||
 | 
					        OP_DL_ABS,
 | 
				
			||||||
        LAST_RA_OP
 | 
					        LAST_RA_OP
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,7 +106,7 @@ bool float_decl_plugin::is_value(expr * n, mpf & val) {
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool float_decl_plugin::is_rm(expr * n, mpf_rounding_mode & val) {
 | 
					bool float_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) {
 | 
				
			||||||
    if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_AWAY)) {
 | 
					    if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_AWAY)) {
 | 
				
			||||||
        val = MPF_ROUND_NEAREST_TAWAY;
 | 
					        val = MPF_ROUND_NEAREST_TAWAY;
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,7 +169,8 @@ public:
 | 
				
			||||||
    app * mk_value(mpf const & v);
 | 
					    app * mk_value(mpf const & v);
 | 
				
			||||||
    bool is_value(expr * n) { return is_app_of(n, m_family_id, OP_FLOAT_VALUE); }
 | 
					    bool is_value(expr * n) { return is_app_of(n, m_family_id, OP_FLOAT_VALUE); }
 | 
				
			||||||
    bool is_value(expr * n, mpf & val);
 | 
					    bool is_value(expr * n, mpf & val);
 | 
				
			||||||
    bool is_rm(expr * n, mpf_rounding_mode & val);
 | 
					    bool is_rm_value(expr * n, mpf_rounding_mode & val);
 | 
				
			||||||
 | 
					    bool is_rm_value(expr * n) { mpf_rounding_mode t; return is_rm_value(n, t); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mpf const & get_value(unsigned id) const { 
 | 
					    mpf const & get_value(unsigned id) const { 
 | 
				
			||||||
        SASSERT(m_value_table.contains(id));
 | 
					        SASSERT(m_value_table.contains(id));
 | 
				
			||||||
| 
						 | 
					@ -199,6 +200,8 @@ public:
 | 
				
			||||||
    sort * mk_rm_sort() { return m().mk_sort(m_fid, ROUNDING_MODE_SORT); }
 | 
					    sort * mk_rm_sort() { return m().mk_sort(m_fid, ROUNDING_MODE_SORT); }
 | 
				
			||||||
    bool is_float(sort * s) { return is_sort_of(s, m_fid, FLOAT_SORT); }
 | 
					    bool is_float(sort * s) { return is_sort_of(s, m_fid, FLOAT_SORT); }
 | 
				
			||||||
    bool is_rm(sort * s) { return is_sort_of(s, m_fid, ROUNDING_MODE_SORT); }
 | 
					    bool is_rm(sort * s) { return is_sort_of(s, m_fid, ROUNDING_MODE_SORT); }
 | 
				
			||||||
 | 
					    bool is_float(expr * e) { return is_float(m_manager.get_sort(e)); }
 | 
				
			||||||
 | 
					    bool is_rm(expr * e) { return is_rm(m_manager.get_sort(e)); }
 | 
				
			||||||
    unsigned get_ebits(sort * s);
 | 
					    unsigned get_ebits(sort * s);
 | 
				
			||||||
    unsigned get_sbits(sort * s);
 | 
					    unsigned get_sbits(sort * s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -218,7 +221,7 @@ public:
 | 
				
			||||||
    app * mk_value(mpf const & v) { return m_plugin->mk_value(v); }
 | 
					    app * mk_value(mpf const & v) { return m_plugin->mk_value(v); }
 | 
				
			||||||
    bool is_value(expr * n) { return m_plugin->is_value(n); }
 | 
					    bool is_value(expr * n) { return m_plugin->is_value(n); }
 | 
				
			||||||
    bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); }     
 | 
					    bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); }     
 | 
				
			||||||
    bool is_rm(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm(n, v); }
 | 
					    bool is_rm_value(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm_value(n, v); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    app * mk_pzero(unsigned ebits, unsigned sbits);
 | 
					    app * mk_pzero(unsigned ebits, unsigned sbits);
 | 
				
			||||||
    app * mk_nzero(unsigned ebits, unsigned sbits);
 | 
					    app * mk_nzero(unsigned ebits, unsigned sbits);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,9 +28,10 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) :
 | 
				
			||||||
    m(m),
 | 
					    m(m),
 | 
				
			||||||
    m_simp(m),
 | 
					    m_simp(m),
 | 
				
			||||||
    m_util(m),
 | 
					    m_util(m),
 | 
				
			||||||
 | 
					    m_bv_util(m),
 | 
				
			||||||
 | 
					    m_arith_util(m),
 | 
				
			||||||
    m_mpf_manager(m_util.fm()),
 | 
					    m_mpf_manager(m_util.fm()),
 | 
				
			||||||
    m_mpz_manager(m_mpf_manager.mpz_manager()),    
 | 
					    m_mpz_manager(m_mpf_manager.mpz_manager()),    
 | 
				
			||||||
    m_bv_util(m),
 | 
					 | 
				
			||||||
    extra_assertions(m) {
 | 
					    extra_assertions(m) {
 | 
				
			||||||
    m_plugin = static_cast<float_decl_plugin*>(m.get_plugin(m.mk_family_id("float")));
 | 
					    m_plugin = static_cast<float_decl_plugin*>(m.get_plugin(m.mk_family_id("float")));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -268,7 +269,7 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) {
 | 
				
			||||||
        result = r;
 | 
					        result = r;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        SASSERT(is_rm_sort(f->get_range()));
 | 
					        SASSERT(is_rm(f->get_range()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = m.mk_fresh_const(
 | 
					        result = m.mk_fresh_const(
 | 
				
			||||||
            #ifdef Z3DEBUG
 | 
					            #ifdef Z3DEBUG
 | 
				
			||||||
| 
						 | 
					@ -281,6 +282,10 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) {
 | 
				
			||||||
        m_rm_const2bv.insert(f, result);
 | 
					        m_rm_const2bv.insert(f, result);
 | 
				
			||||||
        m.inc_ref(f);
 | 
					        m.inc_ref(f);
 | 
				
			||||||
        m.inc_ref(result);
 | 
					        m.inc_ref(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expr_ref rcc(m);
 | 
				
			||||||
 | 
					        rcc = bu().mk_ule(result, bu().mk_numeral(4, 3));
 | 
				
			||||||
 | 
					        extra_assertions.push_back(rcc);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1847,6 +1852,55 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
 | 
				
			||||||
        // Just keep it here, as there will be something else that uses it.
 | 
					        // Just keep it here, as there will be something else that uses it.
 | 
				
			||||||
        mk_triple(args[0], args[1], args[2], result);
 | 
					        mk_triple(args[0], args[1], args[2], result);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else if (num == 3 &&
 | 
				
			||||||
 | 
					             m_bv_util.is_bv(args[0]) &&
 | 
				
			||||||
 | 
					             m_arith_util.is_numeral(args[1]) &&
 | 
				
			||||||
 | 
					             m_arith_util.is_numeral(args[2]))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Three arguments, some of them are not numerals.
 | 
				
			||||||
 | 
					        SASSERT(m_util.is_float(f->get_range()));
 | 
				
			||||||
 | 
					        unsigned ebits = m_util.get_ebits(f->get_range());
 | 
				
			||||||
 | 
					        unsigned sbits = m_util.get_sbits(f->get_range());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expr * rm = args[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rational q;
 | 
				
			||||||
 | 
					        if (!m_arith_util.is_numeral(args[1], q))
 | 
				
			||||||
 | 
					            NOT_IMPLEMENTED_YET();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rational e;
 | 
				
			||||||
 | 
					        if (!m_arith_util.is_numeral(args[2], e))
 | 
				
			||||||
 | 
					            NOT_IMPLEMENTED_YET();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SASSERT(e.is_int64());
 | 
				
			||||||
 | 
					        SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mpf nte, nta, tp, tn, tz;
 | 
				
			||||||
 | 
					        m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator());
 | 
				
			||||||
 | 
					        m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator());
 | 
				
			||||||
 | 
					        m_mpf_manager.set(tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq(), e.to_mpq().numerator());
 | 
				
			||||||
 | 
					        m_mpf_manager.set(tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq(), e.to_mpq().numerator());
 | 
				
			||||||
 | 
					        m_mpf_manager.set(tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq(), e.to_mpq().numerator());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        app_ref a_nte(m), a_nta(m), a_tp(m), a_tn(m), a_tz(m);
 | 
				
			||||||
 | 
					        a_nte = m_plugin->mk_value(nte);
 | 
				
			||||||
 | 
					        a_nta = m_plugin->mk_value(nta);
 | 
				
			||||||
 | 
					        a_tp = m_plugin->mk_value(tp);
 | 
				
			||||||
 | 
					        a_tn = m_plugin->mk_value(tn);
 | 
				
			||||||
 | 
					        a_tz = m_plugin->mk_value(tz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expr_ref bv_nte(m), bv_nta(m), bv_tp(m), bv_tn(m), bv_tz(m);
 | 
				
			||||||
 | 
					        mk_value(a_nte->get_decl(), 0, 0, bv_nte);
 | 
				
			||||||
 | 
					        mk_value(a_nta->get_decl(), 0, 0, bv_nta);
 | 
				
			||||||
 | 
					        mk_value(a_tp->get_decl(), 0, 0, bv_tp);
 | 
				
			||||||
 | 
					        mk_value(a_tn->get_decl(), 0, 0, bv_tn);
 | 
				
			||||||
 | 
					        mk_value(a_tz->get_decl(), 0, 0, bv_tz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)), bv_tn, bv_tz, result);
 | 
				
			||||||
 | 
					        mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)), bv_tp, result, result);
 | 
				
			||||||
 | 
					        mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3)), bv_nta, result, result);
 | 
				
			||||||
 | 
					        mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)), bv_nte, result, result);        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    else if (num == 1 && m_bv_util.is_bv(args[0])) {
 | 
					    else if (num == 1 && m_bv_util.is_bv(args[0])) {
 | 
				
			||||||
        sort * s = f->get_range();
 | 
					        sort * s = f->get_range();
 | 
				
			||||||
        unsigned to_sbits = m_util.get_sbits(s);
 | 
					        unsigned to_sbits = m_util.get_sbits(s);
 | 
				
			||||||
| 
						 | 
					@ -1862,7 +1916,9 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
 | 
				
			||||||
                  m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv),
 | 
					                  m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv),
 | 
				
			||||||
                  result);
 | 
					                  result);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (num == 2 && is_app(args[1]) && m_util.is_float(m.get_sort(args[1]))) {        
 | 
					    else if (num == 2 && 
 | 
				
			||||||
 | 
					             is_app(args[1]) && 
 | 
				
			||||||
 | 
					             m_util.is_float(m.get_sort(args[1]))) {        
 | 
				
			||||||
        // We also support float to float conversion
 | 
					        // We also support float to float conversion
 | 
				
			||||||
        sort * s = f->get_range();
 | 
					        sort * s = f->get_range();
 | 
				
			||||||
        expr_ref rm(m), x(m); 
 | 
					        expr_ref rm(m), x(m); 
 | 
				
			||||||
| 
						 | 
					@ -2016,9 +2072,10 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
 | 
				
			||||||
            mk_ite(c1, v1, result, result);
 | 
					            mk_ite(c1, v1, result, result);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }    
 | 
					    }    
 | 
				
			||||||
    else {
 | 
					    else if (num == 2 &&              
 | 
				
			||||||
 | 
					             m_util.is_rm(args[0]),
 | 
				
			||||||
 | 
					             m_arith_util.is_real(args[1])) {
 | 
				
			||||||
        // .. other than that, we only support rationals for asFloat
 | 
					        // .. other than that, we only support rationals for asFloat
 | 
				
			||||||
        SASSERT(num == 2);
 | 
					 | 
				
			||||||
        SASSERT(m_util.is_float(f->get_range()));        
 | 
					        SASSERT(m_util.is_float(f->get_range()));        
 | 
				
			||||||
        unsigned ebits = m_util.get_ebits(f->get_range());
 | 
					        unsigned ebits = m_util.get_ebits(f->get_range());
 | 
				
			||||||
        unsigned sbits = m_util.get_sbits(f->get_range());
 | 
					        unsigned sbits = m_util.get_sbits(f->get_range());
 | 
				
			||||||
| 
						 | 
					@ -2028,10 +2085,10 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
 | 
				
			||||||
        m_bv_util.is_numeral(to_expr(args[0]), tmp_rat, sz);
 | 
					        m_bv_util.is_numeral(to_expr(args[0]), tmp_rat, sz);
 | 
				
			||||||
        SASSERT(tmp_rat.is_int32());
 | 
					        SASSERT(tmp_rat.is_int32());
 | 
				
			||||||
        SASSERT(sz == 3);
 | 
					        SASSERT(sz == 3);
 | 
				
			||||||
        BV_RM_VAL bv_rm = (BV_RM_VAL) tmp_rat.get_unsigned();
 | 
					        BV_RM_VAL bv_rm = (BV_RM_VAL)tmp_rat.get_unsigned();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mpf_rounding_mode rm;
 | 
					        mpf_rounding_mode rm;
 | 
				
			||||||
        switch(bv_rm)
 | 
					        switch (bv_rm)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        case BV_RM_TIES_TO_AWAY: rm = MPF_ROUND_NEAREST_TAWAY; break;
 | 
					        case BV_RM_TIES_TO_AWAY: rm = MPF_ROUND_NEAREST_TAWAY; break;
 | 
				
			||||||
        case BV_RM_TIES_TO_EVEN: rm = MPF_ROUND_NEAREST_TEVEN; break;
 | 
					        case BV_RM_TIES_TO_EVEN: rm = MPF_ROUND_NEAREST_TEVEN; break;
 | 
				
			||||||
| 
						 | 
					@ -2044,20 +2101,21 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
 | 
				
			||||||
        SASSERT(m_util.au().is_numeral(args[1]));
 | 
					        SASSERT(m_util.au().is_numeral(args[1]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        rational q;
 | 
					        rational q;
 | 
				
			||||||
        SASSERT(m_util.au().is_numeral(args[1]));
 | 
					 | 
				
			||||||
        m_util.au().is_numeral(args[1], q);
 | 
					        m_util.au().is_numeral(args[1], q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mpf v;
 | 
					        mpf v;
 | 
				
			||||||
        m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
 | 
					        m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expr * sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1);
 | 
					        expr * sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1);
 | 
				
			||||||
        expr * s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits-1);
 | 
					        expr * s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1);
 | 
				
			||||||
        expr * e = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits);
 | 
					        expr * e = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mk_triple(sgn, s, e, result);
 | 
					        mk_triple(sgn, s, e, result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        m_util.fm().del(v);
 | 
					        m_util.fm().del(v);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        UNREACHABLE();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SASSERT(is_well_sorted(m, result));    
 | 
					    SASSERT(is_well_sorted(m, result));    
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,9 +45,10 @@ class fpa2bv_converter {
 | 
				
			||||||
    ast_manager              & m;
 | 
					    ast_manager              & m;
 | 
				
			||||||
    basic_simplifier_plugin    m_simp;
 | 
					    basic_simplifier_plugin    m_simp;
 | 
				
			||||||
    float_util                 m_util;
 | 
					    float_util                 m_util;
 | 
				
			||||||
 | 
					    bv_util                    m_bv_util;
 | 
				
			||||||
 | 
					    arith_util                 m_arith_util;
 | 
				
			||||||
    mpf_manager              & m_mpf_manager;
 | 
					    mpf_manager              & m_mpf_manager;
 | 
				
			||||||
    unsynch_mpz_manager      & m_mpz_manager;    
 | 
					    unsynch_mpz_manager      & m_mpz_manager;    
 | 
				
			||||||
    bv_util                    m_bv_util;    
 | 
					 | 
				
			||||||
    float_decl_plugin        * m_plugin;
 | 
					    float_decl_plugin        * m_plugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    obj_map<func_decl, expr*>  m_const2bv;
 | 
					    obj_map<func_decl, expr*>  m_const2bv;
 | 
				
			||||||
| 
						 | 
					@ -64,8 +65,9 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool is_float(sort * s) { return m_util.is_float(s); }
 | 
					    bool is_float(sort * s) { return m_util.is_float(s); }
 | 
				
			||||||
    bool is_float(expr * e) { return is_app(e) && m_util.is_float(to_app(e)->get_decl()->get_range()); }
 | 
					    bool is_float(expr * e) { return is_app(e) && m_util.is_float(to_app(e)->get_decl()->get_range()); }
 | 
				
			||||||
 | 
					    bool is_rm(expr * e) { return m_util.is_rm(e); }
 | 
				
			||||||
 | 
					    bool is_rm(sort * s) { return m_util.is_rm(s); }
 | 
				
			||||||
    bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); }
 | 
					    bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); }
 | 
				
			||||||
    bool is_rm_sort(sort * s) { return m_util.is_rm(s); }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void mk_triple(expr * sign, expr * significand, expr * exponent, expr_ref & result) {
 | 
					    void mk_triple(expr * sign, expr * significand, expr * exponent, expr_ref & result) {
 | 
				
			||||||
        SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1);
 | 
					        SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,17 +78,23 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
 | 
				
			||||||
            return BR_DONE;
 | 
					            return BR_DONE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm_sort(f->get_range())) {
 | 
					        if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm(f->get_range())) {
 | 
				
			||||||
            m_conv.mk_rm_const(f, result);
 | 
					            m_conv.mk_rm_const(f, result);
 | 
				
			||||||
            return BR_DONE;
 | 
					            return BR_DONE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (m().is_eq(f)) {
 | 
					        if (m().is_eq(f)) {
 | 
				
			||||||
            SASSERT(num == 2);
 | 
					            SASSERT(num == 2);
 | 
				
			||||||
            if (m_conv.is_float(args[0])) {
 | 
					            SASSERT(m().get_sort(args[0]) == m().get_sort(args[1]));
 | 
				
			||||||
 | 
					            sort * ds = f->get_domain()[0];
 | 
				
			||||||
 | 
					            if (m_conv.is_float(ds)) {
 | 
				
			||||||
                m_conv.mk_eq(args[0], args[1], result);
 | 
					                m_conv.mk_eq(args[0], args[1], result);
 | 
				
			||||||
                return BR_DONE;
 | 
					                return BR_DONE;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            else if (m_conv.is_rm(ds)) {
 | 
				
			||||||
 | 
					                result = m().mk_eq(args[0], args[1]);
 | 
				
			||||||
 | 
					                return BR_DONE;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return BR_FAILED;
 | 
					            return BR_FAILED;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ void quasi_macros::find_occurrences(expr * e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // we remember whether we have seen an expr once, or more than once;
 | 
					    // we remember whether we have seen an expr once, or more than once;
 | 
				
			||||||
    // when we see it the second time, we don't have to visit it another time,
 | 
					    // when we see it the second time, we don't have to visit it another time,
 | 
				
			||||||
    // as we are only intersted in finding unique function applications. 
 | 
					    // as we are only interested in finding unique function applications. 
 | 
				
			||||||
    m_visited_once.reset();
 | 
					    m_visited_once.reset();
 | 
				
			||||||
    m_visited_more.reset();
 | 
					    m_visited_more.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ void quasi_macros::find_occurrences(expr * e) {
 | 
				
			||||||
            case AST_VAR: break;
 | 
					            case AST_VAR: break;
 | 
				
			||||||
            case AST_QUANTIFIER: m_todo.push_back(to_quantifier(cur)->get_expr()); break;
 | 
					            case AST_QUANTIFIER: m_todo.push_back(to_quantifier(cur)->get_expr()); break;
 | 
				
			||||||
            case AST_APP:
 | 
					            case AST_APP:
 | 
				
			||||||
                if (is_uninterp(cur) && !is_ground(cur)) {
 | 
					                if (is_non_ground_uninterp(cur)) {
 | 
				
			||||||
                    func_decl * f = to_app(cur)->get_decl();
 | 
					                    func_decl * f = to_app(cur)->get_decl();
 | 
				
			||||||
                    m_occurrences.insert_if_not_there(f, 0);
 | 
					                    m_occurrences.insert_if_not_there(f, 0);
 | 
				
			||||||
                    occurrences_map::iterator it = m_occurrences.find_iterator(f);                    
 | 
					                    occurrences_map::iterator it = m_occurrences.find_iterator(f);                    
 | 
				
			||||||
| 
						 | 
					@ -76,6 +76,10 @@ void quasi_macros::find_occurrences(expr * e) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool quasi_macros::is_non_ground_uninterp(expr const * e) const {
 | 
				
			||||||
 | 
					    return is_non_ground(e) && is_uninterp(e);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool quasi_macros::is_unique(func_decl * f) const {
 | 
					bool quasi_macros::is_unique(func_decl * f) const {
 | 
				
			||||||
    return m_occurrences.find(f) == 1;
 | 
					    return m_occurrences.find(f) == 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -149,6 +153,7 @@ bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const {
 | 
				
			||||||
    // Our definition of a quasi-macro:
 | 
					    // Our definition of a quasi-macro:
 | 
				
			||||||
    // Forall X. f[X] = T[X], where f[X] is a term starting with symbol f, f is uninterpreted, 
 | 
					    // Forall X. f[X] = T[X], where f[X] is a term starting with symbol f, f is uninterpreted, 
 | 
				
			||||||
    // f[X] contains all universally quantified variables, and f does not occur in T[X].
 | 
					    // f[X] contains all universally quantified variables, and f does not occur in T[X].
 | 
				
			||||||
 | 
					    TRACE("quasi_macros", tout << "Checking for quasi macro: " << mk_pp(e, m_manager) << std::endl;);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (is_quantifier(e) && to_quantifier(e)->is_forall()) {
 | 
					    if (is_quantifier(e) && to_quantifier(e)->is_forall()) {
 | 
				
			||||||
        quantifier * q = to_quantifier(e);
 | 
					        quantifier * q = to_quantifier(e);
 | 
				
			||||||
| 
						 | 
					@ -157,23 +162,23 @@ bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const {
 | 
				
			||||||
            expr * lhs = to_app(qe)->get_arg(0);
 | 
					            expr * lhs = to_app(qe)->get_arg(0);
 | 
				
			||||||
            expr * rhs = to_app(qe)->get_arg(1);
 | 
					            expr * rhs = to_app(qe)->get_arg(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (is_uninterp(lhs) && is_unique(to_app(lhs)->get_decl()) && 
 | 
					            if (is_non_ground_uninterp(lhs) && is_unique(to_app(lhs)->get_decl()) &&
 | 
				
			||||||
                !depends_on(rhs, to_app(lhs)->get_decl()) && fully_depends_on(to_app(lhs), q)) {
 | 
					                !depends_on(rhs, to_app(lhs)->get_decl()) && fully_depends_on(to_app(lhs), q)) {
 | 
				
			||||||
                a = to_app(lhs);
 | 
					                a = to_app(lhs);
 | 
				
			||||||
                t = rhs;                
 | 
					                t = rhs;                
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            } else if (is_uninterp(rhs) && is_unique(to_app(rhs)->get_decl()) && 
 | 
					            } else if (is_non_ground_uninterp(rhs) && is_unique(to_app(rhs)->get_decl()) &&
 | 
				
			||||||
                !depends_on(lhs, to_app(rhs)->get_decl()) && fully_depends_on(to_app(rhs), q)) {                
 | 
					                !depends_on(lhs, to_app(rhs)->get_decl()) && fully_depends_on(to_app(rhs), q)) {                
 | 
				
			||||||
                a = to_app(rhs);
 | 
					                a = to_app(rhs);
 | 
				
			||||||
                t = lhs;                
 | 
					                t = lhs;                
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }            
 | 
					            }            
 | 
				
			||||||
        } else if (m_manager.is_not(qe) && is_uninterp(to_app(qe)->get_arg(0)) &&
 | 
					        } else if (m_manager.is_not(qe) && is_non_ground_uninterp(to_app(qe)->get_arg(0)) &&
 | 
				
			||||||
                   is_unique(to_app(to_app(qe)->get_arg(0))->get_decl())) { // this is like f(...) = false
 | 
					                   is_unique(to_app(to_app(qe)->get_arg(0))->get_decl())) { // this is like f(...) = false
 | 
				
			||||||
            a = to_app(to_app(qe)->get_arg(0));
 | 
					            a = to_app(to_app(qe)->get_arg(0));
 | 
				
			||||||
            t = m_manager.mk_false();
 | 
					            t = m_manager.mk_false();
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } else if (is_uninterp(qe) && is_unique(to_app(qe)->get_decl())) { // this is like f(...) = true
 | 
					        } else if (is_non_ground_uninterp(qe) && is_unique(to_app(qe)->get_decl())) { // this is like f(...) = true
 | 
				
			||||||
            a = to_app(qe);
 | 
					            a = to_app(qe);
 | 
				
			||||||
            t = m_manager.mk_true();
 | 
					            t = m_manager.mk_true();
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@ class quasi_macros {
 | 
				
			||||||
    expr_mark                 m_visited_more;
 | 
					    expr_mark                 m_visited_more;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    bool is_unique(func_decl * f) const;
 | 
					    bool is_unique(func_decl * f) const;
 | 
				
			||||||
 | 
					    bool is_non_ground_uninterp(expr const * e) const;
 | 
				
			||||||
    bool fully_depends_on(app * a, quantifier * q) const;    
 | 
					    bool fully_depends_on(app * a, quantifier * q) const;    
 | 
				
			||||||
    bool depends_on(expr * e, func_decl * f) const;
 | 
					    bool depends_on(expr * e, func_decl * f) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -323,6 +323,9 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
 | 
					    br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
 | 
				
			||||||
        result_pr = 0;
 | 
					        result_pr = 0;
 | 
				
			||||||
 | 
					        TRACE("bit_blaster", tout << f->get_name() << " ";
 | 
				
			||||||
 | 
					              for (unsigned i = 0; i < num; ++i) tout << mk_pp(args[i], m()) << " ";
 | 
				
			||||||
 | 
					              tout << "\n";);
 | 
				
			||||||
        if (num == 0 && f->get_family_id() == null_family_id && butil().is_bv_sort(f->get_range())) {
 | 
					        if (num == 0 && f->get_family_id() == null_family_id && butil().is_bv_sort(f->get_range())) {
 | 
				
			||||||
            mk_const(f, result);
 | 
					            mk_const(f, result);
 | 
				
			||||||
            return BR_DONE;
 | 
					            return BR_DONE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -828,6 +828,12 @@ void bit_blaster_tpl<Cfg>::mk_eq(unsigned sz, expr * const * a_bits, expr * cons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename Cfg>
 | 
					template<typename Cfg>
 | 
				
			||||||
void bit_blaster_tpl<Cfg>::mk_rotate_left(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits) {
 | 
					void bit_blaster_tpl<Cfg>::mk_rotate_left(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits) {
 | 
				
			||||||
 | 
					    TRACE("bit_blaster", tout << n << ": " << sz << " ";
 | 
				
			||||||
 | 
					          for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
 | 
					              tout << mk_pp(a_bits[i], m()) << " ";
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          tout << "\n";
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
    n = n % sz;
 | 
					    n = n % sz;
 | 
				
			||||||
    for (unsigned i = sz - n; i < sz; i++) 
 | 
					    for (unsigned i = sz - n; i < sz; i++) 
 | 
				
			||||||
        out_bits.push_back(a_bits[i]);
 | 
					        out_bits.push_back(a_bits[i]);
 | 
				
			||||||
| 
						 | 
					@ -974,7 +980,7 @@ void bit_blaster_tpl<Cfg>::mk_ashr(unsigned sz, expr * const * a_bits, expr * co
 | 
				
			||||||
                mk_ite(eqs.get(i - j), a_bits[sz - j - 1], out, new_out);
 | 
					                mk_ite(eqs.get(i - j), a_bits[sz - j - 1], out, new_out);
 | 
				
			||||||
                out = new_out;
 | 
					                out = new_out;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TRACE("bit_blaster_tpl<Cfg>", tout << (sz - i - 1) << " :\n" << mk_pp(out, m()) << "\n";);
 | 
					            TRACE("bit_blaster", tout << (sz - i - 1) << " :\n" << mk_pp(out, m()) << "\n";);
 | 
				
			||||||
            out_bits.set(sz - i - 1, out);
 | 
					            out_bits.set(sz - i - 1, out);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1004,7 +1010,7 @@ void bit_blaster_tpl<Cfg>::mk_ext_rotate_left_right(unsigned sz, expr * const *
 | 
				
			||||||
            out = a_bits[i];
 | 
					            out = a_bits[i];
 | 
				
			||||||
            for (unsigned j = 1; j < sz; j++) {
 | 
					            for (unsigned j = 1; j < sz; j++) {
 | 
				
			||||||
                expr_ref new_out(m());
 | 
					                expr_ref new_out(m());
 | 
				
			||||||
                unsigned src = (Left ? (i - j) : (i + j)) % sz;
 | 
					                unsigned src = (Left ? (sz + i - j) : (i + j)) % sz;
 | 
				
			||||||
                mk_ite(eqs.get(j), a_bits[src], out, new_out);
 | 
					                mk_ite(eqs.get(j), a_bits[src], out, new_out);
 | 
				
			||||||
                out = new_out;
 | 
					                out = new_out;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@ Notes:
 | 
				
			||||||
#include"poly_rewriter_def.h"
 | 
					#include"poly_rewriter_def.h"
 | 
				
			||||||
#include"ast_smt2_pp.h"
 | 
					#include"ast_smt2_pp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mk_extract_proc::mk_extract_proc(bv_util & u):
 | 
					mk_extract_proc::mk_extract_proc(bv_util & u):
 | 
				
			||||||
    m_util(u),
 | 
					    m_util(u),
 | 
				
			||||||
    m_high(0),
 | 
					    m_high(0),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,7 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (num_args == 2) {
 | 
					    if (num_args == 2) {
 | 
				
			||||||
        mpf_rounding_mode rm;
 | 
					        mpf_rounding_mode rm;
 | 
				
			||||||
        if (!m_util.is_rm(args[0], rm))
 | 
					        if (!m_util.is_rm_value(args[0], rm))
 | 
				
			||||||
            return BR_FAILED;
 | 
					            return BR_FAILED;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        rational q;
 | 
					        rational q;
 | 
				
			||||||
| 
						 | 
					@ -109,12 +109,12 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
 | 
				
			||||||
            return BR_FAILED;
 | 
					            return BR_FAILED;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (num_args == 3 && 
 | 
					    else if (num_args == 3 && 
 | 
				
			||||||
             m_util.is_rm(m().get_sort(args[0])) && 
 | 
					             m_util.is_rm(args[0]) && 
 | 
				
			||||||
             m_util.au().is_real(args[1]) &&
 | 
					             m_util.au().is_real(args[1]) &&
 | 
				
			||||||
             m_util.au().is_int(args[2])) {
 | 
					             m_util.au().is_int(args[2])) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mpf_rounding_mode rm;
 | 
					        mpf_rounding_mode rm;
 | 
				
			||||||
        if (!m_util.is_rm(args[0], rm))
 | 
					        if (!m_util.is_rm_value(args[0], rm))
 | 
				
			||||||
            return BR_FAILED;
 | 
					            return BR_FAILED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        rational q;
 | 
					        rational q;
 | 
				
			||||||
| 
						 | 
					@ -130,7 +130,6 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
 | 
				
			||||||
	    m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator());
 | 
						    m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator());
 | 
				
			||||||
        result = m_util.mk_value(v);
 | 
					        result = m_util.mk_value(v);
 | 
				
			||||||
        m_util.fm().del(v);
 | 
					        m_util.fm().del(v);
 | 
				
			||||||
        // TRACE("fp_rewriter", tout << "result: " << result << std::endl; );
 | 
					 | 
				
			||||||
        return BR_DONE;
 | 
					        return BR_DONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
| 
						 | 
					@ -140,7 +139,7 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {    
 | 
					br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {    
 | 
				
			||||||
    mpf_rounding_mode rm;
 | 
					    mpf_rounding_mode rm;
 | 
				
			||||||
    if (m_util.is_rm(arg1, rm)) {
 | 
					    if (m_util.is_rm_value(arg1, rm)) {
 | 
				
			||||||
        scoped_mpf v2(m_util.fm()), v3(m_util.fm());
 | 
					        scoped_mpf v2(m_util.fm()), v3(m_util.fm());
 | 
				
			||||||
        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
 | 
					        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
 | 
				
			||||||
            scoped_mpf t(m_util.fm());
 | 
					            scoped_mpf t(m_util.fm());
 | 
				
			||||||
| 
						 | 
					@ -161,7 +160,7 @@ br_status float_rewriter::mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {    
 | 
					br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {    
 | 
				
			||||||
    mpf_rounding_mode rm;
 | 
					    mpf_rounding_mode rm;
 | 
				
			||||||
    if (m_util.is_rm(arg1, rm)) {
 | 
					    if (m_util.is_rm_value(arg1, rm)) {
 | 
				
			||||||
        scoped_mpf v2(m_util.fm()), v3(m_util.fm());
 | 
					        scoped_mpf v2(m_util.fm()), v3(m_util.fm());
 | 
				
			||||||
        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
 | 
					        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
 | 
				
			||||||
            scoped_mpf t(m_util.fm());
 | 
					            scoped_mpf t(m_util.fm());
 | 
				
			||||||
| 
						 | 
					@ -176,7 +175,7 @@ br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
br_status float_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {
 | 
					br_status float_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {
 | 
				
			||||||
    mpf_rounding_mode rm;
 | 
					    mpf_rounding_mode rm;
 | 
				
			||||||
    if (m_util.is_rm(arg1, rm)) {
 | 
					    if (m_util.is_rm_value(arg1, rm)) {
 | 
				
			||||||
        scoped_mpf v2(m_util.fm()), v3(m_util.fm());
 | 
					        scoped_mpf v2(m_util.fm()), v3(m_util.fm());
 | 
				
			||||||
        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
 | 
					        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
 | 
				
			||||||
            scoped_mpf t(m_util.fm());
 | 
					            scoped_mpf t(m_util.fm());
 | 
				
			||||||
| 
						 | 
					@ -287,7 +286,7 @@ br_status float_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
br_status float_rewriter::mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) {
 | 
					br_status float_rewriter::mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) {
 | 
				
			||||||
    mpf_rounding_mode rm;
 | 
					    mpf_rounding_mode rm;
 | 
				
			||||||
    if (m_util.is_rm(arg1, rm)) {
 | 
					    if (m_util.is_rm_value(arg1, rm)) {
 | 
				
			||||||
        scoped_mpf v2(m_util.fm()), v3(m_util.fm()), v4(m_util.fm());
 | 
					        scoped_mpf v2(m_util.fm()), v3(m_util.fm()), v4(m_util.fm());
 | 
				
			||||||
        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3) && m_util.is_value(arg4, v4)) {
 | 
					        if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3) && m_util.is_value(arg4, v4)) {
 | 
				
			||||||
            scoped_mpf t(m_util.fm());
 | 
					            scoped_mpf t(m_util.fm());
 | 
				
			||||||
| 
						 | 
					@ -302,7 +301,7 @@ br_status float_rewriter::mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, exp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) {
 | 
					br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) {
 | 
				
			||||||
    mpf_rounding_mode rm;
 | 
					    mpf_rounding_mode rm;
 | 
				
			||||||
    if (m_util.is_rm(arg1, rm)) {
 | 
					    if (m_util.is_rm_value(arg1, rm)) {
 | 
				
			||||||
        scoped_mpf v2(m_util.fm());
 | 
					        scoped_mpf v2(m_util.fm());
 | 
				
			||||||
        if (m_util.is_value(arg2, v2)) {
 | 
					        if (m_util.is_value(arg2, v2)) {
 | 
				
			||||||
            scoped_mpf t(m_util.fm());
 | 
					            scoped_mpf t(m_util.fm());
 | 
				
			||||||
| 
						 | 
					@ -317,7 +316,7 @@ br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
br_status float_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) {
 | 
					br_status float_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) {
 | 
				
			||||||
    mpf_rounding_mode rm;
 | 
					    mpf_rounding_mode rm;
 | 
				
			||||||
    if (m_util.is_rm(arg1, rm)) {
 | 
					    if (m_util.is_rm_value(arg1, rm)) {
 | 
				
			||||||
        scoped_mpf v2(m_util.fm());
 | 
					        scoped_mpf v2(m_util.fm());
 | 
				
			||||||
        if (m_util.is_value(arg2, v2)) {
 | 
					        if (m_util.is_value(arg2, v2)) {
 | 
				
			||||||
            scoped_mpf t(m_util.fm());
 | 
					            scoped_mpf t(m_util.fm());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,6 +547,9 @@ public:
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STRINGIZE(x) #x
 | 
				
			||||||
 | 
					#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class get_info_cmd : public cmd {
 | 
					class get_info_cmd : public cmd {
 | 
				
			||||||
    symbol   m_error_behavior;
 | 
					    symbol   m_error_behavior;
 | 
				
			||||||
    symbol   m_name;
 | 
					    symbol   m_name;
 | 
				
			||||||
| 
						 | 
					@ -584,7 +587,11 @@ public:
 | 
				
			||||||
            ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl;
 | 
					            ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (opt == m_version) {
 | 
					        else if (opt == m_version) {
 | 
				
			||||||
            ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER << "\")" << std::endl;
 | 
					            ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER
 | 
				
			||||||
 | 
					#ifdef Z3GITHASH
 | 
				
			||||||
 | 
					                << " - build hashcode " << STRINGIZE_VALUE_OF(Z3GITHASH)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					                << "\")" << std::endl;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (opt == m_status) {
 | 
					        else if (opt == m_status) {
 | 
				
			||||||
            ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl;
 | 
					            ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -978,13 +978,14 @@ namespace datalog {
 | 
				
			||||||
        }        
 | 
					        }        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void rule::get_vars(ptr_vector<sort>& sorts) const {
 | 
					    void rule::get_vars(ast_manager& m, ptr_vector<sort>& sorts) const {
 | 
				
			||||||
        sorts.reset();
 | 
					        sorts.reset();
 | 
				
			||||||
        used_vars used;
 | 
					        used_vars used;
 | 
				
			||||||
        get_used_vars(used);
 | 
					        get_used_vars(used);
 | 
				
			||||||
        unsigned sz = used.get_max_found_var_idx_plus_1();
 | 
					        unsigned sz = used.get_max_found_var_idx_plus_1();
 | 
				
			||||||
        for (unsigned i = 0; i < sz; ++i) {
 | 
					        for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
            sorts.push_back(used.get(i));
 | 
					            sort* s = used.get(i);
 | 
				
			||||||
 | 
					            sorts.push_back(s?s:m.mk_bool_sort());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -304,7 +304,7 @@ namespace datalog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void norm_vars(rule_manager & rm);
 | 
					        void norm_vars(rule_manager & rm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void get_vars(ptr_vector<sort>& sorts) const;
 | 
					        void get_vars(ast_manager& m, ptr_vector<sort>& sorts) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void to_formula(expr_ref& result) const;
 | 
					        void to_formula(expr_ref& result) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -290,7 +290,7 @@ namespace datalog {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TRACE("dl_dr", 
 | 
					            TRACE("dl_dr", 
 | 
				
			||||||
                  tout << r.get_decl()->get_name() << "\n";
 | 
					                  tout << mk_pp(r.get_head(), m) << " :- \n";
 | 
				
			||||||
                  for (unsigned i = 0; i < body.size(); ++i) {
 | 
					                  for (unsigned i = 0; i < body.size(); ++i) {
 | 
				
			||||||
                      tout << mk_pp(body[i].get(), m) << "\n";
 | 
					                      tout << mk_pp(body[i].get(), m) << "\n";
 | 
				
			||||||
                  });
 | 
					                  });
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,7 +148,7 @@ namespace datalog {
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        void mk_qrule_vars(datalog::rule const& r, unsigned rule_id, expr_ref_vector& sub) {
 | 
					        void mk_qrule_vars(datalog::rule const& r, unsigned rule_id, expr_ref_vector& sub) {
 | 
				
			||||||
            ptr_vector<sort> sorts;
 | 
					            ptr_vector<sort> sorts;
 | 
				
			||||||
            r.get_vars(sorts);
 | 
					            r.get_vars(m, sorts);
 | 
				
			||||||
            // populate substitution of bound variables.
 | 
					            // populate substitution of bound variables.
 | 
				
			||||||
            sub.reset();
 | 
					            sub.reset();
 | 
				
			||||||
            sub.resize(sorts.size());
 | 
					            sub.resize(sorts.size());
 | 
				
			||||||
| 
						 | 
					@ -421,7 +421,7 @@ namespace datalog {
 | 
				
			||||||
                    ptr_vector<sort> rule_vars;
 | 
					                    ptr_vector<sort> rule_vars;
 | 
				
			||||||
                    expr_ref_vector args(m), conjs(m);
 | 
					                    expr_ref_vector args(m), conjs(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    r.get_vars(rule_vars);
 | 
					                    r.get_vars(m, rule_vars);
 | 
				
			||||||
                    obj_hashtable<expr> used_vars;
 | 
					                    obj_hashtable<expr> used_vars;
 | 
				
			||||||
                    unsigned num_vars = 0;
 | 
					                    unsigned num_vars = 0;
 | 
				
			||||||
                    for (unsigned i = 0; i < r.get_decl()->get_arity(); ++i) {
 | 
					                    for (unsigned i = 0; i < r.get_decl()->get_arity(); ++i) {
 | 
				
			||||||
| 
						 | 
					@ -514,7 +514,7 @@ namespace datalog {
 | 
				
			||||||
            unsigned sz = r->get_uninterpreted_tail_size();
 | 
					            unsigned sz = r->get_uninterpreted_tail_size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ptr_vector<sort> rule_vars;
 | 
					            ptr_vector<sort> rule_vars;
 | 
				
			||||||
            r->get_vars(rule_vars);
 | 
					            r->get_vars(m, rule_vars);
 | 
				
			||||||
            args.append(prop->get_num_args(), prop->get_args());
 | 
					            args.append(prop->get_num_args(), prop->get_args());
 | 
				
			||||||
            expr_ref_vector sub = mk_skolem_binding(*r, rule_vars, args);
 | 
					            expr_ref_vector sub = mk_skolem_binding(*r, rule_vars, args);
 | 
				
			||||||
            if (sub.empty() && sz == 0) {
 | 
					            if (sub.empty() && sz == 0) {
 | 
				
			||||||
| 
						 | 
					@ -803,7 +803,7 @@ namespace datalog {
 | 
				
			||||||
            func_decl* p = r.get_decl();
 | 
					            func_decl* p = r.get_decl();
 | 
				
			||||||
            ptr_vector<func_decl> const& succs  = *dtu.get_datatype_constructors(m.get_sort(path));
 | 
					            ptr_vector<func_decl> const& succs  = *dtu.get_datatype_constructors(m.get_sort(path));
 | 
				
			||||||
            // populate substitution of bound variables.
 | 
					            // populate substitution of bound variables.
 | 
				
			||||||
            r.get_vars(sorts);
 | 
					            r.get_vars(m, sorts);
 | 
				
			||||||
            sub.reset();
 | 
					            sub.reset();
 | 
				
			||||||
            sub.resize(sorts.size());
 | 
					            sub.resize(sorts.size());
 | 
				
			||||||
            for (unsigned k = 0; k < r.get_decl()->get_arity(); ++k) {
 | 
					            for (unsigned k = 0; k < r.get_decl()->get_arity(); ++k) {
 | 
				
			||||||
| 
						 | 
					@ -1327,7 +1327,7 @@ namespace datalog {
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        void mk_rule_vars(rule& r, unsigned level, unsigned rule_id, expr_ref_vector& sub) {
 | 
					        void mk_rule_vars(rule& r, unsigned level, unsigned rule_id, expr_ref_vector& sub) {
 | 
				
			||||||
            ptr_vector<sort> sorts;
 | 
					            ptr_vector<sort> sorts;
 | 
				
			||||||
            r.get_vars(sorts);
 | 
					            r.get_vars(m, sorts);
 | 
				
			||||||
            // populate substitution of bound variables.
 | 
					            // populate substitution of bound variables.
 | 
				
			||||||
            sub.reset();
 | 
					            sub.reset();
 | 
				
			||||||
            sub.resize(sorts.size());
 | 
					            sub.resize(sorts.size());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ namespace datalog {
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            if (m_next_var == 0) {
 | 
					            if (m_next_var == 0) {
 | 
				
			||||||
                ptr_vector<sort> vars;
 | 
					                ptr_vector<sort> vars;
 | 
				
			||||||
                r.get_vars(vars);
 | 
					                r.get_vars(m, vars);
 | 
				
			||||||
                m_next_var = vars.size() + 1;
 | 
					                m_next_var = vars.size() + 1;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            v = m.mk_var(m_next_var, m.get_sort(e));
 | 
					            v = m.mk_var(m_next_var, m.get_sort(e));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,7 @@ Revision History:
 | 
				
			||||||
#include "dl_mk_interp_tail_simplifier.h"
 | 
					#include "dl_mk_interp_tail_simplifier.h"
 | 
				
			||||||
#include "fixedpoint_params.hpp"
 | 
					#include "fixedpoint_params.hpp"
 | 
				
			||||||
#include "scoped_proof.h"
 | 
					#include "scoped_proof.h"
 | 
				
			||||||
 | 
					#include "model_v2_pp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace datalog {
 | 
					namespace datalog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,11 +68,17 @@ namespace datalog {
 | 
				
			||||||
                func_decl* p = m_new_funcs[i].get();
 | 
					                func_decl* p = m_new_funcs[i].get();
 | 
				
			||||||
                func_decl* q = m_old_funcs[i].get();
 | 
					                func_decl* q = m_old_funcs[i].get();
 | 
				
			||||||
                func_interp* f = model->get_func_interp(p);
 | 
					                func_interp* f = model->get_func_interp(p);
 | 
				
			||||||
 | 
					                if (!f) continue;
 | 
				
			||||||
                expr_ref body(m);                
 | 
					                expr_ref body(m);                
 | 
				
			||||||
                unsigned arity_p = p->get_arity();
 | 
					                unsigned arity_p = p->get_arity();
 | 
				
			||||||
                unsigned arity_q = q->get_arity();
 | 
					                unsigned arity_q = q->get_arity();
 | 
				
			||||||
 | 
					                TRACE("dl",
 | 
				
			||||||
 | 
					                      model_v2_pp(tout, *model);
 | 
				
			||||||
 | 
					                      tout << mk_pp(p, m) << "\n";
 | 
				
			||||||
 | 
					                      tout << mk_pp(q, m) << "\n";);
 | 
				
			||||||
                SASSERT(0 < arity_p);
 | 
					                SASSERT(0 < arity_p);
 | 
				
			||||||
                model->register_decl(p, f);
 | 
					                SASSERT(f);
 | 
				
			||||||
 | 
					                model->register_decl(p, f->copy());
 | 
				
			||||||
                func_interp* g = alloc(func_interp, m, arity_q);
 | 
					                func_interp* g = alloc(func_interp, m, arity_q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (f) {
 | 
					                if (f) {
 | 
				
			||||||
| 
						 | 
					@ -88,11 +95,12 @@ namespace datalog {
 | 
				
			||||||
                for (unsigned j = 0; j < arity_q; ++j) {
 | 
					                for (unsigned j = 0; j < arity_q; ++j) {
 | 
				
			||||||
                    sort* s = q->get_domain(j);
 | 
					                    sort* s = q->get_domain(j);
 | 
				
			||||||
                    arg = m.mk_var(j, s);
 | 
					                    arg = m.mk_var(j, s);
 | 
				
			||||||
 | 
					                    expr* t = arg;
 | 
				
			||||||
                    if (m_bv.is_bv_sort(s)) {
 | 
					                    if (m_bv.is_bv_sort(s)) {
 | 
				
			||||||
                        expr* args[1] = { arg };
 | 
					 | 
				
			||||||
                        unsigned sz = m_bv.get_bv_size(s);
 | 
					                        unsigned sz = m_bv.get_bv_size(s);
 | 
				
			||||||
                        for (unsigned k = 0; k < sz; ++k) {
 | 
					                        for (unsigned k = 0; k < sz; ++k) {
 | 
				
			||||||
                            proj = m.mk_app(m_bv.get_family_id(), OP_BIT2BOOL, 1, args);
 | 
					                            parameter p(k);
 | 
				
			||||||
 | 
					                            proj = m.mk_app(m_bv.get_family_id(), OP_BIT2BOOL, 1, &p, 1, &t);
 | 
				
			||||||
                            sub.insert(m.mk_var(idx++, m.mk_bool_sort()), proj); 
 | 
					                            sub.insert(m.mk_var(idx++, m.mk_bool_sort()), proj); 
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ namespace datalog {
 | 
				
			||||||
        rule_ref r(const_cast<rule*>(&rl), rm);
 | 
					        rule_ref r(const_cast<rule*>(&rl), rm);
 | 
				
			||||||
        ptr_vector<sort> sorts;
 | 
					        ptr_vector<sort> sorts;
 | 
				
			||||||
        expr_ref_vector revsub(m), conjs(m);
 | 
					        expr_ref_vector revsub(m), conjs(m);
 | 
				
			||||||
        rl.get_vars(sorts);
 | 
					        rl.get_vars(m, sorts);
 | 
				
			||||||
        revsub.resize(sorts.size());  
 | 
					        revsub.resize(sorts.size());  
 | 
				
			||||||
        svector<bool> valid(sorts.size(), true);
 | 
					        svector<bool> valid(sorts.size(), true);
 | 
				
			||||||
        for (unsigned i = 0; i < sub.size(); ++i) {
 | 
					        for (unsigned i = 0; i < sub.size(); ++i) {
 | 
				
			||||||
| 
						 | 
					@ -117,8 +117,8 @@ namespace datalog {
 | 
				
			||||||
        rule_ref res(rm);
 | 
					        rule_ref res(rm);
 | 
				
			||||||
        bool_rewriter bwr(m);
 | 
					        bool_rewriter bwr(m);
 | 
				
			||||||
        svector<bool> is_neg;
 | 
					        svector<bool> is_neg;
 | 
				
			||||||
        tgt->get_vars(sorts1);
 | 
					        tgt->get_vars(m, sorts1);
 | 
				
			||||||
        src.get_vars(sorts2);
 | 
					        src.get_vars(m, sorts2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mk_pred(head, src.get_head(), tgt->get_head()); 
 | 
					        mk_pred(head, src.get_head(), tgt->get_head()); 
 | 
				
			||||||
        for (unsigned i = 0; i < src.get_uninterpreted_tail_size(); ++i) {
 | 
					        for (unsigned i = 0; i < src.get_uninterpreted_tail_size(); ++i) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,7 +205,6 @@ namespace datalog {
 | 
				
			||||||
                for (unsigned i = 0; i < rules.size(); ++i) {
 | 
					                for (unsigned i = 0; i < rules.size(); ++i) {
 | 
				
			||||||
                    app* head = rules[i]->get_head();
 | 
					                    app* head = rules[i]->get_head();
 | 
				
			||||||
                    expr_ref_vector conj(m);
 | 
					                    expr_ref_vector conj(m);
 | 
				
			||||||
                    unsigned n = head->get_num_args()-1;
 | 
					 | 
				
			||||||
                    for (unsigned j = 0; j < head->get_num_args(); ++j) {
 | 
					                    for (unsigned j = 0; j < head->get_num_args(); ++j) {
 | 
				
			||||||
                        expr* arg = head->get_arg(j);
 | 
					                        expr* arg = head->get_arg(j);
 | 
				
			||||||
                        if (!is_var(arg)) {
 | 
					                        if (!is_var(arg)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,7 +199,7 @@ namespace datalog {
 | 
				
			||||||
        expr_ref fml(m), cnst(m);
 | 
					        expr_ref fml(m), cnst(m);
 | 
				
			||||||
        var_ref var(m);
 | 
					        var_ref var(m);
 | 
				
			||||||
        ptr_vector<sort> sorts;
 | 
					        ptr_vector<sort> sorts;
 | 
				
			||||||
        r.get_vars(sorts);
 | 
					        r.get_vars(m, sorts);
 | 
				
			||||||
        m_uf.reset();
 | 
					        m_uf.reset();
 | 
				
			||||||
        m_terms.reset();
 | 
					        m_terms.reset();
 | 
				
			||||||
        m_var2cnst.reset();
 | 
					        m_var2cnst.reset();
 | 
				
			||||||
| 
						 | 
					@ -207,9 +207,6 @@ namespace datalog {
 | 
				
			||||||
        fml = m.mk_and(conjs.size(), conjs.c_ptr());
 | 
					        fml = m.mk_and(conjs.size(), conjs.c_ptr());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (unsigned i = 0; i < sorts.size(); ++i) {
 | 
					        for (unsigned i = 0; i < sorts.size(); ++i) {
 | 
				
			||||||
            if (!sorts[i]) {
 | 
					 | 
				
			||||||
                sorts[i] = m.mk_bool_sort();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            var = m.mk_var(i, sorts[i]);
 | 
					            var = m.mk_var(i, sorts[i]);
 | 
				
			||||||
            cnst = m.mk_fresh_const("C", sorts[i]);
 | 
					            cnst = m.mk_fresh_const("C", sorts[i]);
 | 
				
			||||||
            m_var2cnst.insert(var, cnst);
 | 
					            m_var2cnst.insert(var, cnst);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,11 +143,8 @@ namespace datalog {
 | 
				
			||||||
        expr_ref_vector result(m);
 | 
					        expr_ref_vector result(m);
 | 
				
			||||||
        ptr_vector<sort> sorts;
 | 
					        ptr_vector<sort> sorts;
 | 
				
			||||||
        expr_ref v(m), w(m);
 | 
					        expr_ref v(m), w(m);
 | 
				
			||||||
        r.get_vars(sorts);
 | 
					        r.get_vars(m, sorts);
 | 
				
			||||||
        for (unsigned i = 0; i < sorts.size(); ++i) {
 | 
					        for (unsigned i = 0; i < sorts.size(); ++i) {
 | 
				
			||||||
            if (!sorts[i]) {
 | 
					 | 
				
			||||||
                sorts[i] = m.mk_bool_sort();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            v = m.mk_var(i, sorts[i]);
 | 
					            v = m.mk_var(i, sorts[i]);
 | 
				
			||||||
            m_subst.apply(2, m_deltas, expr_offset(v, is_tgt?0:1), w);
 | 
					            m_subst.apply(2, m_deltas, expr_offset(v, is_tgt?0:1), w);
 | 
				
			||||||
            result.push_back(w);            
 | 
					            result.push_back(w);            
 | 
				
			||||||
| 
						 | 
					@ -423,6 +420,11 @@ namespace datalog {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TRACE("dl", tout << "inlined rules after mutual inlining:\n" << m_inlined_rules;  );
 | 
					        TRACE("dl", tout << "inlined rules after mutual inlining:\n" << m_inlined_rules;  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < m_inlined_rules.get_num_rules(); ++i) {
 | 
				
			||||||
 | 
					            rule* r = m_inlined_rules.get_rule(i);
 | 
				
			||||||
 | 
					            datalog::del_rule(m_mc, *r);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool mk_rule_inliner::transform_rule(rule_set const& orig, rule * r0, rule_set& tgt) {
 | 
					    bool mk_rule_inliner::transform_rule(rule_set const& orig, rule * r0, rule_set& tgt) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,7 +141,7 @@ namespace datalog {
 | 
				
			||||||
            m_cache.reset();
 | 
					            m_cache.reset();
 | 
				
			||||||
            m_trail.reset();
 | 
					            m_trail.reset();
 | 
				
			||||||
            m_eqs.reset();
 | 
					            m_eqs.reset();
 | 
				
			||||||
            r.get_vars(vars);
 | 
					            r.get_vars(m, vars);
 | 
				
			||||||
            unsigned num_vars = vars.size();
 | 
					            unsigned num_vars = vars.size();
 | 
				
			||||||
            for (unsigned j = 0; j < utsz; ++j) {
 | 
					            for (unsigned j = 0; j < utsz; ++j) {
 | 
				
			||||||
                tail.push_back(mk_pred(num_vars, r.get_tail(j)));
 | 
					                tail.push_back(mk_pred(num_vars, r.get_tail(j)));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										109
									
								
								src/qe/qe.cpp
									
										
									
									
									
								
							
							
						
						
									
										109
									
								
								src/qe/qe.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -1120,6 +1120,7 @@ namespace qe {
 | 
				
			||||||
            st->init(fml);
 | 
					            st->init(fml);
 | 
				
			||||||
            st->m_vars.append(m_vars.size(), m_vars.c_ptr());
 | 
					            st->m_vars.append(m_vars.size(), m_vars.c_ptr());
 | 
				
			||||||
            SASSERT(invariant());
 | 
					            SASSERT(invariant());
 | 
				
			||||||
 | 
					            TRACE("qe", tout << mk_pp(m_fml, m) << " child: " << mk_pp(fml, m) << "\n";);
 | 
				
			||||||
            return st;
 | 
					            return st;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1133,6 +1134,7 @@ namespace qe {
 | 
				
			||||||
            m_branch_index.insert(branch_id, index);
 | 
					            m_branch_index.insert(branch_id, index);
 | 
				
			||||||
            st->m_vars.append(m_vars.size(), m_vars.c_ptr());
 | 
					            st->m_vars.append(m_vars.size(), m_vars.c_ptr());
 | 
				
			||||||
            SASSERT(invariant());
 | 
					            SASSERT(invariant());
 | 
				
			||||||
 | 
					            //TRACE("qe", tout << mk_pp(m_fml, m) << " child: " << mk_pp(st->fml(), m) << "\n";);
 | 
				
			||||||
            return st;
 | 
					            return st;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1164,6 +1166,16 @@ namespace qe {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expr_ref abstract_variable(app* x, expr* fml) const {
 | 
				
			||||||
 | 
					            expr_ref result(m);
 | 
				
			||||||
 | 
					            expr* y = x;
 | 
				
			||||||
 | 
					            expr_abstract(m, 0, 1, &y, fml, result);            
 | 
				
			||||||
 | 
					            symbol X(x->get_decl()->get_name());
 | 
				
			||||||
 | 
					            sort* s = m.get_sort(x);
 | 
				
			||||||
 | 
					            result = m.mk_exists(1, &s, &X, result);
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void display_validate(std::ostream& out) const {
 | 
					        void display_validate(std::ostream& out) const {
 | 
				
			||||||
            if (m_children.empty()) {
 | 
					            if (m_children.empty()) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
| 
						 | 
					@ -1171,25 +1183,53 @@ namespace qe {
 | 
				
			||||||
            expr_ref q(m);
 | 
					            expr_ref q(m);
 | 
				
			||||||
            expr* x = m_var;
 | 
					            expr* x = m_var;
 | 
				
			||||||
            if (x) {
 | 
					            if (x) {
 | 
				
			||||||
                expr_abstract(m, 0, 1, &x, m_fml, q);
 | 
					                q = abstract_variable(m_var, m_fml);
 | 
				
			||||||
                ptr_vector<expr> fmls;
 | 
					
 | 
				
			||||||
 | 
					                expr_ref_vector fmls(m);
 | 
				
			||||||
 | 
					                expr_ref fml(m);
 | 
				
			||||||
                for (unsigned i = 0; i < m_children.size(); ++i) {
 | 
					                for (unsigned i = 0; i < m_children.size(); ++i) {
 | 
				
			||||||
                    expr* fml = m_children[i]->fml();
 | 
					                    search_tree const& child = *m_children[i];
 | 
				
			||||||
 | 
					                    fml = child.fml();
 | 
				
			||||||
                    if (fml) {
 | 
					                    if (fml) {
 | 
				
			||||||
 | 
					                        // abstract free variables in children.
 | 
				
			||||||
 | 
					                        ptr_vector<app> child_vars, new_vars;
 | 
				
			||||||
 | 
					                        child_vars.append(child.m_vars.size(), child.m_vars.c_ptr());
 | 
				
			||||||
 | 
					                        if (child.m_var) {
 | 
				
			||||||
 | 
					                            child_vars.push_back(child.m_var);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        for (unsigned j = 0; j < child_vars.size(); ++j) {
 | 
				
			||||||
 | 
					                            if (!m_vars.contains(child_vars[j]) &&
 | 
				
			||||||
 | 
					                                !new_vars.contains(child_vars[j])) {
 | 
				
			||||||
 | 
					                                fml = abstract_variable(child_vars[j], fml);
 | 
				
			||||||
 | 
					                                new_vars.push_back(child_vars[j]);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                        fmls.push_back(fml);
 | 
					                        fmls.push_back(fml);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                symbol X(m_var->get_decl()->get_name());
 | 
					                bool_rewriter(m).mk_or(fmls.size(), fmls.c_ptr(), fml);
 | 
				
			||||||
                sort* s = m.get_sort(x);
 | 
					                
 | 
				
			||||||
                q = m.mk_exists(1, &s, &X, q);
 | 
					                fml = m.mk_not(m.mk_iff(q, fml));
 | 
				
			||||||
                expr_ref tmp(m);
 | 
					 | 
				
			||||||
                bool_rewriter(m).mk_or(fmls.size(), fmls.c_ptr(), tmp);
 | 
					 | 
				
			||||||
                expr_ref f(m.mk_not(m.mk_iff(q, tmp)), m);
 | 
					 | 
				
			||||||
                ast_smt_pp pp(m);
 | 
					                ast_smt_pp pp(m);
 | 
				
			||||||
                out << "(echo " << m_var->get_decl()->get_name() << ")\n";
 | 
					                out << "; eliminate " << mk_pp(m_var, m) << "\n";
 | 
				
			||||||
                out << "(push)\n";
 | 
					                out << "(push)\n";
 | 
				
			||||||
                pp.display_smt2(out, f);
 | 
					                pp.display_smt2(out, fml);                
 | 
				
			||||||
                out << "(pop)\n\n";      
 | 
					                out << "(pop)\n\n";      
 | 
				
			||||||
 | 
					                DEBUG_CODE(
 | 
				
			||||||
 | 
					                    smt_params params;
 | 
				
			||||||
 | 
					                    params.m_simplify_bit2int = true;
 | 
				
			||||||
 | 
					                    params.m_arith_enum_const_mod = true;
 | 
				
			||||||
 | 
					                    params.m_bv_enable_int2bv2int = true;
 | 
				
			||||||
 | 
					                    params.m_relevancy_lvl = 0;
 | 
				
			||||||
 | 
					                    smt::kernel ctx(m, params);
 | 
				
			||||||
 | 
					                    ctx.assert_expr(fml);
 | 
				
			||||||
 | 
					                    lbool is_sat = ctx.check();
 | 
				
			||||||
 | 
					                    if (is_sat == l_true) {
 | 
				
			||||||
 | 
					                        std::cout << "; Validation failed:\n";
 | 
				
			||||||
 | 
					                        std::cout << mk_pp(fml, m) << "\n";
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            for (unsigned i = 0; i < m_children.size(); ++i) {
 | 
					            for (unsigned i = 0; i < m_children.size(); ++i) {
 | 
				
			||||||
                if (m_children[i]->fml()) {
 | 
					                if (m_children[i]->fml()) {
 | 
				
			||||||
| 
						 | 
					@ -1410,13 +1450,9 @@ namespace qe {
 | 
				
			||||||
            m_solver.assert_expr(m_fml);
 | 
					            m_solver.assert_expr(m_fml);
 | 
				
			||||||
            if (assumption) m_solver.assert_expr(assumption);
 | 
					            if (assumption) m_solver.assert_expr(assumption);
 | 
				
			||||||
            bool is_sat = false;            
 | 
					            bool is_sat = false;            
 | 
				
			||||||
            while (l_false != m_solver.check()) {
 | 
					            while (l_true == m_solver.check()) {
 | 
				
			||||||
                is_sat = true;
 | 
					                is_sat = true;
 | 
				
			||||||
                model_ref model;
 | 
					                final_check();
 | 
				
			||||||
                m_solver.get_model(model);
 | 
					 | 
				
			||||||
                TRACE("qe", model_v2_pp(tout, *model););
 | 
					 | 
				
			||||||
                model_evaluator model_eval(*model);
 | 
					 | 
				
			||||||
                final_check(model_eval);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!is_sat) {
 | 
					            if (!is_sat) {
 | 
				
			||||||
| 
						 | 
					@ -1466,14 +1502,30 @@ namespace qe {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void final_check(model_evaluator& model_eval) {
 | 
					        void final_check() {
 | 
				
			||||||
            TRACE("qe", tout << "\n";);
 | 
					            model_ref model;
 | 
				
			||||||
            while (can_propagate_assignment(model_eval)) {
 | 
					            m_solver.get_model(model);
 | 
				
			||||||
                propagate_assignment(model_eval);
 | 
					            scoped_ptr<model_evaluator> model_eval = alloc(model_evaluator, *model);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while (true) {
 | 
				
			||||||
 | 
					                TRACE("qe", model_v2_pp(tout, *model););
 | 
				
			||||||
 | 
					                while (can_propagate_assignment(*model_eval)) {
 | 
				
			||||||
 | 
					                    propagate_assignment(*model_eval);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            VERIFY(CHOOSE_VAR == update_current(model_eval, true));
 | 
					                VERIFY(CHOOSE_VAR == update_current(*model_eval, true));
 | 
				
			||||||
                SASSERT(m_current->fml());
 | 
					                SASSERT(m_current->fml());
 | 
				
			||||||
            pop(model_eval);        
 | 
					                if (l_true != m_solver.check()) {
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                m_solver.get_model(model);
 | 
				
			||||||
 | 
					                model_eval = alloc(model_evaluator, *model);
 | 
				
			||||||
 | 
					                search_tree* st = m_current;
 | 
				
			||||||
 | 
					                update_current(*model_eval, false);
 | 
				
			||||||
 | 
					                if (st == m_current) {
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }            
 | 
				
			||||||
 | 
					            pop(*model_eval);                    
 | 
				
			||||||
        } 
 | 
					        } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ast_manager& get_manager() { return m; }
 | 
					        ast_manager& get_manager() { return m; }
 | 
				
			||||||
| 
						 | 
					@ -1633,6 +1685,7 @@ namespace qe {
 | 
				
			||||||
                nb = m_current->get_num_branches();
 | 
					                nb = m_current->get_num_branches();
 | 
				
			||||||
                expr_ref fml(m_current->fml(), m);
 | 
					                expr_ref fml(m_current->fml(), m);
 | 
				
			||||||
                if (!eval(model_eval, b, branch) || branch >= nb) {
 | 
					                if (!eval(model_eval, b, branch) || branch >= nb) {
 | 
				
			||||||
 | 
					                    TRACE("qe", tout << "evaluation failed: setting branch to 0\n";);
 | 
				
			||||||
                    branch = rational::zero();
 | 
					                    branch = rational::zero();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                SASSERT(!branch.is_neg());
 | 
					                SASSERT(!branch.is_neg());
 | 
				
			||||||
| 
						 | 
					@ -1694,11 +1747,12 @@ namespace qe {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //
 | 
					            //
 | 
				
			||||||
            // The current state is satisfiable
 | 
					            // The closed portion of the formula
 | 
				
			||||||
            // and the closed portion of the formula
 | 
					            // can be used as the quantifier-free portion, 
 | 
				
			||||||
            // can be used as the quantifier-free portion.
 | 
					            // unless the current state is unsatisfiable.
 | 
				
			||||||
            // 
 | 
					            // 
 | 
				
			||||||
            if (m.is_true(fml_mixed)) {
 | 
					            if (m.is_true(fml_mixed)) {
 | 
				
			||||||
 | 
					                SASSERT(l_true == m_solver.check());
 | 
				
			||||||
                m_current = m_current->add_child(fml_closed);
 | 
					                m_current = m_current->add_child(fml_closed);
 | 
				
			||||||
                for (unsigned i = 0; m_defs && i < m_current->num_free_vars(); ++i) {
 | 
					                for (unsigned i = 0; m_defs && i < m_current->num_free_vars(); ++i) {
 | 
				
			||||||
                    expr_ref val(m);
 | 
					                    expr_ref val(m);
 | 
				
			||||||
| 
						 | 
					@ -1708,6 +1762,7 @@ namespace qe {
 | 
				
			||||||
                    if (val == x) {
 | 
					                    if (val == x) {
 | 
				
			||||||
                        model_ref model;
 | 
					                        model_ref model;
 | 
				
			||||||
                        lbool is_sat = m_solver.check();
 | 
					                        lbool is_sat = m_solver.check();
 | 
				
			||||||
 | 
					                        if (is_sat == l_undef) return;
 | 
				
			||||||
                        m_solver.get_model(model);
 | 
					                        m_solver.get_model(model);
 | 
				
			||||||
                        SASSERT(is_sat == l_true);
 | 
					                        SASSERT(is_sat == l_true);
 | 
				
			||||||
                        model_evaluator model_eval2(*model);
 | 
					                        model_evaluator model_eval2(*model);
 | 
				
			||||||
| 
						 | 
					@ -1890,7 +1945,7 @@ namespace qe {
 | 
				
			||||||
                vars.reset();
 | 
					                vars.reset();
 | 
				
			||||||
                closed = closed && (r != l_undef);
 | 
					                closed = closed && (r != l_undef);
 | 
				
			||||||
            }        
 | 
					            }        
 | 
				
			||||||
            TRACE("qe", tout << mk_ismt2_pp(fml, m) << "\n";);
 | 
					            TRACE("qe", tout << mk_pp(fml, m) << "\n";);
 | 
				
			||||||
            m_current->add_child(fml)->reset_free_vars();
 | 
					            m_current->add_child(fml)->reset_free_vars();
 | 
				
			||||||
            block_assignment(); 
 | 
					            block_assignment(); 
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@ Revision History:
 | 
				
			||||||
#include "obj_pair_hashtable.h"
 | 
					#include "obj_pair_hashtable.h"
 | 
				
			||||||
#include "nlarith_util.h"
 | 
					#include "nlarith_util.h"
 | 
				
			||||||
#include "model_evaluator.h"
 | 
					#include "model_evaluator.h"
 | 
				
			||||||
 | 
					#include "smt_kernel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace qe {
 | 
					namespace qe {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,8 +82,8 @@ namespace qe {
 | 
				
			||||||
        i_solver_context& m_ctx;
 | 
					        i_solver_context& m_ctx;
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        arith_util        m_arith; // initialize before m_zero_i, etc.
 | 
					        arith_util        m_arith; // initialize before m_zero_i, etc.
 | 
				
			||||||
 | 
					        th_rewriter       simplify;
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        th_rewriter       m_rewriter;
 | 
					 | 
				
			||||||
        arith_eq_solver   m_arith_solver;
 | 
					        arith_eq_solver   m_arith_solver;
 | 
				
			||||||
        bv_util           m_bv;
 | 
					        bv_util           m_bv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,7 +103,7 @@ namespace qe {
 | 
				
			||||||
            m(m), 
 | 
					            m(m), 
 | 
				
			||||||
            m_ctx(ctx),
 | 
					            m_ctx(ctx),
 | 
				
			||||||
            m_arith(m),
 | 
					            m_arith(m),
 | 
				
			||||||
            m_rewriter(m),
 | 
					            simplify(m),
 | 
				
			||||||
            m_arith_solver(m),
 | 
					            m_arith_solver(m),
 | 
				
			||||||
            m_bv(m),
 | 
					            m_bv(m),
 | 
				
			||||||
            m_zero_i(m_arith.mk_numeral(numeral(0), true), m),
 | 
					            m_zero_i(m_arith.mk_numeral(numeral(0), true), m),
 | 
				
			||||||
| 
						 | 
					@ -434,7 +435,6 @@ namespace qe {
 | 
				
			||||||
            expr_ref tmp(e, m);
 | 
					            expr_ref tmp(e, m);
 | 
				
			||||||
            simplify(tmp);
 | 
					            simplify(tmp);
 | 
				
			||||||
            m_arith_rewriter.mk_le(tmp, mk_zero(e), result);
 | 
					            m_arith_rewriter.mk_le(tmp, mk_zero(e), result);
 | 
				
			||||||
            TRACE("qe_verbose", tout << "mk_le " << mk_pp(result, m) << "\n";);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void mk_lt(expr* e, expr_ref& result) {
 | 
					        void mk_lt(expr* e, expr_ref& result) {
 | 
				
			||||||
| 
						 | 
					@ -521,7 +521,8 @@ namespace qe {
 | 
				
			||||||
                expr_ref result1(m), result2(m);
 | 
					                expr_ref result1(m), result2(m);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // a*s + b*t <= 0
 | 
					                // a*s + b*t <= 0
 | 
				
			||||||
                expr_ref as_bt_le_0(result, m), tmp2(m), tmp3(m), tmp4(m);
 | 
					                expr_ref as_bt_le_0(result, m), tmp2(m), asz_bt_le_0(m), tmp3(m), tmp4(m);
 | 
				
			||||||
 | 
					                expr_ref b_divides_sz(m);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // a*s + b*t + (a-1)(b-1) <= 0
 | 
					                // a*s + b*t + (a-1)(b-1) <= 0
 | 
				
			||||||
                tmp2 = m_arith.mk_add(as_bt, slack);
 | 
					                tmp2 = m_arith.mk_add(as_bt, slack);
 | 
				
			||||||
| 
						 | 
					@ -560,30 +561,36 @@ namespace qe {
 | 
				
			||||||
                    sz = m_arith.mk_uminus(sz);
 | 
					                    sz = m_arith.mk_uminus(sz);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                tmp4 = mk_add(mk_mul(a1, sz), bt);
 | 
					                tmp4 = mk_add(mk_mul(a1, sz), bt);
 | 
				
			||||||
                mk_le(tmp4, tmp3);
 | 
					                mk_le(tmp4, asz_bt_le_0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (to_app(tmp3)->get_arg(0) == x &&
 | 
					                if (to_app(asz_bt_le_0)->get_arg(0) == x &&
 | 
				
			||||||
                    m_arith.is_zero(to_app(tmp3)->get_arg(1))) {
 | 
					                    m_arith.is_zero(to_app(asz_bt_le_0)->get_arg(1))) {
 | 
				
			||||||
                    //    exists z in [0 .. |b|-2] . |b| | (z + s) && z <= 0
 | 
					                    //    exists z in [0 .. |b|-2] . |b| | (z + s) && z <= 0
 | 
				
			||||||
                    // <=>
 | 
					                    // <=>
 | 
				
			||||||
                    //    |b| | s 
 | 
					                    //    |b| | s 
 | 
				
			||||||
                    mk_divides(abs_b, s, tmp2);
 | 
					                    mk_divides(abs_b, s, tmp2);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                    mk_divides(abs_b, sz, tmp2);
 | 
					                    mk_divides(abs_b, sz, b_divides_sz);
 | 
				
			||||||
                    mk_and(tmp2, tmp3, tmp4);
 | 
					                    mk_and(b_divides_sz, asz_bt_le_0, tmp4);
 | 
				
			||||||
                    mk_big_or(abs_b - numeral(2), x, tmp4, tmp2);                  
 | 
					                    mk_big_or(abs_b - numeral(2), x, tmp4, tmp2);                  
 | 
				
			||||||
                   
 | 
					                    TRACE("qe",
 | 
				
			||||||
 | 
					                          tout << "b | s + z: " << mk_pp(b_divides_sz, m) << "\n";
 | 
				
			||||||
 | 
					                          tout << "a(s+z) + bt <= 0: " << mk_pp(asz_bt_le_0, m) << "\n";
 | 
				
			||||||
 | 
					                          );                   
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                mk_flat_and(as_bt_le_0, tmp2, result2); 
 | 
					                mk_flat_and(as_bt_le_0, tmp2, result2); 
 | 
				
			||||||
                mk_or(result1, result2, result);
 | 
					                mk_or(result1, result2, result);
 | 
				
			||||||
                simplify(result);
 | 
					                simplify(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //    a*s + b*t + (a-1)(b-1) <= 0 
 | 
				
			||||||
 | 
					                // or exists z in [0 .. |b|-2] . |b| | (z + s) && a*n_sign(b)(s + z) + |b|t <= 0
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            TRACE("qe", 
 | 
					            TRACE("qe", 
 | 
				
			||||||
                  {
 | 
					                  {
 | 
				
			||||||
                      expr_ref_vector trail(m);
 | 
					                      tout << (is_strict?"strict":"non-strict") << "\n";
 | 
				
			||||||
                      tout << "is_strict: " << (is_strict?"true":"false") << "\n";
 | 
					 | 
				
			||||||
                      bound(m, a, t, false).pp(tout, x);
 | 
					                      bound(m, a, t, false).pp(tout, x);
 | 
				
			||||||
                      tout << "\n";
 | 
					                      tout << "\n";
 | 
				
			||||||
                      bound(m, b, s, false).pp(tout, x);
 | 
					                      bound(m, b, s, false).pp(tout, x);
 | 
				
			||||||
| 
						 | 
					@ -592,10 +599,6 @@ namespace qe {
 | 
				
			||||||
                  });            
 | 
					                  });            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        void simplify(expr_ref& p) {
 | 
					 | 
				
			||||||
            m_rewriter(p);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct mul_lt {
 | 
					        struct mul_lt {
 | 
				
			||||||
            arith_util& u;
 | 
					            arith_util& u;
 | 
				
			||||||
            mul_lt(arith_qe_util& u): u(u.m_arith) {}
 | 
					            mul_lt(arith_qe_util& u): u(u.m_arith) {}
 | 
				
			||||||
| 
						 | 
					@ -1052,7 +1055,6 @@ namespace qe {
 | 
				
			||||||
        }        
 | 
					        }        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool reduce_equation(expr* p, expr* fml) {
 | 
					        bool reduce_equation(expr* p, expr* fml) {
 | 
				
			||||||
            TRACE("qe", tout << mk_pp(p, m) << "\n";);
 | 
					 | 
				
			||||||
            numeral k;
 | 
					            numeral k;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (m_arith.is_numeral(p, k) && k.is_zero()) {
 | 
					            if (m_arith.is_numeral(p, k) && k.is_zero()) {
 | 
				
			||||||
| 
						 | 
					@ -1555,9 +1557,10 @@ public:
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                mk_non_resolve(bounds, true,  is_lower, result);
 | 
					                mk_non_resolve(bounds, true,  is_lower, result);
 | 
				
			||||||
                mk_non_resolve(bounds, false, is_lower, result);
 | 
					                mk_non_resolve(bounds, false, is_lower, result);
 | 
				
			||||||
 | 
					                m_util.simplify(result);
 | 
				
			||||||
                add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term());
 | 
					                add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term());
 | 
				
			||||||
                TRACE("qe", 
 | 
					                TRACE("qe", 
 | 
				
			||||||
                        tout << vl << " " << mk_pp(x, m) << "\n";
 | 
					                        tout << vl << " " << mk_pp(x, m) << " infinite case\n";
 | 
				
			||||||
                        tout << mk_pp(fml, m) << "\n";
 | 
					                        tout << mk_pp(fml, m) << "\n";
 | 
				
			||||||
                        tout << mk_pp(result, m) << "\n";);
 | 
					                        tout << mk_pp(result, m) << "\n";);
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
| 
						 | 
					@ -1592,18 +1595,21 @@ public:
 | 
				
			||||||
            expr_ref t(bounds.exprs(is_strict, is_lower)[index], m);
 | 
					            expr_ref t(bounds.exprs(is_strict, is_lower)[index], m);
 | 
				
			||||||
            rational a = bounds.coeffs(is_strict, is_lower)[index];
 | 
					            rational a = bounds.coeffs(is_strict, is_lower)[index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            t = x_t.mk_term(a, t);
 | 
					            
 | 
				
			||||||
            a = x_t.mk_coeff(a);
 | 
					 | 
				
			||||||
                                
 | 
					                                
 | 
				
			||||||
            mk_bounds(bounds, x, true,  is_eq, is_strict, is_lower, index, a, t, result);
 | 
					            mk_bounds(bounds, x, true,  is_eq, is_strict, is_lower, index, a, t, result);
 | 
				
			||||||
            mk_bounds(bounds, x, false, is_eq, is_strict, is_lower, index, a, t, result);
 | 
					            mk_bounds(bounds, x, false, is_eq, is_strict, is_lower, index, a, t, result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            t = x_t.mk_term(a, t);
 | 
				
			||||||
 | 
					            a = x_t.mk_coeff(a);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            mk_resolve(bounds, x, x_t, true,  is_eq, is_strict, is_lower, index, a, t, result);
 | 
					            mk_resolve(bounds, x, x_t, true,  is_eq, is_strict, is_lower, index, a, t, result);
 | 
				
			||||||
            mk_resolve(bounds, x, x_t, false, is_eq, is_strict, is_lower, index, a, t, result);
 | 
					            mk_resolve(bounds, x, x_t, false, is_eq, is_strict, is_lower, index, a, t, result);
 | 
				
			||||||
 | 
					            m_util.simplify(result);
 | 
				
			||||||
            add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term());
 | 
					            add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term());
 | 
				
			||||||
            TRACE("qe", 
 | 
					            TRACE("qe", 
 | 
				
			||||||
                  {
 | 
					                  {
 | 
				
			||||||
                      tout << vl << " " << mk_pp(x, m) << "\n";
 | 
					                      tout << vl << " " << mk_pp(bounds.atoms(is_strict, is_lower)[index],m) << "\n";
 | 
				
			||||||
                      tout << mk_pp(fml, m) << "\n";
 | 
					                      tout << mk_pp(fml, m) << "\n";
 | 
				
			||||||
                      tout << mk_pp(result, m) << "\n";
 | 
					                      tout << mk_pp(result, m) << "\n";
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
| 
						 | 
					@ -2225,6 +2231,12 @@ public:
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            m_util.simplify(result);
 | 
					            m_util.simplify(result);
 | 
				
			||||||
 | 
					            TRACE("qe", 
 | 
				
			||||||
 | 
					                  tout << (is_strict?"strict":"non-strict") << "\n";
 | 
				
			||||||
 | 
					                  tout << (is_lower?"is-lower":"is-upper") << "\n";
 | 
				
			||||||
 | 
					                  tout << "a: " << a << " " << mk_pp(t, m) << "\n";
 | 
				
			||||||
 | 
					                  tout << "b: " << b << " " << mk_pp(s, m) << "\n";
 | 
				
			||||||
 | 
					                  tout << mk_pp(result, m) << "\n";);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
| 
						 | 
					@ -2245,10 +2257,12 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void mk_bounds(bounds_proc& bounds, 
 | 
					        void mk_bounds(bounds_proc& bounds, 
 | 
				
			||||||
                       app* x,  bool is_strict, bool is_eq_ctx, bool is_strict_ctx, bool is_lower, unsigned index, 
 | 
					                       app* x, bool is_strict, bool is_eq_ctx, 
 | 
				
			||||||
 | 
					                       bool is_strict_ctx, bool is_lower, unsigned index, 
 | 
				
			||||||
                       rational const& a, expr* t,
 | 
					                       rational const& a, expr* t,
 | 
				
			||||||
                       expr_ref& result) 
 | 
					                       expr_ref& result) 
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            TRACE("qe", tout << mk_pp(t, m) << "\n";);
 | 
				
			||||||
            SASSERT(!is_eq_ctx || !is_strict_ctx);
 | 
					            SASSERT(!is_eq_ctx || !is_strict_ctx);
 | 
				
			||||||
            unsigned sz = bounds.size(is_strict, is_lower);
 | 
					            unsigned sz = bounds.size(is_strict, is_lower);
 | 
				
			||||||
            expr_ref tmp(m), eq(m);            
 | 
					            expr_ref tmp(m), eq(m);            
 | 
				
			||||||
| 
						 | 
					@ -2258,13 +2272,14 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (unsigned i = 0; i < sz; ++i) {
 | 
					            for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
                app* e   = bounds.atoms(is_strict, is_lower)[i];
 | 
					                app* e   = bounds.atoms(is_strict, is_lower)[i];
 | 
				
			||||||
                expr* s  = bounds.exprs(is_strict, is_lower)[i];
 | 
					                expr_ref s(bounds.exprs(is_strict, is_lower)[i], m);
 | 
				
			||||||
                rational b = bounds.coeffs(is_strict, is_lower)[i]; 
 | 
					                rational b = bounds.coeffs(is_strict, is_lower)[i]; 
 | 
				
			||||||
               
 | 
					               
 | 
				
			||||||
                if (same_strict && i == index) {                    
 | 
					                if (same_strict && i == index) {                    
 | 
				
			||||||
                    if (non_strict_real) {
 | 
					                    if (non_strict_real) {
 | 
				
			||||||
                        m_util.mk_eq(a, x, t, eq);
 | 
					                        m_util.mk_eq(a, x, t, eq);
 | 
				
			||||||
                        TRACE("qe", tout << "a:" << a << " x: " << mk_pp(x, m) << " t: " << mk_pp(t, m) << " eq: " << mk_pp(eq, m) << "\n";);
 | 
					                        TRACE("qe", tout << "a:" << a << " x: " << mk_pp(x, m) << "t: " << 
 | 
				
			||||||
 | 
					                              mk_pp(t, m) << " eq: " << mk_pp(eq, m) << "\n";);
 | 
				
			||||||
                        if (is_eq_ctx) {
 | 
					                        if (is_eq_ctx) {
 | 
				
			||||||
                            m_ctx.add_constraint(true, eq);
 | 
					                            m_ctx.add_constraint(true, eq);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
| 
						 | 
					@ -2292,6 +2307,7 @@ public:
 | 
				
			||||||
                    (non_strict_real && is_eq_ctx && is_strict) ||
 | 
					                    (non_strict_real && is_eq_ctx && is_strict) ||
 | 
				
			||||||
                    (same_strict && i < index);
 | 
					                    (same_strict && i < index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                mk_bound(result_is_strict, is_lower, a, t, b, s, tmp);
 | 
					                mk_bound(result_is_strict, is_lower, a, t, b, s, tmp);
 | 
				
			||||||
                m_util.m_replace.apply_substitution(e, tmp.get(), result);
 | 
					                m_util.m_replace.apply_substitution(e, tmp.get(), result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2330,14 +2346,17 @@ public:
 | 
				
			||||||
                s = x_t.mk_term(b, s);
 | 
					                s = x_t.mk_term(b, s);
 | 
				
			||||||
                b = x_t.mk_coeff(b);
 | 
					                b = x_t.mk_coeff(b);
 | 
				
			||||||
                m_util.mk_resolve(x, strict_resolve, a, t, b, s, tmp);
 | 
					                m_util.mk_resolve(x, strict_resolve, a, t, b, s, tmp);
 | 
				
			||||||
 | 
					                expr_ref save_result(result);
 | 
				
			||||||
                m_util.m_replace.apply_substitution(e, tmp.get(), result);
 | 
					                m_util.m_replace.apply_substitution(e, tmp.get(), result);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                m_ctx.add_constraint(true, mk_not(e), tmp);
 | 
					                m_ctx.add_constraint(true, mk_not(e), tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                TRACE("qe_verbose", 
 | 
					                TRACE("qe_verbose", 
 | 
				
			||||||
                      tout << mk_pp(atm, m) << " ";
 | 
					                      tout << mk_pp(atm, m) << " ";
 | 
				
			||||||
                      tout << mk_pp(e, m) << " ==> ";
 | 
					                      tout << mk_pp(e, m) << " ==>\n";
 | 
				
			||||||
                      tout << mk_pp(tmp, m) << "\n";
 | 
					                      tout << mk_pp(tmp, m) << "\n";
 | 
				
			||||||
 | 
					                      tout << "old fml: " << mk_pp(save_result, m) << "\n";
 | 
				
			||||||
 | 
					                      tout << "new fml: " << mk_pp(result, m) << "\n";
 | 
				
			||||||
                      );           
 | 
					                      );           
 | 
				
			||||||
            }            
 | 
					            }            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@ void preprocessor_params::updt_local_params(params_ref const & _p) {
 | 
				
			||||||
    smt_params_helper p(_p);
 | 
					    smt_params_helper p(_p);
 | 
				
			||||||
    m_macro_finder            = p.macro_finder();
 | 
					    m_macro_finder            = p.macro_finder();
 | 
				
			||||||
    m_pull_nested_quantifiers = p.pull_nested_quantifiers();
 | 
					    m_pull_nested_quantifiers = p.pull_nested_quantifiers();
 | 
				
			||||||
 | 
					    m_refine_inj_axiom        = p.refine_inj_axioms();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void preprocessor_params::updt_params(params_ref const & p) {
 | 
					void preprocessor_params::updt_params(params_ref const & p) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ def_module_params(module_name='smt',
 | 
				
			||||||
                          ('delay_units', BOOL, False, 'if true then z3 will not restart when a unit clause is learned'),
 | 
					                          ('delay_units', BOOL, False, 'if true then z3 will not restart when a unit clause is learned'),
 | 
				
			||||||
                          ('delay_units_threshold', UINT, 32, 'maximum number of learned unit clauses before restarting, ingored if delay_units is false'),
 | 
					                          ('delay_units_threshold', UINT, 32, 'maximum number of learned unit clauses before restarting, ingored if delay_units is false'),
 | 
				
			||||||
                          ('pull_nested_quantifiers', BOOL, False, 'pull nested quantifiers'),
 | 
					                          ('pull_nested_quantifiers', BOOL, False, 'pull nested quantifiers'),
 | 
				
			||||||
 | 
					                          ('refine_inj_axioms', BOOL, True, 'refine injectivity axioms'),
 | 
				
			||||||
                          ('soft_timeout', UINT, 0, 'soft timeout (0 means no timeout)'),
 | 
					                          ('soft_timeout', UINT, 0, 'soft timeout (0 means no timeout)'),
 | 
				
			||||||
                          ('mbqi', BOOL, True, 'model based quantifier instantiation (MBQI)'),
 | 
					                          ('mbqi', BOOL, True, 'model based quantifier instantiation (MBQI)'),
 | 
				
			||||||
                          ('mbqi.max_cexs', UINT, 1, 'initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation'),
 | 
					                          ('mbqi.max_cexs', UINT, 1, 'initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation'),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@ Revision History:
 | 
				
			||||||
void theory_arith_params::updt_params(params_ref const & _p) {
 | 
					void theory_arith_params::updt_params(params_ref const & _p) {
 | 
				
			||||||
    smt_params_helper p(_p);
 | 
					    smt_params_helper p(_p);
 | 
				
			||||||
    m_arith_random_initial_value = p.arith_random_initial_value();
 | 
					    m_arith_random_initial_value = p.arith_random_initial_value();
 | 
				
			||||||
 | 
					    m_arith_random_seed = p.random_seed();
 | 
				
			||||||
    m_arith_mode = static_cast<arith_solver_id>(p.arith_solver());
 | 
					    m_arith_mode = static_cast<arith_solver_id>(p.arith_solver());
 | 
				
			||||||
    m_nl_arith = p.arith_nl();
 | 
					    m_nl_arith = p.arith_nl();
 | 
				
			||||||
    m_nl_arith_gb = p.arith_nl_gb();
 | 
					    m_nl_arith_gb = p.arith_nl_gb();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,8 +191,10 @@ expr * datatype_factory::get_fresh_value(sort * s) {
 | 
				
			||||||
    // Approach 2)
 | 
					    // Approach 2)
 | 
				
			||||||
    // For recursive datatypes.
 | 
					    // For recursive datatypes.
 | 
				
			||||||
    // search for constructor...
 | 
					    // search for constructor...
 | 
				
			||||||
 | 
					    unsigned num_iterations = 0;
 | 
				
			||||||
    if (m_util.is_recursive(s)) {
 | 
					    if (m_util.is_recursive(s)) {
 | 
				
			||||||
        while(true) {
 | 
					        while(true) {
 | 
				
			||||||
 | 
					            ++num_iterations;
 | 
				
			||||||
            TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";);
 | 
					            TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";);
 | 
				
			||||||
            ptr_vector<func_decl> const * constructors = m_util.get_datatype_constructors(s);
 | 
					            ptr_vector<func_decl> const * constructors = m_util.get_datatype_constructors(s);
 | 
				
			||||||
            ptr_vector<func_decl>::const_iterator it   = constructors->begin();
 | 
					            ptr_vector<func_decl>::const_iterator it   = constructors->begin();
 | 
				
			||||||
| 
						 | 
					@ -212,7 +214,13 @@ expr * datatype_factory::get_fresh_value(sort * s) {
 | 
				
			||||||
                          << found_sibling << "\n";);
 | 
					                          << found_sibling << "\n";);
 | 
				
			||||||
                    if (!found_sibling && m_util.is_datatype(s_arg) && m_util.are_siblings(s, s_arg)) {
 | 
					                    if (!found_sibling && m_util.is_datatype(s_arg) && m_util.are_siblings(s, s_arg)) {
 | 
				
			||||||
                        found_sibling = true;
 | 
					                        found_sibling = true;
 | 
				
			||||||
                        expr * maybe_new_arg = get_almost_fresh_value(s_arg);
 | 
					                        expr * maybe_new_arg = 0;
 | 
				
			||||||
 | 
					                        if (num_iterations <= 1) {
 | 
				
			||||||
 | 
					                            maybe_new_arg = get_almost_fresh_value(s_arg);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else {
 | 
				
			||||||
 | 
					                            maybe_new_arg = get_fresh_value(s_arg);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                        if (!maybe_new_arg) {
 | 
					                        if (!maybe_new_arg) {
 | 
				
			||||||
                            TRACE("datatype_factory", 
 | 
					                            TRACE("datatype_factory", 
 | 
				
			||||||
                                  tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";);
 | 
					                                  tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";);
 | 
				
			||||||
| 
						 | 
					@ -231,6 +239,7 @@ expr * datatype_factory::get_fresh_value(sort * s) {
 | 
				
			||||||
                if (found_sibling) {
 | 
					                if (found_sibling) {
 | 
				
			||||||
                    expr_ref new_value(m_manager);
 | 
					                    expr_ref new_value(m_manager);
 | 
				
			||||||
                    new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
 | 
					                    new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
 | 
				
			||||||
 | 
					                    TRACE("datatype_factory", tout << "potential new value: " << mk_pp(new_value, m_manager) << "\n";);
 | 
				
			||||||
                    m_last_fresh_value.insert(s, new_value);
 | 
					                    m_last_fresh_value.insert(s, new_value);
 | 
				
			||||||
                    if (!set->contains(new_value)) {
 | 
					                    if (!set->contains(new_value)) {
 | 
				
			||||||
                        register_value(new_value);
 | 
					                        register_value(new_value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3945,7 +3945,7 @@ namespace smt {
 | 
				
			||||||
              m_fingerprints.display(tout); 
 | 
					              m_fingerprints.display(tout); 
 | 
				
			||||||
              );
 | 
					              );
 | 
				
			||||||
        failure fl = get_last_search_failure();
 | 
					        failure fl = get_last_search_failure();
 | 
				
			||||||
        if (fl == TIMEOUT || fl == MEMOUT || fl == CANCELED || fl == NUM_CONFLICTS) {
 | 
					        if (fl == TIMEOUT || fl == MEMOUT || fl == CANCELED || fl == NUM_CONFLICTS || fl == THEORY) {
 | 
				
			||||||
            // don't generate model.
 | 
					            // don't generate model.
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,6 +102,7 @@ namespace smt {
 | 
				
			||||||
                    if (th && th->build_models()) {
 | 
					                    if (th && th->build_models()) {
 | 
				
			||||||
                        if (r->get_th_var(th->get_id()) != null_theory_var) {
 | 
					                        if (r->get_th_var(th->get_id()) != null_theory_var) {
 | 
				
			||||||
                            proc = th->mk_value(r, *this);
 | 
					                            proc = th->mk_value(r, *this);
 | 
				
			||||||
 | 
					                            SASSERT(proc);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else {
 | 
					                        else {
 | 
				
			||||||
                            TRACE("model_bug", tout << "creating fresh value for #" << r->get_owner_id() << "\n";);
 | 
					                            TRACE("model_bug", tout << "creating fresh value for #" << r->get_owner_id() << "\n";);
 | 
				
			||||||
| 
						 | 
					@ -110,6 +111,7 @@ namespace smt {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else {
 | 
					                    else {
 | 
				
			||||||
                        proc = mk_model_value(r);
 | 
					                        proc = mk_model_value(r);
 | 
				
			||||||
 | 
					                        SASSERT(proc);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                SASSERT(proc);
 | 
					                SASSERT(proc);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -193,7 +193,7 @@ namespace smt {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!r.get_base_var() == x && x > y) {
 | 
					        if (r.get_base_var() != x && x > y) {
 | 
				
			||||||
            std::swap(x, y);
 | 
					            std::swap(x, y);
 | 
				
			||||||
            k.neg();
 | 
					            k.neg();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1198,6 +1198,7 @@ namespace smt {
 | 
				
			||||||
    void theory_bv::relevant_eh(app * n) {
 | 
					    void theory_bv::relevant_eh(app * n) {
 | 
				
			||||||
        ast_manager & m = get_manager();
 | 
					        ast_manager & m = get_manager();
 | 
				
			||||||
        context & ctx   = get_context();
 | 
					        context & ctx   = get_context();
 | 
				
			||||||
 | 
					        TRACE("bv", tout << "relevant: " << mk_pp(n, m) << "\n";);
 | 
				
			||||||
        if (m.is_bool(n)) {
 | 
					        if (m.is_bool(n)) {
 | 
				
			||||||
            bool_var v = ctx.get_bool_var(n);
 | 
					            bool_var v = ctx.get_bool_var(n);
 | 
				
			||||||
            atom * a   = get_bv2a(v);
 | 
					            atom * a   = get_bv2a(v);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,7 +162,7 @@ namespace smt {
 | 
				
			||||||
            m.register_factory(alloc(dl_factory, m_util, m.get_model()));
 | 
					            m.register_factory(alloc(dl_factory, m_util, m.get_model()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        virtual smt::model_value_proc * mk_value(smt::enode * n) {
 | 
					        virtual smt::model_value_proc * mk_value(smt::enode * n, smt::model_generator&) {
 | 
				
			||||||
            return alloc(dl_value_proc, *this, n);
 | 
					            return alloc(dl_value_proc, *this, n);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,9 +201,8 @@ namespace smt {
 | 
				
			||||||
            if(!m_reps.find(s, r) || !m_vals.find(s,v)) {
 | 
					            if(!m_reps.find(s, r) || !m_vals.find(s,v)) {
 | 
				
			||||||
                SASSERT(!m_reps.contains(s));
 | 
					                SASSERT(!m_reps.contains(s));
 | 
				
			||||||
                sort* bv = b().mk_sort(64);
 | 
					                sort* bv = b().mk_sort(64);
 | 
				
			||||||
                // TBD: filter these from model.
 | 
					                r = m().mk_func_decl(m_util.get_family_id(), datalog::OP_DL_REP, 0, 0, 1, &s, bv);
 | 
				
			||||||
                r = m().mk_fresh_func_decl("rep",1, &s,bv);
 | 
					                v = m().mk_func_decl(m_util.get_family_id(), datalog::OP_DL_ABS, 0, 0, 1, &bv, s);
 | 
				
			||||||
                v = m().mk_fresh_func_decl("val",1, &bv,s);
 | 
					 | 
				
			||||||
                m_reps.insert(s, r);
 | 
					                m_reps.insert(s, r);
 | 
				
			||||||
                m_vals.insert(s, v);
 | 
					                m_vals.insert(s, v);
 | 
				
			||||||
                add_trail(r);
 | 
					                add_trail(r);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -218,6 +218,7 @@ br_status bv2int_rewriter::mk_mod(expr * s, expr * t, expr_ref & result) {
 | 
				
			||||||
    if (is_bv2int(s, s1) && is_bv2int(t, t1)) {
 | 
					    if (is_bv2int(s, s1) && is_bv2int(t, t1)) {
 | 
				
			||||||
        align_sizes(s1, t1, false);
 | 
					        align_sizes(s1, t1, false);
 | 
				
			||||||
        result = m_bv.mk_bv2int(m_bv.mk_bv_urem(s1, t1));
 | 
					        result = m_bv.mk_bv2int(m_bv.mk_bv_urem(s1, t1));
 | 
				
			||||||
 | 
					        TRACE("bv2int_rewriter", tout << mk_pp(result,m()) << "\n";);
 | 
				
			||||||
        return BR_DONE;
 | 
					        return BR_DONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -232,6 +233,7 @@ br_status bv2int_rewriter::mk_mod(expr * s, expr * t, expr_ref & result) {
 | 
				
			||||||
        u1 = mk_bv_add(s1, u1, false);
 | 
					        u1 = mk_bv_add(s1, u1, false);
 | 
				
			||||||
        align_sizes(u1, t1, false);
 | 
					        align_sizes(u1, t1, false);
 | 
				
			||||||
        result = m_bv.mk_bv2int(m_bv.mk_bv_urem(u1, t1));
 | 
					        result = m_bv.mk_bv2int(m_bv.mk_bv_urem(u1, t1));
 | 
				
			||||||
 | 
					        TRACE("bv2int_rewriter", tout << mk_pp(result,m()) << "\n";);
 | 
				
			||||||
        return BR_DONE;
 | 
					        return BR_DONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
    ast_manager &      m;
 | 
					    ast_manager &      m;
 | 
				
			||||||
    params_ref         m_params;
 | 
					    params_ref         m_params;
 | 
				
			||||||
    unsigned long long m_max_memory;
 | 
					    unsigned long long m_max_memory;
 | 
				
			||||||
 | 
					    bool               m_cofactor_equalities;
 | 
				
			||||||
    volatile bool      m_cancel;
 | 
					    volatile bool      m_cancel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void checkpoint() { 
 | 
					    void checkpoint() { 
 | 
				
			||||||
| 
						 | 
					@ -36,7 +37,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
        if (memory::get_allocation_size() > m_max_memory)
 | 
					        if (memory::get_allocation_size() > m_max_memory)
 | 
				
			||||||
            throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
 | 
					            throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
 | 
				
			||||||
        if (m_cancel)
 | 
					        if (m_cancel)
 | 
				
			||||||
            throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
 | 
					            throw tactic_exception(TACTIC_CANCELED_MSG);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Collect atoms that contain term if-then-else
 | 
					    // Collect atoms that contain term if-then-else
 | 
				
			||||||
| 
						 | 
					@ -111,7 +112,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
                frame & fr    = m_frame_stack.back();
 | 
					                frame & fr    = m_frame_stack.back();
 | 
				
			||||||
                expr * t      = fr.m_t;
 | 
					                expr * t      = fr.m_t;
 | 
				
			||||||
                bool form_ctx = fr.m_form_ctx;
 | 
					                bool form_ctx = fr.m_form_ctx;
 | 
				
			||||||
                TRACE("cofactor_ite_analyzer", tout << "processing, form_ctx: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";);
 | 
					                TRACE("cofactor", tout << "processing, form_ctx: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                m_owner.checkpoint();
 | 
					                m_owner.checkpoint();
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
| 
						 | 
					@ -150,7 +151,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (i < num_args) {
 | 
					                    if (i < num_args) {
 | 
				
			||||||
                        m_has_term_ite.mark(t);
 | 
					                        m_has_term_ite.mark(t);
 | 
				
			||||||
                        TRACE("cofactor_ite_analyzer", tout << "saving candidate: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";);
 | 
					                        TRACE("cofactor", tout << "saving candidate: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";);
 | 
				
			||||||
                        save_candidate(t, form_ctx);
 | 
					                        save_candidate(t, form_ctx);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -167,6 +168,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expr * get_first(expr * t) { 
 | 
					    expr * get_first(expr * t) { 
 | 
				
			||||||
 | 
					        TRACE("cofactor", tout << mk_ismt2_pp(t, m) << "\n";);
 | 
				
			||||||
        typedef std::pair<expr *, unsigned> frame;
 | 
					        typedef std::pair<expr *, unsigned> frame;
 | 
				
			||||||
        expr_fast_mark1         visited;            
 | 
					        expr_fast_mark1         visited;            
 | 
				
			||||||
        sbuffer<frame>          stack;    
 | 
					        sbuffer<frame>          stack;    
 | 
				
			||||||
| 
						 | 
					@ -225,6 +227,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
       \brief Fuctor for selecting the term if-then-else condition with the most number of occurrences.
 | 
					       \brief Fuctor for selecting the term if-then-else condition with the most number of occurrences.
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    expr * get_best(expr * t) {
 | 
					    expr * get_best(expr * t) {
 | 
				
			||||||
 | 
					        TRACE("cofactor", tout << mk_ismt2_pp(t, m) << "\n";);
 | 
				
			||||||
        typedef std::pair<expr *, unsigned> frame;
 | 
					        typedef std::pair<expr *, unsigned> frame;
 | 
				
			||||||
        obj_map<expr, unsigned> occs;
 | 
					        obj_map<expr, unsigned> occs;
 | 
				
			||||||
        expr_fast_mark1         visited;            
 | 
					        expr_fast_mark1         visited;            
 | 
				
			||||||
| 
						 | 
					@ -299,12 +302,17 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        visited.reset();
 | 
					        visited.reset();
 | 
				
			||||||
        CTRACE("cofactor_ite_get_best", best != 0, tout << "best num-occs: " << best_occs << "\n" << mk_ismt2_pp(best, m) << "\n";);
 | 
					        CTRACE("cofactor", best != 0, tout << "best num-occs: " << best_occs << "\n" << mk_ismt2_pp(best, m) << "\n";);
 | 
				
			||||||
        return best;
 | 
					        return best;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void updt_params(params_ref const & p) {
 | 
					    void updt_params(params_ref const & p) {
 | 
				
			||||||
        m_max_memory     = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
 | 
					        m_max_memory     = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
 | 
				
			||||||
 | 
					        m_cofactor_equalities = p.get_bool("cofactor_equalities", true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void collect_param_descrs(param_descrs & r) {
 | 
				
			||||||
 | 
					        r.insert("cofactor_equalities", CPK_BOOL, "(default: true) use equalities to rewrite bodies of ite-expressions. This is potentially expensive.");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void set_cancel(bool f) {
 | 
					    void set_cancel(bool f) {
 | 
				
			||||||
| 
						 | 
					@ -354,16 +362,16 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
                m_term = 0;
 | 
					                m_term = 0;
 | 
				
			||||||
                expr * lhs;
 | 
					                expr * lhs;
 | 
				
			||||||
                expr * rhs;
 | 
					                expr * rhs;
 | 
				
			||||||
                if (m.is_eq(t, lhs, rhs)) {
 | 
					                if (m_owner.m_cofactor_equalities && m.is_eq(t, lhs, rhs)) {
 | 
				
			||||||
                    if (m.is_unique_value(lhs)) {
 | 
					                    if (m.is_unique_value(lhs)) {
 | 
				
			||||||
                        m_term  = rhs;
 | 
					                        m_term  = rhs;
 | 
				
			||||||
                        m_value = to_app(lhs); 
 | 
					                        m_value = to_app(lhs); 
 | 
				
			||||||
                        TRACE("set_cofactor_atom", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";);
 | 
					                        TRACE("cofactor", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else if (m.is_unique_value(rhs)) {
 | 
					                    else if (m.is_unique_value(rhs)) {
 | 
				
			||||||
                        m_term  = lhs;
 | 
					                        m_term  = lhs;
 | 
				
			||||||
                        m_value = to_app(rhs);
 | 
					                        m_value = to_app(rhs);
 | 
				
			||||||
                        TRACE("set_cofactor_atom", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";);
 | 
					                        TRACE("cofactor", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                // TODO: bounds
 | 
					                // TODO: bounds
 | 
				
			||||||
| 
						 | 
					@ -467,7 +475,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
                    m_cofactor.set_cofactor_atom(neg_c);
 | 
					                    m_cofactor.set_cofactor_atom(neg_c);
 | 
				
			||||||
                    m_cofactor(curr, neg_cofactor);
 | 
					                    m_cofactor(curr, neg_cofactor);
 | 
				
			||||||
                    curr = m.mk_ite(c, pos_cofactor, neg_cofactor);
 | 
					                    curr = m.mk_ite(c, pos_cofactor, neg_cofactor);
 | 
				
			||||||
                    TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
 | 
					                    TRACE("cofactor", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
| 
						 | 
					@ -522,7 +530,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        void cofactor(expr * t, expr_ref & r) {
 | 
					        void cofactor(expr * t, expr_ref & r) {
 | 
				
			||||||
            unsigned step = 0;
 | 
					            unsigned step = 0;
 | 
				
			||||||
            TRACE("cofactor_ite", tout << "cofactor target:\n" << mk_ismt2_pp(t, m) << "\n";);
 | 
					            TRACE("cofactor", tout << "cofactor target:\n" << mk_ismt2_pp(t, m) << "\n";);
 | 
				
			||||||
            expr_ref curr(m);
 | 
					            expr_ref curr(m);
 | 
				
			||||||
            curr = t;
 | 
					            curr = t;
 | 
				
			||||||
            while (true) {
 | 
					            while (true) {
 | 
				
			||||||
| 
						 | 
					@ -543,21 +551,20 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
                m_cofactor(curr, neg_cofactor);
 | 
					                m_cofactor(curr, neg_cofactor);
 | 
				
			||||||
                if (pos_cofactor == neg_cofactor) {
 | 
					                if (pos_cofactor == neg_cofactor) {
 | 
				
			||||||
                    curr = pos_cofactor;
 | 
					                    curr = pos_cofactor;
 | 
				
			||||||
                    TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (m.is_true(pos_cofactor) && m.is_false(neg_cofactor)) {
 | 
					                else if (m.is_true(pos_cofactor) && m.is_false(neg_cofactor)) {
 | 
				
			||||||
                    curr = c;
 | 
					                    curr = c;
 | 
				
			||||||
                    TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (m.is_false(pos_cofactor) && m.is_true(neg_cofactor)) {
 | 
					                else if (m.is_false(pos_cofactor) && m.is_true(neg_cofactor)) {
 | 
				
			||||||
                    curr = neg_c;
 | 
					                    curr = neg_c;
 | 
				
			||||||
                    TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
                    curr = m.mk_ite(c, pos_cofactor, neg_cofactor);
 | 
					                    curr = m.mk_ite(c, pos_cofactor, neg_cofactor);
 | 
				
			||||||
                TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
 | 
					                }
 | 
				
			||||||
 | 
					                TRACE("cofactor", 
 | 
				
			||||||
 | 
					                      tout << "cofactor_ite step: " << step << "\n";
 | 
				
			||||||
 | 
					                      tout << "cofactor: " << mk_ismt2_pp(c, m) << "\n";
 | 
				
			||||||
 | 
					                      tout << mk_ismt2_pp(curr, m) << "\n";);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -570,6 +577,7 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        void operator()(expr * t, expr_ref & r) {
 | 
					        void operator()(expr * t, expr_ref & r) {
 | 
				
			||||||
            ptr_vector<expr> new_args;
 | 
					            ptr_vector<expr> new_args;
 | 
				
			||||||
 | 
					            SASSERT(m_frames.empty());
 | 
				
			||||||
            m_frames.push_back(frame(t, true));
 | 
					            m_frames.push_back(frame(t, true));
 | 
				
			||||||
            while (!m_frames.empty()) {
 | 
					            while (!m_frames.empty()) {
 | 
				
			||||||
                m_owner.checkpoint();
 | 
					                m_owner.checkpoint();
 | 
				
			||||||
| 
						 | 
					@ -649,7 +657,8 @@ struct cofactor_elim_term_ite::imp {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    imp(ast_manager & _m, params_ref const & p):
 | 
					    imp(ast_manager & _m, params_ref const & p):
 | 
				
			||||||
        m(_m),
 | 
					        m(_m),
 | 
				
			||||||
        m_params(p) {
 | 
					        m_params(p),
 | 
				
			||||||
 | 
					        m_cofactor_equalities(true) {
 | 
				
			||||||
        m_cancel = false;
 | 
					        m_cancel = false;
 | 
				
			||||||
        updt_params(p);
 | 
					        updt_params(p);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -686,7 +695,8 @@ void cofactor_elim_term_ite::updt_params(params_ref const & p) {
 | 
				
			||||||
    m_imp->updt_params(p);
 | 
					    m_imp->updt_params(p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cofactor_elim_term_ite::get_param_descrs(param_descrs & r) {
 | 
					void cofactor_elim_term_ite::collect_param_descrs(param_descrs & r) {
 | 
				
			||||||
 | 
					    m_imp->collect_param_descrs(r);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cofactor_elim_term_ite::operator()(expr * t, expr_ref & r) {
 | 
					void cofactor_elim_term_ite::operator()(expr * t, expr_ref & r) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,7 @@ public:
 | 
				
			||||||
    virtual ~cofactor_elim_term_ite();
 | 
					    virtual ~cofactor_elim_term_ite();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void updt_params(params_ref const & p);
 | 
					    void updt_params(params_ref const & p);
 | 
				
			||||||
    static void get_param_descrs(param_descrs & r);
 | 
					    void collect_param_descrs(param_descrs & r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void operator()(expr * t, expr_ref & r);
 | 
					    void operator()(expr * t, expr_ref & r);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,8 +52,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual ~cofactor_term_ite_tactic() {}
 | 
					    virtual ~cofactor_term_ite_tactic() {}
 | 
				
			||||||
    virtual void updt_params(params_ref const & p) { m_params = p; m_elim_ite.updt_params(p); }
 | 
					    virtual void updt_params(params_ref const & p) { m_params = p; m_elim_ite.updt_params(p); }
 | 
				
			||||||
    static  void get_param_descrs(param_descrs & r) { cofactor_elim_term_ite::get_param_descrs(r); }
 | 
					    virtual void collect_param_descrs(param_descrs & r) { m_elim_ite.collect_param_descrs(r); }
 | 
				
			||||||
    virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    virtual void operator()(goal_ref const & g, 
 | 
					    virtual void operator()(goal_ref const & g, 
 | 
				
			||||||
                            goal_ref_buffer & result, 
 | 
					                            goal_ref_buffer & result, 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,7 @@ void filter_model_converter::operator()(model_ref & old_model, unsigned goal_idx
 | 
				
			||||||
        if (fs.is_marked(f))
 | 
					        if (fs.is_marked(f))
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        func_interp * fi = old_model->get_func_interp(f);
 | 
					        func_interp * fi = old_model->get_func_interp(f);
 | 
				
			||||||
 | 
					        SASSERT(fi);
 | 
				
			||||||
        new_model->register_decl(f, fi->copy());
 | 
					        new_model->register_decl(f, fi->copy());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    new_model->copy_usort_interps(*old_model);
 | 
					    new_model->copy_usort_interps(*old_model);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,6 +166,14 @@ public:
 | 
				
			||||||
        return e->get_data().m_value;
 | 
					        return e->get_data().m_value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value const & operator[](key * k) const {
 | 
				
			||||||
 | 
					        return find(k);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value & operator[](key * k) {
 | 
				
			||||||
 | 
					        return find(k);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    iterator find_iterator(Key * k) const { 
 | 
					    iterator find_iterator(Key * k) const { 
 | 
				
			||||||
        return m_table.find(key_data(k));
 | 
					        return m_table.find(key_data(k));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue