mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 13:29:11 +00:00 
			
		
		
		
	Merge branch 'unstable' of https://git01.codeplex.com/z3 into unstable
This commit is contained in:
		
						commit
						ed846a9ff3
					
				
					 11 changed files with 712 additions and 347 deletions
				
			
		| 
						 | 
				
			
			@ -151,6 +151,10 @@ sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, paramete
 | 
			
		|||
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) {
 | 
			
		||||
            m_manager->raise_exception("expecting two integer parameters to floating point sort");
 | 
			
		||||
        }
 | 
			
		||||
        if (parameters[0].get_int() <= 1 || parameters[1].get_int() <= 1)
 | 
			
		||||
            m_manager->raise_exception("floating point sorts need parameters > 1");
 | 
			
		||||
        if (parameters[0].get_int() > parameters[1].get_int())
 | 
			
		||||
            m_manager->raise_exception("floating point sorts with ebits > sbits are currently not supported");
 | 
			
		||||
        return mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
 | 
			
		||||
    case ROUNDING_MODE_SORT:
 | 
			
		||||
        return mk_rm_sort();
 | 
			
		||||
| 
						 | 
				
			
			@ -349,14 +353,14 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
 | 
			
		|||
        sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1);
 | 
			
		||||
        symbol name("asFloat");
 | 
			
		||||
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
 | 
			
		||||
		}
 | 
			
		||||
        }
 | 
			
		||||
    else {
 | 
			
		||||
        // .. Otherwise we only know how to convert rationals/reals. 
 | 
			
		||||
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) 
 | 
			
		||||
            m_manager->raise_exception("expecting two integer parameters to asFloat");        
 | 
			
		||||
        if (arity != 2 && arity != 3)
 | 
			
		||||
			m_manager->raise_exception("invalid number of arguments to asFloat operator");
 | 
			
		||||
		if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
 | 
			
		||||
            m_manager->raise_exception("invalid number of arguments to asFloat operator");
 | 
			
		||||
        if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
 | 
			
		||||
            m_manager->raise_exception("sort mismatch");
 | 
			
		||||
        if (arity == 2) {            
 | 
			
		||||
            sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -35,13 +35,13 @@ class fpa2bv_converter {
 | 
			
		|||
    ast_manager              & m;
 | 
			
		||||
    basic_simplifier_plugin    m_simp;
 | 
			
		||||
    float_util                 m_util;
 | 
			
		||||
	mpf_manager				 & m_mpf_manager;
 | 
			
		||||
	unsynch_mpz_manager      & m_mpz_manager;
 | 
			
		||||
    mpf_manager                 & m_mpf_manager;
 | 
			
		||||
    unsynch_mpz_manager      & m_mpz_manager;
 | 
			
		||||
    bv_util                    m_bv_util;    
 | 
			
		||||
    float_decl_plugin        * m_plugin;
 | 
			
		||||
 | 
			
		||||
    obj_map<func_decl, expr*>  m_const2bv;
 | 
			
		||||
	obj_map<func_decl, expr*>  m_rm_const2bv;
 | 
			
		||||
    obj_map<func_decl, expr*>  m_rm_const2bv;
 | 
			
		||||
    
 | 
			
		||||
public:
 | 
			
		||||
    fpa2bv_converter(ast_manager & m);    
 | 
			
		||||
| 
						 | 
				
			
			@ -52,22 +52,22 @@ public:
 | 
			
		|||
    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_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); }
 | 
			
		||||
    bool is_rm_sort(sort * s) { return m_util.is_rm(s); }
 | 
			
		||||
 | 
			
		||||
    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(significand));
 | 
			
		||||
		SASSERT(m_bv_util.is_bv(exponent));
 | 
			
		||||
        SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1);
 | 
			
		||||
        SASSERT(m_bv_util.is_bv(significand));
 | 
			
		||||
        SASSERT(m_bv_util.is_bv(exponent));
 | 
			
		||||
        result = m.mk_app(m_util.get_family_id(), OP_TO_FLOAT, sign, significand, exponent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void mk_eq(expr * a, expr * b, expr_ref & result);
 | 
			
		||||
    void mk_ite(expr * c, expr * t, expr * f, expr_ref & result);
 | 
			
		||||
 | 
			
		||||
	void mk_rounding_mode(func_decl * f, expr_ref & result);
 | 
			
		||||
    void mk_rounding_mode(func_decl * f, expr_ref & result);
 | 
			
		||||
    void mk_value(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
 | 
			
		||||
    void mk_const(func_decl * f, expr_ref & result);
 | 
			
		||||
	void mk_rm_const(func_decl * f, expr_ref & result);
 | 
			
		||||
    void mk_rm_const(func_decl * f, expr_ref & result);
 | 
			
		||||
 | 
			
		||||
    void mk_plus_inf(func_decl * f, expr_ref & result);
 | 
			
		||||
    void mk_minus_inf(func_decl * f, expr_ref & result);
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,8 @@ public:
 | 
			
		|||
    void mk_to_float(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
 | 
			
		||||
    void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
 | 
			
		||||
 | 
			
		||||
    fpa2bv_model_converter * mk_model_converter();
 | 
			
		||||
    obj_map<func_decl, expr*> const & const2bv() const { return m_const2bv; }
 | 
			
		||||
    obj_map<func_decl, expr*> const & rm_const2bv() const { return m_rm_const2bv; }
 | 
			
		||||
 | 
			
		||||
    void dbg_decouple(const char * prefix, expr_ref & e);
 | 
			
		||||
    expr_ref_vector extra_assertions;
 | 
			
		||||
| 
						 | 
				
			
			@ -122,11 +123,11 @@ protected:
 | 
			
		|||
    void mk_is_denormal(expr * e, expr_ref & result);
 | 
			
		||||
    void mk_is_normal(expr * e, expr_ref & result);
 | 
			
		||||
 | 
			
		||||
	void mk_is_rm(expr * e, BV_RM_VAL rm, expr_ref & result);
 | 
			
		||||
    void mk_is_rm(expr * e, BV_RM_VAL rm, expr_ref & result);
 | 
			
		||||
 | 
			
		||||
    void mk_top_exp(unsigned sz, expr_ref & result);
 | 
			
		||||
    void mk_bot_exp(unsigned sz, expr_ref & result);
 | 
			
		||||
	void mk_min_exp(unsigned ebits, expr_ref & result);
 | 
			
		||||
    void mk_min_exp(unsigned ebits, expr_ref & result);
 | 
			
		||||
    void mk_max_exp(unsigned ebits, expr_ref & result);
 | 
			
		||||
 | 
			
		||||
    void mk_leading_zeros(expr * e, unsigned max_bits, expr_ref & result);
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +136,7 @@ protected:
 | 
			
		|||
    void mk_unbias(expr * e, expr_ref & result);
 | 
			
		||||
 | 
			
		||||
    void unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp, bool normalize);
 | 
			
		||||
    void round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result);	    
 | 
			
		||||
    void round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result);        
 | 
			
		||||
 | 
			
		||||
    void add_core(unsigned sbits, unsigned ebits, expr_ref & rm,
 | 
			
		||||
        expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp,
 | 
			
		||||
| 
						 | 
				
			
			@ -146,11 +147,11 @@ protected:
 | 
			
		|||
class fpa2bv_model_converter : public model_converter {
 | 
			
		||||
    ast_manager               & m;
 | 
			
		||||
    obj_map<func_decl, expr*>   m_const2bv;
 | 
			
		||||
	obj_map<func_decl, expr*>   m_rm_const2bv;
 | 
			
		||||
    obj_map<func_decl, expr*>   m_rm_const2bv;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    fpa2bv_model_converter(ast_manager & m, obj_map<func_decl, expr*> & const2bv,
 | 
			
		||||
		                                    obj_map<func_decl, expr*> & rm_const2bv) : 
 | 
			
		||||
    fpa2bv_model_converter(ast_manager & m, obj_map<func_decl, expr*> const & const2bv,
 | 
			
		||||
                                            obj_map<func_decl, expr*> const & rm_const2bv) : 
 | 
			
		||||
      m(m) {
 | 
			
		||||
          // Just create a copy?
 | 
			
		||||
          for (obj_map<func_decl, expr*>::iterator it = const2bv.begin();
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +162,7 @@ public:
 | 
			
		|||
               m.inc_ref(it->m_key);
 | 
			
		||||
               m.inc_ref(it->m_value);
 | 
			
		||||
          }
 | 
			
		||||
		  for (obj_map<func_decl, expr*>::iterator it = rm_const2bv.begin();
 | 
			
		||||
          for (obj_map<func_decl, expr*>::iterator it = rm_const2bv.begin();
 | 
			
		||||
               it != rm_const2bv.end();
 | 
			
		||||
               it++) 
 | 
			
		||||
          {
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +174,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    virtual ~fpa2bv_model_converter() {
 | 
			
		||||
        dec_ref_map_key_values(m, m_const2bv);
 | 
			
		||||
		dec_ref_map_key_values(m, m_rm_const2bv);
 | 
			
		||||
        dec_ref_map_key_values(m, m_rm_const2bv);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void operator()(model_ref & md, unsigned goal_idx) {
 | 
			
		||||
| 
						 | 
				
			
			@ -198,4 +199,9 @@ protected:
 | 
			
		|||
    void convert(model * bv_mdl, model * float_mdl);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
model_converter * mk_fpa2bv_model_converter(ast_manager & m, 
 | 
			
		||||
                                            obj_map<func_decl, expr*> const & const2bv,
 | 
			
		||||
                                            obj_map<func_decl, expr*> const & rm_const2bv);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
 | 
			
		|||
            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_sort(f->get_range())) {
 | 
			
		||||
            m_conv.mk_rm_const(f, result);
 | 
			
		||||
            return BR_DONE;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
 | 
			
		|||
            case OP_RM_NEAREST_TIES_TO_EVEN:
 | 
			
		||||
            case OP_RM_TOWARD_NEGATIVE:
 | 
			
		||||
            case OP_RM_TOWARD_POSITIVE:
 | 
			
		||||
			case OP_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE;            
 | 
			
		||||
            case OP_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE;            
 | 
			
		||||
            case OP_FLOAT_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE;                             
 | 
			
		||||
            case OP_FLOAT_PLUS_INF: m_conv.mk_plus_inf(f, result); return BR_DONE;
 | 
			
		||||
            case OP_FLOAT_MINUS_INF: m_conv.mk_minus_inf(f, result); return BR_DONE;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ class fpa2bv_tactic : public tactic {
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            if (g->models_enabled())  
 | 
			
		||||
                mc = m_conv.mk_model_converter();
 | 
			
		||||
                mc = mk_fpa2bv_model_converter(m, m_conv.const2bv(), m_conv.rm_const2bv());
 | 
			
		||||
 | 
			
		||||
            g->inc_depth();
 | 
			
		||||
            result.push_back(g.get());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ static void find_le(heap_trie_t& ht, unsigned num_keys, unsigned const* keys) {
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void tst_heap_trie() {
 | 
			
		||||
    heap_trie_t ht;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,7 +253,7 @@ static void saturate_basis(hilbert_basis& hb) {
 | 
			
		|||
    case l_true:  
 | 
			
		||||
        std::cout << "sat\n"; 
 | 
			
		||||
        hb.display(std::cout);
 | 
			
		||||
        validate_sat(hb);
 | 
			
		||||
        //validate_sat(hb);
 | 
			
		||||
        break;
 | 
			
		||||
    case l_false: 
 | 
			
		||||
        std::cout << "unsat\n"; 
 | 
			
		||||
| 
						 | 
				
			
			@ -523,6 +523,9 @@ void tst_hilbert_basis() {
 | 
			
		|||
        tst4();
 | 
			
		||||
        tst4();
 | 
			
		||||
        tst4();
 | 
			
		||||
       tst4();
 | 
			
		||||
       tst4();
 | 
			
		||||
       tst4();
 | 
			
		||||
        tst5();
 | 
			
		||||
        tst6();
 | 
			
		||||
        tst7();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										213
									
								
								src/test/karr.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								src/test/karr.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,213 @@
 | 
			
		|||
#include "hilbert_basis.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Test generation of linear congruences a la Karr.
 | 
			
		||||
 | 
			
		||||
 */
 | 
			
		||||
namespace karr {
 | 
			
		||||
 | 
			
		||||
    struct matrix {
 | 
			
		||||
        vector<vector<rational> > A;
 | 
			
		||||
        vector<rational>          b;
 | 
			
		||||
        
 | 
			
		||||
        unsigned size() const { return A.size(); }
 | 
			
		||||
 | 
			
		||||
        void reset() { 
 | 
			
		||||
            A.reset(); 
 | 
			
		||||
            b.reset(); 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        matrix& operator=(matrix const& other) {
 | 
			
		||||
            reset();
 | 
			
		||||
            append(other);
 | 
			
		||||
            return *this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void append(matrix const& other) {
 | 
			
		||||
            A.append(other.A);
 | 
			
		||||
            b.append(other.b);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void display(std::ostream& out) {
 | 
			
		||||
            for (unsigned i = 0; i < A.size(); ++i) {
 | 
			
		||||
                for (unsigned j = 0; j < A[i].size(); ++j) {
 | 
			
		||||
                    out << A[i][j] << " ";
 | 
			
		||||
                }
 | 
			
		||||
                out << " = " << -b[i] << "\n";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // treat src as a homogeneous matrix.
 | 
			
		||||
    void dualizeH(matrix& dst, matrix const& src) {
 | 
			
		||||
        hilbert_basis hb;
 | 
			
		||||
        for (unsigned i = 0; i < src.size(); ++i) {
 | 
			
		||||
            vector<rational> v(src.A[i]);
 | 
			
		||||
            v.append(src.b[i]);
 | 
			
		||||
            hb.add_eq(v, rational(0));
 | 
			
		||||
        }
 | 
			
		||||
        for (unsigned i = 0; i < 1 + src.A[0].size(); ++i) {
 | 
			
		||||
            hb.set_is_int(i);
 | 
			
		||||
        }
 | 
			
		||||
        lbool is_sat = hb.saturate();
 | 
			
		||||
        hb.display(std::cout);
 | 
			
		||||
        SASSERT(is_sat == l_true);
 | 
			
		||||
        dst.reset();
 | 
			
		||||
        unsigned basis_size = hb.get_basis_size();
 | 
			
		||||
        bool first_initial = true;
 | 
			
		||||
        for (unsigned i = 0; i < basis_size; ++i) {
 | 
			
		||||
            bool is_initial;
 | 
			
		||||
            vector<rational> soln;
 | 
			
		||||
            hb.get_basis_solution(i, soln, is_initial);
 | 
			
		||||
            if (!is_initial) {
 | 
			
		||||
                dst.b.push_back(soln.back());
 | 
			
		||||
                soln.pop_back();
 | 
			
		||||
                dst.A.push_back(soln);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // treat src as an inhomegeneous matrix.
 | 
			
		||||
    void dualizeI(matrix& dst, matrix const& src) {
 | 
			
		||||
        hilbert_basis hb;
 | 
			
		||||
        for (unsigned i = 0; i < src.size(); ++i) {
 | 
			
		||||
            hb.add_eq(src.A[i], -src.b[i]);
 | 
			
		||||
        }
 | 
			
		||||
        for (unsigned i = 0; i < src.A[0].size(); ++i) {
 | 
			
		||||
            hb.set_is_int(i);
 | 
			
		||||
        }
 | 
			
		||||
        lbool is_sat = hb.saturate();
 | 
			
		||||
        hb.display(std::cout);
 | 
			
		||||
        SASSERT(is_sat == l_true);
 | 
			
		||||
        dst.reset();
 | 
			
		||||
        unsigned basis_size = hb.get_basis_size();
 | 
			
		||||
        bool first_initial = true;
 | 
			
		||||
        for (unsigned i = 0; i < basis_size; ++i) {
 | 
			
		||||
            bool is_initial;
 | 
			
		||||
            vector<rational> soln;
 | 
			
		||||
            hb.get_basis_solution(i, soln, is_initial);
 | 
			
		||||
            if (is_initial && first_initial) {
 | 
			
		||||
                dst.A.push_back(soln);
 | 
			
		||||
                dst.b.push_back(rational(1));
 | 
			
		||||
                first_initial = false;
 | 
			
		||||
            }
 | 
			
		||||
            else if (!is_initial) {
 | 
			
		||||
                dst.A.push_back(soln);
 | 
			
		||||
                dst.b.push_back(rational(0));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void juxtapose(matrix& dst, matrix const& M, matrix const& N) {
 | 
			
		||||
        dst = M;
 | 
			
		||||
        dst.append(N);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void join(matrix& dst, matrix const& M, matrix const& N) {
 | 
			
		||||
        matrix MD, ND, dstD;
 | 
			
		||||
        dualizeI(MD, M);
 | 
			
		||||
        dualizeI(ND, N);
 | 
			
		||||
        juxtapose(dstD, MD, ND);
 | 
			
		||||
        dualizeH(dst, dstD);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void joinD(matrix& dst, matrix const& MD, matrix const& ND) {
 | 
			
		||||
        matrix dstD;
 | 
			
		||||
        juxtapose(dstD, MD, ND);
 | 
			
		||||
        dualizeH(dst, dstD);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void transition(
 | 
			
		||||
        matrix& dst,
 | 
			
		||||
        matrix const& src,
 | 
			
		||||
        matrix const& Ab) {
 | 
			
		||||
        matrix T;
 | 
			
		||||
        // length of rows in Ab are twice as long as
 | 
			
		||||
        // length of rows in src.
 | 
			
		||||
        SASSERT(2*src.A[0].size() == Ab.A[0].size());
 | 
			
		||||
        vector<rational> zeros;
 | 
			
		||||
        for (unsigned i = 0; i < src.A[0].size(); ++i) {
 | 
			
		||||
            zeros.push_back(rational(0));
 | 
			
		||||
        }
 | 
			
		||||
        for (unsigned i = 0; i < src.size(); ++i) {
 | 
			
		||||
            T.A.push_back(src.A[i]);
 | 
			
		||||
            T.A.back().append(zeros);            
 | 
			
		||||
        }
 | 
			
		||||
        T.b.append(src.b);
 | 
			
		||||
        T.append(Ab);
 | 
			
		||||
 | 
			
		||||
        T.display(std::cout << "T:\n");
 | 
			
		||||
        matrix TD;
 | 
			
		||||
        dualizeI(TD, T);
 | 
			
		||||
        TD.display(std::cout << "TD:\n");
 | 
			
		||||
        for (unsigned i = 0; i < TD.size(); ++i) {
 | 
			
		||||
            vector<rational> v;            
 | 
			
		||||
            v.append(src.size(), TD.A[i].c_ptr() + src.size());
 | 
			
		||||
            dst.A.push_back(v);
 | 
			
		||||
            dst.b.push_back(TD.b[i]);
 | 
			
		||||
        }
 | 
			
		||||
        dst.display(std::cout << "dst\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static vector<rational> V(int i, int j) {
 | 
			
		||||
        vector<rational> v;
 | 
			
		||||
        v.push_back(rational(i));
 | 
			
		||||
        v.push_back(rational(j));
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static vector<rational> V(int i, int j, int k, int l) {
 | 
			
		||||
        vector<rational> v;
 | 
			
		||||
        v.push_back(rational(i));
 | 
			
		||||
        v.push_back(rational(j));
 | 
			
		||||
        v.push_back(rational(k));
 | 
			
		||||
        v.push_back(rational(l));
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define R(_x_) rational(_x_)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    static void tst1() {
 | 
			
		||||
        matrix Theta;
 | 
			
		||||
        matrix Ab;
 | 
			
		||||
        
 | 
			
		||||
        // 
 | 
			
		||||
        Theta.A.push_back(V(1, 0));
 | 
			
		||||
        Theta.b.push_back(R(0));
 | 
			
		||||
        Theta.A.push_back(V(0, 1));
 | 
			
		||||
        Theta.b.push_back(R(-2));
 | 
			
		||||
 | 
			
		||||
        Theta.display(std::cout << "Theta\n");
 | 
			
		||||
 | 
			
		||||
        Ab.A.push_back(V(-1,  0, 1, 0));
 | 
			
		||||
        Ab.b.push_back(R(1));
 | 
			
		||||
        Ab.A.push_back(V(-1, -2, 0, 1));
 | 
			
		||||
        Ab.b.push_back(R(1));
 | 
			
		||||
 | 
			
		||||
        Ab.display(std::cout << "Ab\n");
 | 
			
		||||
 | 
			
		||||
        matrix ThetaD;
 | 
			
		||||
        dualizeI(ThetaD, Theta);
 | 
			
		||||
        ThetaD.display(std::cout);
 | 
			
		||||
 | 
			
		||||
        matrix t1D, e1;
 | 
			
		||||
        transition(t1D, Theta, Ab);
 | 
			
		||||
        joinD(e1, t1D, ThetaD);
 | 
			
		||||
 | 
			
		||||
        t1D.display(std::cout << "t1D\n");
 | 
			
		||||
        e1.display(std::cout << "e1\n");
 | 
			
		||||
 | 
			
		||||
        matrix t2D, e2;
 | 
			
		||||
        transition(t2D, e1, Ab);
 | 
			
		||||
        joinD(e2, t2D, ThetaD);
 | 
			
		||||
 | 
			
		||||
        t2D.display(std::cout << "t2D\n");
 | 
			
		||||
        e2.display(std::cout << "e2\n");        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void tst_karr() {
 | 
			
		||||
    karr::tst1();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -209,6 +209,7 @@ int main(int argc, char ** argv) {
 | 
			
		|||
    TST(rcf);
 | 
			
		||||
    TST(hilbert_basis);
 | 
			
		||||
    TST(heap_trie);
 | 
			
		||||
    TST(karr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void initialize_mam() {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,14 +117,14 @@ void hwf_manager::set(hwf & o, mpf_rounding_mode rm, char const * value) {
 | 
			
		|||
    std::string v(value);
 | 
			
		||||
    size_t e_pos = v.find('p');
 | 
			
		||||
    if (e_pos == std::string::npos) e_pos = v.find('P');
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    std::string f, e;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    f = (e_pos != std::string::npos) ? v.substr(0, e_pos) : v;
 | 
			
		||||
    e = (e_pos != std::string::npos) ? v.substr(e_pos+1) : "0";    
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    TRACE("mpf_dbg", tout << " f = " << f << " e = " << e << std::endl;);   
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    mpq q;    
 | 
			
		||||
    m_mpq_manager.set(q, f.c_str());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -132,14 +132,14 @@ void hwf_manager::set(hwf & o, mpf_rounding_mode rm, char const * value) {
 | 
			
		|||
    m_mpz_manager.set(ex, e.c_str());
 | 
			
		||||
 | 
			
		||||
    set(o, rm, q, ex);    
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    TRACE("mpf_dbg", tout << "set: res = " << to_string(o) << std::endl;);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hwf_manager::set(hwf & o, mpf_rounding_mode rm, mpq const & significand, mpz const & exponent) {
 | 
			
		||||
    // Assumption: this represents significand * 2^exponent.
 | 
			
		||||
    set_rounding_mode(rm);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    mpq sig; 
 | 
			
		||||
    m_mpq_manager.set(sig, significand);
 | 
			
		||||
    int64 exp = m_mpz_manager.get_int64(exponent);
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +349,7 @@ void hwf_manager::rem(hwf const & x, hwf const & y, hwf & o) {
 | 
			
		|||
    else 
 | 
			
		||||
        o.value = fmod(x.value, y.value);
 | 
			
		||||
 | 
			
		||||
// Here is an x87 alternative if the above makes problems; this may also be faster.
 | 
			
		||||
    // Here is an x87 alternative if the above makes problems; this may also be faster.
 | 
			
		||||
#if 0
 | 
			
		||||
    double xv = x.value;
 | 
			
		||||
    double yv = y.value;
 | 
			
		||||
| 
						 | 
				
			
			@ -434,7 +434,7 @@ void hwf_manager::display_smt2(std::ostream & out, hwf const & a, bool decimal)
 | 
			
		|||
void hwf_manager::to_rational(hwf const & x, unsynch_mpq_manager & qm, mpq & o) {
 | 
			
		||||
    SASSERT(is_normal(x) || is_denormal(x) || is_zero(x));
 | 
			
		||||
    scoped_mpz n(qm), d(qm);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (is_normal(x))
 | 
			
		||||
        qm.set(n, sig(x) | 0x0010000000000000ull);
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -466,7 +466,7 @@ bool hwf_manager::is_neg(hwf const & x) {
 | 
			
		|||
bool hwf_manager::is_pos(hwf const & x) {
 | 
			
		||||
    return !sgn(x) && !is_nan(x);
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
bool hwf_manager::is_nzero(hwf const & x) {
 | 
			
		||||
    return RAW(x.value) == 0x8000000000000000ull;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -581,20 +581,20 @@ void hwf_manager::mk_ninf(hwf & o) {
 | 
			
		|||
 | 
			
		||||
#ifdef _WINDOWS
 | 
			
		||||
#if defined(_AMD64_) || defined(_M_IA64)
 | 
			
		||||
  #ifdef USE_INTRINSICS
 | 
			
		||||
    #define SETRM(RM) _MM_SET_ROUNDING_MODE(RM)
 | 
			
		||||
  #else
 | 
			
		||||
    #define SETRM(RM) _controlfp_s(&sse2_state, RM, _MCW_RC); 
 | 
			
		||||
  #endif
 | 
			
		||||
#ifdef USE_INTRINSICS
 | 
			
		||||
#define SETRM(RM) _MM_SET_ROUNDING_MODE(RM)
 | 
			
		||||
#else
 | 
			
		||||
  #ifdef USE_INTRINSICS
 | 
			
		||||
    #define SETRM(RM) _MM_SET_ROUNDING_MODE(RM)
 | 
			
		||||
  #else
 | 
			
		||||
    #define SETRM(RM) __control87_2(RM, _MCW_RC, &x86_state, &sse2_state)
 | 
			
		||||
  #endif
 | 
			
		||||
#define SETRM(RM) _controlfp_s(&sse2_state, RM, _MCW_RC); 
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
  #define SETRM(RM) fesetround(RM)
 | 
			
		||||
#ifdef USE_INTRINSICS
 | 
			
		||||
#define SETRM(RM) _MM_SET_ROUNDING_MODE(RM)
 | 
			
		||||
#else
 | 
			
		||||
#define SETRM(RM) __control87_2(RM, _MCW_RC, &x86_state, &sse2_state)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#define SETRM(RM) fesetround(RM)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
unsigned hwf_manager::prev_power_of_two(hwf const & a) {
 | 
			
		||||
| 
						 | 
				
			
			@ -608,9 +608,28 @@ unsigned hwf_manager::prev_power_of_two(hwf const & a) {
 | 
			
		|||
 | 
			
		||||
void hwf_manager::set_rounding_mode(mpf_rounding_mode rm)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WINDOWS    
 | 
			
		||||
#ifdef _WINDOWS
 | 
			
		||||
#ifdef USE_INTRINSICS
 | 
			
		||||
    switch (rm) {
 | 
			
		||||
    case MPF_ROUND_NEAREST_TEVEN:             
 | 
			
		||||
    case MPF_ROUND_NEAREST_TEVEN:
 | 
			
		||||
        SETRM(_MM_ROUND_NEAREST);
 | 
			
		||||
        break;
 | 
			
		||||
    case MPF_ROUND_TOWARD_POSITIVE:
 | 
			
		||||
        SETRM(_MM_ROUND_UP);
 | 
			
		||||
        break;
 | 
			
		||||
    case MPF_ROUND_TOWARD_NEGATIVE:
 | 
			
		||||
        SETRM(_MM_ROUND_DOWN);
 | 
			
		||||
        break;
 | 
			
		||||
    case MPF_ROUND_TOWARD_ZERO:
 | 
			
		||||
        SETRM(_MM_ROUND_TOWARD_ZERO);
 | 
			
		||||
        break;
 | 
			
		||||
    case MPF_ROUND_NEAREST_TAWAY:
 | 
			
		||||
    default:
 | 
			
		||||
        UNREACHABLE(); // Note: MPF_ROUND_NEAREST_TAWAY is not supported by the hardware!
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    switch (rm) {
 | 
			
		||||
    case MPF_ROUND_NEAREST_TEVEN:
 | 
			
		||||
        SETRM(_RC_NEAR);
 | 
			
		||||
        break;
 | 
			
		||||
    case MPF_ROUND_TOWARD_POSITIVE:
 | 
			
		||||
| 
						 | 
				
			
			@ -626,6 +645,7 @@ void hwf_manager::set_rounding_mode(mpf_rounding_mode rm)
 | 
			
		|||
    default:
 | 
			
		||||
        UNREACHABLE(); // Note: MPF_ROUND_NEAREST_TAWAY is not supported by the hardware!
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#else // OSX/Linux
 | 
			
		||||
    switch (rm) {
 | 
			
		||||
    case MPF_ROUND_NEAREST_TEVEN:             
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -520,9 +520,8 @@ void mpf_manager::add_sub(mpf_rounding_mode rm, mpf const & x, mpf const & y, mp
 | 
			
		|||
        }
 | 
			
		||||
    }        
 | 
			
		||||
    else if (is_zero(x) && is_zero(y)) {
 | 
			
		||||
        if (sgn(x) && sgn_y)
 | 
			
		||||
            set(o, x);
 | 
			
		||||
        else if (rm == MPF_ROUND_TOWARD_NEGATIVE)
 | 
			
		||||
        if ((x.sign && sgn_y) || 
 | 
			
		||||
            ((rm == MPF_ROUND_TOWARD_NEGATIVE) && (x.sign != sgn_y)))
 | 
			
		||||
            mk_nzero(x.ebits, x.sbits, o);
 | 
			
		||||
        else
 | 
			
		||||
            mk_pzero(x.ebits, x.sbits, o);
 | 
			
		||||
| 
						 | 
				
			
			@ -627,29 +626,28 @@ void mpf_manager::mul(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf &
 | 
			
		|||
        if (is_zero(y))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else 
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, sgn(y), o);
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_pinf(y)) {
 | 
			
		||||
        if (is_zero(x))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, sgn(x), o);
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, x.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_ninf(x)) {
 | 
			
		||||
        if (is_zero(y))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else 
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, !sgn(y), o);
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, !y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_ninf(y)) {
 | 
			
		||||
        if (is_zero(x))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, !sgn(x), o);
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, !x.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_zero(x) || is_zero(y)) {
 | 
			
		||||
        set(o, x);
 | 
			
		||||
        o.sign = x.sign ^ y.sign;
 | 
			
		||||
        mk_zero(x.ebits, x.sbits, x.sign != y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        o.ebits = x.ebits;
 | 
			
		||||
| 
						 | 
				
			
			@ -699,31 +697,35 @@ void mpf_manager::div(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf &
 | 
			
		|||
        if (is_inf(y))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, sgn(y), o);
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_pinf(y)) {
 | 
			
		||||
        if (is_inf(x))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else 
 | 
			
		||||
            mk_zero(x.ebits, x.sbits, (x.sign ^ y.sign) == 1, o);        
 | 
			
		||||
            mk_zero(x.ebits, x.sbits, x.sign != y.sign, o);        
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_ninf(x)) {
 | 
			
		||||
        if (is_inf(y))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, !sgn(y), o);
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, !y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_ninf(y)) {
 | 
			
		||||
        if (is_inf(x))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else 
 | 
			
		||||
            mk_zero(x.ebits, x.sbits, (x.sign ^ y.sign) == 1, o);
 | 
			
		||||
            mk_zero(x.ebits, x.sbits, x.sign != y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_zero(y)) {
 | 
			
		||||
        if (is_zero(x))
 | 
			
		||||
            mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
        else
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, sgn(x), o);
 | 
			
		||||
            mk_inf(x.ebits, x.sbits, x.sign != y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_zero(x)) {
 | 
			
		||||
        // Special case to avoid problems with unpacking of zeros.
 | 
			
		||||
        mk_zero(x.ebits, x.sbits, x.sign != y.sign, o);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        o.ebits = x.ebits;
 | 
			
		||||
| 
						 | 
				
			
			@ -837,6 +839,10 @@ void mpf_manager::sqrt(mpf_rounding_mode rm, mpf const & x, mpf & o) {
 | 
			
		|||
        else
 | 
			
		||||
            mk_nzero(x.ebits, x.sbits, o);
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_pzero(x))
 | 
			
		||||
        mk_pzero(x.ebits, x.sbits, o);
 | 
			
		||||
    else if (is_nzero(x))
 | 
			
		||||
        mk_nzero(x.ebits, x.sbits, o);
 | 
			
		||||
    else {
 | 
			
		||||
        o.ebits = x.ebits;
 | 
			
		||||
        o.sbits = x.sbits;
 | 
			
		||||
| 
						 | 
				
			
			@ -933,7 +939,7 @@ void mpf_manager::rem(mpf const & x, mpf const & y, mpf & o) {
 | 
			
		|||
    else if (is_inf(y))
 | 
			
		||||
        set(o, x);
 | 
			
		||||
    else if (is_zero(x))
 | 
			
		||||
        set(o, x);
 | 
			
		||||
        mk_pzero(x.ebits, x.sbits, o);
 | 
			
		||||
    else if (is_zero(y))
 | 
			
		||||
        mk_nan(x.ebits, x.sbits, o);
 | 
			
		||||
    else {        
 | 
			
		||||
| 
						 | 
				
			
			@ -982,9 +988,9 @@ void mpf_manager::rem(mpf const & x, mpf const & y, mpf & o) {
 | 
			
		|||
void mpf_manager::maximum(mpf const & x, mpf const & y, mpf & o) {
 | 
			
		||||
    if (is_nan(x))
 | 
			
		||||
        set(o, y);
 | 
			
		||||
    else if (is_nan(y) || (sgn(y) && is_zero(x) && is_zero(y)))
 | 
			
		||||
        set(o, x);    
 | 
			
		||||
    else if (gt(x, y))
 | 
			
		||||
    else if (is_nan(y))
 | 
			
		||||
        set(o, x);
 | 
			
		||||
    else if (gt(x, y) || (is_zero(x) && is_nzero(y)))
 | 
			
		||||
        set(o, x);
 | 
			
		||||
    else
 | 
			
		||||
        set(o, y);
 | 
			
		||||
| 
						 | 
				
			
			@ -993,9 +999,9 @@ void mpf_manager::maximum(mpf const & x, mpf const & y, mpf & o) {
 | 
			
		|||
void mpf_manager::minimum(mpf const & x, mpf const & y, mpf & o) {
 | 
			
		||||
    if (is_nan(x))
 | 
			
		||||
        set(o, y);
 | 
			
		||||
    else if (is_nan(y) || (sgn(x) && is_zero(x) && is_zero(y)))
 | 
			
		||||
    else if (is_nan(y))
 | 
			
		||||
        set(o, x);
 | 
			
		||||
    else if (lt(x, y))
 | 
			
		||||
    else if (lt(x, y) || (is_nzero(x) && is_zero(y)))
 | 
			
		||||
        set(o, x);
 | 
			
		||||
    else
 | 
			
		||||
        set(o, y);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue