【问题标题】:Termination proof with functions using set comprehensions使用集合推导的函数终止证明
【发布时间】:2015-10-27 22:08:34
【问题描述】:

考虑以下对树和子树的愚蠢 Isabelle 定义:

datatype tree = Leaf int
              | Node tree tree

fun children :: "tree ⇒ tree set" where
"children (Leaf _) = {}" |
"children (Node a b) = {a, b}"

lemma children_decreasing_size:
  assumes "c ∈ children t"
  shows   "size c < size t"
using assms
by (induction t, auto)

function subtrees :: "tree ⇒ tree set" where
"subtrees t = { s | c s. c ∈ children t ∧ s ∈ subtrees c }"
by auto
termination
apply (relation "measure size", simp)

subtrees 的终止证明在这一点上卡住了,尽管递归调用只对孩子进行,根据有充分根据的 size 关系严格来说,这些孩子更小(正如微不足道的引理所示)。

证明状态如下:

goal (1 subgoal):
 1. ⋀t x xa xb. (xa, t) ∈ measure size

当然,这是不可能证明的,因为xat 的子代的信息丢失了。我做错什么了吗?我能做些什么来保存证明吗?我注意到我可以使用列表而不是集合来制定相同的定义:

fun children_list :: "tree ⇒ tree list" where
"children_list (Leaf _) = []" |
"children_list (Node a b) = [a, b]"

function subtrees_list :: "tree ⇒ tree list" where
"subtrees_list t = concat (map subtrees_list (children_list t))"
by auto
termination
apply (relation "measure size", simp)

并获得一个信息更丰富、可证明的终止目标:

goal (1 subgoal):
 1. ⋀t x.
       x ∈ set (children_list t) ⟹
       (x, t) ∈ measure size

这是 Isabelle 的一些限制,我应该通过不使用集合来解决这个问题吗?

【问题讨论】:

  • 您是否知道,根据您的定义,subtrees 总是返回空集?
  • 嘿,不错。这是从我正在尝试做的更复杂的事情中简化的(太多了)。

标签: isabelle termination


【解决方案1】:

subtrees 的集合推导中对c : children t 的限制没有出现在终止证明义务中,因为函数包不知道任何关于&amp; 的先验信息。可以使用同余规则来实现这一点。在这种情况下,您可以在本地将 conj_cong 声明为 [fundef_cong] 以基本上模拟从左到右的评估顺序(尽管在 HOL 中没有评估之类的东西)。例如,

context notes conj_cong[fundef_cong] begin
fun subtrees :: ...
termination ...
end

上下文块确保声明 conj_cong[fundef_cong] 仅对该函数定义有效。

带有列表的版本之所以有效,是因为它使用了函数map,默认情况下,该函数有一个一致性规则。如果您在集合上使用了单子绑定操作(而不是集合推导式),那么同样的方法也应该适用于集合。

【讨论】:

  • 另一个有效的定义:subtrees t = (⋃c∈children t. subtrees c)。但是,我认为原始递归定义可能更易于使用。
  • @Manuel Eberl:Union 是集合的一元绑定,所以你的建议正是我在上一句中所指的。
  • 哦,对了。当然。我没有注意到这一点。无论如何,这对所有读者来说可能并不明显。
  • 谢谢你们俩。在上面睡觉之后,我确实也想出了使用(⋃c∈children t. subtrees c) 的想法,虽然我不会猜到这就是“monadic bind”在这种情况下的意思。所以感谢您的澄清。
  • 实际上,准确地说,Union 是集合的一元 join。但是绑定,当然可以使用joinmap来定义,其中map是设置图像操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 2015-01-05
  • 2021-07-18
  • 2015-06-14
  • 1970-01-01
相关资源
最近更新 更多