refactor(library/attribute_manager): introduce hierarchy of attribute classes
This commit is contained in:
parent
3974d798c8
commit
31f599e088
13 changed files with 271 additions and 219 deletions
|
|
@ -8,10 +8,10 @@ Author: Leonardo de Moura
|
|||
|
||||
namespace lean {
|
||||
void initialize_old_attributes() {
|
||||
register_prio_attribute("elim", "elimination rule that is eagerly applied by blast grinder");
|
||||
register_prio_attribute("intro!", "introduction rule that is eagerly applied by blast grinder");
|
||||
register_no_params_attribute("no_pattern", "do not consider terms containing this declaration in the pattern inference procedure");
|
||||
register_prio_attribute("forward", "forward chaining");
|
||||
register_attribute(prio_attribute("elim", "elimination rule that is eagerly applied by blast grinder"));
|
||||
register_attribute(prio_attribute("intro!", "introduction rule that is eagerly applied by blast grinder"));
|
||||
register_attribute(basic_attribute("no_pattern", "do not consider terms containing this declaration in the pattern inference procedure"));
|
||||
register_attribute(prio_attribute("forward", "forward chaining"));
|
||||
}
|
||||
void finalize_old_attributes() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,36 +7,51 @@ Author: Leonardo de Moura
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
#include "util/priority_queue.h"
|
||||
#include "util/sstream.h"
|
||||
#include "library/attribute_manager.h"
|
||||
#include "library/scoped_ext.h"
|
||||
|
||||
namespace lean {
|
||||
struct attribute_decl {
|
||||
std::string m_id;
|
||||
std::string m_descr;
|
||||
std::string m_token;
|
||||
set_attribute_proc m_on_set;
|
||||
};
|
||||
|
||||
static std::vector<attribute_decl> * g_attr_decls;
|
||||
static std::unordered_map<std::string, attribute_ptr> * g_attributes;
|
||||
static std::vector<pair<std::string, std::string>> * g_incomp = nullptr;
|
||||
|
||||
static std::string * g_key = nullptr;
|
||||
|
||||
void register_attribute(attribute_ptr attr) {
|
||||
lean_assert(!is_attribute(attr->get_name().c_str()));
|
||||
(*g_attributes)[attr->get_name()] = attr;
|
||||
}
|
||||
|
||||
bool is_attribute(std::string const & attr) {
|
||||
return g_attributes->find(attr) != g_attributes->end();
|
||||
}
|
||||
|
||||
[[ noreturn ]] void throw_unknown_attribute(std::string const & attr) {
|
||||
throw exception(sstream() << "unknown attribute '" << attr << "'");
|
||||
}
|
||||
|
||||
static attribute const & get_attribute(std::string const & attr) {
|
||||
auto it = g_attributes->find(attr);
|
||||
if (it != g_attributes->end())
|
||||
return *it->second;
|
||||
throw_unknown_attribute(attr);
|
||||
}
|
||||
|
||||
struct attr_record {
|
||||
name m_decl;
|
||||
list<unsigned> m_params;
|
||||
name m_decl;
|
||||
attr_data_ptr m_data;
|
||||
|
||||
attr_record() {}
|
||||
attr_record(name decl, list<unsigned> params):
|
||||
m_decl(decl), m_params(params) {}
|
||||
attr_record(name decl, attr_data_ptr data):
|
||||
m_decl(decl), m_data(data) {}
|
||||
|
||||
unsigned hash() const {
|
||||
unsigned h = m_decl.hash();
|
||||
for (unsigned p : m_params)
|
||||
h = ::lean::hash(h, p);
|
||||
if (m_data)
|
||||
h = ::lean::hash(h, m_data->hash());
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
|
@ -49,12 +64,12 @@ struct attr_record_cmp {
|
|||
};
|
||||
|
||||
struct attr_entry {
|
||||
name m_attr;
|
||||
unsigned m_prio;
|
||||
std::string m_attr;
|
||||
unsigned m_prio;
|
||||
attr_record m_record;
|
||||
|
||||
attr_entry() {}
|
||||
attr_entry(name attr, unsigned prio, attr_record record):
|
||||
attr_entry(std::string const & attr, unsigned prio, attr_record const & record):
|
||||
m_attr(attr), m_prio(prio), m_record(record) {}
|
||||
};
|
||||
|
||||
|
|
@ -76,102 +91,48 @@ struct attr_config {
|
|||
}
|
||||
static void write_entry(serializer & s, entry const & e) {
|
||||
s << e.m_attr << e.m_prio << e.m_record.m_decl;
|
||||
write_list(s, e.m_record.m_params);
|
||||
lean_assert(e.m_record.m_data);
|
||||
get_attribute(e.m_attr).write_entry(s, *e.m_record.m_data);
|
||||
}
|
||||
static entry read_entry(deserializer & d) {
|
||||
entry e;
|
||||
d >> e.m_attr >> e.m_prio >> e.m_record.m_decl;
|
||||
e.m_record.m_params = read_list<unsigned>(d);
|
||||
e.m_record.m_data = get_attribute(e.m_attr).read_entry(d);
|
||||
return e;
|
||||
}
|
||||
static optional<unsigned> get_fingerprint(entry const & e) {
|
||||
return optional<unsigned>(hash(hash(e.m_attr.hash(), e.m_record.hash()), e.m_prio));
|
||||
return optional<unsigned>(hash(hash(name(e.m_attr).hash(), e.m_record.hash()), e.m_prio));
|
||||
}
|
||||
};
|
||||
|
||||
template class scoped_ext<attr_config>;
|
||||
typedef scoped_ext<attr_config> attribute_ext;
|
||||
|
||||
bool is_attribute(char const * attr) {
|
||||
for (auto const & d : *g_attr_decls) {
|
||||
if (d.m_id == attr)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
static attr_records const & get_attr_records(environment const & env, std::string const & n) {
|
||||
if (auto state = attribute_ext::get_state(env).find(n))
|
||||
return *state;
|
||||
throw_unknown_attribute(n);
|
||||
}
|
||||
|
||||
void register_attribute(char const * attr, char const * descr, set_attribute_proc const & on_set) {
|
||||
lean_assert(!is_attribute(attr));
|
||||
g_attr_decls->push_back(attribute_decl {attr, descr, std::string("[") + attr, on_set});
|
||||
environment attribute::set_core(environment const & env, io_state const & ios, name const & n, attr_data_ptr data,
|
||||
bool persistent) const {
|
||||
return attribute_ext::add_entry(env, ios, attr_entry(m_id, LEAN_DEFAULT_PRIORITY, attr_record(n, data)), persistent);
|
||||
}
|
||||
|
||||
void register_no_params_attribute(char const * attr, char const * descr, set_no_params_attribute_proc const & on_set) {
|
||||
register_attribute(attr, descr,
|
||||
[=](environment const & env, io_state const & ios, name const & d, unsigned prio,
|
||||
list<unsigned> const & idxs, bool persistent) {
|
||||
if (prio != LEAN_DEFAULT_PRIORITY)
|
||||
throw exception(sstream() << "invalid [" << attr <<
|
||||
"] declaration, unexpected priority declaration");
|
||||
if (idxs)
|
||||
throw exception(sstream() << "invalid [" << attr <<
|
||||
"] declaration, unexpected parameter");
|
||||
return on_set(env, ios, d, persistent);
|
||||
});
|
||||
}
|
||||
void register_no_params_attribute(char const * attr, char const * descr) {
|
||||
register_no_params_attribute(attr, descr,
|
||||
[](environment const & env, io_state const &, name const &, bool) {
|
||||
return env;
|
||||
});
|
||||
environment basic_attribute::set(environment const & env, io_state const & ios, name const & n, bool persistent) const {
|
||||
auto env2 = set_core(env, ios, n, attr_data_ptr(new attr_data), persistent);
|
||||
if (m_on_set)
|
||||
env2 = m_on_set(env2, ios, n, persistent);
|
||||
return env2;
|
||||
}
|
||||
|
||||
void register_prio_attribute(char const * attr, char const * descr, set_prio_attribute_proc const & on_set) {
|
||||
register_attribute(attr, descr,
|
||||
[=](environment const & env, io_state const & ios, name const & d, unsigned prio,
|
||||
list<unsigned> const & idxs, bool persistent) {
|
||||
if (idxs)
|
||||
throw exception(sstream() << "invalid [" << attr <<
|
||||
"] declaration, unexpected parameter");
|
||||
return on_set(env, ios, d, prio, persistent);
|
||||
});
|
||||
}
|
||||
void register_prio_attribute(char const * attr, char const * descr) {
|
||||
register_prio_attribute(attr, descr,
|
||||
[=](environment const & env, io_state const &, name const &, unsigned, bool) {
|
||||
return env;
|
||||
});
|
||||
}
|
||||
|
||||
void register_opt_param_attribute(char const * attr, char const * descr, set_opt_param_attribute_proc const & on_set) {
|
||||
register_attribute(attr, descr,
|
||||
[=](environment const & env, io_state const & ios, name const & d, unsigned prio,
|
||||
list<unsigned> const & idxs, bool persistent) {
|
||||
if (prio != LEAN_DEFAULT_PRIORITY)
|
||||
throw exception(sstream() << "invalid [" << attr <<
|
||||
"] declaration, unexpected priority declaration");
|
||||
if (idxs && tail(idxs))
|
||||
throw exception(sstream() << "invalid [" << attr <<
|
||||
"] declaration, expected at most one parameter");
|
||||
return on_set(env, ios, d, head_opt(idxs), persistent);
|
||||
});
|
||||
}
|
||||
|
||||
void register_params_attribute(char const * attr, char const * descr, set_params_attribute_proc const & on_set) {
|
||||
register_attribute(attr, descr,
|
||||
[=](environment const & env, io_state const & ios, name const & d, unsigned prio,
|
||||
list<unsigned> const & idxs, bool persistent) {
|
||||
if (prio != LEAN_DEFAULT_PRIORITY)
|
||||
throw exception(sstream() << "invalid [" << attr <<
|
||||
"] declaration, unexpected priority declaration");
|
||||
return on_set(env, ios, d, idxs, persistent);
|
||||
});
|
||||
}
|
||||
void register_params_attribute(char const * attr, char const * descr) {
|
||||
register_params_attribute(attr, descr,
|
||||
[=](environment const & env, io_state const &, name const &,
|
||||
list<unsigned> const &, bool) {
|
||||
return env;
|
||||
});
|
||||
environment prio_attribute::set(environment const & env, io_state const & ios, name const & n, unsigned prio,
|
||||
bool persistent) const {
|
||||
auto env2 = attribute_ext::add_entry(env, ios, attr_entry(get_name(), prio, attr_record(n, attr_data_ptr(new attr_data))),
|
||||
persistent);
|
||||
if (m_on_set)
|
||||
env2 = m_on_set(env2, ios, n, prio, persistent);
|
||||
return env2;
|
||||
}
|
||||
|
||||
void register_incompatible(char const * attr1, char const * attr2) {
|
||||
|
|
@ -185,34 +146,34 @@ void register_incompatible(char const * attr1, char const * attr2) {
|
|||
}
|
||||
|
||||
void get_attributes(buffer<char const *> & r) {
|
||||
for (auto const & d : *g_attr_decls)
|
||||
r.push_back(d.m_id.c_str());
|
||||
for (auto const & p : *g_attributes) {
|
||||
r.push_back(p.second->get_name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void get_attribute_tokens(buffer<char const *> & r) {
|
||||
for (auto const & d : *g_attr_decls)
|
||||
r.push_back(d.m_token.c_str());
|
||||
for (auto const & p : *g_attributes) {
|
||||
r.push_back(p.second->get_token().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
char const * get_attribute_from_token(char const * tk) {
|
||||
for (auto const & d : *g_attr_decls) {
|
||||
if (d.m_token == tk)
|
||||
return d.m_id.c_str();
|
||||
if (*tk) {
|
||||
// skip '['
|
||||
if (is_attribute(tk + 1))
|
||||
return get_attribute(tk + 1).get_name().c_str();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char const * get_attribute_token(char const * attr) {
|
||||
for (auto const & d : *g_attr_decls) {
|
||||
if (d.m_id == attr)
|
||||
return d.m_token.c_str();
|
||||
}
|
||||
return nullptr;
|
||||
char const * get_attribute_token(char const * name) {
|
||||
return get_attribute(name).get_token().c_str();
|
||||
}
|
||||
|
||||
bool has_attribute(environment const & env, char const * attr, name const & d) {
|
||||
if (auto it = attribute_ext::get_state(env).find(attr))
|
||||
return it->contains(attr_record(d, list<unsigned>()));
|
||||
// attr_data_ptr is ignored by comparison
|
||||
return it->contains({d, {}});
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -226,40 +187,37 @@ priority_queue<name, name_quick_cmp> get_attribute_instances_by_prio(environment
|
|||
return q;
|
||||
}
|
||||
|
||||
[[ noreturn ]] void throw_unknown_attribute(name const & attr) {
|
||||
throw exception(sstream() << "unknown attribute '" << attr << "'");
|
||||
}
|
||||
|
||||
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
|
||||
name const & d, unsigned prio, list<unsigned> const & params, bool persistent) {
|
||||
for (auto const & decl : *g_attr_decls) {
|
||||
if (decl.m_id == attr) {
|
||||
auto env2 = attribute_ext::add_entry(env, ios, attr_entry(attr, prio, attr_record(d, params)), persistent);
|
||||
return decl.m_on_set(env2, ios, d, prio, params, persistent);
|
||||
}
|
||||
environment set_attribute(environment const & env, io_state const & ios, char const * name,
|
||||
lean::name const & d, unsigned prio, list<unsigned> const & params, bool persistent) {
|
||||
auto const & attr = get_attribute(name);
|
||||
if (auto prio_attr = dynamic_cast<prio_attribute const *>(&attr)) {
|
||||
lean_assert(!params);
|
||||
return prio_attr->set(env, ios, d, prio, persistent);
|
||||
}
|
||||
throw_unknown_attribute(attr);
|
||||
}
|
||||
|
||||
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
|
||||
name const & d, bool persistent) {
|
||||
return set_attribute(env, ios, attr, d, LEAN_DEFAULT_PRIORITY, list<unsigned>(), persistent);
|
||||
}
|
||||
|
||||
unsigned get_attribute_prio(environment const & env, name const & attr, name const & d) {
|
||||
if (auto it = attribute_ext::get_state(env).find(attr)) {
|
||||
optional<unsigned> prio = it->get_prio({d, list<unsigned>()});
|
||||
return prio ? *prio : LEAN_DEFAULT_PRIORITY;
|
||||
lean_assert(prio == LEAN_DEFAULT_PRIORITY);
|
||||
if (auto params_attr = dynamic_cast<unsigned_params_attribute const *>(&attr)) {
|
||||
return params_attr->set(env, ios, d, {params}, persistent);
|
||||
}
|
||||
throw_unknown_attribute(attr);
|
||||
lean_assert(!params);
|
||||
return set_attribute(env, ios, name, d, persistent);
|
||||
}
|
||||
|
||||
list<unsigned> get_attribute_params(environment const & env, name const & attr, name const & d) {
|
||||
if (auto it = attribute_ext::get_state(env).find(attr)) {
|
||||
if (auto record = it->get_key(attr_record {d, list<unsigned>()}))
|
||||
return record->m_params;
|
||||
}
|
||||
throw_unknown_attribute(attr);
|
||||
environment set_attribute(environment const & env, io_state const & ios, char const * name, lean::name const & d,
|
||||
bool persistent) {
|
||||
auto const & attr = get_attribute(name);
|
||||
lean_assert(dynamic_cast<basic_attribute const *>(&attr));
|
||||
return static_cast<basic_attribute const &>(attr).set(env, ios, d, persistent);
|
||||
}
|
||||
|
||||
unsigned get_attribute_prio(environment const & env, std::string const & attr, name const & d) {
|
||||
return get_attr_records(env, attr).get_prio({d, {}}).value();
|
||||
}
|
||||
|
||||
list<unsigned> get_attribute_params(environment const & env, std::string const & attr, name const & d) {
|
||||
auto record = get_attr_records(env, attr).get_key({d, {}});
|
||||
lean_assert(record);
|
||||
lean_assert(dynamic_cast<unsigned_params_attribute_data const *>(record->m_data.get()));
|
||||
return static_cast<unsigned_params_attribute_data const *>(record->m_data.get())->m_params;
|
||||
}
|
||||
|
||||
bool are_incompatible(char const * attr1, char const * attr2) {
|
||||
|
|
@ -271,7 +229,7 @@ bool are_incompatible(char const * attr1, char const * attr2) {
|
|||
}
|
||||
|
||||
void initialize_attribute_manager() {
|
||||
g_attr_decls = new std::vector<attribute_decl>();
|
||||
g_attributes = new std::unordered_map<std::string, attribute_ptr>;
|
||||
g_incomp = new std::vector<pair<std::string, std::string>>();
|
||||
g_key = new std::string("ATTR");
|
||||
attribute_ext::initialize();
|
||||
|
|
@ -281,6 +239,7 @@ void finalize_attribute_manager() {
|
|||
attribute_ext::finalize();
|
||||
delete g_key;
|
||||
delete g_incomp;
|
||||
delete g_attr_decls;
|
||||
delete g_attributes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,29 +14,130 @@ Author: Leonardo de Moura
|
|||
#endif
|
||||
|
||||
namespace lean {
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &, unsigned, list<unsigned> const &,
|
||||
bool)> set_attribute_proc;
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &,
|
||||
bool)> set_no_params_attribute_proc;
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &,
|
||||
unsigned, bool)> set_prio_attribute_proc;
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &,
|
||||
optional<unsigned> const &, bool)> set_opt_param_attribute_proc;
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &, list<unsigned> const &,
|
||||
bool)> set_params_attribute_proc;
|
||||
|
||||
void register_attribute(char const * attr, char const * descr, set_attribute_proc const & on_set);
|
||||
void register_no_params_attribute(char const * attr, char const * descr, set_no_params_attribute_proc const & on_set);
|
||||
void register_no_params_attribute(char const * attr, char const * descr);
|
||||
void register_prio_attribute(char const * attr, char const * descr, set_prio_attribute_proc const & on_set);
|
||||
void register_prio_attribute(char const * attr, char const * descr);
|
||||
void register_opt_param_attribute(char const * attr, char const * descr, set_opt_param_attribute_proc const & on_set);
|
||||
void register_params_attribute(char const * attr, char const * descr, set_params_attribute_proc const & on_set);
|
||||
void register_params_attribute(char const * attr, char const * descr);
|
||||
struct attr_data {
|
||||
virtual unsigned hash() const {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<attr_data> attr_data_ptr;
|
||||
struct attr_config;
|
||||
|
||||
class attribute {
|
||||
friend struct attr_config;
|
||||
private:
|
||||
std::string m_id;
|
||||
std::string m_descr;
|
||||
std::string m_token;
|
||||
protected:
|
||||
environment set_core(environment const &, io_state const &, name const &, attr_data_ptr, bool) const;
|
||||
virtual void write_entry(serializer &, attr_data const &) const = 0;
|
||||
virtual attr_data_ptr read_entry(deserializer &) const = 0;
|
||||
public:
|
||||
attribute(char const * id, char const * descr) : m_id(id), m_descr(descr), m_token(std::string("[") + id) {}
|
||||
std::string const & get_name() const { return m_id; }
|
||||
std::string const & get_token() const { return m_token; }
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<attribute const> attribute_ptr;
|
||||
|
||||
/** \brief An attribute without associated data or priority declaration */
|
||||
class basic_attribute : public attribute {
|
||||
public:
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &, bool)> on_set_proc;
|
||||
private:
|
||||
on_set_proc m_on_set;
|
||||
protected:
|
||||
virtual void write_entry(serializer &, attr_data const &) const override final {}
|
||||
virtual attr_data_ptr read_entry(deserializer &) const override final { return {}; }
|
||||
public:
|
||||
basic_attribute(char const * id, char const * descr, on_set_proc on_set) : attribute(id, descr),
|
||||
m_on_set(on_set) {}
|
||||
basic_attribute(char const * id, char const * descr) : basic_attribute(id, descr, {}) {}
|
||||
virtual environment set(environment const & env, io_state const & ios, name const & n, bool persistent) const;
|
||||
};
|
||||
|
||||
// TODO(sullrich): Let the attribute handle priority parsing itself by introducing a custom
|
||||
// syntax (something like [attr:prio]?)
|
||||
class prio_attribute : public attribute {
|
||||
public:
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &, unsigned, bool)> on_set_proc;
|
||||
private:
|
||||
on_set_proc m_on_set;
|
||||
protected:
|
||||
virtual void write_entry(serializer &, attr_data const &) const override final {}
|
||||
virtual attr_data_ptr read_entry(deserializer &) const override final { return {}; }
|
||||
public:
|
||||
prio_attribute(char const * id, char const * descr, on_set_proc on_set) : attribute(id, descr),
|
||||
m_on_set(on_set) {}
|
||||
prio_attribute(char const * id, char const * descr) : prio_attribute(id, descr, {}) {}
|
||||
virtual environment set(environment const & env, io_state const & ios, name const & n, unsigned prio,
|
||||
bool persistent) const;
|
||||
};
|
||||
|
||||
template<typename Data>
|
||||
class typed_attribute : public attribute {
|
||||
public:
|
||||
typedef std::function<environment(environment const &, io_state const &, name const &, Data const &, bool)>
|
||||
on_set_proc;
|
||||
private:
|
||||
on_set_proc m_on_set;
|
||||
protected:
|
||||
virtual void write_entry(serializer & s, attr_data const & data) const final override {
|
||||
lean_assert(dynamic_cast<Data const *>(&data));
|
||||
static_cast<Data const &>(data).write(s);
|
||||
}
|
||||
virtual attr_data_ptr read_entry(deserializer & d) const final override {
|
||||
auto data = new Data;
|
||||
data->read(d);
|
||||
return attr_data_ptr(data);
|
||||
}
|
||||
public:
|
||||
typed_attribute(char const * id, char const * descr, on_set_proc on_set) : attribute(id, descr),
|
||||
m_on_set(on_set) {}
|
||||
typed_attribute(char const * id, char const * descr) : typed_attribute(id, descr, {}) {}
|
||||
virtual environment set(environment const & env, io_state const & ios, name const & n, Data const & data, bool persistent) const {
|
||||
auto env2 = set_core(env, ios, n, std::unique_ptr<attr_data>(new Data(data)), persistent);
|
||||
if (m_on_set)
|
||||
env2 = m_on_set(env2, ios, n, data, persistent);
|
||||
return env2;
|
||||
}
|
||||
};
|
||||
|
||||
struct unsigned_params_attribute_data : public attr_data {
|
||||
list<unsigned> m_params;
|
||||
unsigned_params_attribute_data(list<unsigned> const & params) : m_params(params) {}
|
||||
unsigned_params_attribute_data() : unsigned_params_attribute_data(list<unsigned>()) {}
|
||||
|
||||
virtual unsigned hash() const override {
|
||||
unsigned h = 0;
|
||||
for (unsigned i : m_params)
|
||||
h = ::lean::hash(h, i);
|
||||
return h;
|
||||
}
|
||||
void write(serializer & s) const {
|
||||
write_list(s, m_params);
|
||||
}
|
||||
void read(deserializer & d) {
|
||||
m_params = read_list<unsigned>(d);
|
||||
}
|
||||
};
|
||||
|
||||
template class typed_attribute<unsigned_params_attribute_data>;
|
||||
typedef typed_attribute<unsigned_params_attribute_data> unsigned_params_attribute;
|
||||
|
||||
void register_attribute(attribute_ptr);
|
||||
|
||||
template<typename Attribute>
|
||||
void register_attribute(Attribute attr) {
|
||||
register_attribute(attribute_ptr(new Attribute(attr)));
|
||||
}
|
||||
|
||||
void register_incompatible(char const * attr1, char const * attr2);
|
||||
|
||||
bool is_attribute(char const * attr);
|
||||
// TODO(sullrich): all of these should become members of/return attribute or a subclass
|
||||
bool is_attribute(std::string const & attr);
|
||||
void get_attributes(buffer<char const *> &);
|
||||
void get_attribute_tokens(buffer<char const *> &);
|
||||
char const * get_attribute_from_token(char const * attr_token);
|
||||
|
|
@ -51,8 +152,8 @@ bool has_attribute(environment const & env, char const * attr, name const & d);
|
|||
void get_attribute_instances(environment const & env, name const & attr, buffer<name> &);
|
||||
priority_queue<name, name_quick_cmp> get_attribute_instances_by_prio(environment const & env, name const & attr);
|
||||
|
||||
unsigned get_attribute_prio(environment const & env, name const & attr, name const & d);
|
||||
list<unsigned> get_attribute_params(environment const & env, name const & attr, name const & d);
|
||||
unsigned get_attribute_prio(environment const & env, std::string const & attr, name const & d);
|
||||
list<unsigned> get_attribute_params(environment const & env, std::string const & attr, name const & d);
|
||||
|
||||
bool are_incompatible(char const * attr1, char const * attr2);
|
||||
|
||||
|
|
|
|||
|
|
@ -422,20 +422,17 @@ void initialize_class() {
|
|||
g_key = new std::string("class");
|
||||
class_ext::initialize();
|
||||
|
||||
register_no_params_attribute("class", "type class",
|
||||
[](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_class(env, d, persistent);
|
||||
});
|
||||
register_attribute(basic_attribute("class", "type class", [](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_class(env, d, persistent);
|
||||
}));
|
||||
|
||||
register_prio_attribute("instance", "type class instance",
|
||||
[](environment const & env, io_state const &, name const & d, unsigned prio, bool persistent) {
|
||||
return add_instance(env, d, prio, persistent);
|
||||
});
|
||||
register_attribute(prio_attribute("instance", "type class instance", [](environment const & env, io_state const &, name const & d, unsigned prio, bool persistent) {
|
||||
return add_instance(env, d, prio, persistent);
|
||||
}));
|
||||
|
||||
register_prio_attribute("trans_instance", "transitive type class instance",
|
||||
[](environment const & env, io_state const &, name const & d, unsigned prio, bool persistent) {
|
||||
return add_trans_instance(env, d, prio, persistent);
|
||||
});
|
||||
register_attribute(prio_attribute("trans_instance", "transitive type class instance", [](environment const & env, io_state const &, name const & d, unsigned prio, bool persistent) {
|
||||
return add_trans_instance(env, d, prio, persistent);
|
||||
}));
|
||||
}
|
||||
|
||||
void finalize_class() {
|
||||
|
|
|
|||
|
|
@ -49,11 +49,9 @@ bool has_constructor_hint(environment const & env, name const & d) {
|
|||
}
|
||||
|
||||
void initialize_normalize() {
|
||||
register_params_attribute("unfold", "unfold definition when the given positions are constructors");
|
||||
register_no_params_attribute("unfold_full",
|
||||
"instructs normalizer (and simplifier) that function application (f a_1 ... a_n) should be unfolded when it is fully applied");
|
||||
register_no_params_attribute("constructor",
|
||||
"instructs normalizer (and simplifier) that function application (f ...) should be unfolded when it is the major premise of a constructor like operator");
|
||||
register_attribute(unsigned_params_attribute("unfold", "unfold definition when the given positions are constructors"));
|
||||
register_attribute(basic_attribute("unfold_full", "instructs normalizer (and simplifier) that function application (f a_1 ... a_n) should be unfolded when it is fully applied"));
|
||||
register_attribute(basic_attribute("constructor", "instructs normalizer (and simplifier) that function application (f ...) should be unfolded when it is the major premise of a constructor like operator"));
|
||||
}
|
||||
|
||||
void finalize_normalize() {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ Author: Leonardo de Moura
|
|||
|
||||
namespace lean {
|
||||
void initialize_reducible() {
|
||||
register_no_params_attribute("reducible", "reducible");
|
||||
register_no_params_attribute("semireducible", "semireducible");
|
||||
register_no_params_attribute("irreducible", "irreducible");
|
||||
register_attribute(basic_attribute("reducible", "reducible"));
|
||||
register_attribute(basic_attribute("semireducible", "semireducible"));
|
||||
register_attribute(basic_attribute("irreducible", "irreducible"));
|
||||
|
||||
register_incompatible("reducible", "semireducible");
|
||||
register_incompatible("reducible", "irreducible");
|
||||
|
|
|
|||
|
|
@ -325,25 +325,21 @@ is_relation_pred mk_is_relation_pred(environment const & env) {
|
|||
void initialize_relation_manager() {
|
||||
g_key = new std::string("REL");
|
||||
rel_ext::initialize();
|
||||
register_no_params_attribute("refl", "reflexive relation",
|
||||
[](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_refl(env, d, persistent);
|
||||
});
|
||||
register_attribute(basic_attribute("refl", "reflexive relation", [](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_refl(env, d, persistent);
|
||||
}));
|
||||
|
||||
register_no_params_attribute("symm", "symmetric relation",
|
||||
[](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_symm(env, d, persistent);
|
||||
});
|
||||
register_attribute(basic_attribute("symm", "symmetric relation", [](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_symm(env, d, persistent);
|
||||
}));
|
||||
|
||||
register_no_params_attribute("trans", "transitive relation",
|
||||
[](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_trans(env, d, persistent);
|
||||
});
|
||||
register_attribute(basic_attribute("trans", "transitive relation", [](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_trans(env, d, persistent);
|
||||
}));
|
||||
|
||||
register_no_params_attribute("subst", "substitution",
|
||||
[](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_subst(env, d, persistent);
|
||||
});
|
||||
register_attribute(basic_attribute("subst", "substitution", [](environment const & env, io_state const &, name const & d, bool persistent) {
|
||||
return add_subst(env, d, persistent);
|
||||
}));
|
||||
}
|
||||
|
||||
void finalize_relation_manager() {
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ public:
|
|||
add_delayed_update([=](environment const & env, io_state const & ios) -> environment {
|
||||
return register_entry(env, ios, e);
|
||||
});
|
||||
|
||||
}
|
||||
static state const & get_state(environment const & env) {
|
||||
return get(env).m_state;
|
||||
|
|
|
|||
|
|
@ -132,15 +132,14 @@ vm_obj tactic_backward_lemmas_find(vm_obj const & lemmas, vm_obj const & h, vm_o
|
|||
|
||||
void initialize_backward_lemmas() {
|
||||
register_trace_class(name{"tactic", "back_chaining"});
|
||||
register_prio_attribute("intro", "introduction rule for backward chaining",
|
||||
[](environment const & env, io_state const & ios, name const & c, unsigned, bool) {
|
||||
aux_type_context ctx(env, ios.get_options());
|
||||
auto index = get_backward_target(ctx, c);
|
||||
if (!index || index->kind() != expr_kind::Constant)
|
||||
throw exception(sstream() << "invalid [intro] attribute for '" << c
|
||||
<< "', head symbol of resulting type must be a constant");
|
||||
return env;
|
||||
});
|
||||
register_attribute(prio_attribute("intro", "introduction rule for backward chaining", [](environment const & env, io_state const & ios, name const & c, unsigned, bool) {
|
||||
aux_type_context ctx(env, ios.get_options());
|
||||
auto index = get_backward_target(ctx, c);
|
||||
if (!index || index->kind() != expr_kind::Constant)
|
||||
throw exception(sstream() << "invalid [intro] attribute for '" << c
|
||||
<< "', head symbol of resulting type must be a constant");
|
||||
return env;
|
||||
}));
|
||||
DECLARE_VM_BUILTIN(name({"tactic", "mk_back_lemmas_core"}), tactic_mk_backward_lemmas);
|
||||
DECLARE_VM_BUILTIN(name({"tactic", "back_lemmas_insert_core"}), tactic_backward_lemmas_insert);
|
||||
DECLARE_VM_BUILTIN(name({"tactic", "back_lemmas_find"}), tactic_backward_lemmas_find);
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ void initialize_defeq_simp_lemmas() {
|
|||
|
||||
defeq_simp_lemmas_ext::initialize();
|
||||
|
||||
register_prio_attribute("defeq", "defeq simp lemma", add_defeq_simp_lemma);
|
||||
register_attribute(prio_attribute("defeq", "defeq simp lemma", add_defeq_simp_lemma));
|
||||
}
|
||||
|
||||
void finalize_defeq_simp_lemmas() {
|
||||
|
|
|
|||
|
|
@ -534,13 +534,13 @@ simp_lemmas get_simp_lemmas(type_context & tctx) {
|
|||
while (i > 0) {
|
||||
--i;
|
||||
tmp_type_context tmp_tctx(tctx);
|
||||
r = add_core(tmp_tctx, r, simp_lemmas[i], get_attribute_prio(tctx.env(), get_simp_name(), simp_lemmas[i]));
|
||||
r = add_core(tmp_tctx, r, simp_lemmas[i], get_attribute_prio(tctx.env(), "simp", simp_lemmas[i]));
|
||||
}
|
||||
i = congr_lemmas.size();
|
||||
while (i > 0) {
|
||||
--i;
|
||||
tmp_type_context tmp_tctx(tctx);
|
||||
r = add_congr_core(tmp_tctx, r, congr_lemmas[i], get_attribute_prio(tctx.env(), get_congr_name(), congr_lemmas[i]));
|
||||
r = add_congr_core(tmp_tctx, r, congr_lemmas[i], get_attribute_prio(tctx.env(), "congr", congr_lemmas[i]));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
@ -586,8 +586,8 @@ void initialize_simp_lemmas() {
|
|||
DECLARE_VM_BUILTIN(name({"tactic", "mk_simp_lemmas_core"}), tactic_mk_simp_lemmas);
|
||||
DECLARE_VM_BUILTIN(name({"tactic", "simp_lemmas_insert_core"}), tactic_simp_lemmas_insert);
|
||||
|
||||
register_prio_attribute(get_simp_name().get_string(), "simplification lemma", on_add_simp_lemma);
|
||||
register_prio_attribute(get_congr_name().get_string(), "congruence lemma", on_add_congr_lemma);
|
||||
register_attribute(prio_attribute(get_simp_name().get_string(), "simplification lemma", on_add_simp_lemma));
|
||||
register_attribute(prio_attribute(get_congr_name().get_string(), "congruence lemma", on_add_congr_lemma));
|
||||
}
|
||||
|
||||
void finalize_simp_lemmas() {
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ void initialize_unification_hint() {
|
|||
|
||||
unification_hint_ext::initialize();
|
||||
|
||||
register_prio_attribute("unify", "unification hint", add_unification_hint);
|
||||
register_attribute(prio_attribute("unify", "unification hint", add_unification_hint));
|
||||
}
|
||||
|
||||
void finalize_unification_hint() {
|
||||
|
|
|
|||
|
|
@ -344,10 +344,11 @@ has_recursors_pred::has_recursors_pred(environment const & env):
|
|||
void initialize_user_recursors() {
|
||||
g_key = new std::string("UREC");
|
||||
recursor_ext::initialize();
|
||||
register_opt_param_attribute("recursor", "user defined recursor",
|
||||
[](environment const & env, io_state const &, name const & d, optional<unsigned> const & major, bool persistent) {
|
||||
return add_user_recursor(env, d, major, persistent);
|
||||
});
|
||||
register_attribute(unsigned_params_attribute("recursor", "user defined recursor", [](environment const & env, io_state const &, name const & n, unsigned_params_attribute_data const & data, bool persistent) {
|
||||
if (data.m_params && tail(data.m_params))
|
||||
throw exception(sstream() << "invalid [recursor] declaration, expected at most one parameter");
|
||||
return add_user_recursor(env, n, head_opt(data.m_params), persistent);
|
||||
}));
|
||||
}
|
||||
|
||||
void finalize_user_recursors() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue