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.