feat(frontends/lean/structure_cmd): allow user to reference parent structures when defining new fields
See new test for an example. closes #371
This commit is contained in:
parent
13660cfecd
commit
bfd679d52d
2 changed files with 36 additions and 2 deletions
|
@ -119,6 +119,7 @@ struct structure_cmd_fn {
|
|||
modifiers m_modifiers;
|
||||
buffer<expr> m_params;
|
||||
expr m_type;
|
||||
buffer<optional<name>> m_parent_refs;
|
||||
buffer<expr> m_parents;
|
||||
buffer<bool> m_private_parents;
|
||||
name m_mk;
|
||||
|
@ -209,7 +210,9 @@ struct structure_cmd_fn {
|
|||
m_p.next();
|
||||
is_private_parent = true;
|
||||
}
|
||||
expr parent = m_p.parse_expr();
|
||||
pair<optional<name>, expr> qparent = m_p.parse_qualified_expr();
|
||||
m_parent_refs.push_back(qparent.first);
|
||||
expr const & parent = qparent.second;
|
||||
m_parents.push_back(parent);
|
||||
m_private_parents.push_back(is_private_parent);
|
||||
check_parent(parent, pos);
|
||||
|
@ -462,12 +465,30 @@ struct structure_cmd_fn {
|
|||
solve_constraints(cseq);
|
||||
}
|
||||
|
||||
/** \brief Add params and fields to parser local scope */
|
||||
/** \brief Add params, fields and references to parent structures into parser local scope */
|
||||
void add_locals() {
|
||||
for (expr const & param : m_params)
|
||||
m_p.add_local(param);
|
||||
for (expr const & field : m_fields)
|
||||
m_p.add_local(field);
|
||||
for (unsigned i = 0; i < m_parents.size(); i++) {
|
||||
if (auto n = m_parent_refs[i]) {
|
||||
expr const & parent = m_parents[i];
|
||||
field_map const & fmap = m_field_maps[i];
|
||||
buffer<expr> parent_params;
|
||||
expr const & parent_fn = get_app_args(parent, parent_params);
|
||||
levels const & parent_ls = const_levels(parent_fn);
|
||||
name const & parent_name = const_name(parent_fn);
|
||||
auto parent_info = get_parent_info(parent_name);
|
||||
name const & parent_intro_name = inductive::intro_rule_name(std::get<2>(parent_info));
|
||||
expr parent_intro = mk_app(mk_constant(parent_intro_name, parent_ls), parent_params);
|
||||
for (unsigned idx : fmap) {
|
||||
expr const & field = m_fields[idx];
|
||||
parent_intro = mk_app(parent_intro, field);
|
||||
}
|
||||
m_p.add_local_expr(*n, mk_as_is(parent_intro));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Check if new field names collide with fields inherited from parent datastructures */
|
||||
|
|
13
tests/lean/run/parent_struct_ref.lean
Normal file
13
tests/lean/run/parent_struct_ref.lean
Normal file
|
@ -0,0 +1,13 @@
|
|||
open nat
|
||||
|
||||
structure point (A B : Type) :=
|
||||
(x : A) (y : B)
|
||||
|
||||
structure foo extends p1 : point nat nat, p2 : point bool bool renaming x→a y→b :=
|
||||
(H1 : point.x p2 = point.y p2) (H2 : point.x p1 + point.y p1 > 10)
|
||||
|
||||
example (s : foo) : foo.a s = foo.b s :=
|
||||
foo.H1 s
|
||||
|
||||
example (s : foo) : foo.x s + foo.y s > 10 :=
|
||||
foo.H2 s
|
Loading…
Reference in a new issue