简体   繁体   English

在Agda中编写证明

[英]Writing Proofs in Agda

I want to write proofs of the statement "for all x there exist ay such that x < y and y is even ". 我想写一些声明的证明“对于所有x,存在这样的x <y和y是偶数”。 I tried in this way... 我试过这种方式......

-- ll means less function i.e ' < '

_ll_ : ℕ → ℕ → Bool
0 ll 0 = false
0 ll _ = true
a ll 0 = false
(suc a) ll (suc b) = a ll b 

even : ℕ → Bool
even 0 = true
even 1 = false
even (suc (suc n)) = even n

Teven : Bool → Set
Teven true = ⊤
Teven false = ⊥


thm0 : (x : ℕ) →  Σ[ y ∈ ℕ ]  (Teven ( and (x ll y) (even y))) 
thm0 0 = suc (suc zero) , record {}
thm0 (suc a) = ?

for the last line ie for 'suc a' agda is not able to find solution. 对于最后一行,即'suc a'agda无法找到解决方案。 I once tried by writing 2 * suc a , record {}. 我曾经写过2 * suc a,record {}。 But this is also not working. 但这也行不通。 Any help will be appreciated. 任何帮助将不胜感激。

What you actually want is to do two steps at once. 你真正想要的是一次做两个步骤。

The problem with this kind of definitions is something that is called "boolean blindness" - by encoding your propositions as booleans, you lose any kind of useful information they contain. 这种定义的问题被称为“布尔盲” - 通过将您的命题编码为布尔值,您将丢失它们包含的任何有用信息。 The effect is that you have to rely on normalization to (hopefully) do its thing, you cannot help Agda in any other way (say by pattern matching on proof terms). 效果是你必须依靠规范化(希望)做它的事情,你不能以任何其他方式帮助Agda(比如通过证据条件上的模式匹配)。

However, in your case, you can change the definition of thm0 slightly to help Agda with normalization. 但是,在您的情况下,您可以稍微更改thm0的定义以帮助Agda进行规范化。 even makes two suc steps in every recursion step - you can make thm0 do two steps as well. even提出了两个suc在每个递归步骤步骤-你可以让thm0做两步为好。

Let's take a look: 让我们来看看:

thm0 : ∀ x → ∃ λ y → Teven ((x ll y) ∧ (even y))
thm0 zero = suc (suc zero) , tt

Two new cases are for suc zero (also known as 1 ): 两个新案例是suc zero (也称为1 ):

thm0 (suc zero) = suc (suc zero) , tt

And for suc (suc x') : 而对于suc (suc x')

thm0 (suc (suc x') = ?

Now, if we knew that y (the one you existentially quantified over) is suc (suc y') for some other y' , Agda could normalize even y to even y' (this is just following the definition). 现在,如果我们知道y (你存在量化的那个suc (suc y')对于其他y'是成功的suc (suc y') ,那么Agda even y可以将even y归一化到even y' (这只是遵循定义)。 Same deal with the "less-than" proof - once you know that x = suc (suc x') and y = suc (suc y') for some y' ( x' we already know), you can reduce x ll y to x' ll y' . 同样处理“小于”证明 - 一旦你知道某些y'x'我们已经知道) x = suc (suc x')y = suc (suc y') ),你就可以减少x ll yx' ll y'

So the choice for y is simple... but how do we get y' (and the proof, of course)? 因此y的选择很简单......但我们如何得到y' (当然还有证据)? We can use induction (recursion) and apply thm0 to x' ! 我们可以使用归纳(递归)并将thm0应用于x' Remember that given x' , thm0 returns some y' together with a proof that even y' and x' ll y' - this is precisely what we need. 请记住,给x' thm0返回一些y'连同证明, even y'x' ll y' -这正是我们需要的。

thm0 (suc (suc a)) with thm0 a
... | y' , p = ?

Then we simply plug in y = suc (suc y') and p (as stated above, (x ll y) ∧ even y reduces to (x' ll y') ∧ even y' , which is p ). 然后我们简单地插入y = suc (suc y')p (如上所述, (x ll y) ∧ even y减少到(x' ll y') ∧ even y' ,即p )。

Final code: 最终代码:

thm0 : ∀ x → ∃ λ y → Teven ((x ll y) ∧ (even y))
thm0 zero = suc (suc zero) , tt
thm0 (suc zero) = suc (suc zero) , tt
thm0 (suc (suc x')) with thm0 x'
... | y' , p = suc (suc y') , p

However, that being said, I'd advice against this. 然而,话虽如此,我建议不要这样做。 Do not encode your propositions as booleans and then use them at the type level via Teven . 不要将您的命题编码为布尔值,然后通过Teven在类型级别使用它们。 This really only works for simple things and cannot be extended to more complicated propositions. 这真的只适用于简单的事情,不能扩展到更复杂的命题。 Instead, try explicit proof terms: 相反,尝试明确的证据条款:

data _less-than_ : ℕ → ℕ → Set where
  suc : ∀ {x y} → x less-than y → x less-than suc y
  ref : ∀ {x}                   → x less-than suc x

data Even : ℕ → Set where
  zero    :                  Even 0
  suc-suc : ∀ {x} → Even x → Even (2 + x)

thm0 can be then written using a simple lemma: thm0可以使用一个简单的引理来编写thm0

something-even : ∀ n → Even n ⊎ Even (suc n)
something-even zero = inj₁ zero
something-even (suc n) with something-even n
... | inj₁ x = inj₂ (suc-suc x)
... | inj₂ y = inj₁ y

(this states that either n is even or its successor is even). (这表明n是偶数或其后继者是偶数)。 In fact, thm0 can be implemented without using recursion! 实际上, thm0可以在不使用递归的情况下实现!

thm0 : ∀ x → ∃ λ y → Even y × x less-than y
thm0 n with something-even n
... | inj₁ x = suc (suc n) , suc-suc x , suc ref
... | inj₂ y = suc n , y , ref

Funnily enough, when I wrote this definition, I just pattern matched on something-even (suc n) and used Ca (autocomplete) to fill in the right sides! 有趣的是,当我写这个定义时,我只是模仿匹配的something-even (suc n)并使用Ca (自动完成)来填充右边! When given enough hints, Agda can write the code without my help. 如果给出足够的提示,Agda可以在没有我帮助的情况下编写代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM