lean4-htt/src/library/deep_copy.cpp
Leonardo de Moura 9afb53fad5 feat(kernel/expr): allow metavariables to have user-facing names
We need this feature for:
1) Defining nonlinear search patterns. Example: (?m <= ?m + 1)
2) Preprocessing recursive equations and support the pattern
refinement approach used in Agda. Example: in Agda, they accept
```
def append {A : Type} : Π (m n : nat), Vec A m -> Vec A n -> Vec A (m + n)
| m n nil            ys := ys
| m n (cons m' x xs) ys := cons x (append m' n xs ys)
```
These equations have to be refined. For example, `m` has to be
replaced with `0` (in the first equation), and `succ m'` in the
second. To implement this kind of refinement, we need to convert
the pattern variables (local constants) into metavariables during
elaboration. Then, the unassigned metavariables become local constants
again. This preprocessing step will fix some of the issues on #1594.
To completely fix #1594, we will need yet another preprocessing step
which will implement "complete transition" used in the equation
compiler before we start elim_match.cpp
2017-07-16 07:16:41 -07:00

38 lines
1.5 KiB
C++

/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include "util/buffer.h"
#include "kernel/expr.h"
#include "kernel/replace_fn.h"
namespace lean {
expr copy(expr const & a) {
scoped_expr_caching scope(false);
switch (a.kind()) {
case expr_kind::Var: return mk_var(var_idx(a));
case expr_kind::Constant: return mk_constant(const_name(a), const_levels(a));
case expr_kind::Sort: return mk_sort(sort_level(a));
case expr_kind::Macro: return mk_macro(to_macro(a)->m_definition, macro_num_args(a), macro_args(a));
case expr_kind::App: return mk_app(app_fn(a), app_arg(a));
case expr_kind::Lambda: return mk_lambda(binding_name(a), binding_domain(a), binding_body(a), binding_info(a));
case expr_kind::Pi: return mk_pi(binding_name(a), binding_domain(a), binding_body(a), binding_info(a));
case expr_kind::Meta: return mk_metavar(mlocal_name(a), mlocal_pp_name(a), mlocal_type(a));
case expr_kind::Local: return mk_local(mlocal_name(a), mlocal_pp_name(a), mlocal_type(a), local_info(a));
case expr_kind::Let: return mk_let(let_name(a), let_type(a), let_value(a), let_body(a));
}
lean_unreachable(); // LCOV_EXCL_LINE
}
expr deep_copy(expr const & e) {
scoped_expr_caching scope(false);
return replace(e, [](expr const & e) {
if (is_atomic(e))
return some_expr(copy(e));
else
return none_expr();
});
}
}