2 句法范畴
2.1 指令范畴
2.1.1 定义与声明
-
定义与声明的相关解析器
-
declId:可能跟随宇宙名称列表的标识符,形如foo或foo.{u,v} -
declSig与optDeclSig:常量声明时的(可选)参数列表与类型标注,形如[...] : type -
declVal:声明的右半部分,分为三种形式whereDecls:一系列临时定义,也可用let代替declValSimple:形如:= expr,用于简单声明declValEqns:一系列| pat => expr,用于模式匹配定义whereStructInst:where及跟随于其后的field := value,用于结构体与类型类
-
optDeriving:要求 Lean 生成代码
-
-
declaration:常量声明-
«abbrev»:缩写,Lean 会将其标记为可约定义(即可展开的定义) -
definition:定义常量 -
«theorem»:基本与definition一致,习惯上用于定理证明 -
«opaque»:不透明常量.不执行类型检查,未提供值时利用Inhabited类型类创建默认值 -
«instance»:类型类重载实例 -
«axiom»:声明公理,可能破坏逻辑一致性 -
«example»:声明一个无名且不永久保存的定理 -
«inductive»:归纳类型,包括可以选择的枚举类型与可以包含自身实例的递归类型ctor:若干个构造子,其名称置于与类型同名的命名空间中- 构造子的参数不能是一个将正在定义的数据类型
-
classInductive:归纳类型类 -
«structure»:定义结构体与类型类,本质是只有一个分支的归纳类型-
«extends»:结构体继承,实质上创建了to前缀的字段structInst可以使用被继承结构的字段初始化- 扩展字段记号为被继承结构的字段提供了额外支持
- 指定多重继承时,仅创建第一条到父结构体的
to前缀字段,余下字段直接复制,其他to前缀函数自动生成
-
structCtor:结构体构造子,结构S的默认构造子名称为S.mk- 构造子是一个接受所有字段作为输入值的函数,其名称置于与类型同名的命名空间中
- 可通过在
:=或where后、所有字段前添加name ::以修改默认构造子名称为name
- 访问器:结构体的每个字段定义了相应的访问器函数,其在结构体的命名空间中与字段具有相同名称
特殊结构体构造子
-
structInst:形如{ x := e, ... }- 若
e与x同名,则:= e可被省略 - 若结构体元素预期类型无法被自动推断,可通过
:在大括号内指定类型(在大括号外指定类型的行为是typeAscription) - 若已存在结构体元素
legacy,则可通过with创建一个部分不同的新元素,例如{ legacy with x := e }
- 若
-
anonymousCtor:匿名构造子,形如⟨e, ...⟩- 相当于
c e ...,其中预期类型是具有单个构造子c的归纳类型 - 如果参数超过两个,则余下参数变为新匿名构造子应用,例如
⟨a, b, c⟩ : α × (β × γ)等价于⟨a, ⟨b, c⟩⟩
- 相当于
-
tuple:有序对构造子,形如(e, ...)()是Unit.unit的简写(a b)是Prod.mk a b的简写(a, b, c)是(a, (b, c))的简写,以此类推
-
-
-
declModifiers:声明修饰符-
docComment:文档注释,不可单独使用commentBody中对-/进行检测- 文档注释会被解析并保存到句法树中,可通过
TSyntax.getDocString获得注释文本
-
attributes:属性,即与对象相关联的标签 -
visibility:修改定义在命名空间外的可见性,本质是阻止 Lean 创建较短的别名 -
«noncomputable»:不可计算函数 -
«unsafe»:使用了不安全特性的函数.普通函数不能直接调用unsafe函数 -
«partial»:非全函数,即不一定停机的函数
-
-
变量声明
-
«universe»:宇宙变量 -
«variable»:函数变量,指示 Lean 将声明的变量作为绑定变量插入定义中
-
-
补充定义
-
«attribute»:为定义指定属性 -
«deriving»:为类型定义派生实例
-
2.1.2 组织特性
-
namespace与section-
namespace:将一系列声明放在命名空间- Lean 中的每个名称都位于一个命名空间,且多层命名空间可被直接定义
- 命名空间名称仅用作前缀,不假设本身是否被定义
_root_是系统保留命名空间,用于显式指明空前缀
-
«section»:小节,限制variable的作用范围variable命令指示 Lean 将声明的变量作为绑定变量插入定义中- 匿名
section可不提供标识符
-
«end»:封闭namespace与section -
«set_option»:改变 Lean 行为,生效范围限制在命名空间、小节或文件内
-
-
«open»与«export»-
«open»:在不显式指定的情况下使用对应命名空间内的名称,本质为常量创建了别名openHiding:打开命名空间,除了指定名称openRenaming:仅打开命名空间内的特定名称,并为指定名称重命名openOnly:仅打开命名空间内的特定名称openSimple:打开命名空间
-
export Some.Namespace (name₁ name₂)使得name₁与name₂- 在当前命名空间无需前缀
Some.Namespace即可访问 - 在
export所在命名空间N之外以N.name₁与N.name₂形式访问
- 在当前命名空间无需前缀
-
-
«mutual»:包围互相调用的代码
2.1.3 句法解析
-
句法解析
-
«syntax»:声明句法规则 -
syntaxCat:声明句法范畴
-
-
句法解析相关的语法糖
-
«macro_rules»:相当于@[macro ...] def ... -
«elab_rules»:相当于@[command_elab ...] def ... -
«macro»:相当于syntax与macro-
«notation» -
«mixfix»
-
-
«elab»:相当于syntax与elab
-
2.1.4 辅助指令
-
eval:使用快速字节码求值器对项进行求值 -
#reduce:使用内核类型检查程序对项进行归约,直到无法再进行归约 -
check:仅检查项的类型而不求值 -
print:揭示数据类型和定义的内部结构-
printAxioms:列出依赖公理 -
printEqns:列出等式
-
2.1.5 特殊指令
-
«init_quot»:定义类型α上的二元关系r形成的商Quot r增加四个定义
Quot.mk:将类型α映射到商@Quot α rQuit.ind:设β是Quot r上的谓词,且对任意Quot.mk a : Quot r成立,则β对任意q : Quot r成立Quot.lift:设函数f : α → β有r a b蕴含f a = f b,则可从f导出函数f': Quot r → β
-
addDocString:将文档注释添加到现有声明,替换既存文档注释
2.2 项范畴
2.3.1 宇宙与类型
-
Type、Sort与Prop:类型、分类与命题-
宇宙层级
Prop即Sort 0或Sort;Type 0或Type即Sort 1;Type n即Sort (n + 1)Sort n的类型是Type n;Type n的类型是Type (n + 1)- 函数类型占据可同时包含参数类型和返回类型的最小宇宙,除非函数返回
Prop(此时函数类型也为Prop)
分类 类型 命题 Sort 0— PropSort 1Type 0— Sort 2Type 1— -
explicitUniv:显式标识层级
-
-
函数类型表达式
-
arrow:箭头表达式,右结合 -
depArrow与«forall»:依值箭头表达式与任意符号,左结合
-
-
类型归属与类型(命题)标注
-
typeAscription:类型归属记号,指示 Lean 将表达式解释为指定类型 -
typeSpec与optType:通用(可选)类型标注 -
«show»:命题标注
-
2.3.2 函数与应用
-
bracketedBinder:括号绑定器-
explicitBinder:显式绑定器,形如(x y : A)或(x y),可通过(x : A := v)或(x : A := by tac)指定默认值 -
implicitBinder:隐式绑定器,形如{x y : A}或{x y}- 通常模式下,隐式绑定器应能被自主推断,Lean 会自动为该参数填充占位符
_ - 在
@显式模式下,隐式绑定器与显式绑定器表现相一致
- 通常模式下,隐式绑定器应能被自主推断,Lean 会自动为该参数填充占位符
-
strictImplicitBinder:严格隐式绑定器,形如⦃x y : A⦄、{{x y : A}}、⦃x y⦄或{{x y}}- 除非指定了至少一个后续显式参数,严格隐式绑定器不会自动插入占位符
_ - 假设遵循上述规则,严格隐式绑定器与隐式绑定器表现相一致
- 除非指定了至少一个后续显式参数,严格隐式绑定器不会自动插入占位符
-
instBinder:实例绑定器,形如[C]或[inst : C].Lean 通过归一化找到唯一能通过类型检查的参数值- 单个实例绑定器不可同时指定多个变量
- 通常模式下,Lean 自动进行类型类推断并插入
C的实例 - 在
@显式模式下,如果_被用于实例隐式参数,则仍可实行类型类推断;也可通过(_)禁用该特性
-
-
«fun»:\(\lambda\) 表达式,即匿名函数.变量名部分支持单项模式匹配 -
应用:左结合,可使用
<|改变结合顺序namedArgument:命名参数,形如(field := value)ellipsis:提供缺少的显式参数作为占位符termParser:直接传入一个普通项
-
扩展字段记号:若
e : T,则可将T.f e简记为e.f,f可以是索引或标识符.也称作投影记号- 若
e : T且存在T.f的声明,则e.f等价于T.f (p := e),其中p是第一个类型为T的显式参数 - 若
T是一个结构体类型且f : F是T的一个字段,则T.f是一个类型为T → F的函数,于是T.f e可简写为e.f - 若
T是一个结构体类型且i是一个正数,则e.i是e的第i个字段之简写
- 若
2.3.3 标识符与字面值
-
标识符与占位符
hole:占位符,指示 Lean 自动填充«sorry»:生成任何证明或对象,可用于增量性地构建长证明
-
字面值:包括整数、浮点数、字符串、字符与名称
-
doubleQuotedName:表示Name元素,但会请求 Lean 静态检查名称是否位于声明范围内 -
quot与precheckedQuot:(一系列)命令的句法模式,用于模式匹配时使用`(category| ...)`表示自定义句法范畴
-
2.3.4 局部定义
-
«let»:局部定义可用的表达式(称为主体)必须在新行上,且列数不大于let关键字的所在列letIdDecl:形如let x := eletPatDecl:形如let pat := e,相当于只有一项的模式匹配letEqnsDecl:形如let f | pat1 => e1 | pat2 => e2 ...
-
«letrec»:递归let定义必须通过编写let rec明确表示 -
«have»:形如have := e、have f x1 x2 := e、have pat := e或have f | pat1 => e1 | pat2 => e2 ...当使用匿名
have时,可用this指代最新的表达式 -
单句命令
-
«open»:作用于单独语句的open -
«set_option»:作用于单独语句的set_option
-
2.3.5 其他记号
-
«match»:模式匹配,形如match e, ... with | p, ... => f | ...,分支条件可以重叠(使用第一个匹配项),不可遗漏generalizingParam:当不构建证明时,match不会自动替换因变量类型中匹配的变量,可用match (generalizing := true)以强制执行此操作matchDiscr:形如h1 : e1, e2, h3 : e3, ...- 若以
match h : e, ... with | p, ... => f | ...使用模式匹配,则在f中可用h : e = p Syntax引用也可用于模式匹配,从而将Syntax值与引号、模式变量或占位符_进行匹配
- 若以
matchAlts- 若以
,分隔多个matchDiscr,则matchAlts也应对应相同数量的参数 - 若以
|分隔多个分支,则rhsParser的绑定变量必须对所有分支都有意义 match默认只匹配构造子组成的项,或可被归约到构造子应用、且标记了match_pattern属性的函数- 若匹配项
t含有不可被归约到构造子应用的项,则应使用.(t)表示其不可被访问
- 若以
-
«do»:单子的简便记法- 对于
do { E },直接译为E - 对于
do { let x ← E₁; S; ...; Eₙ },译为E₁ >>= fun x => do { S; ...; Eₙ } - 对于
do { E₁ S; ...; Eₙ },译为E₁ >>= fun () => do { S; ...; Eₙ } -
对于
do { let x := E₁; S; ...; Eₙ },译为
do 记号内的类型
忽略
let x := E.设S₁, S₂, ⋯, Sₙ为语句Eᵢ或let x ← Eᵢ,Eᵢ与E为表达式,则下述语句块可译为
其中
xᵢ是αᵢ元素或()的简记.设m为单子类型,α₁, α₂, ⋯, αₙ, β为任意类型,则- 当
xᵢ为()时,αᵢ必为Unit - 所有
m必须相同,但α₁, α₂, ⋯, αₙ, β可各不相同 - 最终返回值类型为
m β
- 对于
-
byTactic:证明策略,指示 Lean 如何构建证明 -
Termination.suffix:停机性证明terminationBy:提供停机参数,若要使用:后的匿名参数,可以匿名函数形式命名terminationBy?:建议自动推断的停机参数decreasingBy:手动证明终止参数,在每次递归调用时都会减少
2.3 属性范畴
- 内建属性:先于
Lean.Parser定义的属性- 与句法范畴对应的属性
builtin_term_parser:对应termParserbuiltin_command_parser:对应commandParserbuiltin_attr_parser:对应attrParserbuiltin_tactic_parser:对应tacticParserbuiltin_syntax_parser:对应syntaxParserbuiltin_level_parser:对应levelParserbuiltin_prio_parser:对应priorityParserbuiltin_prec_parser:对应precedenceParserbuiltin_doElem_parser:对应doElemParser
- 与类型类对应的属性
instance:标记类型类实例(定义可不使用instance)default_instance:标记类型类默认实例
- 与可约性对应的属性
reducible:可约声明,在任何地方展开.abbrev应用的设置semireducible:部分可约声明,部分开销较高的自动化不展开.def默认应用的设置irreducible:不可约声明,从不展开
inherit_doc:从特定声明继承文档
- 与句法范畴对应的属性
- 标签属性:在定义所在模块中标记声明
match_pattern:标记可在模式识别中使用的定义computed_field:用于归纳类型的computedFields
- 参数属性:标签属性的变体,可以在其中将参数附加到属性
export:将 Lean 定义导出为外部可调用符号extern:指定外部库函数作为定义实现,标记该属性的常量不可被用于证明Falseimplemented_by:指定 Lean 函数作为定义实现(可能为unsafe)
-
枚举属性:给定类型为
α的列表[a₁, a₂, ..., aₙ],枚举属性提供属性Attrᵢ用于将值aᵢ与声明关联起来inline:标记定义为内联noinline:标记定义为非内联macro_inline:标记定义在 ANF 转换前内联always_inline:标记定义始终内联
其他属性
simp:标记简化策略可用等式builtin_macro与macro:定义宏builtin_command_elab与command_elab:定义繁饰器
2.4 策略范畴
-
«unknown»:无法识别策略的回落机制 -
«match»:策略内模式匹配 -
decide:用于可判定相等性的目标native_decide:使用#eval对可判定性实例求值,效率高于decide -
内建表达式策略
-
«open» -
«set_option»
-
2.5 句法范畴
-
范畴与标识符
-
括号相关
-
分隔符组合子
2.6 其他范畴
2.6.1 层级范畴
-
num、ident与hole:数字、标识符与占位符 -
最大层级与层级增加,其中
imax u v在v为0时得到0
2.6.2 优先级范畴
-
numPrio:用于各种声明 -
numPrec:用于句法或宏等元编程声明
2.6.3 do 元素范畴
-
基础表达式
-
doLet与doLetRec:let局部定义 -
doExpr:作为语句的项 -
doLetArrow:左箭头表达式liftMethod:简单提升嵌套活动.只能用于do语句块中
-
-
附加特性
-
doIf与doUnless:条件语句 -
doFor:循环语句 -
doTry:异常处理,是MonadExcept的简写 -
doMatch:模式匹配 -
doBreak、doContinue与doReturn:控制语句 -
doNested:嵌套do语句块
-