agda的检查功能如何运作?

时间:2013-09-02 01:46:10

标签: proof agda

我在上一个问题Using the value of a computed function for a proof in agda中看到过检查功能的一个例子,但是我仍然无法绕过那个问题。

这是一个简单的例子:

给定函数crazy

crazy : ℕ -> ℕ
crazy 0 = 10
crazy 1 = 0
crazy 2 = 0
crazy 3 = 1
crazy 4 = 0
crazy xxx = xxx

我想创建一个safe函数,使safe : {nn : ℕ} -> (id nn) ≢ 0 -> Fin (id nn)。换句话说,它会返回一个数字mod疯狂,如果你给它一个疯狂的证据是0.(我知道这个例子有点做作,我可能最好在函数签名中使用suc

我的第一个解决方案是

safebad : {nn : ℕ} -> (crazy nn) ≢ 0 -> Fin (crazy nn)
safebad {1} hh with hh refl
... | ()
safebad {2} hh with hh refl
... | ()
safebad {4} hh with hh refl
... | ()
safebad {0} hh = # 0
safebad {3} hh = # 0
safebad {suc (suc (suc (suc (suc _))))} _ = # 0

但这很漫长而且很混乱。所以我试图在Using the value of a computed function for a proof in agda中模仿这个例子,但只能到目前为止

safegood : (nn : ℕ) -> (crazy nn) ≢ 0 -> Fin (crazy nn)
safegood nn nez with crazy nn | inspect crazy nn
... | 0 | [ proof ] = ⊥-elim ???
... | _ | _ = # 0

inspect使用Hidden来隐藏类型签名中的函数应用程序的记录,我想。然后可以使用揭示来检索。

我认为这是我理解的:

Reveal_is_似乎保留了隐藏fx的值;以及x的结果应用于f[_]将证明这种平等。

⊥-elim证明了矛盾,并引发了矛盾。

我将???用于此工作的内容是什么?

1 个答案:

答案 0 :(得分:3)

你正在使它变得不必要地复杂化。 inspect仅在需要使用模式匹配前的值等于模式匹配后的值的证明时才有用。请注意,您在范围内有nez,这使得这很简单。

我们真正想要做的是将假设crazy nn ≢ 0减少到0 ≢ 0,我们可以轻松地将其用于构建矛盾。我们如何将crazy nn缩减为0?您已经尝试过第一个选项 - 浏览所有可能的crazy参数,然后查找确实将crazy nn缩减为0的参数。另一种选择是简单地抽象crazy nn

的值

首先,我们使用with之前的目标类型是Fin (crazy nn)nez的类型是crazy nn ≢ 0。现在,我们抽象crazy nn

safegood nn nez with crazy nn
... | w = ?

请注意,我们的目标现在是Fin wnez的类型为w ≢ 0,更容易使用!最后,我们在w上模式匹配:

safegood nn nez with crazy nn
... | zero  = ?
... | suc w = ?

第一个目标现在是Fin 0,我们有一个0 ≢ 0作为我们的假设之一。这显然是一个废话,将nezrefl结合起来给我们提供了⊥-elim可以使用的矛盾:

safegood nn nez with crazy nn
... | zero  = ⊥-elim (nez refl)
... | suc w = ?

看不到inspect!事实上,在这里使用inspect就像往返一样:您将类型中的crazy nn缩减为0,获得crazy nn ≡ 0的证明,现在您需要“无法减少“0返回crazy nn,以便您可以使用nez proof


为了完整起见:您可以通过使用已弃用的crazy nn来避免nez上的模式匹配,以保持证明inspect的类型完整:

open Deprecated-inspect
  renaming (inspect to inspect′)

safegood₂ : (nn : ℕ) → crazy nn ≢ 0 → Fin (crazy nn)
safegood₂ nn nez with inspect′ (crazy nn)
... | zero  with-≡ eq = ⊥-elim (nez eq)
... | suc _ with-≡ eq = ?

由于我们抽象inspect′ (crazy nn),所以没有crazy nn子表达式被替换,nez将保留其原始类型。


谈论疯狂的往返:您可以使用proof来重建nez的原始类型;再次,这更像是“可能有用的知识”,而不是“在这里使用”:

safegood : (nn : ℕ) → crazy nn ≢ 0 → Fin (crazy nn)
safegood nn nez with crazy nn | inspect crazy nn
... | 0 | [ proof ] = ⊥-elim (subst (λ x → x ≢ 0) (sym proof) nez proof)
... | _ | _         = ?