feat(library/rewriter): add rewrite_* functions
rewrite_* functions take the rewriting results of the sub-components and construct the rewriting result for the main component. For instance, rewrite_app function takes env, ctx, and the value v s.t. v = (e_0 e_1 ... e_n) and the rewriting results for e_i's as a vector(buffer) (e'_0, pf_0 -- proof of e_0 = e'_0) (e'_1, pf_1 -- proof of e_1 = e'_1) ... (e'_n, pf_n -- proof of e_n = e'_n). Then rewrite_app function construct the new v' v' = (e'_0 e'_1 ... e'_n) and the proof of v = v' which is constructed with pf_i's. These functions are used in the component rewriters such as app_RW and let_type_RW, as well as more complicated rewriters such as depth rewriter.
This commit is contained in:
parent
a9eb2a9307
commit
1d76a6f71d
2 changed files with 547 additions and 230 deletions
|
@ -1,5 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
Copyright (c) 2013 Microsoft Corporation.
|
||||||
|
Copyright (c) 2013 Carnegie Mellon University.
|
||||||
|
All rights reserved.
|
||||||
Released under Apache 2.0 license as described in the file LICENSE.
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
Author: Soonho Kong
|
Author: Soonho Kong
|
||||||
|
@ -20,8 +22,10 @@
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::pair;
|
using std::initializer_list;
|
||||||
using std::make_pair;
|
using std::make_pair;
|
||||||
|
using std::ostream;
|
||||||
|
using std::pair;
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
|
||||||
|
@ -102,17 +106,15 @@ pair<expr, expr> theorem_rewriter_cell::operator()(environment const &, context
|
||||||
lean_trace("rewriter", tout << "Proof = " << proof << endl;);
|
lean_trace("rewriter", tout << "Proof = " << proof << endl;);
|
||||||
return make_pair(new_rhs, proof);
|
return make_pair(new_rhs, proof);
|
||||||
}
|
}
|
||||||
std::ostream & theorem_rewriter_cell::display(std::ostream & out) const {
|
ostream & theorem_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Thm_RW("
|
out << "Thm_RW(" << m_type << ", " << m_body << ")";
|
||||||
<< m_type << ", "
|
|
||||||
<< m_body << ")";
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrElse Rewriter
|
// OrElse Rewriter
|
||||||
orelse_rewriter_cell::orelse_rewriter_cell(rewriter const & rw1, rewriter const & rw2)
|
orelse_rewriter_cell::orelse_rewriter_cell(rewriter const & rw1, rewriter const & rw2)
|
||||||
:rewriter_cell(rewriter_kind::OrElse), m_rwlist({rw1, rw2}) { }
|
:rewriter_cell(rewriter_kind::OrElse), m_rwlist({rw1, rw2}) { }
|
||||||
orelse_rewriter_cell::orelse_rewriter_cell(std::initializer_list<rewriter> const & l)
|
orelse_rewriter_cell::orelse_rewriter_cell(initializer_list<rewriter> const & l)
|
||||||
:rewriter_cell(rewriter_kind::OrElse), m_rwlist(l) {
|
:rewriter_cell(rewriter_kind::OrElse), m_rwlist(l) {
|
||||||
lean_assert(l.size() >= 2);
|
lean_assert(l.size() >= 2);
|
||||||
}
|
}
|
||||||
|
@ -128,11 +130,9 @@ pair<expr, expr> orelse_rewriter_cell::operator()(environment const & env, conte
|
||||||
// If the execution reaches here, it means every rewriter failed.
|
// If the execution reaches here, it means every rewriter failed.
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
}
|
}
|
||||||
std::ostream & orelse_rewriter_cell::display(std::ostream & out) const {
|
ostream & orelse_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Or_RW({";
|
out << "Or_RW({";
|
||||||
for_each(m_rwlist, [&out](rewriter const & rw) {
|
for (rewriter const & rw : m_rwlist) { out << rw << "; "; }
|
||||||
out << rw << "; ";
|
|
||||||
});
|
|
||||||
out << "})";
|
out << "})";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ std::ostream & orelse_rewriter_cell::display(std::ostream & out) const {
|
||||||
// Then Rewriter
|
// Then Rewriter
|
||||||
then_rewriter_cell::then_rewriter_cell(rewriter const & rw1, rewriter const & rw2)
|
then_rewriter_cell::then_rewriter_cell(rewriter const & rw1, rewriter const & rw2)
|
||||||
:rewriter_cell(rewriter_kind::Then), m_rwlist({rw1, rw2}) { }
|
:rewriter_cell(rewriter_kind::Then), m_rwlist({rw1, rw2}) { }
|
||||||
then_rewriter_cell::then_rewriter_cell(std::initializer_list<rewriter> const & l)
|
then_rewriter_cell::then_rewriter_cell(initializer_list<rewriter> const & l)
|
||||||
:rewriter_cell(rewriter_kind::Then), m_rwlist(l) {
|
:rewriter_cell(rewriter_kind::Then), m_rwlist(l) {
|
||||||
lean_assert(l.size() >= 2);
|
lean_assert(l.size() >= 2);
|
||||||
}
|
}
|
||||||
|
@ -158,11 +158,9 @@ pair<expr, expr> then_rewriter_cell::operator()(environment const & env, context
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
std::ostream & then_rewriter_cell::display(std::ostream & out) const {
|
ostream & then_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Then_RW({";
|
out << "Then_RW({";
|
||||||
for_each(m_rwlist, [&out](rewriter const & rw) {
|
for (rewriter const & rw : m_rwlist) { out << rw << "; "; }
|
||||||
out << rw << "; ";
|
|
||||||
});
|
|
||||||
out << "})";
|
out << "})";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -170,7 +168,7 @@ std::ostream & then_rewriter_cell::display(std::ostream & out) const {
|
||||||
// Try Rewriter
|
// Try Rewriter
|
||||||
try_rewriter_cell::try_rewriter_cell(rewriter const & rw1, rewriter const & rw2)
|
try_rewriter_cell::try_rewriter_cell(rewriter const & rw1, rewriter const & rw2)
|
||||||
:rewriter_cell(rewriter_kind::Try), m_rwlist({rw1, rw2}) { }
|
:rewriter_cell(rewriter_kind::Try), m_rwlist({rw1, rw2}) { }
|
||||||
try_rewriter_cell::try_rewriter_cell(std::initializer_list<rewriter> const & l)
|
try_rewriter_cell::try_rewriter_cell(initializer_list<rewriter> const & l)
|
||||||
:rewriter_cell(rewriter_kind::Try), m_rwlist(l) {
|
:rewriter_cell(rewriter_kind::Try), m_rwlist(l) {
|
||||||
lean_assert(l.size() >= 1);
|
lean_assert(l.size() >= 1);
|
||||||
}
|
}
|
||||||
|
@ -187,11 +185,9 @@ pair<expr, expr> try_rewriter_cell::operator()(environment const & env, context
|
||||||
expr const & t = type_inferer(env)(v, ctx);
|
expr const & t = type_inferer(env)(v, ctx);
|
||||||
return make_pair(v, Refl(t, v));
|
return make_pair(v, Refl(t, v));
|
||||||
}
|
}
|
||||||
std::ostream & try_rewriter_cell::display(std::ostream & out) const {
|
ostream & try_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Try_RW({";
|
out << "Try_RW({";
|
||||||
for_each(m_rwlist, [&out](rewriter const & rw) {
|
for (rewriter const & rw : m_rwlist) { out << rw << "; "; }
|
||||||
out << rw << "; ";
|
|
||||||
});
|
|
||||||
out << "})";
|
out << "})";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -204,79 +200,14 @@ pair<expr, expr> app_rewriter_cell::operator()(environment const & env, context
|
||||||
if (!is_app(v))
|
if (!is_app(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
|
|
||||||
unsigned n = num_args(v);
|
buffer<pair<expr, expr>> results;
|
||||||
lean_assert_ge(n, 2);
|
for (unsigned i = 0; i < num_args(v); i++) {
|
||||||
expr f = arg(v, 0);
|
results.push_back(m_rw(env, ctx, arg(v, i)));
|
||||||
pair<expr, expr> result = m_rw(env, ctx, f);
|
|
||||||
expr new_f = result.first;
|
|
||||||
bool f_changed = (f != new_f);
|
|
||||||
|
|
||||||
for (unsigned i = 1; i < n; i++) {
|
|
||||||
// Information about f
|
|
||||||
new_f = result.first;
|
|
||||||
expr proof_f = result.second;
|
|
||||||
type_inferer lc(env);
|
|
||||||
expr const & f_ty = lc(f, ctx);
|
|
||||||
lean_assert(is_pi(f_ty));
|
|
||||||
expr f_ty_domain = abst_domain(f_ty); // A
|
|
||||||
expr f_ty_body = mk_lambda(abst_name(f_ty), f_ty_domain, abst_body(f_ty)); // B
|
|
||||||
|
|
||||||
// Information about arg_i
|
|
||||||
expr arg_i = arg(v, i);
|
|
||||||
pair<expr, expr> new_result = m_rw(env, ctx, arg_i);
|
|
||||||
expr new_arg_i = new_result.first;
|
|
||||||
expr proof_arg_i = new_result.second;
|
|
||||||
bool arg_changed = (arg_i != new_arg_i);
|
|
||||||
|
|
||||||
if (f_changed) {
|
|
||||||
if (arg_changed) {
|
|
||||||
// Congr : Pi (A : Type u) (B : A -> Type u) (f g : Pi (x : A) B x) (a b : A) (H1 : f = g) (H2 : a = b), f a = g b
|
|
||||||
expr new_v = new_f(new_arg_i);
|
|
||||||
expr new_proof = Congr(f_ty_domain,
|
|
||||||
f_ty_body,
|
|
||||||
f,
|
|
||||||
new_f,
|
|
||||||
arg_i,
|
|
||||||
new_arg_i,
|
|
||||||
proof_f,
|
|
||||||
proof_arg_i);
|
|
||||||
result = make_pair(new_v, new_proof);
|
|
||||||
} else {
|
|
||||||
// Congr1 : Pi (A : Type u) (B : A -> Type u) (f g: Pi (x : A) B x) (a : A) (H : f = g), f a = g a
|
|
||||||
expr new_v = new_f(new_arg_i);
|
|
||||||
expr new_proof = Congr1(f_ty_domain,
|
|
||||||
f_ty_body,
|
|
||||||
f,
|
|
||||||
new_f,
|
|
||||||
arg_i,
|
|
||||||
proof_f);
|
|
||||||
result = make_pair(new_v, new_proof);
|
|
||||||
}
|
}
|
||||||
} else {
|
return rewrite_app(env, ctx, v, results);
|
||||||
if (arg_changed) {
|
|
||||||
// Congr2 : Pi (A : Type u) (B : A -> Type u) (a b : A) (f : Pi (x : A) B x) (H : a = b), f a = f b
|
|
||||||
expr new_v = new_f(new_arg_i);
|
|
||||||
expr new_proof = Congr2(f_ty_domain,
|
|
||||||
f_ty_body,
|
|
||||||
arg_i,
|
|
||||||
new_arg_i,
|
|
||||||
f,
|
|
||||||
proof_arg_i);
|
|
||||||
result = make_pair(new_v, new_proof);
|
|
||||||
f_changed = true;
|
|
||||||
} else {
|
|
||||||
// Refl
|
|
||||||
expr new_v = new_f(new_arg_i);
|
|
||||||
expr new_proof = Refl(lc(new_f, ctx), new_f);
|
|
||||||
result = make_pair(new_v, new_proof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f = f(arg_i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & app_rewriter_cell::display(std::ostream & out) const {
|
ostream & app_rewriter_cell::display(ostream & out) const {
|
||||||
out << "App_RW(" << m_rw << ")";
|
out << "App_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -290,25 +221,16 @@ pair<expr, expr> lambda_type_rewriter_cell::operator()(environment const & env,
|
||||||
if (!is_lambda(v))
|
if (!is_lambda(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
expr const & ty = abst_domain(v);
|
expr const & ty = abst_domain(v);
|
||||||
pair<expr, expr> result = m_rw(env, ctx, ty);
|
type_inferer ti(env);
|
||||||
expr const & new_ty = result.first;
|
pair<expr, expr> result_ty = m_rw(env, ctx, ty);
|
||||||
type_inferer lc(env);
|
if (ty != result_ty.first) {
|
||||||
expr const & ty_of_v = lc(v, ctx);
|
return rewrite_lambda_type(env, ctx, v, result_ty);
|
||||||
if (ty != new_ty) {
|
|
||||||
expr const & new_v = mk_lambda(abst_name(v), new_ty, abst_body(v));
|
|
||||||
expr const & ty_of_ty = lc(ty, ctx);
|
|
||||||
expr proof = Subst(ty_of_ty, ty, new_ty,
|
|
||||||
Fun({Const("x"), ty_of_ty},
|
|
||||||
Eq(mk_lambda(abst_name(v), ty, abst_body(v)),
|
|
||||||
mk_lambda(abst_name(v), Const("x"), abst_body(v)))),
|
|
||||||
Refl(ty_of_v, v),
|
|
||||||
result.second);
|
|
||||||
return make_pair(new_v, proof);
|
|
||||||
} else {
|
} else {
|
||||||
return make_pair(v, Refl(ty_of_v, v));
|
// nothing changed
|
||||||
|
return make_pair(v, Refl(ti(v, ctx), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostream & lambda_type_rewriter_cell::display(std::ostream & out) const {
|
ostream & lambda_type_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Lambda_Type_RW(" << m_rw << ")";
|
out << "Lambda_Type_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -321,29 +243,22 @@ lambda_body_rewriter_cell::~lambda_body_rewriter_cell() { }
|
||||||
pair<expr, expr> lambda_body_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
pair<expr, expr> lambda_body_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
||||||
if (!is_lambda(v))
|
if (!is_lambda(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
expr const & body = abst_body(v);
|
|
||||||
name const & n = abst_name(v);
|
name const & n = abst_name(v);
|
||||||
expr const & ty = abst_domain(v);
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
context new_ctx = extend(ctx, n, ty);
|
context new_ctx = extend(ctx, n, ty);
|
||||||
pair<expr, expr> result = m_rw(env, new_ctx, body);
|
pair<expr, expr> result_body = m_rw(env, new_ctx, body);
|
||||||
type_inferer lc(env);
|
if (body != result_body.first) {
|
||||||
expr const & ty_of_v = lc(v, ctx);
|
// body changed
|
||||||
expr const & new_body = result.first;
|
return rewrite_lambda_body(env, ctx, v, result_body);
|
||||||
if (body != new_body) {
|
|
||||||
expr const & new_v = mk_lambda(n, ty, new_body);
|
|
||||||
expr const & ty_of_body = lc(body, new_ctx);
|
|
||||||
expr proof = Subst(ty_of_body, body, new_body,
|
|
||||||
Fun({Const("x"), ty_of_body},
|
|
||||||
Eq(mk_lambda(abst_name(v), ty, abst_body(v)),
|
|
||||||
mk_lambda(abst_name(v), ty, Const("x")))),
|
|
||||||
Refl(ty_of_v, v),
|
|
||||||
result.second);
|
|
||||||
return make_pair(new_v, proof);
|
|
||||||
} else {
|
} else {
|
||||||
return make_pair(v, Refl(ty_of_v, v));
|
// nothing changed
|
||||||
|
type_inferer ti(env);
|
||||||
|
return make_pair(v, Refl(ti(v, ctx), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostream & lambda_body_rewriter_cell::display(std::ostream & out) const {
|
ostream & lambda_body_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Lambda_Body_RW(" << m_rw << ")";
|
out << "Lambda_Body_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +275,7 @@ pair<expr, expr> lambda_rewriter_cell::operator()(environment const & env, conte
|
||||||
mk_lambda_body_rewriter(m_rw));
|
mk_lambda_body_rewriter(m_rw));
|
||||||
return rw(env, ctx, v);
|
return rw(env, ctx, v);
|
||||||
}
|
}
|
||||||
std::ostream & lambda_rewriter_cell::display(std::ostream & out) const {
|
ostream & lambda_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Lambda_RW(" << m_rw << ")";
|
out << "Lambda_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -373,26 +288,18 @@ pi_type_rewriter_cell::~pi_type_rewriter_cell() { }
|
||||||
pair<expr, expr> pi_type_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
pair<expr, expr> pi_type_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
||||||
if (!is_pi(v))
|
if (!is_pi(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
|
|
||||||
expr const & ty = abst_domain(v);
|
expr const & ty = abst_domain(v);
|
||||||
pair<expr, expr> result = m_rw(env, ctx, ty);
|
pair<expr, expr> result_ty = m_rw(env, ctx, ty);
|
||||||
expr const & new_ty = result.first;
|
if (ty != result_ty.first) {
|
||||||
type_inferer lc(env);
|
return rewrite_pi_type(env, ctx, v, result_ty);
|
||||||
expr const & ty_of_v = lc(v, ctx);
|
|
||||||
if (ty != new_ty) {
|
|
||||||
expr const & new_v = mk_pi(abst_name(v), new_ty, abst_body(v));
|
|
||||||
expr const & ty_of_ty = lc(ty, ctx);
|
|
||||||
expr proof = Subst(ty_of_ty, ty, new_ty,
|
|
||||||
Fun({Const("x"), ty_of_ty},
|
|
||||||
Eq(mk_pi(abst_name(v), ty, abst_body(v)),
|
|
||||||
mk_pi(abst_name(v), Const("x"), abst_body(v)))),
|
|
||||||
Refl(ty_of_v, v),
|
|
||||||
result.second);
|
|
||||||
return make_pair(new_v, proof);
|
|
||||||
} else {
|
} else {
|
||||||
return make_pair(v, Refl(ty_of_v, v));
|
// nothing changed
|
||||||
|
type_inferer ti(env);
|
||||||
|
return make_pair(v, Refl(ti(v, ctx), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostream & pi_type_rewriter_cell::display(std::ostream & out) const {
|
ostream & pi_type_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Pi_Type_RW(" << m_rw << ")";
|
out << "Pi_Type_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -405,29 +312,22 @@ pi_body_rewriter_cell::~pi_body_rewriter_cell() { }
|
||||||
pair<expr, expr> pi_body_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
pair<expr, expr> pi_body_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
||||||
if (!is_pi(v))
|
if (!is_pi(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
expr const & body = abst_body(v);
|
|
||||||
name const & n = abst_name(v);
|
name const & n = abst_name(v);
|
||||||
expr const & ty = abst_domain(v);
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
context new_ctx = extend(ctx, n, ty);
|
context new_ctx = extend(ctx, n, ty);
|
||||||
pair<expr, expr> result = m_rw(env, new_ctx, body);
|
pair<expr, expr> result_body = m_rw(env, new_ctx, body);
|
||||||
type_inferer lc(env);
|
if (body != result_body.first) {
|
||||||
expr const & ty_of_v = lc(v, ctx);
|
// body changed
|
||||||
expr const & new_body = result.first;
|
return rewrite_pi_body(env, ctx, v, result_body);
|
||||||
if (body != new_body) {
|
|
||||||
expr const & new_v = mk_pi(n, ty, new_body);
|
|
||||||
expr const & ty_of_body = lc(body, new_ctx);
|
|
||||||
expr proof = Subst(ty_of_body, body, new_body,
|
|
||||||
Fun({Const("x"), ty_of_body},
|
|
||||||
Eq(mk_pi(abst_name(v), ty, abst_body(v)),
|
|
||||||
mk_pi(abst_name(v), ty, Const("x")))),
|
|
||||||
Refl(ty_of_v, v),
|
|
||||||
result.second);
|
|
||||||
return make_pair(new_v, proof);
|
|
||||||
} else {
|
} else {
|
||||||
return make_pair(v, Refl(ty_of_v, v));
|
// nothing changed
|
||||||
|
type_inferer ti(env);
|
||||||
|
return make_pair(v, Refl(ti(v, ctx), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostream & pi_body_rewriter_cell::display(std::ostream & out) const {
|
ostream & pi_body_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Pi_Body_RW(" << m_rw << ")";
|
out << "Pi_Body_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +343,7 @@ pair<expr, expr> pi_rewriter_cell::operator()(environment const & env, context &
|
||||||
mk_pi_body_rewriter(m_rw));
|
mk_pi_body_rewriter(m_rw));
|
||||||
return rw(env, ctx, v);
|
return rw(env, ctx, v);
|
||||||
}
|
}
|
||||||
std::ostream & pi_rewriter_cell::display(std::ostream & out) const {
|
ostream & pi_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Pi_RW(" << m_rw << ")";
|
out << "Pi_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -455,26 +355,18 @@ let_type_rewriter_cell::~let_type_rewriter_cell() { }
|
||||||
pair<expr, expr> let_type_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
pair<expr, expr> let_type_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
||||||
if (!is_let(v))
|
if (!is_let(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
|
|
||||||
expr const & ty = let_type(v);
|
expr const & ty = let_type(v);
|
||||||
pair<expr, expr> result = m_rw(env, ctx, ty);
|
pair<expr, expr> result_ty = m_rw(env, ctx, ty);
|
||||||
expr const & new_ty = result.first;
|
if (ty != result_ty.first) {
|
||||||
type_inferer lc(env);
|
// ty changed
|
||||||
expr const & ty_of_v = lc(v, ctx);
|
return rewrite_let_type(env, ctx, v, result_ty);
|
||||||
if (ty != new_ty) {
|
|
||||||
expr const & new_v = mk_let(let_name(v), new_ty, let_value(v), let_body(v));
|
|
||||||
expr const & ty_of_ty = lc(ty, ctx);
|
|
||||||
expr proof = Subst(ty_of_ty, ty, new_ty,
|
|
||||||
Fun({Const("x"), ty_of_ty},
|
|
||||||
Eq(mk_let(let_name(v), ty, let_value(v), let_body(v)),
|
|
||||||
mk_let(let_name(v), Const("x"), let_value(v), let_body(v)))),
|
|
||||||
Refl(ty_of_v, v),
|
|
||||||
result.second);
|
|
||||||
return make_pair(new_v, proof);
|
|
||||||
} else {
|
} else {
|
||||||
return make_pair(v, Refl(ty_of_v, v));
|
type_inferer ti(env);
|
||||||
|
return make_pair(v, Refl(ti(v, ctx), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostream & let_type_rewriter_cell::display(std::ostream & out) const {
|
ostream & let_type_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Let_Type_RW(" << m_rw << ")";
|
out << "Let_Type_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -486,26 +378,18 @@ let_value_rewriter_cell::~let_value_rewriter_cell() { }
|
||||||
pair<expr, expr> let_value_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
pair<expr, expr> let_value_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
||||||
if (!is_let(v))
|
if (!is_let(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
|
|
||||||
expr const & val = let_value(v);
|
expr const & val = let_value(v);
|
||||||
pair<expr, expr> result = m_rw(env, ctx, val);
|
pair<expr, expr> result_val = m_rw(env, ctx, val);
|
||||||
expr const & new_val = result.first;
|
if (val != result_val.first) {
|
||||||
type_inferer lc(env);
|
// ty changed
|
||||||
expr const & ty_of_v = lc(v, ctx);
|
return rewrite_let_value(env, ctx, v, result_val);
|
||||||
if (val != new_val) {
|
|
||||||
expr const & new_v = mk_let(let_name(v), let_type(v), new_val, let_body(v));
|
|
||||||
expr const & ty_of_val = lc(val, ctx);
|
|
||||||
expr proof = Subst(ty_of_val, val, new_val,
|
|
||||||
Fun({Const("x"), ty_of_val},
|
|
||||||
Eq(mk_let(let_name(v), let_type(v), let_value(v), let_body(v)),
|
|
||||||
mk_let(let_name(v), let_type(v), Const("x"), let_body(v)))),
|
|
||||||
Refl(ty_of_v, v),
|
|
||||||
result.second);
|
|
||||||
return make_pair(new_v, proof);
|
|
||||||
} else {
|
} else {
|
||||||
return make_pair(v, Refl(ty_of_v, v));
|
type_inferer ti(env);
|
||||||
|
return make_pair(v, Refl(ti(v, ctx), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostream & let_value_rewriter_cell::display(std::ostream & out) const {
|
ostream & let_value_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Let_Value_RW(" << m_rw << ")";
|
out << "Let_Value_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -518,30 +402,20 @@ pair<expr, expr> let_body_rewriter_cell::operator()(environment const & env, con
|
||||||
if (!is_let(v))
|
if (!is_let(v))
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
|
|
||||||
expr const & body = let_body(v);
|
|
||||||
name const & n = let_name(v);
|
name const & n = let_name(v);
|
||||||
expr const & ty = let_type(v);
|
expr const & ty = let_type(v);
|
||||||
expr const & val = let_value(v);
|
expr const & val = let_value(v);
|
||||||
|
expr const & body = let_body(v);
|
||||||
context new_ctx = extend(ctx, n, ty);
|
context new_ctx = extend(ctx, n, ty);
|
||||||
pair<expr, expr> result = m_rw(env, new_ctx, body);
|
pair<expr, expr> result_body = m_rw(env, new_ctx, body);
|
||||||
type_inferer lc(env);
|
if (body != result_body.first) {
|
||||||
expr const & ty_of_v = lc(v, ctx);
|
return rewrite_let_body(env, ctx, v, result_body);
|
||||||
expr const & new_body = result.first;
|
|
||||||
if (body != new_body) {
|
|
||||||
expr const & new_v = mk_let(n, ty, val, new_body);
|
|
||||||
expr const & ty_of_body = lc(body, new_ctx);
|
|
||||||
expr proof = Subst(ty_of_body, body, new_body,
|
|
||||||
Fun({Const("x"), ty_of_body},
|
|
||||||
Eq(mk_let(let_name(v), let_type(v), let_value(v), let_body(v)),
|
|
||||||
mk_let(let_name(v), let_type(v), let_value(v), Const("x")))),
|
|
||||||
Refl(ty_of_v, v),
|
|
||||||
result.second);
|
|
||||||
return make_pair(new_v, proof);
|
|
||||||
} else {
|
} else {
|
||||||
return make_pair(v, Refl(ty_of_v, v));
|
type_inferer ti(env);
|
||||||
|
return make_pair(v, Refl(ti(v, ctx), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostream & let_body_rewriter_cell::display(std::ostream & out) const {
|
ostream & let_body_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Let_Body_RW(" << m_rw << ")";
|
out << "Let_Body_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -558,7 +432,7 @@ pair<expr, expr> let_rewriter_cell::operator()(environment const & env, context
|
||||||
mk_let_body_rewriter(m_rw)});
|
mk_let_body_rewriter(m_rw)});
|
||||||
return rw(env, ctx, v);
|
return rw(env, ctx, v);
|
||||||
}
|
}
|
||||||
std::ostream & let_rewriter_cell::display(std::ostream & out) const {
|
ostream & let_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Let_RW(" << m_rw << ")";
|
out << "Let_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -569,7 +443,7 @@ fail_rewriter_cell::~fail_rewriter_cell() { }
|
||||||
pair<expr, expr> fail_rewriter_cell::operator()(environment const &, context &, expr const &) const throw(rewriter_exception) {
|
pair<expr, expr> fail_rewriter_cell::operator()(environment const &, context &, expr const &) const throw(rewriter_exception) {
|
||||||
throw rewriter_exception();
|
throw rewriter_exception();
|
||||||
}
|
}
|
||||||
std::ostream & fail_rewriter_cell::display(std::ostream & out) const {
|
ostream & fail_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Fail_RW()";
|
out << "Fail_RW()";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -581,7 +455,7 @@ pair<expr, expr> success_rewriter_cell::operator()(environment const & env, cont
|
||||||
expr const & t = type_inferer(env)(v, ctx);
|
expr const & t = type_inferer(env)(v, ctx);
|
||||||
return make_pair(v, Refl(t, v));
|
return make_pair(v, Refl(t, v));
|
||||||
}
|
}
|
||||||
std::ostream & success_rewriter_cell::display(std::ostream & out) const {
|
ostream & success_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Success_RW()";
|
out << "Success_RW()";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -591,13 +465,13 @@ repeat_rewriter_cell::repeat_rewriter_cell(rewriter const & rw):rewriter_cell(re
|
||||||
repeat_rewriter_cell::~repeat_rewriter_cell() { }
|
repeat_rewriter_cell::~repeat_rewriter_cell() { }
|
||||||
pair<expr, expr> repeat_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
pair<expr, expr> repeat_rewriter_cell::operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception) {
|
||||||
pair<expr, expr> result = mk_success_rewriter()(env, ctx, v);
|
pair<expr, expr> result = mk_success_rewriter()(env, ctx, v);
|
||||||
type_inferer lc(env);
|
type_inferer ti(env);
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
pair<expr, expr> new_result = m_rw(env, ctx, result.first);
|
pair<expr, expr> new_result = m_rw(env, ctx, result.first);
|
||||||
if (result.first == new_result.first)
|
if (result.first == new_result.first)
|
||||||
break;
|
break;
|
||||||
expr const & ty = lc(v, ctx);
|
expr const & ty = ti(v, ctx);
|
||||||
result = make_pair(new_result.first,
|
result = make_pair(new_result.first,
|
||||||
Trans(ty, v, result.first, new_result.first, result.second, new_result.second));
|
Trans(ty, v, result.first, new_result.first, result.second, new_result.second));
|
||||||
}
|
}
|
||||||
|
@ -606,18 +480,30 @@ pair<expr, expr> repeat_rewriter_cell::operator()(environment const & env, conte
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
std::ostream & repeat_rewriter_cell::display(std::ostream & out) const {
|
ostream & repeat_rewriter_cell::display(ostream & out) const {
|
||||||
out << "Repeat_RW(" << m_rw << ")";
|
out << "Repeat_RW(" << m_rw << ")";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Depth rewriter
|
||||||
|
depth_rewriter_cell::depth_rewriter_cell(rewriter const & rw):rewriter_cell(rewriter_kind::Depth), m_rw(rw) { }
|
||||||
|
depth_rewriter_cell::~depth_rewriter_cell() { }
|
||||||
|
pair<expr, expr> depth_rewriter_cell::operator()(environment const &, context &, expr const &) const throw(rewriter_exception) {
|
||||||
|
// TODO(soonhok): implement
|
||||||
|
throw rewriter_exception();
|
||||||
|
}
|
||||||
|
ostream & depth_rewriter_cell::display(ostream & out) const {
|
||||||
|
out << "Depth_RW(" << m_rw << ")";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
rewriter mk_theorem_rewriter(expr const & type, expr const & body) {
|
rewriter mk_theorem_rewriter(expr const & type, expr const & body) {
|
||||||
return rewriter(new theorem_rewriter_cell(type, body));
|
return rewriter(new theorem_rewriter_cell(type, body));
|
||||||
}
|
}
|
||||||
rewriter mk_then_rewriter(rewriter const & rw1, rewriter const & rw2) {
|
rewriter mk_then_rewriter(rewriter const & rw1, rewriter const & rw2) {
|
||||||
return rewriter(new then_rewriter_cell(rw1, rw2));
|
return rewriter(new then_rewriter_cell(rw1, rw2));
|
||||||
}
|
}
|
||||||
rewriter mk_then_rewriter(std::initializer_list<rewriter> const & l) {
|
rewriter mk_then_rewriter(initializer_list<rewriter> const & l) {
|
||||||
return rewriter(new then_rewriter_cell(l));
|
return rewriter(new then_rewriter_cell(l));
|
||||||
}
|
}
|
||||||
rewriter mk_try_rewriter(rewriter const & rw) {
|
rewriter mk_try_rewriter(rewriter const & rw) {
|
||||||
|
@ -626,13 +512,13 @@ rewriter mk_try_rewriter(rewriter const & rw) {
|
||||||
rewriter mk_try_rewriter(rewriter const & rw1, rewriter const & rw2) {
|
rewriter mk_try_rewriter(rewriter const & rw1, rewriter const & rw2) {
|
||||||
return rewriter(new try_rewriter_cell(rw1, rw2));
|
return rewriter(new try_rewriter_cell(rw1, rw2));
|
||||||
}
|
}
|
||||||
rewriter mk_try_rewriter(std::initializer_list<rewriter> const & l) {
|
rewriter mk_try_rewriter(initializer_list<rewriter> const & l) {
|
||||||
return rewriter(new try_rewriter_cell(l));
|
return rewriter(new try_rewriter_cell(l));
|
||||||
}
|
}
|
||||||
rewriter mk_orelse_rewriter(rewriter const & rw1, rewriter const & rw2) {
|
rewriter mk_orelse_rewriter(rewriter const & rw1, rewriter const & rw2) {
|
||||||
return rewriter(new orelse_rewriter_cell(rw1, rw2));
|
return rewriter(new orelse_rewriter_cell(rw1, rw2));
|
||||||
}
|
}
|
||||||
rewriter mk_orelse_rewriter(std::initializer_list<rewriter> const & l) {
|
rewriter mk_orelse_rewriter(initializer_list<rewriter> const & l) {
|
||||||
return rewriter(new orelse_rewriter_cell(l));
|
return rewriter(new orelse_rewriter_cell(l));
|
||||||
}
|
}
|
||||||
rewriter mk_app_rewriter(rewriter const & rw) {
|
rewriter mk_app_rewriter(rewriter const & rw) {
|
||||||
|
@ -677,4 +563,415 @@ rewriter mk_success_rewriter() {
|
||||||
rewriter mk_repeat_rewriter(rewriter const & rw) {
|
rewriter mk_repeat_rewriter(rewriter const & rw) {
|
||||||
return rewriter(new repeat_rewriter_cell(rw));
|
return rewriter(new repeat_rewriter_cell(rw));
|
||||||
}
|
}
|
||||||
|
rewriter mk_depth_rewriter(rewriter const & rw) {
|
||||||
|
return rewriter(new depth_rewriter_cell(rw));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (lambda n : ty. body)
|
||||||
|
// rewritten ty, new_ty
|
||||||
|
// proof of (ty = new_ty), pf_ty
|
||||||
|
// Output:
|
||||||
|
// the result new_v = (lambda n : new_ty. body),
|
||||||
|
// proof of (lambda n : ty. body) = (lambda n : new_ty. body)
|
||||||
|
pair<expr, expr> rewrite_lambda_type(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_ty) {
|
||||||
|
lean_assert(is_lambda(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & new_ty = result_ty.first;
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
if (ty == new_ty) {
|
||||||
|
return make_pair(v, Refl(ty_v, v));
|
||||||
|
} else {
|
||||||
|
name const & n = abst_name(v);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
|
expr const & pf_ty = result_ty.second;
|
||||||
|
expr const & new_v = mk_lambda(n, new_ty, body);
|
||||||
|
expr const & ty_ty = ti(ty, ctx);
|
||||||
|
lean_assert_eq(ty_ty, ti(new_ty, ctx)); // TODO(soonhok): generalize for hetreogeneous types
|
||||||
|
expr const & proof = Subst(ty_ty, ty, new_ty,
|
||||||
|
Fun({Const("T"), ty_ty},
|
||||||
|
mk_eq(v, mk_lambda(n, Const("T"), body))),
|
||||||
|
Refl(ty_v, v), pf_ty);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (lambda n : ty. body)
|
||||||
|
// rewritten body, new_body
|
||||||
|
// proof of (body = new_body), pf_body
|
||||||
|
// Output:
|
||||||
|
// the result new_v = (lambda n : ty. new_body),
|
||||||
|
// proof of (lambda n : ty. body) = (lambda n : ty. new_body)
|
||||||
|
pair<expr, expr> rewrite_lambda_body(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_body) {
|
||||||
|
lean_assert(is_lambda(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
|
expr const & new_body = result_body.first;
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
if (body == new_body) {
|
||||||
|
return make_pair(v, Refl(ty_v, v));
|
||||||
|
} else {
|
||||||
|
name const & n = abst_name(v);
|
||||||
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & pf_body = result_body.second;
|
||||||
|
expr const & new_v = mk_lambda(n, ty, new_body);
|
||||||
|
expr const & ty_body = ti(body, extend(ctx, n, ty));
|
||||||
|
lean_assert_eq(ty_body, ti(new_body, ctx)); // TODO(soonhok): generalize for hetreogeneous types
|
||||||
|
expr const & proof = Subst(ty_body, body, new_body,
|
||||||
|
Fun({Const("e"), ty_body},
|
||||||
|
mk_eq(v, mk_lambda(n, ty, Const("e")))),
|
||||||
|
Refl(ty_v, v), pf_body);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generalized version of rewrite_labmda_type and rewrite_lambda_body
|
||||||
|
// Input:
|
||||||
|
// v = (lambda n : ty. body)
|
||||||
|
// rewritten ty, new_ty and proof of (ty = new_ty), pf_ty
|
||||||
|
// rewritten body, new_body and proof of (body = new_body), pf_body
|
||||||
|
// Output:
|
||||||
|
// new_v = (lambda n : new_ty. new_body)
|
||||||
|
// proof of (lambda n : ty. body) = (lambda n : new_ty. new_body)
|
||||||
|
pair<expr, expr> rewrite_lambda(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_ty, pair<expr, expr> const & result_body) {
|
||||||
|
lean_assert(is_lambda(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
name const & n = abst_name(v);
|
||||||
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
|
expr const & new_ty = result_ty.first;
|
||||||
|
expr const & pf_ty = result_ty.second;
|
||||||
|
expr const & new_body = result_body.first;
|
||||||
|
expr const & pf_body = result_body.second;
|
||||||
|
expr const & ty_ty = ti(ty, ctx);
|
||||||
|
expr const & ty_body = ti(body, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & new_v1 = mk_lambda(n, new_ty, body);
|
||||||
|
expr const & ty_new_v1 = ti(v, ctx);
|
||||||
|
expr const & new_v2 = mk_lambda(n, new_ty, new_body);
|
||||||
|
// proof1 : v = new_v1
|
||||||
|
expr const & proof1 = Subst(ty_ty, ty, new_ty,
|
||||||
|
Fun({Const("T"), ty_ty},
|
||||||
|
mk_eq(v, mk_lambda(n, Const("T"), body))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf_ty);
|
||||||
|
// proof2 : new_v1 = new_v2
|
||||||
|
expr const & proof2 = Subst(ty_body, body, new_body,
|
||||||
|
Fun({Const("e"), ty_body},
|
||||||
|
mk_eq(new_v1, mk_lambda(n, new_ty, Const("e")))),
|
||||||
|
Refl(ty_new_v1, new_v1),
|
||||||
|
pf_body);
|
||||||
|
expr const & proof = Trans(ty_v, v, new_v1, new_v2, proof1, proof2);
|
||||||
|
return make_pair(new_v2, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (Pi n : ty. body)
|
||||||
|
// rewritten ty, new_ty
|
||||||
|
// proof of (ty = new_ty), pf_ty
|
||||||
|
// Output:
|
||||||
|
// the result new_v = (Pi n : new_ty. body),
|
||||||
|
// proof of (Pi n : ty. body) = (Pi n : new_ty. body)
|
||||||
|
pair<expr, expr> rewrite_pi_type(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_ty) {
|
||||||
|
lean_assert(is_pi(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
name const & n = abst_name(v);
|
||||||
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
|
expr const & new_ty = result_ty.first;
|
||||||
|
expr const & pf = result_ty.second;
|
||||||
|
expr const & new_v = mk_pi(n, new_ty, body);
|
||||||
|
expr const & ty_ty = ti(ty, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & proof = Subst(ty_ty, ty, new_ty,
|
||||||
|
Fun({Const("T"), ty_ty},
|
||||||
|
mk_eq(v, mk_pi(n, Const("T"), body))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (Pi n : ty. body)
|
||||||
|
// rewritten body, new_body
|
||||||
|
// proof of (body = new_body), pf_body
|
||||||
|
// Output:
|
||||||
|
// the result new_v = (Pi n : ty. new_body),
|
||||||
|
// proof of (Pi n : ty. body) = (Pi n : ty. new_body)
|
||||||
|
pair<expr, expr> rewrite_pi_body(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_body) {
|
||||||
|
lean_assert(is_pi(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
name const & n = abst_name(v);
|
||||||
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
|
expr const & new_body = result_body.first;
|
||||||
|
expr const & pf = result_body.second;
|
||||||
|
expr const & new_v = mk_pi(n, ty, new_body);
|
||||||
|
expr const & ty_body = ti(body, extend(ctx, n, ty));
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & proof = Subst(ty_body, body, new_body,
|
||||||
|
Fun({Const("e"), ty_body},
|
||||||
|
mk_eq(v, mk_pi(n, ty, Const("e")))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generalized version of rewrite_labmda_type and rewrite_Pi_body
|
||||||
|
// Input:
|
||||||
|
// v = (Pi n : ty. body)
|
||||||
|
// rewritten ty, new_ty and proof of (ty = new_ty), pf_ty
|
||||||
|
// rewritten body, new_body and proof of (body = new_body), pf_body
|
||||||
|
// Output:
|
||||||
|
// new_v = (Pi n : new_ty. new_body)
|
||||||
|
// proof of (Pi n : ty. body) = (Pi n : new_ty. new_body)
|
||||||
|
pair<expr, expr> rewrite_pi(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_ty, pair<expr, expr> const & result_body) {
|
||||||
|
lean_assert(is_pi(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
name const & n = abst_name(v);
|
||||||
|
expr const & ty = abst_domain(v);
|
||||||
|
expr const & body = abst_body(v);
|
||||||
|
expr const & new_ty = result_ty.first;
|
||||||
|
expr const & pf_ty = result_ty.second;
|
||||||
|
expr const & new_body = result_body.first;
|
||||||
|
expr const & pf_body = result_body.second;
|
||||||
|
expr const & ty_ty = ti(ty, ctx);
|
||||||
|
expr const & ty_body = ti(body, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & new_v1 = mk_pi(n, new_ty, body);
|
||||||
|
expr const & ty_new_v1 = ti(v, ctx);
|
||||||
|
expr const & new_v2 = mk_pi(n, new_ty, new_body);
|
||||||
|
// proof1 : v = new_v1
|
||||||
|
expr const & proof1 = Subst(ty_ty, ty, new_ty,
|
||||||
|
Fun({Const("T"), ty_ty},
|
||||||
|
mk_eq(v, mk_pi(n, Const("T"), body))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf_ty);
|
||||||
|
// proof2 : new_v1 = new_v2
|
||||||
|
expr const & proof2 = Subst(ty_body, body, new_body,
|
||||||
|
Fun({Const("e"), ty_body},
|
||||||
|
mk_eq(new_v1, mk_pi(n, new_ty, Const("e")))),
|
||||||
|
Refl(ty_new_v1, new_v1),
|
||||||
|
pf_body);
|
||||||
|
expr const & proof = Trans(ty_v, v, new_v1, new_v2, proof1, proof2);
|
||||||
|
return make_pair(new_v2, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (lhs = rhs)
|
||||||
|
// rewritten lhs, new_lhs
|
||||||
|
// proof of (lhs = new_lhs), pf
|
||||||
|
// Output:
|
||||||
|
// new_v = (new_lhs = rhs)
|
||||||
|
// proof of (lhs = rhs) = (new_lhs = rhs)
|
||||||
|
pair<expr, expr> rewrite_eq_lhs(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_lhs) {
|
||||||
|
lean_assert(is_eq(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
expr const & lhs = eq_lhs(v);
|
||||||
|
expr const & rhs = eq_rhs(v);
|
||||||
|
expr const & new_lhs = result_lhs.first;
|
||||||
|
expr const & pf = result_lhs.second;
|
||||||
|
expr const & new_v = mk_eq(new_lhs, rhs);
|
||||||
|
expr const & ty_lhs = ti(lhs, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & proof = Subst(ty_lhs, lhs, new_lhs,
|
||||||
|
Fun({Const("x"), ty_lhs},
|
||||||
|
mk_eq(v, mk_eq(Const("x"), rhs))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (lhs = rhs)
|
||||||
|
// rewritten rhs, new_rhs
|
||||||
|
// proof of (rhs = new_rhs), pf
|
||||||
|
// Output:
|
||||||
|
// new_v = (lhs = new_rhs)
|
||||||
|
// proof of (lhs = rhs) = (lhs = new_rhs)
|
||||||
|
pair<expr, expr> rewrite_eq_rhs(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_rhs) {
|
||||||
|
lean_assert(is_eq(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
expr const & lhs = eq_lhs(v);
|
||||||
|
expr const & rhs = eq_rhs(v);
|
||||||
|
expr const & new_rhs = result_rhs.first;
|
||||||
|
expr const & pf = result_rhs.second;
|
||||||
|
expr const & new_v = mk_eq(rhs, new_rhs);
|
||||||
|
expr const & ty_rhs = ti(rhs, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & proof = Subst(ty_rhs, rhs, new_rhs,
|
||||||
|
Fun({Const("x"), ty_rhs},
|
||||||
|
mk_eq(v, mk_eq(lhs, Const("x")))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generalized version
|
||||||
|
// Input
|
||||||
|
// v = (lhs = rhs)
|
||||||
|
// rewritten lhs, new_lhs and proof of (lhs = new_lhs), pf_lhs
|
||||||
|
// rewritten rhs, new_rhs and proof of (rhs = new_rhs), pf_rhs
|
||||||
|
// Output:
|
||||||
|
// new_v = (new_lhs = new_rhs)
|
||||||
|
// proof of (lhs = rhs) = (new_lhs = new_rhs)
|
||||||
|
pair<expr, expr> rewrite_eq(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_lhs, pair<expr, expr> const & result_rhs) {
|
||||||
|
lean_assert(is_eq(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
expr const & lhs = eq_lhs(v);
|
||||||
|
expr const & rhs = eq_rhs(v);
|
||||||
|
expr const & new_lhs = result_lhs.first;
|
||||||
|
expr const & pf_lhs = result_lhs.second;
|
||||||
|
expr const & new_rhs = result_rhs.first;
|
||||||
|
expr const & pf_rhs = result_rhs.second;
|
||||||
|
expr const & new_v1 = mk_eq(new_lhs, rhs);
|
||||||
|
expr const & new_v2 = mk_eq(new_lhs, new_rhs);
|
||||||
|
expr const & ty_lhs = ti(lhs, ctx);
|
||||||
|
expr const & ty_rhs = ti(rhs, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & ty_new_v1 = ti(new_v1, ctx);
|
||||||
|
// proof1 : v = new_v1
|
||||||
|
expr const & proof1 = Subst(ty_lhs, lhs, new_lhs,
|
||||||
|
Fun({Const("x"), ty_lhs},
|
||||||
|
mk_eq(v, mk_eq(Const("x"), rhs))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf_lhs);
|
||||||
|
// proof2 : new_v1 = new_v2
|
||||||
|
expr const & proof2 = Subst(ty_rhs, rhs, new_rhs,
|
||||||
|
Fun({Const("x"), ty_rhs},
|
||||||
|
mk_eq(v, mk_eq(lhs, Const("x")))),
|
||||||
|
Refl(ty_new_v1, new_v1),
|
||||||
|
pf_rhs);
|
||||||
|
expr const & proof = Trans(ty_v, v, new_v1, new_v2, proof1, proof2);
|
||||||
|
return make_pair(new_v2, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (let n : ty = val in body)
|
||||||
|
// rewritten ty, new_ty
|
||||||
|
// proof of (ty = new_ty), pf
|
||||||
|
// Output:
|
||||||
|
// new_v = (let n : new_ty = val in body)
|
||||||
|
// proof of (let n : ty = val in body) = (let n : new_ty = val in body)
|
||||||
|
pair<expr, expr> rewrite_let_type(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_ty) {
|
||||||
|
lean_assert(is_let(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
name const & n = let_name(v);
|
||||||
|
expr const & ty = let_type(v);
|
||||||
|
expr const & val = let_value(v);
|
||||||
|
expr const & body = let_body(v);
|
||||||
|
expr const & new_ty = result_ty.first;
|
||||||
|
expr const & pf = result_ty.second;
|
||||||
|
expr const & new_v = mk_let(n, new_ty, val, body);
|
||||||
|
expr const & ty_ty = ti(ty, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & proof = Subst(ty_ty, ty, new_ty,
|
||||||
|
Fun({Const("x"), ty_ty},
|
||||||
|
mk_eq(v, mk_let(n, Const("x"), val, body))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (let n : ty = val in body)
|
||||||
|
// rewritten val, new_val
|
||||||
|
// proof of (val = new_val), pf
|
||||||
|
// Output:
|
||||||
|
// new_v = (let n : ty = new_val in body)
|
||||||
|
// proof of (let n : ty = val in body) = (let n : ty = new_val in body)
|
||||||
|
pair<expr, expr> rewrite_let_value(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_value) {
|
||||||
|
lean_assert(is_let(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
name const & n = let_name(v);
|
||||||
|
expr const & ty = let_type(v);
|
||||||
|
expr const & val = let_value(v);
|
||||||
|
expr const & body = let_body(v);
|
||||||
|
expr const & new_val = result_value.first;
|
||||||
|
expr const & pf = result_value.second;
|
||||||
|
expr const & new_v = mk_let(n, ty, new_val, body);
|
||||||
|
expr const & ty_val = ti(val, ctx);
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & proof = Subst(ty_val, val, new_val,
|
||||||
|
Fun({Const("x"), ty_val},
|
||||||
|
mk_eq(v, mk_let(n, ty, Const("x"), body))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (let n : ty = val in body)
|
||||||
|
// rewritten body, new_body
|
||||||
|
// proof of (body = new_body), pf
|
||||||
|
// Output:
|
||||||
|
// new_v = (let n : ty = val in new_body)
|
||||||
|
// proof of (let n : ty = val in body) = (let n : ty = val in new_body)
|
||||||
|
pair<expr, expr> rewrite_let_body(environment const & env, context & ctx, expr const & v, pair<expr, expr> const & result_body) {
|
||||||
|
lean_assert(is_let(v));
|
||||||
|
type_inferer ti(env);
|
||||||
|
name const & n = let_name(v);
|
||||||
|
expr const & ty = let_type(v);
|
||||||
|
expr const & val = let_value(v);
|
||||||
|
expr const & body = let_body(v);
|
||||||
|
expr const & new_body = result_body.first;
|
||||||
|
expr const & pf = result_body.second;
|
||||||
|
expr const & new_v = mk_let(n, ty, val, new_body);
|
||||||
|
expr const & ty_body = ti(body, extend(ctx, n, ty, body));
|
||||||
|
expr const & ty_v = ti(v, ctx);
|
||||||
|
expr const & proof = Subst(ty_body, body, new_body,
|
||||||
|
Fun({Const("e"), ty_body},
|
||||||
|
mk_eq(v, mk_let(n, ty, val, Const("e")))),
|
||||||
|
Refl(ty_v, v),
|
||||||
|
pf);
|
||||||
|
return make_pair(new_v, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
// v = (e_0 e_1 ... e_n)
|
||||||
|
// result_i = (e'_i, proof of e_i = e'_i) for 0 <= i <= n
|
||||||
|
// Output:
|
||||||
|
// new_v = ( e'_0 e'_1 ... e'_n )
|
||||||
|
// proof of (e_0 e_1 ... e_n) = ( e'_0 e'_1 ... e'_n )
|
||||||
|
pair<expr, expr> rewrite_app(environment const & env, context & ctx, expr const & v, buffer<pair<expr, expr>> const & results ) {
|
||||||
|
type_inferer ti(env);
|
||||||
|
expr f = arg(v, 0);
|
||||||
|
expr new_f = results[0].first;
|
||||||
|
expr pf = results[0].second;
|
||||||
|
for (unsigned i = 1; i < results.size(); i++) {
|
||||||
|
expr const & f_ty = ti(f, ctx);
|
||||||
|
lean_assert(is_pi(f_ty));
|
||||||
|
expr const & f_ty_domain = abst_domain(f_ty); // A
|
||||||
|
expr f_ty_body = mk_lambda(abst_name(f_ty), f_ty_domain, abst_body(f_ty)); // B
|
||||||
|
expr const & e_i = arg(v, i);
|
||||||
|
expr const & new_e_i = results[i].first;
|
||||||
|
expr const & pf_e_i = results[i].second;
|
||||||
|
bool f_changed = f != new_f;
|
||||||
|
if (f_changed) {
|
||||||
|
if (arg(v, i) != results[i].first) {
|
||||||
|
// Congr : Pi (A : Type u) (B : A -> Type u) (f g : Pi
|
||||||
|
// (x : A) B x) (a b : A) (H1 : f = g) (H2 : a = b), f
|
||||||
|
// a = g b
|
||||||
|
pf = Congr(f_ty_domain, f_ty_body, f, new_f, e_i, new_e_i, pf, pf_e_i);
|
||||||
|
} else {
|
||||||
|
// Congr1 : Pi (A : Type u) (B : A -> Type u) (f g: Pi
|
||||||
|
// (x : A) B x) (a : A) (H : f = g), f a = g a
|
||||||
|
pf = Congr1(f_ty_domain, f_ty_body, f, new_f, e_i, pf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (arg(v, i) != results[i].first) {
|
||||||
|
// Congr2 : Pi (A : Type u) (B : A -> Type u) (a b : A) (f : Pi (x : A) B x) (H : a = b), f a = f b
|
||||||
|
pf = Congr2(f_ty_domain, f_ty_body, e_i, new_e_i, f, pf_e_i);
|
||||||
|
} else {
|
||||||
|
// Refl
|
||||||
|
pf = Refl(ti(f(e_i), ctx), f(e_i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f = f (e_i);
|
||||||
|
new_f = new_f (new_e_i);
|
||||||
|
}
|
||||||
|
return make_pair(new_f, pf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
Copyright (c) 2013 Microsoft Corporation.
|
||||||
|
Copyright (c) 2013 Carnegie Mellon University.
|
||||||
|
All rights reserved.
|
||||||
Released under Apache 2.0 license as described in the file LICENSE.
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
Author: Soonho Kong
|
Author: Soonho Kong
|
||||||
|
@ -10,15 +12,8 @@ Author: Soonho Kong
|
||||||
#include "util/exception.h"
|
#include "util/exception.h"
|
||||||
#include "kernel/environment.h"
|
#include "kernel/environment.h"
|
||||||
|
|
||||||
// Term Rewriting
|
// TODO(soonhok)
|
||||||
// APP_RW
|
|
||||||
// LAMBDA_RW
|
|
||||||
// PI_RW
|
|
||||||
// LET_RW
|
|
||||||
// DEPTH_RW
|
|
||||||
// TRIVIAL_RW
|
|
||||||
// FORALL
|
// FORALL
|
||||||
// FAIL
|
|
||||||
// FAIL_IF
|
// FAIL_IF
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
@ -33,7 +28,7 @@ enum class rewriter_kind { Theorem, OrElse, Then, Try, App,
|
||||||
LambdaType, LambdaBody, Lambda,
|
LambdaType, LambdaBody, Lambda,
|
||||||
PiType, PiBody, Pi,
|
PiType, PiBody, Pi,
|
||||||
LetType, LetValue, LetBody, Let,
|
LetType, LetValue, LetBody, Let,
|
||||||
Fail, Success, Repeat };
|
Fail, Success, Repeat, Depth };
|
||||||
|
|
||||||
class rewriter;
|
class rewriter;
|
||||||
|
|
||||||
|
@ -261,6 +256,16 @@ public:
|
||||||
std::pair<expr, expr> operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception);
|
std::pair<expr, expr> operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class depth_rewriter_cell : public rewriter_cell {
|
||||||
|
private:
|
||||||
|
rewriter m_rw;
|
||||||
|
std::ostream & display(std::ostream & out) const;
|
||||||
|
public:
|
||||||
|
depth_rewriter_cell(rewriter const & rw);
|
||||||
|
~depth_rewriter_cell();
|
||||||
|
std::pair<expr, expr> operator()(environment const & env, context & ctx, expr const & v) const throw(rewriter_exception);
|
||||||
|
};
|
||||||
|
|
||||||
/** \brief (For debugging) Display the content of this rewriter */
|
/** \brief (For debugging) Display the content of this rewriter */
|
||||||
inline std::ostream & operator<<(std::ostream & out, rewriter_cell const & rc) { rc.display(out); return out; }
|
inline std::ostream & operator<<(std::ostream & out, rewriter_cell const & rc) { rc.display(out); return out; }
|
||||||
inline std::ostream & operator<<(std::ostream & out, rewriter const & rw) { out << *(rw.m_ptr); return out; }
|
inline std::ostream & operator<<(std::ostream & out, rewriter const & rw) { out << *(rw.m_ptr); return out; }
|
||||||
|
@ -287,4 +292,19 @@ rewriter mk_let_rewriter(rewriter const & rw);
|
||||||
rewriter mk_fail_rewriter();
|
rewriter mk_fail_rewriter();
|
||||||
rewriter mk_success_rewriter();
|
rewriter mk_success_rewriter();
|
||||||
rewriter mk_repeat_rewriter(rewriter const & rw);
|
rewriter mk_repeat_rewriter(rewriter const & rw);
|
||||||
|
rewriter mk_depth_rewriter(rewriter const & rw);
|
||||||
|
|
||||||
|
std::pair<expr, expr> rewrite_lambda_type(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_ty);
|
||||||
|
std::pair<expr, expr> rewrite_lambda_body(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_body);
|
||||||
|
std::pair<expr, expr> rewrite_lambda(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_ty, std::pair<expr, expr> const & result_body);
|
||||||
|
std::pair<expr, expr> rewrite_pi_type(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_ty);
|
||||||
|
std::pair<expr, expr> rewrite_pi_body(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_body);
|
||||||
|
std::pair<expr, expr> rewrite_pi(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_ty, std::pair<expr, expr> const & result_body);
|
||||||
|
std::pair<expr, expr> rewrite_eq_lhs(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_lhs);
|
||||||
|
std::pair<expr, expr> rewrite_eq_rhs(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_rhs);
|
||||||
|
std::pair<expr, expr> rewrite_eq(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_lhs, std::pair<expr, expr> const & result_rhs);
|
||||||
|
std::pair<expr, expr> rewrite_let_type(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_ty);
|
||||||
|
std::pair<expr, expr> rewrite_let_value(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_value);
|
||||||
|
std::pair<expr, expr> rewrite_let_body(environment const & env, context & ctx, expr const & v, std::pair<expr, expr> const & result_body);
|
||||||
|
std::pair<expr, expr> rewrite_app(environment const & env, context & ctx, expr const & v, buffer<std::pair<expr, expr>> const & results );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue