2014-05-20 16:40:30 +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
|
|
|
|
*/
|
2014-10-27 23:49:29 +00:00
|
|
|
#include "util/interrupt.h"
|
2014-05-20 16:40:30 +00:00
|
|
|
#include "util/name_generator.h"
|
|
|
|
#include "kernel/type_checker.h"
|
|
|
|
#include "kernel/instantiate.h"
|
|
|
|
#include "kernel/abstract.h"
|
2014-12-15 02:49:48 +00:00
|
|
|
#include "kernel/inductive/inductive.h"
|
2014-09-27 03:16:03 +00:00
|
|
|
#include "library/reducible.h"
|
2014-05-20 16:40:30 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
class normalize_fn {
|
2014-10-27 21:49:11 +00:00
|
|
|
type_checker & m_tc;
|
|
|
|
name_generator m_ngen;
|
2014-10-27 23:49:29 +00:00
|
|
|
std::function<bool(expr const &)> m_pred; // NOLINT
|
2014-10-27 21:49:11 +00:00
|
|
|
bool m_save_cnstrs;
|
|
|
|
constraint_seq m_cnstrs;
|
2014-05-20 16:40:30 +00:00
|
|
|
|
|
|
|
expr normalize_binding(expr const & e) {
|
|
|
|
expr d = normalize(binding_domain(e));
|
2014-06-30 16:14:55 +00:00
|
|
|
expr l = mk_local(m_ngen.next(), binding_name(e), d, binding_info(e));
|
2014-05-20 16:40:30 +00:00
|
|
|
expr b = abstract(normalize(instantiate(binding_body(e), l)), l);
|
|
|
|
return update_binding(e, d, b);
|
|
|
|
}
|
|
|
|
|
2014-05-20 18:53:58 +00:00
|
|
|
expr normalize_app(expr const & e) {
|
|
|
|
buffer<expr> args;
|
2014-12-15 02:49:48 +00:00
|
|
|
bool modified = false;
|
2014-05-20 18:53:58 +00:00
|
|
|
expr f = get_app_rev_args(e, args);
|
2014-12-15 02:49:48 +00:00
|
|
|
for (expr & a : args) {
|
|
|
|
expr new_a = normalize(a);
|
|
|
|
if (new_a != a)
|
|
|
|
modified = true;
|
|
|
|
a = new_a;
|
|
|
|
}
|
|
|
|
if (!modified)
|
|
|
|
return e;
|
|
|
|
expr r = mk_rev_app(f, args);
|
|
|
|
if (is_constant(f) && inductive::is_elim_rule(m_tc.env(), const_name(f))) {
|
|
|
|
return normalize(r);
|
|
|
|
} else {
|
|
|
|
return r;
|
|
|
|
}
|
2014-05-20 18:53:58 +00:00
|
|
|
}
|
|
|
|
|
2014-05-20 16:40:30 +00:00
|
|
|
expr normalize(expr e) {
|
2014-10-27 23:49:29 +00:00
|
|
|
check_system("normalize");
|
2014-10-27 21:49:11 +00:00
|
|
|
if (!m_pred(e))
|
|
|
|
return e;
|
|
|
|
auto w = m_tc.whnf(e);
|
|
|
|
e = w.first;
|
|
|
|
if (m_save_cnstrs)
|
|
|
|
m_cnstrs += w.second;
|
2014-05-20 16:40:30 +00:00
|
|
|
switch (e.kind()) {
|
|
|
|
case expr_kind::Var: case expr_kind::Constant: case expr_kind::Sort:
|
|
|
|
case expr_kind::Meta: case expr_kind::Local: case expr_kind::Macro:
|
|
|
|
return e;
|
|
|
|
case expr_kind::Lambda: case expr_kind::Pi:
|
|
|
|
return normalize_binding(e);
|
|
|
|
case expr_kind::App:
|
2014-05-20 18:53:58 +00:00
|
|
|
return normalize_app(e);
|
2014-05-20 16:40:30 +00:00
|
|
|
}
|
|
|
|
lean_unreachable(); // LCOV_EXCL_LINE
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2014-10-27 21:49:11 +00:00
|
|
|
normalize_fn(type_checker & tc, bool save = true):
|
|
|
|
m_tc(tc), m_ngen(m_tc.mk_ngen()),
|
|
|
|
m_pred([](expr const &) { return true; }),
|
|
|
|
m_save_cnstrs(save) {}
|
|
|
|
|
2014-10-27 23:49:29 +00:00
|
|
|
normalize_fn(type_checker & tc, std::function<bool(expr const &)> const & fn): // NOLINT
|
2014-10-27 21:49:11 +00:00
|
|
|
m_tc(tc), m_ngen(m_tc.mk_ngen()),
|
|
|
|
m_pred(fn) {}
|
|
|
|
|
|
|
|
expr operator()(expr const & e) {
|
|
|
|
m_cnstrs = constraint_seq();
|
|
|
|
return normalize(e);
|
|
|
|
}
|
|
|
|
|
2014-09-27 03:16:03 +00:00
|
|
|
expr operator()(level_param_names const & ls, expr const & e) {
|
2014-10-27 21:49:11 +00:00
|
|
|
m_cnstrs = constraint_seq();
|
|
|
|
return m_tc.with_params(ls, [&]() {
|
2014-09-27 03:16:03 +00:00
|
|
|
return normalize(e);
|
|
|
|
});
|
|
|
|
}
|
2014-10-27 21:49:11 +00:00
|
|
|
|
|
|
|
constraint_seq get_cnstrs() const { return m_cnstrs; }
|
2014-05-20 16:40:30 +00:00
|
|
|
};
|
|
|
|
|
2014-10-27 21:49:11 +00:00
|
|
|
expr normalize(environment const & env, expr const & e) {
|
|
|
|
auto tc = mk_type_checker(env, true);
|
|
|
|
bool save_cnstrs = false;
|
|
|
|
return normalize_fn(*tc, save_cnstrs)(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
expr normalize(environment const & env, level_param_names const & ls, expr const & e) {
|
|
|
|
auto tc = mk_type_checker(env, true);
|
|
|
|
bool save_cnstrs = false;
|
|
|
|
return normalize_fn(*tc, save_cnstrs)(ls, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
expr normalize(type_checker & tc, expr const & e) {
|
|
|
|
bool save_cnstrs = false;
|
|
|
|
return normalize_fn(tc, save_cnstrs)(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
expr normalize(type_checker & tc, expr const & e, constraint_seq & cs) {
|
|
|
|
normalize_fn fn(tc);
|
|
|
|
expr r = fn(e);
|
|
|
|
cs += fn.get_cnstrs();
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2014-10-27 23:49:29 +00:00
|
|
|
expr normalize(type_checker & tc, expr const & e, std::function<bool(expr const &)> const & pred, // NOLINT
|
|
|
|
constraint_seq & cs) {
|
2014-10-27 21:49:11 +00:00
|
|
|
normalize_fn fn(tc, pred);
|
|
|
|
expr r = fn(e);
|
|
|
|
cs += fn.get_cnstrs();
|
|
|
|
return r;
|
|
|
|
}
|
2014-05-20 16:40:30 +00:00
|
|
|
}
|