refactor(library): add attribute manager

This commit is contained in:
Leonardo de Moura 2015-12-17 20:56:02 -08:00
parent 74366aa061
commit 45dbf76df9
22 changed files with 641 additions and 47 deletions

View file

@ -7,6 +7,7 @@ Author: Leonardo de Moura
#include <limits>
#include <utility>
#include "util/pair.h"
#include "library/attribute_manager.h"
#include "frontends/lean/token_table.h"
namespace lean {
@ -108,12 +109,9 @@ void init_token_table(token_table & t) {
{"theorem", "axiom", "axioms", "variable", "protected", "private", "reveal",
"definition", "example", "coercion", "abbreviation", "noncomputable",
"variables", "parameter", "parameters", "constant", "constants",
"[persistent]", "[visible]", "[instance]", "[trans_instance]", "[light",
"[none]", "[class]", "[coercion]", "[reducible]", "[irreducible]", "[semireducible]", "[quasireducible]",
"[simp]", "[congr]", "[parsing_only]", "[multiple_instances]", "[symm]", "[trans]", "[refl]", "[subst]", "[recursor",
"evaluate", "check", "eval", "[wf]", "[whnf]", "[priority", "[unfold_full]", "[unfold_hints]", "[intro]",
"[forward]", "[no_pattern]", "[constructor]", "[elim]", "[intro!]", "[unfold", "print",
"end", "namespace", "section", "prelude", "help",
"[visible]", "[none]", "[parsing_only]",
"evaluate", "check", "eval", "[wf]", "[whnf]", "[priority", "[unfold_hints]",
"print", "end", "namespace", "section", "prelude", "help",
"import", "inductive", "record", "structure", "module", "universe", "universes", "local",
"precedence", "reserve", "infixl", "infixr", "infix", "postfix", "prefix", "notation",
"tactic_infixl", "tactic_infixr", "tactic_infix", "tactic_postfix", "tactic_prefix", "tactic_notation",
@ -145,6 +143,11 @@ void init_token_table(token_table & t) {
++it2;
}
buffer<char const *> attrs;
get_attribute_tokens(attrs);
for (char const * attr : attrs)
t = add_command_token(t, attr);
auto it3 = aliases;
while (it3->first) {
t = add_token(t, it3->first, it3->second, 0);

View file

@ -149,7 +149,6 @@ tactic_notation tactic_notation
call call
calc calc
obtain obtain
persistent [persistent]
root _root_
fields fields
trust trust

View file

@ -39,16 +39,6 @@ void consume_until_end(parser & p) {
p.next();
}
bool parse_persistent(parser & p, bool & persistent) {
if (p.curr_is_token_or_id(get_persistent_tk())) {
p.next();
persistent = true;
return true;
} else {
return false;
}
}
void check_command_period_or_eof(parser const & p) {
if (!p.curr_is_command() && !p.curr_is_eof() && !p.curr_is_token(get_period_tk()) &&
!p.curr_is_script_block())

View file

@ -18,11 +18,6 @@ class parser;
/** \brief Consume tokes until 'end' token is consumed */
void consume_until_end(parser & p);
/** \brief Parse optional '[persistent]' modifier.
return true if it is was found, and paremeter \c persistent to true.
*/
bool parse_persistent(parser & p, bool & persistent);
/** \brief Throw and error if the current token is not a command, nor a '.', nor an end-of-file. */
void check_command_period_or_eof(parser const & p);
/** \brief Throw and error if the current token is not a command, nor an open binder, nor a '.', nor an end-of-file. */

View file

@ -18,4 +18,5 @@ add_library(library OBJECT deep_copy.cpp expr_lt.cpp io_state.cpp
aux_recursors.cpp norm_num.cpp decl_stats.cpp meng_paulson.cpp
norm_num.cpp class_instance_resolution.cpp type_context.cpp
tmp_type_context.cpp fun_info_manager.cpp congr_lemma_manager.cpp
abstract_expr_manager.cpp light_lt_manager.cpp trace.cpp)
abstract_expr_manager.cpp light_lt_manager.cpp trace.cpp
attribute_manager.cpp)

View file

@ -0,0 +1,312 @@
/*
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include <vector>
#include <string>
#include <algorithm>
#include "util/sstream.h"
#include "library/attribute_manager.h"
namespace lean {
struct attribute_decl {
std::string m_id;
std::string m_descr;
std::string m_token;
has_attribute_proc m_tester;
};
struct default_attribute_decl : public attribute_decl {
set_attribute_proc m_setter;
};
struct prioritized_attribute_decl : public attribute_decl {
set_prio_attribute_proc m_setter;
get_attribute_prio_proc m_getter;
};
struct param_attribute_decl : public attribute_decl {
set_param_attribute_proc m_setter;
get_attribute_param_proc m_getter;
};
struct opt_param_attribute_decl : public attribute_decl {
set_opt_param_attribute_proc m_setter;
get_attribute_param_proc m_getter;
};
struct params_attribute_decl : public attribute_decl {
set_params_attribute_proc m_setter;
get_attribute_params_proc m_getter;
};
static std::vector<default_attribute_decl> * g_default_attrs = nullptr;
static std::vector<prioritized_attribute_decl> * g_prio_attrs = nullptr;
static std::vector<param_attribute_decl> * g_param_attrs = nullptr;
static std::vector<opt_param_attribute_decl> * g_opt_param_attrs = nullptr;
static std::vector<params_attribute_decl> * g_params_attrs = nullptr;
static std::vector<pair<std::string, std::string>> * g_incomp = nullptr;
template<typename Decls>
bool is_attribute(Decls const & decls, char const * attr) {
for (auto const & d : decls) {
if (d.m_id == attr)
return true;
}
return false;
}
bool is_attribute(char const * attr) {
return
is_attribute(*g_default_attrs, attr) ||
is_attribute(*g_prio_attrs, attr) ||
is_attribute(*g_param_attrs, attr) ||
is_attribute(*g_opt_param_attrs, attr) ||
is_attribute(*g_params_attrs, attr);
}
template<typename Decl, typename Setter, typename Tester>
void set_core_fields(Decl & decl, char const * attr, char const * descr, Setter const & setter, Tester const & tester) {
decl.m_id = attr;
decl.m_descr = descr;
decl.m_setter = setter;
decl.m_tester = tester;
}
void register_attribute(char const * attr, char const * descr, set_attribute_proc const & setter,
has_attribute_proc const & tester) {
lean_assert(!is_attribute(attr));
default_attribute_decl decl;
set_core_fields(decl, attr, descr, setter, tester);
decl.m_token = std::string("[") + attr + "]";
g_default_attrs->push_back(decl);
}
void register_prio_attribute(char const * attr, char const * descr, set_prio_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_prio_proc const & getter) {
lean_assert(!is_attribute(attr));
prioritized_attribute_decl decl;
set_core_fields(decl, attr, descr, setter, tester);
decl.m_token = std::string("[") + attr + "]";
decl.m_getter = getter;
g_prio_attrs->push_back(decl);
}
void register_param_attribute(char const * attr, char const * descr, set_param_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_param_proc const & getter) {
lean_assert(!is_attribute(attr));
param_attribute_decl decl;
set_core_fields(decl, attr, descr, setter, tester);
decl.m_token = std::string("[") + attr;
decl.m_getter = getter;
g_param_attrs->push_back(decl);
}
void register_opt_param_attribute(char const * attr, char const * descr, set_opt_param_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_param_proc const & getter) {
lean_assert(!is_attribute(attr));
opt_param_attribute_decl decl;
set_core_fields(decl, attr, descr, setter, tester);
decl.m_token = std::string("[") + attr;
decl.m_getter = getter;
g_opt_param_attrs->push_back(decl);
}
void register_params_attribute(char const * attr, char const * descr, set_params_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_params_proc const & getter) {
lean_assert(!is_attribute(attr));
params_attribute_decl decl;
set_core_fields(decl, attr, descr, setter, tester);
decl.m_token = std::string("[") + attr;
decl.m_getter = getter;
g_params_attrs->push_back(decl);
}
void register_incompatible(char const * attr1, char const * attr2) {
lean_assert(is_attribute(attr1));
lean_assert(is_attribute(attr2));
std::string s1(attr1);
std::string s2(attr2);
if (s1 > s2)
std::swap(s1, s2);
g_incomp->emplace_back(s1, s2);
}
template<typename Decls>
void get_attributes(Decls const & decls, buffer<char const *> & r) {
for (auto const & d : decls)
r.push_back(d.m_id.c_str());
}
void get_attributes(buffer<char const *> & r) {
get_attributes(*g_default_attrs, r);
get_attributes(*g_prio_attrs, r);
get_attributes(*g_param_attrs, r);
get_attributes(*g_opt_param_attrs, r);
get_attributes(*g_params_attrs, r);
}
template<typename Decls>
void get_attribute_tokens(Decls const & decls, buffer<char const *> & r) {
for (auto const & d : decls)
r.push_back(d.m_token.c_str());
}
void get_attribute_tokens(buffer<char const *> & r) {
get_attribute_tokens(*g_default_attrs, r);
get_attribute_tokens(*g_prio_attrs, r);
get_attribute_tokens(*g_param_attrs, r);
get_attribute_tokens(*g_opt_param_attrs, r);
get_attribute_tokens(*g_params_attrs, r);
}
template<typename Decls>
char const * get_attribute_from_token(Decls const & decls, char const * tk) {
for (auto const & d : decls) {
if (d.m_token == tk)
return d.m_id.c_str();
}
return nullptr;
}
char const * get_attribute_from_token(char const * tk) {
if (auto r = get_attribute_from_token(*g_default_attrs, tk)) return r;
if (auto r = get_attribute_from_token(*g_prio_attrs, tk)) return r;
if (auto r = get_attribute_from_token(*g_param_attrs, tk)) return r;
if (auto r = get_attribute_from_token(*g_opt_param_attrs, tk)) return r;
if (auto r = get_attribute_from_token(*g_params_attrs, tk)) return r;
return nullptr;
}
attribute_kind get_attribute_kind (char const * attr) {
lean_assert(is_attribute(attr));
if (is_attribute(*g_default_attrs, attr)) return attribute_kind::Default;
if (is_attribute(*g_prio_attrs, attr)) return attribute_kind::Prioritized;
if (is_attribute(*g_param_attrs, attr)) return attribute_kind::Parametric;
if (is_attribute(*g_opt_param_attrs, attr)) return attribute_kind::OptParametric;
if (is_attribute(*g_params_attrs, attr)) return attribute_kind::MultiParametric;
lean_unreachable();
}
template<typename Decls>
bool has_attribute(Decls const & decls, environment const & env, char const * attr, name const & d) {
for (auto const & decl : decls) {
if (decl.m_id == attr)
return decl.m_tester(env, d);
}
return false;
}
bool has_attribute(environment const & env, char const * attr, name const & d) {
return
has_attribute(*g_default_attrs, env, attr, d) ||
has_attribute(*g_prio_attrs, env, attr, d) ||
has_attribute(*g_param_attrs, env, attr, d) ||
has_attribute(*g_opt_param_attrs, env, attr, d) ||
has_attribute(*g_params_attrs, env, attr, d);
}
[[ noreturn ]] void throw_unknown_attribute(char const * attr) {
throw exception(sstream() << "unknown attribute '" << attr << "'");
}
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, name const & ns, bool persistent) {
for (auto const & decl : *g_default_attrs) {
if (decl.m_id == attr)
return decl.m_setter(env, ios, d, ns, persistent);
}
throw_unknown_attribute(attr);
}
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, unsigned prio, name const & ns, bool persistent) {
for (auto const & decl : *g_prio_attrs) {
if (decl.m_id == attr)
return decl.m_setter(env, ios, d, prio, ns, persistent);
}
throw_unknown_attribute(attr);
}
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, unsigned const & param, name const & ns, bool persistent) {
for (auto const & decl : *g_param_attrs) {
if (decl.m_id == attr)
return decl.m_setter(env, ios, d, param, ns, persistent);
}
throw_unknown_attribute(attr);
}
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, optional<unsigned> const & param, name const & ns, bool persistent) {
for (auto const & decl : *g_opt_param_attrs) {
if (decl.m_id == attr)
return decl.m_setter(env, ios, d, param, ns, persistent);
}
throw_unknown_attribute(attr);
}
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, list<unsigned> const & params, name const & ns, bool persistent) {
for (auto const & decl : *g_params_attrs) {
if (decl.m_id == attr)
return decl.m_setter(env, ios, d, params, ns, persistent);
}
throw_unknown_attribute(attr);
}
unsigned get_attribute_prio(environment const & env, char const * attr, name const & d) {
for (auto const & decl : *g_prio_attrs) {
if (decl.m_id == attr)
return decl.m_getter(env, d);
}
throw_unknown_attribute(attr);
}
unsigned get_attribute_param(environment const & env, char const * attr, name const & d) {
for (auto const & decl : *g_param_attrs) {
if (decl.m_id == attr)
return decl.m_getter(env, d);
}
for (auto const & decl : *g_opt_param_attrs) {
if (decl.m_id == attr)
return decl.m_getter(env, d);
}
throw_unknown_attribute(attr);
}
list<unsigned> get_attribute_params(environment const & env, char const * attr, name const & d) {
for (auto const & decl : *g_params_attrs) {
if (decl.m_id == attr)
return decl.m_getter(env, d);
}
throw_unknown_attribute(attr);
}
bool are_incompatible(char const * attr1, char const * attr2) {
std::string s1(attr1);
std::string s2(attr2);
if (s1 > s2)
std::swap(s1, s2);
return std::find(g_incomp->begin(), g_incomp->end(), mk_pair(s1, s2)) != g_incomp->end();
}
void initialize_attribute_manager() {
g_default_attrs = new std::vector<default_attribute_decl>();
g_prio_attrs = new std::vector<prioritized_attribute_decl>();
g_param_attrs = new std::vector<param_attribute_decl>();
g_opt_param_attrs = new std::vector<opt_param_attribute_decl>();
g_params_attrs = new std::vector<params_attribute_decl>();
g_incomp = new std::vector<pair<std::string, std::string>>();
}
void finalize_attribute_manager() {
delete g_default_attrs;
delete g_prio_attrs;
delete g_param_attrs;
delete g_opt_param_attrs;
delete g_params_attrs;
}
}

View file

@ -0,0 +1,73 @@
/*
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#pragma once
#include "kernel/environment.h"
#include "library/io_state.h"
#ifndef LEAN_DEFAULT_PRIORITY
#define LEAN_DEFAULT_PRIORITY 1000u
#endif
namespace lean {
typedef std::function<environment(environment const &, io_state const &, name const &,
name const &, bool)> set_attribute_proc;
typedef std::function<environment(environment const &, io_state const &, name const &,
unsigned, name const &, bool)> set_prio_attribute_proc;
typedef std::function<environment(environment const &, io_state const &, name const &,
unsigned const &, name const &, bool)> set_param_attribute_proc;
typedef std::function<environment(environment const &, io_state const &, name const &,
optional<unsigned> const &, name const &, bool)> set_opt_param_attribute_proc;
typedef std::function<environment(environment const &, io_state const &, name const &, list<unsigned> const &,
name const &, bool)> set_params_attribute_proc;
typedef std::function<bool(environment const &, name const &)> has_attribute_proc; // NOLINT
typedef std::function<unsigned(environment const &, name const &)> get_attribute_prio_proc;
typedef std::function<unsigned(environment const &, name const &)> get_attribute_param_proc;
typedef std::function<list<unsigned>(environment const &, name const &)> get_attribute_params_proc;
void register_attribute(char const * attr, char const * descr, set_attribute_proc const & setter,
has_attribute_proc const & tester);
void register_prio_attribute(char const * attr, char const * descr, set_prio_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_prio_proc const & getter);
void register_opt_param_attribute(char const * attr, char const * descr, set_opt_param_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_param_proc const & getter);
void register_param_attribute(char const * attr, char const * descr, set_param_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_param_proc const & getter);
void register_params_attribute(char const * attr, char const * descr, set_params_attribute_proc const & setter,
has_attribute_proc const & tester, get_attribute_params_proc const & getter);
void register_incompatible(char const * attr1, char const * attr2);
enum class attribute_kind { Default, Prioritized, Parametric, OptParametric, MultiParametric };
bool is_attribute(char 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);
attribute_kind get_attribute_kind (char const * attr);
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, name const & ns, bool persistent);
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, unsigned prio, name const & ns, bool persistent);
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, unsigned const & param, name const & ns, bool persistent);
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, optional<unsigned> const & param, name const & ns, bool persistent);
environment set_attribute(environment const & env, io_state const & ios, char const * attr,
name const & d, list<unsigned> const & params, name const & ns, bool persistent);
bool has_attribute(environment const & env, char const * attr, name const & d);
unsigned get_attribute_prio(environment const & env, char const * attr, name const & d);
unsigned get_attribute_param(environment const & env, char const * attr, name const & d);
list<unsigned> get_attribute_params(environment const & env, char const * attr, name const & d);
bool are_incompatible(char const * attr1, char const * attr2);
void initialize_attribute_manager();
void finalize_attribute_manager();
}

View file

@ -3,12 +3,13 @@ Copyright (c) 2015 Daniel Selsam. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Daniel Selsam
*/
#include "library/blast/backward/backward_rule_set.h"
#include <string>
#include "util/sstream.h"
#include "kernel/error_msgs.h"
#include "kernel/instantiate.h"
#include "library/scoped_ext.h"
#include <string>
#include "library/attribute_manager.h"
#include "library/blast/backward/backward_rule_set.h"
namespace lean {
@ -150,6 +151,15 @@ void initialize_backward_rule_set() {
g_class_name = new name("brs");
g_key = new std::string("brs");
brs_ext::initialize();
register_prio_attribute("intro", "backward chaining",
[](environment const & env, io_state const &, name const & d, unsigned prio, name const & ns, bool persistent) {
return add_backward_rule(env, d, prio, ns, persistent);
},
is_backward_rule,
[](environment const &, name const &) {
// TODO(Leo): fix it after we refactor backward_rule_set
return LEAN_DEFAULT_PRIORITY;
});
}
void finalize_backward_rule_set() {

View file

@ -6,6 +6,7 @@ Author: Leonardo de Moura
*/
#include <string>
#include "library/scoped_ext.h"
#include "library/attribute_manager.h"
#include "library/blast/forward/forward_lemma_set.h"
namespace lean {
@ -69,6 +70,18 @@ void initialize_forward_lemma_set() {
g_name = new name("forward");
g_key = new std::string("FWD");
forward_lemma_set_ext::initialize();
register_prio_attribute("forward", "forward chaining",
[](environment const & env, io_state const &, name const & d, unsigned prio, name const & ns, bool persistent) {
return add_forward_lemma(env, d, prio, ns, persistent);
},
is_forward_lemma,
[](environment const & env, name const & n) {
if (auto prio = get_forward_lemma_set(env).find(n))
return *prio;
else
return LEAN_DEFAULT_PRIORITY;
});
}
void finalize_forward_lemma_set() {

View file

@ -18,6 +18,7 @@ Author: Leonardo de Moura
#include "library/annotation.h"
#include "library/occurs.h"
#include "library/scoped_ext.h"
#include "library/attribute_manager.h"
#include "library/idx_metavar.h"
#include "library/blast/options.h"
#include "library/blast/blast.h"
@ -649,6 +650,12 @@ void initialize_pattern() {
no_pattern_ext::initialize();
g_pattern_hint = new name("pattern_hint");
register_annotation(*g_pattern_hint);
register_attribute("no_pattern", "do not consider terms containing this declaration in the pattern inference procedure",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_no_pattern(env, d, ns, persistent);
},
is_no_pattern);
}
void finalize_pattern() {

View file

@ -12,6 +12,7 @@ Author: Leonardo de Moura
#include "library/scoped_ext.h"
#include "library/user_recursors.h"
#include "library/tmp_type_context.h"
#include "library/attribute_manager.h"
#include "library/blast/blast.h"
#include "library/blast/grinder/intro_elim_lemmas.h"
@ -115,6 +116,26 @@ void initialize_intro_elim_lemmas() {
g_class_name = new name("grinder");
g_key = new std::string("grinder");
intro_elim_ext::initialize();
register_prio_attribute("elim", "elimination rule that is eagerly applied by blast grinder",
add_elim_lemma,
is_elim_lemma,
[](environment const & env, name const & d) {
if (auto p = intro_elim_ext::get_state(env).m_elim_lemmas.get_prio(d))
return *p;
else
return LEAN_DEFAULT_PRIORITY;
});
register_prio_attribute("intro!", "introduction rule that is eagerly applied by blast grinder",
add_intro_lemma,
is_intro_lemma,
[](environment const & env, name const & d) {
if (auto p = intro_elim_ext::get_state(env).m_intro_lemmas.get_prio(d))
return *p;
else
return LEAN_DEFAULT_PRIORITY;
});
}
void finalize_intro_elim_lemmas() {

View file

@ -5,16 +5,17 @@ Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include <string>
#include <vector>
#include "util/sstream.h"
#include "kernel/instantiate.h"
#include "kernel/find_fn.h"
#include "kernel/error_msgs.h"
#include "library/scoped_ext.h"
#include "library/expr_pair.h"
#include "library/attribute_manager.h"
#include "library/relation_manager.h"
#include "library/blast/simplifier/ceqv.h"
#include "library/blast/simplifier/simp_rule_set.h"
#include <vector>
namespace lean {
simp_rule_core::simp_rule_core(name const & id, levels const & umetas, list<expr> const & emetas,
@ -581,6 +582,25 @@ void initialize_simplifier_rule_set() {
g_class_name = new name("simps");
g_key = new std::string("simp");
rrs_ext::initialize();
register_prio_attribute("simp", "simplification rule",
[](environment const & env, io_state const &, name const & d, unsigned prio, name const & ns, bool persistent) {
return add_simp_rule(env, d, prio, ns, persistent);
},
is_simp_rule,
[](environment const &, name const &) {
// TODO(Leo): fix it after we refactor simp_rule_set
return LEAN_DEFAULT_PRIORITY;
});
register_prio_attribute("congr", "congruence rule",
[](environment const & env, io_state const &, name const & d, unsigned prio, name const & ns, bool persistent) {
return add_congr_rule(env, d, prio, ns, persistent);
},
is_congr_rule,
[](environment const &, name const &) {
// TODO(Leo): fix it after we refactor simp_rule_set
return LEAN_DEFAULT_PRIORITY;
});
}
void finalize_simplifier_rule_set() {

View file

@ -16,6 +16,7 @@ Author: Leonardo de Moura
#include "library/protected.h"
#include "library/class.h"
#include "library/decl_stats.h"
#include "library/attribute_manager.h"
#ifndef LEAN_INSTANCE_DEFAULT_PRIORITY
#define LEAN_INSTANCE_DEFAULT_PRIORITY 1000
@ -347,6 +348,14 @@ bool is_instance(environment const & env, name const & i) {
return s.is_instance(i);
}
unsigned get_instance_priority(environment const & env, name const & n) {
class_state const & s = class_ext::get_state(env);
class_state::instance_priorities insts = s.m_priorities;
if (auto r = insts.find(n))
return *r;
return LEAN_DEFAULT_PRIORITY;
}
name_predicate mk_class_pred(environment const & env) {
class_state const & s = class_ext::get_state(env);
class_state::class_instances cs = s.m_instances;
@ -477,6 +486,34 @@ void initialize_class() {
g_class_name = new name("classes");
g_key = new std::string("class");
class_ext::initialize();
register_attribute("class", "type class",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_class(env, d, ns, persistent);
},
is_class);
register_attribute("multiple_instances", "a type class where elaborator should consider multiple solutions",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return mark_multiple_instances(env, d, ns, persistent);
},
try_multiple_instances);
register_prio_attribute("instance", "type class instance",
[](environment const & env, io_state const &, name const & d, unsigned prio,
name const & ns, bool persistent) {
return add_instance(env, d, prio, ns, persistent);
},
is_instance,
get_instance_priority);
register_prio_attribute("trans_instance", "transitive type class instance",
[](environment const & env, io_state const &, name const & d, unsigned prio,
name const & ns, bool persistent) {
return add_trans_instance(env, d, prio, ns, persistent);
},
is_instance,
get_instance_priority);
}
void finalize_class() {

View file

@ -18,6 +18,7 @@ Author: Leonardo de Moura
#include "library/scoped_ext.h"
#include "library/pp_options.h"
#include "library/generic_exception.h"
#include "library/attribute_manager.h"
namespace lean {
static name * g_fun = nullptr;
@ -76,22 +77,6 @@ struct coercion_config {
template class scoped_ext<coercion_config>;
typedef scoped_ext<coercion_config> coercion_ext;
void initialize_coercion() {
g_fun = new name("_Fun");
g_sort = new name("_Sort");
g_class_name = new name("coercions");
g_key = new std::string("coerce");
coercion_ext::initialize();
}
void finalize_coercion() {
coercion_ext::finalize();
delete g_key;
delete g_class_name;
delete g_fun;
delete g_sort;
}
optional<pair<name, unsigned>> is_coercion(environment const & env, name const & f) {
coercion_state const & ext = coercion_ext::get_state(env);
if (auto it = ext.m_coercions.find(f))
@ -384,4 +369,25 @@ environment add_coercion(environment const & env, io_state const &, name const &
}
lean_unreachable(); // LCOV_EXCL_LINE
}
void initialize_coercion() {
g_fun = new name("_Fun");
g_sort = new name("_Sort");
g_class_name = new name("coercions");
g_key = new std::string("coerce");
coercion_ext::initialize();
register_attribute("coercion", "coercion",
[](environment const & env, io_state const & ios, name const & d, name const & ns, bool persistent) {
return add_coercion(env, ios, d, ns, persistent);
},
[](environment const & env, name const & n) { return static_cast<bool>(is_coercion(env, n)); });
}
void finalize_coercion() {
coercion_ext::finalize();
delete g_key;
delete g_class_name;
delete g_fun;
delete g_sort;
}
}

View file

@ -48,9 +48,11 @@ Author: Leonardo de Moura
#include "library/type_context.h"
#include "library/congr_lemma_manager.h"
#include "library/app_builder.h"
#include "library/attribute_manager.h"
namespace lean {
void initialize_library_module() {
initialize_attribute_manager();
initialize_trace();
initialize_constants();
initialize_fingerprint();
@ -142,5 +144,6 @@ void finalize_library_module() {
finalize_fingerprint();
finalize_constants();
finalize_trace();
finalize_attribute_manager();
}
}

View file

@ -3,14 +3,15 @@ Copyright (c) 2015 Daniel Selsam. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Daniel Selsam
*/
#include "library/light_lt_manager.h"
#include <string>
#include "util/sstream.h"
#include "util/name_set.h"
#include "util/safe_arith.h"
#include "kernel/error_msgs.h"
#include "kernel/instantiate.h"
#include "library/scoped_ext.h"
#include <string>
#include "library/attribute_manager.h"
#include "library/light_lt_manager.h"
namespace lean {
@ -193,6 +194,16 @@ void initialize_light_rule_set() {
g_class_name = new name("lrs");
g_key = new std::string("lrs");
lrs_ext::initialize();
register_param_attribute("light", "hint for simplifier",
[](environment const & env, io_state const &, name const & d, unsigned idx, name const & ns, bool persistent) {
return add_light_rule(env, d, idx, ns, persistent);
},
[](environment const & env, name const & n) { return static_cast<bool>(is_light_rule(env, n)); },
[](environment const & env, name const & n) {
auto r = is_light_rule(env, n);
lean_assert(r);
return *r;
});
}
void finalize_light_rule_set() {
@ -200,5 +211,4 @@ void finalize_light_rule_set() {
delete g_key;
delete g_class_name;
}
}

View file

@ -18,6 +18,7 @@ Author: Leonardo de Moura
#include "library/util.h"
#include "library/scoped_ext.h"
#include "library/kernel_serializer.h"
#include "library/attribute_manager.h"
namespace lean {
/**
@ -165,6 +166,26 @@ void initialize_normalize() {
g_unfold_hint_name = new name("unfold_hints");
g_key = new std::string("unfoldh");
unfold_hint_ext::initialize();
register_params_attribute("unfold", "unfold definition when the given positions are constructors",
[](environment const & env, io_state const &, name const & d, list<unsigned> const & idxs, name const & ns, bool persistent) {
return add_unfold_hint(env, d, idxs, ns, persistent);
},
[](environment const & env, name const & n) { return static_cast<bool>(has_unfold_hint(env, n)); },
[](environment const & env, name const & n) { return has_unfold_hint(env, n); });
register_attribute("unfold_full",
"instructs normalizer (and simplifier) that function application (f a_1 ... a_n) should be unfolded when it is fully applied",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_unfold_full_hint(env, d, ns, persistent);
},
has_unfold_full_hint);
register_attribute("constructor",
"instructs normalizer (and simplifier) that function application (f ...) should be unfolded when it is the major premise of a constructor like operator",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_constructor_hint(env, d, ns, persistent);
},
has_constructor_hint);
}
void finalize_normalize() {

View file

@ -53,7 +53,7 @@ list<unsigned> has_unfold_hint(environment const & env, name const & d);
environment add_unfold_full_hint(environment const & env, name const & n, name const & ns, bool persistent);
environment erase_unfold_full_hint(environment const & env, name const & n, name const & ns, bool persistent);
/** \brief Retrieve the hint added with the procedure add_unfold_full_hint. */
optional<unsigned> has_unfold_full_hint(environment const & env, name const & d);
bool has_unfold_full_hint(environment const & env, name const & d);
/** \brief unfold-m hint instructs normalizer (and simplifier) that function application
@ -61,7 +61,7 @@ optional<unsigned> has_unfold_full_hint(environment const & env, name const & d)
environment add_constructor_hint(environment const & env, name const & n, name const & ns, bool persistent);
environment erase_constructor_hint(environment const & env, name const & n, name const & ns, bool persistent);
/** \brief Retrieve the hint added with the procedure add_constructor_hint. */
optional<unsigned> has_constructor_hint(environment const & env, name const & d);
bool has_constructor_hint(environment const & env, name const & d);
expr try_eta(expr const & e);
expr beta_reduce(expr t);

View file

@ -12,6 +12,7 @@ Author: Leonardo de Moura
#include "library/scoped_ext.h"
#include "library/reducible.h"
#include "library/kernel_bindings.h"
#include "library/attribute_manager.h"
namespace lean {
struct reducible_entry {
@ -69,6 +70,37 @@ void initialize_reducible() {
g_key = new std::string("redu");
g_tmp_prefix = new name(name::mk_internal_unique_name());
reducible_ext::initialize();
register_attribute("reducible", "reducible",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return set_reducible(env, d, reducible_status::Reducible, ns, persistent);
},
[](environment const & env, name const & d) { return get_reducible_status(env, d) == reducible_status::Reducible; });
register_attribute("quasireducible", "quasireducible",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return set_reducible(env, d, reducible_status::Quasireducible, ns, persistent);
},
[](environment const & env, name const & d) { return get_reducible_status(env, d) == reducible_status::Quasireducible; });
register_attribute("semireducible", "semireducible",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return set_reducible(env, d, reducible_status::Semireducible, ns, persistent);
},
[](environment const & env, name const & d) { return get_reducible_status(env, d) == reducible_status::Semireducible; });
register_attribute("irreducible", "irreducible",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return set_reducible(env, d, reducible_status::Irreducible, ns, persistent);
},
[](environment const & env, name const & d) { return get_reducible_status(env, d) == reducible_status::Irreducible; });
register_incompatible("reducible", "quasireducible");
register_incompatible("reducible", "semireducible");
register_incompatible("reducible", "irreducible");
register_incompatible("quasireducible", "semireducible");
register_incompatible("quasireducible", "irreducible");
register_incompatible("semireducible", "irreducible");
}
void finalize_reducible() {

View file

@ -12,6 +12,7 @@ Author: Leonardo de Moura
#include "library/constants.h"
#include "library/scoped_ext.h"
#include "library/relation_manager.h"
#include "library/attribute_manager.h"
namespace lean {
// Check whether e is of the form (f ...) where f is a constant. If it is return f.
@ -329,6 +330,29 @@ void initialize_relation_manager() {
g_rel_name = new name("rel");
g_key = new std::string("rel");
rel_ext::initialize();
register_attribute("refl", "reflexive relation",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_refl(env, d, ns, persistent);
},
is_refl_relation);
register_attribute("symm", "symmetric relation",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_symm(env, d, ns, persistent);
},
is_symm_relation);
register_attribute("trans", "transitive relation",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_trans(env, d, ns, persistent);
},
is_trans_relation);
register_attribute("subst", "substitution",
[](environment const & env, io_state const &, name const & d, name const & ns, bool persistent) {
return add_subst(env, d, ns, persistent);
},
[](environment const & env, name const & n) { return static_cast<bool>(get_subst_extra_info(env, n)); });
}
void finalize_relation_manager() {

View file

@ -13,6 +13,7 @@ Author: Leonardo de Moura
#include "library/util.h"
#include "library/kernel_serializer.h"
#include "library/user_recursors.h"
#include "library/attribute_manager.h"
namespace lean {
bool recursor_info::is_minor(unsigned pos) const {
@ -346,6 +347,15 @@ void initialize_user_recursors() {
g_class_name = new name("recursor");
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, name const & ns, bool persistent) {
return add_user_recursor(env, d, major, ns, persistent);
},
is_user_defined_recursor,
[](environment const & env, name const & d) {
auto info = get_recursor_info(env, d);
return info.get_major_pos();
});
}
void finalize_user_recursors() {

View file

@ -56,6 +56,13 @@ public:
return m_key_to_pos.contains(k);
}
optional<unsigned> get_prio(K const & k) const {
if (auto p = m_key_to_pos.find(k))
return optional<unsigned>(p->first);
else
return optional<unsigned>();
}
void clear() {
m_key_to_pos.clear();
m_pos_to_key.clear();