我想定义一种相当简单的树,但是我不确定该怎么做。
首先,用自然数值定义一个标准的二叉树,除了我们不允许空树:
Inductive nat_btree : Type :=
| leaf : nat -> nat_btree
| unary : nat_btree -> nat -> nat_btree
| binary : nat_btree -> nat_btree -> nat -> nat_btree.
现在,我想做的是定义一个数据类型,我们将其称为special_nat_btree,它是一个nat_btree,其条件是每个节点都是:
例如,我们可以有以下内容:
1
|
2 2 3
\ / |
4 4
\ /
16
|
17
但是我真的不知道正确的语法,甚至不知道在Coq中实现该语法的最佳方法。我最初的想法是要求证明子树中的“根值”与我们要构造的内容相匹配。因此,例如,上面的“一元”构造函数将变为:
unary : forall (t : special_nat_btree) (n : nat),
special_nat_btree -> nat -> (n = S (root_val t)) ->
special_nat_btree
除了上面的语法可能已经错误之外,这种方法还需要定义一个“ root_val”函数,该函数将与special_nat_btree相互递归。填写我的推理,我得到以下信息(它将无法编译):
Inductive special_nat_btree : Type :=
| leaf : nat -> special_nat_btree
| unary : forall (t : special_nat_btree) (n : nat),
special_nat_btree -> nat -> (n = S (root_val t)) ->
special_nat_btree
| binary : forall (t_1 t_2 : special_nat_btree) (n : nat),
special_nat_btree -> special_nat_btree -> nat ->
(root_val t_1 = root_val t_2) ->
(n = (root_val t_1) * (root_val t_1)) -> special_nat_btree
with
root_val (t : special_nat_btree) : nat :=
match t with
| leaf n => n
| unary t' n p => n
| binary t_1 t_2 n p_1 p_2 => n
end.
而且,嗯,我敢肯定,我已经偏离了这个方向。那么我应该如何处理呢?或者,如果我的想法还没有完全解决,完成我想做的事情的正确语法是什么?
答案 0 :(得分:4)
该索引类型如何
(* [btree n]: tree with root value [n]. *)
Inductive btree : nat -> Type :=
| leaf : forall n, btree n
| unary : forall n, btree n -> btree (S n)
| binary : forall n, btree n -> btree n -> btree (n * n)
.
然后使用sigma表示不确定的树:
Definition tree : Type := { n : nat & btree n }.
例如:
Example foo : tree := existT _ _
(unary _ (binary _ (binary _ (unary _ (leaf 1))
(leaf 2))
(unary _ (leaf 3)))).
树中的_
实际上不是您所描述的节点的值,而是实际值(n
中的btree n
)根据这些字段的内容计算得出(因此,只需将它们保留在上面就比较容易混淆):unary x _
是一个值为x+1
的节点,其子节点的值为x
。