У меня есть следующий язык записей:

datatype "term" = Rcd "string ⇀ term"

fun id_term :: "term ⇒ term" 
  where "id_term (Rcd vals) = Rcd (map_option id_term ∘ vals)"

Это не проходит проверку завершения, потому что функция типа size постоянно равна 0. Я также не вижу, как обеспечить вычислимую меру, не ограничивая отображение конечной областью.

Итак: Как я могу доказать прекращение для приведенного выше определения? Я подозреваю, что должен доказать обоснованность некоторых индуктивных предикатов в терминах, но я не совсем уверен, как это сделать.

0
Sebastian Graf 24 Апр 2017 в 12:00

2 ответа

Лучший ответ

Для не примитивно-рекурсивных функций вы также можете использовать команду function, но все становится немного сложнее из-за того, что у вас нет size меры. По сути, вы должны определить подтермическое отношение и показать, что оно обосновано, а затем вы можете использовать это, чтобы показать, что ваша функция завершается:

datatype "term" = Rcd "string ⇀ term"

inductive subterm :: "term ⇒ term ⇒ bool" where
  "t ∈ ran f ⟹ subterm t (Rcd f)"

lemma accp_subterm: "Wellfounded.accp subterm t"
proof (induction t)
  case (Rcd f)
  have IH: "Wellfounded.accp subterm t" if "t ∈ ran f" for t
    using Rcd[of "Some t" t] and that by (auto simp: eq_commute ran_def)
  show ?case by (rule accpI) (auto intro: IH elim!: subterm.cases)
qed

definition subterm_rel where "subterm_rel = {(t, Rcd f) |f t. t ∈ ran f}"

lemma subterm_rel_altdef: "subterm_rel = {(s, t) |s t. subterm s t}"
  by (auto simp: subterm_rel_def subterm.simps)

lemma subterm_relI [intro]: "t ∈ ran f ⟹ (t, Rcd f) ∈ subterm_rel"
  by (simp add: subterm_rel_def)

lemma subterm_relI' [intro]: "Some t = f x ⟹ (t, Rcd f) ∈ subterm_rel"
  by (auto simp: subterm_rel_def ran_def)

lemma wf_subterm_rel [simp, intro]: "wf subterm_rel"
  using accp_subterm unfolding subterm_rel_altdef accp_eq_acc wf_acc_iff by simp

function id_term :: "term ⇒ term" 
  where "id_term (Rcd vals) = Rcd (map_option id_term ∘ vals)"
by pat_completeness simp_all
termination by (relation subterm_rel) auto
2
Manuel Eberl 24 Апр 2017 в 15:19

Вы можете определить эту функцию используя primrec:

primrec id_term :: "term ⇒ term"
  where "id_term (Rcd vals) = Rcd (map_option id_term ∘ vals)"

primrec позволяет использовать функции map задействованных конструкторов типов. В вашем случае это map_option и op ∘.

2
larsrh 24 Апр 2017 в 09:12