LogRel.AlgorithmicJudgments: definition of conversion (typed and untyped
From Coq Require Import ssrbool.
From LogRel Require Import Utils Syntax.All GenericTyping.
Section Definitions.
From LogRel Require Import Utils Syntax.All GenericTyping.
Section Definitions.
We locally disable typing notations to be able to use them in the definition
here before declaring the right instance.
Close Scope typing_scope.
Inductive ConvTypeAlg : context -> term -> term -> Type :=
| typeConvRed {Γ A A' B B'} :
[A ⤳* A'] ->
[B ⤳* B'] ->
[Γ |- A' ≅h B'] ->
[Γ |- A ≅ B]
| typeConvRed {Γ A A' B B'} :
[A ⤳* A'] ->
[B ⤳* B'] ->
[Γ |- A' ≅h B'] ->
[Γ |- A ≅ B]
with ConvTypeRedAlg : context -> term -> term -> Type :=
| typePiCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A'] ->
[ Γ ,, A |- B ≅ B'] ->
[ Γ |- tProd A B ≅h tProd A' B']
| typeUnivConvAlg {Γ} :
[Γ |- U ≅h U]
| typeNatConvAlg {Γ} :
[Γ |- tNat ≅h tNat]
| typeEmptyConvAlg {Γ} :
[Γ |- tEmpty ≅h tEmpty]
| typeSigCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A'] ->
[ Γ ,, A |- B ≅ B'] ->
[ Γ |- tSig A B ≅h tSig A' B']
| typeIdCongAlg {Γ A A' x x' y y'} :
[ Γ |- A ≅ A'] ->
[ Γ |- x ≅ x' : A] ->
[ Γ |- y ≅ y' : A] ->
[ Γ |- tId A x y ≅h tId A' x' y']
| typeNeuConvAlg {Γ M N T} :
whne M ->
whne N ->
[ Γ |- M ~ N ▹ T] ->
[ Γ |- M ≅h N]
| typePiCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A'] ->
[ Γ ,, A |- B ≅ B'] ->
[ Γ |- tProd A B ≅h tProd A' B']
| typeUnivConvAlg {Γ} :
[Γ |- U ≅h U]
| typeNatConvAlg {Γ} :
[Γ |- tNat ≅h tNat]
| typeEmptyConvAlg {Γ} :
[Γ |- tEmpty ≅h tEmpty]
| typeSigCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A'] ->
[ Γ ,, A |- B ≅ B'] ->
[ Γ |- tSig A B ≅h tSig A' B']
| typeIdCongAlg {Γ A A' x x' y y'} :
[ Γ |- A ≅ A'] ->
[ Γ |- x ≅ x' : A] ->
[ Γ |- y ≅ y' : A] ->
[ Γ |- tId A x y ≅h tId A' x' y']
| typeNeuConvAlg {Γ M N T} :
whne M ->
whne N ->
[ Γ |- M ~ N ▹ T] ->
[ Γ |- M ≅h N]
with ConvNeuAlg : context -> term -> term -> term -> Type :=
| neuVarConvAlg {Γ n decl} :
in_ctx Γ n decl ->
[Γ |- tRel n ~ tRel n ▹ decl]
| neuAppCongAlg {Γ m n t u A B} :
[ Γ |- m ~h n ▹ tProd A B ] ->
[ Γ |- t ≅ u : A ] ->
[ Γ |- tApp m t ~ tApp n u ▹ B[t..] ]
| neuNatElimCong {Γ n n' P P' hz hz' hs hs'} :
| neuVarConvAlg {Γ n decl} :
in_ctx Γ n decl ->
[Γ |- tRel n ~ tRel n ▹ decl]
| neuAppCongAlg {Γ m n t u A B} :
[ Γ |- m ~h n ▹ tProd A B ] ->
[ Γ |- t ≅ u : A ] ->
[ Γ |- tApp m t ~ tApp n u ▹ B[t..] ]
| neuNatElimCong {Γ n n' P P' hz hz' hs hs'} :
Here, we know by invariant that the inferred type has to be tNat,
so there should be no need to check that, but with parameterized/indexed
inductive we need to recover informations from the neutrals to construct
the context for the predicate and the type of the branches.
[Γ |- n ~h n' ▹ tNat] ->
[Γ,, tNat |- P ≅ P'] ->
[Γ |- hz ≅ hz' : P[tZero..]] ->
[Γ |- hs ≅ hs' : elimSuccHypTy P] ->
[Γ |- tNatElim P hz hs n ~ tNatElim P' hz' hs' n' ▹ P[n..]]
| neuEmptyElimCong {Γ P P' e e'} :
[Γ |- e ~h e' ▹ tEmpty] ->
[Γ ,, tEmpty |- P ≅ P'] ->
[Γ |- tEmptyElim P e ~ tEmptyElim P' e' ▹ P[e..]]
| neuFstCongAlg {Γ m n A B} :
[ Γ |- m ~h n ▹ tSig A B ] ->
[ Γ |- tFst m ~ tFst n ▹ A ]
| neuSndCongAlg {Γ m n A B} :
[ Γ |- m ~h n ▹ tSig A B ] ->
[ Γ |- tSnd m ~ tSnd n ▹ B[(tFst m)..] ]
| neuIdElimCong {Γ A A' A'' x x' x'' P P' hr hr' y y' y'' e e'} :
[Γ |- e ~h e' ▹ tId A'' x'' y''] ->
[Γ ,, A ,, tId A⟨@wk1 Γ A⟩ x⟨@wk1 Γ A⟩ (tRel 0) |- P ≅ P'] ->
[Γ |- hr ≅ hr' : P[tRefl A x .: x..]] ->
[Γ |- tIdElim A x P hr y e ~ tIdElim A' x' P' hr' y' e' ▹ P[e .: y..] ]
[Γ,, tNat |- P ≅ P'] ->
[Γ |- hz ≅ hz' : P[tZero..]] ->
[Γ |- hs ≅ hs' : elimSuccHypTy P] ->
[Γ |- tNatElim P hz hs n ~ tNatElim P' hz' hs' n' ▹ P[n..]]
| neuEmptyElimCong {Γ P P' e e'} :
[Γ |- e ~h e' ▹ tEmpty] ->
[Γ ,, tEmpty |- P ≅ P'] ->
[Γ |- tEmptyElim P e ~ tEmptyElim P' e' ▹ P[e..]]
| neuFstCongAlg {Γ m n A B} :
[ Γ |- m ~h n ▹ tSig A B ] ->
[ Γ |- tFst m ~ tFst n ▹ A ]
| neuSndCongAlg {Γ m n A B} :
[ Γ |- m ~h n ▹ tSig A B ] ->
[ Γ |- tSnd m ~ tSnd n ▹ B[(tFst m)..] ]
| neuIdElimCong {Γ A A' A'' x x' x'' P P' hr hr' y y' y'' e e'} :
[Γ |- e ~h e' ▹ tId A'' x'' y''] ->
[Γ ,, A ,, tId A⟨@wk1 Γ A⟩ x⟨@wk1 Γ A⟩ (tRel 0) |- P ≅ P'] ->
[Γ |- hr ≅ hr' : P[tRefl A x .: x..]] ->
[Γ |- tIdElim A x P hr y e ~ tIdElim A' x' P' hr' y' e' ▹ P[e .: y..] ]
with ConvNeuRedAlg : context -> term -> term -> term -> Type :=
| neuConvRed {Γ m n A A'} :
[Γ |- m ~ n ▹ A] ->
[A ⤳* A'] ->
whnf A' ->
[Γ |- m ~h n ▹ A']
| neuConvRed {Γ m n A A'} :
[Γ |- m ~ n ▹ A] ->
[A ⤳* A'] ->
whnf A' ->
[Γ |- m ~h n ▹ A']
with ConvTermAlg : context -> term -> term -> term -> Type :=
| termConvRed {Γ t t' u u' A A'} :
[A ⤳* A'] ->
[t ⤳* t'] ->
[u ⤳* u' ] ->
[Γ |- t' ≅h u' : A'] ->
[Γ |- t ≅ u : A]
| termConvRed {Γ t t' u u' A A'} :
[A ⤳* A'] ->
[t ⤳* t'] ->
[u ⤳* u' ] ->
[Γ |- t' ≅h u' : A'] ->
[Γ |- t ≅ u : A]
with ConvTermRedAlg : context -> term -> term -> term -> Type :=
| termPiCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A' : U] ->
[ Γ ,, A |- B ≅ B' : U] ->
[ Γ |- tProd A B ≅h tProd A' B' : U]
| termNatReflAlg {Γ} :
[Γ |- tNat ≅h tNat : U]
| termZeroReflAlg {Γ} :
[Γ |- tZero ≅h tZero : tNat]
| termSuccCongAlg {Γ t t'} :
[Γ |- t ≅ t' : tNat] ->
[Γ |- tSucc t ≅h tSucc t' : tNat]
| termEmptyReflAlg {Γ} :
[Γ |- tEmpty ≅h tEmpty : U]
| termFunConvAlg {Γ : context} {f g A B} :
whnf f ->
whnf g ->
[ Γ,, A |- eta_expand f ≅ eta_expand g : B] ->
[ Γ |- f ≅h g : tProd A B]
| termSigCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A' : U] ->
[ Γ ,, A |- B ≅ B' : U] ->
[ Γ |- tSig A B ≅h tSig A' B' : U]
| termPairConvAlg {Γ : context} {p q A B} :
whnf p ->
whnf q ->
[ Γ |- tFst p ≅ tFst q : A] ->
[ Γ |- tSnd p ≅ tSnd q : B[(tFst p)..]] ->
[ Γ |- p ≅h q : tSig A B]
| termIdCongAlg {Γ A A' x x' y y'} :
[Γ |- A ≅ A' : U] ->
[Γ |- x ≅ x' : A] ->
[Γ |- y ≅ y' : A] ->
[Γ |- tId A x y ≅h tId A' x' y' : U]
| termIdReflCong {Γ A A' A'' x x' y y'} :
[Γ |- tRefl A x ≅h tRefl A' x' : tId A'' y y' ]
| termNeuConvAlg {Γ m n T P} :
[Γ |- m ~ n ▹ T] ->
isPosType P ->
[Γ |- m ≅h n : P]
where "[ Γ |- A ≅ B ]" := (ConvTypeAlg Γ A B)
and "[ Γ |- A ≅h B ]" := (ConvTypeRedAlg Γ A B)
and "[ Γ |- m ~ n ▹ T ]" := (ConvNeuAlg Γ T m n)
and "[ Γ |- m ~h n ▹ T ]" := (ConvNeuRedAlg Γ T m n)
and "[ Γ |- t ≅ u : T ]" := (ConvTermAlg Γ T t u)
and "[ Γ |- t ≅h u : T ]" := (ConvTermRedAlg Γ T t u)
and "[ t ⤳ t' ]" := (OneRedAlg t t')
and "[ t ⤳* t' ]" := (RedClosureAlg t t').
| termPiCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A' : U] ->
[ Γ ,, A |- B ≅ B' : U] ->
[ Γ |- tProd A B ≅h tProd A' B' : U]
| termNatReflAlg {Γ} :
[Γ |- tNat ≅h tNat : U]
| termZeroReflAlg {Γ} :
[Γ |- tZero ≅h tZero : tNat]
| termSuccCongAlg {Γ t t'} :
[Γ |- t ≅ t' : tNat] ->
[Γ |- tSucc t ≅h tSucc t' : tNat]
| termEmptyReflAlg {Γ} :
[Γ |- tEmpty ≅h tEmpty : U]
| termFunConvAlg {Γ : context} {f g A B} :
whnf f ->
whnf g ->
[ Γ,, A |- eta_expand f ≅ eta_expand g : B] ->
[ Γ |- f ≅h g : tProd A B]
| termSigCongAlg {Γ A B A' B'} :
[ Γ |- A ≅ A' : U] ->
[ Γ ,, A |- B ≅ B' : U] ->
[ Γ |- tSig A B ≅h tSig A' B' : U]
| termPairConvAlg {Γ : context} {p q A B} :
whnf p ->
whnf q ->
[ Γ |- tFst p ≅ tFst q : A] ->
[ Γ |- tSnd p ≅ tSnd q : B[(tFst p)..]] ->
[ Γ |- p ≅h q : tSig A B]
| termIdCongAlg {Γ A A' x x' y y'} :
[Γ |- A ≅ A' : U] ->
[Γ |- x ≅ x' : A] ->
[Γ |- y ≅ y' : A] ->
[Γ |- tId A x y ≅h tId A' x' y' : U]
| termIdReflCong {Γ A A' A'' x x' y y'} :
[Γ |- tRefl A x ≅h tRefl A' x' : tId A'' y y' ]
| termNeuConvAlg {Γ m n T P} :
[Γ |- m ~ n ▹ T] ->
isPosType P ->
[Γ |- m ≅h n : P]
where "[ Γ |- A ≅ B ]" := (ConvTypeAlg Γ A B)
and "[ Γ |- A ≅h B ]" := (ConvTypeRedAlg Γ A B)
and "[ Γ |- m ~ n ▹ T ]" := (ConvNeuAlg Γ T m n)
and "[ Γ |- m ~h n ▹ T ]" := (ConvNeuRedAlg Γ T m n)
and "[ Γ |- t ≅ u : T ]" := (ConvTermAlg Γ T t u)
and "[ Γ |- t ≅h u : T ]" := (ConvTermRedAlg Γ T t u)
and "[ t ⤳ t' ]" := (OneRedAlg t t')
and "[ t ⤳* t' ]" := (RedClosureAlg t t').
Typing
Inductive WfTypeAlg : context -> term -> Type :=
| wfTypeU Γ : [ Γ |- U ]
| wfTypeProd {Γ A B} :
[Γ |- A ] ->
[Γ,, A |- B] ->
[Γ |- tProd A B]
| wfTypeNat {Γ} :
[Γ |- tNat]
| wfTypeEmpty {Γ} :
[Γ |- tEmpty]
| wfTypeSig {Γ A B} :
[Γ |- A ] ->
[Γ,, A |- B] ->
[Γ |- tSig A B]
| wfTypeId {Γ A x y} :
[Γ |- A] ->
[Γ |- x ◃ A] ->
[Γ |- y ◃ A] ->
[Γ |- tId A x y]
| wfTypeUniv {Γ A} :
~ isCanonical A ->
[Γ |- A ▹h U] ->
[Γ |- A]
| wfTypeU Γ : [ Γ |- U ]
| wfTypeProd {Γ A B} :
[Γ |- A ] ->
[Γ,, A |- B] ->
[Γ |- tProd A B]
| wfTypeNat {Γ} :
[Γ |- tNat]
| wfTypeEmpty {Γ} :
[Γ |- tEmpty]
| wfTypeSig {Γ A B} :
[Γ |- A ] ->
[Γ,, A |- B] ->
[Γ |- tSig A B]
| wfTypeId {Γ A x y} :
[Γ |- A] ->
[Γ |- x ◃ A] ->
[Γ |- y ◃ A] ->
[Γ |- tId A x y]
| wfTypeUniv {Γ A} :
~ isCanonical A ->
[Γ |- A ▹h U] ->
[Γ |- A]
with InferAlg : context -> term -> term -> Type :=
| infVar {Γ n decl} :
in_ctx Γ n decl ->
[Γ |- tRel n ▹ decl]
| infProd {Γ} {A B} :
[ Γ |- A ▹h U] ->
[Γ ,, A |- B ▹h U ] ->
[ Γ |- tProd A B ▹ U ]
| infLam {Γ} {A B t} :
[ Γ |- A] ->
[ Γ ,, A |- t ▹ B ] ->
[ Γ |- tLambda A t ▹ tProd A B]
| infApp {Γ} {f a A B} :
[ Γ |- f ▹h tProd A B ] ->
[ Γ |- a ◃ A ] ->
[ Γ |- tApp f a ▹ B[a..] ]
| infNat {Γ} :
[Γ |- tNat ▹ U]
| infZero {Γ} :
[Γ |- tZero ▹ tNat]
| infSucc {Γ t} :
[Γ |- t ▹h tNat] ->
[Γ |- tSucc t ▹ tNat]
| infNatElim {Γ P hz hs n} :
[Γ |- n ▹h tNat] ->
[Γ,, tNat |- P] ->
[Γ |- hz ◃ P[tZero..]] ->
[Γ |- hs ◃ elimSuccHypTy P] ->
[Γ |- tNatElim P hz hs n ▹ P[n..]]
| infEmpty {Γ} :
[Γ |- tEmpty ▹ U]
| infEmptyElim {Γ P e} :
[Γ |- e ▹h tEmpty] ->
[Γ ,, tEmpty |- P ] ->
[Γ |- tEmptyElim P e ▹ P[e..]]
| infSig {Γ} {A B} :
[ Γ |- A ▹h U] ->
[Γ ,, A |- B ▹h U ] ->
[ Γ |- tSig A B ▹ U ]
| infPair {Γ A B a b} :
[ Γ |- A] ->
[Γ ,, A |- B] ->
[Γ |- a ◃ A] ->
[Γ |- b ◃ B[a..]] ->
[Γ |- tPair A B a b ▹ tSig A B]
| infFst {Γ A B p} :
[Γ |- p ▹h tSig A B] ->
[Γ |- tFst p ▹ A]
| infSnd {Γ A B p} :
[Γ |- p ▹h tSig A B] ->
[Γ |- tSnd p ▹ B[(tFst p)..]]
| infId {Γ A x y} :
[Γ |- A ▹h U] ->
[Γ |- x ◃ A] ->
[Γ |- y ◃ A] ->
[Γ |- tId A x y ▹ U]
| infRefl {Γ A x} :
[Γ |- A] ->
[Γ |- x ◃ A] ->
[Γ |- tRefl A x ▹ tId A x x]
| infIdElim {Γ A x P hr y e} :
[Γ |- A] ->
[Γ |- x ◃ A] ->
[Γ,, A,, tId A⟨@wk1 Γ A⟩ x⟨@wk1 Γ A⟩ (tRel 0) |- P] ->
[Γ |- hr ◃ P[tRefl A x .: x..]] ->
[Γ |- y ◃ A] ->
[Γ |- e ◃ tId A x y] ->
[Γ |- tIdElim A x P hr y e ▹ P[e .: y..]]
| infVar {Γ n decl} :
in_ctx Γ n decl ->
[Γ |- tRel n ▹ decl]
| infProd {Γ} {A B} :
[ Γ |- A ▹h U] ->
[Γ ,, A |- B ▹h U ] ->
[ Γ |- tProd A B ▹ U ]
| infLam {Γ} {A B t} :
[ Γ |- A] ->
[ Γ ,, A |- t ▹ B ] ->
[ Γ |- tLambda A t ▹ tProd A B]
| infApp {Γ} {f a A B} :
[ Γ |- f ▹h tProd A B ] ->
[ Γ |- a ◃ A ] ->
[ Γ |- tApp f a ▹ B[a..] ]
| infNat {Γ} :
[Γ |- tNat ▹ U]
| infZero {Γ} :
[Γ |- tZero ▹ tNat]
| infSucc {Γ t} :
[Γ |- t ▹h tNat] ->
[Γ |- tSucc t ▹ tNat]
| infNatElim {Γ P hz hs n} :
[Γ |- n ▹h tNat] ->
[Γ,, tNat |- P] ->
[Γ |- hz ◃ P[tZero..]] ->
[Γ |- hs ◃ elimSuccHypTy P] ->
[Γ |- tNatElim P hz hs n ▹ P[n..]]
| infEmpty {Γ} :
[Γ |- tEmpty ▹ U]
| infEmptyElim {Γ P e} :
[Γ |- e ▹h tEmpty] ->
[Γ ,, tEmpty |- P ] ->
[Γ |- tEmptyElim P e ▹ P[e..]]
| infSig {Γ} {A B} :
[ Γ |- A ▹h U] ->
[Γ ,, A |- B ▹h U ] ->
[ Γ |- tSig A B ▹ U ]
| infPair {Γ A B a b} :
[ Γ |- A] ->
[Γ ,, A |- B] ->
[Γ |- a ◃ A] ->
[Γ |- b ◃ B[a..]] ->
[Γ |- tPair A B a b ▹ tSig A B]
| infFst {Γ A B p} :
[Γ |- p ▹h tSig A B] ->
[Γ |- tFst p ▹ A]
| infSnd {Γ A B p} :
[Γ |- p ▹h tSig A B] ->
[Γ |- tSnd p ▹ B[(tFst p)..]]
| infId {Γ A x y} :
[Γ |- A ▹h U] ->
[Γ |- x ◃ A] ->
[Γ |- y ◃ A] ->
[Γ |- tId A x y ▹ U]
| infRefl {Γ A x} :
[Γ |- A] ->
[Γ |- x ◃ A] ->
[Γ |- tRefl A x ▹ tId A x x]
| infIdElim {Γ A x P hr y e} :
[Γ |- A] ->
[Γ |- x ◃ A] ->
[Γ,, A,, tId A⟨@wk1 Γ A⟩ x⟨@wk1 Γ A⟩ (tRel 0) |- P] ->
[Γ |- hr ◃ P[tRefl A x .: x..]] ->
[Γ |- y ◃ A] ->
[Γ |- e ◃ tId A x y] ->
[Γ |- tIdElim A x P hr y e ▹ P[e .: y..]]
with InferRedAlg : context -> term -> term -> Type :=
| infRed {Γ t A A'} :
[Γ |- t ▹ A ] ->
[ A ⤳* A'] ->
whnf A' ->
[Γ |- t ▹h A']
| infRed {Γ t A A'} :
[Γ |- t ▹ A ] ->
[ A ⤳* A'] ->
whnf A' ->
[Γ |- t ▹h A']
with CheckAlg : context -> term -> term -> Type :=
| checkConv {Γ t A A'} :
[ Γ |- t ▹ A ] ->
conv_type Γ A A' ->
[ Γ |- t ◃ A' ]
where "[ Γ |- A ]" := (WfTypeAlg Γ A)
and "[ Γ |- t ▹ T ]" := (InferAlg Γ T t)
and "[ Γ |- t ▹h T ]" := (InferRedAlg Γ T t)
and "[ Γ |- t ◃ T ]" := (CheckAlg Γ T t).
| checkConv {Γ t A A'} :
[ Γ |- t ▹ A ] ->
conv_type Γ A A' ->
[ Γ |- t ◃ A' ]
where "[ Γ |- A ]" := (WfTypeAlg Γ A)
and "[ Γ |- t ▹ T ]" := (InferAlg Γ T t)
and "[ Γ |- t ▹h T ]" := (InferRedAlg Γ T t)
and "[ Γ |- t ◃ T ]" := (CheckAlg Γ T t).
Context well-formation
Inductive WfContextAlg : context -> Type :=
| conNilAlg : [|- ε]
| conConsAlg {Γ A} :
[|- Γ] ->
[ Γ |- A] ->
[|- Γ,, A]
where "[ |- Γ ]" := (WfContextAlg Γ).
End Definitions.
| conNilAlg : [|- ε]
| conConsAlg {Γ A} :
[|- Γ] ->
[ Γ |- A] ->
[|- Γ,, A]
where "[ |- Γ ]" := (WfContextAlg Γ).
End Definitions.
Inductive UConvAlg : term -> term -> Type :=
| termUConvRed {t t' u u'} :
[t ⤳* t'] ->
[u ⤳* u' ] ->
[t' ≅h u'] ->
[t ≅ u]
| termUConvRed {t t' u u'} :
[t ⤳* t'] ->
[u ⤳* u' ] ->
[t' ≅h u'] ->
[t ≅ u]
with UConvRedAlg : term -> term -> Type :=
| UnivReflUAlg :
[U ≅h U]
| PiCongUAlg {A B A' B'} :
[A ≅ A'] ->
[B ≅ B'] ->
[tProd A B ≅h tProd A' B']
| NatReflUAlg :
[tNat ≅h tNat]
| ZeroReflUAlg :
[tZero ≅h tZero]
| SuccCongUAlg {t t'} :
[t ≅ t'] ->
[tSucc t ≅h tSucc t']
| EmptyReflUAlg :
[tEmpty ≅h tEmpty]
| LamCongUAlg {A t A' t'} :
[t ≅ t'] ->
[tLambda A t ≅h tLambda A' t']
| LambNeUAlg {A t n'} :
whne n' ->
[t ≅ eta_expand n'] ->
[tLambda A t ≅h n']
| NeLamUAlg {n A' t'} :
whne n ->
[eta_expand n ≅ t'] ->
[n ≅h tLambda A' t']
| SigCongUAlg {A B A' B'} :
[A ≅ A'] ->
[ B ≅ B'] ->
[tSig A B ≅h tSig A' B']
| PairCongUAlg {A B p q A' B' p' q'} :
[p ≅ p'] ->
[q ≅ q'] ->
[tPair A B p q ≅h tPair A' B' p' q']
| PairNeUAlg {A B p q n'} :
whne n' ->
[p ≅ tFst n'] ->
[q ≅ tSnd n'] ->
[tPair A B p q ≅h n']
| NePairUAlg {n A' B' p' q'} :
whne n ->
[tFst n ≅ p'] ->
[tSnd n ≅ q'] ->
[n ≅h tPair A' B' p' q']
| IdCongUAlg {A A' x x' y y'} :
[A ≅ A'] ->
[x ≅ x'] ->
[y ≅ y'] ->
[tId A x y ≅h tId A' x' y']
| IdReflCongUAlg {A x A' x'} :
[tRefl A x ≅h tRefl A' x']
| NeuConvUAlg {m n} :
[m ~ n] ->
[m ≅h n]
| UnivReflUAlg :
[U ≅h U]
| PiCongUAlg {A B A' B'} :
[A ≅ A'] ->
[B ≅ B'] ->
[tProd A B ≅h tProd A' B']
| NatReflUAlg :
[tNat ≅h tNat]
| ZeroReflUAlg :
[tZero ≅h tZero]
| SuccCongUAlg {t t'} :
[t ≅ t'] ->
[tSucc t ≅h tSucc t']
| EmptyReflUAlg :
[tEmpty ≅h tEmpty]
| LamCongUAlg {A t A' t'} :
[t ≅ t'] ->
[tLambda A t ≅h tLambda A' t']
| LambNeUAlg {A t n'} :
whne n' ->
[t ≅ eta_expand n'] ->
[tLambda A t ≅h n']
| NeLamUAlg {n A' t'} :
whne n ->
[eta_expand n ≅ t'] ->
[n ≅h tLambda A' t']
| SigCongUAlg {A B A' B'} :
[A ≅ A'] ->
[ B ≅ B'] ->
[tSig A B ≅h tSig A' B']
| PairCongUAlg {A B p q A' B' p' q'} :
[p ≅ p'] ->
[q ≅ q'] ->
[tPair A B p q ≅h tPair A' B' p' q']
| PairNeUAlg {A B p q n'} :
whne n' ->
[p ≅ tFst n'] ->
[q ≅ tSnd n'] ->
[tPair A B p q ≅h n']
| NePairUAlg {n A' B' p' q'} :
whne n ->
[tFst n ≅ p'] ->
[tSnd n ≅ q'] ->
[n ≅h tPair A' B' p' q']
| IdCongUAlg {A A' x x' y y'} :
[A ≅ A'] ->
[x ≅ x'] ->
[y ≅ y'] ->
[tId A x y ≅h tId A' x' y']
| IdReflCongUAlg {A x A' x'} :
[tRefl A x ≅h tRefl A' x']
| NeuConvUAlg {m n} :
[m ~ n] ->
[m ≅h n]
with UConvNeuAlg : term -> term -> Type :=
| VarConvUAlg {n} :
[tRel n ~ tRel n]
| AppCongUAlg {m n t u} :
[m ~ n] ->
[t ≅ u] ->
[tApp m t ~ tApp n u]
| NatElimCongUAlg {n n' P P' hz hz' hs hs'} :
[n ~ n'] ->
[P ≅ P'] ->
[hz ≅ hz'] ->
[hs ≅ hs'] ->
[tNatElim P hz hs n ~ tNatElim P' hz' hs' n']
| EmptyElimCongUAlg {P P' e e'} :
[e ~ e'] ->
[P ≅ P'] ->
[tEmptyElim P e ~ tEmptyElim P' e']
| FstCongUAlg {m n} :
[m ~ n] ->
[tFst m ~ tFst n]
| SndCongUAlg {m n} :
[m ~ n] ->
[tSnd m ~ tSnd n]
| IdElimCongUAlg {A A' x x' P P' hr hr' y y' e e'} :
[e ~ e'] ->
[P ≅ P'] ->
[hr ≅ hr'] ->
[tIdElim A x P hr y e ~ tIdElim A' x' P' hr' y' e']
where "[ A ≅ B ]" := (UConvAlg A B)
and "[ A ≅h B ]" := (UConvRedAlg A B)
and "[ m ~ n ]" := (UConvNeuAlg m n).
| VarConvUAlg {n} :
[tRel n ~ tRel n]
| AppCongUAlg {m n t u} :
[m ~ n] ->
[t ≅ u] ->
[tApp m t ~ tApp n u]
| NatElimCongUAlg {n n' P P' hz hz' hs hs'} :
[n ~ n'] ->
[P ≅ P'] ->
[hz ≅ hz'] ->
[hs ≅ hs'] ->
[tNatElim P hz hs n ~ tNatElim P' hz' hs' n']
| EmptyElimCongUAlg {P P' e e'} :
[e ~ e'] ->
[P ≅ P'] ->
[tEmptyElim P e ~ tEmptyElim P' e']
| FstCongUAlg {m n} :
[m ~ n] ->
[tFst m ~ tFst n]
| SndCongUAlg {m n} :
[m ~ n] ->
[tSnd m ~ tSnd n]
| IdElimCongUAlg {A A' x x' P P' hr hr' y y' e e'} :
[e ~ e'] ->
[P ≅ P'] ->
[hr ≅ hr'] ->
[tIdElim A x P hr y e ~ tIdElim A' x' P' hr' y' e']
where "[ A ≅ B ]" := (UConvAlg A B)
and "[ A ≅h B ]" := (UConvRedAlg A B)
and "[ m ~ n ]" := (UConvNeuAlg m n).
Module AlgorithmicTypingData.
#[export] Instance WfContext_Algo `{ta : tag} `{! ConvType ta} : WfContext ta | 100 := WfContextAlg.
#[export] Instance WfType_Algo `{ta : tag} `{! ConvType ta} : WfType ta | 100 := WfTypeAlg.
#[export] Instance Inferring_Algo `{ta : tag} `{! ConvType ta} : Inferring ta | 100 := InferAlg.
#[export] Instance InferringRed_Algo `{ta : tag} `{! ConvType ta} : InferringRed ta | 100 := InferRedAlg.
#[export] Instance Checking_Algo `{ta : tag} `{! ConvType ta} : Checking ta | 100 := CheckAlg.
Ltac fold_algo :=
change (@WfContextAlg ?ta _) with (wf_context (ta := ta)) in * ;
change (@WfTypeAlg ?ta _) with (wf_type (ta := ta)) in *;
change (@InferAlg ?ta _) with (inferring (ta := ta)) in * ;
change (@InferRedAlg ?ta _) with (infer_red (ta := ta)) in * ;
change (@CheckAlg ?ta _) with (check (ta := ta)) in *.
Smpl Add fold_algo : refold.
End AlgorithmicTypingData.
Module AlgorithmicTypedConvData.
Definition al : tag.
Proof.
constructor.
Qed.
#[export] Instance ConvType_Algo : ConvType al := ConvTypeAlg.
#[export] Instance ConvTypeRed_Algo : ConvTypeRed al := ConvTypeRedAlg.
#[export] Instance ConvTerm_Algo : ConvTerm al := ConvTermAlg.
#[export] Instance ConvTermRed_Algo : ConvTermRed al := ConvTermRedAlg.
#[export] Instance ConvNeu_Algo : ConvNeu al := ConvNeuAlg.
#[export] Instance ConvNeuRed_Algo : ConvNeuRed al := ConvNeuRedAlg.
Ltac fold_algo_tconv :=
change ConvTypeAlg with (conv_type (ta := al)) in * ;
change ConvTypeRedAlg with (conv_type_red (ta := al)) in * ;
change ConvTermAlg with (conv_term (ta := al)) in * ;
change ConvTermRedAlg with (conv_term_red (ta := al)) in * ;
change ConvNeuAlg with (conv_neu (ta := al)) in * ;
change ConvTypeRedAlg with (conv_type_red (ta := al)) in * ;
change ConvTermRedAlg with (conv_term_red (ta := al)) in * ;
change ConvNeuRedAlg with (conv_neu_red (ta := al)) in *.
Smpl Add fold_algo_tconv : refold.
End AlgorithmicTypedConvData.
Induction principles
Section InductionPrinciples.
Import AlgorithmicTypingData AlgorithmicTypedConvData.
Scheme
Minimality for ConvTypeAlg Sort Type with
Minimality for ConvTypeRedAlg Sort Type with
Minimality for ConvNeuAlg Sort Type with
Minimality for ConvNeuRedAlg Sort Type with
Minimality for ConvTermAlg Sort Type with
Minimality for ConvTermRedAlg Sort Type.
Scheme
Minimality for WfTypeAlg Sort Type with
Minimality for InferAlg Sort Type with
Minimality for InferRedAlg Sort Type with
Minimality for CheckAlg Sort Type.
Combined Scheme _AlgoConvInduction from
ConvTypeAlg_rect_nodep,
ConvTypeRedAlg_rect_nodep,
ConvNeuAlg_rect_nodep,
ConvNeuRedAlg_rect_nodep,
ConvTermAlg_rect_nodep,
ConvTermRedAlg_rect_nodep.
Combined Scheme _AlgoTypingInduction from
WfTypeAlg_rect_nodep,
InferAlg_rect_nodep,
InferRedAlg_rect_nodep,
CheckAlg_rect_nodep.
Let _AlgoConvInductionType :=
ltac:(let ind := fresh "ind" in
pose (ind := _AlgoConvInduction);
refold ;
let ind_ty := type of ind in
exact ind_ty).
Let AlgoConvInductionType :=
ltac: (let ind := eval cbv delta [_AlgoConvInductionType] zeta
in _AlgoConvInductionType in
let ind' := polymorphise ind in
exact ind').
Lemma AlgoConvInduction : AlgoConvInductionType.
Proof.
intros PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq **.
pose proof (_AlgoConvInduction PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq) as H.
destruct H as [?[?[?[?[?]]]]] ; cycle -1.
1: by_prod_splitter.
all: assumption.
Qed.
Let _AlgoTypingInductionType :=
ltac:(let ind := fresh "ind" in
pose (ind := _AlgoTypingInduction);
refold ;
let ind_ty := type of ind in
exact ind_ty).
Let AlgoTypingInductionType :=
ltac: (let ind := eval cbv delta [_AlgoTypingInductionType] zeta
in _AlgoTypingInductionType in
let ind' := polymorphise ind in
exact ind').
Lemma AlgoTypingInduction : AlgoTypingInductionType.
Proof.
intros ? conv PTy PInf PInfRed PCheck **.
pose proof (_AlgoTypingInduction _ _ PTy PInf PInfRed PCheck) as H.
destruct H as [?[?[?]]] ; cycle -1.
1: by_prod_splitter.
all: assumption.
Qed.
Definition AlgoConvInductionConcl :=
ltac:(
let t := eval cbv delta [AlgoConvInductionType] beta in AlgoConvInductionType in
let t' := remove_steps t in
exact t').
Definition AlgoTypingInductionConcl :=
ltac:(
let t := eval cbv delta [AlgoTypingInductionType] beta in AlgoTypingInductionType in
let t' := remove_steps t in
exact t').
Scheme
Minimality for UConvAlg Sort Type with
Minimality for UConvRedAlg Sort Type with
Minimality for UConvNeuAlg Sort Type.
Combined Scheme UAlgoConvInduction from
UConvAlg_rect_nodep,
UConvRedAlg_rect_nodep,
UConvNeuAlg_rect_nodep.
Arguments UAlgoConvInduction PEq PRedEq PNeEq : rename.
Definition UAlgoConvInductionConcl :=
ltac:(
let t := type of UAlgoConvInduction in
let t' := remove_steps t in
exact t').
End InductionPrinciples.
Arguments AlgoConvInductionConcl PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq : rename.
Arguments AlgoConvInduction PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq : rename.
Arguments AlgoTypingInductionConcl {ta conv} PTy PInf PInfRed PCheck : rename.
Arguments AlgoTypingInduction {ta conv} PTy PInf PInfRed PCheck : rename.
Import AlgorithmicTypingData AlgorithmicTypedConvData.
Scheme
Minimality for ConvTypeAlg Sort Type with
Minimality for ConvTypeRedAlg Sort Type with
Minimality for ConvNeuAlg Sort Type with
Minimality for ConvNeuRedAlg Sort Type with
Minimality for ConvTermAlg Sort Type with
Minimality for ConvTermRedAlg Sort Type.
Scheme
Minimality for WfTypeAlg Sort Type with
Minimality for InferAlg Sort Type with
Minimality for InferRedAlg Sort Type with
Minimality for CheckAlg Sort Type.
Combined Scheme _AlgoConvInduction from
ConvTypeAlg_rect_nodep,
ConvTypeRedAlg_rect_nodep,
ConvNeuAlg_rect_nodep,
ConvNeuRedAlg_rect_nodep,
ConvTermAlg_rect_nodep,
ConvTermRedAlg_rect_nodep.
Combined Scheme _AlgoTypingInduction from
WfTypeAlg_rect_nodep,
InferAlg_rect_nodep,
InferRedAlg_rect_nodep,
CheckAlg_rect_nodep.
Let _AlgoConvInductionType :=
ltac:(let ind := fresh "ind" in
pose (ind := _AlgoConvInduction);
refold ;
let ind_ty := type of ind in
exact ind_ty).
Let AlgoConvInductionType :=
ltac: (let ind := eval cbv delta [_AlgoConvInductionType] zeta
in _AlgoConvInductionType in
let ind' := polymorphise ind in
exact ind').
Lemma AlgoConvInduction : AlgoConvInductionType.
Proof.
intros PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq **.
pose proof (_AlgoConvInduction PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq) as H.
destruct H as [?[?[?[?[?]]]]] ; cycle -1.
1: by_prod_splitter.
all: assumption.
Qed.
Let _AlgoTypingInductionType :=
ltac:(let ind := fresh "ind" in
pose (ind := _AlgoTypingInduction);
refold ;
let ind_ty := type of ind in
exact ind_ty).
Let AlgoTypingInductionType :=
ltac: (let ind := eval cbv delta [_AlgoTypingInductionType] zeta
in _AlgoTypingInductionType in
let ind' := polymorphise ind in
exact ind').
Lemma AlgoTypingInduction : AlgoTypingInductionType.
Proof.
intros ? conv PTy PInf PInfRed PCheck **.
pose proof (_AlgoTypingInduction _ _ PTy PInf PInfRed PCheck) as H.
destruct H as [?[?[?]]] ; cycle -1.
1: by_prod_splitter.
all: assumption.
Qed.
Definition AlgoConvInductionConcl :=
ltac:(
let t := eval cbv delta [AlgoConvInductionType] beta in AlgoConvInductionType in
let t' := remove_steps t in
exact t').
Definition AlgoTypingInductionConcl :=
ltac:(
let t := eval cbv delta [AlgoTypingInductionType] beta in AlgoTypingInductionType in
let t' := remove_steps t in
exact t').
Scheme
Minimality for UConvAlg Sort Type with
Minimality for UConvRedAlg Sort Type with
Minimality for UConvNeuAlg Sort Type.
Combined Scheme UAlgoConvInduction from
UConvAlg_rect_nodep,
UConvRedAlg_rect_nodep,
UConvNeuAlg_rect_nodep.
Arguments UAlgoConvInduction PEq PRedEq PNeEq : rename.
Definition UAlgoConvInductionConcl :=
ltac:(
let t := type of UAlgoConvInduction in
let t' := remove_steps t in
exact t').
End InductionPrinciples.
Arguments AlgoConvInductionConcl PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq : rename.
Arguments AlgoConvInduction PTyEq PTyRedEq PNeEq PNeRedEq PTmEq PTmRedEq : rename.
Arguments AlgoTypingInductionConcl {ta conv} PTy PInf PInfRed PCheck : rename.
Arguments AlgoTypingInduction {ta conv} PTy PInf PInfRed PCheck : rename.