feat(frontends/lean): allow transient classes/instances, i.e.,

classes/instances that are not saved in .olean files
This commit is contained in:
Leonardo de Moura 2014-09-19 12:42:22 -07:00
parent 93c2c30310
commit 48dbd13eef
8 changed files with 57 additions and 55 deletions

View file

@ -63,42 +63,30 @@ end is_transitive
inductive is_equivalence {T : Type} (R : T → T → Type) : Prop :=
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 :=
is_equivalence.rec (λx y z, x) 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_symmetric [instance]
{T : Type} {R : T → T → Type} {C : is_equivalence R} : is_symmetric R :=
is_equivalence.rec (λx y z, y) C
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
inductive is_PER {T : Type} (R : T → T → Type) : Prop :=
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 :=
is_PER.rec (λx y, x) C
theorem is_transitive {T : Type} {R : T → T → Type} {C : is_PER R} : is_transitive R :=
theorem is_PER.is_transitive [instance]
{T : Type} {R : T → T → Type} {C : is_PER R} : is_transitive R :=
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
-- -----------------------------------------

View file

@ -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)) :
fibrant (Πx : A, B x)
instance unit_fibrant
instance nat_fibrant
instance bool_fibrant
instance sum_fibrant
instance prod_fibrant
instance sigma_fibrant
instance pi_fibrant
theorem test_fibrant : fibrant (nat × (nat ⊎ nat)) := _
instance [persistent] unit_fibrant
instance [persistent] nat_fibrant
instance [persistent] bool_fibrant
instance [persistent] sum_fibrant
instance [persistent] prod_fibrant
instance [persistent] sigma_fibrant
instance [persistent] pi_fibrant
end fibrant

View file

@ -46,8 +46,6 @@ static name g_renaming("renaming");
static name g_as("as");
static name g_colon(":");
static name g_persistent("[persistent]");
environment print_cmd(parser & p) {
if (p.curr() == scanner::token_kind::String) {
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 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) {
bool persistent = false;
parse_persistent(p, persistent);

View file

@ -11,6 +11,7 @@ Author: Leonardo de Moura
#include "library/kernel_serializer.h"
#include "library/opaque_hints.h"
#include "frontends/lean/parser.h"
#include "frontends/lean/util.h"
#include "frontends/lean/tactic_hint.h"
namespace lean {
@ -91,13 +92,13 @@ name get_class_name(environment const & env, expr const & e) {
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);
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();
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);
expr type = d.get_type();
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)));
}
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) {
@ -124,24 +125,29 @@ list<name> get_class_instances(environment const & env, name const & c) {
environment add_instance_cmd(parser & p) {
bool found = false;
bool persistent = false;
parse_persistent(p, persistent);
environment env = p.env();
while (p.curr_is_identifier()) {
found = true;
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)
throw parser_error("invalid 'class instance' declaration, at least one identifier expected", p.pos());
return env;
}
environment add_class_cmd(parser & p) {
bool found = false;
environment env = p.env();
bool persistent = false;
parse_persistent(p, persistent);
while (p.curr_is_identifier()) {
found = true;
name c = p.check_constant_next("invalid 'class' declaration, constant expected");
env = add_class(env, c);
env = add_class(env, c, persistent);
}
if (!found)
throw parser_error("invalid 'class' declaration, at least one identifier expected", p.pos());

View file

@ -12,9 +12,9 @@ Author: Leonardo de Moura
namespace lean {
/** \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. */
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 . */
bool is_class(environment const & env, name const & c);
/** \brief Return the instances of the given class. */

View file

@ -17,6 +17,18 @@ Author: Leonardo de Moura
#include "frontends/lean/parser.h"
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) {
if (!n.is_atomic())
throw exception(sstream() << "invalid declaration name '" << n << "', identifier must be atomic");

View file

@ -12,6 +12,12 @@ Author: Leonardo de Moura
namespace lean {
class parser;
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_in_section_or_context(parser const & p);
bool is_root_namespace(name const & n);

View file

@ -0,0 +1,4 @@
import hott.fibrant
open prod sum fibrant
theorem test_fibrant : fibrant (nat × (nat ⊎ nat))