mirror of
https://github.com/Z3Prover/z3
synced 2025-05-09 00:35:47 +00:00
Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
3f9edad676
commit
e9eab22e5c
1186 changed files with 381859 additions and 0 deletions
241
lib/polynomial_cmds.cpp
Normal file
241
lib/polynomial_cmds.cpp
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
polynomial_cmds.cpp
|
||||
|
||||
Abstract:
|
||||
Commands for debugging polynomial module.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-12-23
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include<sstream>
|
||||
#include"cmd_context.h"
|
||||
#include"cmd_util.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"scoped_ctrl_c.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"expr2polynomial.h"
|
||||
#include"parametric_cmd.h"
|
||||
#include"mpq.h"
|
||||
#include"algebraic_numbers.h"
|
||||
#include"pp.h"
|
||||
#include"pp_params.h"
|
||||
#include"polynomial_var2value.h"
|
||||
#include"expr2var.h"
|
||||
|
||||
static void to_poly(cmd_context & ctx, expr * t) {
|
||||
polynomial::numeral_manager nm;
|
||||
polynomial::manager pm(nm);
|
||||
default_expr2polynomial expr2poly(ctx.m(), pm);
|
||||
polynomial::polynomial_ref p(pm);
|
||||
polynomial::scoped_numeral d(nm);
|
||||
if (!expr2poly.to_polynomial(t, p, d)) {
|
||||
throw cmd_exception("expression is not a polynomial");
|
||||
}
|
||||
expr_ref r(ctx.m());
|
||||
expr2poly.to_expr(p, true, r);
|
||||
if (!nm.is_one(d))
|
||||
ctx.regular_stream() << "(* " << nm.to_string(d) << " ";
|
||||
ctx.display(ctx.regular_stream(), r);
|
||||
if (!nm.is_one(d))
|
||||
ctx.regular_stream() << ")";
|
||||
ctx.regular_stream() << std::endl;
|
||||
}
|
||||
|
||||
static void factor(cmd_context & ctx, expr * t, polynomial::factor_params const & ps) {
|
||||
polynomial::numeral_manager nm;
|
||||
polynomial::manager pm(nm);
|
||||
default_expr2polynomial expr2poly(ctx.m(), pm);
|
||||
polynomial::polynomial_ref p(pm);
|
||||
polynomial::scoped_numeral d(nm);
|
||||
if (!expr2poly.to_polynomial(t, p, d)) {
|
||||
throw cmd_exception("expression is not a polynomial");
|
||||
}
|
||||
polynomial::factors fs(pm);
|
||||
factor(p, fs, ps);
|
||||
ctx.regular_stream() << "(factors";
|
||||
rational f0(fs.get_constant());
|
||||
f0 = f0 / rational(d);
|
||||
ctx.regular_stream() << std::endl << f0;
|
||||
unsigned num_factors = fs.distinct_factors();
|
||||
expr_ref f(ctx.m());
|
||||
for (unsigned i = 0; i < num_factors; i++) {
|
||||
ctx.regular_stream() << std::endl;
|
||||
if (fs.get_degree(i) > 1)
|
||||
ctx.regular_stream() << "(^ ";
|
||||
expr2poly.to_expr(fs[i], true, f);
|
||||
ctx.display(ctx.regular_stream(), f);
|
||||
if (fs.get_degree(i) > 1)
|
||||
ctx.regular_stream() << " " << fs.get_degree(i) << ")";
|
||||
}
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
class poly_isolate_roots_cmd : public cmd {
|
||||
struct context {
|
||||
arith_util m_util;
|
||||
unsynch_mpq_manager m_qm;
|
||||
polynomial::manager m_pm;
|
||||
algebraic_numbers::manager m_am;
|
||||
polynomial_ref m_p;
|
||||
default_expr2polynomial m_expr2poly;
|
||||
polynomial::var m_var;
|
||||
typedef polynomial::simple_var2value<algebraic_numbers::manager> x2v;
|
||||
x2v m_x2v;
|
||||
|
||||
context(ast_manager & m):
|
||||
m_util(m),
|
||||
m_pm(m_qm),
|
||||
m_am(m_qm),
|
||||
m_p(m_pm),
|
||||
m_expr2poly(m, m_pm),
|
||||
m_var(polynomial::null_var),
|
||||
m_x2v(m_am) {
|
||||
}
|
||||
|
||||
void set_next_arg(cmd_context & ctx, expr * arg) {
|
||||
if (m_p.get() == 0) {
|
||||
scoped_mpz d(m_qm);
|
||||
if (!m_expr2poly.to_polynomial(arg, m_p, d))
|
||||
throw cmd_exception("expression is not a polynomial");
|
||||
}
|
||||
else if (m_var == polynomial::null_var) {
|
||||
if (!m_expr2poly.is_var(arg))
|
||||
throw cmd_exception("invalid assignment, argument is not a variable in the given polynomial");
|
||||
m_var = m_expr2poly.get_mapping().to_var(arg);
|
||||
}
|
||||
else {
|
||||
rational k;
|
||||
scoped_anum v(m_am);
|
||||
if (m_util.is_numeral(arg, k)) {
|
||||
m_am.set(v, k.to_mpq());
|
||||
}
|
||||
else if (m_util.is_irrational_algebraic_numeral(arg)) {
|
||||
m_am.set(v, m_util.to_irrational_algebraic_numeral(arg));
|
||||
}
|
||||
else {
|
||||
throw cmd_exception("invalid assignment, argument is not a value");
|
||||
}
|
||||
m_x2v.push_back(m_var, v);
|
||||
m_var = polynomial::null_var;
|
||||
}
|
||||
}
|
||||
|
||||
void execute(cmd_context & ctx) {
|
||||
if (m_p.get() == 0)
|
||||
throw cmd_exception("polynomial expected");
|
||||
polynomial::var_vector xs;
|
||||
m_pm.vars(m_p, xs);
|
||||
unsigned num_assigned = 0;
|
||||
for (unsigned i = 0; i < xs.size(); i++) {
|
||||
if (m_x2v.contains(xs[i]))
|
||||
num_assigned++;
|
||||
}
|
||||
if (num_assigned != xs.size() && num_assigned + 1 != xs.size())
|
||||
throw cmd_exception("given assignment is not sufficient to make the given polynomial univariate");
|
||||
scoped_anum_vector rs(m_am);
|
||||
m_am.isolate_roots(m_p, m_x2v, rs);
|
||||
ctx.regular_stream() << "(roots";
|
||||
for (unsigned i = 0; i < rs.size(); i++) {
|
||||
ctx.regular_stream() << std::endl;
|
||||
if (!get_pp_default_params().m_pp_decimal)
|
||||
m_am.display_root_smt2(ctx.regular_stream(), rs[i]);
|
||||
else
|
||||
m_am.display_decimal(ctx.regular_stream(), rs[i]);
|
||||
}
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
scoped_ptr<context> m_ctx;
|
||||
|
||||
public:
|
||||
poly_isolate_roots_cmd(char const * name = "poly/isolate-roots"):cmd(name), m_ctx(0) {}
|
||||
|
||||
virtual char const * get_usage() const { return "<term> (<term> <value>)*"; }
|
||||
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "isolate the roots a multivariate polynomial modulo an assignment"; }
|
||||
|
||||
virtual unsigned get_arity() const { return VAR_ARITY; }
|
||||
|
||||
virtual void prepare(cmd_context & ctx) {
|
||||
m_ctx = alloc(context, ctx.m());
|
||||
}
|
||||
|
||||
virtual void finalize(cmd_context & ctx) {
|
||||
m_ctx = 0;
|
||||
}
|
||||
|
||||
virtual void failure_cleanup(cmd_context & ctx) {
|
||||
m_ctx = 0;
|
||||
}
|
||||
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
return CPK_EXPR;
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, expr * arg) {
|
||||
m_ctx->set_next_arg(ctx, arg);
|
||||
}
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
m_ctx->execute(ctx);
|
||||
m_ctx = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
UNARY_CMD(to_poly_cmd, "to-poly", "<term>", "convert expression into sum-of-monomials form", CPK_EXPR, expr *, to_poly(ctx, arg););
|
||||
|
||||
class poly_factor_cmd : public parametric_cmd {
|
||||
expr * m_target;
|
||||
public:
|
||||
poly_factor_cmd(char const * name = "poly/factor"):parametric_cmd(name) {}
|
||||
|
||||
virtual char const * get_usage() const { return "<term> (<keyword> <value>)*"; }
|
||||
|
||||
virtual char const * get_main_descr() const {
|
||||
return "factor a polynomial";
|
||||
}
|
||||
|
||||
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
|
||||
polynomial::factor_params::get_param_descrs(p);
|
||||
}
|
||||
|
||||
virtual void prepare(cmd_context & ctx) {
|
||||
parametric_cmd::prepare(ctx);
|
||||
m_target = 0;
|
||||
}
|
||||
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
if (m_target == 0) return CPK_EXPR;
|
||||
return parametric_cmd::next_arg_kind(ctx);
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, expr * arg) {
|
||||
m_target = arg;
|
||||
}
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
polynomial::factor_params ps;
|
||||
ps.updt_params(m_params);
|
||||
factor(ctx, m_target, ps);
|
||||
}
|
||||
};
|
||||
|
||||
void install_polynomial_cmds(cmd_context & ctx) {
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
ctx.insert(alloc(to_poly_cmd));
|
||||
ctx.insert(alloc(poly_factor_cmd));
|
||||
ctx.insert(alloc(poly_isolate_roots_cmd));
|
||||
#endif
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue