英文:
Syntax error: '.' expected after [vernac:gallina] (in [vernac_aux]) in Coq when using inductive with integers
问题
"Syntax error: '.' expected after [vernac:gallina] (in [vernac_aux])." -> "语法错误:在 [vernac:gallina] 中期望'.'。"
英文:
So I'm trying to define an inductive set in coq that has integers from 0 to 10:
Inductive OD : Set := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10.
I get this message:
Syntax error: '.' expected after [vernac:gallina] (in [vernac_aux]).
Nothing I tried has really worked
答案1
得分: 1
Unfortunately the parser is expecting a constructor not a number after :=
. You can bypass this using Notation
.
Inductive OD : Set := N0 | N1 | N2 | N3 | N4 | N5 | N6 | N7 | N8 | N9 | N10.
Notation "0" := N0.
Notation "1" := N1.
Notation "2" := N2.
Notation "3" := N3.
Notation "4" := N4.
Notation "5" := N5.
Notation "6" := N6.
Notation "7" := N7.
Notation "8" := N8.
Notation "9" := N9.
Notation "10" := N10.
英文:
Unfortunately the parser is expecting a constructor not a number after :=
. You can bypass this using Notation
.
Inductive OD : Set := N0 | N1 | N2 | N3 | N4 | N5 | N6 | N7 | N8 | N9 | N10.
Notation "0" := N0.
Notation "1" := N1.
Notation "2" := N2.
Notation "3" := N3.
Notation "4" := N4.
Notation "5" := N5.
Notation "6" := N6.
Notation "7" := N7.
Notation "8" := N8.
Notation "9" := N9.
Notation "10" := N10.
答案2
得分: 0
你的问题涉及不同性质的对象。当你说“一个归纳类型,包含从0到10的整数”时,实际上描述的是一种不可能的情况。
归纳类型的本质是,它们的元素与任何其他类型的元素都不同。因此,你可以决定定义一个包含十一个元素的归纳类型,以一种方式命名,使其提醒人们0到10的11个整数,但你希望定义的这个新的归纳类型实际上并不包含这些整数。换句话说,整数0到10不是这种类型的成员。
因此,第一个解决方案是Lolo在另一个答案中提出的解决方案,如下所示:
Inductive OD : Set := N0 | N1 | N2 | N3 | N4 | N5 | N6 | N7 | N8 | N9 | N10.
然而,元素N0
到N10
不是整数,它们是类型OD
的元素。你不能在需要整数的操作中使用它们。
这是类型理论(Type Theory)与集合论(set theory)之间的固有差异,类型理论是Coq系统的基础理论,而人们在进行数学实践时通常使用的是集合论。
为了减小类型OD
与整数之间的差距,有另一种方法,不同于上面显示的表示方法。我们可以提供类型整数和类型OD之间的强制转换。以下是我的解决方案:
Open Scope Z.
Definition Z_of_OD (x : OD) :=
match x with
N0 => 0
| N1 => 1
| N2 => 2
| N3 => 3
| N4 => 4
| N5 => 5
| N6 => 6
| N7 => 7
| N8 => 8
| N9 => 9
| N10 => 10
end.
Coercion Z_of_OD : OD >-> Z.
Check ( 135 + N0).
Definition OD_of_Z (x : Z) :=
match x with
0 => N0
| 1 => N1
| 2 => N2
| 3 => N3
| 4 => N4
| 5 => N5
| 6 => N6
| 7 => N7
| 8 => N8
| 9 => N9
| _ => N10
end.
Coercion OD_of_Z : Z >-> OD.
Check 8 : OD.
正如你可以看到的,通过这两个Check
命令,你现在有了一个包含11个元素的类型OD
,它关联到整数(但它们不是整数),这要归功于提供的两个强制转换Z_of_OD
和OD_of_Z
。借助这些强制转换,任何整数都可以视为OD
的元素,整数范围外的整数被映射到N10
。因此,你可以在期望整数的地方使用类型OD
的对象,也可以在期望OD
的元素的地方使用类型Z
的对象。
在实际应用中,Coq系统保持了这种区别,所以OD
没有整数0
到10
,但在日常使用中,这模拟了你想要的效果,我相信。
例如,你可以定义一个将OD
的元素映射到循环的后继的函数。
Definition OD_succ (x : OD) :=
match x with
N0 => N1
| N1 => N2
| N2 => N3
| N3 => N4
| N4 => N5
| N5 => N6
| N6 => N7
| N7 => N8
| N8 => N9
| N9 => N10
| N10 => N0
end.
函数OD_succ
需要一个类型为OD
的参数,并返回类型OD
的结果,但我们可以编写以下表达式:
Compute (1 + OD_succ 10).
这返回1,因为:
- 10不是类型为
OD
的,所以10
被替换为OD_of_Z 10
OD_of_Z
计算为N0
OD_succ (OD_of_Z 10)
不是整数,因此不能在整数操作中使用,它被替换为Z_of_OD (OD_succ (OD_of_Z 10)
Z_of_OD (OD_succ (OD_of_Z 10)
的计算返回整数0- 1 + 0的计算返回整数1。
另一方面,如果要求
Compute OD_succ 10.
结果具有类型OD
,显示为N0
。因此,Coq系统保持了类型之间的区别。这些强制转换只是使这种区别更加方便。
英文:
Your question mixes objects of a different nature. When you say "an inductive type that has integers from 0 to 10", you are actually describing a situation that is impossible.
It is the nature of inductive types that their elements are distinct from elements of any other types. So you can decide to define an inductive with eleven elements, named in a way that reminds of the 11 integers 0 to 10, but this new inductive you wish to define does not have these integers. In other words, the integers 0 to 10 are not members of this type.
So a first solution is the one presented by Lolo in a different answer, repeated here:
Inductive OD : Set := N0 | N1 | N2 | N3 | N4 | N5 | N6 | N7 | N8 | N9 | N10.
However, the elements N0
.. N10
are not integers, they are elements of type OD
. You cannot use them in operations that require integers.
This an inherent difference between Type Theory, the theory that underlies the Coq system and set theory, the theory that people are accustomed to use when performing practicing mathematics.
To reduce the gap between type OD
and integers, there is another approach than the notation approach shown above. We can provide coercions between the type of integers and and the type OD. Here is my solution:
Open Scope Z.
Definition Z_of_OD (x : OD) :=
match x with
N0 => 0
| N1 => 1
| N2 => 2
| N3 => 3
| N4 => 4
| N5 => 5
| N6 => 6
| N7 => 7
| N8 => 8
| N9 => 9
| N10 => 10
end.
Coercion Z_of_OD : OD >-> Z.
Check ( 135 + N0).
Definition OD_of_Z (x : Z) :=
match x with
0 => N0
| 1 => N1
| 2 => N2
| 3 => N3
| 4 => N4
| 5 => N5
| 6 => N6
| 7 => N7
| 8 => N8
| 9 => N9
| _ => N10
end.
Coercion OD_of_Z : Z >-> OD.
Check 8 : OD.
As you can see with the two Check
commands, you now have a type OD
containing 11 elements, which associated to integers (but they are not integers) thanks to the two provided coercions Z_of_OD
and OD_of_Z
. Thanks to these coercions, any integer can be viewed as an element of OD
, the integers that are outside the range of OD
being mapped to N10
. So you can use an object of type OD
where you would expect an integer and you can use an object of type Z
where you would expect an element of OD
.
In practice, the Coq system maintain the distinction, so that OD
does not have the integers 0
to 10
, but in day-to-day usage, this simulates what you want, I believe.
For instance you can define a function that maps the elements of OD
to a circular notion of successor.
Definition OD_succ (x : OD) :=
match x with
N0 => N1
| N1 => N2
| N2 => N3
| N3 => N4
| N4 => N5
| N5 => N6
| N6 => N7
| N7 => N8
| N8 => N9
| N9 => N10
| N10 => N0
end.
The function OD_succ
requires an argument of type OD
and returns a result in type OD, but we can write the following expression:
Compute (1 + OD_succ 10).
This returns 1 because
- 10 is not of type
OD
, so10
is replaced byOD_of_Z 10
OD_of_Z
computes toN0
OD_succ (OD_of_Z 10)
is not an integer, so it cannot be used in an integer operation, it is replaced byZ_of_OD (OD_succ (OD_of_Z 10)
- the computation of
Z_of_OD (OD_succ (OD_of_Z 10)
returns the integer 0 - the computation of 1 + 0 returns the integer 1.
On the other hand, if require
Compute OD_succ 10.
The result has type OD
and is displayed as N0
. So the distinction between types is maintained by the Coq system. The coercions simply makes this distinction more comfortable to live with.
This approach still has some drawbacks, for instance, we need a little more work to talk about the subset of integers that corresponds to OD
, but there are other solutions for this. If you want to go in that direction, I suggest you study the treatment of finite types and intial segments of the natural numbers (named ordinal
types) in the library mathematical components
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论