/* 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 "util/sstream.h" #include "kernel/error_msgs.h" #include "kernel/instantiate.h" #include "library/scoped_ext.h" #include namespace lean { using blast::backward_rule; using blast::backward_rule_set; using blast::gexpr; static name * g_class_name = nullptr; static std::string * g_key = nullptr; struct brs_state { backward_rule_set m_backward_rule_set; name_set m_names; void add(environment const & env, io_state const & ios, name const & cname, unsigned prio) { default_type_context tctx(env, ios); m_backward_rule_set.insert(tctx, cname, prio); m_names.insert(cname); } }; struct brs_entry { name m_name; unsigned m_priority; brs_entry() {} brs_entry(name const & n, unsigned prio): m_name(n), m_priority(prio) { } }; struct brs_config { typedef brs_entry entry; typedef brs_state state; static void add_entry(environment const & env, io_state const & ios, state & s, entry const & e) { s.add(env, ios, e.m_name, e.m_priority); } static name const & get_class_name() { return *g_class_name; } static std::string const & get_serialization_key() { return *g_key; } static void write_entry(serializer & s, entry const & e) { s << e.m_name << e.m_priority; } static entry read_entry(deserializer & d) { entry e; d >> e.m_name >> e.m_priority; return e; } static optional get_fingerprint(entry const & e) { return some(e.m_name.hash()); } }; template class scoped_ext; typedef scoped_ext brs_ext; environment add_backward_rule(environment const & env, name const & n, unsigned priority, bool persistent) { return brs_ext::add_entry(env, get_dummy_ios(), brs_entry(n, priority), persistent); } bool is_backward_rule(environment const & env, name const & n) { return brs_ext::get_state(env).m_names.contains(n); } backward_rule_set get_backward_rule_set(environment const & env) { return brs_ext::get_state(env).m_backward_rule_set; } backward_rule_set get_backward_rule_sets(environment const & env, io_state const & ios, name const & ns) { backward_rule_set brs; list const * entries = brs_ext::get_entries(env, ns); if (entries) { for (auto const & e : *entries) { default_type_context tctx(env, ios); brs.insert(tctx, e.m_name, e.m_priority); } } return brs; } io_state_stream const & operator<<(io_state_stream const & out, backward_rule_set const & brs) { out << "backward rules\n"; brs.for_each([&](head_index const & head_idx, backward_rule const & r) { out << head_idx << " ==> " << r.get_proof() << "\n"; }); return out; } namespace blast { bool operator==(backward_rule const & r1, backward_rule const & r2) { return r1.get_proof() == r2.get_proof(); } void backward_rule_set::insert(type_context & tctx, name const & id, gexpr const & proof, expr const & _thm, unsigned prio) { expr thm = tctx.whnf(_thm); while (is_pi(thm)) { expr local = tctx.mk_tmp_local(binding_domain(thm), binding_info(thm)); thm = tctx.whnf(instantiate(binding_body(thm), local)); } m_set.insert(head_index(thm), backward_rule(id, proof, prio)); } void backward_rule_set::insert(type_context & tctx, name const & name, unsigned prio) { gexpr proof(tctx.env(), name); declaration const & d = tctx.env().get(name); insert(tctx, name, proof, d.get_type(), prio); } void backward_rule_set::erase(name_set const & ids) { // This method is not very smart and doesn't use any indexing or caching. // So, it may be a bottleneck in the future buffer > to_delete; for_each([&](head_index const & h, backward_rule const & r) { if (ids.contains(r.get_id())) { to_delete.push_back(mk_pair(h, r)); } }); for (auto const & hr : to_delete) { m_set.erase(hr.first, hr.second); } } void backward_rule_set::erase(name const & id) { name_set ids; ids.insert(id); erase(ids); } void backward_rule_set::for_each(std::function const & fn) const { m_set.for_each_entry(fn); } list backward_rule_set::find(head_index const & h) const { list const * rule_list = m_set.find(h); if (!rule_list) return list(); return map2(*rule_list, [&](backward_rule const & r) { return r.get_proof(); }); } void initialize_backward_rule_set() { g_class_name = new name("brs"); g_key = new std::string("brs"); brs_ext::initialize(); } void finalize_backward_rule_set() { brs_ext::finalize(); delete g_key; delete g_class_name; } } }