我喜欢自己的范围,可以使用长不确定性。
Declare Scope my_scope.
Delimit Scope my_scope with my.
Open Scope my_scope.
Definition f (x y a b : nat) : nat := x+y+a+b.
Notation "x < y * a = b" := (f x y a b)
(at level 100, no associativity) : my_scope.
Check (1 < 2 * 3 = 4)%my.
你如何制作新的范围?
编辑:我选择“x&lt; y * a = b”来覆盖Coq的运算符(每个运算符具有不同的优先级)。
答案 0 :(得分:2)
命令Declare Scope
不存在。有关范围的各种命令在section 12.2 of the Coq manual中进行了描述。
您选择的示例符号存在固有问题,因为它与预定义符号冲突,这些符号似乎在您的符号之前使用。
当查看解析器看到_ < _
的第一个组件并认为您实际上是在谈论整数的比较时,它会将第二个部分看作是符号_ * _
的一个实例,然后它看到所有这一切都是平等的左手边。整个解析器都很开心,它构造了一个表达式:
(1 < (2 * 3)) = 4
这是由解析器构造的,尚未征求类型系统。类型检查器将自然数视为(_ < _)
的第一个孩子并且很高兴。它认为(_ * _)
是第二个孩子,它很高兴,它现在知道该产品的第一个孩子应该是一个nat号,它仍然很开心;最后它有一个相等,这个相等的第一个组件是Prop
类型,但第二个组件是nat
类型。
如果您输入Locate "_ < _ * _ = _".
,则答案会告诉您确实定义了新的表示法。问题是这种表示法永远不会被使用,因为解析器总是找到它之前可以使用的另一种表示法。理解为什么符号优先于另一个符号需要更多的解析技术知识,正如Coq手册第12章中所提到的那样(对我来说模糊):
Coq可扩展解析由Camlp5执行,Camlp5本质上是一个LL1解析器。
您必须选择各种变量的级别x
,y
,a
和b
,以便这些变量都不会匹配很多文字。例如,我尝试定义一个靠近你的符号,但是带有一个开始和一个结束括号(我猜这大大简化了任务)。
Notation "<< x < y * a = b >>" := (f x y a b)
(x at level 59, y at level 39, a at level 59) : my_scope.
选择x
级别低于=
级别,选择y级别低于*
级别a
级别=
1}}被选择为低于Print Grammar constr.
。通过阅读命令Check << 1 < 2 * 3 = 4 >>.
的答案获得级别。它似乎有效,因为接受以下命令。
{{1}}
但是你可能需要加一点工程才能有一个非常好的符号。
答案 1 :(得分:0)
回答标题中的实际问题:
当您声明使用它的表示法时,会创建新作用域。也就是说,您不单独声明新范围my_scope
。你只需写
Notation "x <<< y" := (f x y) (at level 100, no associativity) : my_scope.
并声明了新范围my_scope
。