在考虑:
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。
答案 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-P
是normalize-S
的双重身份,并且具有以下类型:
normalize-P : ∀ n {m} -> normalize n ≡ P m -> ∀ i -> normalize (m ‵sub‵ i) ≡ m ‵sub‵ i
我们可以将normalize-S
应用于类型normalize (S m) ≡ S m
:normalize-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