feat(frontends/lean): force 'classes' to be declared before instances are declared, closes #228

This commit is contained in:
Leonardo de Moura 2014-10-07 18:02:15 -07:00
parent d8572e249d
commit 744cee8dd8
24 changed files with 53 additions and 36 deletions

View file

@ -61,11 +61,11 @@ namespace category
i = id ∘ i : eq.symm id_left i = id ∘ i : eq.symm id_left
... = id : H ... = id : H
inductive is_section {A B : ob} (f : mor A B) : Type := inductive is_section [class] {A B : ob} (f : mor A B) : Type :=
mk : ∀{g}, g ∘ f = id → is_section f mk : ∀{g}, g ∘ f = id → is_section f
inductive is_retraction {A B : ob} (f : mor A B) : Type := inductive is_retraction [class] {A B : ob} (f : mor A B) : Type :=
mk : ∀{g}, f ∘ g = id → is_retraction f mk : ∀{g}, f ∘ g = id → is_retraction f
inductive is_iso {A B : ob} (f : mor A B) : Type := inductive is_iso [class] {A B : ob} (f : mor A B) : Type :=
mk : ∀{g}, g ∘ f = id → f ∘ g = id → is_iso f mk : ∀{g}, g ∘ f = id → f ∘ g = id → is_iso f
definition retraction_of {A B : ob} (f : mor A B) {H : is_section f} : mor B A := definition retraction_of {A B : ob} (f : mor A B) {H : is_section f} : mor B A :=

View file

@ -18,7 +18,7 @@ definition symmetric {T : Type} (R : T → T → Type) : Type := ∀⦃x y⦄, R
definition transitive {T : Type} (R : T → T → Type) : Type := ∀⦃x y z⦄, R x y → R y z → R x z definition transitive {T : Type} (R : T → T → Type) : Type := ∀⦃x y z⦄, R x y → R y z → R x z
inductive is_reflexive {T : Type} (R : T → T → Type) : Prop := inductive is_reflexive [class] {T : Type} (R : T → T → Type) : Prop :=
mk : reflexive R → is_reflexive R mk : reflexive R → is_reflexive R
namespace is_reflexive namespace is_reflexive
@ -32,7 +32,7 @@ namespace is_reflexive
end is_reflexive end is_reflexive
inductive is_symmetric {T : Type} (R : T → T → Type) : Prop := inductive is_symmetric [class] {T : Type} (R : T → T → Type) : Prop :=
mk : symmetric R → is_symmetric R mk : symmetric R → is_symmetric R
namespace is_symmetric namespace is_symmetric
@ -46,7 +46,7 @@ namespace is_symmetric
end is_symmetric end is_symmetric
inductive is_transitive {T : Type} (R : T → T → Type) : Prop := inductive is_transitive [class] {T : Type} (R : T → T → Type) : Prop :=
mk : transitive R → is_transitive R mk : transitive R → is_transitive R
namespace is_transitive namespace is_transitive
@ -60,7 +60,7 @@ namespace is_transitive
end is_transitive end is_transitive
inductive is_equivalence {T : Type} (R : T → T → Type) : Prop := inductive is_equivalence [class] {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
theorem is_equivalence.is_reflexive [instance] theorem is_equivalence.is_reflexive [instance]
@ -90,12 +90,12 @@ theorem is_PER.is_transitive [instance]
-- Congruence for unary and binary functions -- Congruence for unary and binary functions
-- ----------------------------------------- -- -----------------------------------------
inductive congruence {T1 : Type} (R1 : T1 → T1 → Prop) {T2 : Type} (R2 : T2 → T2 → Prop) inductive congruence [class] {T1 : Type} (R1 : T1 → T1 → Prop) {T2 : Type} (R2 : T2 → T2 → Prop)
(f : T1 → T2) : Prop := (f : T1 → T2) : Prop :=
mk : (∀x y, R1 x y → R2 (f x) (f y)) → congruence R1 R2 f mk : (∀x y, R1 x y → R2 (f x) (f y)) → congruence R1 R2 f
-- for binary functions -- for binary functions
inductive congruence2 {T1 : Type} (R1 : T1 → T1 → Prop) {T2 : Type} (R2 : T2 → T2 → Prop) inductive congruence2 [class] {T1 : Type} (R1 : T1 → T1 → Prop) {T2 : Type} (R2 : T2 → T2 → Prop)
{T3 : Type} (R3 : T3 → T3 → Prop) (f : T1 → T2 → T3) : Prop := {T3 : Type} (R3 : T3 → T3 → Prop) (f : T1 → T2 → T3) : Prop :=
mk : (∀(x1 y1 : T1) (x2 y2 : T2), R1 x1 y1 → R2 x2 y2 → R3 (f x1 x2) (f y1 y2)) → mk : (∀(x1 y1 : T1) (x2 y2 : T2), R1 x1 y1 → R2 x2 y2 → R3 (f x1 x2) (f y1 y2)) →
congruence2 R1 R2 R3 f congruence2 R1 R2 R3 f
@ -161,7 +161,7 @@ congruence.mk (λx y H, H)
-- Relations that can be coerced to functions / implications -- Relations that can be coerced to functions / implications
-- --------------------------------------------------------- -- ---------------------------------------------------------
inductive mp_like {R : Type → Type → Prop} {a b : Type} (H : R a b) : Type := inductive mp_like [class] {R : Type → Type → Prop} {a b : Type} (H : R a b) : Type :=
mk {} : (a → b) → @mp_like R a b H mk {} : (a → b) → @mp_like R a b H
namespace mp_like namespace mp_like

View file

@ -7,7 +7,7 @@ import data.prod data.sum data.sigma
open unit bool nat prod sum sigma open unit bool nat prod sum sigma
inductive fibrant (T : Type) : Type := inductive fibrant [class] (T : Type) : Type :=
fibrant_mk : fibrant T fibrant_mk : fibrant T
namespace fibrant namespace fibrant

View file

@ -4,7 +4,7 @@
import logic.connectives import logic.connectives
inductive decidable (p : Prop) : Type := inductive decidable [class] (p : Prop) : Type :=
inl : p → decidable p, inl : p → decidable p,
inr : ¬p → decidable p inr : ¬p → decidable p

View file

@ -4,7 +4,7 @@
import logic.connectives import logic.connectives
inductive inhabited (A : Type) : Type := inductive inhabited [class] (A : Type) : Type :=
mk : A → inhabited A mk : A → inhabited A
namespace inhabited namespace inhabited

View file

@ -4,7 +4,7 @@
import .inhabited import .inhabited
open inhabited open inhabited
inductive nonempty (A : Type) : Prop := inductive nonempty [class] (A : Type) : Prop :=
intro : A → nonempty A intro : A → nonempty A
namespace nonempty namespace nonempty

View file

@ -123,11 +123,17 @@ static void check_class(environment const & env, name const & c_name) {
throw exception(sstream() << "invalid class, '" << c_name << "' is a definition"); throw exception(sstream() << "invalid class, '" << c_name << "' is a definition");
} }
static void check_is_class(environment const & env, name const & c_name) {
class_state const & s = class_ext::get_state(env);
if (!s.m_instances.contains(c_name))
throw exception(sstream() << "'" << c_name << "' is not a class");
}
name get_class_name(environment const & env, expr const & e) { name get_class_name(environment const & env, expr const & e) {
if (!is_constant(e)) if (!is_constant(e))
throw exception("class expected, expression is not a constant"); throw exception("class expected, expression is not a constant");
name const & c_name = const_name(e); name const & c_name = const_name(e);
check_class(env, c_name); check_is_class(env, c_name);
return c_name; return c_name;
} }
@ -156,7 +162,7 @@ environment add_instance(environment const & env, name const & n, unsigned prior
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));
check_class(env, c); check_is_class(env, c);
return class_ext::add_entry(env, get_dummy_ios(), class_entry(c, n, priority), persistent); return class_ext::add_entry(env, get_dummy_ios(), class_entry(c, n, priority), persistent);
} }

View file

@ -0,0 +1,7 @@
import logic
definition subsingleton (A : Type) := ∀⦃a b : A⦄, a = b
class subsingleton
protected definition prop.subsingleton [instance] (P : Prop) : subsingleton P :=
λa b, !proof_irrel

View file

@ -0,0 +1,2 @@
bad_class.lean:4:0: error: invalid class, 'subsingleton' is a definition
bad_class.lean:6:0: error: 'eq' is not a class

View file

@ -2,7 +2,7 @@ import logic data.prod priority
open priority open priority
set_option pp.notation false set_option pp.notation false
inductive C (A : Type) := inductive C [class] (A : Type) :=
mk : A → C A mk : A → C A
definition val {A : Type} (c : C A) : A := definition val {A : Type} (c : C A) : A :=

View file

