feat(kernel/hits): add two builtin HITs: type_quotient and trunc
This commit is contained in:
parent
591a563be3
commit
8241863abe
19 changed files with 275 additions and 34 deletions
|
@ -13,7 +13,7 @@ import .type_quotient
|
||||||
open type_quotient eq equiv
|
open type_quotient eq equiv
|
||||||
|
|
||||||
namespace coeq
|
namespace coeq
|
||||||
context
|
section
|
||||||
|
|
||||||
universe u
|
universe u
|
||||||
parameters {A B : Type.{u}} (f g : A → B)
|
parameters {A B : Type.{u}} (f g : A → B)
|
||||||
|
|
|
@ -12,7 +12,7 @@ Definition of general colimits and sequential colimits.
|
||||||
open eq nat type_quotient sigma equiv
|
open eq nat type_quotient sigma equiv
|
||||||
|
|
||||||
namespace colimit
|
namespace colimit
|
||||||
context
|
section
|
||||||
parameters {I J : Type} (A : I → Type) (dom cod : J → I)
|
parameters {I J : Type} (A : I → Type) (dom cod : J → I)
|
||||||
(f : Π(j : J), A (dom j) → A (cod j))
|
(f : Π(j : J), A (dom j) → A (cod j))
|
||||||
variables {i : I} (a : A i) (j : J) (b : A (dom j))
|
variables {i : I} (a : A i) (j : J) (b : A (dom j))
|
||||||
|
@ -52,7 +52,7 @@ context
|
||||||
definition rec_cglue [reducible] {P : colimit → Type}
|
definition rec_cglue [reducible] {P : colimit → Type}
|
||||||
(Pincl : Π⦃i : I⦄ (x : A i), P (ι x))
|
(Pincl : Π⦃i : I⦄ (x : A i), P (ι x))
|
||||||
(Pglue : Π(j : J) (x : A (dom j)), cglue j x ▹ Pincl (f j x) = Pincl x)
|
(Pglue : Π(j : J) (x : A (dom j)), cglue j x ▹ Pincl (f j x) = Pincl x)
|
||||||
{j : J} (x : A (dom j)) : apD (rec Pincl Pglue) (cglue j x) = sorry ⬝ Pglue j x ⬝ sorry :=
|
{j : J} (x : A (dom j)) : apD (rec Pincl Pglue) (cglue j x) = Pglue j x :=
|
||||||
sorry
|
sorry
|
||||||
|
|
||||||
protected definition elim {P : Type} (Pincl : Π⦃i : I⦄ (x : A i), P)
|
protected definition elim {P : Type} (Pincl : Π⦃i : I⦄ (x : A i), P)
|
||||||
|
@ -67,7 +67,7 @@ context
|
||||||
definition elim_cglue [reducible] {P : Type}
|
definition elim_cglue [reducible] {P : Type}
|
||||||
(Pincl : Π⦃i : I⦄ (x : A i), P)
|
(Pincl : Π⦃i : I⦄ (x : A i), P)
|
||||||
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) = Pincl x)
|
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) = Pincl x)
|
||||||
{j : J} (x : A (dom j)) : ap (elim Pincl Pglue) (cglue j x) = sorry ⬝ Pglue j x ⬝ sorry :=
|
{j : J} (x : A (dom j)) : ap (elim Pincl Pglue) (cglue j x) = Pglue j x :=
|
||||||
sorry
|
sorry
|
||||||
|
|
||||||
protected definition elim_type (Pincl : Π⦃i : I⦄ (x : A i), Type)
|
protected definition elim_type (Pincl : Π⦃i : I⦄ (x : A i), Type)
|
||||||
|
@ -89,7 +89,7 @@ end colimit
|
||||||
|
|
||||||
/- definition of a sequential colimit -/
|
/- definition of a sequential colimit -/
|
||||||
namespace seq_colim
|
namespace seq_colim
|
||||||
context
|
section
|
||||||
parameters {A : ℕ → Type} (f : Π⦃n⦄, A n → A (succ n))
|
parameters {A : ℕ → Type} (f : Π⦃n⦄, A n → A (succ n))
|
||||||
variables {n : ℕ} (a : A n)
|
variables {n : ℕ} (a : A n)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import .type_quotient
|
||||||
open type_quotient eq sum equiv
|
open type_quotient eq sum equiv
|
||||||
|
|
||||||
namespace cylinder
|
namespace cylinder
|
||||||
context
|
section
|
||||||
|
|
||||||
universe u
|
universe u
|
||||||
parameters {A B : Type.{u}} (f : A → B)
|
parameters {A B : Type.{u}} (f : A → B)
|
||||||
|
|
|
@ -13,7 +13,7 @@ import .type_quotient
|
||||||
open type_quotient eq sum equiv
|
open type_quotient eq sum equiv
|
||||||
|
|
||||||
namespace pushout
|
namespace pushout
|
||||||
context
|
section
|
||||||
|
|
||||||
parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
||||||
|
|
||||||
|
@ -54,16 +54,16 @@ parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
||||||
definition rec_inl {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
definition rec_inl {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
||||||
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), glue x ▹ Pinl (f x) = Pinr (g x))
|
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), glue x ▹ Pinl (f x) = Pinr (g x))
|
||||||
(x : BL) : rec Pinl Pinr Pglue (inl x) = Pinl x :=
|
(x : BL) : rec Pinl Pinr Pglue (inl x) = Pinl x :=
|
||||||
rec_class_of _ _ _ --idp
|
idp
|
||||||
|
|
||||||
definition rec_inr {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
definition rec_inr {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
||||||
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), glue x ▹ Pinl (f x) = Pinr (g x))
|
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), glue x ▹ Pinl (f x) = Pinr (g x))
|
||||||
(x : TR) : rec Pinl Pinr Pglue (inr x) = Pinr x :=
|
(x : TR) : rec Pinl Pinr Pglue (inr x) = Pinr x :=
|
||||||
rec_class_of _ _ _ --idp
|
idp
|
||||||
|
|
||||||
definition rec_glue {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
definition rec_glue {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
||||||
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), glue x ▹ Pinl (f x) = Pinr (g x))
|
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), glue x ▹ Pinl (f x) = Pinr (g x))
|
||||||
(x : TL) : apD (rec Pinl Pinr Pglue) (glue x) = sorry ⬝ Pglue x ⬝ sorry :=
|
(x : TL) : apD (rec Pinl Pinr Pglue) (glue x) = Pglue x :=
|
||||||
sorry
|
sorry
|
||||||
|
|
||||||
protected definition elim {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
protected definition elim {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
||||||
|
@ -76,7 +76,7 @@ parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
||||||
|
|
||||||
definition elim_glue {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
definition elim_glue {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
||||||
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) (y : pushout) (x : TL)
|
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) (y : pushout) (x : TL)
|
||||||
: ap (elim Pinl Pinr Pglue) (glue x) = sorry ⬝ Pglue x ⬝ sorry :=
|
: ap (elim Pinl Pinr Pglue) (glue x) = Pglue x :=
|
||||||
sorry
|
sorry
|
||||||
|
|
||||||
protected definition elim_type (Pinl : BL → Type) (Pinr : TR → Type)
|
protected definition elim_type (Pinl : BL → Type) (Pinr : TR → Type)
|
||||||
|
@ -109,7 +109,7 @@ end
|
||||||
{ intro b, cases b,
|
{ intro b, cases b,
|
||||||
exact (inl _ _ ⋆),
|
exact (inl _ _ ⋆),
|
||||||
exact (inr _ _ ⋆)},
|
exact (inr _ _ ⋆)},
|
||||||
{ intro b, cases b, apply rec_inl, apply rec_inr},
|
{ intro b, cases b, esimp, esimp},
|
||||||
{ intro x, fapply (pushout.rec_on _ _ x),
|
{ intro x, fapply (pushout.rec_on _ _ x),
|
||||||
intro u, cases u, rewrite [↑function.compose,↑pushout.rec_on,rec_inl],
|
intro u, cases u, rewrite [↑function.compose,↑pushout.rec_on,rec_inl],
|
||||||
intro u, cases u, rewrite [↑function.compose,↑pushout.rec_on,rec_inr],
|
intro u, cases u, rewrite [↑function.compose,↑pushout.rec_on,rec_inr],
|
||||||
|
|
|
@ -13,7 +13,7 @@ import .type_quotient .trunc
|
||||||
open eq is_trunc trunc type_quotient
|
open eq is_trunc trunc type_quotient
|
||||||
|
|
||||||
namespace quotient
|
namespace quotient
|
||||||
context
|
section
|
||||||
parameters {A : Type} (R : A → A → hprop)
|
parameters {A : Type} (R : A → A → hprop)
|
||||||
-- set-quotients are just truncations of type-quotients
|
-- set-quotients are just truncations of type-quotients
|
||||||
definition quotient : Type := trunc 0 (type_quotient (λa a', trunctype.carrier (R a a')))
|
definition quotient : Type := trunc 0 (type_quotient (λa a', trunctype.carrier (R a a')))
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace trunc
|
||||||
|
|
||||||
protected definition elim {n : trunc_index} {A : Type} {P : Type}
|
protected definition elim {n : trunc_index} {A : Type} {P : Type}
|
||||||
[Pt : is_trunc n P] (H : A → P) : trunc n A → P :=
|
[Pt : is_trunc n P] (H : A → P) : trunc n A → P :=
|
||||||
rec H
|
trunc.rec H
|
||||||
|
|
||||||
protected definition elim_on {n : trunc_index} {A : Type} {P : Type} (aa : trunc n A)
|
protected definition elim_on {n : trunc_index} {A : Type} {P : Type} (aa : trunc n A)
|
||||||
[Pt : is_trunc n P] (H : A → P) : P :=
|
[Pt : is_trunc n P] (H : A → P) : P :=
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace type_quotient
|
||||||
|
|
||||||
protected definition elim {P : Type} (Pc : A → P) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a')
|
protected definition elim {P : Type} (Pc : A → P) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a')
|
||||||
(x : type_quotient R) : P :=
|
(x : type_quotient R) : P :=
|
||||||
rec Pc (λa a' H, !tr_constant ⬝ Pp H) x
|
type_quotient.rec Pc (λa a' H, !tr_constant ⬝ Pp H) x
|
||||||
|
|
||||||
protected definition elim_on [reducible] {P : Type} (x : type_quotient R)
|
protected definition elim_on [reducible] {P : Type} (x : type_quotient R)
|
||||||
(Pc : A → P) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') : P :=
|
(Pc : A → P) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') : P :=
|
||||||
|
@ -26,7 +26,7 @@ namespace type_quotient
|
||||||
|
|
||||||
protected definition elim_eq_of_rel {P : Type} (Pc : A → P)
|
protected definition elim_eq_of_rel {P : Type} (Pc : A → P)
|
||||||
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') {a a' : A} (H : R a a')
|
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') {a a' : A} (H : R a a')
|
||||||
: ap (elim Pc Pp) (eq_of_rel H) = sorry ⬝ Pp H ⬝ sorry :=
|
: ap (elim Pc Pp) (eq_of_rel H) = Pp H :=
|
||||||
sorry
|
sorry
|
||||||
|
|
||||||
protected definition elim_type (Pc : A → Type)
|
protected definition elim_type (Pc : A → Type)
|
||||||
|
@ -39,7 +39,7 @@ namespace type_quotient
|
||||||
|
|
||||||
protected definition elim_type_eq_of_rel (Pc : A → Type)
|
protected definition elim_type_eq_of_rel (Pc : A → Type)
|
||||||
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') {a a' : A} (H : R a a')
|
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') {a a' : A} (H : R a a')
|
||||||
: transport (elim_type Pc Pp) (eq_of_rel H) = sorry /-to_fun (Pp H)-/ :=
|
: transport (elim_type Pc Pp) (eq_of_rel H) = to_fun (Pp H) :=
|
||||||
sorry
|
sorry
|
||||||
|
|
||||||
definition elim_type_uncurried (H : Σ(Pc : A → Type), Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a')
|
definition elim_type_uncurried (H : Σ(Pc : A → Type), Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a')
|
||||||
|
|
|
@ -33,23 +33,17 @@ open is_trunc eq
|
||||||
constant trunc.{u} (n : trunc_index) (A : Type.{u}) : Type.{u}
|
constant trunc.{u} (n : trunc_index) (A : Type.{u}) : Type.{u}
|
||||||
|
|
||||||
namespace trunc
|
namespace trunc
|
||||||
|
|
||||||
constant tr {n : trunc_index} {A : Type} (a : A) : trunc n A
|
constant tr {n : trunc_index} {A : Type} (a : A) : trunc n A
|
||||||
constant is_trunc_trunc (n : trunc_index) (A : Type) : is_trunc n (trunc n A)
|
constant is_trunc_trunc (n : trunc_index) (A : Type) : is_trunc n (trunc n A)
|
||||||
|
|
||||||
attribute is_trunc_trunc [instance]
|
attribute is_trunc_trunc [instance]
|
||||||
|
|
||||||
/-protected-/ constant rec {n : trunc_index} {A : Type} {P : trunc n A → Type}
|
protected constant rec {n : trunc_index} {A : Type} {P : trunc n A → Type}
|
||||||
[Pt : Πaa, is_trunc n (P aa)] (H : Πa, P (tr a)) : Πaa, P aa
|
[Pt : Πaa, is_trunc n (P aa)] (H : Πa, P (tr a)) : Πaa, P aa
|
||||||
|
|
||||||
protected definition rec_on [reducible] {n : trunc_index} {A : Type} {P : trunc n A → Type}
|
protected definition rec_on [reducible] {n : trunc_index} {A : Type} {P : trunc n A → Type}
|
||||||
(aa : trunc n A) [Pt : Πaa, is_trunc n (P aa)] (H : Πa, P (tr a)) : P aa :=
|
(aa : trunc n A) [Pt : Πaa, is_trunc n (P aa)] (H : Πa, P (tr a)) : P aa :=
|
||||||
trunc.rec H aa
|
trunc.rec H aa
|
||||||
|
|
||||||
definition rec_tr [reducible] {n : trunc_index} {A : Type} {P : trunc n A → Type}
|
|
||||||
[Pt : Πaa, is_trunc n (P aa)] (H : Πa, P (tr a)) (a : A) : trunc.rec H (tr a) = H a :=
|
|
||||||
sorry --idp
|
|
||||||
|
|
||||||
end trunc
|
end trunc
|
||||||
|
|
||||||
constant type_quotient.{u v} {A : Type.{u}} (R : A → A → Type.{v}) : Type.{max u v}
|
constant type_quotient.{u v} {A : Type.{u}} (R : A → A → Type.{v}) : Type.{max u v}
|
||||||
|
@ -61,7 +55,7 @@ namespace type_quotient
|
||||||
constant eq_of_rel {A : Type} {R : A → A → Type} {a a' : A} (H : R a a')
|
constant eq_of_rel {A : Type} {R : A → A → Type} {a a' : A} (H : R a a')
|
||||||
: class_of R a = class_of R a'
|
: class_of R a = class_of R a'
|
||||||
|
|
||||||
/-protected-/ constant rec {A : Type} {R : A → A → Type} {P : type_quotient R → Type}
|
protected constant rec {A : Type} {R : A → A → Type} {P : type_quotient R → Type}
|
||||||
(Pc : Π(a : A), P (class_of R a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a')
|
(Pc : Π(a : A), P (class_of R a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a')
|
||||||
(x : type_quotient R) : P x
|
(x : type_quotient R) : P x
|
||||||
|
|
||||||
|
@ -70,13 +64,23 @@ namespace type_quotient
|
||||||
(Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a') : P x :=
|
(Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a') : P x :=
|
||||||
rec Pc Pp x
|
rec Pc Pp x
|
||||||
|
|
||||||
|
end type_quotient
|
||||||
|
|
||||||
|
init_hits -- Initialize builtin computational rules for trunc and type_quotient
|
||||||
|
|
||||||
|
namespace trunc
|
||||||
|
definition rec_tr [reducible] {n : trunc_index} {A : Type} {P : trunc n A → Type}
|
||||||
|
[Pt : Πaa, is_trunc n (P aa)] (H : Πa, P (tr a)) (a : A) : trunc.rec H (tr a) = H a :=
|
||||||
|
idp
|
||||||
|
end trunc
|
||||||
|
|
||||||
|
namespace type_quotient
|
||||||
definition rec_class_of {A : Type} {R : A → A → Type} {P : type_quotient R → Type}
|
definition rec_class_of {A : Type} {R : A → A → Type} {P : type_quotient R → Type}
|
||||||
(Pc : Π(a : A), P (class_of R a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a')
|
(Pc : Π(a : A), P (class_of R a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a')
|
||||||
(a : A) : rec Pc Pp (class_of R a) = Pc a :=
|
(a : A) : type_quotient.rec Pc Pp (class_of R a) = Pc a :=
|
||||||
sorry --idp
|
idp
|
||||||
|
|
||||||
constant rec_eq_of_rel {A : Type} {R : A → A → Type} {P : type_quotient R → Type}
|
constant rec_eq_of_rel {A : Type} {R : A → A → Type} {P : type_quotient R → Type}
|
||||||
(Pc : Π(a : A), P (class_of R a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a')
|
(Pc : Π(a : A), P (class_of R a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), eq_of_rel H ▹ Pc a = Pc a')
|
||||||
{a a' : A} (H : R a a') : apD (rec Pc Pp) (eq_of_rel H) = sorry ⬝ Pp H ⬝ sorry
|
{a a' : A} (H : R a a') : apD (type_quotient.rec Pc Pp) (eq_of_rel H) = Pp H
|
||||||
|
|
||||||
end type_quotient
|
end type_quotient
|
||||||
|
|
|
@ -319,6 +319,8 @@ add_subdirectory(kernel/inductive)
|
||||||
set(LEAN_LIBS ${LEAN_LIBS} inductive)
|
set(LEAN_LIBS ${LEAN_LIBS} inductive)
|
||||||
add_subdirectory(kernel/quotient)
|
add_subdirectory(kernel/quotient)
|
||||||
set(LEAN_LIBS ${LEAN_LIBS} quotient)
|
set(LEAN_LIBS ${LEAN_LIBS} quotient)
|
||||||
|
add_subdirectory(kernel/hits)
|
||||||
|
set(LEAN_LIBS ${LEAN_LIBS} hits)
|
||||||
add_subdirectory(library)
|
add_subdirectory(library)
|
||||||
set(LEAN_LIBS ${LEAN_LIBS} library)
|
set(LEAN_LIBS ${LEAN_LIBS} library)
|
||||||
add_subdirectory(library/tactic)
|
add_subdirectory(library/tactic)
|
||||||
|
|
|
@ -13,6 +13,7 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/instantiate.h"
|
#include "kernel/instantiate.h"
|
||||||
#include "kernel/inductive/inductive.h"
|
#include "kernel/inductive/inductive.h"
|
||||||
#include "kernel/quotient/quotient.h"
|
#include "kernel/quotient/quotient.h"
|
||||||
|
#include "kernel/hits/hits.h"
|
||||||
#include "kernel/default_converter.h"
|
#include "kernel/default_converter.h"
|
||||||
#include "library/io_state_stream.h"
|
#include "library/io_state_stream.h"
|
||||||
#include "library/scoped_ext.h"
|
#include "library/scoped_ext.h"
|
||||||
|
@ -70,6 +71,7 @@ static void print_axioms(parser & p) {
|
||||||
name const & n = d.get_name();
|
name const & n = d.get_name();
|
||||||
if (!d.is_definition() &&
|
if (!d.is_definition() &&
|
||||||
!is_quotient_decl(env, n) &&
|
!is_quotient_decl(env, n) &&
|
||||||
|
!is_hits_decl(env, n) &&
|
||||||
!inductive::is_inductive_decl(env, n) &&
|
!inductive::is_inductive_decl(env, n) &&
|
||||||
!inductive::is_elim_rule(env, n) &&
|
!inductive::is_elim_rule(env, n) &&
|
||||||
!inductive::is_intro_rule(env, n)) {
|
!inductive::is_intro_rule(env, n)) {
|
||||||
|
@ -674,9 +676,17 @@ static environment help_cmd(parser & p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
environment init_quotient_cmd(parser & p) {
|
environment init_quotient_cmd(parser & p) {
|
||||||
|
if (!(p.env().prop_proof_irrel() && p.env().impredicative()))
|
||||||
|
throw parser_error("invalid init_quotient command, this command is only available for kernels containing an impredicative and proof irrelevant Prop", p.cmd_pos());
|
||||||
return module::declare_quotient(p.env());
|
return module::declare_quotient(p.env());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
environment init_hits_cmd(parser & p) {
|
||||||
|
if (p.env().prop_proof_irrel() || p.env().impredicative())
|
||||||
|
throw parser_error("invalid init_hits command, this command is only available for proof relevant and predicative kernels", p.cmd_pos());
|
||||||
|
return module::declare_hits(p.env());
|
||||||
|
}
|
||||||
|
|
||||||
void init_cmd_table(cmd_table & r) {
|
void init_cmd_table(cmd_table & r) {
|
||||||
add_cmd(r, cmd_info("open", "create aliases for declarations, and use objects defined in other namespaces",
|
add_cmd(r, cmd_info("open", "create aliases for declarations, and use objects defined in other namespaces",
|
||||||
open_cmd));
|
open_cmd));
|
||||||
|
@ -694,6 +704,7 @@ void init_cmd_table(cmd_table & r) {
|
||||||
add_cmd(r, cmd_info("local", "define local attributes or notation", local_cmd));
|
add_cmd(r, cmd_info("local", "define local attributes or notation", local_cmd));
|
||||||
add_cmd(r, cmd_info("help", "brief description of available commands and options", help_cmd));
|
add_cmd(r, cmd_info("help", "brief description of available commands and options", help_cmd));
|
||||||
add_cmd(r, cmd_info("init_quotient", "initialize quotient type computational rules", init_quotient_cmd));
|
add_cmd(r, cmd_info("init_quotient", "initialize quotient type computational rules", init_quotient_cmd));
|
||||||
|
add_cmd(r, cmd_info("init_hits", "initialize builtin HITs", init_hits_cmd));
|
||||||
add_cmd(r, cmd_info("#erase_cache", "erase cached definition (for debugging purposes)", erase_cache_cmd));
|
add_cmd(r, cmd_info("#erase_cache", "erase cached definition (for debugging purposes)", erase_cache_cmd));
|
||||||
add_cmd(r, cmd_info("#projections", "generate projections for inductive datatype (for debugging purposes)", projections_cmd));
|
add_cmd(r, cmd_info("#projections", "generate projections for inductive datatype (for debugging purposes)", projections_cmd));
|
||||||
add_cmd(r, cmd_info("#telescope_eq", "(for debugging purposes)", telescope_eq_cmd));
|
add_cmd(r, cmd_info("#telescope_eq", "(for debugging purposes)", telescope_eq_cmd));
|
||||||
|
|
|
@ -100,7 +100,7 @@ void init_token_table(token_table & t) {
|
||||||
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "calc_symm", "tactic_hint",
|
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "calc_symm", "tactic_hint",
|
||||||
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "class",
|
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "class",
|
||||||
"multiple_instances", "find_decl", "attribute", "persistent",
|
"multiple_instances", "find_decl", "attribute", "persistent",
|
||||||
"include", "omit", "migrate", "init_quotient", "#erase_cache", "#projections", "#telescope_eq", nullptr};
|
"include", "omit", "migrate", "init_quotient", "init_hits", "#erase_cache", "#projections", "#telescope_eq", nullptr};
|
||||||
|
|
||||||
pair<char const *, char const *> aliases[] =
|
pair<char const *, char const *> aliases[] =
|
||||||
{{g_lambda_unicode, "fun"}, {"forall", "Pi"}, {g_forall_unicode, "Pi"}, {g_pi_unicode, "Pi"},
|
{{g_lambda_unicode, "fun"}, {"forall", "Pi"}, {g_forall_unicode, "Pi"}, {g_pi_unicode, "Pi"},
|
||||||
|
|
|
@ -12,6 +12,7 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/init_module.h"
|
#include "kernel/init_module.h"
|
||||||
#include "kernel/inductive/inductive.h"
|
#include "kernel/inductive/inductive.h"
|
||||||
#include "kernel/quotient/quotient.h"
|
#include "kernel/quotient/quotient.h"
|
||||||
|
#include "kernel/hits/hits.h"
|
||||||
#include "library/init_module.h"
|
#include "library/init_module.h"
|
||||||
#include "library/tactic/init_module.h"
|
#include "library/tactic/init_module.h"
|
||||||
#include "library/definitional/init_module.h"
|
#include "library/definitional/init_module.h"
|
||||||
|
@ -29,6 +30,7 @@ void initialize() {
|
||||||
initialize_kernel_module();
|
initialize_kernel_module();
|
||||||
initialize_inductive_module();
|
initialize_inductive_module();
|
||||||
initialize_quotient_module();
|
initialize_quotient_module();
|
||||||
|
initialize_hits_module();
|
||||||
init_default_print_fn();
|
init_default_print_fn();
|
||||||
initialize_library_module();
|
initialize_library_module();
|
||||||
initialize_tactic_module();
|
initialize_tactic_module();
|
||||||
|
@ -42,6 +44,7 @@ void finalize() {
|
||||||
finalize_definitional_module();
|
finalize_definitional_module();
|
||||||
finalize_tactic_module();
|
finalize_tactic_module();
|
||||||
finalize_library_module();
|
finalize_library_module();
|
||||||
|
finalize_hits_module();
|
||||||
finalize_quotient_module();
|
finalize_quotient_module();
|
||||||
finalize_inductive_module();
|
finalize_inductive_module();
|
||||||
finalize_kernel_module();
|
finalize_kernel_module();
|
||||||
|
|
2
src/kernel/hits/CMakeLists.txt
Normal file
2
src/kernel/hits/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
add_library(hits hits.cpp)
|
||||||
|
target_link_libraries(hits ${LEAN_LIBS})
|
167
src/kernel/hits/hits.cpp
Normal file
167
src/kernel/hits/hits.cpp
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
|
Author: Leonardo de Moura
|
||||||
|
|
||||||
|
Builtin HITs:
|
||||||
|
- n-truncation
|
||||||
|
- type quotients (non-truncated quotients)
|
||||||
|
*/
|
||||||
|
#include "util/sstream.h"
|
||||||
|
#include "kernel/kernel_exception.h"
|
||||||
|
#include "kernel/environment.h"
|
||||||
|
#include "kernel/hits/hits.h"
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
static name * g_hits_extension = nullptr;
|
||||||
|
static name * g_trunc = nullptr;
|
||||||
|
static name * g_trunc_tr = nullptr;
|
||||||
|
static name * g_trunc_rec = nullptr;
|
||||||
|
static name * g_trunc_is_trunc_trunc = nullptr;
|
||||||
|
static name * g_type_quotient = nullptr;
|
||||||
|
static name * g_type_quotient_class_of = nullptr;
|
||||||
|
static name * g_type_quotient_rec = nullptr;
|
||||||
|
static name * g_type_quotient_eq_of_rel = nullptr;
|
||||||
|
static name * g_type_quotient_rec_eq_of_rel = nullptr;
|
||||||
|
|
||||||
|
struct hits_env_ext : public environment_extension {
|
||||||
|
bool m_initialized;
|
||||||
|
hits_env_ext():m_initialized(false){}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \brief Auxiliary object for registering the environment extension */
|
||||||
|
struct hits_env_ext_reg {
|
||||||
|
unsigned m_ext_id;
|
||||||
|
hits_env_ext_reg() { m_ext_id = environment::register_extension(std::make_shared<hits_env_ext>()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static hits_env_ext_reg * g_ext = nullptr;
|
||||||
|
|
||||||
|
/** \brief Retrieve environment extension */
|
||||||
|
static hits_env_ext const & get_extension(environment const & env) {
|
||||||
|
return static_cast<hits_env_ext const &>(env.get_extension(g_ext->m_ext_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief Update environment extension */
|
||||||
|
static environment update(environment const & env, hits_env_ext const & ext) {
|
||||||
|
return env.update(g_ext->m_ext_id, std::make_shared<hits_env_ext>(ext));
|
||||||
|
}
|
||||||
|
|
||||||
|
environment declare_hits(environment const & env) {
|
||||||
|
hits_env_ext ext = get_extension(env);
|
||||||
|
ext.m_initialized = true;
|
||||||
|
return update(env, ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<pair<expr, constraint_seq>> hits_normalizer_extension::operator()(expr const & e, extension_context & ctx) const {
|
||||||
|
environment const & env = ctx.env();
|
||||||
|
expr const & fn = get_app_fn(e);
|
||||||
|
if (!is_constant(fn))
|
||||||
|
return none_ecs();
|
||||||
|
hits_env_ext const & ext = get_extension(env);
|
||||||
|
if (!ext.m_initialized)
|
||||||
|
return none_ecs();
|
||||||
|
unsigned mk_pos;
|
||||||
|
name * mk_name;
|
||||||
|
unsigned f_pos;
|
||||||
|
if (const_name(fn) == *g_trunc_rec) {
|
||||||
|
mk_pos = 5;
|
||||||
|
mk_name = g_trunc_tr;
|
||||||
|
f_pos = 4;
|
||||||
|
} else if (const_name(fn) == *g_type_quotient_rec) {
|
||||||
|
mk_pos = 5;
|
||||||
|
mk_name = g_type_quotient_class_of;
|
||||||
|
f_pos = 3;
|
||||||
|
} else {
|
||||||
|
return none_ecs();
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer<expr> args;
|
||||||
|
get_app_args(e, args);
|
||||||
|
if (args.size() <= mk_pos)
|
||||||
|
return none_ecs();
|
||||||
|
|
||||||
|
auto mk_cs = ctx.whnf(args[mk_pos]);
|
||||||
|
expr const & mk = mk_cs.first;
|
||||||
|
expr const & mk_fn = get_app_fn(mk);
|
||||||
|
if (!is_constant(mk_fn))
|
||||||
|
return none_ecs();
|
||||||
|
if (const_name(mk_fn) != *mk_name)
|
||||||
|
return none_ecs();
|
||||||
|
|
||||||
|
expr const & f = args[f_pos];
|
||||||
|
expr r = mk_app(f, app_arg(mk));
|
||||||
|
return some_ecs(r, mk_cs.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ctx>
|
||||||
|
optional<expr> is_hits_meta_app_core(Ctx & ctx, expr const & e) {
|
||||||
|
expr const & fn = get_app_fn(e);
|
||||||
|
if (!is_constant(fn))
|
||||||
|
return none_expr();
|
||||||
|
unsigned mk_pos;
|
||||||
|
if (const_name(fn) == *g_trunc_rec) {
|
||||||
|
mk_pos = 5;
|
||||||
|
} else if (const_name(fn) == *g_type_quotient_rec) {
|
||||||
|
mk_pos = 5;
|
||||||
|
} else {
|
||||||
|
return none_expr();
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer<expr> args;
|
||||||
|
get_app_args(e, args);
|
||||||
|
if (args.size() <= mk_pos)
|
||||||
|
return none_expr();
|
||||||
|
|
||||||
|
expr mk_app = ctx.whnf(args[mk_pos]).first;
|
||||||
|
return has_expr_metavar_strict(mk_app);
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<expr> hits_normalizer_extension::may_reduce_later(expr const & e, extension_context & ctx) const {
|
||||||
|
return is_hits_meta_app_core(ctx, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hits_normalizer_extension::supports(name const & feature) const {
|
||||||
|
return feature == *g_hits_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_hits_decl(environment const & env, name const & n) {
|
||||||
|
if (!get_extension(env).m_initialized)
|
||||||
|
return false;
|
||||||
|
return
|
||||||
|
n == *g_trunc || n == *g_trunc_tr || n == *g_trunc_rec ||
|
||||||
|
n == *g_trunc_is_trunc_trunc ||
|
||||||
|
n == *g_type_quotient || n == *g_type_quotient_class_of ||
|
||||||
|
n == *g_type_quotient_rec || n == *g_type_quotient_eq_of_rel ||
|
||||||
|
n == *g_type_quotient_rec_eq_of_rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize_hits_module() {
|
||||||
|
g_hits_extension = new name("hits_extension");
|
||||||
|
g_trunc = new name{"trunc"};
|
||||||
|
g_trunc_tr = new name{"trunc", "tr"};
|
||||||
|
g_trunc_rec = new name{"trunc", "rec"};
|
||||||
|
g_trunc_is_trunc_trunc = new name{"trunc", "is_trunc_trunc"};
|
||||||
|
g_type_quotient = new name{"type_quotient"};
|
||||||
|
g_type_quotient_class_of = new name{"type_quotient", "class_of"};
|
||||||
|
g_type_quotient_rec = new name{"type_quotient", "rec"};
|
||||||
|
g_type_quotient_eq_of_rel = new name{"type_quotient", "eq_of_rel"};
|
||||||
|
g_type_quotient_rec_eq_of_rel = new name{"type_quotient", "rec_eq_of_rel"};
|
||||||
|
g_ext = new hits_env_ext_reg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void finalize_hits_module() {
|
||||||
|
delete g_ext;
|
||||||
|
delete g_hits_extension;
|
||||||
|
delete g_trunc;
|
||||||
|
delete g_trunc_tr;
|
||||||
|
delete g_trunc_rec;
|
||||||
|
delete g_trunc_is_trunc_trunc;
|
||||||
|
delete g_type_quotient;
|
||||||
|
delete g_type_quotient_class_of;
|
||||||
|
delete g_type_quotient_rec;
|
||||||
|
delete g_type_quotient_eq_of_rel;
|
||||||
|
delete g_type_quotient_rec_eq_of_rel;
|
||||||
|
}
|
||||||
|
}
|
28
src/kernel/hits/hits.h
Normal file
28
src/kernel/hits/hits.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
|
Author: Leonardo de Moura
|
||||||
|
|
||||||
|
Builtin HITs:
|
||||||
|
- n-truncation
|
||||||
|
- type quotients (non-truncated quotients)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
/** \brief Normalizer extension for applying builtin HITs computational rules. */
|
||||||
|
class hits_normalizer_extension : public normalizer_extension {
|
||||||
|
public:
|
||||||
|
virtual optional<pair<expr, constraint_seq>> operator()(expr const & e, extension_context & ctx) const;
|
||||||
|
virtual optional<expr> may_reduce_later(expr const & e, extension_context & ctx) const;
|
||||||
|
virtual bool supports(name const & feature) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \brief The following function must be invoked to register the builtin HITs computation rules in the kernel. */
|
||||||
|
environment declare_hits(environment const & env);
|
||||||
|
/** \brief Return true iff \c n is one of the HITs builtin constants. */
|
||||||
|
bool is_hits_decl(environment const & env, name const & n);
|
||||||
|
void initialize_hits_module();
|
||||||
|
void finalize_hits_module();
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
Copyright (c) 2014-2015 Microsoft Corporation. All rights reserved.
|
||||||
Released under Apache 2.0 license as described in the file LICENSE.
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
Author: Leonardo de Moura
|
Author: Leonardo de Moura
|
||||||
*/
|
*/
|
||||||
#include "kernel/inductive/inductive.h"
|
#include "kernel/inductive/inductive.h"
|
||||||
|
#include "kernel/hits/hits.h"
|
||||||
#include "library/inductive_unifier_plugin.h"
|
#include "library/inductive_unifier_plugin.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
@ -15,8 +16,9 @@ environment mk_hott_environment(unsigned trust_lvl) {
|
||||||
false /* Type.{0} is not proof irrelevant */,
|
false /* Type.{0} is not proof irrelevant */,
|
||||||
true /* Eta */,
|
true /* Eta */,
|
||||||
false /* Type.{0} is not impredicative */,
|
false /* Type.{0} is not impredicative */,
|
||||||
/* builtin support for inductive */
|
/* builtin support for inductive and hits */
|
||||||
std::unique_ptr<normalizer_extension>(new inductive_normalizer_extension()));
|
compose(std::unique_ptr<normalizer_extension>(new inductive_normalizer_extension()),
|
||||||
|
std::unique_ptr<normalizer_extension>(new hits_normalizer_extension())));
|
||||||
return set_unifier_plugin(env, mk_inductive_unifier_plugin());
|
return set_unifier_plugin(env, mk_inductive_unifier_plugin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ Author: Leonardo de Moura
|
||||||
#include "util/name_map.h"
|
#include "util/name_map.h"
|
||||||
#include "kernel/type_checker.h"
|
#include "kernel/type_checker.h"
|
||||||
#include "kernel/quotient/quotient.h"
|
#include "kernel/quotient/quotient.h"
|
||||||
|
#include "kernel/hits/hits.h"
|
||||||
#include "library/module.h"
|
#include "library/module.h"
|
||||||
#include "library/sorry.h"
|
#include "library/sorry.h"
|
||||||
#include "library/kernel_serializer.h"
|
#include "library/kernel_serializer.h"
|
||||||
|
@ -164,6 +165,7 @@ static std::string * g_glvl_key = nullptr;
|
||||||
static std::string * g_decl_key = nullptr;
|
static std::string * g_decl_key = nullptr;
|
||||||
static std::string * g_inductive = nullptr;
|
static std::string * g_inductive = nullptr;
|
||||||
static std::string * g_quotient = nullptr;
|
static std::string * g_quotient = nullptr;
|
||||||
|
static std::string * g_hits = nullptr;
|
||||||
|
|
||||||
namespace module {
|
namespace module {
|
||||||
environment add(environment const & env, std::string const & k, std::function<void(serializer &)> const & wr) {
|
environment add(environment const & env, std::string const & k, std::function<void(serializer &)> const & wr) {
|
||||||
|
@ -218,6 +220,19 @@ static void quotient_reader(deserializer &, module_idx, shared_environment & sen
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
environment declare_hits(environment const & env) {
|
||||||
|
environment new_env = ::lean::declare_hits(env);
|
||||||
|
return add(new_env, *g_hits, [=](serializer &) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hits_reader(deserializer &, module_idx, shared_environment & senv,
|
||||||
|
std::function<void(asynch_update_fn const &)> &,
|
||||||
|
std::function<void(delayed_update_fn const &)> &) {
|
||||||
|
senv.update([&](environment const & env) {
|
||||||
|
return ::lean::declare_hits(env);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
environment add_inductive(environment env,
|
environment add_inductive(environment env,
|
||||||
level_param_names const & level_params,
|
level_param_names const & level_params,
|
||||||
unsigned num_params,
|
unsigned num_params,
|
||||||
|
@ -576,13 +591,16 @@ void initialize_module() {
|
||||||
g_decl_key = new std::string("decl");
|
g_decl_key = new std::string("decl");
|
||||||
g_inductive = new std::string("ind");
|
g_inductive = new std::string("ind");
|
||||||
g_quotient = new std::string("quot");
|
g_quotient = new std::string("quot");
|
||||||
|
g_hits = new std::string("hits");
|
||||||
register_module_object_reader(*g_inductive, module::inductive_reader);
|
register_module_object_reader(*g_inductive, module::inductive_reader);
|
||||||
register_module_object_reader(*g_quotient, module::quotient_reader);
|
register_module_object_reader(*g_quotient, module::quotient_reader);
|
||||||
|
register_module_object_reader(*g_hits, module::hits_reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalize_module() {
|
void finalize_module() {
|
||||||
delete g_inductive;
|
delete g_inductive;
|
||||||
delete g_quotient;
|
delete g_quotient;
|
||||||
|
delete g_hits;
|
||||||
delete g_decl_key;
|
delete g_decl_key;
|
||||||
delete g_glvl_key;
|
delete g_glvl_key;
|
||||||
delete g_object_readers;
|
delete g_object_readers;
|
||||||
|
|
|
@ -109,6 +109,9 @@ environment add_inductive(environment env,
|
||||||
/** \brief The following function must be invoked to register the quotient type computation rules in the kernel. */
|
/** \brief The following function must be invoked to register the quotient type computation rules in the kernel. */
|
||||||
environment declare_quotient(environment const & env);
|
environment declare_quotient(environment const & env);
|
||||||
|
|
||||||
|
/** \brief The following function must be invoked to register the builtin HITs in the kernel. */
|
||||||
|
environment declare_hits(environment const & env);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Declare a single inductive datatype. This is just a helper function implemented on top of
|
\brief Declare a single inductive datatype. This is just a helper function implemented on top of
|
||||||
the previous (more general) add_inductive.
|
the previous (more general) add_inductive.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
open is_trunc
|
open is_trunc
|
||||||
|
namespace hide
|
||||||
inductive trunc (n : trunc_index) (A : Type) : Type :=
|
inductive trunc (n : trunc_index) (A : Type) : Type :=
|
||||||
tr {} : A → trunc n A
|
tr {} : A → trunc n A
|
||||||
|
|
||||||
|
@ -30,3 +30,4 @@ namespace trunc
|
||||||
by intro xx; apply (trunc_rec_on xx); intro x; exact (tr (f x))
|
by intro xx; apply (trunc_rec_on xx); intro x; exact (tr (f x))
|
||||||
|
|
||||||
end trunc
|
end trunc
|
||||||
|
end hide
|
||||||
|
|
Loading…
Reference in a new issue