2014-01-18 20:50:46 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
|
|
#include <functional>
|
2014-01-18 23:37:36 +00:00
|
|
|
#include "util/lua.h"
|
2014-01-19 01:23:41 +00:00
|
|
|
#include "util/list.h"
|
|
|
|
#include "util/splay_tree.h"
|
|
|
|
#include "util/name.h"
|
2014-01-18 20:50:46 +00:00
|
|
|
#include "kernel/environment.h"
|
|
|
|
#include "kernel/formatter.h"
|
2014-01-19 20:03:59 +00:00
|
|
|
#include "library/io_state_stream.h"
|
2014-01-22 05:16:23 +00:00
|
|
|
#include "library/simplifier/congr.h"
|
2014-01-18 20:50:46 +00:00
|
|
|
|
|
|
|
namespace lean {
|
2014-01-19 04:52:33 +00:00
|
|
|
class rewrite_rule_set;
|
|
|
|
class rewrite_rule {
|
|
|
|
friend class rewrite_rule_set;
|
|
|
|
name m_id;
|
|
|
|
expr m_lhs;
|
|
|
|
expr m_rhs;
|
|
|
|
expr m_ceq;
|
|
|
|
expr m_proof;
|
|
|
|
unsigned m_num_args;
|
|
|
|
bool m_is_permutation;
|
|
|
|
rewrite_rule(name const & id, expr const & lhs, expr const & rhs, expr const & ceq, expr const & proof,
|
|
|
|
unsigned num_args, bool is_permutation);
|
|
|
|
public:
|
|
|
|
name const & get_id() const { return m_id; }
|
|
|
|
expr const & get_lhs() const { return m_lhs; }
|
|
|
|
expr const & get_rhs() const { return m_rhs; }
|
|
|
|
expr const & get_ceq() const { return m_ceq; }
|
|
|
|
expr const & get_proof() const { return m_proof; }
|
|
|
|
unsigned get_num_args() const { return m_num_args; }
|
|
|
|
bool is_permutation() const { return m_is_permutation; }
|
|
|
|
};
|
|
|
|
|
2014-01-19 01:23:41 +00:00
|
|
|
/**
|
|
|
|
\brief Actual implementation of the \c rewrite_rule_set class.
|
|
|
|
*/
|
2014-01-18 20:50:46 +00:00
|
|
|
class rewrite_rule_set {
|
2014-01-19 01:23:41 +00:00
|
|
|
typedef splay_tree<name, name_quick_cmp> name_set;
|
|
|
|
ro_environment::weak_ref m_env;
|
|
|
|
list<rewrite_rule> m_rule_set; // TODO(Leo): use better data-structure, e.g., discrimination trees
|
|
|
|
name_set m_disabled_rules;
|
2014-01-22 05:16:23 +00:00
|
|
|
list<congr_theorem_info> m_congr_thms; // This is probably ok since we usually have very few congruence theorems
|
2014-01-19 01:23:41 +00:00
|
|
|
|
|
|
|
bool enabled(rewrite_rule const & rule) const;
|
2014-01-18 20:50:46 +00:00
|
|
|
public:
|
|
|
|
rewrite_rule_set(ro_environment const & env);
|
2014-01-19 01:23:41 +00:00
|
|
|
rewrite_rule_set(rewrite_rule_set const & other);
|
2014-01-18 20:50:46 +00:00
|
|
|
~rewrite_rule_set();
|
2014-01-19 01:23:41 +00:00
|
|
|
|
2014-01-18 20:50:46 +00:00
|
|
|
/**
|
|
|
|
\brief Convert the theorem \c th with proof \c proof into conditional rewrite rules, and
|
|
|
|
insert the rules into this rule set. The new rules are tagged with the given \c id.
|
|
|
|
*/
|
|
|
|
void insert(name const & id, expr const & th, expr const & proof);
|
2014-01-19 01:23:41 +00:00
|
|
|
|
2014-01-18 20:50:46 +00:00
|
|
|
/**
|
|
|
|
\brief Convert the theorem/axiom named \c th_name in the environment into conditional rewrite rules,
|
|
|
|
and insert the rules into this rule set. The new rules are tagged with the theorem name.
|
|
|
|
|
|
|
|
This method throws an exception if the environment does not have a theorem/axiom named \c th_name.
|
|
|
|
*/
|
|
|
|
void insert(name const & th_name);
|
|
|
|
|
2014-01-18 23:37:36 +00:00
|
|
|
/** \brief Return true iff the conditional rewrite rules tagged with the given id are enabled. */
|
2014-01-18 20:50:46 +00:00
|
|
|
bool enabled(name const & id) const;
|
|
|
|
|
2014-01-19 01:23:41 +00:00
|
|
|
/** \brief Enable/disable the conditional rewrite rules tagged with the given identifier. */
|
|
|
|
void enable(name const & id, bool f);
|
|
|
|
|
2014-01-22 05:16:23 +00:00
|
|
|
/** \brief Add a new congruence theorem. */
|
|
|
|
void insert_congr(expr const & e);
|
|
|
|
void insert_congr(name const & th_name);
|
|
|
|
|
2014-01-19 04:52:33 +00:00
|
|
|
typedef std::function<bool(rewrite_rule const &)> match_fn; // NOLINT
|
|
|
|
typedef std::function<void(rewrite_rule const &, bool)> visit_fn;
|
2014-01-18 20:50:46 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-19 04:52:33 +00:00
|
|
|
\brief Execute <tt>fn(rule)</tt> for each (enabled) rule whose the left-hand-side may
|
2014-01-18 20:50:46 +00:00
|
|
|
match \c e.
|
|
|
|
The traversal is interrupted as soon as \c fn returns true.
|
|
|
|
*/
|
2014-01-19 04:52:33 +00:00
|
|
|
bool find_match(expr const &, match_fn const & fn) const;
|
2014-01-19 01:23:41 +00:00
|
|
|
|
2014-01-19 04:52:33 +00:00
|
|
|
/** \brief Execute <tt>fn(rule, enabled)</tt> for each rule in this rule set. */
|
2014-01-18 23:37:36 +00:00
|
|
|
void for_each(visit_fn const & fn) const;
|
2014-01-18 20:50:46 +00:00
|
|
|
|
2014-01-18 23:37:36 +00:00
|
|
|
/** \brief Pretty print this rule set. */
|
2014-01-18 20:50:46 +00:00
|
|
|
format pp(formatter const & fmt, options const & opts) const;
|
|
|
|
};
|
2014-01-19 20:03:59 +00:00
|
|
|
io_state_stream const & operator<<(io_state_stream const & out, rewrite_rule_set const & rs);
|
2014-01-18 23:37:36 +00:00
|
|
|
|
2014-01-19 01:23:41 +00:00
|
|
|
name const & get_default_rewrite_rule_set_id();
|
2014-01-18 23:37:36 +00:00
|
|
|
/**
|
|
|
|
\brief Create a rewrite rule set inside the given environment.
|
|
|
|
|
|
|
|
\remark The rule set is saved when the environment is serialized.
|
|
|
|
\remark This procedure throws an exception if the environment already contains a rule set named \c rule_set_id.
|
|
|
|
*/
|
2014-01-19 01:23:41 +00:00
|
|
|
void mk_rewrite_rule_set(environment const & env, name const & rule_set_id = get_default_rewrite_rule_set_id());
|
2014-01-18 23:37:36 +00:00
|
|
|
/**
|
|
|
|
\brief Convert the theorem named \c th_name into conditional rewrite rules
|
|
|
|
and insert them in the rule set named \c rule_set_id in the given environment.
|
|
|
|
|
|
|
|
\remark This procedure throws an exception if the environment does not have a theorem/axiom named \c th_name.
|
|
|
|
\remark This procedure throws an exception if the environment does not have a rule set named \c rule_set_id.
|
|
|
|
*/
|
|
|
|
void add_rewrite_rules(environment const & env, name const & rule_set_id, name const & th_name);
|
2014-01-19 01:23:41 +00:00
|
|
|
inline void add_rewrite_rules(environment const & env, name const & th_name) {
|
|
|
|
add_rewrite_rules(env, get_default_rewrite_rule_set_id(), th_name);
|
|
|
|
}
|
|
|
|
|
2014-01-18 23:37:36 +00:00
|
|
|
/**
|
|
|
|
\brief Enable/disable the rewrite rules whose id is \c rule_id in the given rule set.
|
|
|
|
|
|
|
|
\remark This procedure throws an exception if the environment does not have a rule set named \c rule_set_id.
|
|
|
|
*/
|
|
|
|
void enable_rewrite_rules(environment const & env, name const & rule_set_id, name const & rule_id, bool flag);
|
2014-01-19 01:23:41 +00:00
|
|
|
inline void enable_rewrite_rules(environment const & env, name const & rule_id, bool flag) {
|
|
|
|
enable_rewrite_rules(env, get_default_rewrite_rule_set_id(), rule_id, flag);
|
|
|
|
}
|
|
|
|
|
2014-01-22 05:16:23 +00:00
|
|
|
/**
|
|
|
|
\brief Add a new congruence theorem to the given rewrite rule set.
|
|
|
|
*/
|
|
|
|
void add_congr_theorem(environment const & env, name const & rule_set_id, name const & th_name);
|
|
|
|
inline void add_congr_theorem(environment const & env, name const & th_name) {
|
|
|
|
add_congr_theorem(env, get_default_rewrite_rule_set_id(), th_name);
|
|
|
|
}
|
|
|
|
|
2014-01-18 23:37:36 +00:00
|
|
|
/**
|
|
|
|
\brief Return the rule set name \c rule_set_id in the given environment.
|
|
|
|
|
|
|
|
\remark This procedure throws an exception if the environment does not have a rule set named \c rule_set_id.
|
|
|
|
*/
|
2014-01-19 01:23:41 +00:00
|
|
|
rewrite_rule_set get_rewrite_rule_set(ro_environment const & env, name const & rule_set_id = get_default_rewrite_rule_set_id());
|
2014-01-18 23:37:36 +00:00
|
|
|
void open_rewrite_rule_set(lua_State * L);
|
2014-01-18 20:50:46 +00:00
|
|
|
}
|