3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

have sat cleaner use a fixed-point

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-01-10 11:38:35 -08:00
parent 9c318ed304
commit efaab6d8fd
4 changed files with 94 additions and 80 deletions

View file

@ -143,7 +143,77 @@ namespace datatype {
}
return r;
}
size* size::mk_power(size* a1, size* a2) { return alloc(power, a1, a2); }
size* size::mk_power(size* a1, size* a2) {
return alloc(power, a1, a2);
}
sort_size plus::eval(obj_map<sort, sort_size> const& S) {
rational r(0);
ptr_vector<size> todo;
todo.push_back(m_arg1);
todo.push_back(m_arg2);
while (!todo.empty()) {
size* s = todo.back();
todo.pop_back();
plus* p = dynamic_cast<plus*>(s);
if (p) {
todo.push_back(p->m_arg1);
todo.push_back(p->m_arg2);
}
else {
sort_size sz = s->eval(S);
if (sz.is_infinite()) return sz;
if (sz.is_very_big()) return sz;
r += rational(sz.size(), rational::ui64());
}
}
return sort_size(r);
}
size* plus::subst(obj_map<sort,size*>& S) {
return mk_plus(m_arg1->subst(S), m_arg2->subst(S));
}
sort_size times::eval(obj_map<sort, sort_size> const& S) {
sort_size s1 = m_arg1->eval(S);
sort_size s2 = m_arg2->eval(S);
if (s1.is_infinite()) return s1;
if (s2.is_infinite()) return s2;
if (s1.is_very_big()) return s1;
if (s2.is_very_big()) return s2;
rational r = rational(s1.size(), rational::ui64()) * rational(s2.size(), rational::ui64());
return sort_size(r);
}
size* times::subst(obj_map<sort,size*>& S) {
return mk_times(m_arg1->subst(S), m_arg2->subst(S));
}
sort_size power::eval(obj_map<sort, sort_size> const& S) {
sort_size s1 = m_arg1->eval(S);
sort_size s2 = m_arg2->eval(S);
// s1^s2
if (s1.is_infinite()) return s1;
if (s2.is_infinite()) return s2;
if (s1.is_very_big()) return s1;
if (s2.is_very_big()) return s2;
if (s1.size() == 1) return s1;
if (s2.size() == 1) return s1;
if (s1.size() > (2 << 20) || s2.size() > 10) return sort_size::mk_very_big();
rational r = ::power(rational(s1.size(), rational::ui64()), static_cast<unsigned>(s2.size()));
return sort_size(r);
}
size* power::subst(obj_map<sort,size*>& S) {
return mk_power(m_arg1->subst(S), m_arg2->subst(S));
}
size* sparam::subst(obj_map<sort, size*>& S) {
return S[m_param];
}
}
namespace decl {
@ -667,7 +737,7 @@ namespace datatype {
continue;
}
ptr_vector<param_size::size> s_add;
ptr_vector<param_size::size> s_add;
for (constructor const* c : d) {
ptr_vector<param_size::size> s_mul;
for (accessor const* a : *c) {

View file

@ -132,71 +132,28 @@ namespace datatype {
size* m_arg1, *m_arg2;
plus(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref();}
~plus() override { m_arg1->dec_ref(); m_arg2->dec_ref(); }
size* subst(obj_map<sort,size*>& S) override { return mk_plus(m_arg1->subst(S), m_arg2->subst(S)); }
sort_size eval(obj_map<sort, sort_size> const& S) override {
rational r(0);
ptr_vector<size> todo;
todo.push_back(m_arg1);
todo.push_back(m_arg2);
while (!todo.empty()) {
size* s = todo.back();
todo.pop_back();
plus* p = dynamic_cast<plus*>(s);
if (p) {
todo.push_back(p->m_arg1);
todo.push_back(p->m_arg2);
}
else {
sort_size sz = s->eval(S);
if (sz.is_infinite()) return sz;
if (sz.is_very_big()) return sz;
r += rational(sz.size(), rational::ui64());
}
}
return sort_size(r);
}
size* subst(obj_map<sort,size*>& S) override;
sort_size eval(obj_map<sort, sort_size> const& S) override;
};
struct times : public size {
size* m_arg1, *m_arg2;
times(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); }
~times() override { m_arg1->dec_ref(); m_arg2->dec_ref(); }
size* subst(obj_map<sort,size*>& S) override { return mk_times(m_arg1->subst(S), m_arg2->subst(S)); }
sort_size eval(obj_map<sort, sort_size> const& S) override {
sort_size s1 = m_arg1->eval(S);
sort_size s2 = m_arg2->eval(S);
if (s1.is_infinite()) return s1;
if (s2.is_infinite()) return s2;
if (s1.is_very_big()) return s1;
if (s2.is_very_big()) return s2;
rational r = rational(s1.size(), rational::ui64()) * rational(s2.size(), rational::ui64());
return sort_size(r);
}
size* subst(obj_map<sort,size*>& S) override;
sort_size eval(obj_map<sort, sort_size> const& S) override;
};
struct power : public size {
size* m_arg1, *m_arg2;
power(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); }
~power() override { m_arg1->dec_ref(); m_arg2->dec_ref(); }
size* subst(obj_map<sort,size*>& S) override { return mk_power(m_arg1->subst(S), m_arg2->subst(S)); }
sort_size eval(obj_map<sort, sort_size> const& S) override {
sort_size s1 = m_arg1->eval(S);
sort_size s2 = m_arg2->eval(S);
// s1^s2
if (s1.is_infinite()) return s1;
if (s2.is_infinite()) return s2;
if (s1.is_very_big()) return s1;
if (s2.is_very_big()) return s2;
if (s1.size() == 1) return s1;
if (s2.size() == 1) return s1;
if (s1.size() > (2 << 20) || s2.size() > 10) return sort_size::mk_very_big();
rational r = ::power(rational(s1.size(), rational::ui64()), static_cast<unsigned>(s2.size()));
return sort_size(r);
}
size* subst(obj_map<sort,size*>& S) override;
sort_size eval(obj_map<sort, sort_size> const& S) override;
};
struct sparam : public size {
sort_ref m_param;
sparam(sort_ref& p): m_param(p) {}
~sparam() override {}
size* subst(obj_map<sort,size*>& S) override { return S[m_param]; }
size* subst(obj_map<sort, size*>& S) override;
sort_size eval(obj_map<sort, sort_size> const& S) override { return S[m_param]; }
};
};