Coq:添加隐式变量
Coq: adding implicit variables
假设我有一组函数,每个函数都可以依赖于一个或两个隐式变量A B: Type
。我怎样才能指定这个? IE。将这些变量添加到它们的变量列表中并将它们设置为隐式。
最明显的方法是在它们的定义中添加 {A B: Type}
。然而,在现实生活和适度复杂的开发中,此类隐式共享列表很容易达到 6-10 个条目并包含复杂的类型,从而使函数定义难以阅读,甚至更难以理解它们的相似性或对提到的类型进行更改。因此这个解决方案不适用。
我可以将所有函数包含在一个部分或模块中,并在开头写 Variables (A B: Type) etc
,但这不会使变量隐式化,而且我必须在部分末尾为所有函数手动设置参数。更糟糕的是,这会使所有变量共享。 IE。如果我声明
Section sect.
Variable A B: Type.
Definition f (t: A -> Type) := (..).
Definition g (t: A -> Type) (s: B -> Type) := G (f t) (f s).
End sect.
(G
是一些双变量函数)那么 g
将不会被接受,因为 s
不在 A -> Type
中,即使本质上 [=18] =] 只需要一个任意类型族。
我可以制作一个部分并声明 Context {A B: Type}
。这将使这些变量对所有函数都是隐式的,但像以前的情况一样的共享问题仍然存在。因此,我将不得不任意地将我的函数分成几个部分,以便我可以使用隐式参数的不同值调用 Sect.1 中的函数。这行得通,但很丑,我可以很容易地想象出这样一种情况,即每个部分必须有 2-3 个函数长,这样我才能正确调用它们。
有没有更好的解决方案?
您可以做两件难度较小的事情:
Generalizable All Variables.
Definition g `(t: A -> Type) `(s: B -> Type) := G (f t) (f s).
现在您可以使用反引号了,它会自动插入您需要的隐式变量,使定义有效。这是我引入隐式的最常见方式。
另一种方式是跟随你的部分:
Arguments g : default implicits.
您需要为每个定义的术语重复此操作,但至少您不需要命名所有参数。
假设我有一组函数,每个函数都可以依赖于一个或两个隐式变量A B: Type
。我怎样才能指定这个? IE。将这些变量添加到它们的变量列表中并将它们设置为隐式。
最明显的方法是在它们的定义中添加 {A B: Type}
。然而,在现实生活和适度复杂的开发中,此类隐式共享列表很容易达到 6-10 个条目并包含复杂的类型,从而使函数定义难以阅读,甚至更难以理解它们的相似性或对提到的类型进行更改。因此这个解决方案不适用。
我可以将所有函数包含在一个部分或模块中,并在开头写 Variables (A B: Type) etc
,但这不会使变量隐式化,而且我必须在部分末尾为所有函数手动设置参数。更糟糕的是,这会使所有变量共享。 IE。如果我声明
Section sect.
Variable A B: Type.
Definition f (t: A -> Type) := (..).
Definition g (t: A -> Type) (s: B -> Type) := G (f t) (f s).
End sect.
(G
是一些双变量函数)那么 g
将不会被接受,因为 s
不在 A -> Type
中,即使本质上 [=18] =] 只需要一个任意类型族。
我可以制作一个部分并声明 Context {A B: Type}
。这将使这些变量对所有函数都是隐式的,但像以前的情况一样的共享问题仍然存在。因此,我将不得不任意地将我的函数分成几个部分,以便我可以使用隐式参数的不同值调用 Sect.1 中的函数。这行得通,但很丑,我可以很容易地想象出这样一种情况,即每个部分必须有 2-3 个函数长,这样我才能正确调用它们。
有没有更好的解决方案?
您可以做两件难度较小的事情:
Generalizable All Variables.
Definition g `(t: A -> Type) `(s: B -> Type) := G (f t) (f s).
现在您可以使用反引号了,它会自动插入您需要的隐式变量,使定义有效。这是我引入隐式的最常见方式。
另一种方式是跟随你的部分:
Arguments g : default implicits.
您需要为每个定义的术语重复此操作,但至少您不需要命名所有参数。