chore(library): remove relation_manager

This commit is contained in:
Leonardo de Moura 2018-09-07 12:35:04 -07:00
parent 373e979a2a
commit c48eaed9a4
8 changed files with 14 additions and 537 deletions

View file

@ -215,20 +215,18 @@ intro :: (mp : a → b) (mpr : b → a)
infix = := eq
attribute [refl] eq.refl
@[pattern] def rfl {α : Sort u} {a : α} : a = a := eq.refl a
@[elab_as_eliminator, subst]
@[elab_as_eliminator]
theorem eq.subst {α : Sort u} {P : α → Prop} {a b : α} (h₁ : a = b) (h₂ : P a) : P b :=
eq.ndrec h₂ h₁
notation h1 ▸ h2 := eq.subst h1 h2
@[trans] theorem eq.trans {α : Sort u} {a b c : α} (h₁ : a = b) (h₂ : b = c) : a = c :=
theorem eq.trans {α : Sort u} {a b c : α} (h₁ : a = b) (h₂ : b = c) : a = c :=
h₂ ▸ h₁
@[symm] theorem eq.symm {α : Sort u} {a b : α} (h : a = b) : b = a :=
theorem eq.symm {α : Sort u} {a b : α} (h : a = b) : b = a :=
h ▸ rfl
infix == := heq
@ -627,7 +625,7 @@ notation x && y := band x y
def implies (a b : Prop) := a → b
@[trans] theorem implies.trans {p q r : Prop} (h₁ : implies p q) (h₂ : implies q r) : implies p r :=
theorem implies.trans {p q r : Prop} (h₁ : implies p q) (h₂ : implies q r) : implies p r :=
assume hp, h₂ (h₁ hp)
def trivial : true := ⟨⟩
@ -725,8 +723,6 @@ theorem eq_tt_of_ne_ff : ∀ {b : bool}, b ≠ ff → b = tt
| tt h := rfl
| ff h := false.elim (h rfl)
attribute [refl] heq.refl
section
variables {α β φ : Sort u} {a a' : α} {b b' : β} {c : φ}
@ -744,19 +740,19 @@ eq.rec_on (eq_of_heq h₁) h₂
theorem heq.subst {p : ∀ T : Sort u, T → Prop} (h₁ : a == b) (h₂ : p α a) : p β b :=
heq.ndrec_on h₁ h₂
@[symm] theorem heq.symm (h : a == b) : b == a :=
theorem heq.symm (h : a == b) : b == a :=
heq.ndrec_on h (heq.refl a)
theorem heq_of_eq (h : a = a') : a == a' :=
eq.subst h (heq.refl a)
@[trans] theorem heq.trans (h₁ : a == b) (h₂ : b == c) : a == c :=
theorem heq.trans (h₁ : a == b) (h₂ : b == c) : a == c :=
heq.subst h₂ h₁
@[trans] theorem heq_of_heq_of_eq (h₁ : a == b) (h₂ : b = b') : a == b' :=
theorem heq_of_heq_of_eq (h₁ : a == b) (h₂ : b = b') : a == b' :=
heq.trans h₁ (heq_of_eq h₂)
@[trans] theorem heq_of_eq_of_heq (h₁ : a = a') (h₂ : a' == b) : a == b :=
theorem heq_of_eq_of_heq (h₁ : a = a') (h₂ : a' == b) : a == b :=
heq.trans (heq_of_eq h₁) h₂
def type_eq_of_heq (h : a == b) : α = β :=
@ -820,20 +816,17 @@ theorem iff.elim_right : (a ↔ b) → b → a := iff.mpr
theorem iff_iff_implies_and_implies (a b : Prop) : (a ↔ b) ↔ (a → b) ∧ (b → a) :=
iff.intro (λ h, and.intro h.mp h.mpr) (λ h, iff.intro h.left h.right)
@[refl]
theorem iff.refl (a : Prop) : a ↔ a :=
iff.intro (assume h, h) (assume h, h)
theorem iff.rfl {a : Prop} : a ↔ a :=
iff.refl a
@[trans]
theorem iff.trans (h₁ : a ↔ b) (h₂ : b ↔ c) : a ↔ c :=
iff.intro
(assume ha, iff.mp h₂ (iff.mp h₁ ha))
(assume hc, iff.mpr h₁ (iff.mpr h₂ hc))
@[symm]
theorem iff.symm (h : a ↔ b) : b ↔ a :=
iff.intro (iff.elim_right h) (iff.elim_left h)
@ -1734,15 +1727,15 @@ instance setoid_has_equiv {α : Sort u} [setoid α] : has_equiv α :=
namespace setoid
variables {α : Sort u} [setoid α]
@[refl] theorem refl (a : α) : a ≈ a :=
theorem refl (a : α) : a ≈ a :=
match setoid.iseqv α with
| ⟨h_refl, h_symm, h_trans⟩ := h_refl a
@[symm] theorem symm {a b : α} (hab : a ≈ b) : b ≈ a :=
theorem symm {a b : α} (hab : a ≈ b) : b ≈ a :=
match setoid.iseqv α with
| ⟨h_refl, h_symm, h_trans⟩ := h_symm hab
@[trans] theorem trans {a b c : α} (hab : a ≈ b) (hbc : b ≈ c) : a ≈ c :=
theorem trans {a b c : α} (hab : a ≈ b) (hbc : b ≈ c) : a ≈ c :=
(match setoid.iseqv α with
| ⟨h_refl, h_symm, h_trans⟩ := h_trans hab hbc)
end setoid
@ -1787,7 +1780,7 @@ eq.subst (@iff_eq_eq a true) this
/- Quotients -/
-- iff can now be used to do substitutions in a calculation
@[subst] theorem iff_subst {a b : Prop} {p : Prop → Prop} (h₁ : a ↔ b) (h₂ : p a) : p b :=
theorem iff_subst {a b : Prop} {p : Prop → Prop} (h₁ : a ↔ b) (h₂ : p a) : p b :=
eq.subst (propext h₁) h₂
namespace quot

View file

@ -198,7 +198,7 @@ h₁ ◾ h₂ ◾ h₃ ◾ h₄ ◾ h₅ ◾ h₆
/- Inequalities -/
@[refl] protected def le_refl : ∀ n : nat, n ≤ n
protected def le_refl : ∀ n : nat, n ≤ n
| zero := rfl
| (succ n) := le_refl n

View file

@ -6,8 +6,7 @@ add_library(library OBJECT deep_copy.cpp expr_lt.cpp io_state.cpp
class.cpp util.cpp print.cpp annotation.cpp quote.cpp
protected.cpp reducible.cpp init_module.cpp
exception.cpp fingerprint.cpp pp_options.cpp
app_builder.cpp projection.cpp relation_manager.cpp
user_recursors.cpp idx_metavar.cpp noncomputable.cpp
app_builder.cpp projection.cpp user_recursors.cpp idx_metavar.cpp noncomputable.cpp
aux_recursors.cpp trace.cpp
attribute_manager.cpp local_context.cpp metavar_context.cpp type_context.cpp export_decl.cpp
fun_info.cpp replace_visitor_with_tc.cpp aux_definition.cpp pattern_attribute.cpp

View file

@ -13,7 +13,6 @@ Author: Leonardo de Moura
#include "library/constants.h"
#include "library/cache_helper.h"
#include "library/app_builder.h"
#include "library/relation_manager.h"
namespace lean {
static void trace_fun(name const & n) {
@ -414,26 +413,6 @@ public:
return mk_app(c, total_nargs, {a1, a2, a3});
}
/** \brief Similar to mk_app(n, lhs, rhs), but handles eq and iff more efficiently. */
expr mk_rel(name const & n, expr const & lhs, expr const & rhs) {
if (n == get_eq_name()) {
return mk_eq(lhs, rhs);
} else if (n == get_iff_name()) {
return mk_iff(lhs, rhs);
} else if (auto info = get_relation_info(env(), n)) {
buffer<bool> mask;
for (unsigned i = 0; i < info->get_arity(); i++) {
mask.push_back(i == info->get_lhs_pos() || i == info->get_rhs_pos());
}
expr args[2] = {lhs, rhs};
return mk_app(n, info->get_arity(), mask.data(), args);
} else {
// for unregistered relations assume lhs and rhs are the last two arguments.
expr args[2] = {lhs, rhs};
return mk_app(n, 2, args);
}
}
expr mk_eq(expr const & a, expr const & b) {
expr A = m_ctx.infer(a);
level lvl = get_level(A);
@ -459,8 +438,6 @@ public:
return mk_iff_refl(a);
} else if (relname == get_heq_name()) {
return mk_heq_refl(a);
} else if (auto info = get_refl_extra_info(env(), relname)) {
return mk_app(info->m_name, 1, &a);
} else {
lean_app_builder_trace(
tout() << "failed to build reflexivity proof, '" << relname
@ -490,8 +467,6 @@ public:
return mk_iff_symm(H);
} else if (relname == get_heq_name()) {
return mk_heq_symm(H);
} else if (auto info = get_symm_extra_info(env(), relname)) {
return mk_app(info->m_name, 1, &H);
} else {
lean_app_builder_trace(
tout() << "failed to build symmetry proof, '" << relname
@ -544,9 +519,6 @@ public:
return mk_iff_trans(H1, H2);
} else if (relname == get_heq_name()) {
return mk_heq_trans(H1, H2);
} else if (auto info = get_trans_extra_info(env(), relname, relname)) {
expr args[2] = {H1, H2};
return mk_app(info->m_name, 2, args);
} else {
lean_app_builder_trace(
tout() << "failed to build symmetry proof, '" << relname
@ -670,27 +642,6 @@ public:
return ::lean::mk_app({mk_constant(get_heq_of_eq_name(), {lvl}), A, a, b, H});
}
/** \brief Given a reflexive relation R, and a proof H : a = b,
build a proof for (R a b) */
expr lift_from_eq(name const & R, expr const & H) {
if (R == get_eq_name())
return H;
expr H_type = m_ctx.relaxed_whnf(m_ctx.infer(H));
// H_type : @eq A a b
expr A, a, b;
if (!is_eq(H_type, A, a, b)) {
lean_app_builder_trace(tout() << "failed to build lift_of_eq equality proof expected:\n" << H << "\n";);
throw app_builder_exception();
}
type_context_old::tmp_locals locals(m_ctx);
expr x = locals.push_local(name("A"), A);
// motive := fun x : A, a ~ x
expr motive = locals.mk_lambda(mk_rel(R, a, x));
// minor : a ~ a
expr minor = mk_refl(R, a);
return mk_eq_rec(motive, minor, H);
}
expr mk_ss_elim(expr const & A, expr const & ss_inst, expr const & old_e, expr const & new_e) {
level lvl = get_level(A);
return ::lean::mk_app(mk_constant(get_subsingleton_elim_name(), {lvl}), A, ss_inst, old_e, new_e);
@ -784,10 +735,6 @@ expr mk_app(type_context_old & ctx, name const & c, unsigned total_nargs, unsign
return app_builder(ctx).mk_app(c, total_nargs, expl_nargs, expl_args);
}
expr mk_rel(type_context_old & ctx, name const & n, expr const & lhs, expr const & rhs) {
return app_builder(ctx).mk_rel(n, lhs, rhs);
}
expr mk_eq(type_context_old & ctx, expr const & lhs, expr const & rhs) {
return app_builder(ctx).mk_eq(lhs, rhs);
}
@ -950,10 +897,6 @@ expr mk_funext(type_context_old & ctx, expr const & lam_pf) {
return mk_app(ctx, get_funext_name(), lam_pf);
}
expr lift_from_eq(type_context_old & ctx, name const & R, expr const & H) {
return app_builder(ctx).lift_from_eq(R, H);
}
expr mk_iff_false_intro(type_context_old & ctx, expr const & H) {
// TODO(Leo): implement custom version if bottleneck.
return mk_app(ctx, get_iff_false_intro_name(), {H});

View file

@ -8,7 +8,6 @@ Author: Leonardo de Moura
#include <memory>
#include <unordered_map>
#include "kernel/environment.h"
#include "library/relation_manager.h"
#include "library/reducible.h"
#include "library/type_context.h"
@ -81,7 +80,6 @@ inline expr mk_app(type_context_old & ctx, name const & c, unsigned total_nargs,
}
/** \brief Similar to mk_app(n, lhs, rhs), but handles eq and iff more efficiently. */
expr mk_rel(type_context_old & ctx, name const & n, expr const & lhs, expr const & rhs);
expr mk_eq(type_context_old & ctx, expr const & lhs, expr const & rhs);
expr mk_iff(type_context_old & ctx, expr const & lhs, expr const & rhs);
expr mk_heq(type_context_old & ctx, expr const & lhs, expr const & rhs);
@ -133,10 +131,6 @@ expr mk_congr(type_context_old & ctx, expr const & H1, expr const & H2, bool ski
expr mk_funext(type_context_old & ctx, expr const & lam_pf);
/** \brief Given a reflexive relation R, and a proof H : a = b,
build a proof for (R a b) */
expr lift_from_eq(type_context_old & ctx, name const & R, expr const & H);
/** \brief not p -> (p <-> false) */
expr mk_iff_false_intro(type_context_old & ctx, expr const & H);
/** \brief p -> (p <-> true) */

View file

@ -27,7 +27,6 @@ Author: Leonardo de Moura
#include "library/util.h"
#include "library/pp_options.h"
#include "library/projection.h"
#include "library/relation_manager.h"
#include "library/user_recursors.h"
#include "library/noncomputable.h"
#include "library/aux_recursors.h"
@ -98,7 +97,6 @@ void initialize_library_module() {
initialize_quote();
initialize_pp_options();
initialize_projection();
initialize_relation_manager();
initialize_user_recursors();
initialize_noncomputable();
initialize_aux_recursors();
@ -126,7 +124,6 @@ void finalize_library_module() {
finalize_aux_recursors();
finalize_noncomputable();
finalize_user_recursors();
finalize_relation_manager();
finalize_projection();
finalize_pp_options();
finalize_quote();

View file

@ -1,351 +0,0 @@
/*
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 <string>
#include "runtime/sstream.h"
#include "runtime/optional.h"
#include "util/name.h"
#include "util/rb_map.h"
#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.
static name const & get_fn_const(expr const & e, char const * msg) {
expr const & fn = get_app_fn(e);
if (!is_constant(unwrap_pos(fn)))
throw exception(msg);
return const_name(fn);
}
static pair<expr, unsigned> extract_arg_types_core(environment const & env, name const & f, buffer<expr> & arg_types) {
constant_info info = env.get(f);
expr f_type = info.get_type();
while (is_pi(f_type)) {
arg_types.push_back(binding_domain(f_type));
f_type = binding_body(f_type);
}
return mk_pair(f_type, info.get_num_lparams());
}
enum class op_kind { Relation, Subst, Trans, Refl, Symm };
struct rel_entry {
op_kind m_kind;
name m_name;
rel_entry() {}
rel_entry(op_kind k, name const & n):m_kind(k), m_name(n) {}
};
struct rel_state {
typedef name_map<refl_info> refl_table;
typedef name_map<subst_info> subst_table;
typedef name_map<symm_info> symm_table;
typedef rb_map<name_pair, trans_info, name_pair_quick_cmp> trans_table;
typedef name_map<relation_info> rop_table;
trans_table m_trans_table;
refl_table m_refl_table;
subst_table m_subst_table;
symm_table m_symm_table;
rop_table m_rop_table;
rel_state() {}
bool is_equivalence(name const & rop) const {
return m_trans_table.contains(mk_pair(rop, rop)) && m_refl_table.contains(rop) && m_symm_table.contains(rop);
}
static void throw_invalid_relation(name const & rop) {
throw exception(sstream() << "invalid binary relation declaration, relation '" << rop
<< "' must have two explicit parameters");
}
void register_rop(environment const & env, name const & rop) {
if (m_rop_table.contains(rop))
return;
constant_info info = env.get(rop);
optional<unsigned> lhs_pos;
optional<unsigned> rhs_pos;
unsigned i = 0;
expr type = info.get_type();
while (is_pi(type)) {
if (is_explicit(binding_info(type))) {
if (!lhs_pos) {
lhs_pos = i;
} else if (!rhs_pos) {
rhs_pos = i;
} else {
lhs_pos = rhs_pos;
rhs_pos = i;
}
}
type = binding_body(type);
i++;
}
if (lhs_pos && rhs_pos) {
m_rop_table.insert(rop, relation_info(i, *lhs_pos, *rhs_pos));
} else {
throw_invalid_relation(rop);
}
}
void add_subst(environment const & env, name const & subst) {
buffer<expr> arg_types;
auto p = extract_arg_types_core(env, subst, arg_types);
expr r_type = p.first;
unsigned nunivs = p.second;
unsigned nargs = arg_types.size();
if (nargs < 2)
throw exception("invalid substitution theorem, it must have at least 2 arguments");
name const & rop = get_fn_const(arg_types[nargs-2], "invalid substitution theorem, penultimate argument must be an operator application");
m_subst_table.insert(rop, subst_info(subst, nunivs, nargs));
}
void add_refl(environment const & env, name const & refl) {
buffer<expr> arg_types;
auto p = extract_arg_types_core(env, refl, arg_types);
expr r_type = p.first;
unsigned nunivs = p.second;
unsigned nargs = arg_types.size();
if (nargs < 1)
throw exception("invalid reflexivity rule, it must have at least 1 argument");
name const & rop = get_fn_const(r_type, "invalid reflexivity rule, result type must be an operator application");
register_rop(env, rop);
m_refl_table.insert(rop, refl_info(refl, nunivs, nargs));
}
void add_trans(environment const & env, name const & trans) {
buffer<expr> arg_types;
auto p = extract_arg_types_core(env, trans, arg_types);
expr r_type = p.first;
unsigned nunivs = p.second;
unsigned nargs = arg_types.size();
if (nargs < 5)
throw exception("invalid transitivity rule, it must have at least 5 arguments");
name const & rop = get_fn_const(r_type, "invalid transitivity rule, result type must be an operator application");
name const & op1 = get_fn_const(arg_types[nargs-2], "invalid transitivity rule, penultimate argument must be an operator application");
name const & op2 = get_fn_const(arg_types[nargs-1], "invalid transitivity rule, last argument must be an operator application");
register_rop(env, rop);
m_trans_table.insert(name_pair(op1, op2), trans_info(trans, nunivs, nargs, rop));
}
void add_symm(environment const & env, name const & symm) {
buffer<expr> arg_types;
auto p = extract_arg_types_core(env, symm, arg_types);
expr r_type = p.first;
unsigned nunivs = p.second;
unsigned nargs = arg_types.size();
if (nargs < 1)
throw exception("invalid symmetry rule, it must have at least 1 argument");
name const & rop = get_fn_const(r_type, "invalid symmetry rule, result type must be an operator application");
register_rop(env, rop);
m_symm_table.insert(rop, symm_info(symm, nunivs, nargs));
}
};
struct rel_config {
typedef rel_state state;
typedef rel_entry entry;
static void add_entry(environment const & env, io_state const &, state & s, entry const & e) {
switch (e.m_kind) {
case op_kind::Relation: s.register_rop(env, e.m_name); break;
case op_kind::Refl: s.add_refl(env, e.m_name); break;
case op_kind::Subst: s.add_subst(env, e.m_name); break;
case op_kind::Trans: s.add_trans(env, e.m_name); break;
case op_kind::Symm: s.add_symm(env, e.m_name); break;
}
}
static const char * get_serialization_key() { return "REL"; }
static void write_entry(serializer & s, entry const & e) {
s << static_cast<char>(e.m_kind) << e.m_name;
}
static entry read_entry(deserializer & d) {
entry e;
char cmd;
d >> cmd >> e.m_name;
e.m_kind = static_cast<op_kind>(cmd);
return e;
}
static optional<unsigned> get_fingerprint(entry const &) {
return optional<unsigned>();
}
};
template class scoped_ext<rel_config>;
typedef scoped_ext<rel_config> rel_ext;
environment add_relation(environment const & env, name const & n, bool persistent) {
return rel_ext::add_entry(env, get_dummy_ios(), rel_entry(op_kind::Relation, n), persistent);
}
environment add_subst(environment const & env, name const & n, bool persistent) {
return rel_ext::add_entry(env, get_dummy_ios(), rel_entry(op_kind::Subst, n), persistent);
}
environment add_refl(environment const & env, name const & n, bool persistent) {
return rel_ext::add_entry(env, get_dummy_ios(), rel_entry(op_kind::Refl, n), persistent);
}
environment add_symm(environment const & env, name const & n, bool persistent) {
return rel_ext::add_entry(env, get_dummy_ios(), rel_entry(op_kind::Symm, n), persistent);
}
environment add_trans(environment const & env, name const & n, bool persistent) {
return rel_ext::add_entry(env, get_dummy_ios(), rel_entry(op_kind::Trans, n), persistent);
}
static optional<relation_lemma_info> get_info(name_map<relation_lemma_info> const & table, name const & op) {
if (auto it = table.find(op)) {
return optional<relation_lemma_info>(*it);
} else {
return optional<relation_lemma_info>();
}
}
optional<refl_info> get_refl_extra_info(environment const & env, name const & op) {
return get_info(rel_ext::get_state(env).m_refl_table, op);
}
optional<subst_info> get_subst_extra_info(environment const & env, name const & op) {
return get_info(rel_ext::get_state(env).m_subst_table, op);
}
optional<symm_info> get_symm_extra_info(environment const & env, name const & op) {
return get_info(rel_ext::get_state(env).m_symm_table, op);
}
optional<trans_info> get_trans_extra_info(environment const & env, name const & op1, name const & op2) {
if (auto it = rel_ext::get_state(env).m_trans_table.find(mk_pair(op1, op2))) {
return optional<trans_info>(*it);
} else {
return optional<trans_info>();
}
}
bool is_subst_relation(environment const & env, name const & op) {
return rel_ext::get_state(env).m_subst_table.contains(op);
}
optional<name> get_refl_info(environment const & env, name const & op) {
if (auto it = get_refl_extra_info(env, op))
return optional<name>(it->m_name);
else
return optional<name>();
}
optional<name> get_symm_info(environment const & env, name const & op) {
if (auto it = get_symm_extra_info(env, op))
return optional<name>(it->m_name);
else
return optional<name>();
}
optional<name> get_trans_info(environment const & env, name const & op) {
if (auto it = get_trans_extra_info(env, op, op))
return optional<name>(it->m_name);
else
return optional<name>();
}
refl_info_getter mk_refl_info_getter(environment const & env) {
auto t = rel_ext::get_state(env).m_refl_table;
return [=](name const & n) { return get_info(t, n); }; // NOLINT
}
trans_info_getter mk_trans_info_getter(environment const & env) {
auto t = rel_ext::get_state(env).m_trans_table;
return [=](name const & op1, name const & op2) { // NOLINT
if (auto it = t.find(mk_pair(op1, op2))) {
return optional<trans_info>(*it);
} else {
return optional<trans_info>();
}
};
}
symm_info_getter mk_symm_info_getter(environment const & env) {
auto t = rel_ext::get_state(env).m_symm_table;
return [=](name const & n) { return get_info(t, n); }; // NOLINT
}
bool is_equivalence(environment const & env, name const & rop) {
return rel_ext::get_state(env).is_equivalence(rop);
}
relation_info const * get_relation_info(environment const & env, name const & rop) {
return rel_ext::get_state(env).m_rop_table.find(rop);
}
relation_info_getter mk_relation_info_getter(environment const & env) {
auto table = rel_ext::get_state(env).m_rop_table;
return [=](name const & rop) { // NOLINT
if (auto r = table.find(rop))
return optional<relation_info>(*r);
else
return optional<relation_info>();
};
}
bool is_relation(name_map<relation_info> const & table, expr const & e, name & rop, expr & lhs, expr & rhs) {
if (!is_app(e))
return false;
expr const & f = get_app_fn(e);
if (!is_constant(f))
return false;
auto r = table.find(const_name(f));
if (!r)
return false;
buffer<expr> args;
get_app_args(e, args);
if (r->get_arity() != args.size())
return false;
rop = const_name(f);
lhs = args[r->get_lhs_pos()];
rhs = args[r->get_rhs_pos()];
return true;
}
bool is_relation(environment const & env, expr const & e, name & rop, expr & lhs, expr & rhs) {
return is_relation(rel_ext::get_state(env).m_rop_table, e, rop, lhs, rhs);
}
is_relation_pred mk_is_relation_pred(environment const & env) {
name_map<relation_info> table = rel_ext::get_state(env).m_rop_table;
return [=](expr const & e, name & rop, expr & lhs, expr & rhs) { // NOLINT
return is_relation(table, e, rop, lhs, rhs);
};
}
void initialize_relation_manager() {
rel_ext::initialize();
register_system_attribute(basic_attribute("refl", "reflexive relation",
[](environment const & env, io_state const &, name const & d, unsigned,
bool persistent) {
return add_refl(env, d, persistent);
}));
register_system_attribute(basic_attribute("symm", "symmetric relation",
[](environment const & env, io_state const &, name const & d, unsigned,
bool persistent) {
return add_symm(env, d, persistent);
}));
register_system_attribute(basic_attribute("trans", "transitive relation",
[](environment const & env, io_state const &, name const & d, unsigned,
bool persistent) {
return add_trans(env, d, persistent);
}));
register_system_attribute(basic_attribute("subst", "substitution",
[](environment const & env, io_state const &, name const & d, unsigned,
bool persistent) {
return add_subst(env, d, persistent);
}));
}
void finalize_relation_manager() {
rel_ext::finalize();
}
}

View file

@ -1,98 +0,0 @@
/*
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"
namespace lean {
struct relation_info {
unsigned m_arity;
unsigned m_lhs_pos;
unsigned m_rhs_pos;
public:
relation_info() {}
relation_info(unsigned arity, unsigned lhs, unsigned rhs):
m_arity(arity), m_lhs_pos(lhs), m_rhs_pos(rhs) {
lean_assert(m_lhs_pos < m_arity);
lean_assert(m_rhs_pos < m_arity);
}
unsigned get_arity() const { return m_arity; }
unsigned get_lhs_pos() const { return m_lhs_pos; }
unsigned get_rhs_pos() const { return m_rhs_pos; }
};
/** \brief Return true if \c rop is a registered equivalence relation in the given manager */
bool is_equivalence(environment const & env, name const & rop);
/** \brief If \c rop is a registered relation, then return a non-null pointer to the associated information
Lean assumes that the arguments of the binary relation are the last two explicit arguments.
Everything else is assumed to be a parameter.
*/
relation_info const * get_relation_info(environment const & env, name const & rop);
inline bool is_relation(environment const & env, name const & rop) { return get_relation_info(env, rop) != nullptr; }
typedef std::function<optional<relation_info>(name const &)> relation_info_getter;
relation_info_getter mk_relation_info_getter(environment const & env);
/** \brief Return true iff \c e is of the form (lhs rop rhs) where rop is a registered relation. */
bool is_relation(environment const & env, expr const & e, name & rop, expr & lhs, expr & rhs);
typedef std::function<bool(expr const &, name &, expr &, expr &)> is_relation_pred; // NOLINT
/** \brief Construct an \c is_relation predicate for the given environment. */
is_relation_pred mk_is_relation_pred(environment const & env);
/** \brief Declare a new binary relation named \c n */
environment add_relation(environment const & env, name const & n, bool persistent);
/** \brief Declare subst/refl/symm/trans lemmas for a binary relation,
* it also declares the relation if it has not been declared yet */
environment add_subst(environment const & env, name const & n, bool persistent);
environment add_refl(environment const & env, name const & n, bool persistent);
environment add_symm(environment const & env, name const & n, bool persistent);
environment add_trans(environment const & env, name const & n, bool persistent);
struct relation_lemma_info {
name m_name;
unsigned m_num_univs;
unsigned m_num_args;
relation_lemma_info() {}
relation_lemma_info(name const & n, unsigned nunivs, unsigned nargs):m_name(n), m_num_univs(nunivs), m_num_args(nargs) {}
};
typedef relation_lemma_info refl_info;
typedef relation_lemma_info symm_info;
typedef relation_lemma_info subst_info;
struct trans_info : public relation_lemma_info {
name m_res_relation;
trans_info() {}
trans_info(name const & n, unsigned nunivs, unsigned nargs, name const & rel):
relation_lemma_info(n, nunivs, nargs), m_res_relation(rel) {}
};
optional<subst_info> get_subst_extra_info(environment const & env, name const & op);
optional<refl_info> get_refl_extra_info(environment const & env, name const & op);
optional<symm_info> get_symm_extra_info(environment const & env, name const & op);
optional<trans_info> get_trans_extra_info(environment const & env, name const & op1, name const & op2);
optional<name> get_refl_info(environment const & env, name const & op);
optional<name> get_symm_info(environment const & env, name const & op);
optional<name> get_trans_info(environment const & env, name const & op);
typedef std::function<optional<refl_info>(name const &)> refl_info_getter;
typedef std::function<optional<trans_info>(name const &, name const &)> trans_info_getter;
typedef std::function<optional<symm_info>(name const &)> symm_info_getter;
refl_info_getter mk_refl_info_getter(environment const & env);
trans_info_getter mk_trans_info_getter(environment const & env);
symm_info_getter mk_symm_info_getter(environment const & env);
bool is_subst_relation(environment const & env, name const & op);
inline bool is_trans_relation(environment const & env, name const & op) { return static_cast<bool>(get_trans_info(env, op)); }
inline bool is_symm_relation(environment const & env, name const & op) { return static_cast<bool>(get_symm_info(env, op)); }
inline bool is_refl_relation(environment const & env, name const & op) { return static_cast<bool>(get_refl_info(env, op)); }
void initialize_relation_manager();
void finalize_relation_manager();
}