内置标识符名称的字符串操作。 🍓 AST形成的便捷组合器: 𝓋𝓇𝒶, λ𝓋_↦_, … . 🛠 大量引用术语和类型的示例。 🎯 示例数据类型的单例类型的批量派生, 以及可推导的证明 💛 🎵 自动化仅 回流 具有 模式匹配 🏄 Agda中C风格宏的讨论 🌵 使用宏在不增加语法开销的情况下提取证明模式 💪 🎼 关于我不能做的事情的评论,可能是因为我不能做 😭
进口 介绍 名称 ─ 已知标识符的类型 精氨酸 ─ 参数的类型 期限 ─ 术语类型 使用Typechecking Monad进行元编程 总费用 取消引用—创建新功能和类型 Sidequest:避免单调乏味 回流 证据 宏——抽象证明模式 我们的第一个实证策略 编写宏的启发 在子表达式的深处怎么样?
模块温和介绍反思 将级别导入为级别 打开导入反射隐藏(名称;类型) 打开导入关系。 二元的。 命题等式隐藏([_]) 打开导入关系。 一次使用(可决定) 打开导入关系。 Nullary公司 打开导入数据。 单位 打开导入数据。 Nat as Nat隐藏(_⊓_) 打开导入数据。 布尔 打开导入数据。 产品 打开导入数据。 作为列表列出 打开导入数据。 字符作为字符 打开导入数据。 字符串作为字符串
data RGB:设置位置 红、绿、蓝:RGB
a-name:名称 a-name=quoteℕ isNat:Name→Bool isNat(引号ℕ)=真 isNat _=假 --错误:设置→名称 --错误的s=引号s{-s未知-}
名称 配备了平等、排序和显示功能。 Quote对函数参数无效; 标识符必须是已知的。
_:showName(quote _≡_)≡“Agda.Buildin.Equality._≡__” _=回流 _:showName(引号红色)≡“gentle-intro-to-reflection.RGB.Red” _=回流
{-类似于“$”,但用于字符串。-} __:(列表字符→列表字符)→字符串→字符串 f⟨𝒮⟩s=从列表(f(到列表s)) {-这应该在标准库中;我找不到它。-} 到十二月:{У}{A:集У}→(p:A→Bool)→可决定{У){A}(λA→pa≡true) 到12月p x和p x toDec p x | false=无λ() toDec p x | true=是ref
module-name:字符串 模块名称=takeWhile(toDec(λc→not(c Char.=='.')))showName(引号红色) _:module-name≡“gentle-intro-to反射” _=回流 strName:Name→String strName n=drop(1+String.length模块名称)⟨𝒮⟩showName n {-“1+”表示限定名中的“.”分隔符。-} _:strName(引号红色)≡“RGB.Red” _=回流
{-参数可以是(可见)、{隐藏}或⦃实例⦄-} 数据可见性:设置位置 可见隐藏实例:可见性 {-参数可以是相关的也可以是无关的:-} 数据相关性:设置位置 相关无关:相关性 {-可见性和相关性表征参数的行为:-} data ArgInfo:设置位置 arg-info:(v:可见性)(r:相关性)→ArgInfo data Arg(A:Set):设置位置 参数:(i:ArgInfo)(x:A)→参数A
{-可见相关参数-} 𝓋𝓇𝒶 : {A:设置}→A→参数A 𝓋𝓇𝒶 = arg(arg-info可见相关) {-𝒽idden𝓇elevant𝒶argument-} 𝒽𝓇𝒶 : {A:设置}→A→参数A 𝒽𝓇𝒶 = arg(arg-info隐藏相关)
-
变量是De Bruijn索引的,可以应用于参数列表。 -
索引 n个 指的是 n个 远离“此处”的位置。 {-可见相关变量-} 𝓋𝓇𝓋 : (debuijn:ℕ)(args:列表(Arg术语))→Arg术语 𝓋𝓇𝓋 n args=arg(arg-info可见相关)(var n args) {-𝒽idden𝓇elevant𝓋变量-} 𝒽𝓇𝓋 : (debuijn:ℕ)(args:列表(Arg术语))→Arg术语 𝒽𝓇𝓋 n args=arg(arg-info隐藏相关)(var n args)
数据术语,其中 {-变量具有De Bruijn索引,可以应用于参数。-} var:(x:ℕ)(args:List(Arg Term))→Term {-构造函数和定义可以应用于参数列表。-} con:(c:名称)(args:列表(参数术语))→术语 def:(f:名称)(args:List(Arg Term))→Term {-λ-抽象绑定一个变量;“t”是变量的字符串名 和羔羊的身体一起。 -} lam:(v:可见性)(t:Abs术语)→术语{-Abs A≅字符串×A-} pat-lam:(cs:List子句)(args:List(Arg Term))→Term {-望远镜,或函数类型;λ-类型抽象。-} pi:(a:Arg类型)(b:Abs类型)→术语 {-“Set n”或表示类型的某些术语-} agda排序:(s:sort)→术语 {-元变量;通过quoteTerm-}引入 meta:(x:meta)→列表(参数术语)→术语 {-文字≅ℕ|Word64|Float|Char|String|Name|Meta-} lit:(l:文字)→术语 {-本AST无法表示的项目;例如,孔。-} 未知:术语{-在取消查询时被视为“_”。-} 数据排序位置 集合:(t:Term)→排序{-给定(可能是中性)级别的集合。-} lit:(n:Nat)→排序{-给定混凝土水平的集合。-} 未知:排序 数据子句,其中 子句:(ps:列表(Arg模式))(t:术语)→子句 荒谬的条款:(ps:列表(Arg模式))→条款
导入数据。 Vec作为V 导入数据。 Fin作为F _:quoteTermℕ≡def(引号\8469;)[] _=回流 _:quoteTerm V.Vec≡def(引用V.Vec)[] _=回流 _:quoteTerm(F.Fin 3)≡def(引用F.Fin) _=回流
_:quoteTerm 1≡lit(nat 1) _=回流 _:quoteTerm(例如零) ≡con(引用suc)(arg(arg-info可见相关)(引用项0)[]) _=回流 {-使用我们的助手\120007\119990\-} _:quoteTerm(suc zero)≡con(quote suc)(引用suc) _=回流
_:quoteTerm true≡con(引号true)[] _=回流 _:引号项_ lect _ lect def(引号_ lect _)[] _=回流 _:quoteTerm(“b”≡“a”) Select-def(引号_ Select_) (定义(引用级别为零)[]) ●𝒽𝓇𝒶(def(引号字符串)[]) ●𝓋𝓇𝒶(亮起(字符串“b”)) ●𝓇𝒶(lit(字符串“a”)) _=回流
_:∀{level:level.level}{Type:Set level}(x y:Type) → 引用项(x≡y) ≡def(引号≡) (𝒽𝓇𝓋 3 [] ∷ 𝒽𝓇𝓋 2 [] ∷ 𝓋𝓇𝓋 1 [] ∷ 𝓋𝓇𝓋 0 [] ∷ []) _=λx y→回流
假设:集合 假设𝒻:𝒜→ℬ _:quoteTerm𝒻≡def(引号\119995;)[] _=回流
模块{AB:Set}{f:A→B}其中 _:quoteTerm f≡var 0[] _=回流
_:quoteTerm((λx→x)“nice”)≡lit(字符串“nice“) _=回流
id:{A:Set}→A→A id x=x _:报价项(λ(x:ℕ)→id x) ≡def(引号id)(def(quote id)[])б[]) _=回流
_:quoteTerm(id“a”) ≡def(引号id) (def(引号字符串)[]) _=回流
_:quoteTerm(λ(x:Bool)→x)≡lam可见(abs“x”(var 0[])) _=回流
_:quoteTerm(λ(a:ℕ)(f:ℕ→ℕ)→f a) ≡lam可见(abs“a” (lam可见(abs“f” (var 0(arg(arg-info可见相关)(var 1[])([]))) _=回流
infixr 5λ𝓋_λ𝒽_↦_ λ𝓋_↦_λ𝒽_:字符串→术语→术语 λ𝓋x↦车身=lam可见(abs x车身) λ𝒽x↦车身=隐藏的lam(abs x车身)
_:报价项(λ(a:ℕ)(f:\8469;→\8469;)→f a) ≡λ“a”λ“f”变量0[(变量1[])] _=回流
_:{AB:Set}→quoteTerm(λ(A:A)(B:B)→A) ≡λ“a”(λ“b”变量1[]) _=回流 _:quoteTerm(λ{A B:集合}(A:A)(_:B)→A) ≡(λ“A”(λB) _=回流 常数:{AB:Set}→A→B→A 常数a_=a _:quoteTerm const≡def(引号const)[] _=回流
_:quoteTerm(_≡“b”) ≡λ𝓋“部分”↦ (定义(引用_≡_) (𝒽𝓇𝒶(def(引用Level.zero)[]) 𝒽𝓇𝒶 (def(引号字符串)[]) 𝓋𝓇𝒶 (var 0[])| 𝓋𝓇𝒶 (lit(字符串“b”)) _=回流
假设 TC:{a}→设置a→设置a returnTC:∀{a}{a:设置a}→a→TC a bindTC:∀{ab}{a:集合a}{b:集合b}→TC a→(a→TC b)→TC b
_>>=_:{ab}{a:集合a}{b:集合b}→TC a→(a→TC b)→TC b _>>=_=绑定TC _>>_:∀{ab}{a:集合a}{b:集合b}→TC a→TC b→TC b _>>_=λp q→p>>=(λ_→q)
假设 {-拿下你所拥有的,并努力使其符合当前目标。-} 统一:(有:学期)(目标:学期)→TC {-尝试第一次计算,如果由于类型错误而崩溃,请尝试第二次。-} catchTC:∀{a}{a:设置a}→TC a→TC a {-推断给定术语的类型。-} inferType:术语→TC类型 {-根据给定类型检查术语。这可能会解析隐式参数 在术语中,因此将返回一个新的细化术语。 可用于创建 新的元变量:newMeta t=checkType未知t-} checkType:术语→类型→TC术语 {-计算术语的标准形式。-} 正常化:术语→TC术语 {-引用一个值,返回相应的Term.-} quoteTC:∀{a}{a:设置a}→a→TC术语 {-取消对术语的引用,返回相应的值。-} unquoteTC:{a}{a:Set a}→Term→TC a {-创建新名称。-} freshName:字符串→TC名称 {-声明给定类型的新函数。必须定义该函数 稍后使用“defineFun”。 采用参数名称以允许声明实例 和不相关的函数。 Arg的可见性不能隐藏。-} declareDef:参数名称→类型→TC⊤ {-定义已声明的函数。该函数可能已使用 “declareDef”或在程序中具有显式类型签名。-} defineFun:Name→List子句→TC⊤ {-获取已定义名称的类型。替换“primNameType”。-} getType:Name→TC类型 {-获取已定义名称的定义。替换“primNameDefinition”。-} getDefinition:名称→TC定义 {-更改inferType、checkType、quoteTC、getContext的行为 使结果正常化(或不正常化)。 默认行为为否 归一化。-} 标准化:{a}{a:Seta}→Bool→TCA→TCA
数据IsRed:RGB→设置位置 是的:是红色
IsRed:RGB→设置 IsRed x=x≡红色
“▽₀”:Arg术语 “ ℓ₀” = 𝒽𝓇𝒶 (定义(引用级别为零)[]) “RGB”:参数术语 “RGB”=(定义(引号RGB)[]) “红色”:Arg术语 “红色”=(引用红色)
未报价Decl IsRed= do ty←quoteTC(RGB→设置) 声明Def(IsRed)ty defineFun IsRed[子句[(var“x”)](def(quote _≡_)(“▽₀”“RGB”“Red”𝓇𝓋0[][])]
red-is-a-溶液:IsRed red red-is-a-solution=回流 绿色即非解决方案:(IsRed-green) 绿色-非-解决方案=λ() red-is是唯一的解决方案:∀{c}→IsRed c→c≡red red-is-the-only-solution ref=refl
{-定义阶段,我们可以在形成这个程序时使用“?”。-} define Is:名称→名称→TC⊤ define-Is Is-name qcolour=defineFun Is-name [条款[(var“x”)] 声明-Is:名称→名称→TC⊤ 声明-是Is-name qcolour= 确实让η=is-name τ←quoteTC(RGB→设置) declareDef(η)τ defineFun is名称 [条款[(var“x”)] (def(quote _≡_)(“У₀”(“RGB”) {-取消引用阶段-} IsRed′:RGB→设置 unquoteDef IsRed′=define-Is IsRed’(引用红色) {-尝试-} _:IsRed′Red _=回流
unquoteDecl IsBlue=声明-IsBlue(引用蓝色) unquoteDecl IsGreen=声明IsGreen(引用绿色) {-示例用法-} 分离rgb:{c}→(IsBlue c×IsGreen c) 分离rgb(ref,())
未引用的Decl{-标识-} =do{-让η=恒等式-} η←新生姓名“身份” τ←quoteTC({A:Set}→A→A) declareDef(η)τ defineFunη[子句[(var“x”)](var 0[])] {-“身份”不在范围内!? _:∀{x:ℕ}→恒等式x≡x _=回流 -}
-
注释掉 新鲜名称 行并将周围的工件取消注释为,以便 单元测试通过。 -
将其用作模板,取消引用函数 随处-0:\→\ 它始终为0。 -
取消引用常量组合符 K:{AB:Set}→A→B→A . unquoteDecl everywhere-0 =做 _:随处-0 3≡0 _=回流 未报价Decl K =做 _:K 3“猫”≡3 _=回流
{-编程阶段} 声明唯一:名称→(RGB→设置)→RGB→TC⊤ 声明独特的S色= =做 {-取消引用阶段-} unquoteDecl red-unique=declare-unique red-unique IsRed红色 unquoteDecl green unique=声明唯一的绿色唯一的IsGreen绿色 unquoteDecl blue-unique=声明独特的blue-unique IsBlue blue {测试-} _:∀{c}→IsGreen c→c≡Green _=绿色-unique
just-Red:RGB→RGB just-Red红色=红色 just-Red绿色=红色 just-Red蓝色=红色 仅蓝色:RGB→RGB only-蓝色-蓝色=蓝色 仅蓝色_=蓝色
just-Red-is常量:∀{c}→just-Red c≡Red just-Red-is-constant{Red}=参考 just-Red-is-constant{Green}=参考 just-Red-is-constant{Blue}=参考 {-恶心,又一个乏味的证明-} only-Blue-is常量:∀{c}→only-Bloe c≡Blue only-Blue-is常量{Blue}=ref 只有蓝色是常量{红色}=refl only-Blue-is-constant{Green}=ref
构造函数:定义→列表名称 构造函数(数据类型pars-cs)=cs 构造函数_=[] 按refls:名称→术语→TC⊤ by-refls名称thm-you-hope-is-provable-by-refls =let mk-cls:名称→子句 mk-cls qcolour=子句[(con qcolour[])](con(引号ref)[]) 在里面 do让η=标称 δ←getDefinition(引用RGB) let子句=List.map mk-cls(构造函数δ) declareDef(η)thm-you-hope-is-provable-by-refs 定义Funη子句
_:∀{c}→仅红色c≡红色 _=不错 其中unquoteDecl-nice=by-refls-nice(quoteTerm(∀{c}→just-Red c≡Red))
-
第一个 美好的 指的是函数 由非上市公司RHS创建。 -
RHS公司 美好的 指提供的Name值 通过LHS。 -
左侧 美好的 是Name值的声明。
_:∀{c}→仅蓝色c≡蓝色 _=不错 其中unquoteDecl-nice=by-refls-nice(quoteTerm∀{c}→仅蓝色c≡蓝色)
-
元程序可以在术语位置运行。 -
在没有宏块的情况下,我们使用 无报价 关键字。 -
自动报价; 例如。, 如果 f:Term→Name→Bool→Term→TC⊤ 然后是一个应用程序 f u v w 去糖成 unquote(f(quoteTerm u)(引号v)w) . 无语法开销:宏像普通函数一样应用。
luckyNum₀:术语→TC⊤ luckyNum₀h=统一h(引用条款55) 编号: num₀=取消引用luckyNum
宏 luckyNum:术语→TC⊤ luckyNum h=统一h(quoteTerm 55) 编号:ℕ num=幸运数字
宏 第一个:术语→TC⊤ 第一个目标= myconst:{AB:Set}→A→B→A myconst=λx→λy→第一个 mysum:({x}y:ℕ)→\8469' mysum y=y+第一个
宏 使用:术语→术语→TC⊤ 使用=秒 {-完全定义,无参数。-} 2+2≈4 : 2 + 2 ≡ 4 2+2≈4=回流 _:使用2+2≈4≡“漂亮” _=回流 {-'p'有参数。-} _:{xy:ℕ}{p:x≡y}→使用p≡“哇那里” _=回流
+-rid:{n}→n+0≡n +-rid{zero}=回流 +-rid{suc n}=cong suc+-rid *-rid:{n}→n*1≡n *-rid{zero}=回流 *-rid{suc n}=cong suc*-rid ^-rid:{n}→n^1≡n ^-rid{zero}=回流 ^-rid{sucn}=cong-suc^-rid
{-“for loops”或“Incluction forℕ”-} foldn:(P:ℕ→Set)(基数:P zero)(ind:∀n→P n→P(sucn)) → ∀ (n:ℕ)→P n foldn P base ind zero=基数 foldn P base ind(sucn)=ind n(foldn P base ind n)
_:∀(x:ℕ)→x+0≡x _=foldn_ref(λ_→cong-suc){-这两个和接下来的两个是相同的-} _:∀(x:ℕ)→x*1≡x _=foldn_ref(λ_→cong-suc){-Yup,与前面的证明相同-} _:∀(x:ℕ)→x^1≡x _=foldn_ref(λ_→cong-suc){-无变化,与前面的证明相同-}
当你看到重复,复制,知道还有改进的余地! (•̀ᴗ•́)و
不要重复!
make-rid:(让A=ℕ)(_ \8469]:A→A→A)(e:A)→名称→TC⊤ 使rid为标称 =做 _:∀{x:ℕ}→x+0≡x _=nice where unquoteDecl nice=make-rid _+_ 0 nice
宏 _普通的has-rid_:(设A=ℕ)(_ \8469]:A→A→A)(e:A)→项→TC _平凡的目标 =doτ←quoteTC(λ(x:ℕ)→xe≡x) 统一目标(def(quote foldn){-使用foldn-} (𝓋𝓇𝒶τ{-类型P-} ▪𝓇𝒶(con(引号ref)[]){-基本情况-} ●𝓋𝓇𝒶(λ\120011'“_”↦quoteTerm(cong-suc)){-感应步长-} ∷ []))
_:∀(x:ℕ)→x+0≡x _=_+_微不足道的-has-rid 0 _:∀(x:ℕ)→x*1≡x _=_*_普通的手-里德1 _:∀(x:ℕ)→x*1≡x _=_^_平凡的手-里德1
+-rid′:∀{n}→n+0≡n +-rid′{zero}=回流 +-rid′{suc n}=报价目标e in 让 suc-n:术语 suc-n=con(引用suc)[(var 0[])] lhs:期限 lhs=def(引号+)(suc-n) {-检查我们对目标“e”的理解。-} _:e≡def(引号_≡_) (quoteTerm Level.zero) ●lhs _=回流 {-它看起来正常化了什么。-} _:quoteTerm(例如(n+0)≡n) ≡unquoteλ目标→(do g←归一化目标; 统一g目标) _=回流 在里面 cong-suc+-rid′
≡-type-info:Term→TC(Arg Term×Arg Terms×Term×Term) ≡-type-info(def(quote _≡_)(\120001;\119983;arg _ l arg _r[]))=返回TC(𝓁,𝒯,l,r) ≡-type-info _=typeError[strErr“术语不是≡类型。”]
{-尝试计算的语法糖,如果失败,则尝试另一个-} try-fun:∀{a}{a:设置a}→TC a→TC a try-fun=捕获TC 语法try-fun t f=try t or else f
宏 应用₁:术语→术语→TC⊤ apply₁p目标=尝试(doτ←inferType p 𝓁 , 𝒯 , l,r←≡-类型信息τ 统一目标(def(quote sym)( 𝓁 ∷ 𝒯 ∷ 𝒽𝓇𝒶 l|𝒽𝓇r|𝓋p|[])) 或以else 统一目标p
假设𝓍𝓎:ℕ 假设𝓆:𝓍+2 lect𝓎 {-相同的证明产生两个定理 _ : 𝓎 ≡ 𝓍 + 2 _=应用 _ : 𝓍 + 2 ≡ 𝓎 _=应用
{-键入批注-} 语法有A A=A∶A 有:∀(A:Set)(A:A)→A 有A A=A
woah:{A:Set}(xy:A)→x≡y→(y≡x)×(x≡y) woah x y p=应用p,应用p 其中--每次调用都会生成不同的证明,实际上: 第一个pf:(应用₁p∶(y≡x))≡symp 第一个pf=refl 第二个pf:(应用₁p∶(x≡y))≡p 第二个pf=refl
_:∀{A:Set}{x:A}→应用₁x≡x _=回流 _:应用“哈”选择“哈” _=回流
宏 应用三:术语→术语→TC⊤ 应用三p目标=____ yummah:{A:集}{xy:A}(p:x Selecty)→x Selecty×y Selectx×y Selecty yummah p=应用三p,应用三p和应用三p
≡-type-info′:名称→TC(参数术语×参数术语×术语×术语) ≡-type-info′=↓ 宏 sumSides:名称→术语→TC⊤ sumSides n目标= _:sumSides𝓆≡𝓍+2+𝓎 _=回流
编写no-op宏: mymacro p目标=统一p目标 . 编写测试用例 mymacro p≡p . 感觉不错,你成功了。 稍微改变一下测试,使其更接近你的目标。 测试现在中断了,去修复它。 转至步骤3。
-
假设 x、 y、h、p 所以这个问题摆得很好。 -
使用上述方法形成no-op宏。 -
将测试细化为 mymacro p≡λe→0 并细化宏。 -
将测试细化为 mymacro p≡λe→e 并细化宏。 -
最终通过了预期的测试 mymacro p≡λe→he ─ 然后eta降低。 在此过程中,返回 一串 的名称 小时 或将测试重写为 _≡_{零级}{ℕ→\8469»}(mymacro p)≡ . 这可以提供有关如何修复或继续宏构造的见解。 -
扔掉这些假设,一次一个,让它们在测试中成为论据; 每次都要细化宏,以便在删除每个假设时测试继续通过。 每个假设移除都可能需要更改现有的辅助功能。 -
我们考虑了函数应用,然后是变量函数,最后是 考虑构造函数。 确保针对此特定问题的测试涵盖所有这些内容。
{-如果我们有“f$args”,则返回“f”。-} $-头:期限→期限 $-head(var v args)=var v[] $-head(con c args)=con c[] $-head(def f args)=def f[] $-head(pat-lam cs args)=pat-lam cs[] $-水头t=t
宏 应用₄:术语→术语→TC⊤ apply₄p目标=try(doτ←inferType目标 _,_,l,r←≡-类型信息τ 统一目标(def(quote cong)($-head l) 奥尔斯统一目标p _:∀{xy:ℕ}{f:\8469;→\8469»}(p:x选择y)→fx选择fy _=λp→应用₄p _:∀{xy:ℕ}{fg:\8469;→\8469»}(p:x选择y) → x≡y --→fx≡gy{-“apply₄p”现在有一个统一错误^_^-} _=λp→应用₄p
例如X+(X*例如X+例如X) Select⟨cong(λit→suc X+it)(+-suc_ _)⟩ suc X+suc(X*suc X+X)
打开导入数据。 自然属性 {-+-suc:∀mn→m+sucn≡suc(m+n)-} 测试₀:∀{mnk:ℕ}→k+(m+sucn)≡k+suc(m+n) 测试{m}{n}{k}=cong(k+)(+-sucmn)
假设𝒳:ℕ 假设𝒢:suc𝒳+ 𝒮𝒳 : Arg术语 𝒮𝒳 = 𝓋𝓇𝒶 (con(quote suc)[引用术语]) 𝒢 ˡ𝒢ʳ:术语 𝒢 ˡ=定义(引号_+_)( 𝒮𝒳 ∷ 𝓋𝓇𝒶 (def(引号_+_)(引号_*_)(引用术语 𝒳) ∷ 𝒮𝒳 ∷ [])) ∷ 𝒮𝒳 ∷ [])) ∷ []) 𝒢 ʳ=定义(引号_+_)( 𝒮𝒳 ∷ 𝓋𝓇𝒶 (con(引号suc)[(def(引号_+_)(def)(引号_*_)(引用术语 𝒳) ∷ 𝒮𝒳 ∷ [])(引用术语)
{-肯定应该在标准库中-} ⌊_⌋:∀{a}{a:设置a}→Dec a→Bool ⌊yes p⌋=真 ⌊否⌋=假 进口Agda。 内置。 作为内置的反射 _$-≟_:术语→术语→布尔 con c args$-≟con c′args′=Builtin.primQNameEquality c′ def f args$-≟def f′args′=内置.primQNameEquality f f′ var x args$-≟var x′args′=⌊x Nat.\8799;x′⌋ _$-≟_=错误 {-只获取头和相同数量的常用参数,不深入任何地方。:'(-} 中缀5_⊓_ {-#TERMINATING#-}{-通过添加燃料(con c args)≔1+长度args来解决此问题-} _⊓_:术语→术语→术语 l⊓r和l$-≟r|l|r …|false|x|y=未知 …|true|var f args | var f′args′=var f(List.zipWith(λ{(arg i!!t)(arg j!!s)→arg i!! (t⊓s)})args args′) …|true|con f args | con f′args′=con f(List.zipWith(λ{(arg i!!t)(arg j!!s)→arg i!! (t⊓s)})args args′) …|true|def f args | def f′args′=def f(List.zipWith(λ{(arg i!!t)(arg j!!s)→arg i!! (t⊓s)})args args′) …|true|ll|_=ll{左偏;使用“unknown”不能确保幂等性。-}
_:选择定义(引号_+_)( 𝒮𝒳 ∷ 𝓋𝓇𝒶 未知©[]) _=回流 {使用参数函数𝒶和参数编号X-}进行测试 _:{X:ℕ}{\119990;:\8469'→\8469]} → 设gl=quoteTerm(X+(X*X+X)) gr=报价条款(X+X(X*X+X)) 在gl⊓gr≡def(引号+)(变量0[变量1[])])中 _=回流
更换间隔 未知的 使用De Bruijn索引。 然后,找出有多少未知数,并为每个未知数在前面贴上一只无名的羔羊。 在前面粘贴一个lambda会破坏现有的De Bruijn索引,因此为每个lambda增加这些索引。
{-“unknown”指向一个变量,即De Bruijn索引-} unknown-elim:ℕ→列表(Arg Term)→列表(Arg Term) 未知-elim n[]=[] unknown-elim n(arg i unknown|xs)=arg i(var n〔〕)|unknown-elim(n+1)xs 未知-elim n(arg i(var x args)xs)=arg i 未知elim n(arg i xŞxs)=arg i xŞ未知elim n xs {-基本上我们想要:身体(未知ᵢ)⇒λ_→身体(var 0) 然而,现在“body”中的所有“var 0”引用引用了错误的参数; 他们现在指的是“比以前多了一个lambda”。-} 未知计数:列表(参数项)→ℕ 未知计数[]=0 未知计数(arg i未知xs)=1+未知计数xs 未知计数(arg i|xs)=未知计数xs 未知-λ:ℕ→术语→术语 未知-λ零体=体 未知-λ(sucn)体=未知-λs n(λ𝓋“截面”↦体) {-将“未知”替换为节-} 补丁:Term→Term 修补它@(def f args)=未知-λ(未知-计数args)(def f(未知-elim 0 args)) 修补它@(var f args)=未知-λ(未知-计数args)(var f(未知-elim 0 args)) 修补它@(con f args)=未知-λ(unknown-count args)(con f(unknowsn-elim 0 args)) 补丁t=t
宏 脊柱:术语→术语→TC⊤ spine p目标 =doτ←推断类型p _,_,l,r←≡-类型信息τ 统一目标(补丁(l⊓r))
_:spine𝒢≡suc𝒳+_ _=回流 模块测试假定功能,其中 假设:→ 假设_ 𝒷_ : ℕ → ℕ → ℕ 假设 𝓰 : 𝒶 𝒳 𝒷 𝒳 ≡ 𝒶 𝒳 𝒷 𝒶 𝓍 _:脊柱𝓰≡(𝒶𝒳𝃏_) _=回流 _:{X:ℕ}{G:suc X+(X*suc X+suc X)select suc X+/suc(X*suc X+X)} → 引用项G lect var 0[] _=回流
宏 apply:术语→术语→TC⊤ 应用p孔 =doτ←inferType孔 _,_,l,r←≡-类型信息τ 统一孔((def(引号cong) (补丁(l⊓r))
_:suc𝒳+(\119987;*suc𝃋·+suc߃)select suc \196987;+suc _=应用(+-suc(𝒳*suc \119987;) 测试:{mnk:}→k+(m+sucn)≡k+suc(m+n) test{m}{n}{k}=apply(+-sucmn)