如何在agda中证明一种形式(a | b)?

时间:2014-10-28 17:49:15

标签: agda dependent-type

在考虑:

In Agda is it possible to define a datatype that has equations?

我正在使用以下数据类型:

data Int : Set where
    Z : Int
    S : Int -> Int
    P : Int -> Int

以上是整数的不良定义,上面的答案给出了解决方法。但是,可以定义可能有用的上述Int类型的减少。

normalize : Int -> Int
normalize Z = Z
normalize (S n) with normalize n
... | P m = m
... | m = S m
normalize (P n) with normalize n
... | S m = m
... | m = P m

需要证明的是:

idempotent : (n : Int) -> normalize n \== normalize (normalize n)

当您展开案例时,您可以获得例如

idempotent (P n) = ? 

洞的目标有类型

(normalize (P n) | normalize n) \== normalize (normalize (P n) | normalize n)

我还没有看到这个“|”之前,我也不知道如何制作涉及它们的类型证明。证明需要模式匹配,例如,

idempotent (P n) with inspect (normalize n)
... (S m) with-\== = ?
... m with-\== = ?

但是这里第二个案例的洞仍然有一个“|”在里面。所以我有点困惑。

--------编辑---------------

证明一个更简单的陈述会有所帮助:

normLemma : (n m : NZ) -> normalize n \== P m -> normalize (S n) \== m

“纸上”证明非常简单。假设归一化n = P m,考虑

normalize (S n) = case normalize n of
  P k -> k
  x -> S x

但是,将n归一化假定为P m,因此归一化(S n)= k。然后k = m,因为归一化n = P m = P k,这意味着m = k。因此归一化(S n)= m。

2 个答案:

答案 0 :(得分:3)

用户 Vitus 建议使用普通表格。

如果我们有这两个功能:

normalForm : ∀ n -> NormalForm (normalize n)
idempotent' : ∀ {n} -> NormalForm n -> normalize n ≡ n

然后我们可以轻松地将它们组合起来以获得我们需要的结果:

idempotent : ∀ n -> normalize (normalize n) ≡ normalize n
idempotent = idempotent' ∘ normalForm

以下是正常形式的定义:

data NormalForm : Int -> Set where
  NZ  : NormalForm Z
  NSZ : NormalForm (S Z)
  NPZ : NormalForm (P Z)
  NSS : ∀ {n} -> NormalForm (S n) -> NormalForm (S (S n))
  NPP : ∀ {n} -> NormalForm (P n) -> NormalForm (P (P n))

即。只有S (S ... (S Z)...P (P ... (P Z)...)这样的字词才是正常形式。

证据相当简单:

normalForm : ∀ n -> NormalForm (normalize n)
normalForm  Z    = NZ
normalForm (S n) with normalize n | normalForm n
... | Z    | nf     = NSZ
... | S  _ | nf     = NSS nf
... | P ._ | NPZ    = NZ
... | P ._ | NPP nf = nf
normalForm (P n) with normalize n | normalForm n
... | Z    | nf     = NPZ
... | S ._ | NSZ    = NZ
... | S ._ | NSS nf = nf
... | P  _ | nf     = NPP nf

idempotent' : ∀ {n} -> NormalForm n -> normalize n ≡ n
idempotent'  NZ     = refl
idempotent'  NSZ    = refl
idempotent'  NPZ    = refl
idempotent' (NSS p) rewrite idempotent' p = refl
idempotent' (NPP p) rewrite idempotent' p = refl

整个代码:https://gist.github.com/flickyfrans/f2c7d5413b3657a94950#file-another-one

答案 1 :(得分:2)

idempotent : (n : Int) -> normalize (normalize n) ≡ normalize n
idempotent  Z    = refl
idempotent (S n) with normalize n | inspect normalize n
... | Z   |   _   = refl
... | S m | [ p ] = {!!}
... | P m | [ p ] = {!!}

第一洞的背景是

Goal: (normalize (S (S m)) | (normalize (S m) | normalize m)) ≡
      S (S m)
————————————————————————————————————————————————————————————
p : normalize n ≡ S m
m : Int
n : Int

(normalize (S (S m)) | (normalize (S m) | normalize m)) ≡ S (S m)只是normalize (S (S m))的扩展版本。所以我们可以稍微改写一下上下文:

Goal: normalize (S (S m)) ≡ S (S m)
————————————————————————————————————————————————————————————
p : normalize n ≡ S m
m : Int
n : Int

由于normalize函数的定义

normalize (S n) with normalize n
... | P m = m
... | m = S m

normalize (S n) ≡ S (normalize n),如果normalize n不包含P s。

如果我们有一个类似normalize n ≡ S m的等式,那么m已经标准化,并且不包含P s。但如果m不包含P,那么normalize m。我们有normalize (S m) ≡ S (normalize m)

让我们证明一个更普遍的引理:

normalize-S : ∀ n {m} -> normalize n ≡ S m -> ∀ i -> normalize (m ‵add‵ i) ≡ m ‵add‵ i

其中`add`是

_‵add‵_ : Int -> ℕ -> Int
n ‵add‵  0      = n
n ‵add‵ (suc i) = S (n ‵add‵ i)

normalize-S表示,如果m不包含P,则表示如下:

normalize (S (S ... (S m)...)) ≡ S (S ... (S (normalize m))...)

这是一个证据:

  normalize-S : ∀ n {m} -> normalize n ≡ S m -> ∀ i -> normalize (m ‵add‵ i) ≡ m ‵add‵ i
  normalize-S  Z    ()    i
  normalize-S (S n) p     i with normalize n | inspect normalize n
  normalize-S (S n) refl  i | Z       |   _   = {!!}
  normalize-S (S n) refl  i | S m     | [ q ] = {!!}
  normalize-S (S n) refl  i | P (S m) | [ q ] = {!!}
  normalize-S (P n) p     i with normalize n | inspect normalize n
  normalize-S (P n) ()    i | Z       |   _     
  normalize-S (P n) refl  i | S (S m) | [ q ] = {!!}
  normalize-S (P n) ()    i | P _     |   _

第一洞的背景是

Goal: normalize (Z ‵add‵ i) ≡ Z ‵add‵ i
————————————————————————————————————————————————————————————
i  : ℕ
.w : Reveal .Data.Unit.Core.hide normalize n is Z
n  : Int

即。 normalize (S (S ... (S Z)...)) ≡ S (S ... (S Z)...)。我们可以很容易地证明这一点:

normalize-add : ∀ i -> normalize (Z ‵add‵ i) ≡ Z ‵add‵ i
normalize-add  0      = refl
normalize-add (suc i) rewrite normalize-add i with i
... | 0     = refl
... | suc _ = refl

所以我们可以用normalize-add i填充第一个洞。

第二洞的背景是

Goal: normalize (S m ‵add‵ i) ≡ S m ‵add‵ i
————————————————————————————————————————————————————————————
i : ℕ
q : .Data.Unit.Core.reveal (.Data.Unit.Core.hide normalize n) ≡ S m
m : Int
n : Int

虽然normalize-S n q (suc i)具有以下类型:

(normalize (S (m ‵add‵ i)) | normalize (m ‵add‵ i)) ≡ S (m ‵add‵ i)

或者,很快,normalize (S (m ‵add‵ i)) ≡ S (m ‵add‵ i)。因此,我们需要将S m ‵add‵ i替换为S (m ‵add‵ i)

inj-add : ∀ n i -> S n ‵add‵ i ≡ S (n ‵add‵ i)
inj-add n  0      = refl
inj-add n (suc i) = cong S (inj-add n i)

现在我们可以写

  normalize-S (S n) refl  i | S m | [ q ] rewrite inj-add m i = normalize-S n q (suc i)

第三洞的背景是

Goal: normalize (m ‵add‵ i) ≡ m ‵add‵ i
————————————————————————————————————————————————————————————
i : ℕ
q : .Data.Unit.Core.reveal (.Data.Unit.Core.hide normalize n) ≡
    P (S m)
m : Int
n : Int

normalize-P n q 0为我们提供了normalize (S m) ≡ S m,其中normalize-Pnormalize-S的双重身份,并且具有以下类型:

  normalize-P : ∀ n {m} -> normalize n ≡ P m -> ∀ i -> normalize (m ‵sub‵ i) ≡ m ‵sub‵ i

我们可以将normalize-S应用于类型normalize (S m) ≡ S mnormalize-S (S m) (normalize-P n q 0) i的内容。这个表达式正是我们想要的类型。所以我们可以写

  normalize-S (S n) refl  i | P (S m) | [ q ] = normalize-S (S m) (normalize-P n q 0) i

第四洞与第三洞类似:

  normalize-S (P n) refl  i | S (S m) | [ q ] = normalize-S (S m) (normalize-S n q 0) i

这个漏洞存在问题:Agda没有看到normalize-S (S m) _ _终止,因为S m在语法上不小于S n。然而,通过使用有根据的递归来使Agda更有可能。

拥有所有这些东西我们可以很容易地证明idempotent定理:

idempotent : (n : Int) -> normalize (normalize n) ≡ normalize n
idempotent  Z    = refl
idempotent (S n) with normalize n | inspect normalize n
... | Z   |   _   = refl
... | S m | [ p ] = normalize-S n p 2
... | P m | [ p ] = normalize-P n p 0
idempotent (P n) with normalize n | inspect normalize n
... | Z   |   _   = refl
... | S m | [ p ] = normalize-S n p 0
... | P m | [ p ] = normalize-P n p 2

以下是代码:https://gist.github.com/flickyfrans/f2c7d5413b3657a94950 有两个版本:{-# TERMINATING #-} pragma和没有。

修改

idempotent只是

idempotent : ∀ n -> normalize (normalize n) ≡ normalize n
idempotent n with normalize n | inspect normalize n
... | Z   |   _   = refl
... | S _ | [ p ] = normalize-S n p 1
... | P _ | [ p ] = normalize-P n p 1