Isabelle 涉及映射的数据类型上函数的终止证明

Isabelle 涉及映射的数据类型上函数的终止证明,isabelle,termination,Isabelle,Termination,我有以下记录语言: datatype "term" = Rcd "string ⇀ term" fun id_term :: "term ⇒ term" where "id_term (Rcd vals) = Rcd (map_option id_term ∘ vals)" 这不会通过终止检查器,因为类型的size函数始终为0。我也不知道如何在不将映射约束到有限域的情况下提供可计算的度量 那么:我如何证明上述定义的终止?我怀疑我必须证明某些归纳谓词在术语上的良好基础,但我不确定如何做到

我有以下记录语言:

datatype "term" = Rcd "string ⇀ term"

fun id_term :: "term ⇒ term" 
  where "id_term (Rcd vals) = Rcd (map_option id_term ∘ vals)"
这不会通过终止检查器,因为类型的
size
函数始终为0。我也不知道如何在不将映射约束到有限域的情况下提供可计算的度量


那么:我如何证明上述定义的终止?我怀疑我必须证明某些归纳谓词在术语上的良好基础,但我不确定如何做到这一点。

您可以使用
primrec
定义此函数:

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

primrec
允许您使用相关类型构造函数的
map
函数。在您的例子中,这是
map\u选项
op∘

您可以使用
primrec
定义此函数:

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

primrec
允许您使用相关类型构造函数的
map
函数。在您的例子中,这是
map\u选项
op∘

对于非原始递归函数,您也可以使用
函数
命令,但是由于没有
大小
度量,事情变得有点复杂。本质上,您必须定义一个子项关系并证明它是有根据的,然后您可以使用它来表明您的函数终止:

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

对于非原始递归函数,也可以使用
函数
命令,但由于没有
大小
度量值,事情会变得更加复杂。本质上,您必须定义一个子项关系并证明它是有根据的,然后您可以使用它来表明您的函数终止:

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

啊,下面安德烈亚斯·洛希比勒的评论基本上概括了这一推理。啊,下面安德烈亚斯·洛希比勒的评论基本上概括了这一推理。哇,正如我所怀疑的,这真是太多了。谢谢你的努力!虽然简单的
primrec
解决方案对我来说已经足够了,但这可能更符合我所问问题的答案;这只是我尝试的第一件事,效果相当不错。我有点期待数据类型包在默认情况下生成类似的内容,但显然不是这样。您还可以使用
subterm_rel
的传递闭包作为您的关系,这给了您更多的灵活性。这与当前的问题并不相关,但是对于二进制关系的自反闭包和传递闭包是否有一些库解决方案?请看
~/src/HOL/transitive_闭包。thy
。它有
reflcl
trancl
rtrancl
用于二元关系的自反/传递/自反传递闭包(建模为一组对)。对于被建模为二元谓词的二元关系,也有一些变量的末尾带有一个
p
。哇,正如我所怀疑的,这真是太多了。谢谢你的努力!虽然简单的
primrec
解决方案对我来说已经足够了,但这可能更符合我所问问题的答案;这只是我尝试的第一件事,效果相当不错。我有点期待数据类型包在默认情况下生成类似的内容,但显然不是这样。您还可以使用
subterm_rel
的传递闭包作为您的关系,这给了您更多的灵活性。这与当前的问题并不相关,但是对于二进制关系的自反闭包和传递闭包是否有一些库解决方案?请看
~/src/HOL/transitive_闭包。thy
。它有
reflcl
trancl
rtrancl
用于二元关系的自反/传递/自反传递闭包(建模为一组对)。对于建模为二元谓词的二元关系,还有一些变量的末尾带有
p