Рассмотрим следующее глупое определение Изабель деревьев и поддеревьев:
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
Конечно, это невозможно доказать, поскольку информация о том, что xa
является потомком t
, потеряна. Я сделал что-то не так? Могу ли я что-нибудь сделать, чтобы сохранить доказательство? Замечу, что я могу сформулировать то же определение, используя списки вместо наборов:
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
Это какое-то ограничение в Изабель, которое я должен просто обойти, не используя для этого наборы?
subtrees
всегда возвращает пустой набор? - person Manuel Eberl   schedule 28.10.2015