lean4-htt/src/frontends/lean/structure_instance.cpp
2018-09-06 18:09:22 -07:00

94 lines
3.2 KiB
C++

/*
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include <string>
#include "runtime/sstream.h"
#include "frontends/lean/parser.h"
#include "frontends/lean/tokens.h"
#include "frontends/lean/structure_instance.h"
namespace lean {
static name * g_structure_instance = nullptr;
static name * g_catchall = nullptr;
static name * g_struct = nullptr;
static name * g_field = nullptr;
static expr mk_structure_instance_core(name const & s, bool ca, names const & fs, unsigned num, expr const * args) {
kvmap m = set_nat(kvmap(), *g_structure_instance, num);
m = set_bool(m, *g_catchall, ca);
m = set_name(m, *g_struct, s);
expr nil = mk_Prop();
expr r = nil;
names it_fs = fs;
for (unsigned i = 0; i < num; i++) {
name f;
if (it_fs)
f = head(it_fs);
r = mk_app(mk_mdata(set_name(kvmap(), *g_field, f), args[i]), r);
if (it_fs)
it_fs = tail(it_fs);
}
return mk_mdata(m, r);
}
expr mk_structure_instance(name const & s, buffer<name> const & fns, buffer<expr> const & fvs,
buffer<expr> const & sources, bool catchall) {
lean_assert(fns.size() == fvs.size());
buffer<expr> aux;
aux.append(fvs);
aux.append(sources);
return mk_structure_instance_core(s, catchall, names(fns), aux.size(), aux.data());
}
expr mk_structure_instance(structure_instance_info const & info) {
return mk_structure_instance(info.m_struct_name, info.m_field_names, info.m_field_values, info.m_sources,
info.m_catchall);
}
bool is_structure_instance(expr const & e) {
return is_mdata(e) && get_nat(mdata_data(e), *g_structure_instance);
}
structure_instance_info get_structure_instance_info(expr const & e) {
lean_assert(is_structure_instance(e));
structure_instance_info info;
info.m_struct_name = *get_name(mdata_data(e), *g_struct);
info.m_catchall = *get_bool(mdata_data(e), *g_catchall);
unsigned num = get_nat(mdata_data(e), *g_structure_instance)->get_small_value();
expr it = mdata_expr(e);
for (unsigned i = 0; i < num; i++) {
expr curr = app_fn(it);
lean_assert(is_mdata(curr));
name fname = *get_name(mdata_data(curr), *g_field);
expr arg = mdata_expr(curr);
if (fname.is_anonymous()) {
info.m_sources.push_back(arg);
} else {
info.m_field_names.push_back(fname);
info.m_field_values.push_back(arg);
}
it = app_arg(it);
}
std::reverse(info.m_sources.begin(), info.m_sources.end());
std::reverse(info.m_field_values.begin(), info.m_field_values.end());
std::reverse(info.m_field_names.begin(), info.m_field_names.end());
return info;
}
void initialize_structure_instance() {
g_structure_instance = new name("structure instance");
g_struct = new name("struct");
g_catchall = new name("catchall");
g_field = new name("field");
}
void finalize_structure_instance() {
delete g_structure_instance;
delete g_struct;
delete g_catchall;
delete g_field;
}
}