@ -15,10 +15,10 @@ context
end end
namespace algebra namespace algebra
inductive mul_struct (A : Type) : Type := inductive mul_struct [class] (A : Type) : Type :=
mk : (A → A → A) → mul_struct A mk : (A → A → A) → mul_struct A
inductive add_struct (A : Type) : Type := inductive add_struct [class] (A : Type) : Type :=
mk : (A → A → A) → add_struct A mk : (A → A → A) → add_struct A
definition mul {A : Type} {s : mul_struct A} (a b : A) definition mul {A : Type} {s : mul_struct A} (a b : A)
@ -32,6 +32,7 @@ namespace algebra
infixl `+`:65 := add infixl `+`:65 := add
end algebra end algebra
open algebra
inductive nat : Type := inductive nat : Type :=
zero : nat, zero : nat,
succ : nat → nat succ : nat → nat
@ -54,7 +55,7 @@ end nat
namespace algebra namespace algebra
namespace semigroup namespace semigroup
inductive semigroup_struct (A : Type) : Type := inductive semigroup_struct [class] (A : Type) : Type :=
mk : Π (mul : A → A → A), is_assoc mul → semigroup_struct A mk : Π (mul : A → A → A), is_assoc mul → semigroup_struct A
definition mul {A : Type} (s : semigroup_struct A) (a b : A) definition mul {A : Type} (s : semigroup_struct A) (a b : A)
@ -79,7 +80,7 @@ end semigroup
namespace monoid namespace monoid
check semigroup.mul check semigroup.mul
inductive monoid_struct (A : Type) : Type := inductive monoid_struct [class] (A : Type) : Type :=
mk_monoid_struct : Π (mul : A → A → A) (id : A), is_assoc mul → is_id mul id → monoid_struct A mk_monoid_struct : Π (mul : A → A → A) (id : A), is_assoc mul → is_id mul id → monoid_struct A
definition mul {A : Type} (s : monoid_struct A) (a b : A) definition mul {A : Type} (s : monoid_struct A) (a b : A)

View file

@ -56,7 +56,7 @@ theorem not_zero_add (x y : nat) (H : ¬ is_zero y) : ¬ is_zero (x + y)
not_is_zero_succ (x+w), not_is_zero_succ (x+w),
subst (symm H1) H2) subst (symm H1) H2)
inductive not_zero (x : nat) : Prop := inductive not_zero [class] (x : nat) : Prop :=
intro : ¬ is_zero x → not_zero x intro : ¬ is_zero x → not_zero x
theorem not_zero_not_is_zero {x : nat} (H : not_zero x) : ¬ is_zero x theorem not_zero_not_is_zero {x : nat} (H : not_zero x) : ¬ is_zero x

View file

@ -1,7 +1,7 @@
import logic import logic
namespace algebra namespace algebra
inductive mul_struct (A : Type) : Type := inductive mul_struct [class] (A : Type) : Type :=
mk : (A → A → A) → mul_struct A mk : (A → A → A) → mul_struct A
definition mul {A : Type} {s : mul_struct A} (a b : A) definition mul {A : Type} {s : mul_struct A} (a b : A)
@ -10,6 +10,7 @@ namespace algebra
infixl `*`:75 := mul infixl `*`:75 := mul
end algebra end algebra
open algebra
namespace nat namespace nat
inductive nat : Type := inductive nat : Type :=
zero : nat, zero : nat,

View file

@ -1,7 +1,7 @@
import logic import logic
open tactic open tactic
inductive inh (A : Type) : Type := inductive inh [class] (A : Type) : Type :=
intro : A -> inh A intro : A -> inh A
theorem inh_bool [instance] : inh Prop theorem inh_bool [instance] : inh Prop

View file

@ -1,7 +1,7 @@
import logic data.prod import logic data.prod
open tactic prod open tactic prod
inductive inh (A : Type) : Prop := inductive inh [class] (A : Type) : Prop :=
intro : A -> inh A intro : A -> inh A
instance inh.intro instance inh.intro

View file

@ -6,7 +6,7 @@ constant nat_add : nat → nat → nat
constant int_add : int → int → int constant int_add : int → int → int
constant real_add : real → real → real constant real_add : real → real → real
inductive add_struct (A : Type) := inductive add_struct [class] (A : Type) :=
mk : (A → A → A) → add_struct A mk : (A → A → A) → add_struct A
definition add {A : Type} {S : add_struct A} (a b : A) : A := definition add {A : Type} {S : add_struct A} (a b : A) : A :=

View file

@ -8,7 +8,7 @@ open function
namespace congr namespace congr
inductive struc {T1 : Type} {T2 : Type} (R1 : T1 → T1 → Prop) (R2 : T2 → T2 → Prop) inductive struc [class] {T1 : Type} {T2 : Type} (R1 : T1 → T1 → Prop) (R2 : T2 → T2 → Prop)
(f : T1 → T2) : Prop := (f : T1 → T2) : Prop :=
mk : (∀x y : T1, R1 x y → R2 (f x) (f y)) → struc R1 R2 f mk : (∀x y : T1, R1 x y → R2 (f x) (f y)) → struc R1 R2 f

View file

