我试图将多维数组表示为受限函数,我在定义看似原始函数时遇到了麻烦。
以下是定义:
Require Export Fin. Require Export PeanoNat. Inductive ispace : nat -> Type := Rect: forall d:nat, ((Fin.t d) -> nat) -> ispace d. Inductive index : nat -> Type := Idx: forall d: nat, (Fin.t d -> nat) -> index d. Inductive bound_idx : forall d, index d -> ispace d -> Prop -> Type := RectBoundIdx : forall d f_idx f_shp, bound_idx d (Idx d f_idx) (Rect d f_shp) (forall i, f_idx i < f_shp i). Inductive array : forall d (is:ispace d), (forall idx pf, bound_idx d idx is pf -> nat) -> Type := RectArray: forall (d:nat) sh_f val_f, array d (Rect d sh_f) val_f.
我为矩形索引空间,索引和由矩形索引空间限定的索引定义类型族。数组类型是从受限索引空间到nat的函数。
现在,我正在尝试从这样的函数构造一个数组:
Definition func_to_arr d is (af:forall idx pf, bound_idx d idx is pf -> nat) := match is with | Rect d f => RectArray d f af end.
Coq告诉我:
Error: In environment d : nat is : ispace d af : forall (idx : index d) (pf : Prop), bound_idx d idx is pf -> nat d0 : nat f : t d0 -> nat The term "af" has type "forall (idx : index d) (pf : Prop), bound_idx d idx is pf -> nat" while it is expected to have type "forall (idx : index d0) (pf : Prop), bound_idx d0 idx (Rect d0 f) pf -> nat" (cannot unify "index d0" and "index d").
所以我想知道,我怎样才能将这些信息传递给上面的定义,以便它变得有效。除非我误解了某些东西,否则af的类型包含重建数组的所有必要信息。
答案 0 :(得分:0)
这个问题在使用Coq的依赖类型编程中很常见。为了解决这个问题,人们通常使用A. Chlipala在CPDT中描述的护航模式(更多章节,IIRC),并在Stackoverflow上提到多次。
以下是如何定义功能的方法。
Definition func_to_arr d is (af:forall idx pf, bound_idx d idx is pf -> nat) :=
match is
as is'
in (ispace d1)
return
forall af' : forall idx pf, bound_idx d1 idx is' pf -> nat, array d1 is' af'
with
| Rect d2 f => fun af' => RectArray d2 f af'
end af.
我在这里做依赖模式匹配,基本上执行&#34;重写&#34;因此,Coq可以看到人类读者通常认为理所当然的变量之间的联系。您可以在本手册的extended pattern matching部分阅读我在此处使用的构造。
顺便提一下,如果您将d
参数设为归纳类型而不是将其作为索引,则不需要使用{{1} }},d1
和d2
不是必需的。如果选择是偶然的,那么您可能需要查看answer explaining the difference between those。