给定以下关于peano数的类型级加法函数
sealed trait Nat
class O extends Nat
class S[N <: Nat] extends Nat
type plus[a <: Nat, b <: Nat] = a match
case O => b
case S[n] => S[n plus b]
假设我们要证明这样的定理
对于所有自然数n,n+0=n
也许可以这样说
type plus_n_0 = [n <: Nat] =>> (n plus O) =:= n
当涉及到为定理提供证据时,我们可以很容易地要求scala编译器在特定情况下提供证据
summon[plus_n_O[S[S[O]]]] // ok, 2 + 0 = 2
但是我们怎么能问scala它是否能为所有的示例生成证据呢 [n <: Nat]
,从而提供 plus_n_0
?
1条答案
按热度按时间gt0wga4j1#
以下是一种可能的方法,即尝试对本段进行字面解释:
当证明一个陈述时
E:N→U
关于所有的自然数,只要证明一下就足够了0
以及succ(n)
,假设它持续n
,即我们建造ez:E(0)
以及es:∏(n:N)E(n)→E(succ(n))
.来自hott手册(第5.1节)。
以下是代码实现的计划:
为“某些财产”的陈述提供证据意味着什么
P
适用于所有自然数”。下面,我们将使用签名人在哪里
apply
-方法本质上说是“为了所有人”n <: N
,我们可以找到P[n]
".注意,方法声明为
inline
. 这是确保∀n.P(n)
是构造性的,并且在运行时可执行(但是,请参见编辑历史记录以获取具有手动生成的见证条件的备选方案)。假设自然数的某种归纳法则。下面,我们将使用以下公式:
我认为应该有可能
derive
这样的归纳法则使用了一些元编程工具。为归纳原理的基本情况和归纳情况撰写证明。
???
利润代码如下所示:
它编译、运行和打印:
这意味着我们已经成功地对类型为的可执行证据项调用了递归定义的方法
two plus O =:= O
.一些进一步的评论
这个
trivialLemma
是必要的summon
在另一个里面given
不要意外地生成递归循环,这有点烦人。分离
liftCo
-方法S[_ <: U]
是需要的,因为=:=.liftCo
不允许类型构造函数具有上界类型参数。compiletime.erasedValue
+inline match
太棒了!它自动生成某种运行时小控件,允许我们对“擦除”类型进行模式匹配。在我发现这一点之前,我试图手动构造适当的见证条件,但这似乎根本没有必要,它是免费提供的(请参阅编辑历史记录以了解手动构造见证条件的方法)。