z3-z3-4.13.0.src.muz.base.dl_rule_transformer.cpp Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
dl_rule_transformer.cpp
Abstract:
Author:
Krystof Hoder (t-khoder) 2010-09-20.
Revision History:
--*/
#include
#include
#include "muz/base/dl_context.h"
#include "muz/base/dl_rule_transformer.h"
#include "util/stopwatch.h"
namespace datalog {
rule_transformer::rule_transformer(context & ctx)
: m_context(ctx), m_rule_manager(m_context.get_rule_manager()), m_dirty(false) {
}
rule_transformer::~rule_transformer() {
reset();
}
void rule_transformer::reset() {
for (auto* p : m_plugins)
dealloc(p);
m_plugins.reset();
m_dirty = false;
}
void rule_transformer::cancel() {
for (auto* p : m_plugins)
p->cancel();
}
struct rule_transformer::plugin_comparator {
bool operator()(rule_transformer::plugin * p1, rule_transformer::plugin * p2) {
return p1->get_priority() > p2->get_priority();
}
};
void rule_transformer::ensure_ordered() {
if (m_dirty) {
std::sort(m_plugins.begin(), m_plugins.end(), plugin_comparator());
m_dirty = false;
}
}
void rule_transformer::register_plugin(plugin * p) {
m_plugins.push_back(p);
p->attach(*this);
m_dirty = true;
}
bool rule_transformer::operator()(rule_set & rules) {
ensure_ordered();
bool modified = false;
TRACE("dl_rule_transf",
tout<<"init:\n";
rules.display(tout);
);
scoped_ptr new_rules = alloc(rule_set, rules);
plugin_vector::iterator it = m_plugins.begin();
plugin_vector::iterator end = m_plugins.end();
for(; it!=end && !m_context.canceled(); ++it) {
plugin & p = **it;
IF_VERBOSE(1, verbose_stream() << "(transform " << typeid(p).name() << "...";);
stopwatch sw;
sw.start();
scoped_ptr new_rules1 = p(*new_rules);
sw.stop();
double sec = sw.get_seconds();
if (sec < 0.001) sec = 0.0;
if (!new_rules1) {
IF_VERBOSE(1, verbose_stream() << "no-op " << sec << "s)\n";);
continue;
}
if (p.can_destratify_negation() &&
!new_rules1->is_closed() &&
!new_rules1->close()) {
warning_msg("a rule transformation skipped "
"because it destratified negation");
new_rules1 = nullptr;
IF_VERBOSE(1, verbose_stream() << "no-op " << sec << "s)\n";);
continue;
}
modified = true;
new_rules = new_rules1.detach();
new_rules->ensure_closed();
IF_VERBOSE(1, verbose_stream() << new_rules->get_num_rules() << " rules " << sec << "s)\n";);
TRACE("dl_rule_transf",
tout << typeid(p).name()<<":\n";
new_rules->display(tout);
);
}
if (modified) {
rules.replace_rules(*new_rules);
}
return modified;
}
//------------------------------
//
//rule_transformer::plugin
//
//------------------------------
void rule_transformer::plugin::remove_duplicate_tails(app_ref_vector& tail, bool_vector& tail_neg)
{
//one set for positive and one for negative
obj_hashtable tail_apps[2];
unsigned i=0;
while(i