refactor(kernel/default_converter): cleanup
This commit is contained in:
parent
3f06f7b6fd
commit
71b9215a70
2 changed files with 96 additions and 56 deletions
|
@ -34,7 +34,7 @@ optional<pair<expr, constraint_seq>> default_converter::norm_ext(expr const & e,
|
|||
|
||||
optional<expr> default_converter::d_norm_ext(expr const & e, type_checker & c, constraint_seq & cs) {
|
||||
if (auto r = norm_ext(e, c)) {
|
||||
cs = cs + r->second;
|
||||
cs += r->second;
|
||||
return some_expr(r->first);
|
||||
} else {
|
||||
return none_expr();
|
||||
|
@ -203,11 +203,10 @@ pair<expr, constraint_seq> default_converter::whnf(expr const & e_prime, type_ch
|
|||
|
||||
expr default_converter::whnf(expr const & e_prime, type_checker & c, constraint_seq & cs) {
|
||||
auto r = whnf(e_prime, c);
|
||||
cs = cs + r.second;
|
||||
cs += r.second;
|
||||
return r.first;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Given lambda/Pi expressions \c t and \c s, return true iff \c t is def eq to \c s.
|
||||
|
||||
|
@ -249,7 +248,7 @@ bool default_converter::is_def_eq(level const & l1, level const & l2, delayed_ju
|
|||
if (is_equivalent(l1, l2)) {
|
||||
return true;
|
||||
} else if (has_meta(l1) || has_meta(l2)) {
|
||||
cs = cs + constraint_seq(mk_level_eq_cnstr(l1, l2, jst.get()));
|
||||
cs += constraint_seq(mk_level_eq_cnstr(l1, l2, jst.get()));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -274,7 +273,7 @@ lbool default_converter::quick_is_def_eq(expr const & t, expr const & s, type_ch
|
|||
return l_true; // t and s are structurally equal
|
||||
if (is_meta(t) || is_meta(s)) {
|
||||
// if t or s is a metavariable (or the application of a metavariable), then add constraint
|
||||
cs = cs + constraint_seq(mk_eq_cnstr(t, s, jst.get()));
|
||||
cs += constraint_seq(mk_eq_cnstr(t, s, jst.get()));
|
||||
return l_true;
|
||||
}
|
||||
if (t.kind() == s.kind()) {
|
||||
|
@ -315,7 +314,7 @@ bool default_converter::is_app_of(expr t, name const & f_name) {
|
|||
}
|
||||
|
||||
/** \brief Try to solve (fun (x : A), B) =?= s by trying eta-expansion on s */
|
||||
bool default_converter::try_eta_expansion(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs) {
|
||||
bool default_converter::try_eta_expansion_core(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs) {
|
||||
if (is_lambda(t) && !is_lambda(s)) {
|
||||
auto tcs = infer_type(c, s);
|
||||
auto wcs = whnf(tcs.first, c);
|
||||
|
@ -326,23 +325,96 @@ bool default_converter::try_eta_expansion(expr const & t, expr const & s, type_c
|
|||
auto dcs = is_def_eq(t, new_s, c, jst);
|
||||
if (!dcs.first)
|
||||
return false;
|
||||
cs = cs + dcs.second + wcs.second + tcs.second;
|
||||
cs += dcs.second + wcs.second + tcs.second;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Return true iff \c t and \c s are definitionally equal.
|
||||
|
||||
\remark Store in \c cs any generated constraints.
|
||||
*/
|
||||
bool default_converter::is_def_eq(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs) {
|
||||
auto bcs = is_def_eq(t, s, c, jst);
|
||||
if (bcs.first) {
|
||||
cs = cs + bcs.second;
|
||||
cs += bcs.second;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Return true if \c t and \c s are definitionally equal because they are applications of the form
|
||||
<tt>(f a_1 ... a_n)</tt> <tt>(g b_1 ... b_n)</tt>, and \c f and \c g are definitionally equal, and
|
||||
\c a_i and \c b_i are also definitionally equal for every 1 <= i <= n.
|
||||
Return false otherwise.
|
||||
|
||||
\remark Store in \c cs any generated constraints
|
||||
*/
|
||||
bool default_converter::is_def_eq_app(expr const & t, expr const & s, type_checker & c, delayed_justification & jst,
|
||||
constraint_seq & cs) {
|
||||
if (is_app(t) && is_app(s)) {
|
||||
buffer<expr> t_args;
|
||||
buffer<expr> s_args;
|
||||
expr t_fn = get_app_args(t, t_args);
|
||||
expr s_fn = get_app_args(s, s_args);
|
||||
constraint_seq cs_prime = cs;
|
||||
if (is_def_eq(t_fn, s_fn, c, jst, cs_prime) && t_args.size() == s_args.size()) {
|
||||
unsigned i = 0;
|
||||
for (; i < t_args.size(); i++) {
|
||||
if (!is_def_eq(t_args[i], s_args[i], c, jst, cs_prime))
|
||||
break;
|
||||
}
|
||||
if (i == t_args.size()) {
|
||||
cs = cs_prime;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \brief Return true if \c t and \c s are definitionally equal due to proof irrelevant.
|
||||
Return false otherwise.
|
||||
|
||||
\remark Store in \c cs any generated constraints.
|
||||
*/
|
||||
bool default_converter::is_def_eq_proof_irrel(expr const & t, expr const & s, type_checker & c, delayed_justification & jst,
|
||||
constraint_seq & cs) {
|
||||
if (!m_env.prop_proof_irrel())
|
||||
return false;
|
||||
// Proof irrelevance support for Prop (aka Type.{0})
|
||||
auto tcs = infer_type(c, t);
|
||||
auto scs = infer_type(c, s);
|
||||
expr t_type = tcs.first;
|
||||
expr s_type = scs.first;
|
||||
// remark: is_prop returns true only if t_type reducible to Prop.
|
||||
// If t_type contains metavariables, then reduction can get stuck, and is_prop will return false.
|
||||
auto pcs = is_prop(t_type, c);
|
||||
if (pcs.first) {
|
||||
auto dcs = is_def_eq(t_type, s_type, c, jst);
|
||||
if (dcs.first) {
|
||||
cs += dcs.second + scs.second + pcs.second + tcs.second;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// If we can't stablish whether t_type is Prop, we try s_type.
|
||||
pcs = is_prop(s_type, c);
|
||||
if (pcs.first) {
|
||||
auto dcs = is_def_eq(t_type, s_type, c, jst);
|
||||
if (dcs.first) {
|
||||
cs += dcs.second + scs.second + pcs.second + tcs.second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// This procedure will miss the case where s_type and t_type cannot be reduced to Prop
|
||||
// because they contain metavariables.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Return true iff t is definitionally equal to s. */
|
||||
pair<bool, constraint_seq> default_converter::is_def_eq(expr const & t, expr const & s, type_checker & c, delayed_justification & jst) {
|
||||
check_system("is_definitionally_equal");
|
||||
|
@ -433,56 +505,18 @@ pair<bool, constraint_seq> default_converter::is_def_eq(expr const & t, expr con
|
|||
}
|
||||
|
||||
// At this point, t_n and s_n are in weak head normal form (modulo meta-variables and proof irrelevance)
|
||||
if (!delay_check && is_app(t_n) && is_app(s_n)) {
|
||||
buffer<expr> t_args;
|
||||
buffer<expr> s_args;
|
||||
expr t_fn = get_app_args(t_n, t_args);
|
||||
expr s_fn = get_app_args(s_n, s_args);
|
||||
constraint_seq cs_prime = cs;
|
||||
if (is_def_eq(t_fn, s_fn, c, jst, cs_prime) && t_args.size() == s_args.size()) {
|
||||
unsigned i = 0;
|
||||
for (; i < t_args.size(); i++) {
|
||||
if (!is_def_eq(t_args[i], s_args[i], c, jst, cs_prime))
|
||||
break;
|
||||
}
|
||||
if (i == t_args.size()) {
|
||||
return to_bcs(true, cs_prime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (try_eta_expansion(t_n, s_n, c, jst, cs) ||
|
||||
try_eta_expansion(s_n, t_n, c, jst, cs))
|
||||
if (!delay_check && is_def_eq_app(t_n, s_n, c, jst, cs))
|
||||
return to_bcs(true, cs);
|
||||
|
||||
if (m_env.prop_proof_irrel()) {
|
||||
// Proof irrelevance support for Prop (aka Type.{0})
|
||||
auto tcs = infer_type(c, t);
|
||||
auto scs = infer_type(c, s);
|
||||
expr t_type = tcs.first;
|
||||
expr s_type = scs.first;
|
||||
// remark: is_prop returns true only if t_type reducible to Prop.
|
||||
// If t_type contains metavariables, then reduction can get stuck, and is_prop will return false.
|
||||
auto pcs = is_prop(t_type, c);
|
||||
if (pcs.first) {
|
||||
auto dcs = is_def_eq(t_type, s_type, c, jst);
|
||||
if (dcs.first)
|
||||
return to_bcs(true, dcs.second + scs.second + pcs.second + tcs.second);
|
||||
} else {
|
||||
// If we can't stablish whether t_type is Prop, we try s_type.
|
||||
pcs = is_prop(s_type, c);
|
||||
if (pcs.first) {
|
||||
auto dcs = is_def_eq(t_type, s_type, c, jst);
|
||||
if (dcs.first)
|
||||
return to_bcs(true, dcs.second + scs.second + pcs.second + tcs.second);
|
||||
}
|
||||
// This procedure will miss the case where s_type and t_type cannot be reduced to Prop
|
||||
// because they contain metavariables.
|
||||
}
|
||||
}
|
||||
if (try_eta_expansion(t_n, s_n, c, jst, cs))
|
||||
return to_bcs(true, cs);
|
||||
|
||||
constraint_seq pi_cs;
|
||||
if (is_def_eq_proof_irrel(t, s, c, jst, pi_cs))
|
||||
return to_bcs(true, pi_cs);
|
||||
|
||||
if (may_reduce_later(t_n, c) || may_reduce_later(s_n, c) || delay_check) {
|
||||
cs = cs + constraint_seq(mk_eq_cnstr(t_n, s_n, jst.get()));
|
||||
cs += constraint_seq(mk_eq_cnstr(t_n, s_n, jst.get()));
|
||||
return to_bcs(true, cs);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,8 +54,13 @@ protected:
|
|||
lbool quick_is_def_eq(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs);
|
||||
bool is_def_eq_args(expr t, expr s, type_checker & c, delayed_justification & jst, constraint_seq & cs);
|
||||
bool is_app_of(expr t, name const & f_name);
|
||||
bool try_eta_expansion(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs);
|
||||
bool try_eta_expansion_core(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs);
|
||||
bool try_eta_expansion(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs) {
|
||||
return try_eta_expansion_core(t, s, c, jst, cs) || try_eta_expansion_core(s, t, c, jst, cs);
|
||||
}
|
||||
bool is_def_eq(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs);
|
||||
bool is_def_eq_app(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs);
|
||||
bool is_def_eq_proof_irrel(expr const & t, expr const & s, type_checker & c, delayed_justification & jst, constraint_seq & cs);
|
||||
|
||||
pair<bool, constraint_seq> is_prop(expr const & e, type_checker & c);
|
||||
|
||||
|
@ -64,8 +69,9 @@ public:
|
|||
extra_opaque_pred const & pred);
|
||||
|
||||
virtual bool is_opaque(declaration const & d) const;
|
||||
virtual pair<expr, constraint_seq> whnf(expr const & e_prime, type_checker & c);
|
||||
virtual optional<module_idx> get_module_idx() const { return m_module_idx; }
|
||||
|
||||
virtual pair<expr, constraint_seq> whnf(expr const & e_prime, type_checker & c);
|
||||
virtual pair<bool, constraint_seq> is_def_eq(expr const & t, expr const & s, type_checker & c, delayed_justification & jst);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue