在Agda中证明一个空的类型

时间:2013-08-09 03:10:01

标签: theorem-proving agda

我想在agda中证明2 * 3!= 5。为此,我将定义一个带有签名2 *3≡5→⊥的函数。

利用我的乘法定义

data _*_≡_ : ℕ → ℕ → ℕ → Set where
  base : ∀ {n} → 0 * n ≡ 0
  succ : ∀ {n m k j} → m * n ≡ j → j + n ≡ k → suc m * n ≡ k

我已经证实了

1*3≡3 : 1 * 3 ≡ 3
1*3≡3 = (succ base) znn

3+3≡5 : 3 + 3 ≡ 5 → ⊥
3+3≡5 (sns (sns (sns ())))

但是当我试图证明:

m235 : 2 * 3 ≡ 5 → ⊥
m235 ( ( succ  1*3≡3 ) ( x ) ) = ( 3+3≡5 x )

编译器吐出关于x

的错误
.j != (suc 2) of type ℕ
when checking that the expression x has type 3 + 3 ≡ 5

对不起,如果这是一个愚蠢的问题。提前谢谢。

1 个答案:

答案 0 :(得分:4)

首先,您忘记包含_+_≡_的定义。我假设它如下:

data _+_≡_ : ℕ → ℕ → ℕ → Set where
  znn : ∀ {n} → 0 + n ≡ n
  sns : ∀ {n m k} → n + m ≡ k → suc n + m ≡ suc k

接下来,您的问题不在于找到正确的语法,但您必须弄清楚如何从类型2 * 3 ≡ 5的值中得出结论。通过你已经完成的模式匹配,你可以通过用一个?替换右边的那个,调用Cc Cl来编译和使用Cc C-来询问Agda在上下文中可用的值是什么,以询问上下文: / p>

m235 : 2 * 3 ≡ 5 → ⊥
m235 ( ( succ  1*3≡3 ) ( x ) ) = ?

阿格达会说:

Goal : ⊥
-----------------------------
x     : .j + 3 ≡ 5
1*3≡3 : 1 * 3 ≡ .j
.j    : ℕ

即:您希望证明底部(即与假设不一致),并且您在上下文中有3个值可用。您有1 * 3 ≡ .j类型的证明,未知号码.j以及.j + 3 ≡ 5类型证明。你似乎认为Agda可以自动注意到j必须是3,但这对它来说太困难了:它只会从统一中得出结论,而不是自己进行实际推理。因此,解决方案是帮助Agda理解为什么.j必须为3.您可以通过对类型1 * 3 ≡ .j的证明进行进一步模式匹配来实现此目的:

m235 : 2 * 3 ≡ 5 → ⊥
m235 ((succ (succ base znn)) sum) = ?

现在上下文如下:

Goal: ⊥
————————————————————————————————————————————————————————————
x : 3 + 3 ≡ 5

现在,您可以将x类型的证明3 + 3 ≡ 5与先前证明此类证明不存在的证据相结合完成:

m235 : 2 * 3 ≡ 5 → ⊥
m235 (succ (succ base znn) x) = 3+3≡5 x

更新:我在第一次阅读时错过了,但在我错过的问题上有一个误解而且没有解释。错误在以下代码中:

m235 : 2 * 3 ≡ 5 → ⊥
m235 (succ  1*3≡3 x) = 3+3≡5 x

这里的误解是,本节左侧的变量名1 *3≡3并未引用先前定义的相同名称的值。相反,它引入了一个新的新变量,Agda知道该变量具有相同的类型,但其值不为人所知。

使用Agda 2.3.2中引入的“模式同义词”功能可以实现您的期望:请参阅the release notes

pattern 1*3≡3 = (succ base) znn

m235 : 2 * 3 ≡ 5 → ⊥
m235 (succ  1*3≡3 x) = 3+3≡5 x

只有模式同义词在模式中扩展,其他值不是。