You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have mutually inductive types and terms where types can both contain terms (e.g., refinement predicates) and bind term variables (e.g., dependent function types).
In this setting, type substitution .[U/] does not shift U's term variables when going under a term binder in the outer type.
RequireImport Autosubst.Autosubst.
Inductive Ty : Type :=
| TVar : var -> Ty
| TFun : Ty -> {bind Termin Ty} -> Ty
| TRefine : Ty -> {bind Term} -> Ty
withTerm : Type :=
| tvar : var -> Term.
GlobalInstance Ids_Ty : Ids Ty. derive. Defined.
GlobalInstance Rename_Ty : Rename Ty. derive. Defined.
GlobalInstance Subst_Ty : Subst Ty. derive. Defined.
GlobalInstance SubstLemmas_Ty : SubstLemmas Ty. derive. Defined.
GlobalInstance Ids_Term : Ids Term. derive. Defined.
GlobalInstance Rename_Term : Rename Term. derive. Defined.
GlobalInstance Subst_Term : Subst Term. derive. Defined.
GlobalInstance SubstLemmas_Term : SubstLemmas Term. derive. Defined.
GlobalInstance HSubst_Term_Ty : HSubst Term Ty. derive. Defined.
Example ty_subst_does_not_shift :
(TFun (TVar 0) (TVar 0)).[(TRefine (TVar 1) (tvar 1))/] =
TFun (TRefine (TVar 1) (tvar 1)) (TRefine (TVar 1) (tvar 1)).
(* ^^^^^^ should be tvar 2 *)Proof. reflexivity. Qed.
Both copies of the substituted type are identical. The second one is under TFun's term binder ({bind Term in Ty}), so its free term variable tvar 1 should have been shifted to tvar 2.
It seems type substitution .[sigma] only tracks type-variable binders (applying up when going under {bind Ty ...}) but does not track term-variable binders ({bind Term in Ty}), so the substituted type is inserted verbatim regardless of how many term binders have been crossed.
Is this a known limitation?
All existing Autosubst 1 examples have types that never contain terms, so this issue does not arise there.
I read Autosubst 2 uses vector substitutions that track all sorts simultaneously, which should in principle handle this correctly. However, I'd prefer to stay on Autosubst 1 if possible.
I have mutually inductive types and terms where types can both contain terms (e.g., refinement predicates) and bind term variables (e.g., dependent function types).
In this setting, type substitution
.[U/]does not shiftU's term variables when going under a term binder in the outer type.Both copies of the substituted type are identical. The second one is under
TFun's term binder ({bind Term in Ty}), so its free term variabletvar 1should have been shifted totvar 2.It seems type substitution
.[sigma]only tracks type-variable binders (applyingupwhen going under{bind Ty ...}) but does not track term-variable binders ({bind Term in Ty}), so the substituted type is inserted verbatim regardless of how many term binders have been crossed.Is this a known limitation?
Ids_outernecessary forHSubstLemmas? #4 discusses related limitations with heterogeneous substitution, but it seems to predate support for mutually inductive types.