/* 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 #include "library/unfold_macros.h" #include "kernel/type_checker.h" #include "kernel/inductive/inductive.h" #include "kernel/standard_kernel.h" #include "library/module.h" #include "library/projection.h" #include "library/util.h" #include "library/relation_manager.h" #include "library/inductive_compiler/ginductive.h" #include "library/vm/vm_nat.h" #include "library/vm/vm_name.h" #include "library/vm/vm_option.h" #include "library/vm/vm_string.h" #include "library/vm/vm_level.h" #include "library/vm/vm_expr.h" #include "library/vm/vm_declaration.h" #include "library/vm/vm_exceptional.h" #include "library/vm/vm_list.h" namespace lean { struct vm_environment : public vm_external { environment m_val; vm_environment(environment const & v):m_val(v) {} virtual ~vm_environment() {} virtual void dealloc() override { this->~vm_environment(); get_vm_allocator().deallocate(sizeof(vm_environment), this); } virtual vm_external * ts_clone(vm_clone_fn const &) override { return new vm_environment(m_val); } virtual vm_external * clone(vm_clone_fn const &) override { return new (get_vm_allocator().allocate(sizeof(vm_environment))) vm_environment(m_val); } }; bool is_env(vm_obj const & o) { return is_external(o) && dynamic_cast(to_external(o)); } environment const & to_env(vm_obj const & o) { lean_assert(is_external(o)); lean_assert(dynamic_cast(to_external(o))); return static_cast(to_external(o))->m_val; } vm_obj to_obj(environment const & n) { return mk_vm_external(new (get_vm_allocator().allocate(sizeof(vm_environment))) vm_environment(n)); } vm_obj environment_mk_std(vm_obj const & l) { return to_obj(mk_environment(force_to_unsigned(l, 0))); } vm_obj environment_trust_lvl(vm_obj const & env) { return mk_vm_nat(to_env(env).trust_lvl()); } vm_obj environment_add(vm_obj const & env, vm_obj const & decl) { try { return mk_vm_exceptional_success(to_obj(module::add(to_env(env), check(to_env(env), to_declaration(decl))))); } catch (throwable & ex) { return mk_vm_exceptional_exception(ex); } } vm_obj environment_get(vm_obj const & env, vm_obj const & n) { try { return mk_vm_exceptional_success(to_obj(to_env(env).get(to_name(n)))); } catch (throwable & ex) { return mk_vm_exceptional_exception(ex); } } static list to_list_intro_rule(vm_obj const & cnstrs) { if (is_simple(cnstrs)) return list(); else return list(mk_local(to_name(cfield(cfield(cnstrs, 0), 0)), to_expr(cfield(cfield(cnstrs, 0), 1))), to_list_intro_rule(cfield(cnstrs, 1))); } vm_obj environment_add_inductive(vm_obj const & env, vm_obj const & n, vm_obj const & ls, vm_obj const & num, vm_obj const & type, vm_obj const & cnstrs, vm_obj const & is_meta) { try { environment new_env = module::add_inductive(to_env(env), inductive::inductive_decl(to_name(n), to_list_name(ls), force_to_unsigned(num, 0), to_expr(type), to_list_intro_rule(cnstrs)), !to_bool(is_meta)); return mk_vm_exceptional_success(to_obj(new_env)); } catch (throwable & ex) { return mk_vm_exceptional_exception(ex); } } vm_obj environment_is_inductive(vm_obj const & env, vm_obj const & n) { return mk_vm_bool(static_cast(inductive::is_inductive_decl(to_env(env), to_name(n)))); } vm_obj environment_is_constructor(vm_obj const & env, vm_obj const & n) { return mk_vm_bool(static_cast(inductive::is_intro_rule(to_env(env), to_name(n)))); } vm_obj environment_inductive_type_of(vm_obj const & env, vm_obj const & n) { if (auto I = inductive::is_intro_rule(to_env(env), to_name(n))) return mk_vm_some(to_obj(*I)); else return mk_vm_none(); } vm_obj environment_is_recursor(vm_obj const & env, vm_obj const & n) { return mk_vm_bool(static_cast(inductive::is_elim_rule(to_env(env), to_name(n)))); } vm_obj environment_is_recursive(vm_obj const & env, vm_obj const & n) { return mk_vm_bool(static_cast(is_recursive_datatype(to_env(env), to_name(n)))); } vm_obj environment_constructors_of(vm_obj const & env, vm_obj const & n) { buffer ns; get_intro_rule_names(to_env(env), to_name(n), ns); return to_obj(to_list(ns)); } vm_obj environment_recursor_of(vm_obj const & env, vm_obj const & n) { if (auto I = inductive::is_elim_rule(to_env(env), to_name(n))) return mk_vm_some(to_obj(*I)); else return mk_vm_none(); } vm_obj environment_inductive_num_params(vm_obj const & env, vm_obj const & n) { if (auto r = inductive::get_num_params(to_env(env), to_name(n))) return mk_vm_nat(*r); else return mk_vm_nat(0); } vm_obj environment_inductive_num_indices(vm_obj const & env, vm_obj const & n) { if (auto r = inductive::get_num_indices(to_env(env), to_name(n))) return mk_vm_nat(*r); else return mk_vm_nat(0); } vm_obj environment_inductive_dep_elim(vm_obj const & env, vm_obj const & n) { return mk_vm_bool(inductive::has_dep_elim(to_env(env), to_name(n))); } vm_obj environment_is_ginductive(vm_obj const & env, vm_obj const & n) { return mk_vm_bool(static_cast(is_ginductive(to_env(env), to_name(n)))); } vm_obj environment_fold(vm_obj const &, vm_obj const & env, vm_obj const & a, vm_obj const & fn) { vm_obj r = a; to_env(env).for_each_declaration([&](declaration const & d) { r = invoke(fn, to_obj(d), r); }); return r; } vm_obj environment_relation_info(vm_obj const & env, vm_obj const & n) { if (relation_info const * info = get_relation_info(to_env(env), to_name(n))) { vm_obj r = mk_vm_pair(mk_vm_nat(info->get_arity()), mk_vm_pair(mk_vm_nat(info->get_lhs_pos()), mk_vm_nat(info->get_rhs_pos()))); return mk_vm_some(r); } else { return mk_vm_none(); } } vm_obj environment_refl_for(vm_obj const & env, vm_obj const & n) { if (optional r = get_refl_info(to_env(env), to_name(n))) { return mk_vm_some(to_obj(*r)); } else { return mk_vm_none(); } } vm_obj environment_trans_for(vm_obj const & env, vm_obj const & n) { if (optional r = get_trans_info(to_env(env), to_name(n))) { return mk_vm_some(to_obj(*r)); } else { return mk_vm_none(); } } vm_obj environment_symm_for(vm_obj const & env, vm_obj const & n) { if (optional r = get_symm_info(to_env(env), to_name(n))) { return mk_vm_some(to_obj(*r)); } else { return mk_vm_none(); } } vm_obj environment_decl_olean(vm_obj const & env, vm_obj const & n) { if (optional olean = get_decl_olean(to_env(env), to_name(n))) { return mk_vm_some(to_obj(*olean)); } else { return mk_vm_none(); } } vm_obj environment_decl_pos_info(vm_obj const & env, vm_obj const & n) { if (optional pos = get_decl_pos_info(to_env(env), to_name(n))) { return mk_vm_some(mk_vm_pair(mk_vm_nat(pos->first), mk_vm_nat(pos->second))); } else { return mk_vm_none(); } } /* structure projection_info := (cname : name) (nparams : nat) (idx : nat) (is_class : bool) */ vm_obj environment_is_projection(vm_obj const & env, vm_obj const & n) { if (auto info = get_projection_info(to_env(env), to_name(n))) { return mk_vm_some(mk_vm_constructor(0, to_obj(info->m_constructor), mk_vm_nat(info->m_nparams), mk_vm_nat(info->m_i), mk_vm_bool(info->m_inst_implicit))); } else { return mk_vm_none(); } } vm_obj environment_unfold_untrusted_macros(vm_obj const & env, vm_obj const & e) { return to_obj(unfold_untrusted_macros(to_env(env), to_expr(e))); } void initialize_vm_environment() { DECLARE_VM_BUILTIN(name({"environment", "mk_std"}), environment_mk_std); DECLARE_VM_BUILTIN(name({"environment", "trust_lvl"}), environment_trust_lvl); DECLARE_VM_BUILTIN(name({"environment", "add"}), environment_add); DECLARE_VM_BUILTIN(name({"environment", "get"}), environment_get); DECLARE_VM_BUILTIN(name({"environment", "fold"}), environment_fold); DECLARE_VM_BUILTIN(name({"environment", "add_inductive"}), environment_add_inductive); DECLARE_VM_BUILTIN(name({"environment", "is_inductive"}), environment_is_inductive); DECLARE_VM_BUILTIN(name({"environment", "is_constructor"}), environment_is_constructor); DECLARE_VM_BUILTIN(name({"environment", "is_recursor"}), environment_is_recursor); DECLARE_VM_BUILTIN(name({"environment", "is_recursive"}), environment_is_recursive); DECLARE_VM_BUILTIN(name({"environment", "inductive_type_of"}), environment_inductive_type_of); DECLARE_VM_BUILTIN(name({"environment", "constructors_of"}), environment_constructors_of); DECLARE_VM_BUILTIN(name({"environment", "recursor_of"}), environment_recursor_of); DECLARE_VM_BUILTIN(name({"environment", "inductive_num_params"}), environment_inductive_num_params); DECLARE_VM_BUILTIN(name({"environment", "inductive_num_indices"}), environment_inductive_num_indices); DECLARE_VM_BUILTIN(name({"environment", "inductive_dep_elim"}), environment_inductive_dep_elim); DECLARE_VM_BUILTIN(name({"environment", "is_ginductive"}), environment_is_ginductive); DECLARE_VM_BUILTIN(name({"environment", "is_projection"}), environment_is_projection); DECLARE_VM_BUILTIN(name({"environment", "relation_info"}), environment_relation_info); DECLARE_VM_BUILTIN(name({"environment", "refl_for"}), environment_refl_for); DECLARE_VM_BUILTIN(name({"environment", "symm_for"}), environment_symm_for); DECLARE_VM_BUILTIN(name({"environment", "trans_for"}), environment_trans_for); DECLARE_VM_BUILTIN(name({"environment", "decl_olean"}), environment_decl_olean); DECLARE_VM_BUILTIN(name({"environment", "decl_pos_info"}), environment_decl_pos_info); DECLARE_VM_BUILTIN(name({"environment", "unfold_untrusted_macros"}), environment_unfold_untrusted_macros); } void finalize_vm_environment() { } }