@ -16,7 +16,7 @@ definition reflexive {T : Type} (R : T → T → Prop) : Prop := ∀x, R x x
-- Congruence classes for unary and binary functions -- Congruence classes for unary and binary functions
-- ------------------------------------------------- -- -------------------------------------------------
inductive congruence {T1 : Type} {T2 : Type} (R1 : T1 → T1 → Prop) (R2 : T2 → T2 → Prop) inductive congruence [class] {T1 : Type} {T2 : Type} (R1 : T1 → T1 → Prop) (R2 : T2 → T2 → Prop)
(f : T1 → T2) : Prop := (f : T1 → T2) : Prop :=
mk : (∀x y : T1, R1 x y → R2 (f x) (f y)) → congruence R1 R2 f mk : (∀x y : T1, R1 x y → R2 (f x) (f y)) → congruence R1 R2 f

View file

@ -12,7 +12,7 @@ context
definition is_inv := ∀ a, a*a^-1 = one definition is_inv := ∀ a, a*a^-1 = one
end end
inductive group_struct (A : Type) : Type := inductive group_struct [class] (A : Type) : Type :=
mk_group_struct : Π (mul : A → A → A) (one : A) (inv : A → A), is_assoc mul → is_id mul one → is_inv mul one inv → group_struct A mk_group_struct : Π (mul : A → A → A) (one : A) (inv : A → A), is_assoc mul → is_id mul one → is_inv mul one inv → group_struct A
inductive group : Type := inductive group : Type :=

View file

@ -12,7 +12,7 @@ context
definition is_inv := ∀ a, a*a^-1 = one definition is_inv := ∀ a, a*a^-1 = one
end end
inductive group_struct (A : Type) : Type := inductive group_struct [class] (A : Type) : Type :=
mk : Π (mul : A → A → A) (one : A) (inv : A → A), is_assoc mul → is_id mul one → is_inv mul one inv → group_struct A mk : Π (mul : A → A → A) (one : A) (inv : A → A), is_assoc mul → is_id mul one → is_inv mul one inv → group_struct A
inductive group : Type := inductive group : Type :=

View file

@ -56,7 +56,7 @@ section
include s include s
definition semigroup_has_mul [instance] : has_mul A := has_mul.mk semigroup.mul definition semigroup_has_mul [instance] : has_mul A := has_mul.mk semigroup.mul
theorem mul_assoc [instance] (a b c : A) : a * b * c = a * (b * c) := theorem mul_assoc (a b c : A) : a * b * c = a * (b * c) :=
!semigroup.assoc !semigroup.assoc
end end

View file

@ -12,7 +12,7 @@ namespace simp
-- set_option pp.implicit true -- set_option pp.implicit true
-- first define a class of homogeneous equality -- first define a class of homogeneous equality
inductive simplifies_to {T : Type} (t1 t2 : T) : Prop := inductive simplifies_to [class] {T : Type} (t1 t2 : T) : Prop :=
mk : t1 = t2 → simplifies_to t1 t2 mk : t1 = t2 → simplifies_to t1 t2
theorem get_eq {T : Type} {t1 t2 : T} (C : simplifies_to t1 t2) : t1 = t2 := theorem get_eq {T : Type} {t1 t2 : T} (C : simplifies_to t1 t2) : t1 = t2 :=

View file

@ -8,7 +8,7 @@ import logic data.nat
open nat open nat
-- first define a class of homogeneous equality -- first define a class of homogeneous equality
inductive simplifies_to {T : Type} (t1 t2 : T) : Prop := inductive simplifies_to [class] {T : Type} (t1 t2 : T) : Prop :=
mk : t1 = t2 → simplifies_to t1 t2 mk : t1 = t2 → simplifies_to t1 t2
namespace simplifies_to namespace simplifies_to

View file

@ -60,9 +60,9 @@ namespace category
i = id ∘ i : eq.symm !id_left i = id ∘ i : eq.symm !id_left
... = id : H ... = id : H
inductive is_section (f : hom a b) : Type := mk : ∀{g}, g ∘ f = id → is_section f inductive is_section [class] (f : hom a b) : Type := mk : ∀{g}, g ∘ f = id → is_section f
inductive is_retraction (f : hom a b) : Type := mk : ∀{g}, f ∘ g = id → is_retraction f inductive is_retraction [class] (f : hom a b) : Type := mk : ∀{g}, f ∘ g = id → is_retraction f
inductive is_iso (f : hom a b) : Type := mk : ∀{g}, g ∘ f = id → f ∘ g = id → is_iso f inductive is_iso [class] (f : hom a b) : Type := mk : ∀{g}, g ∘ f = id → f ∘ g = id → is_iso f
definition retraction_of (f : hom a b) {H : is_section f} : hom b a := definition retraction_of (f : hom a b) {H : is_section f} : hom b a :=
is_section.rec (λg h, g) H is_section.rec (λg h, g) H