Ben*_*son 4 tree agda dependent-type
我通过学习 Agda 来自学依赖类型。
这是一种按大小平衡的二叉树类型。
open import Data.Nat
open import Data.Nat.Properties.Simple
data T (A : Set) : ? -> Set where
empty : T A 0
leaf : A -> T A 1
bal : ? {n} -> T A n -> T A n -> T A (n + n)
heavyL : ? {n} -> T A (suc n) -> T A n -> T A (suc (n + n))
Run Code Online (Sandbox Code Playgroud)
一棵树可以是完全平衡的 ( bal),或者左子树可以比右子树多包含一个元素 ( heavyL)。(在这种情况下,下一个插入将进入右子树。)这个想法是插入将在树的左半部分和右半部分之间翻转,有效地(确定性地)打乱输入列表。
我无法定义类型检查insert:
insert : ? {A n} -> A -> T A n -> T A (suc n)
insert x empty = leaf x
insert x (leaf y) = bal (leaf x) (leaf y)
insert x (bal l r) = heavyL (insert x l) r
insert x (heavyL l r) = bal l (insert x r)
Run Code Online (Sandbox Code Playgroud)
Agda 拒绝bal l (insert x r)作为heavyL案例的右侧:
.n + suc .n != suc (.n + .n) of type ?
when checking that the expression bal l (insert x r) has type
T .A (suc (suc (.n + .n)))
Run Code Online (Sandbox Code Playgroud)
我试图用证明来修补我的定义......
insert x (heavyL {n} l r) rewrite +-suc n n = bal l (insert x r)
Run Code Online (Sandbox Code Playgroud)
...但我收到相同的错误消息。(我误解了什么rewrite?)
我还尝试在相同的证明假设下转换等效大小的树:
convertT : ? {n m A} -> T A (n + suc m) -> T A (suc (n + m))
convertT {n} {m} t rewrite +-suc n m = t
insert x (heavyL {n} l r) rewrite +-suc n n = bal (convertT l) (convertT (insert x r))
Run Code Online (Sandbox Code Playgroud)
Agda 接受了这种可能性,但以黄色突出显示了该等式。我想我需要明确给出我传递给bal构造函数的两个子树的大小:
insert x (heavyL {n} l r) rewrite +-suc n n = bal {n = suc n} (convertT l) (convertT (insert x r))
Run Code Online (Sandbox Code Playgroud)
但是现在我再次收到相同的错误消息!
n + suc n != suc (n + n) of type ?
when checking that the expression
bal {n = suc n} (convertT l) (convertT (insert x r)) has type
T .A (suc (suc (n + n)))
Run Code Online (Sandbox Code Playgroud)
我没有想法了。我确定我犯了一个愚蠢的错误。我究竟做错了什么?我需要做什么来定义类型检查insert?
您的rewrite尝试几乎可以奏效,但它使用的相等性正朝着错误的方向发展。为了让它朝着正确的方向工作,你可以翻转它:
open import Relation.Binary.PropositionalEquality
-- ...
insert x (heavyL {n} l r) rewrite sym (+-suc n n) = bal l (insert x r)
Run Code Online (Sandbox Code Playgroud)
或使用with条款:
insert x (heavyL {n} l r) with bal l (insert x r)
... | t rewrite +-suc n n = t
Run Code Online (Sandbox Code Playgroud)
另一种可能性是在右侧自己执行替换:
open import Relation.Binary.PropositionalEquality
-- ...
insert x (heavyL {n} l r) = subst (T _) (+-suc (suc n) n) (bal l (insert x r))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
153 次 |
| 最近记录: |