coq - 克服在另一个构造函数的定义中有构造函数的需要
问题描述
很可能我正在尝试实现一些有缺陷的东西,但是我遇到了在另一个构造函数的定义中需要一个构造函数。
愚蠢的例子:
Inductive silly_type : Type :=
| constr1 : nat -> silly_type
| constr2 : forall (x : silly_type), (exists n : nat, (x = constr1 n)) -> silly_type.
有两种方法可以创建 的元素silly_type
,或者使用自然数,constr1
或者使用创建的constr2
元素。silly_type
constr1
上面的定义silly_type
在 coq 中无效,但我不知道如何在我不太愚蠢的示例中克服这一点。
不那么愚蠢的例子:
我试图有一个expr
表示类型表达式的归纳类型。
让我们首先从表示类型的归纳类型开始:
Inductive type : Type :=
| base_type : nat -> type
| arrow_type : type -> type -> type
| iso_arrow_type : type -> type -> type.
有一些用整数索引的基本类型,arrow_type
表示类型之间的函数和iso_arrow_type
表示类型之间的可逆函数。
符号:
Notation "A --> B" := (arrow_type A B) (at level 30, right associativity).
Notation "A <-> B" := (iso_arrow_type A B).
输入表达式:
Inductive expr : type -> Type :=
| var : forall (X : type) (n : nat), expr X
| eval : forall {X Y : type} (f : expr (X --> Y)) (x : expr X), expr Y
| inv : forall {X Y : type}, expr ((X <-> Y) --> (Y <-> X))
| to_fun : forall {X Y : type}, expr ((X <-> Y) --> (X --> Y))
| to_iso : forall {X Y : type} (f : expr (X --> Y)), (is_invertible f) -> expr (Y --> X).
您可以使用 来创建任何类型的索引变量,使用var
来评估函数eval
,使用 来反转可逆函数inv
,使用 将可逆函数转换为实际函数,to_fun
这样您就可以使用 来评估它eval
。
问题出在最后一个构造函数上to_iso
。有时,我会知道函数(的元素X --> Y
)实际上是可逆的,我想要一些机制将其转换为类型X <-> Y
。
但是,要定义is_invertible
我认为我需要使用eval
. 这让我想到了构造函数eval
需要在构造函数的定义中的问题to_iso
。
要定义is_invertible
,我们首先需要定义 的相等概念expr
:
Inductive ExprEq : forall (X : type), X -> X -> Prop :=
| expr_eq_refl : forall {X : type}, forall (x : X), ExprEq X x x
| eq_on_values : forall {X Y : type}, forall (f g : (X --> Y)), (forall (x : X), f[x] == g[x]) -> f == g
where
"x == y" := (ExprEq _ x y) and "f [ x ]" := (eval f x) and "x =/= y" := (not (ExprEq _ x y)).
因此,我们有标准的自反性x == x
,函数的相等性f==g
可以由所有元素的相等性来决定f[x]==g[x]
。
现在,我们准备好定义is_invertible
:
Definition is_invertible {X Y : type} (f : X --> Y) : Prop := exists g : Y --> X, (forall x, g[f[x]] == x) /\ (forall y, f[g[y]] == y).
这个定义is_invertible
是有问题的,它使用eval
(f[x] := (eval f x)
)。此外,问题有点复杂。我们需要定义ExprEq
已经用于eval
定义其构造函数的类型。
约束:保持expr
可判定
我真正想要保留的是equal( =
)expr
是可判定的,即能够证明
Lemma eq_expr_dec {X : type} (x y : type) : {x=y} + {x<>y}.
我真的不关心定义的相等==
性的可判定性,但可判定性=
对我来说很重要。
解决方案
您可以使用依赖类型来索引您的构造函数。例如
Inductive silly_type : nat -> Type :=
| constr1 : nat -> silly_type 0
| constr2 : silly_type 0 -> silly_type 1.
所以你只能在 constr2 中使用由 constr1 产生的值。这种方法通常可以区分使用不同构造函数创建的值。
推荐阅读
- javafx - 如何提高 JavaFX 中 TableView 的性能
- json - 如何在某些 github 存储库中执行唤醒命令?
- python - 使用 genfromtxt 加载数据时如何替换值
- python-3.6 - 在目录中递归查找给定文件
- angular - 以角度将数据从图像提取到文本
- python - Python,将 1d 数据投影和插值到 3d 网格(头部表面脑电图功率)
- python - Numpy 数组元素与 Float64 的比较
- javascript - 如何使用 Word API/Office JS 实现单词在拼写错误期间显示的红色曲线?
- api - Jmeter中GET请求的可变路径参数
- c# - 组合框列表更改时属性值更改为空(WPF)