Coq 克服在其他构造函数的定义中使用构造函数的需要
很可能我试图实现一些有缺陷的东西,但是我遇到了一个需要在另一个构造函数的定义中有一个构造函数的情况 愚蠢的例子: 有两种方法可以创建Coq 克服在其他构造函数的定义中使用构造函数的需要,coq,Coq,很可能我试图实现一些有缺陷的东西,但是我遇到了一个需要在另一个构造函数的定义中有一个构造函数的情况 愚蠢的例子: 有两种方法可以创建silly_type元素,一种是使用自然数和constr1,另一种是使用constr2和silly_type元素创建constr1 上面的silly_type定义在coq中无效,但我不知道如何在我不那么愚蠢的示例中克服这一点 不那么愚蠢的例子: 我试图得到一个表示类型表达式的归纳类型expr 让我们首先从表示类型的归纳类型开始: Inductive type : T
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\u type
表示类型之间的函数,iso\u arrow\u type
表示类型之间的可逆函数
符号:
Notation "A --> B" := (arrow_type A B) (at level 30, right associativity).
Notation "A <-> B" := (iso_arrow_type A B).
因此,我们有标准的自反性x==x
,函数的相等性f==g
可以由所有元素的相等性f[x]==g[x]
决定
现在,我们准备好定义是可逆的
:
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).
的这个定义是可逆的
是有问题的,它使用的是eval
(f[x]:=(eval f x)
)。此外,问题要复杂一些。我们需要定义类型ExprEq
,该类型已经使用eval
来定义其构造函数
约束:保持expr
可判定
我真正想保留的是,expr
的等式(=
)是可判定的,即能够证明
Lemma eq_expr_dec {X : type} (x y : type) : {x=y} + {x<>y}.
引理eq_expr_dec{X:type}(xy:type):{X=y}+{xy}。
我真的不关心定义的等式的可判定性
=
,但是=
的可判定性对我来说很重要。您可以使用依赖类型来索引构造函数。比如说
Inductive silly_type : nat -> Type :=
| constr1 : nat -> silly_type 0
| constr2 : silly_type 0 -> silly_type 1.
因此,您只能在constr2中使用constr1生成的值。一般来说,这种方法可以区分使用不同构造函数创建的值。常见的做法是避免语法和语义的混合,而恰恰是避免遇到循环性问题。你描述
的方式是可逆的
似乎很有语义,所以你有没有考虑过不按语法编码,接受部分语义?@李耀霞是的,我也在考虑。现在,我正在探索不同的方法来做这件事。@李耀霞如果我理解正确,你是否建议从到iso的定义中省略是可逆的?然后,在处理表达式时,检查to_iso
的所有用法是否有效?没错!这就是我的建议。
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).
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.