3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

more on polynorm

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-08-14 11:55:23 -07:00
parent 0fd94a033f
commit 6c5f7741b2
2 changed files with 110 additions and 1 deletions

View file

@ -2,6 +2,7 @@
#include "smt2parser.h"
#include "arith_decl_plugin.h"
#include "reg_decl_plugins.h"
#include "arith_rewriter.h"
#include "ast_pp.h"
@ -27,6 +28,114 @@ static char const* example1 = "(= (+ (- (* x x) (* 2 y)) y) 0)";
static char const* example2 = "(= (+ 4 3 (- (* x x) (* 2 y)) y) 0)";
class poly_nf {
expr_ref m_coefficient;
expr_ref_vector m_coefficients;
expr_ref_vector m_factors;
public:
poly_nf(ast_manager& m):
m_coefficient(m),
m_coefficients(m),
m_factors(m) {}
expr_ref& coefficient() { return m_coefficient; }
expr_ref_vector& coefficients() { return m_coefficients; }
expr_ref_vector& factors() { return m_factors; }
void reset() {
m_coefficient.reset();
m_coefficients.reset();
m_factors.reset();
}
};
class polynorm {
ast_manager& m;
arith_util m_arith;
arith_rewriter m_arith_rw;
th_rewriter m_rw;
public:
polynorm(ast_manager& m): m(m), m_arith(m), m_arith_rw(m), m_rw(m) {}
private:
expr_ref_vector mk_fresh_constants(unsigned num, sort* s) {
expr_ref_vector result(m);
for (unsigned i = 0; i < num; ++i) {
result.push_back(m.mk_fresh_const("fresh", s));
}
return result;
}
expr_ref_vector mk_fresh_reals(unsigned num) {
return mk_fresh_constants(num, m_arith.mk_real());
}
expr_ref mk_mul(unsigned num_args, expr* const* args) {
expr_ref result(m);
m_arith_rw.mk_mul(num_args, args, result);
return result;
}
void nf(expr_ref& term, obj_hashtable<expr>& constants, poly_nf& poly) {
expr_ref_vector& factors = poly.factors();
expr_ref_vector& coefficients = poly.coefficients();
expr_ref& coefficient = poly.coefficient();
m_rw(term);
if (m_arith.is_add(term)) {
factors.append(to_app(term)->get_num_args(), to_app(term)->get_args());
}
else {
factors.push_back(term);
}
for (unsigned i = 0; i < factors.size(); ++i) {
expr* f = factors[i].get();
unsigned num_args = 1;
expr* const* args = &f;
if (m_arith.is_mul(f)) {
num_args = to_app(f)->get_num_args();
args = to_app(f)->get_args();
}
for (unsigned j = 0; j < num_args; ++j) {
if (m_arith.is_numeral(args[j]) || constants.contains(args[j])) {
//consts.push_back(args[j]);
}
else {
// vars.push_back(args[j]);
}
// deal with the relevant corner cases.
}
#if 0
rational r;
if (m_arith.is_mul(f) && m_arith.is_numeral(to_app(f)->get_arg(0), r)) {
coefficients.push_back(r);
factors[i] = mk_mul(to_app(f)->get_num_args()-1, to_app(f)->get_args()+1);
}
else if (m_arith.is_numeral(f, r)) {
factors[i] = factors.back();
factors.pop_back();
SASSERT(coefficient.is_zero());
SASSERT(!r.is_zero());
coefficient = r;
--i; // repeat examining 'i'
}
else {
coefficients.push_back(rational(1));
}
#endif
}
TRACE("polynorm",
tout << mk_pp(coefficient, m) << "\n";
for (unsigned i = 0; i < factors.size(); ++i) {
tout << mk_pp(factors[i].get(), m) << " * " << mk_pp(coefficients[i].get(), m) << "\n";
});
}
};
// ast
/// sort : ast
/// func_decl : ast