feat(*): add support for separate HoTT library

This commit is contained in:
Leonardo de Moura 2014-12-05 14:34:02 -08:00
parent 71e1555eb4
commit eb87c18693
12 changed files with 152 additions and 24 deletions

4
hott/.project Normal file
View file

@ -0,0 +1,4 @@
+ *.hlean
- flycheck*.lean
- flycheck*.hlean
- .#*.hlean

23
hott/init/datatypes.hlean Normal file
View file

@ -0,0 +1,23 @@
/-
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
Basic datatypes
-/
prelude
notation [parsing-only] `Type'` := Type.{_+1}
notation [parsing-only] `Type₊` := Type.{_+1}
notation `Type₀` := Type.{0}
notation `Type₁` := Type.{1}
notation `Type₂` := Type.{2}
notation `Type₃` := Type.{3}
inductive unit : Type :=
star : unit
inductive empty : Type
structure prod (A B : Type) :=
mk :: (pr1 : A) (pr2 : B)

8
hott/init/default.hlean Normal file
View file

@ -0,0 +1,8 @@
/-
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import init.datatypes

View file

@ -33,11 +33,11 @@ bool display_deps(environment const & env, std::ostream & out, std::ostream & er
auto display_dep = [&](optional<unsigned> const & k, name const & f) { auto display_dep = [&](optional<unsigned> const & k, name const & f) {
import_args = true; import_args = true;
try { try {
std::string m_name = find_file(base, k, name_to_file(f), {".lean", ".olean", ".lua"}); std::string m_name = find_file(base, k, name_to_file(f), {".lean", ".hlean", ".olean", ".lua"});
int last_idx = m_name.find_last_of("."); int last_idx = m_name.find_last_of(".");
std::string rawname = m_name.substr(0, last_idx); std::string rawname = m_name.substr(0, last_idx);
std::string ext = m_name.substr(last_idx); std::string ext = m_name.substr(last_idx);
if (ext == ".lean") if (ext == ".lean" || ext == ".hlean")
m_name = rawname + ".olean"; m_name = rawname + ".olean";
display_path(out, m_name); display_path(out, m_name);
import_prefix = true; import_prefix = true;

View file

@ -727,9 +727,11 @@ struct inductive_cmd_fn {
name const & n = inductive_decl_name(d); name const & n = inductive_decl_name(d);
pos_info pos = *m_decl_pos_map.find(n); pos_info pos = *m_decl_pos_map.find(n);
env = mk_rec_on(env, n); env = mk_rec_on(env, n);
env = mk_induction_on(env, n);
save_def_info(name(n, "rec_on"), pos); save_def_info(name(n, "rec_on"), pos);
save_def_info(name(n, "induction_on"), pos); if (env.impredicative()) {
env = mk_induction_on(env, n);
save_def_info(name(n, "induction_on"), pos);
}
if (has_unit) { if (has_unit) {
env = mk_cases_on(env, n); env = mk_cases_on(env, n);
save_def_info(name(n, "cases_on"), pos); save_def_info(name(n, "cases_on"), pos);
@ -740,9 +742,11 @@ struct inductive_cmd_fn {
} }
if (has_prod) { if (has_prod) {
env = mk_below(env, n); env = mk_below(env, n);
env = mk_ibelow(env, n);
save_if_defined(name{n, "below"}, pos); save_if_defined(name{n, "below"}, pos);
save_if_defined(name(n, "ibelow"), pos); if (env.impredicative()) {
env = mk_ibelow(env, n);
save_if_defined(name(n, "ibelow"), pos);
}
} }
} }
} }
@ -751,9 +755,11 @@ struct inductive_cmd_fn {
pos_info pos = *m_decl_pos_map.find(n); pos_info pos = *m_decl_pos_map.find(n);
if (has_unit && has_prod) { if (has_unit && has_prod) {
env = mk_brec_on(env, n); env = mk_brec_on(env, n);
env = mk_binduction_on(env, n);
save_if_defined(name{n, "brec_on"}, pos); save_if_defined(name{n, "brec_on"}, pos);
save_if_defined(name(n, "binduction_on"), pos); if (env.impredicative()) {
env = mk_binduction_on(env, n);
save_if_defined(name(n, "binduction_on"), pos);
}
} }
} }
return env; return env;

View file

@ -658,13 +658,15 @@ struct structure_cmd_fn {
void declare_auxiliary() { void declare_auxiliary() {
m_env = mk_rec_on(m_env, m_name); m_env = mk_rec_on(m_env, m_name);
m_env = mk_induction_on(m_env, m_name);
name rec_on_name(m_name, "rec_on"); name rec_on_name(m_name, "rec_on");
name induction_on_name(m_name, "induction_on");
add_rec_alias(rec_on_name); add_rec_alias(rec_on_name);
add_rec_alias(induction_on_name);
save_def_info(rec_on_name); save_def_info(rec_on_name);
save_def_info(induction_on_name); if (m_env.impredicative()) {
m_env = mk_induction_on(m_env, m_name);
name induction_on_name(m_name, "induction_on");
add_rec_alias(induction_on_name);
save_def_info(induction_on_name);
}
add_rec_on_alias(name(m_name, "destruct")); add_rec_on_alias(name(m_name, "destruct"));
add_rec_on_alias(name(m_name, "cases_on")); add_rec_on_alias(name(m_name, "cases_on"));
} }

View file

@ -10,6 +10,6 @@ add_library(library deep_copy.cpp expr_lt.cpp io_state.cpp occurs.cpp
definition_cache.cpp declaration_index.cpp definition_cache.cpp declaration_index.cpp
print.cpp annotation.cpp typed_expr.cpp let.cpp type_util.cpp print.cpp annotation.cpp typed_expr.cpp let.cpp type_util.cpp
protected.cpp metavar_closure.cpp reducible.cpp init_module.cpp protected.cpp metavar_closure.cpp reducible.cpp init_module.cpp
fingerprint.cpp flycheck.cpp) fingerprint.cpp flycheck.cpp hott_kernel.cpp)
target_link_libraries(library ${LEAN_LIBS}) target_link_libraries(library ${LEAN_LIBS})

View file

@ -0,0 +1,22 @@
/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include "kernel/inductive/inductive.h"
#include "library/inductive_unifier_plugin.h"
namespace lean {
using inductive::inductive_normalizer_extension;
/** \brief Create Lean environment for Homotopy Type Theory */
environment mk_hott_environment(unsigned trust_lvl) {
environment env = environment(trust_lvl,
false /* Type.{0} is not proof irrelevant */,
true /* Eta */,
false /* Type.{0} is not impredicative */,
/* builtin support for inductive */
std::unique_ptr<normalizer_extension>(new inductive_normalizer_extension()));
return set_unifier_plugin(env, mk_inductive_unifier_plugin());
}
}

13
src/library/hott_kernel.h Normal file
View file

@ -0,0 +1,13 @@
/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#pragma once
#include "kernel/environment.h"
namespace lean {
/** \brief Create Lean environment for Homotopy Type Theory */
environment mk_hott_environment(unsigned trust_lvl = 0);
}

View file

@ -25,6 +25,7 @@ Author: Leonardo de Moura
#include "kernel/kernel_exception.h" #include "kernel/kernel_exception.h"
#include "kernel/formatter.h" #include "kernel/formatter.h"
#include "library/standard_kernel.h" #include "library/standard_kernel.h"
#include "library/hott_kernel.h"
#include "library/module.h" #include "library/module.h"
#include "library/io_state_stream.h" #include "library/io_state_stream.h"
#include "library/definition_cache.h" #include "library/definition_cache.h"
@ -45,6 +46,7 @@ using lean::io_state;
using lean::io_state_stream; using lean::io_state_stream;
using lean::regular; using lean::regular;
using lean::mk_environment; using lean::mk_environment;
using lean::mk_hott_environment;
using lean::set_environment; using lean::set_environment;
using lean::set_io_state; using lean::set_io_state;
using lean::definition_cache; using lean::definition_cache;
@ -57,7 +59,7 @@ using lean::declaration_index;
using lean::keep_theorem_mode; using lean::keep_theorem_mode;
using lean::module_name; using lean::module_name;
enum class input_kind { Unspecified, Lean, Lua, Trace }; enum class input_kind { Unspecified, Lean, HLean, Lua, Trace };
static void on_ctrl_c(int ) { static void on_ctrl_c(int ) {
lean::request_interrupt(); lean::request_interrupt();
@ -81,6 +83,8 @@ static void display_help(std::ostream & out) {
std::cout << "Input format:\n"; std::cout << "Input format:\n";
std::cout << " --lean use parser for Lean default input format for files,\n"; std::cout << " --lean use parser for Lean default input format for files,\n";
std::cout << " with unknown extension (default)\n"; std::cout << " with unknown extension (default)\n";
std::cout << " --hlean use parser for Lean default input format \n";
std::cout << " and use HoTT compatible kernel for files, with unknown extension\n";
std::cout << " --lua use Lua parser for files with unknown extension\n"; std::cout << " --lua use Lua parser for files with unknown extension\n";
std::cout << " --server-trace use lean server trace parser for files with unknown extension\n"; std::cout << " --server-trace use lean server trace parser for files with unknown extension\n";
std::cout << "Miscellaneous:\n"; std::cout << "Miscellaneous:\n";
@ -130,6 +134,7 @@ static struct option g_long_options[] = {
{"version", no_argument, 0, 'v'}, {"version", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"lean", no_argument, 0, 'l'}, {"lean", no_argument, 0, 'l'},
{"hlean", no_argument, 0, 'H'},
{"lua", no_argument, 0, 'u'}, {"lua", no_argument, 0, 'u'},
{"server-trace", no_argument, 0, 'R'}, {"server-trace", no_argument, 0, 'R'},
{"path", no_argument, 0, 'p'}, {"path", no_argument, 0, 'p'},
@ -155,7 +160,7 @@ static struct option g_long_options[] = {
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
#define BASIC_OPT_STR "RXTFC:dD:qlupgvhk:012t:012o:c:i:" #define BASIC_OPT_STR "HRXTFC:dD:qlupgvhk:012t:012o:c:i:"
#if defined(LEAN_USE_BOOST) && defined(LEAN_MULTI_THREAD) #if defined(LEAN_USE_BOOST) && defined(LEAN_MULTI_THREAD)
static char const * g_opt_str = BASIC_OPT_STR "Sj:012s:012"; static char const * g_opt_str = BASIC_OPT_STR "Sj:012s:012";
@ -327,7 +332,7 @@ int main(int argc, char ** argv) {
std::string cpp_output; std::string cpp_output;
std::string cache_name; std::string cache_name;
std::string index_name; std::string index_name;
input_kind default_k = input_kind::Lean; // default input_kind default_k = input_kind::Unspecified;
while (true) { while (true) {
int c = getopt_long(argc, argv, g_opt_str, g_long_options, NULL); int c = getopt_long(argc, argv, g_opt_str, g_long_options, NULL);
if (c == -1) if (c == -1)
@ -351,6 +356,9 @@ int main(int argc, char ** argv) {
case 'l': case 'l':
default_k = input_kind::Lean; default_k = input_kind::Lean;
break; break;
case 'H':
default_k = input_kind::HLean;
break;
case 'u': case 'u':
default_k = input_kind::Lua; default_k = input_kind::Lua;
break; break;
@ -419,7 +427,35 @@ int main(int argc, char ** argv) {
lean_assert(num_threads == 1); lean_assert(num_threads == 1);
#endif #endif
environment env = mk_environment(trust_lvl); bool has_lean = (default_k == input_kind::Lean);
bool has_hlean = (default_k == input_kind::HLean);
for (int i = optind; i < argc; i++) {
char const * ext = get_file_extension(argv[i]);
if (strcmp(ext, "lean") == 0) {
has_lean = true;
if (has_hlean) {
std::cerr << ".hlean file cannot be mixed with .lean files\n";
return 1;
}
if (default_k == input_kind::Unspecified)
default_k = input_kind::Lean;
} else if (strcmp(ext, "hlean") == 0) {
has_hlean = true;
if (has_lean) {
std::cerr << ".lean file cannot be mixed with .hlean files\n";
return 1;
}
if (default_k == input_kind::Unspecified)
default_k = input_kind::HLean;
}
}
if (default_k == input_kind::Unspecified)
default_k = input_kind::Lean;
if (has_hlean)
lean::initialize_lean_path(true);
environment env = has_hlean ? mk_hott_environment(trust_lvl) : mk_environment(trust_lvl);
io_state ios(opts, lean::mk_pretty_formatter_factory()); io_state ios(opts, lean::mk_pretty_formatter_factory());
script_state S = lean::get_thread_script_state(); script_state S = lean::get_thread_script_state();
set_environment set1(S, env); set_environment set1(S, env);
@ -446,12 +482,15 @@ int main(int argc, char ** argv) {
if (ext) { if (ext) {
if (strcmp(ext, "lean") == 0) { if (strcmp(ext, "lean") == 0) {
k = input_kind::Lean; k = input_kind::Lean;
} else if (strcmp(ext, "hlean") == 0) {
k = input_kind::HLean;
} else if (strcmp(ext, "lua") == 0) { } else if (strcmp(ext, "lua") == 0) {
k = input_kind::Lua; k = input_kind::Lua;
} }
} }
switch (k) { switch (k) {
case input_kind::Lean: case input_kind::Lean:
case input_kind::HLean:
if (only_deps) { if (only_deps) {
if (!display_deps(env, std::cout, std::cerr, argv[i])) if (!display_deps(env, std::cout, std::cerr, argv[i]))
ok = false; ok = false;

View file

@ -118,15 +118,22 @@ std::string get_path(std::string f) {
static std::string * g_lean_path = nullptr; static std::string * g_lean_path = nullptr;
static std::vector<std::string> * g_lean_path_vector = nullptr; static std::vector<std::string> * g_lean_path_vector = nullptr;
void init_lean_path() { void init_lean_path(bool use_hott) {
#if defined(LEAN_EMSCRIPTEN) #if defined(LEAN_EMSCRIPTEN)
*g_lean_path = "/library"; *g_lean_path = "/library";
g_lean_path_vector->push_back(*g_lean_path); g_lean_path_vector->push_back(*g_lean_path);
#else #else
char * r = getenv("LEAN_PATH"); char * r = nullptr;
if (use_hott)
r = getenv("LEAN_PATH");
else
r = getenv("HLEAN_PATH");
if (r == nullptr) { if (r == nullptr) {
std::string exe_path = get_path(get_exe_location()); std::string exe_path = get_path(get_exe_location());
*g_lean_path = exe_path + g_sep + ".." + g_sep + "library"; if (use_hott)
*g_lean_path = exe_path + g_sep + ".." + g_sep + "hott";
else
*g_lean_path = exe_path + g_sep + ".." + g_sep + "library";
*g_lean_path += g_path_sep; *g_lean_path += g_path_sep;
*g_lean_path += exe_path + g_sep + ".." + g_sep + "lib" + g_sep + "lean"; *g_lean_path += exe_path + g_sep + ".." + g_sep + "lib" + g_sep + "lean";
*g_lean_path += g_path_sep; *g_lean_path += g_path_sep;
@ -153,13 +160,13 @@ void init_lean_path() {
static char g_sep_str[2]; static char g_sep_str[2];
void initialize_lean_path() { void initialize_lean_path(bool use_hott) {
g_default_file_name = new std::string(LEAN_DEFAULT_MODULE_FILE_NAME); g_default_file_name = new std::string(LEAN_DEFAULT_MODULE_FILE_NAME);
g_lean_path = new std::string(); g_lean_path = new std::string();
g_lean_path_vector = new std::vector<std::string>(); g_lean_path_vector = new std::vector<std::string>();
g_sep_str[0] = g_sep; g_sep_str[0] = g_sep;
g_sep_str[1] = 0; g_sep_str[1] = 0;
init_lean_path(); init_lean_path(use_hott);
} }
void finalize_lean_path() { void finalize_lean_path() {
@ -173,6 +180,10 @@ bool has_file_ext(std::string const & fname, char const * ext) {
return fname.size() > ext_len && fname.substr(fname.size() - ext_len, ext_len) == ext; return fname.size() > ext_len && fname.substr(fname.size() - ext_len, ext_len) == ext;
} }
bool is_hlean_file(std::string const & fname) {
return has_file_ext(fname, ".hlean");
}
bool is_lean_file(std::string const & fname) { bool is_lean_file(std::string const & fname) {
return has_file_ext(fname, ".lean"); return has_file_ext(fname, ".lean");
} }
@ -186,7 +197,7 @@ bool is_lua_file(std::string const & fname) {
} }
bool is_known_file_ext(std::string const & fname) { bool is_known_file_ext(std::string const & fname) {
return is_lean_file(fname) || is_olean_file(fname) || is_lua_file(fname); return is_lean_file(fname) || is_hlean_file(fname) || is_olean_file(fname) || is_lua_file(fname);
} }
optional<std::string> check_file_core(std::string file, char const * ext) { optional<std::string> check_file_core(std::string file, char const * ext) {

View file

@ -55,6 +55,6 @@ void display_path(std::ostream & out, std::string const & fname);
std::string dirname(char const * fname); std::string dirname(char const * fname);
std::string path_append(char const * path1, char const * path2); std::string path_append(char const * path1, char const * path2);
void initialize_lean_path(); void initialize_lean_path(bool use_hott = false);
void finalize_lean_path(); void finalize_lean_path();
} }