feat(frontends/lean): allow transient classes/instances, i.e.,
classes/instances that are not saved in .olean files
This commit is contained in:
parent
93c2c30310
commit
48dbd13eef
8 changed files with 57 additions and 55 deletions
|
@ -63,42 +63,30 @@ end is_transitive
|
||||||
inductive is_equivalence {T : Type} (R : T → T → Type) : Prop :=
|
inductive is_equivalence {T : Type} (R : T → T → Type) : Prop :=
|
||||||
mk : is_reflexive R → is_symmetric R → is_transitive R → is_equivalence R
|
mk : is_reflexive R → is_symmetric R → is_transitive R → is_equivalence R
|
||||||
|
|
||||||
namespace is_equivalence
|
theorem is_equivalence.is_reflexive [instance]
|
||||||
|
{T : Type} (R : T → T → Type) {C : is_equivalence R} : is_reflexive R :=
|
||||||
|
is_equivalence.rec (λx y z, x) C
|
||||||
|
|
||||||
theorem is_reflexive {T : Type} (R : T → T → Type) {C : is_equivalence R} : is_reflexive R :=
|
theorem is_equivalence.is_symmetric [instance]
|
||||||
is_equivalence.rec (λx y z, x) C
|
{T : Type} {R : T → T → Type} {C : is_equivalence R} : is_symmetric R :=
|
||||||
|
is_equivalence.rec (λx y z, y) C
|
||||||
theorem is_symmetric {T : Type} {R : T → T → Type} {C : is_equivalence R} : is_symmetric R :=
|
|
||||||
is_equivalence.rec (λx y z, y) C
|
|
||||||
|
|
||||||
theorem is_transitive {T : Type} {R : T → T → Type} {C : is_equivalence R} : is_transitive R :=
|
|
||||||
is_equivalence.rec (λx y z, z) C
|
|
||||||
|
|
||||||
end is_equivalence
|
|
||||||
|
|
||||||
instance is_equivalence.is_reflexive
|
|
||||||
instance is_equivalence.is_symmetric
|
|
||||||
instance is_equivalence.is_transitive
|
|
||||||
|
|
||||||
|
theorem is_equivalence.is_transitive [instance]
|
||||||
|
{T : Type} {R : T → T → Type} {C : is_equivalence R} : is_transitive R :=
|
||||||
|
is_equivalence.rec (λx y z, z) C
|
||||||
|
|
||||||
-- partial equivalence relation
|
-- partial equivalence relation
|
||||||
inductive is_PER {T : Type} (R : T → T → Type) : Prop :=
|
inductive is_PER {T : Type} (R : T → T → Type) : Prop :=
|
||||||
mk : is_symmetric R → is_transitive R → is_PER R
|
mk : is_symmetric R → is_transitive R → is_PER R
|
||||||
|
|
||||||
namespace is_PER
|
theorem is_PER.is_symmetric [instance]
|
||||||
|
{T : Type} {R : T → T → Type} {C : is_PER R} : is_symmetric R :=
|
||||||
|
is_PER.rec (λx y, x) C
|
||||||
|
|
||||||
theorem is_symmetric {T : Type} {R : T → T → Type} {C : is_PER R} : is_symmetric R :=
|
theorem is_PER.is_transitive [instance]
|
||||||
is_PER.rec (λx y, x) C
|
{T : Type} {R : T → T → Type} {C : is_PER R} : is_transitive R :=
|
||||||
|
|
||||||
theorem is_transitive {T : Type} {R : T → T → Type} {C : is_PER R} : is_transitive R :=
|
|
||||||
is_PER.rec (λx y, y) C
|
is_PER.rec (λx y, y) C
|
||||||
|
|
||||||
end is_PER
|
|
||||||
|
|
||||||
instance is_PER.is_symmetric
|
|
||||||
instance is_PER.is_transitive
|
|
||||||
|
|
||||||
|
|
||||||
-- Congruence for unary and binary functions
|
-- Congruence for unary and binary functions
|
||||||
-- -----------------------------------------
|
-- -----------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,12 @@ axiom sigma_fibrant {A : Type} {B : A → Type} (C1 : fibrant A) (C2 : Πx : A,
|
||||||
axiom pi_fibrant {A : Type} {B : A → Type} (C1 : fibrant A) (C2 : Πx : A, fibrant (B x)) :
|
axiom pi_fibrant {A : Type} {B : A → Type} (C1 : fibrant A) (C2 : Πx : A, fibrant (B x)) :
|
||||||
fibrant (Πx : A, B x)
|
fibrant (Πx : A, B x)
|
||||||
|
|
||||||
instance unit_fibrant
|
instance [persistent] unit_fibrant
|
||||||
instance nat_fibrant
|
instance [persistent] nat_fibrant
|
||||||
instance bool_fibrant
|
instance [persistent] bool_fibrant
|
||||||
instance sum_fibrant
|
instance [persistent] sum_fibrant
|
||||||
instance prod_fibrant
|
instance [persistent] prod_fibrant
|
||||||
instance sigma_fibrant
|
instance [persistent] sigma_fibrant
|
||||||
instance pi_fibrant
|
instance [persistent] pi_fibrant
|
||||||
|
|
||||||
theorem test_fibrant : fibrant (nat × (nat ⊎ nat)) := _
|
|
||||||
|
|
||||||
end fibrant
|
end fibrant
|
||||||
|
|
|
@ -46,8 +46,6 @@ static name g_renaming("renaming");
|
||||||
static name g_as("as");
|
static name g_as("as");
|
||||||
static name g_colon(":");
|
static name g_colon(":");
|
||||||
|
|
||||||
static name g_persistent("[persistent]");
|
|
||||||
|
|
||||||
environment print_cmd(parser & p) {
|
environment print_cmd(parser & p) {
|
||||||
if (p.curr() == scanner::token_kind::String) {
|
if (p.curr() == scanner::token_kind::String) {
|
||||||
p.regular_stream() << p.get_str_val() << endl;
|
p.regular_stream() << p.get_str_val() << endl;
|
||||||
|
@ -296,16 +294,6 @@ environment open_export_cmd(parser & p, bool open) {
|
||||||
environment open_cmd(parser & p) { return open_export_cmd(p, true); }
|
environment open_cmd(parser & p) { return open_export_cmd(p, true); }
|
||||||
environment export_cmd(parser & p) { return open_export_cmd(p, false); }
|
environment export_cmd(parser & p) { return open_export_cmd(p, false); }
|
||||||
|
|
||||||
bool parse_persistent(parser & p, bool & persistent) {
|
|
||||||
if (p.curr_is_token_or_id(g_persistent)) {
|
|
||||||
p.next();
|
|
||||||
persistent = true;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
environment coercion_cmd(parser & p) {
|
environment coercion_cmd(parser & p) {
|
||||||
bool persistent = false;
|
bool persistent = false;
|
||||||
parse_persistent(p, persistent);
|
parse_persistent(p, persistent);
|
||||||
|
|
|
@ -11,6 +11,7 @@ Author: Leonardo de Moura
|
||||||
#include "library/kernel_serializer.h"
|
#include "library/kernel_serializer.h"
|
||||||
#include "library/opaque_hints.h"
|
#include "library/opaque_hints.h"
|
||||||
#include "frontends/lean/parser.h"
|
#include "frontends/lean/parser.h"
|
||||||
|
#include "frontends/lean/util.h"
|
||||||
#include "frontends/lean/tactic_hint.h"
|
#include "frontends/lean/tactic_hint.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
@ -91,13 +92,13 @@ name get_class_name(environment const & env, expr const & e) {
|
||||||
return c_name;
|
return c_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
environment add_class(environment const & env, name const & n) {
|
environment add_class(environment const & env, name const & n, bool persistent) {
|
||||||
check_class(env, n);
|
check_class(env, n);
|
||||||
return class_ext::add_entry(env, get_dummy_ios(), class_entry(n));
|
return class_ext::add_entry(env, get_dummy_ios(), class_entry(n), persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static name g_tmp_prefix = name::mk_internal_unique_name();
|
static name g_tmp_prefix = name::mk_internal_unique_name();
|
||||||
environment add_instance(environment const & env, name const & n) {
|
environment add_instance(environment const & env, name const & n, bool persistent) {
|
||||||
declaration d = env.get(n);
|
declaration d = env.get(n);
|
||||||
expr type = d.get_type();
|
expr type = d.get_type();
|
||||||
name_generator ngen(g_tmp_prefix);
|
name_generator ngen(g_tmp_prefix);
|
||||||
|
@ -109,7 +110,7 @@ environment add_instance(environment const & env, name const & n) {
|
||||||
type = instantiate(binding_body(type), mk_local(ngen.next(), binding_domain(type)));
|
type = instantiate(binding_body(type), mk_local(ngen.next(), binding_domain(type)));
|
||||||
}
|
}
|
||||||
name c = get_class_name(env, get_app_fn(type));
|
name c = get_class_name(env, get_app_fn(type));
|
||||||
return class_ext::add_entry(env, get_dummy_ios(), class_entry(c, n));
|
return class_ext::add_entry(env, get_dummy_ios(), class_entry(c, n), persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_class(environment const & env, name const & c) {
|
bool is_class(environment const & env, name const & c) {
|
||||||
|
@ -124,24 +125,29 @@ list<name> get_class_instances(environment const & env, name const & c) {
|
||||||
|
|
||||||
environment add_instance_cmd(parser & p) {
|
environment add_instance_cmd(parser & p) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
bool persistent = false;
|
||||||
|
parse_persistent(p, persistent);
|
||||||
environment env = p.env();
|
environment env = p.env();
|
||||||
while (p.curr_is_identifier()) {
|
while (p.curr_is_identifier()) {
|
||||||
found = true;
|
found = true;
|
||||||
name c = p.check_constant_next("invalid 'class instance' declaration, constant expected");
|
name c = p.check_constant_next("invalid 'class instance' declaration, constant expected");
|
||||||
env = add_instance(env, c);
|
env = add_instance(env, c, persistent);
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
throw parser_error("invalid 'class instance' declaration, at least one identifier expected", p.pos());
|
throw parser_error("invalid 'class instance' declaration, at least one identifier expected", p.pos());
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
environment add_class_cmd(parser & p) {
|
environment add_class_cmd(parser & p) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
environment env = p.env();
|
environment env = p.env();
|
||||||
|
bool persistent = false;
|
||||||
|
parse_persistent(p, persistent);
|
||||||
while (p.curr_is_identifier()) {
|
while (p.curr_is_identifier()) {
|
||||||
found = true;
|
found = true;
|
||||||
name c = p.check_constant_next("invalid 'class' declaration, constant expected");
|
name c = p.check_constant_next("invalid 'class' declaration, constant expected");
|
||||||
env = add_class(env, c);
|
env = add_class(env, c, persistent);
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
throw parser_error("invalid 'class' declaration, at least one identifier expected", p.pos());
|
throw parser_error("invalid 'class' declaration, at least one identifier expected", p.pos());
|
||||||
|
|
|
@ -12,9 +12,9 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
/** \brief Add a new 'class' to the environment (if it is not already declared) */
|
/** \brief Add a new 'class' to the environment (if it is not already declared) */
|
||||||
environment add_class(environment const & env, name const & n);
|
environment add_class(environment const & env, name const & n, bool persistent = true);
|
||||||
/** \brief Add a new 'class instance' to the environment. */
|
/** \brief Add a new 'class instance' to the environment. */
|
||||||
environment add_instance(environment const & env, name const & n);
|
environment add_instance(environment const & env, name const & n, bool persistent = true);
|
||||||
/** \brief Return true iff \c c was declared with \c add_class . */
|
/** \brief Return true iff \c c was declared with \c add_class . */
|
||||||
bool is_class(environment const & env, name const & c);
|
bool is_class(environment const & env, name const & c);
|
||||||
/** \brief Return the instances of the given class. */
|
/** \brief Return the instances of the given class. */
|
||||||
|
|
|
@ -17,6 +17,18 @@ Author: Leonardo de Moura
|
||||||
#include "frontends/lean/parser.h"
|
#include "frontends/lean/parser.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
static name g_persistent("[persistent]");
|
||||||
|
|
||||||
|
bool parse_persistent(parser & p, bool & persistent) {
|
||||||
|
if (p.curr_is_token_or_id(g_persistent)) {
|
||||||
|
p.next();
|
||||||
|
persistent = true;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void check_atomic(name const & n) {
|
void check_atomic(name const & n) {
|
||||||
if (!n.is_atomic())
|
if (!n.is_atomic())
|
||||||
throw exception(sstream() << "invalid declaration name '" << n << "', identifier must be atomic");
|
throw exception(sstream() << "invalid declaration name '" << n << "', identifier must be atomic");
|
||||||
|
|
|
@ -12,6 +12,12 @@ Author: Leonardo de Moura
|
||||||
namespace lean {
|
namespace lean {
|
||||||
class parser;
|
class parser;
|
||||||
typedef std::unique_ptr<type_checker> type_checker_ptr;
|
typedef std::unique_ptr<type_checker> type_checker_ptr;
|
||||||
|
|
||||||
|
/** \brief Parse optional '[persistent]' modifier.
|
||||||
|
return true if it is was found, and paremeter \c persistent to true.
|
||||||
|
*/
|
||||||
|
bool parse_persistent(parser & p, bool & persistent);
|
||||||
|
|
||||||
void check_atomic(name const & n);
|
void check_atomic(name const & n);
|
||||||
void check_in_section_or_context(parser const & p);
|
void check_in_section_or_context(parser const & p);
|
||||||
bool is_root_namespace(name const & n);
|
bool is_root_namespace(name const & n);
|
||||||
|
|
4
tests/lean/run/fibrant.lean
Normal file
4
tests/lean/run/fibrant.lean
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import hott.fibrant
|
||||||
|
open prod sum fibrant
|
||||||
|
|
||||||
|
theorem test_fibrant : fibrant (nat × (nat ⊎ nat))
|
Loading…
Reference in a new issue