refactor(*): explicit initialization/finalization for serialization
modules, expression annotations, and tactics
This commit is contained in:
parent
b1ee888aae
commit
b6781711b1
47 changed files with 684 additions and 376 deletions
|
@ -7,13 +7,18 @@ Author: Leonardo de Moura
|
|||
#include "frontends/lean/extra_info.h"
|
||||
|
||||
namespace lean {
|
||||
name const & get_extra_info() {
|
||||
static name g_extra_info("extra_info");
|
||||
static register_annotation_fn g_extra_info_annotation(g_extra_info);
|
||||
return g_extra_info;
|
||||
}
|
||||
static name g_extra_info_name = get_extra_info(); // force 'extra_info' annotation to be registered
|
||||
static name * g_extra_info = nullptr;
|
||||
name const & get_extra_info() { return *g_extra_info; }
|
||||
|
||||
expr mk_extra_info(expr const & e) { return mk_annotation(get_extra_info(), e); }
|
||||
bool is_extra_info(expr const & e) { return is_annotation(e, get_extra_info()); }
|
||||
|
||||
void initialize_extra_info() {
|
||||
g_extra_info = new name("extra_info");
|
||||
register_annotation(*g_extra_info);
|
||||
}
|
||||
|
||||
void finalize_extra_info() {
|
||||
delete g_extra_info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,4 +14,7 @@ namespace lean {
|
|||
expr mk_extra_info(expr const & e);
|
||||
/** \brief Return true iff \c e is a term annotated with mk_extra_info */
|
||||
bool is_extra_info(expr const & e);
|
||||
|
||||
void initialize_extra_info();
|
||||
void finalize_extra_info();
|
||||
}
|
||||
|
|
|
@ -7,14 +7,20 @@ Author: Leonardo de Moura
|
|||
#include "frontends/lean/elaborator.h"
|
||||
#include "frontends/lean/pp_options.h"
|
||||
#include "frontends/lean/parser.h"
|
||||
#include "frontends/lean/no_info.h"
|
||||
#include "frontends/lean/extra_info.h"
|
||||
|
||||
namespace lean {
|
||||
void initialize_frontend_lean_module() {
|
||||
initialize_elaborator();
|
||||
initialize_pp_options();
|
||||
initialize_parser();
|
||||
initialize_no_info();
|
||||
initialize_extra_info();
|
||||
}
|
||||
void finalize_frontend_lean_module() {
|
||||
finalize_extra_info();
|
||||
finalize_no_info();
|
||||
finalize_parser();
|
||||
finalize_pp_options();
|
||||
finalize_elaborator();
|
||||
|
|
|
@ -7,13 +7,18 @@ Author: Leonardo de Moura
|
|||
#include "frontends/lean/no_info.h"
|
||||
|
||||
namespace lean {
|
||||
name const & get_no_info() {
|
||||
static name g_no_info("no_info");
|
||||
static register_annotation_fn g_no_info_annotation(g_no_info);
|
||||
return g_no_info;
|
||||
}
|
||||
static name g_no_info_name = get_no_info(); // force 'no_info' annotation to be registered
|
||||
static name * g_no_info = nullptr;
|
||||
name const & get_no_info() { return *g_no_info; }
|
||||
|
||||
expr mk_no_info(expr const & e) { return mk_annotation(get_no_info(), e); }
|
||||
bool is_no_info(expr const & e) { return is_annotation(e, get_no_info()); }
|
||||
|
||||
void initialize_no_info() {
|
||||
g_no_info = new name("no_info");
|
||||
register_annotation(*g_no_info);
|
||||
}
|
||||
|
||||
void finalize_no_info() {
|
||||
delete g_no_info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,4 +16,7 @@ namespace lean {
|
|||
expr mk_no_info(expr const & e);
|
||||
/** \brief Return true iff \c e is a term annotated with mk_no_info */
|
||||
bool is_no_info(expr const & e);
|
||||
|
||||
void initialize_no_info();
|
||||
void finalize_no_info();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "util/init_module.h"
|
||||
#include "util/sexpr/init_module.h"
|
||||
#include "kernel/init_module.h"
|
||||
#include "library/init_module.h"
|
||||
#include "library/tactic/init_module.h"
|
||||
#include "frontends/lean/init_module.h"
|
||||
|
@ -12,7 +14,9 @@ Author: Leonardo de Moura
|
|||
|
||||
namespace lean {
|
||||
void initialize() {
|
||||
initialize_util_module();
|
||||
initialize_sexpr_module();
|
||||
initialize_kernel_module();
|
||||
initialize_library_module();
|
||||
initialize_tactic_module();
|
||||
initialize_frontend_lean_module();
|
||||
|
@ -21,7 +25,9 @@ void finalize() {
|
|||
finalize_frontend_lean_module();
|
||||
finalize_tactic_module();
|
||||
finalize_library_module();
|
||||
finalize_kernel_module();
|
||||
finalize_sexpr_module();
|
||||
finalize_util_module();
|
||||
}
|
||||
|
||||
initializer::initializer() {
|
||||
|
|
|
@ -3,6 +3,6 @@ replace_fn.cpp free_vars.cpp abstract.cpp instantiate.cpp
|
|||
formatter.cpp declaration.cpp replace_visitor.cpp environment.cpp
|
||||
justification.cpp pos_info_provider.cpp metavar.cpp converter.cpp
|
||||
constraint.cpp type_checker.cpp error_msgs.cpp kernel_exception.cpp
|
||||
normalizer_extension.cpp)
|
||||
normalizer_extension.cpp init_module.cpp)
|
||||
|
||||
target_link_libraries(kernel ${LEAN_LIBS})
|
||||
|
|
12
src/kernel/init_module.cpp
Normal file
12
src/kernel/init_module.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
namespace lean {
|
||||
void initialize_kernel_module() {
|
||||
}
|
||||
void finalize_kernel_module() {
|
||||
}
|
||||
}
|
11
src/kernel/init_module.h
Normal file
11
src/kernel/init_module.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
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
|
||||
namespace lean {
|
||||
void initialize_kernel_module();
|
||||
void finalize_kernel_module();
|
||||
}
|
|
@ -8,18 +8,15 @@ Author: Leonardo de Moura
|
|||
#include <memory>
|
||||
#include <string>
|
||||
#include "util/sstream.h"
|
||||
#include "library/kernel_serializer.h"
|
||||
#include "library/annotation.h"
|
||||
|
||||
namespace lean {
|
||||
name const & get_annotation_name() {
|
||||
static name g_annotation("annotation");
|
||||
return g_annotation;
|
||||
}
|
||||
static name * g_annotation = nullptr;
|
||||
static std::string * g_annotation_opcode = nullptr;
|
||||
|
||||
std::string const & get_annotation_opcode() {
|
||||
static std::string g_annotation_opcode("Annot");
|
||||
return g_annotation_opcode;
|
||||
}
|
||||
name const & get_annotation_name() { return *g_annotation; }
|
||||
std::string const & get_annotation_opcode() { return *g_annotation_opcode; }
|
||||
|
||||
/** \brief We use a macro to mark expressions that denote "let" and "have"-expressions.
|
||||
These marks have no real semantic meaning, but are useful for helping Lean's pretty printer.
|
||||
|
@ -51,14 +48,12 @@ public:
|
|||
};
|
||||
|
||||
typedef std::unordered_map<name, macro_definition, name_hash, name_eq> annotation_macros;
|
||||
annotation_macros & get_annotation_macros() {
|
||||
static std::unique_ptr<annotation_macros> g_annotation_macros;
|
||||
if (!g_annotation_macros) g_annotation_macros.reset(new annotation_macros());
|
||||
return *(g_annotation_macros.get());
|
||||
}
|
||||
static annotation_macros * g_annotation_macros = nullptr;
|
||||
|
||||
annotation_macros & get_annotation_macros() { return *g_annotation_macros; }
|
||||
|
||||
void register_annotation(name const & n) {
|
||||
annotation_macros & ms = get_annotation_macros();
|
||||
annotation_macros & ms = get_annotation_macros();
|
||||
lean_assert(ms.find(n) == ms.end());
|
||||
ms.insert(mk_pair(n, macro_definition(new annotation_macro_definition_cell(n))));
|
||||
}
|
||||
|
@ -124,32 +119,45 @@ expr copy_annotations(expr const & from, expr const & to) {
|
|||
return r;
|
||||
}
|
||||
|
||||
name const & get_have_name() {
|
||||
static name g_have("have");
|
||||
static register_annotation_fn g_have_annotation(g_have);
|
||||
return g_have;
|
||||
static name * g_have = nullptr;
|
||||
static name * g_show = nullptr;
|
||||
static name * g_proof_qed = nullptr;
|
||||
|
||||
expr mk_have_annotation(expr const & e) { return mk_annotation(*g_have, e); }
|
||||
expr mk_show_annotation(expr const & e) { return mk_annotation(*g_show, e); }
|
||||
expr mk_proof_qed_annotation(expr const & e) { return mk_annotation(*g_proof_qed, e); }
|
||||
bool is_have_annotation(expr const & e) { return is_annotation(e, *g_have); }
|
||||
bool is_show_annotation(expr const & e) { return is_annotation(e, *g_show); }
|
||||
bool is_proof_qed_annotation(expr const & e) { return is_annotation(e, *g_proof_qed); }
|
||||
|
||||
void initialize_annotation() {
|
||||
g_annotation = new name("annotation");
|
||||
g_annotation_opcode = new std::string("Annot");
|
||||
g_annotation_macros = new annotation_macros();
|
||||
g_have = new name("have");
|
||||
g_show = new name("show");
|
||||
g_proof_qed = new name("proof-qed");
|
||||
|
||||
register_annotation(*g_have);
|
||||
register_annotation(*g_show);
|
||||
register_annotation(*g_proof_qed);
|
||||
|
||||
register_macro_deserializer(get_annotation_opcode(),
|
||||
[](deserializer & d, unsigned num, expr const * args) {
|
||||
if (num != 1)
|
||||
throw corrupted_stream_exception();
|
||||
name k;
|
||||
d >> k;
|
||||
return mk_annotation(k, args[0]);
|
||||
});
|
||||
}
|
||||
|
||||
name const & get_show_name() {
|
||||
static name g_show("show");
|
||||
static register_annotation_fn g_show_annotation(g_show);
|
||||
return g_show;
|
||||
void finalize_annotation() {
|
||||
delete g_proof_qed;
|
||||
delete g_show;
|
||||
delete g_have;
|
||||
delete g_annotation_macros;
|
||||
delete g_annotation_opcode;
|
||||
delete g_annotation;
|
||||
}
|
||||
|
||||
name const & get_proof_qed_name() {
|
||||
static name g_proof_qed("proof-qed");
|
||||
static register_annotation_fn g_proof_qed_annotation(g_proof_qed);
|
||||
return g_proof_qed;
|
||||
}
|
||||
|
||||
static name g_have_name = get_have_name(); // force 'have' annotation to be registered
|
||||
static name g_show_name = get_show_name(); // force 'show' annotation to be registered
|
||||
static name g_proof_qed_name = get_proof_qed_name(); // force 'proof-qed' annotation to be registered
|
||||
|
||||
expr mk_have_annotation(expr const & e) { return mk_annotation(get_have_name(), e); }
|
||||
expr mk_show_annotation(expr const & e) { return mk_annotation(get_show_name(), e); }
|
||||
expr mk_proof_qed_annotation(expr const & e) { return mk_annotation(get_proof_qed_name(), e); }
|
||||
bool is_have_annotation(expr const & e) { return is_annotation(e, get_have_name()); }
|
||||
bool is_show_annotation(expr const & e) { return is_annotation(e, get_show_name()); }
|
||||
bool is_proof_qed_annotation(expr const & e) { return is_annotation(e, get_proof_qed_name()); }
|
||||
}
|
||||
|
|
|
@ -13,10 +13,6 @@ namespace lean {
|
|||
Use helper obect #register_annotation_fn.
|
||||
*/
|
||||
void register_annotation(name const & n);
|
||||
/** \brief Helper object for declaring a new kind of annotation */
|
||||
struct register_annotation_fn {
|
||||
register_annotation_fn(name const & kind) { register_annotation(kind); }
|
||||
};
|
||||
|
||||
/** \brief Create an annotated expression with tag \c kind based on \c e.
|
||||
|
||||
|
@ -71,4 +67,7 @@ bool is_proof_qed_annotation(expr const & e);
|
|||
|
||||
/** \brief Return the serialization 'opcode' for annotation macros. */
|
||||
std::string const & get_annotation_opcode();
|
||||
|
||||
void initialize_annotation();
|
||||
void finalize_annotation();
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ Author: Leonardo de Moura
|
|||
#include "library/kernel_serializer.h"
|
||||
|
||||
namespace lean {
|
||||
static name g_choice_name("choice");
|
||||
static std::string g_choice_opcode("Choice");
|
||||
[[ noreturn ]] static void throw_ex() { throw exception("unexpected occurrence of 'choice' expression");
|
||||
}
|
||||
static name * g_choice_name = nullptr;
|
||||
static std::string * g_choice_opcode = nullptr;
|
||||
|
||||
[[ noreturn ]] static void throw_ex() { throw exception("unexpected occurrence of 'choice' expression"); }
|
||||
|
||||
// We encode a 'choice' expression using a macro.
|
||||
// This is a trick to avoid creating a new kind of expression.
|
||||
|
@ -22,31 +22,44 @@ static std::string g_choice_opcode("Choice");
|
|||
// and have no semantic significance.
|
||||
class choice_macro_cell : public macro_definition_cell {
|
||||
public:
|
||||
virtual name get_name() const { return g_choice_name; }
|
||||
virtual name get_name() const { return *g_choice_name; }
|
||||
// Choice expressions must be replaced with metavariables before invoking the type checker.
|
||||
// Choice expressions cannot be exported. They are transient/auxiliary objects.
|
||||
virtual expr get_type(expr const &, expr const *, extension_context &) const { throw_ex(); }
|
||||
virtual optional<expr> expand(expr const &, extension_context &) const { throw_ex(); }
|
||||
virtual void write(serializer & s) const {
|
||||
// we should be able to write choice expressions because of notation declarations
|
||||
s.write_string(g_choice_opcode);
|
||||
s.write_string(*g_choice_opcode);
|
||||
}
|
||||
};
|
||||
|
||||
static macro_definition g_choice(new choice_macro_cell());
|
||||
static macro_definition * g_choice = nullptr;
|
||||
expr mk_choice(unsigned num_es, expr const * es) {
|
||||
lean_assert(num_es > 0);
|
||||
if (num_es == 1)
|
||||
return es[0];
|
||||
else
|
||||
return mk_macro(g_choice, num_es, es);
|
||||
return mk_macro(*g_choice, num_es, es);
|
||||
}
|
||||
|
||||
static register_macro_deserializer_fn
|
||||
choice_macro_des_fn(g_choice_opcode, [](deserializer &, unsigned num, expr const * args) { return mk_choice(num, args); });
|
||||
void initialize_choice() {
|
||||
g_choice_name = new name("choice");
|
||||
g_choice_opcode = new std::string("Choice");
|
||||
g_choice = new macro_definition(new choice_macro_cell());
|
||||
register_macro_deserializer(*g_choice_opcode,
|
||||
[](deserializer &, unsigned num, expr const * args) {
|
||||
return mk_choice(num, args);
|
||||
});
|
||||
}
|
||||
|
||||
void finalize_choice() {
|
||||
delete g_choice;
|
||||
delete g_choice_opcode;
|
||||
delete g_choice_name;
|
||||
}
|
||||
|
||||
bool is_choice(expr const & e) {
|
||||
return is_macro(e) && macro_def(e) == g_choice;
|
||||
return is_macro(e) && macro_def(e) == *g_choice;
|
||||
}
|
||||
|
||||
unsigned get_num_choices(expr const & e) {
|
||||
|
|
|
@ -35,4 +35,6 @@ unsigned get_num_choices(expr const & e);
|
|||
*/
|
||||
expr const & get_choice(expr const & e, unsigned i);
|
||||
void open_choice(lua_State * L);
|
||||
void initialize_choice();
|
||||
void finalize_choice();
|
||||
}
|
||||
|
|
|
@ -10,38 +10,37 @@ Author: Leonardo de Moura
|
|||
#include "library/kernel_bindings.h"
|
||||
|
||||
namespace lean {
|
||||
name const & get_explicit_name() {
|
||||
static name g_explicit_name("@");
|
||||
static register_annotation_fn g_explicit_annotation(g_explicit_name);
|
||||
return g_explicit_name;
|
||||
}
|
||||
static name * g_explicit_name = nullptr;
|
||||
static name * g_implicit_name = nullptr;
|
||||
static name * g_as_is_name = nullptr;
|
||||
|
||||
name const & get_implicit_name() {
|
||||
static name g_implicit_name("@^-1");
|
||||
static register_annotation_fn g_implicit_annotation(g_implicit_name);
|
||||
return g_implicit_name;
|
||||
}
|
||||
|
||||
name const & get_as_is_name() {
|
||||
static name g_as_is_name("as_is");
|
||||
static register_annotation_fn g_as_is_annotation(g_as_is_name);
|
||||
return g_as_is_name;
|
||||
}
|
||||
static name g_explicit_name = get_explicit_name(); // force '@' annotation to be registered
|
||||
static name g_implicit_name = get_implicit_name(); // force '@^-1' annotation to be registered
|
||||
static name g_as_is_name = get_as_is_name(); // force 'as_is' annotation to be registered
|
||||
|
||||
expr mk_explicit(expr const & e) { return mk_annotation(get_explicit_name(), e); }
|
||||
bool is_explicit(expr const & e) { return is_annotation(e, get_explicit_name()); }
|
||||
bool is_nested_explicit(expr const & e) { return is_nested_annotation(e, get_explicit_name()); }
|
||||
expr mk_as_is(expr const & e) { return mk_annotation(get_as_is_name(), e); }
|
||||
bool is_as_is(expr const & e) { return is_annotation(e, get_as_is_name()); }
|
||||
expr mk_implicit(expr const & e) { return mk_annotation(get_implicit_name(), e); }
|
||||
bool is_implicit(expr const & e) { return is_annotation(e, get_implicit_name()); }
|
||||
expr mk_explicit(expr const & e) { return mk_annotation(*g_explicit_name, e); }
|
||||
bool is_explicit(expr const & e) { return is_annotation(e, *g_explicit_name); }
|
||||
bool is_nested_explicit(expr const & e) { return is_nested_annotation(e, *g_explicit_name); }
|
||||
expr mk_as_is(expr const & e) { return mk_annotation(*g_as_is_name, e); }
|
||||
bool is_as_is(expr const & e) { return is_annotation(e, *g_as_is_name); }
|
||||
expr mk_implicit(expr const & e) { return mk_annotation(*g_implicit_name, e); }
|
||||
bool is_implicit(expr const & e) { return is_annotation(e, *g_implicit_name); }
|
||||
expr const & get_explicit_arg(expr const & e) { lean_assert(is_explicit(e)); return get_annotation_arg(e); }
|
||||
expr const & get_as_is_arg(expr const & e) { lean_assert(is_as_is(e)); return get_annotation_arg(e); }
|
||||
expr const & get_implicit_arg(expr const & e) { lean_assert(is_implicit(e)); return get_annotation_arg(e); }
|
||||
|
||||
void initialize_explicit() {
|
||||
g_explicit_name = new name("@");
|
||||
g_implicit_name = new name("@^-1");
|
||||
g_as_is_name = new name("as_is");
|
||||
|
||||
register_annotation(*g_explicit_name);
|
||||
register_annotation(*g_implicit_name);
|
||||
register_annotation(*g_as_is_name);
|
||||
}
|
||||
|
||||
void finalize_explicit() {
|
||||
delete g_as_is_name;
|
||||
delete g_implicit_name;
|
||||
delete g_explicit_name;
|
||||
}
|
||||
|
||||
static int mk_explicit(lua_State * L) { return push_expr(L, mk_explicit(to_expr(L, 1))); }
|
||||
static int is_explicit(lua_State * L) { return push_boolean(L, is_explicit(to_expr(L, 1))); }
|
||||
static void check_explicit(lua_State * L, int idx) {
|
||||
|
|
|
@ -42,4 +42,6 @@ expr const & get_as_is_arg(expr const & e);
|
|||
*/
|
||||
expr const & get_implicit_arg(expr const & e);
|
||||
void open_explicit(lua_State * L);
|
||||
void initialize_explicit();
|
||||
void finalize_explicit();
|
||||
}
|
||||
|
|
|
@ -5,13 +5,37 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "library/unifier.h"
|
||||
#include "library/kernel_serializer.h"
|
||||
#include "library/let.h"
|
||||
#include "library/typed_expr.h"
|
||||
#include "library/choice.h"
|
||||
#include "library/string.h"
|
||||
#include "library/resolve_macro.h"
|
||||
#include "library/annotation.h"
|
||||
#include "library/explicit.h"
|
||||
|
||||
namespace lean {
|
||||
void initialize_library_module() {
|
||||
initialize_unifier();
|
||||
initialize_kernel_serializer();
|
||||
initialize_let();
|
||||
initialize_typed_expr();
|
||||
initialize_choice();
|
||||
initialize_string();
|
||||
initialize_resolve_macro();
|
||||
initialize_annotation();
|
||||
initialize_explicit();
|
||||
}
|
||||
|
||||
void finalize_library_module() {
|
||||
finalize_explicit();
|
||||
finalize_annotation();
|
||||
finalize_resolve_macro();
|
||||
finalize_string();
|
||||
finalize_choice();
|
||||
finalize_typed_expr();
|
||||
finalize_let();
|
||||
finalize_kernel_serializer();
|
||||
finalize_unifier();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,14 +81,14 @@ struct level_sd {
|
|||
}
|
||||
};
|
||||
|
||||
static level_sd g_level_sd;
|
||||
static level_sd * g_level_sd = nullptr;
|
||||
|
||||
serializer & operator<<(serializer & s, level const & n) {
|
||||
s.get_extension<level_serializer>(g_level_sd.m_s_extid).write(n);
|
||||
s.get_extension<level_serializer>(g_level_sd->m_s_extid).write(n);
|
||||
return s;
|
||||
}
|
||||
|
||||
level read_level(deserializer & d) { return d.get_extension<level_deserializer>(g_level_sd.m_d_extid).read(); }
|
||||
level read_level(deserializer & d) { return d.get_extension<level_deserializer>(g_level_sd->m_d_extid).read(); }
|
||||
|
||||
serializer & operator<<(serializer & s, levels const & ls) { return write_list<level>(s, ls); }
|
||||
|
||||
|
@ -96,11 +96,10 @@ levels read_levels(deserializer & d) { return read_list<level>(d, read_level); }
|
|||
|
||||
// Expression serialization
|
||||
typedef std::unordered_map<std::string, macro_definition_cell::reader> macro_readers;
|
||||
static std::unique_ptr<macro_readers> g_macro_readers;
|
||||
static macro_readers * g_macro_readers = nullptr;
|
||||
|
||||
macro_readers & get_macro_readers() {
|
||||
if (!g_macro_readers)
|
||||
g_macro_readers.reset(new macro_readers());
|
||||
return *(g_macro_readers.get());
|
||||
return *g_macro_readers;
|
||||
}
|
||||
|
||||
void register_macro_deserializer(std::string const & k, macro_definition_cell::reader rd) {
|
||||
|
@ -133,7 +132,7 @@ static binder_info read_binder_info(deserializer & d) {
|
|||
return binder_info(imp, cast, ctx, s_imp);
|
||||
}
|
||||
|
||||
static name g_binder_name("a");
|
||||
static name * g_binder_name = nullptr;
|
||||
|
||||
class expr_serializer : public object_serializer<expr, expr_hash_alloc, expr_eqp> {
|
||||
typedef object_serializer<expr, expr_hash_alloc, expr_eqp> super;
|
||||
|
@ -143,7 +142,7 @@ class expr_serializer : public object_serializer<expr, expr_hash_alloc, expr_eqp
|
|||
void write_binder_name(serializer & s, name const & a) {
|
||||
// make sure binding names are atomic string
|
||||
if (!a.is_atomic() || a.is_numeral()) {
|
||||
s << g_binder_name.append_after(m_next_id);
|
||||
s << g_binder_name->append_after(m_next_id);
|
||||
m_next_id++;
|
||||
} else {
|
||||
s << a;
|
||||
|
@ -260,15 +259,15 @@ struct expr_sd {
|
|||
m_d_extid = deserializer::register_extension([](){ return std::unique_ptr<deserializer::extension>(new expr_deserializer()); });
|
||||
}
|
||||
};
|
||||
static expr_sd g_expr_sd;
|
||||
static expr_sd * g_expr_sd = nullptr;
|
||||
|
||||
serializer & operator<<(serializer & s, expr const & n) {
|
||||
s.get_extension<expr_serializer>(g_expr_sd.m_s_extid).write(n);
|
||||
s.get_extension<expr_serializer>(g_expr_sd->m_s_extid).write(n);
|
||||
return s;
|
||||
}
|
||||
|
||||
expr read_expr(deserializer & d) {
|
||||
return d.get_extension<expr_deserializer>(g_expr_sd.m_d_extid).read();
|
||||
return d.get_extension<expr_deserializer>(g_expr_sd->m_d_extid).read();
|
||||
}
|
||||
|
||||
// Declaration serialization
|
||||
|
@ -359,13 +358,17 @@ inductive_decls read_inductive_decls(deserializer & d) {
|
|||
return inductive_decls(ps, num_params, to_list(decls.begin(), decls.end()));
|
||||
}
|
||||
|
||||
static register_macro_deserializer_fn
|
||||
annotation_des_fn(get_annotation_opcode(),
|
||||
[](deserializer & d, unsigned num, expr const * args) {
|
||||
if (num != 1)
|
||||
throw corrupted_stream_exception();
|
||||
name k;
|
||||
d >> k;
|
||||
return mk_annotation(k, args[0]);
|
||||
});
|
||||
void initialize_kernel_serializer() {
|
||||
g_level_sd = new level_sd();
|
||||
g_macro_readers = new macro_readers();
|
||||
g_binder_name = new name("a");
|
||||
g_expr_sd = new expr_sd();
|
||||
}
|
||||
|
||||
void finalize_kernel_serializer() {
|
||||
delete g_expr_sd;
|
||||
delete g_binder_name;
|
||||
delete g_macro_readers;
|
||||
delete g_level_sd;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,15 +26,14 @@ serializer & operator<<(serializer & s, expr const & e);
|
|||
expr read_expr(deserializer & d);
|
||||
inline deserializer & operator>>(deserializer & d, expr & e) { e = read_expr(d); return d; }
|
||||
|
||||
void register_macro_deserializer(std::string const & k, macro_definition_cell::reader rd);
|
||||
struct register_macro_deserializer_fn {
|
||||
register_macro_deserializer_fn(std::string const & k, macro_definition_cell::reader rd) { register_macro_deserializer(k, rd); }
|
||||
};
|
||||
|
||||
serializer & operator<<(serializer & s, declaration const & d);
|
||||
declaration read_declaration(deserializer & d, module_idx midx);
|
||||
|
||||
typedef std::tuple<level_param_names, unsigned, list<inductive::inductive_decl>> inductive_decls;
|
||||
serializer & operator<<(serializer & s, inductive_decls const & ds);
|
||||
inductive_decls read_inductive_decls(deserializer & d);
|
||||
|
||||
void register_macro_deserializer(std::string const & k, macro_definition_cell::reader rd);
|
||||
void initialize_kernel_serializer();
|
||||
void finalize_kernel_serializer();
|
||||
}
|
||||
|
|
|
@ -10,15 +10,17 @@ Author: Leonardo de Moura
|
|||
#include "library/kernel_serializer.h"
|
||||
|
||||
namespace lean {
|
||||
static name g_let_value("letv");
|
||||
std::string const & get_let_value_opcode() {
|
||||
static std::string g_let_value_opcode("LetV");
|
||||
return g_let_value_opcode;
|
||||
}
|
||||
static name * g_let_value = nullptr;
|
||||
static std::string * g_let_value_opcode = nullptr;
|
||||
static atomic<unsigned> * g_next_let_value_id = nullptr;
|
||||
static name * g_let = nullptr;
|
||||
static std::string * g_let_opcode = nullptr;
|
||||
|
||||
std::string const & get_let_value_opcode() { return *g_let_value_opcode; }
|
||||
std::string const & get_let_opcode() { return * g_let_opcode; }
|
||||
|
||||
static atomic<unsigned> g_next_let_value_id(0);
|
||||
static unsigned next_let_value_id() {
|
||||
return atomic_fetch_add_explicit(&g_next_let_value_id, 1u, memory_order_seq_cst);
|
||||
return atomic_fetch_add_explicit(g_next_let_value_id, 1u, memory_order_seq_cst);
|
||||
}
|
||||
|
||||
class let_value_definition_cell : public macro_definition_cell {
|
||||
|
@ -29,7 +31,7 @@ class let_value_definition_cell : public macro_definition_cell {
|
|||
}
|
||||
public:
|
||||
let_value_definition_cell():m_id(next_let_value_id()) {}
|
||||
virtual name get_name() const { return g_let_value; }
|
||||
virtual name get_name() const { return *g_let_value; }
|
||||
virtual expr get_type(expr const & m, expr const * arg_types, extension_context &) const {
|
||||
check_macro(m);
|
||||
return arg_types[0];
|
||||
|
@ -63,19 +65,6 @@ expr get_let_value_expr(expr const e) {
|
|||
return macro_arg(e, 0);
|
||||
}
|
||||
|
||||
static register_macro_deserializer_fn
|
||||
let_value_des_fn(get_let_value_opcode(),
|
||||
[](deserializer &, unsigned num, expr const * args) {
|
||||
if (num != 1) throw corrupted_stream_exception();
|
||||
return mk_let_value(args[0]);
|
||||
});
|
||||
|
||||
static name g_let("let");
|
||||
std::string const & get_let_opcode() {
|
||||
static std::string g_let_opcode("Let");
|
||||
return g_let_opcode;
|
||||
}
|
||||
|
||||
class let_macro_definition_cell : public macro_definition_cell {
|
||||
name m_var_name;
|
||||
void check_macro(expr const & m) const {
|
||||
|
@ -85,7 +74,7 @@ class let_macro_definition_cell : public macro_definition_cell {
|
|||
public:
|
||||
let_macro_definition_cell(name const & n):m_var_name(n) {}
|
||||
name const & get_var_name() const { return m_var_name; }
|
||||
virtual name get_name() const { return g_let; }
|
||||
virtual name get_name() const { return *g_let; }
|
||||
virtual expr get_type(expr const & m, expr const * arg_types, extension_context &) const {
|
||||
check_macro(m);
|
||||
return arg_types[1];
|
||||
|
@ -125,12 +114,31 @@ expr const & get_let_body(expr const & e) {
|
|||
return macro_arg(e, 1);
|
||||
}
|
||||
|
||||
static register_macro_deserializer_fn
|
||||
let_des_fn(get_let_opcode(),
|
||||
[](deserializer & d, unsigned num, expr const * args) {
|
||||
if (num != 2) throw corrupted_stream_exception();
|
||||
name n;
|
||||
d >> n;
|
||||
return mk_let(n, args[0], args[1]);
|
||||
});
|
||||
void initialize_let() {
|
||||
g_let_value = new name("letv");
|
||||
g_let_value_opcode = new std::string("LetV");
|
||||
g_next_let_value_id = new atomic<unsigned>(0);
|
||||
register_macro_deserializer(*g_let_value_opcode,
|
||||
[](deserializer &, unsigned num, expr const * args) {
|
||||
if (num != 1) throw corrupted_stream_exception();
|
||||
return mk_let_value(args[0]);
|
||||
});
|
||||
g_let = new name("let");
|
||||
g_let_opcode = new std::string("Let");
|
||||
register_macro_deserializer(*g_let_opcode,
|
||||
[](deserializer & d, unsigned num, expr const * args) {
|
||||
if (num != 2) throw corrupted_stream_exception();
|
||||
name n;
|
||||
d >> n;
|
||||
return mk_let(n, args[0], args[1]);
|
||||
});
|
||||
}
|
||||
|
||||
void finalize_let() {
|
||||
delete g_let_opcode;
|
||||
delete g_let;
|
||||
delete g_next_let_value_id;
|
||||
delete g_let_value_opcode;
|
||||
delete g_let_value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,4 +17,7 @@ bool is_let(expr const & e);
|
|||
name const & get_let_var_name(expr const & e);
|
||||
expr const & get_let_value(expr const & e);
|
||||
expr const & get_let_body(expr const & e);
|
||||
|
||||
void initialize_let();
|
||||
void finalize_let();
|
||||
}
|
||||
|
|
|
@ -15,18 +15,17 @@ Author: Leonardo de Moura
|
|||
#include "library/bin_app.h"
|
||||
|
||||
namespace lean {
|
||||
static name g_resolve_macro_name("resolve");
|
||||
static std::string g_resolve_opcode("Res");
|
||||
|
||||
static name * g_resolve_macro_name = nullptr;
|
||||
static std::string * g_resolve_opcode = nullptr;
|
||||
// Declarations used by the resolve_macro
|
||||
static expr g_or(Const("or"));
|
||||
static expr g_not(Const("not"));
|
||||
static expr g_false(Const("false"));
|
||||
static expr g_or_elim(Const(name("or", "elim")));
|
||||
static expr g_or_intro_left(Const(name("or", "intro_left")));
|
||||
static expr g_or_intro_right(Const(name("or", "intro_right")));
|
||||
static expr g_absurd_elim(Const("absurd_elim"));
|
||||
static expr g_var_0(mk_var(0));
|
||||
static expr * g_or = nullptr;
|
||||
static expr * g_not = nullptr;
|
||||
static expr * g_false = nullptr;
|
||||
static expr * g_or_elim = nullptr;
|
||||
static expr * g_or_intro_left = nullptr;
|
||||
static expr * g_or_intro_right = nullptr;
|
||||
static expr * g_absurd_elim = nullptr;
|
||||
static expr * g_var_0 = nullptr;
|
||||
/**
|
||||
\brief Resolve macro encodes a simple propositional resolution step.
|
||||
It takes three arguments:
|
||||
|
@ -68,7 +67,8 @@ class resolve_macro_definition_cell : public macro_definition_cell {
|
|||
simple_delayed_justification m_dummy_jst;
|
||||
public:
|
||||
resolve_macro_definition_cell():m_dummy_jst([] { return mk_justification("resolve macro"); }) {
|
||||
m_dummy_jst.get(); // the delayed_justification may be accessed by different threads, thus we force its initialization.
|
||||
// the delayed_justification may be accessed by different threads, thus we force its initialization.
|
||||
m_dummy_jst.get();
|
||||
}
|
||||
|
||||
// The following const cast is say because we already initialized the delayed justification in the constructor.
|
||||
|
@ -112,7 +112,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool is_or(expr const & a, expr & lhs, expr & rhs) const { return is_bin_app(a, g_or, lhs, rhs); }
|
||||
bool is_or(expr const & a, expr & lhs, expr & rhs) const { return is_bin_app(a, *g_or, lhs, rhs); }
|
||||
|
||||
bool collect(expr const & lhs, expr const & rhs, expr const & l, buffer<expr> & R, extension_context & ctx) const {
|
||||
bool r1 = collect(lhs, l, R, ctx);
|
||||
|
@ -143,7 +143,7 @@ public:
|
|||
environment const & env = ctx.env();
|
||||
check_num_args(env, m);
|
||||
expr l = whnf(macro_arg(m, 0), ctx);
|
||||
expr not_l = whnf(g_not(l), ctx);
|
||||
expr not_l = whnf(mk_app(*g_not, l), ctx);
|
||||
expr C1 = arg_types[1];
|
||||
expr C2 = arg_types[2];
|
||||
buffer<expr> R; // resolvent
|
||||
|
@ -151,7 +151,7 @@ public:
|
|||
throw_kernel_exception(env, "invalid resolve macro, positive literal was not found", m);
|
||||
if (!collect(C2, not_l, R, ctx))
|
||||
throw_kernel_exception(env, "invalid resolve macro, negative literal was not found", m);
|
||||
return mk_bin_rop(g_or, g_false, R.size(), R.data());
|
||||
return mk_bin_rop(*g_or, *g_false, R.size(), R.data());
|
||||
}
|
||||
|
||||
// End of resolve_macro get_type implementation
|
||||
|
@ -166,7 +166,7 @@ public:
|
|||
environment const & env = ctx.env();
|
||||
check_num_args(env, m);
|
||||
expr l = whnf(macro_arg(m, 0), ctx);
|
||||
expr not_l = whnf(g_not(l), ctx);
|
||||
expr not_l = whnf(mk_app(*g_not, l), ctx);
|
||||
expr H1 = macro_arg(m, 1);
|
||||
expr H2 = macro_arg(m, 2);
|
||||
expr C1 = infer_type(H1, ctx);
|
||||
|
@ -176,7 +176,7 @@ public:
|
|||
return some_expr(mk_or_elim_tree1(l, not_l, C1, H1, C2, H2, R, ctx));
|
||||
}
|
||||
|
||||
bool is_or_app(expr const & a) const { return is_bin_app(a, g_or); }
|
||||
bool is_or_app(expr const & a) const { return is_bin_app(a, *g_or); }
|
||||
|
||||
/** \brief Given l : H, and R == (or ... l ...), create a proof term for R using or_intro_left and or_intro_right */
|
||||
expr mk_or_intro(expr const & l, expr const & H, expr const & R, extension_context & ctx) const {
|
||||
|
@ -187,11 +187,11 @@ public:
|
|||
// or_intro_left {a : Prop} (H : a) (b : Prop) : a ∨ b
|
||||
// or_intro_right {b : Prop} (a : Prop) (H : b) : a ∨ b
|
||||
if (is_def_eq(l, lhs, ctx)) {
|
||||
return g_or_intro_left(l, H, rhs);
|
||||
return mk_app(*g_or_intro_left, l, H, rhs);
|
||||
} else if (is_def_eq(l, rhs, ctx)) {
|
||||
return g_or_intro_right(l, lhs, H);
|
||||
return mk_app(*g_or_intro_right, l, lhs, H);
|
||||
} else {
|
||||
return g_or_intro_right(rhs, lhs, mk_or_intro(l, H, rhs, ctx));
|
||||
return mk_app(*g_or_intro_right, rhs, lhs, mk_or_intro(l, H, rhs, ctx));
|
||||
}
|
||||
} else if (is_def_eq(l, R, ctx)) {
|
||||
return H;
|
||||
|
@ -242,9 +242,10 @@ public:
|
|||
expr H2_1 = lift(H2);
|
||||
expr R_1 = lift(R);
|
||||
// or_elim {a b c : Prop} (H1 : a ∨ b) (H2 : a → c) (H3 : b → c) : c
|
||||
return g_or_elim(lhs1, rhs1, R, H1,
|
||||
mk_lambda("H2", lhs1, mk_or_elim_tree1(l_1, not_l_1, lhs1_1, g_var_0, C2_1, H2_1, R_1, ctx)),
|
||||
mk_lambda("H3", rhs1, mk_or_elim_tree1(l_1, not_l_1, rhs1_1, g_var_0, C2_1, H2_1, R_1, ctx)));
|
||||
return mk_app({*g_or_elim,
|
||||
lhs1, rhs1, R, H1,
|
||||
mk_lambda("H2", lhs1, mk_or_elim_tree1(l_1, not_l_1, lhs1_1, *g_var_0, C2_1, H2_1, R_1, ctx)),
|
||||
mk_lambda("H3", rhs1, mk_or_elim_tree1(l_1, not_l_1, rhs1_1, *g_var_0, C2_1, H2_1, R_1, ctx))});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -265,7 +266,7 @@ public:
|
|||
return mk_or_elim_tree2(l, H, not_l, lhs, rhs, H2, R, ctx);
|
||||
} else if (is_def_eq(C2, not_l, ctx)) {
|
||||
// absurd_elim {a : Prop} (b : Prop) (H1 : a) (H2 : ¬ a) : b
|
||||
return g_absurd_elim(l, R, H, H2);
|
||||
return mk_app(*g_absurd_elim, l, R, H, H2);
|
||||
} else {
|
||||
return mk_or_intro(C2, H2, R, ctx);
|
||||
}
|
||||
|
@ -288,31 +289,58 @@ public:
|
|||
expr rhs2_1 = lift(rhs2);
|
||||
expr R_1 = lift(R);
|
||||
// or_elim {a b c : Prop} (H1 : a ∨ b) (H2 : a → c) (H3 : b → c) : c
|
||||
return g_or_elim(lhs2, rhs2, R, H2,
|
||||
mk_lambda("H2", lhs2, mk_or_elim_tree2(l_1, H_1, not_l_1, lhs2_1, g_var_0, R_1, ctx)),
|
||||
mk_lambda("H3", rhs2, mk_or_elim_tree2(l_1, H_1, not_l_1, rhs2_1, g_var_0, R_1, ctx)));
|
||||
return mk_app({*g_or_elim,
|
||||
lhs2, rhs2, R, H2,
|
||||
mk_lambda("H2", lhs2, mk_or_elim_tree2(l_1, H_1, not_l_1, lhs2_1, *g_var_0, R_1, ctx)),
|
||||
mk_lambda("H3", rhs2, mk_or_elim_tree2(l_1, H_1, not_l_1, rhs2_1, *g_var_0, R_1, ctx))});
|
||||
}
|
||||
|
||||
virtual name get_name() const { return g_resolve_macro_name; }
|
||||
virtual name get_name() const { return *g_resolve_macro_name; }
|
||||
/** \brief Resolve is a very simple macro, we can trust its implementation most of the time. */
|
||||
virtual unsigned trust_level() const { return 0; }
|
||||
virtual void write(serializer & s) const { s.write_string(g_resolve_opcode); }
|
||||
virtual void write(serializer & s) const { s.write_string(*g_resolve_opcode); }
|
||||
};
|
||||
|
||||
static macro_definition g_resolve_macro_definition(new resolve_macro_definition_cell());
|
||||
static macro_definition * g_resolve_macro_definition = nullptr;
|
||||
|
||||
expr mk_resolve_macro(expr const & l, expr const & H1, expr const & H2) {
|
||||
expr args[3] = {l, H1, H2};
|
||||
return mk_macro(g_resolve_macro_definition, 3, args);
|
||||
return mk_macro(*g_resolve_macro_definition, 3, args);
|
||||
}
|
||||
|
||||
static register_macro_deserializer_fn
|
||||
resolve_macro_des_fn(g_resolve_opcode,
|
||||
[](deserializer &, unsigned num, expr const * args) {
|
||||
if (num != 3)
|
||||
throw corrupted_stream_exception();
|
||||
return mk_resolve_macro(args[0], args[1], args[2]);
|
||||
});
|
||||
void initialize_resolve_macro() {
|
||||
g_resolve_macro_name = new name("resolve");
|
||||
g_resolve_opcode = new std::string("Res");
|
||||
g_or = new expr(Const("or"));
|
||||
g_not = new expr(Const("not"));
|
||||
g_false = new expr(Const("false"));
|
||||
g_or_elim = new expr(Const(name("or", "elim")));
|
||||
g_or_intro_left = new expr(Const(name("or", "intro_left")));
|
||||
g_or_intro_right = new expr(Const(name("or", "intro_right")));
|
||||
g_absurd_elim = new expr(Const("absurd_elim"));
|
||||
g_var_0 = new expr(mk_var(0));
|
||||
g_resolve_macro_definition = new macro_definition(new resolve_macro_definition_cell());
|
||||
register_macro_deserializer(*g_resolve_opcode,
|
||||
[](deserializer &, unsigned num, expr const * args) {
|
||||
if (num != 3)
|
||||
throw corrupted_stream_exception();
|
||||
return mk_resolve_macro(args[0], args[1], args[2]);
|
||||
});
|
||||
}
|
||||
|
||||
void finalize_resolve_macro() {
|
||||
delete g_resolve_macro_definition;
|
||||
delete g_var_0;
|
||||
delete g_absurd_elim;
|
||||
delete g_or_intro_right;
|
||||
delete g_or_intro_left;
|
||||
delete g_or_elim;
|
||||
delete g_false;
|
||||
delete g_not;
|
||||
delete g_or;
|
||||
delete g_resolve_opcode;
|
||||
delete g_resolve_macro_name;
|
||||
}
|
||||
|
||||
static int mk_resolve_macro(lua_State * L) { return push_expr(L, mk_resolve_macro(to_expr(L, 1), to_expr(L, 2), to_expr(L, 3))); }
|
||||
void open_resolve_macro(lua_State * L) { SET_GLOBAL_FUN(mk_resolve_macro, "resolve_macro"); }
|
||||
|
|
|
@ -11,4 +11,6 @@ Author: Leonardo de Moura
|
|||
namespace lean {
|
||||
expr mk_resolve_macro(expr const & l, expr const & H1, expr const & H2);
|
||||
void open_resolve_macro(lua_State * L);
|
||||
void initialize_resolve_macro();
|
||||
void finalize_resolve_macro();
|
||||
}
|
||||
|
|
|
@ -11,17 +11,16 @@ Author: Leonardo de Moura
|
|||
#include "library/string.h"
|
||||
|
||||
namespace lean {
|
||||
static name g_string_macro("string_macro");
|
||||
static std::string g_string_opcode("Str");
|
||||
|
||||
static expr g_bool(Const(name("bool")));
|
||||
static expr g_ff(Const(name("bool", "ff")));
|
||||
static expr g_tt(Const(name("bool", "tt")));
|
||||
static expr g_char(Const(name("char")));
|
||||
static expr g_ascii(Const(name("char", "mk")));
|
||||
static expr g_string(Const(name("string")));
|
||||
static expr g_empty(Const(name("string", "empty")));
|
||||
static expr g_str(Const(name("string", "str")));
|
||||
static name * g_string_macro = nullptr;
|
||||
static std::string * g_string_opcode = nullptr;
|
||||
static expr * g_bool = nullptr;
|
||||
static expr * g_ff = nullptr;
|
||||
static expr * g_tt = nullptr;
|
||||
static expr * g_char = nullptr;
|
||||
static expr * g_ascii = nullptr;
|
||||
static expr * g_string = nullptr;
|
||||
static expr * g_empty = nullptr;
|
||||
static expr * g_str = nullptr;
|
||||
|
||||
expr from_string_core(unsigned i, std::string const & s);
|
||||
|
||||
|
@ -33,9 +32,9 @@ public:
|
|||
virtual bool lt(macro_definition_cell const & d) const {
|
||||
return m_value < static_cast<string_macro const &>(d).m_value;
|
||||
}
|
||||
virtual name get_name() const { return g_string_macro; }
|
||||
virtual name get_name() const { return *g_string_macro; }
|
||||
virtual expr get_type(expr const &, expr const *, extension_context &) const {
|
||||
return g_string;
|
||||
return *g_string;
|
||||
}
|
||||
virtual optional<expr> expand(expr const &, extension_context &) const {
|
||||
return some_expr(from_string_core(0, m_value));
|
||||
|
@ -71,7 +70,7 @@ public:
|
|||
}
|
||||
virtual bool is_atomic_pp(bool, bool) const { return true; }
|
||||
virtual unsigned hash() const { return std::hash<std::string>()(m_value); }
|
||||
virtual void write(serializer & s) const { s << g_string_opcode << m_value; }
|
||||
virtual void write(serializer & s) const { s << *g_string_opcode << m_value; }
|
||||
std::string const & get_value() const { return m_value; }
|
||||
};
|
||||
|
||||
|
@ -88,25 +87,49 @@ string_macro const & to_string_macro(expr const & e) {
|
|||
return *static_cast<string_macro const *>(macro_def(e).raw());
|
||||
}
|
||||
|
||||
static register_macro_deserializer_fn
|
||||
string_macro_des_fn(g_string_opcode,
|
||||
[](deserializer & d, unsigned num, expr const *) {
|
||||
if (num != 0)
|
||||
throw corrupted_stream_exception();
|
||||
std::string v = d.read_string();
|
||||
return mk_string_macro(v);
|
||||
});
|
||||
void initialize_string() {
|
||||
g_string_macro = new name("string_macro");
|
||||
g_string_opcode = new std::string("Str");
|
||||
g_bool = new expr(Const(name("bool")));
|
||||
g_ff = new expr(Const(name("bool", "ff")));
|
||||
g_tt = new expr(Const(name("bool", "tt")));
|
||||
g_char = new expr(Const(name("char")));
|
||||
g_ascii = new expr(Const(name("char", "mk")));
|
||||
g_string = new expr(Const(name("string")));
|
||||
g_empty = new expr(Const(name("string", "empty")));
|
||||
g_str = new expr(Const(name("string", "str")));
|
||||
register_macro_deserializer(*g_string_opcode,
|
||||
[](deserializer & d, unsigned num, expr const *) {
|
||||
if (num != 0)
|
||||
throw corrupted_stream_exception();
|
||||
std::string v = d.read_string();
|
||||
return mk_string_macro(v);
|
||||
});
|
||||
}
|
||||
|
||||
void finalize_string() {
|
||||
delete g_str;
|
||||
delete g_empty;
|
||||
delete g_string;
|
||||
delete g_ascii;
|
||||
delete g_char;
|
||||
delete g_tt;
|
||||
delete g_ff;
|
||||
delete g_bool;
|
||||
delete g_string_opcode;
|
||||
delete g_string_macro;
|
||||
}
|
||||
|
||||
bool has_string_decls(environment const & env) {
|
||||
try {
|
||||
type_checker tc(env);
|
||||
return
|
||||
tc.infer(g_ff).first == g_bool &&
|
||||
tc.infer(g_tt).first == g_bool &&
|
||||
tc.infer(g_ascii).first == g_bool >> (g_bool >> (g_bool >> (g_bool >> (g_bool >> (g_bool >> (g_bool >> (g_bool >> g_char))))))) &&
|
||||
tc.infer(g_empty).first == g_string &&
|
||||
tc.infer(g_str).first == g_char >> (g_string >> g_string);
|
||||
} catch (...) {
|
||||
tc.infer(*g_ff).first == *g_bool &&
|
||||
tc.infer(*g_tt).first == *g_bool &&
|
||||
tc.infer(*g_ascii).first == *g_bool >> (*g_bool >> (*g_bool >> (*g_bool >> (*g_bool >> (*g_bool >> (*g_bool >> (*g_bool >> *g_char))))))) &&
|
||||
tc.infer(*g_empty).first == *g_string &&
|
||||
tc.infer(*g_str).first == *g_char >> (*g_string >> *g_string);
|
||||
} catch (exception &) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -115,21 +138,21 @@ expr from_char(unsigned char c) {
|
|||
buffer<expr> bits;
|
||||
while (c != 0) {
|
||||
if (c % 2 == 1)
|
||||
bits.push_back(g_tt);
|
||||
bits.push_back(*g_tt);
|
||||
else
|
||||
bits.push_back(g_ff);
|
||||
bits.push_back(*g_ff);
|
||||
c /= 2;
|
||||
}
|
||||
while (bits.size() < 8)
|
||||
bits.push_back(g_ff);
|
||||
return mk_rev_app(g_ascii, bits.size(), bits.data());
|
||||
bits.push_back(*g_ff);
|
||||
return mk_rev_app(*g_ascii, bits.size(), bits.data());
|
||||
}
|
||||
|
||||
expr from_string_core(unsigned i, std::string const & s) {
|
||||
if (i == s.size())
|
||||
return g_empty;
|
||||
return *g_empty;
|
||||
else
|
||||
return mk_app(g_str, from_char(s[i]), from_string_core(i+1, s));
|
||||
return mk_app(*g_str, from_char(s[i]), from_string_core(i+1, s));
|
||||
}
|
||||
|
||||
expr from_string(std::string const & s) {
|
||||
|
@ -138,13 +161,13 @@ expr from_string(std::string const & s) {
|
|||
|
||||
bool to_char_core(expr const & e, buffer<char> & tmp) {
|
||||
buffer<expr> args;
|
||||
if (get_app_rev_args(e, args) == g_ascii && args.size() == 8) {
|
||||
if (get_app_rev_args(e, args) == *g_ascii && args.size() == 8) {
|
||||
unsigned v = 0;
|
||||
for (unsigned i = 0; i < args.size(); i++) {
|
||||
v *= 2;
|
||||
if (args[i] == g_tt)
|
||||
if (args[i] == *g_tt)
|
||||
v++;
|
||||
else if (args[i] != g_ff)
|
||||
else if (args[i] != *g_ff)
|
||||
return false;
|
||||
}
|
||||
tmp.push_back(v);
|
||||
|
@ -155,12 +178,12 @@ bool to_char_core(expr const & e, buffer<char> & tmp) {
|
|||
}
|
||||
|
||||
bool to_string_core(expr const & e, buffer<char> & tmp) {
|
||||
if (e == g_empty) {
|
||||
if (e == *g_empty) {
|
||||
return true;
|
||||
} else {
|
||||
buffer<expr> args;
|
||||
return
|
||||
get_app_args(e, args) == g_str &&
|
||||
get_app_args(e, args) == *g_str &&
|
||||
args.size() == 2 &&
|
||||
to_char_core(args[0], tmp) &&
|
||||
to_string_core(args[1], tmp);
|
||||
|
|
|
@ -36,4 +36,7 @@ expr from_string(std::string const & s);
|
|||
\see from_string
|
||||
*/
|
||||
optional<std::string> to_string(expr const & e);
|
||||
|
||||
void initialize_string();
|
||||
void finalize_string();
|
||||
}
|
||||
|
|
|
@ -17,38 +17,39 @@ Author: Leonardo de Moura
|
|||
|
||||
namespace lean {
|
||||
typedef std::unordered_map<name, expr_to_tactic_fn, name_hash, name_eq> expr_to_tactic_map;
|
||||
static expr_to_tactic_map * g_map = nullptr;
|
||||
|
||||
expr_to_tactic_map & get_expr_to_tactic_map() {
|
||||
static expr_to_tactic_map g_map;
|
||||
return g_map;
|
||||
return *g_map;
|
||||
}
|
||||
|
||||
void register_expr_to_tactic(name const & n, expr_to_tactic_fn const & fn) {
|
||||
void register_tac(name const & n, expr_to_tactic_fn const & fn) {
|
||||
get_expr_to_tactic_map().insert(mk_pair(n, fn));
|
||||
}
|
||||
|
||||
static name g_tac("tactic"), g_builtin_tac_name(g_tac, "builtin");
|
||||
static name g_exact_tac_name(g_tac, "exact"), g_and_then_tac_name(g_tac, "and_then");
|
||||
static name g_or_else_tac_name(g_tac, "or_else"), g_repeat_tac_name(g_tac, "repeat"), g_fixpoint_name(g_tac, "fixpoint");
|
||||
static name g_determ_tac_name(g_tac, "determ");
|
||||
static expr g_exact_tac_fn(Const(g_exact_tac_name)), g_and_then_tac_fn(Const(g_and_then_tac_name));
|
||||
static expr g_or_else_tac_fn(Const(g_or_else_tac_name)), g_repeat_tac_fn(Const(g_repeat_tac_name));
|
||||
static expr g_determ_tac_fn(Const(g_determ_tac_name));
|
||||
static expr g_tac_type(Const(g_tac)), g_builtin_tac(Const(g_builtin_tac_name)), g_fixpoint_tac(Const(g_fixpoint_name));
|
||||
expr const & get_exact_tac_fn() { return g_exact_tac_fn; }
|
||||
expr const & get_and_then_tac_fn() { return g_and_then_tac_fn; }
|
||||
expr const & get_or_else_tac_fn() { return g_or_else_tac_fn; }
|
||||
expr const & get_determ_tac_fn() { return g_determ_tac_fn; }
|
||||
expr const & get_repeat_tac_fn() { return g_repeat_tac_fn; }
|
||||
expr const & get_tactic_type() { return g_tac_type; }
|
||||
static expr * g_exact_tac_fn = nullptr;
|
||||
static expr * g_and_then_tac_fn = nullptr;
|
||||
static expr * g_or_else_tac_fn = nullptr;
|
||||
static expr * g_repeat_tac_fn = nullptr;
|
||||
static expr * g_determ_tac_fn = nullptr;
|
||||
static expr * g_tac_type = nullptr;
|
||||
static expr * g_builtin_tac = nullptr;
|
||||
static expr * g_fixpoint_tac = nullptr;
|
||||
expr const & get_exact_tac_fn() { return *g_exact_tac_fn; }
|
||||
expr const & get_and_then_tac_fn() { return *g_and_then_tac_fn; }
|
||||
expr const & get_or_else_tac_fn() { return *g_or_else_tac_fn; }
|
||||
expr const & get_determ_tac_fn() { return *g_determ_tac_fn; }
|
||||
expr const & get_repeat_tac_fn() { return *g_repeat_tac_fn; }
|
||||
expr const & get_tactic_type() { return *g_tac_type; }
|
||||
|
||||
bool has_tactic_decls(environment const & env) {
|
||||
try {
|
||||
type_checker tc(env);
|
||||
return
|
||||
tc.infer(g_builtin_tac).first == g_tac_type &&
|
||||
tc.infer(g_and_then_tac_fn).first == g_tac_type >> (g_tac_type >> g_tac_type) &&
|
||||
tc.infer(g_or_else_tac_fn).first == g_tac_type >> (g_tac_type >> g_tac_type) &&
|
||||
tc.infer(g_repeat_tac_fn).first == g_tac_type >> g_tac_type;
|
||||
tc.infer(*g_builtin_tac).first == *g_tac_type &&
|
||||
tc.infer(*g_and_then_tac_fn).first == *g_tac_type >> (*g_tac_type >> *g_tac_type) &&
|
||||
tc.infer(*g_or_else_tac_fn).first == *g_tac_type >> (*g_tac_type >> *g_tac_type) &&
|
||||
tc.infer(*g_repeat_tac_fn).first == *g_tac_type >> *g_tac_type;
|
||||
} catch (exception &) {
|
||||
return false;
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ static void throw_failed(expr const & e) {
|
|||
static bool is_builtin_tactic(expr const & v) {
|
||||
if (is_lambda(v))
|
||||
return is_builtin_tactic(binding_body(v));
|
||||
else if (v == g_builtin_tac)
|
||||
else if (v == *g_builtin_tac)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
@ -107,13 +108,13 @@ tactic expr_to_tactic(type_checker & tc, expr e, pos_info_provider const * p) {
|
|||
}
|
||||
}
|
||||
|
||||
static name g_tmp_prefix = name::mk_internal_unique_name();
|
||||
static name * g_tmp_prefix = nullptr;
|
||||
MK_THREAD_LOCAL_GET(unsigned, get_expr_tac_id, 0)
|
||||
static name_generator next_name_generator() {
|
||||
unsigned & c = get_expr_tac_id();
|
||||
unsigned r = c;
|
||||
c++;
|
||||
return name_generator(name(g_tmp_prefix, r));
|
||||
return name_generator(name(*g_tmp_prefix, r));
|
||||
}
|
||||
|
||||
tactic expr_to_tactic(environment const & env, expr const & e, pos_info_provider const * p) {
|
||||
|
@ -127,16 +128,16 @@ tactic fixpoint(expr const & b) {
|
|||
});
|
||||
}
|
||||
|
||||
register_simple_tac::register_simple_tac(name const & n, std::function<tactic()> f) {
|
||||
register_expr_to_tactic(n, [=](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
void register_simple_tac(name const & n, std::function<tactic()> const & f) {
|
||||
register_tac(n, [=](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
if (!is_constant(e))
|
||||
throw expr_to_tactic_exception(e, "invalid constant tactic");
|
||||
return f();
|
||||
});
|
||||
}
|
||||
|
||||
register_bin_tac::register_bin_tac(name const & n, std::function<tactic(tactic const &, tactic const &)> f) {
|
||||
register_expr_to_tactic(n, [=](type_checker & tc, expr const & e, pos_info_provider const * p) {
|
||||
void register_bin_tac(name const & n, std::function<tactic(tactic const &, tactic const &)> const & f) {
|
||||
register_tac(n, [=](type_checker & tc, expr const & e, pos_info_provider const * p) {
|
||||
buffer<expr> args;
|
||||
get_app_args(e, args);
|
||||
if (args.size() != 2)
|
||||
|
@ -146,8 +147,8 @@ register_bin_tac::register_bin_tac(name const & n, std::function<tactic(tactic c
|
|||
});
|
||||
}
|
||||
|
||||
register_unary_tac::register_unary_tac(name const & n, std::function<tactic(tactic const &)> f) {
|
||||
register_expr_to_tactic(n, [=](type_checker & tc, expr const & e, pos_info_provider const * p) {
|
||||
void register_unary_tac(name const & n, std::function<tactic(tactic const &)> const & f) {
|
||||
register_tac(n, [=](type_checker & tc, expr const & e, pos_info_provider const * p) {
|
||||
buffer<expr> args;
|
||||
get_app_args(e, args);
|
||||
if (args.size() != 1)
|
||||
|
@ -156,8 +157,8 @@ register_unary_tac::register_unary_tac(name const & n, std::function<tactic(tact
|
|||
});
|
||||
}
|
||||
|
||||
register_unary_num_tac::register_unary_num_tac(name const & n, std::function<tactic(tactic const &, unsigned k)> f) {
|
||||
register_expr_to_tactic(n, [=](type_checker & tc, expr const & e, pos_info_provider const * p) {
|
||||
void register_unary_num_tac(name const & n, std::function<tactic(tactic const &, unsigned k)> const & f) {
|
||||
register_tac(n, [=](type_checker & tc, expr const & e, pos_info_provider const * p) {
|
||||
buffer<expr> args;
|
||||
get_app_args(e, args);
|
||||
if (args.size() != 2)
|
||||
|
@ -174,64 +175,103 @@ register_unary_num_tac::register_unary_num_tac(name const & n, std::function<tac
|
|||
});
|
||||
}
|
||||
|
||||
static register_simple_tac reg_id(name(g_tac, "id"), []() { return id_tactic(); });
|
||||
static register_simple_tac reg_now(name(g_tac, "now"), []() { return now_tactic(); });
|
||||
static register_simple_tac reg_assumption(name(g_tac, "assumption"), []() { return assumption_tactic(); });
|
||||
static register_simple_tac reg_eassumption(name(g_tac, "eassumption"), []() { return eassumption_tactic(); });
|
||||
static register_simple_tac reg_fail(name(g_tac, "fail"), []() { return fail_tactic(); });
|
||||
static register_simple_tac reg_beta(name(g_tac, "beta"), []() { return beta_tactic(); });
|
||||
static register_bin_tac reg_then(g_and_then_tac_name, [](tactic const & t1, tactic const & t2) { return then(t1, t2); });
|
||||
static register_bin_tac reg_append(name(g_tac, "append"), [](tactic const & t1, tactic const & t2) { return append(t1, t2); });
|
||||
static register_bin_tac reg_interleave(name(g_tac, "interleave"), [](tactic const & t1, tactic const & t2) { return interleave(t1, t2); });
|
||||
static register_bin_tac reg_par(name(g_tac, "par"), [](tactic const & t1, tactic const & t2) { return par(t1, t2); });
|
||||
static register_bin_tac reg_orelse(g_or_else_tac_name, [](tactic const & t1, tactic const & t2) { return orelse(t1, t2); });
|
||||
static register_unary_tac reg_repeat(g_repeat_tac_name, [](tactic const & t1) { return repeat(t1); });
|
||||
static register_tac reg_state(name(g_tac, "state"), [](type_checker &, expr const & e, pos_info_provider const * p) {
|
||||
if (p)
|
||||
if (auto it = p->get_pos_info(e))
|
||||
return trace_state_tactic(std::string(p->get_file_name()), *it);
|
||||
return trace_state_tactic();
|
||||
});
|
||||
static register_tac reg_trace(name(g_tac, "trace"), [](type_checker & tc, expr const & e, pos_info_provider const *) {
|
||||
buffer<expr> args;
|
||||
get_app_args(e, args);
|
||||
if (args.size() != 1)
|
||||
throw expr_to_tactic_exception(e, "invalid trace tactic, argument expected");
|
||||
if (auto str = to_string(args[0]))
|
||||
return trace_tactic(*str);
|
||||
else if (auto str = to_string(tc.whnf(args[0]).first))
|
||||
return trace_tactic(*str);
|
||||
else
|
||||
throw expr_to_tactic_exception(e, "invalid trace tactic, string value expected");
|
||||
});
|
||||
static register_tac reg_apply(name(g_tac, "apply"), [](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
return apply_tactic(app_arg(e));
|
||||
});
|
||||
static register_tac reg_exact(g_exact_tac_name, [](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
return exact_tactic(app_arg(e));
|
||||
});
|
||||
static register_tac reg_unfold(name(g_tac, "unfold"), [](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
expr id = get_app_fn(app_arg(e));
|
||||
if (!is_constant(id))
|
||||
return fail_tactic();
|
||||
else
|
||||
return unfold_tactic(const_name(id));
|
||||
});
|
||||
static register_unary_num_tac reg_at_most(name(g_tac, "at_most"), [](tactic const & t, unsigned k) { return take(t, k); });
|
||||
static register_unary_num_tac reg_discard(name(g_tac, "discard"), [](tactic const & t, unsigned k) { return discard(t, k); });
|
||||
static register_unary_num_tac reg_focus_at(name(g_tac, "focus_at"), [](tactic const & t, unsigned k) { return focus(t, k); });
|
||||
static register_unary_num_tac reg_try_for(name(g_tac, "try_for"), [](tactic const & t, unsigned k) { return try_for(t, k); });
|
||||
static register_tac reg_fixpoint(g_fixpoint_name, [](type_checker & tc, expr const & e, pos_info_provider const *) {
|
||||
if (!is_constant(app_fn(e)))
|
||||
throw expr_to_tactic_exception(e, "invalid fixpoint tactic, it must have one argument");
|
||||
expr r = tc.whnf(mk_app(app_arg(e), e)).first;
|
||||
return fixpoint(r);
|
||||
});
|
||||
static name * g_by_name = nullptr;
|
||||
|
||||
static name g_by_name("by");
|
||||
register_annotation_fn g_by_annotation(g_by_name);
|
||||
|
||||
expr mk_by(expr const & e) { return mk_annotation(g_by_name, e); }
|
||||
bool is_by(expr const & e) { return is_annotation(e, g_by_name); }
|
||||
expr mk_by(expr const & e) { return mk_annotation(*g_by_name, e); }
|
||||
bool is_by(expr const & e) { return is_annotation(e, *g_by_name); }
|
||||
expr const & get_by_arg(expr const & e) { lean_assert(is_by(e)); return get_annotation_arg(e); }
|
||||
|
||||
void initialize_expr_to_tactic() {
|
||||
g_tmp_prefix = new name(name::mk_internal_unique_name());
|
||||
|
||||
g_by_name = new name("by");
|
||||
register_annotation(*g_by_name);
|
||||
|
||||
g_map = new expr_to_tactic_map();
|
||||
|
||||
name g_tac("tactic");
|
||||
name g_builtin_tac_name(g_tac, "builtin");
|
||||
name g_exact_tac_name(g_tac, "exact");
|
||||
name g_and_then_tac_name(g_tac, "and_then");
|
||||
name g_or_else_tac_name(g_tac, "or_else");
|
||||
name g_repeat_tac_name(g_tac, "repeat");
|
||||
name g_fixpoint_name(g_tac, "fixpoint");
|
||||
name g_determ_tac_name(g_tac, "determ");
|
||||
g_exact_tac_fn = new expr(Const(g_exact_tac_name));
|
||||
g_and_then_tac_fn = new expr(Const(g_and_then_tac_name));
|
||||
g_or_else_tac_fn = new expr(Const(g_or_else_tac_name));
|
||||
g_repeat_tac_fn = new expr(Const(g_repeat_tac_name));
|
||||
g_determ_tac_fn = new expr(Const(g_determ_tac_name));
|
||||
g_tac_type = new expr(Const(g_tac));
|
||||
g_builtin_tac = new expr(Const(g_builtin_tac_name));
|
||||
g_fixpoint_tac = new expr(Const(g_fixpoint_name));
|
||||
|
||||
register_simple_tac(name(g_tac, "id"), []() { return id_tactic(); });
|
||||
register_simple_tac(name(g_tac, "now"), []() { return now_tactic(); });
|
||||
register_simple_tac(name(g_tac, "assumption"), []() { return assumption_tactic(); });
|
||||
register_simple_tac(name(g_tac, "eassumption"), []() { return eassumption_tactic(); });
|
||||
register_simple_tac(name(g_tac, "fail"), []() { return fail_tactic(); });
|
||||
register_simple_tac(name(g_tac, "beta"), []() { return beta_tactic(); });
|
||||
register_bin_tac(g_and_then_tac_name, [](tactic const & t1, tactic const & t2) { return then(t1, t2); });
|
||||
register_bin_tac(name(g_tac, "append"), [](tactic const & t1, tactic const & t2) { return append(t1, t2); });
|
||||
register_bin_tac(name(g_tac, "interleave"), [](tactic const & t1, tactic const & t2) { return interleave(t1, t2); });
|
||||
register_bin_tac(name(g_tac, "par"), [](tactic const & t1, tactic const & t2) { return par(t1, t2); });
|
||||
register_bin_tac(g_or_else_tac_name, [](tactic const & t1, tactic const & t2) { return orelse(t1, t2); });
|
||||
register_unary_tac(g_repeat_tac_name, [](tactic const & t1) { return repeat(t1); });
|
||||
register_tac(name(g_tac, "state"), [](type_checker &, expr const & e, pos_info_provider const * p) {
|
||||
if (p)
|
||||
if (auto it = p->get_pos_info(e))
|
||||
return trace_state_tactic(std::string(p->get_file_name()), *it);
|
||||
return trace_state_tactic();
|
||||
});
|
||||
register_tac(name(g_tac, "trace"), [](type_checker & tc, expr const & e, pos_info_provider const *) {
|
||||
buffer<expr> args;
|
||||
get_app_args(e, args);
|
||||
if (args.size() != 1)
|
||||
throw expr_to_tactic_exception(e, "invalid trace tactic, argument expected");
|
||||
if (auto str = to_string(args[0]))
|
||||
return trace_tactic(*str);
|
||||
else if (auto str = to_string(tc.whnf(args[0]).first))
|
||||
return trace_tactic(*str);
|
||||
else
|
||||
throw expr_to_tactic_exception(e, "invalid trace tactic, string value expected");
|
||||
});
|
||||
register_tac(name(g_tac, "apply"), [](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
return apply_tactic(app_arg(e));
|
||||
});
|
||||
register_tac(g_exact_tac_name, [](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
return exact_tactic(app_arg(e));
|
||||
});
|
||||
register_tac(name(g_tac, "unfold"), [](type_checker &, expr const & e, pos_info_provider const *) {
|
||||
expr id = get_app_fn(app_arg(e));
|
||||
if (!is_constant(id))
|
||||
return fail_tactic();
|
||||
else
|
||||
return unfold_tactic(const_name(id));
|
||||
});
|
||||
register_unary_num_tac(name(g_tac, "at_most"), [](tactic const & t, unsigned k) { return take(t, k); });
|
||||
register_unary_num_tac(name(g_tac, "discard"), [](tactic const & t, unsigned k) { return discard(t, k); });
|
||||
register_unary_num_tac(name(g_tac, "focus_at"), [](tactic const & t, unsigned k) { return focus(t, k); });
|
||||
register_unary_num_tac(name(g_tac, "try_for"), [](tactic const & t, unsigned k) { return try_for(t, k); });
|
||||
register_tac(g_fixpoint_name, [](type_checker & tc, expr const & e, pos_info_provider const *) {
|
||||
if (!is_constant(app_fn(e)))
|
||||
throw expr_to_tactic_exception(e, "invalid fixpoint tactic, it must have one argument");
|
||||
expr r = tc.whnf(mk_app(app_arg(e), e)).first;
|
||||
return fixpoint(r);
|
||||
});
|
||||
}
|
||||
|
||||
void finalize_expr_to_tactic() {
|
||||
delete g_fixpoint_tac;
|
||||
delete g_builtin_tac;
|
||||
delete g_tac_type;
|
||||
delete g_determ_tac_fn;
|
||||
delete g_repeat_tac_fn;
|
||||
delete g_or_else_tac_fn;
|
||||
delete g_and_then_tac_fn;
|
||||
delete g_exact_tac_fn;
|
||||
delete g_map;
|
||||
delete g_by_name;
|
||||
delete g_tmp_prefix;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,21 +57,12 @@ public:
|
|||
typedef std::function<tactic(type_checker & tc, expr const & e, pos_info_provider const *)> expr_to_tactic_fn;
|
||||
|
||||
/** \brief Register a new "procedural attachment" for expr_to_tactic. */
|
||||
void register_expr_to_tactic(name const & n, expr_to_tactic_fn const & fn);
|
||||
void register_tac(name const & n, expr_to_tactic_fn const & fn);
|
||||
void register_simple_tac(name const & n, std::function<tactic()> const & f);
|
||||
void register_bin_tac(name const & n, std::function<tactic(tactic const &, tactic const &)> const & f);
|
||||
void register_unary_tac(name const & n, std::function<tactic(tactic const &)> const & f);
|
||||
void register_unary_num_tac(name const & n, std::function<tactic(tactic const &, unsigned)> const & f);
|
||||
|
||||
struct register_tac {
|
||||
register_tac(name const & n, expr_to_tactic_fn fn) { register_expr_to_tactic(n, fn); }
|
||||
};
|
||||
struct register_simple_tac {
|
||||
register_simple_tac(name const & n, std::function<tactic()> f);
|
||||
};
|
||||
struct register_bin_tac {
|
||||
register_bin_tac(name const & n, std::function<tactic(tactic const &, tactic const &)> f);
|
||||
};
|
||||
struct register_unary_tac {
|
||||
register_unary_tac(name const & n, std::function<tactic(tactic const &)> f);
|
||||
};
|
||||
struct register_unary_num_tac {
|
||||
register_unary_num_tac(name const & n, std::function<tactic(tactic const &, unsigned)> f);
|
||||
};
|
||||
void initialize_expr_to_tactic();
|
||||
void finalize_expr_to_tactic();
|
||||
}
|
||||
|
|
|
@ -5,13 +5,16 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "library/tactic/proof_state.h"
|
||||
#include "library/tactic/expr_to_tactic.h"
|
||||
|
||||
namespace lean {
|
||||
void initialize_tactic_module() {
|
||||
initialize_proof_state();
|
||||
initialize_expr_to_tactic();
|
||||
}
|
||||
|
||||
void finalize_tactic_module() {
|
||||
finalize_expr_to_tactic();
|
||||
finalize_proof_state();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,16 +8,12 @@ Author: Leonardo de Moura
|
|||
#include "library/kernel_serializer.h"
|
||||
|
||||
namespace lean {
|
||||
name const & get_typed_expr_name() {
|
||||
static name g_typed_expr("typed_expr");
|
||||
return g_typed_expr;
|
||||
}
|
||||
|
||||
std::string const & get_typed_expr_opcode() {
|
||||
static std::string g_typed_expr_opcode("TyE");
|
||||
return g_typed_expr_opcode;
|
||||
}
|
||||
static name * g_typed_expr_name = nullptr;
|
||||
static std::string * g_typed_expr_opcode = nullptr;
|
||||
static macro_definition * g_typed_expr = nullptr;
|
||||
|
||||
name const & get_typed_expr_name() { return *g_typed_expr_name; }
|
||||
std::string const & get_typed_expr_opcode() { return *g_typed_expr_opcode; }
|
||||
|
||||
/** \brief This macro is used to "enforce" a given type to an expression.
|
||||
It is equivalent to
|
||||
|
@ -51,24 +47,33 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static macro_definition g_typed_expr(new typed_expr_macro_definition_cell());
|
||||
|
||||
bool is_typed_expr(expr const & e) {
|
||||
return is_macro(e) && macro_def(e) == g_typed_expr;
|
||||
return is_macro(e) && macro_def(e) == *g_typed_expr;
|
||||
}
|
||||
|
||||
expr mk_typed_expr(expr const & t, expr const & v) {
|
||||
expr args[2] = {t, v};
|
||||
return mk_macro(g_typed_expr, 2, args);
|
||||
return mk_macro(*g_typed_expr, 2, args);
|
||||
}
|
||||
|
||||
expr get_typed_expr_type(expr const & e) { lean_assert(is_typed_expr(e)); return macro_arg(e, 0); }
|
||||
expr get_typed_expr_expr(expr const & e) { lean_assert(is_typed_expr(e)); return macro_arg(e, 1); }
|
||||
|
||||
static register_macro_deserializer_fn
|
||||
typed_expr_macro_des_fn(get_typed_expr_opcode(), [](deserializer &, unsigned num, expr const * args) {
|
||||
if (num != 2)
|
||||
throw corrupted_stream_exception();
|
||||
return mk_typed_expr(args[0], args[1]);
|
||||
});
|
||||
void initialize_typed_expr() {
|
||||
g_typed_expr_name = new name("typed_expr");
|
||||
g_typed_expr_opcode = new std::string("TyE");
|
||||
g_typed_expr = new macro_definition(new typed_expr_macro_definition_cell());
|
||||
register_macro_deserializer(*g_typed_expr_opcode,
|
||||
[](deserializer &, unsigned num, expr const * args) {
|
||||
if (num != 2)
|
||||
throw corrupted_stream_exception();
|
||||
return mk_typed_expr(args[0], args[1]);
|
||||
});
|
||||
}
|
||||
|
||||
void finalize_typed_expr() {
|
||||
delete g_typed_expr;
|
||||
delete g_typed_expr_opcode;
|
||||
delete g_typed_expr_name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,4 +22,7 @@ expr get_typed_expr_type(expr const & e);
|
|||
\remark get_typed_expr_type(mk_typed_expr(t, e)) == e
|
||||
*/
|
||||
expr get_typed_expr_expr(expr const & e);
|
||||
|
||||
void initialize_typed_expr();
|
||||
void finalize_typed_expr();
|
||||
}
|
||||
|
|
|
@ -10,11 +10,15 @@ Author: Leonardo de Moura
|
|||
#include <vector>
|
||||
#include <limits>
|
||||
#include "util/test.h"
|
||||
#include "util/init_module.h"
|
||||
#include "util/sexpr/init_module.h"
|
||||
#include "kernel/expr.h"
|
||||
#include "kernel/expr_sets.h"
|
||||
#include "kernel/free_vars.h"
|
||||
#include "kernel/abstract.h"
|
||||
#include "kernel/instantiate.h"
|
||||
#include "kernel/init_module.h"
|
||||
#include "library/init_module.h"
|
||||
#include "library/max_sharing.h"
|
||||
#include "library/print.h"
|
||||
#include "library/deep_copy.h"
|
||||
|
@ -363,6 +367,10 @@ static void tst18() {
|
|||
|
||||
int main() {
|
||||
save_stack_info();
|
||||
initialize_util_module();
|
||||
initialize_sexpr_module();
|
||||
initialize_kernel_module();
|
||||
initialize_library_module();
|
||||
init_default_print_fn();
|
||||
lean_assert(sizeof(expr) == sizeof(optional<expr>));
|
||||
tst1();
|
||||
|
@ -392,5 +400,9 @@ int main() {
|
|||
std::cout << "sizeof(optional<sexpr>): " << sizeof(optional<sexpr>) << "\n";
|
||||
std::cout << "sizeof(std::function): " << sizeof(std::function<expr(expr const &, optional<expr> const &)>) << "\n";
|
||||
std::cout << "done" << "\n";
|
||||
finalize_library_module();
|
||||
finalize_kernel_module();
|
||||
finalize_sexpr_module();
|
||||
finalize_util_module();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,12 @@ Author: Leonardo de Moura
|
|||
#include <locale>
|
||||
#include "util/test.h"
|
||||
#include "util/exception.h"
|
||||
#include "util/init_module.h"
|
||||
#include "util/sexpr/init_module.h"
|
||||
#include "kernel/init_module.h"
|
||||
#include "kernel/level.h"
|
||||
#include "library/kernel_serializer.h"
|
||||
#include "library/init_module.h"
|
||||
using namespace lean;
|
||||
|
||||
static void check_serializer(level const & l) {
|
||||
|
@ -63,7 +67,15 @@ static void tst2() {
|
|||
|
||||
int main() {
|
||||
save_stack_info();
|
||||
initialize_util_module();
|
||||
initialize_sexpr_module();
|
||||
initialize_kernel_module();
|
||||
initialize_library_module();
|
||||
tst1();
|
||||
tst2();
|
||||
finalize_library_module();
|
||||
finalize_kernel_module();
|
||||
finalize_sexpr_module();
|
||||
finalize_util_module();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ Author: Soonho Kong
|
|||
#include <utility>
|
||||
#include <string>
|
||||
#include "util/test.h"
|
||||
#include "util/init_module.h"
|
||||
#include "util/numerics/mpq.h"
|
||||
#include "util/sexpr/format.h"
|
||||
#include "util/sexpr/sexpr_fn.h"
|
||||
|
@ -127,6 +128,7 @@ static void tst6() {
|
|||
|
||||
int main() {
|
||||
save_stack_info();
|
||||
initialize_util_module();
|
||||
initialize_sexpr_module();
|
||||
tst1();
|
||||
tst2();
|
||||
|
@ -135,5 +137,6 @@ int main() {
|
|||
tst5();
|
||||
tst6();
|
||||
finalize_sexpr_module();
|
||||
finalize_util_module();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
|||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include "util/test.h"
|
||||
#include "util/init_module.h"
|
||||
#include "util/sexpr/options.h"
|
||||
#include "util/sexpr/option_declarations.h"
|
||||
#include "util/sexpr/init_module.h"
|
||||
|
@ -155,6 +156,7 @@ static void tst6() {
|
|||
|
||||
int main() {
|
||||
save_stack_info();
|
||||
initialize_util_module();
|
||||
initialize_sexpr_module();
|
||||
name fakeopt("fakeopt");
|
||||
register_bool_option(fakeopt, false, "fake option");
|
||||
|
@ -167,5 +169,6 @@ int main() {
|
|||
tst6();
|
||||
|
||||
finalize_sexpr_module();
|
||||
finalize_util_module();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ Author: Leonardo de Moura
|
|||
#include "util/debug.h"
|
||||
#include "util/list.h"
|
||||
#include "util/name.h"
|
||||
#include "util/init_module.h"
|
||||
using namespace lean;
|
||||
|
||||
template<typename T>
|
||||
|
@ -66,15 +67,15 @@ struct list_int_initializer {
|
|||
}
|
||||
};
|
||||
|
||||
static list_int_initializer g_list_int_initializer;
|
||||
std::unique_ptr<list_int_initializer> g_list_int_initializer;
|
||||
|
||||
serializer & operator<<(serializer & s, list<int> const & l) {
|
||||
s.get_extension<list_int_serializer>(g_list_int_initializer.m_serializer_extid).write(l);
|
||||
s.get_extension<list_int_serializer>(g_list_int_initializer->m_serializer_extid).write(l);
|
||||
return s;
|
||||
}
|
||||
|
||||
deserializer & operator>>(deserializer & d, list<int> & l) {
|
||||
l = d.get_extension<list_int_deserializer>(g_list_int_initializer.m_deserializer_extid).read();
|
||||
l = d.get_extension<list_int_deserializer>(g_list_int_initializer->m_deserializer_extid).read();
|
||||
return d;
|
||||
}
|
||||
|
||||
|
@ -171,9 +172,13 @@ static void tst4() {
|
|||
}
|
||||
|
||||
int main() {
|
||||
save_stack_info();
|
||||
initialize_util_module();
|
||||
g_list_int_initializer.reset(new list_int_initializer());
|
||||
tst1();
|
||||
tst2();
|
||||
tst3();
|
||||
tst4();
|
||||
finalize_util_module();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ Author: Leonardo de Moura
|
|||
#include <string>
|
||||
#include "util/test.h"
|
||||
#include "util/name.h"
|
||||
#include "util/init_module.h"
|
||||
#include "util/numerics/mpq.h"
|
||||
#include "util/sexpr/sexpr.h"
|
||||
#include "util/sexpr/sexpr_fn.h"
|
||||
|
@ -240,6 +241,7 @@ static void tst10() {
|
|||
|
||||
int main() {
|
||||
save_stack_info();
|
||||
initialize_util_module();
|
||||
initialize_sexpr_module();
|
||||
tst1();
|
||||
tst2();
|
||||
|
@ -252,5 +254,6 @@ int main() {
|
|||
tst9();
|
||||
tst10();
|
||||
finalize_sexpr_module();
|
||||
finalize_util_module();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ add_library(util trace.cpp debug.cpp name.cpp name_set.cpp
|
|||
realpath.cpp script_state.cpp script_exception.cpp rb_map.cpp
|
||||
lua.cpp luaref.cpp lua_named_param.cpp stackinfo.cpp lean_path.cpp
|
||||
serializer.cpp lbool.cpp thread_script_state.cpp bitap_fuzzy_search.cpp
|
||||
init_module.cpp
|
||||
${THREAD_CPP})
|
||||
|
||||
target_link_libraries(util ${LEAN_LIBS})
|
||||
|
|
|
@ -49,13 +49,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static std::unique_ptr<extension_factory> g_extension_factory;
|
||||
|
||||
static extension_factory & get_extension_factory() {
|
||||
if (!g_extension_factory)
|
||||
g_extension_factory.reset(new extension_factory());
|
||||
return *g_extension_factory;
|
||||
}
|
||||
static extension_factory * g_extension_factory;
|
||||
static void initialize() { g_extension_factory = new extension_factory(); }
|
||||
static void finalize() { delete g_extension_factory; }
|
||||
static extension_factory & get_extension_factory() { return *g_extension_factory; }
|
||||
|
||||
static unsigned register_extension(mk_extension mk) {
|
||||
return get_extension_factory().register_extension(mk);
|
||||
|
@ -79,5 +76,6 @@ public:
|
|||
}
|
||||
};
|
||||
template<typename T>
|
||||
std::unique_ptr<typename extensible_object<T>::extension_factory> extensible_object<T>::g_extension_factory;
|
||||
typename extensible_object<T>::extension_factory *
|
||||
extensible_object<T>::g_extension_factory = nullptr;
|
||||
}
|
||||
|
|
19
src/util/init_module.cpp
Normal file
19
src/util/init_module.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
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 "util/serializer.h"
|
||||
#include "util/name.h"
|
||||
|
||||
namespace lean {
|
||||
void initialize_util_module() {
|
||||
initialize_serializer();
|
||||
initialize_name();
|
||||
}
|
||||
void finalize_util_module() {
|
||||
finalize_name();
|
||||
finalize_serializer();
|
||||
}
|
||||
}
|
12
src/util/init_module.h
Normal file
12
src/util/init_module.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
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
|
||||
|
||||
namespace lean {
|
||||
void initialize_util_module();
|
||||
void finalize_util_module();
|
||||
}
|
|
@ -477,15 +477,23 @@ struct name_sd {
|
|||
m_deserializer_extid = deserializer::register_extension([](){ return std::unique_ptr<deserializer::extension>(new name_deserializer()); });
|
||||
}
|
||||
};
|
||||
static name_sd g_name_sd;
|
||||
static name_sd * g_name_sd = nullptr;
|
||||
|
||||
void initialize_name() {
|
||||
g_name_sd = new name_sd();
|
||||
}
|
||||
|
||||
void finalize_name() {
|
||||
delete g_name_sd;
|
||||
}
|
||||
|
||||
serializer & operator<<(serializer & s, name const & n) {
|
||||
s.get_extension<name_serializer>(g_name_sd.m_serializer_extid).write(n);
|
||||
s.get_extension<name_serializer>(g_name_sd->m_serializer_extid).write(n);
|
||||
return s;
|
||||
}
|
||||
|
||||
name read_name(deserializer & d) {
|
||||
return d.get_extension<name_deserializer>(g_name_sd.m_deserializer_extid).read();
|
||||
return d.get_extension<name_deserializer>(g_name_sd->m_deserializer_extid).read();
|
||||
}
|
||||
|
||||
DECL_UDATA(name)
|
||||
|
|
|
@ -196,4 +196,6 @@ list<name> & to_list_name(lua_State * L, int idx);
|
|||
list<name> to_list_name_ext(lua_State * L, int idx);
|
||||
int push_list_name(lua_State * L, list<name> const & l);
|
||||
void open_name(lua_State * L);
|
||||
void initialize_name();
|
||||
void finalize_name();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Copyright (c) 2013-2014 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
|
@ -14,9 +14,7 @@ Author: Leonardo de Moura
|
|||
#endif
|
||||
|
||||
namespace lean {
|
||||
/**
|
||||
\brief Helper class for serializing objects.
|
||||
*/
|
||||
/** \brief Helper class for serializing objects. */
|
||||
template<class T, class HashFn, class EqFn>
|
||||
class object_serializer : public serializer::extension {
|
||||
std::unordered_map<T, unsigned, HashFn, EqFn> m_table;
|
||||
|
@ -43,9 +41,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Helper class for deserializing objects.
|
||||
*/
|
||||
/** \brief Helper class for deserializing objects. */
|
||||
template<class T>
|
||||
class object_deserializer : public deserializer::extension {
|
||||
std::vector<T> m_table;
|
||||
|
|
|
@ -12,6 +12,16 @@ Author: Leonardo de Moura
|
|||
#include "util/exception.h"
|
||||
|
||||
namespace lean {
|
||||
void initialize_serializer() {
|
||||
serializer::initialize();
|
||||
deserializer::initialize();
|
||||
}
|
||||
|
||||
void finalize_serializer() {
|
||||
deserializer::finalize();
|
||||
serializer::finalize();
|
||||
}
|
||||
|
||||
void serializer_core::write_unsigned(unsigned i) {
|
||||
static_assert(sizeof(i) == 4, "unexpected unsigned size");
|
||||
m_out.put((i >> 24) & 0xff);
|
||||
|
|
|
@ -71,6 +71,9 @@ public:
|
|||
corrupted_stream_exception();
|
||||
};
|
||||
|
||||
void initialize_serializer();
|
||||
void finalize_serializer();
|
||||
|
||||
template<typename T>
|
||||
serializer & write_list(serializer & s, list<T> const & ls) {
|
||||
s << length(ls);
|
||||
|
|
|
@ -10,6 +10,7 @@ Author: Leonardo de Moura
|
|||
|
||||
namespace lean {
|
||||
void initialize_sexpr_module() {
|
||||
initialize_sexpr();
|
||||
initialize_option_declarations();
|
||||
initialize_options();
|
||||
initialize_format();
|
||||
|
@ -19,5 +20,6 @@ void finalize_sexpr_module() {
|
|||
finalize_format();
|
||||
finalize_options();
|
||||
finalize_option_declarations();
|
||||
finalize_sexpr();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -370,15 +370,23 @@ struct sexpr_sd {
|
|||
m_d_extid = deserializer::register_extension([](){ return std::unique_ptr<deserializer::extension>(new sexpr_deserializer()); });
|
||||
}
|
||||
};
|
||||
static sexpr_sd g_sexpr_sd;
|
||||
static sexpr_sd * g_sexpr_sd = nullptr;
|
||||
|
||||
void initialize_sexpr() {
|
||||
g_sexpr_sd = new sexpr_sd();
|
||||
}
|
||||
|
||||
void finalize_sexpr() {
|
||||
delete g_sexpr_sd;
|
||||
}
|
||||
|
||||
serializer & operator<<(serializer & s, sexpr const & n) {
|
||||
s.get_extension<sexpr_serializer>(g_sexpr_sd.m_s_extid).write(n);
|
||||
s.get_extension<sexpr_serializer>(g_sexpr_sd->m_s_extid).write(n);
|
||||
return s;
|
||||
}
|
||||
|
||||
sexpr read_sexpr(deserializer & d) {
|
||||
return d.get_extension<sexpr_deserializer>(g_sexpr_sd.m_d_extid).read();
|
||||
return d.get_extension<sexpr_deserializer>(g_sexpr_sd->m_d_extid).read();
|
||||
}
|
||||
|
||||
DECL_UDATA(sexpr)
|
||||
|
|
|
@ -186,4 +186,6 @@ inline deserializer & operator>>(deserializer & d, sexpr & a) { a = read_sexpr(d
|
|||
|
||||
UDATA_DEFS(sexpr)
|
||||
void open_sexpr(lua_State * L);
|
||||
void initialize_sexpr();
|
||||
void finalize_sexpr();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue