资讯动态

Rocq Prover `Arguments` 命令完全指南:隐式参数、记号作用域与化简行为控制

发布时间:2026/10/13 6:09:16 来源:尧图企业网站定制
形式化验证编程语言【免费下载链接】coqThe Rocq Prover is an interactive theorem prover, or proof assistant. It provides a formal language to write mathematical definitions, executable algorithms and theorems together with an environment for semi-interactive development of machine-checked proofs.项目地址https://gitcode.com/gh_mirrors/co/coq点击查看免费下载Arguments是 Rocq Prover即 Coq 的延续项目中用于在常量、归纳类型或构造子定义完成后调整其参数属性的核心命令。它提供对 elaborationGallina 语言扩展向内核核心语言的翻译过程的细粒度控制具体包括将参数声明为隐式、把参数绑定到指定记号作用域notation scope、控制simpl/cbn等化简策略对该常量的展开行为以及提供双向类型检查bidirectionality提示。读完本文你将掌握Arguments的完整语法、各类修饰符的语义、手动与自动隐式参数声明方法以及如何借助源码实现理解其底层机制。命令概览与完整语法Arguments命令作用于已定义完成的函数引用reference可以是常量、归纳类型、构造子或全局变量其完整语法如下Arguments reference {* arg_specs } {* , {* implicits_alt } } {? : {, args_modifier } }其中各个语法单元定义如下arg_specs :: argument_spec | / | | ( { argument_spec } ) {* scope_delimiter } | [ { argument_spec } ] {* scope_delimiter } | %{ { argument_spec } %} {* scope_delimiter } argument_spec :: {? ! } name {* scope_delimiter } implicits_alt :: name | [ { name } ] | %{ { name } %} args_modifier :: simpl nomatch | simpl never | clear simpl | default implicits | clear implicits | clear scopes | clear bidirectionality hint | rename | assert | extra scopes | clear scopes and implicits | clear implicits and scopes该命令的功能包括四个方面声明隐式参数被声明为隐式的参数在之后任何应用reference的表达式中都必须省略绑定记号作用域声明函数的某些参数应在指定的 notation scope 中解释影响展开行为控制simpl与cbn策略何时展开该函数详见下文“对展开的影响”一节提供双向性提示通过指定参数类型检查的顺序详见下文“双向性提示”一节。从语法层面看该命令的解析实现在 vernac/g_vernac.mlgarg_specs中的[ ... ]将内层参数标记为NonMaxImplicit非最大插入的隐式参数{ ... }标记为MaxImplicit最大插入的隐式参数而(、)包裹的参数保持Explicit显式状态args_modifier则被解析为SimplDontExposeCase、SimplNeverUnfold、ClearReduction、DefaultImplicits、ClearImplicits、ClearScopes、ClearBidiHint、Rename、Assert、ExtraScopes等内部标记其中clear scopes and implicits与clear implicits and scopes等价均展开为两个标记的组合。命令最终进入VernacArguments语法树节点由 vernac/vernacentries.ml 分派给 vernac/comArguments.ml 中的vernac_arguments处理函数执行。作用域local / global 属性Arguments支持local与global属性attribute。默认行为是将效果限制在当前 section 内同时把效果延伸到当前模块或库文件之外。具体来说添加local若命令不在 section 中则把效果限制在当前模块内添加global若命令位于 section 内则把效果延伸到当前 section 及当前模块之外。这一机制在源码中体现为section_local标志的传递vernac/comArguments.ml 中无论是参数重命名Arguments_renaming.rename_arguments、作用域声明Notation.declare_arguments_scope、隐式参数设置Impargs.set_implicits/Impargs.declare_implicits、化简行为设置Reductionops.ReductionBehaviour.set ~local还是双向性提示的注册都显式携带section_local参数而interp/impargs.ml中的is_local函数local || isVarRef ref Global.is_in_section ref则决定了声明以ImplLocal局部方式还是作为可交互的Lib.add_leaf全局对象进入库对象系统。参数规格arg_specs详解arg_specs中的每个单元都有特定语义逐一说明如下。/指定展开所需的最小应用参数个数/表示该函数只有在被应用了/之前的全部参数之后才被展开。例如Arguments f a b /之后(f a b)会被展开而(f a)保持原样。参见下文“对展开的影响”。注意The / modifier may only occur once./修饰符最多出现一次——这一限制在 vernac/comArguments.ml 中通过检查Option.has_some red实现若重复出现会直接抛出该用户错误。双向类型检查的分界点告诉类型检查算法先对之前的参数做类型检查然后把该类型检查上下文中的信息传播下去用于检查剩余参数。同样最多出现一次The modifier may only occur once.对应 vernac/comArguments.ml 的检查。详见下文“双向性提示”。( name ... )带作用域的显式参数简写:n:( name__1 name__2 ... ){* %scope }是name__1{* %scope } name__2{* %scope } ...的简写即括号内的每个参数都追加相同的%scope 作用域后缀参数本身保持显式。[ name ... ]声明非最大插入的隐式参数[ name__1 name__2 ... ]{* %scope }把括号内的名字声明为**非最大插入non-maximally inserted**的隐式参数它等价于逐个写[ name__1 ]{* %scope } [ name__2 ]{* %scope } ...。{ name ... }声明最大插入的隐式参数{ name__1 name__2 ... %}{* %scope }把括号内的名字声明为**最大插入maximally inserted**的隐式参数等价于{ name__1 %}{* %scope } { name__2 %}{* %scope } ...。最大插入意味着当函数被部分应用且下一个参数是隐式参数时Rocq 会自动为该隐式参数插入一个元变量existential variable而不是必须由使用者显式省略。这两种插入模式在 interp/impargs.ml 中体现为NonMaxImplicit - Some { impl_max false; ... }与MaxImplicit - Some { impl_max true; ... }其中impl_max字段正是是否最大插入的标志在 vernac/g_vernac.mlg 中[与{两种括号分别被映射为NonMaxImplicit与MaxImplicit状态。!递归参数标记!标记某个参数为递归参数表示该函数仅当所有用!标记的参数都归约到构造子constructor时才展开。参见下文对展开的影响。源码中!对应的recarg_like标志被收集为索引列表rargsvernac/comArguments.ml最终作为UnfoldWhen/UnfoldWhenNoMatch行为中when_flags.recargs的一部分。name {* %_ scope }形式参数与作用域绑定name是函数reference的一个形式参数即函数定义中使用的参数名。除非指定了rename否则name列表必须是形式参数含全部隐式参数的一个前缀_可用于跳过某个形式参数。该构造把name声明为非隐式参数前提是clear implicits被指定、或本Arguments命令中的其他name被声明为隐式。scope可以是作用域名或它们的定界键delimiting key当存在多个作用域时记号按最左侧包含它的作用域解释参见下文绑定参数到作用域。需要特别说明的弃用项% scope语法自 8.19 起弃用改为语义上等价的%_ scope未来版本会恢复% scope在项term中的语义即把作用域压入整个子项的作用域栈。这一变更在 vernac/comArguments.ml 中以argument-scope-delimiter警告的形式实现默认级别为AsError警告文本甚至给出了一行sed迁移脚本对*.v文件在Arguments行中把%替换为%_。该构造还可能触发以下错误均定义在 vernac/comArguments.ml 中To rename arguments the rename flag must be specified.提供了重命名但未加rename标志对应源码 L217-L226 的检查Flag rename expected to rename name into name.重命名目标名不符Arguments of section variables such as name may not be renamed.section 变量的参数不允许重命名修饰符args_modifier详解冒号:之后可以逗号分隔地列出多个修饰符clear implicits把所有隐式参数变回显式参数。注意The clear implicits flag must be omitted if implicit annotations are given.如果给出了隐式标注则必须省略此标志——对应源码 vernac/comArguments.ml 的兼容性检查。default implicits自动确定该对象的隐式参数详见下文自动声明隐式参数。The default implicits flag is incompatible with implicit annotations.与隐式标注不兼容。rename为对象重命名隐式参数详见重命名隐式参数。assert断言对象具有预期的参数个数与参数名详见重命名隐式参数中的示例。此修饰符对应warn_arguments_assert警告vernac/comArguments.ml当Arguments命令既没有重命名、隐式声明、作用域声明、化简行为修改也没有任何标志时会提示This command is just asserting the names of arguments of qualid. If this is what you want, add : assert to silence the warning. If you want to clear implicit arguments, add : clear implicits. If you want to clear notation scopes, add : clear scopes——即一个无操作的Arguments命令会被当作断言处理并给出警告添加: assert可消除该警告。clear scopes清除reference的参数作用域。extra scopes定义额外的参数作用域用于发生到Funclass的强制coercion或类型为计算所得computed type的情形参见 隐式强制文档。simpl nomatch阻止reference的化简步骤把match构造暴露在头部位置详见对展开的影响。simpl never完全阻止对reference执行化简步骤详见对展开的影响。clear simpl重置此前对化简步骤的修改即取消此前所有的simpl never、simpl nomatch、/和!。clear bidirectionality hint移除双向性提示即。修饰符之间的兼容性检查在 vernac/comArguments.ml 与 L248-L274 中统一实现例如assert与rename不兼容、clear scopes与extra scopes不兼容、clear implicits与default implicits不兼容、clear simpl与simpl never/simpl nomatch/!//各自不兼容、simpl never与simpl nomatch/!//不兼容、clear bidirectionality hint与不兼容。化简行为的最终组合被归结为pretyping/reductionops.ml中ReductionBehaviour模块的三种类型reductionops.mlNeverUnfold、UnfoldWhen { recargs; nargs }与UnfoldWhenNoMatch { recargs; nargs }其中recargs记录!标记的参数位置nargs记录/之前参数的个数。多重隐式参数替代implicits_alt:n:implicits_alt用于为**只能应用于固定数量参数**的函数指定替代的隐式参数声明例如排除类型为多态的函数。语法上多个替代以逗号,分隔每个替代形如name、[ { name } ]或%{ { name } %}。选择规则如下解析parsing时使用与函数应用匹配的最长隐式参数列表来决定插入哪些隐式参数打印printing时使用隐式参数最多的替代若Printing Implicit标志未设置则隐式参数会被省略。在 interp/impargs.ml 的实现中多个替代被按隐式参数个数降序排序、检查序列长度必须互不相同check_inclusion并要求引用对象必须是刚性的check_rigidity否则报错Multiple sequences of implicit arguments available only for references that cannot be applied to an arbitrarily large number of arguments.每个替代最终以LessArgsThan (nargs-n)的键存入隐式参数数据库。map的完整示例见下文。查看当前设置可以使用About命令查看某个reference当前的隐式参数设置或使用Print Implicit命令查看对象的隐式参数详情参见 隐式参数文档中的显示隐式参数章节。手动声明隐式参数假设我们有如下定义Inductive list (A : Type) : Type : | nil : list A | cons : A - list A - list A. Check (cons nat 3 (nil nat)). Arguments cons [A] _ _. Arguments nil {A}. Check (cons 3 nil). Fixpoint map (A B : Type) (f : A - B) (l : list A) : list B : match l with nil nil | cons a t cons (f a) (map A B f t) end. Fixpoint length (A : Type) (l : list A) : nat : match l with nil 0 | cons _ m S (length A m) end. Arguments map [A B] f l. Arguments length {A} l. (* A has to be maximally inserted *) Check (fun l:list (list nat) map length l).逐步解读Arguments cons [A] _ _.将cons的类型参数A声明为非最大插入的隐式参数后面的_依次跳过x与l两个显式参数即保持它们显式。此后Check (cons 3 nil).不再需要写出nat。Arguments nil {A}.将nil的唯一参数A声明为最大插入的隐式参数因此nil可以在cons 3 nil中被直接使用。Arguments map [A B] f l.map的两个类型参数A B为隐式f l保持显式。Arguments length {A} l.length的A必须最大插入因为length的类型是forall A : Type, list A - natA出现在末尾的nat之外只能靠上下文推断若不大最大插入部分应用时无法自动补全。多重替代示例Arguments map [A B] f l, [A] B f l, A B f l. Check (fun l map length l map (list nat) nat length l).这里为map声明了三组替代[A B] f l两个隐式参数、[A] B f l一个隐式参数、A B f l全显式。打印时选用隐式参数最多的[A B] f l因此左边map length l中length的A由l : list (list nat)推断而右边map (list nat) nat length l则显式给出了两个类型参数两者被判定为可转换convertible。需要注意的是从实现角度这种多替代机制不太自然与部分应用配合不佳——impargs.ml 中对多替代要求严格的序列长度互异与刚性检查即是其局限性的体现。自动声明隐式参数default implicits:n:default implicits 修饰符让 Rocq **自动确定**对象的隐式参数。自动检测受若干标志控制决定是否考虑严格strict、上下文contextual或可逆模式reversible-pattern隐式参数参见 [隐式参数文档](https://link.gitcode.com/i/16e66e0656b4379e2e10899b86e2489d#L270-L308) 中关于Strict Implicit、Contextual Implicit、Reversible Pattern Implicit与Maximal Implicit Insertion 标志的说明。Inductive list (A:Set) : Set : | nil : list A | cons : A - list A - list A. Arguments cons : default implicits. Print Implicit cons. Arguments nil : default implicits. Print Implicit nil. Set Contextual Implicit. Arguments nil : default implicits. Print Implicit nil.默认情况下cons的类型参数A作为严格隐式参数会被自动识别nil的唯一参数A是上下文隐式参数只能从应用环境的期望类型推断默认不被声明为隐式。而执行Set Contextual Implicit之后再次Arguments nil : default implicitsA就会被自动声明为隐式参数。实现上default implicits调用 interp/impargs.ml 的declare_implicits它读取全局的implicit_args标志记录{ !implicit_args with auto true }并调用compute_global_implicits完成自动计算而Set Contextual Implicit等标志正是这个记录中contextual、revpattern、maximal、strict等字段的开关。隐式参数计算考虑常量的展开隐式参数的计算会考虑常量的展开。例如下面这个经典的传递性例子Parameter X : Type. Definition Relation : X - X - Prop. Definition Transitivity (R:Relation) : forall x y:X, R x y - forall z:X, R y z - R x z. Parameters (R : Relation) (p : Transitivity R). Arguments p : default implicits. Print p. Print Implicit p. Parameters (a b c : X) (r1 : R a b) (r2 : R b c). Check (p r1 r2).变量p的类型是(Transitivity R)它可归约为forall x,y:U, R x y - forall z:U, R y z - R x z。由于x、y、z严格出现在类型体中default implicits会把它们全部判定为隐式参数因此Check (p r1 r2).合法——Rocq 能根据r1 : R a b与r2 : R b c反向推断出x a、y b、z c。重命名隐式参数rename 与 assert承接上例我们可以为p的隐式参数起新的名字Arguments p [s t] _ [u] _: rename. Check (p r1 (u:c)). Check (p (s:a) (t:b) r1 (u:c) r2). Fail Arguments p [s t] _ [w] _ : assert.Arguments p [s t] _ [u] _ : rename.把前两个隐式参数分别重命名为s、t第三个隐式参数重命名为u两个_保持显式参数。加了rename之后就可以用(u:c)这种命名实参named arguments按名字传参。第二条Check演示了同时用名字与位置混合传参。第三条Fail ... : assert演示了assert的用途它只是断言参数名与个数与预期一致这里把u写成了w与真实重命名后的名字不符因此命令失败这正是 vernac/comArguments.ml 中rename递归检查两列名字并收集重命名对的逻辑w与既有名不一致且无rename标志时直接报错。重命名的底层存储由Arguments_renaming模块负责vernac/comArguments.ml 调用Arguments_renaming.rename_argumentsprev_names通过Arguments_renaming.arguments_names读取若尚未重命名则回退到从类型计算出的原始名inf_names。绑定参数到作用域scopesArguments plus_fct (f1 f2)%_F x%_R%_F.该命令声明plus_fct的前两个参数在定界键F对应的作用域中解释第三个参数先尝试作用域R、再尝试F当某个记号在R中没有解释时。解释规则当解释一个项时如果reference的某些参数由记号notation构造则该记号在由绑定作用域扩展后的作用域栈中解释。这些作用域的效果仅限于该参数本身不会传播到子项但那些在记号解释后、恰好又成为某个引用参数的子项会按照该引用绑定的参数作用域来解释。记号内标识符的解释时机在记号中匹配记号标识符的子项在记号声明时标识符所处的作用域中解释。下面的例子完整演示了这一语义Parameter g : bool - bool. Declare Scope mybool_scope. Notation : true (only parsing) : bool_scope. Notation : false (only parsing): mybool_scope. Bind Scope bool_scope with bool. Notation x : (g x). Check . Arguments g _%_mybool_scope. Check . Delimit Scope mybool_scope with mybool. Check %mybool .解读 是记号(g x)的实例。记号的参数在声明 x 时处于全局作用域中该记号声明时没有指定作用域因此第一次Check 中在bool_scope中解释为trueArguments g _%_mybool_scope.把g的参数绑定到mybool_scope。此后 的参数作为g的参数按绑定作用域在mybool_scope中解释为falseDelimit Scope mybool_scope with mybool.之后 %mybool 中%mybool显式指定作用域结果也解释为false。实现上作用域绑定由 interp/notation.ml 的Notation.declare_arguments_scope注册进 notation 系统vernac/comArguments.ml 会先把作用域键解析为真实作用域对象Notation.find_scope/Notation.find_delimiters_scope并检测其中是否包含无界定界符以触发 8.19 弃用警告。实际开发中这种按参数绑定作用域的写法在数学库里极为常见例如 test-suite/bugs/HoTT_coq_029.v 中对Object、Morphism、Identity、Compose的参数分别绑定了%_type、%_category、%_object、%_morphism等作用域并与!、rename组合使用。对展开的影响simpl / cbn 行为这是Arguments命令最容易被低估的能力之一它可以精确控制simpl、cbn甚至hnf何时展开某个常量。pretyping/reductionops.ml中的ReductionBehaviour模块reductionops.ml用一张Cpred.t * t QConstant.Map.t的表记录每个常量的展开行为NeverUnfold常量存放在Cpred集合中以支持快速查询其余行为以UnfoldWhen/UnfoldWhenNoMatch形式存入映射。下面逐一说明四种行为模式。simpl never永不展开Arguments Nat.sub n m : simpl never.该命令之后形如(Nat.sub (S x) y)的表达式不会被cbn或simpl触碰Nat.sub处于头部位置。但要注意simpl的一个例外该修饰符不适用于match、fix、原语投影primitive projection的主参数化简也不适用于隐藏着 match/fix/原语投影的可展开常量的主参数化简。因此Arguments Nat.sub n m : simpl never.之后(Nat.sub (S x) 0) 1仍会被simpl化为S (x 1)因为此处Nat.sub是的主参数化简发生在的递归机制内部而非直接展开Nat.sub。/只有应用足够多参数时才展开Definition fcomp A B C f (g : A - B) (x : A) : C : f (g x). Arguments fcomp {A B C} f g x /. Notation f \o g : (fcomp f g) (at level 50).(f \o g)即fcomp f g只应用了/之前的两个参数被simpl保持原样((f \o g) t)则被化简为(f (g t))。同样的机制还可以让一个常量总是展开volatileDefinition volatile : fun x : nat x. Arguments volatile / x.Arguments volatile / x中/前面没有参数nargs_for_red Some 0对应 reductionops.ml 打印行为中的{ recargs []; nargs Some 0 } - always unfold ...即无条件展开。/的位置还有一处源码约束The / modifier should be put before any extra scope./必须放在任何额外作用域之前。!参数归约为构造子时才展开Arguments minus !n !m.(minus (S x) y)保持不动y未归约为构造子(minus (S x) (S y))化简为(minus x y)两个参数都是构造子头部。!的实现是把recarg_like参数的索引收集进when_flags.recargs化简引擎在展开前检查这些位置的实参是否构造子头部。Rocq 内部甚至以此为基础实现了Nat.sub、minus这类按构造子递归、保护递归参数防止过早展开的标准策略。simpl nomatch避免暴露 match 头部Arguments minus n m : simpl nomatch.该命令之后(minus (S (S x)) (S y))被化简为(minus (S x) y)即使继续化简本可再多走一步——因为继续化简会暴露match构造于头部位置被nomatch禁止。simpl nomatch同时影响cbn、simpl与hnf三个策略。simpl 的内部化简顺序了解simpl的实现有助于理解上述行为simpl首先应用 βι-归约β 归约与 ι 归约即函数应用与 match/fix 的归约然后展开透明常量并尝试进一步 βι-归约但当展开后没有 ι 规则被应用时δ-归约常量展开不会被应用。例如对(plus n O) n使用simpl不会产生任何变化plus的递归需要匹配n但n是变量而非构造子。clear simpl修饰符则用于一键撤销以上所有化简相关设置simpl never、simpl nomatch、/、!并重置回默认行为None即完全按透明性展开对应 reductionops.ml 中_, false, false, [], None - None的分支。双向性提示bidirectionality hints背景单向类型检查的局限在类型检查一个应用时Rocq 通常不利用上下文信息来推断参数的类型只会在事后检查为该应用推断出的类型与期望类型是否一致。这意味着即便期望类型已经蕴含了某个参数的具体形态Rocq 也不会提前用它去帮助推断剩余参数。的语义一个包含arg_specs__1 arg_specs__2的Arguments命令提供双向性提示类型检查算法在检查qualid的应用时先类型检查arg_specs__1中的参数然后把来自类型检查上下文的信息传播下去用于类型检查arg_specs__2中的剩余参数。从实现上看该机制由 pretyping/pretyping.ml 中的bidi_hints摘要一个GlobRefMap值为之前参数个数支撑pretype_app在期望类型已知tycon非空时通过get_bidirectionality_hint查询全局引用对应的提示pretyping.ml当参数序号n nargs_before_bidi时该参数先被替换为一个存在性变量new_evar待之前的参数类型检查完成后再用这些信息统一求解pretyping.ml。提示只有在存在期望类型时才被应用We apply bidirectionality hints only if an expected type is specified。提示的注册在非 section 环境下通过inBidiHints库对象持久化vernac/comArguments.mlclear bidirectionality hint则注册一个None值来清除它。示例一与强制coercion配合Definition b2n (b : bool) : if b then 1 else 0. Coercion b2n : bool - nat.若没有提示Rocq 无法自动把关于bool的存在性陈述强制到关于nat的陈述因为插入强制的需求只有从子项的期望类型才能得知Fail Check (ex_intro _ true _ : exists n : nat, n 0).而加上合适的双向性提示后示例即可工作Arguments ex_intro _ _ _ _. Check (ex_intro _ true _ : exists n : nat, n 0).之前的_ _先被检查把期望类型是exists n : nat, n 0的信息传播到之后的参数从而在true处成功插入b2n强制。示例二不使用强制的数值比较Import Nat. Definition leb_implies_le {n m} (H : (n ? m) true) : n m. Proof. revert m H; induction n as [| n IH]; intros m; [intros _; exact (le_0_n _) |]. destruct m; intros [ H]; apply le_n_S, IH; exact H. Qed.可以用leb_implies_le来证明3 4在H的位置直接给出eq_refl而无需显式写出3 ? 4 true的证明。理论上Rocq 能利用期望类型3 4与定义中的n m推断出n 3、m 4但默认它不能把为某些参数推断出的值用于剩余参数的推断Fail Check leb_implies_le (eq_refl _) : 3 4.使用双向性提示后左侧参数推断出的值n 3、m 4被传播到右侧(?n ? ?m)得以归约为true从而让eq_refl通过检查Arguments leb_implies_le n m H. Check leb_implies_le (eq_refl _) : 3 4.注意事项Program 模式下的项改写Rocq 会尽量使用你提供的参数构造项但在某些涉及Program 模式的情形下之后双向性提示起点之后的参数可能被替换为可转换但句法上不同的项。这是使用双向性提示时需要注意的语义细节也是 Rocq 官方文档明确标注的已知行为。从源码看Arguments的完整执行流程综合 vernac/comArguments.ml 的vernac_arguments一条Arguments命令的处理可归纳为五个阶段标志解析与兼容性检查读取assert、rename、clear scopes、extra scopes、clear implicits、default implicits、simpl never、simpl nomatch、clear simpl、clear bidirectionality hint等标志并逐对检查互斥组合comArguments.ml参数规格扫描遍历arg_specs收集!标记recarg_like、/位置nargs_for_red与位置nargs_before_bidi三者各有只能出现一次的约束comArguments.ml名字与个数校验把用户提供的参数名与从全局类型计算出的形式参数名列表对齐处理_跳过、检测多余参数err_extra_args、未声明参数err_missing_args以及重命名需求comArguments.ml行为组合把simpl相关修饰符、!、/组合为ReductionBehaviour.tNeverUnfold/UnfoldWhen/UnfoldWhenNoMatchcomArguments.ml副作用写入依次执行参数重命名、作用域声明、隐式参数设置手动Impargs.set_implicits或自动Impargs.declare_implicits、化简行为注册ReductionBehaviour.set、双向性提示注册Pretyping.add_bidirectionality_hint或通过Lib.add_leaf持久化comArguments.ml。这些副作用大部分以库对象的形式进入 Rocq 的持久化机制Lib.add_leaf这意味着它们会随模块导出、被Require加载的库继承也解释了默认把效果延伸到当前模块之外的行为。结语Arguments命令是 Rocq 日常形式化开发中高频使用、但语义细节丰富的核心命令。它的四个维度——隐式参数声明手动/自动/多重替代、参数-作用域绑定、化简行为控制simpl never、/、!、simpl nomatch与双向性提示——分别对应 elaboration、notation 系统、归约引擎与类型检查器四个子系统。理解其语法与修饰符组合规则尤其是各修饰符之间的互斥约束有助于避免常见的参数未声明缺少 rename 标志修饰符不兼容等报错而结合 vernac/comArguments.ml、interp/impargs.ml、pretyping/reductionops.ml 与 pretyping/pretyping.ml 等源码则可以更精确地预判每一条Arguments命令的实际效果。在日常开发中善用About与Print Implicit检查对象的隐式参数状态是调试相关问题的第一步。赞分享形式化验证编程语言【免费下载链接】coqThe Rocq Prover is an interactive theorem prover, or proof assistant. It provides a formal language to write mathematical definitions, executable algorithms and theorems together with an environment for semi-interactive development of machine-checked proofs.项目地址https://gitcode.com/gh_mirrors/co/coq点击查看免费下载相关推荐Rocq 隐式参数Implicit Arguments完全指南声明、自动推断与实战控制Rocq 隐式参数Implicit Arguments完全指南声明、自动推断与实战控制 隐式参数Implicit Arguments是 Rocq Pr形式化验证编程语言Rocq Prover 变更详解About 命令现在展示 Abbreviation 参数的符号作用域Rocq Prover 变更详解About 命令现在展示 Abbreviation 参数的符号作用域 本篇指南解析 Rocq ProverCoq 的继任者形式化验证编程语言Rocq Prover 命令行工具完全指南命令体系、参数解析与系统配置Rocq Prover 命令行工具完全指南命令体系、参数解析与系统配置 Rocq ProverCoq 证明助手的新一代命名通过 rocq 一个统一入口对外形式化验证编程语言上一篇如何在10分钟内掌握Taichi GPU编程Python性能提升100倍的完整指南下一篇如何快速掌握Babel从语法解析到插件开发的完整指南 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