如何使用fmmap_keys定义函数的终止顺序?

时间:2018-11-09 14:22:57

标签: isabelle

我正在尝试基于fmap为数据类型定义一个最高操作:

datatype t = A | B | C "(nat, t) fmap"

abbreviation
  "supc f xs ys ≡
    fmmap_keys
      (λk x. f x (the (fmlookup ys k)))
      (fmfilter (λk. k |∈| fmdom ys) xs)"

fun sup_t (infixl "⊔" 65) where
  "A ⊔ _ = A"
| "B ⊔ B = B"
| "B ⊔ _ = A"
| "C xs ⊔ C ys = C (supc (⊔) xs ys)"
| "C xs ⊔ _ = A"

并得到错误:

Unfinished subgoals:
(a, 1, <):
 1. ⋀ys x. size (the (fmlookup ys x)) < Suc (∑x∈fset (fset_of_fmap ys). Suc (case x of (a, x) ⇒ size x))
(a, 1, <=):
 1. ⋀ys x. size (the (fmlookup ys x)) ≤ Suc (∑x∈fset (fset_of_fmap ys). Suc (case x of (a, x) ⇒ size x))
(a, 2, <):
 1. ⋀xs xa. size xa < Suc (∑x∈fset (fset_of_fmap xs). Suc (case x of (a, x) ⇒ size x))
(a, 2, <=):
 1. ⋀xs xa. size xa ≤ Suc (∑x∈fset (fset_of_fmap xs). Suc (case x of (a, x) ⇒ size x))
(a, 3, <):
 1. False
Calls:
  a) (C xs, C ys) ~> (xa, the (fmlookup ys x))
Measures:
  1) λp. size (snd p)
  2) λp. size (fst p)
  3) size
Result matrix:
    1  2  3 
a:  ?  ?  <=

Could not find lexicographic termination order.

如果我简化作为第一个参数传递给fmmap_keys的函数,则错误消失:

abbreviation
  "supc f xs ys ≡
    fmmap_keys
      (λk x. x)
      (fmfilter (λk. k |∈| fmdom ys) xs)"

所以我想,该错误是由sup_t的复杂递归调用引起的。不终止的唯一可能来源是C («[x ↦ C (...)]»)形式的结构。但是,每次递归调用都会删除一个外部C,因此该函数应终止。

您能建议如何解决此错误或重新定义supc吗?


更新

这是一个替代定义:

abbreviation
  "supc f xs ys ≡
    fmap_of_list (map
      (λ(k, x). (k, f x (the (fmlookup ys k))))
      (sorted_list_of_fmap (fmfilter (λk. k |∈| fmdom ys) xs)))"

function sup_t (infixl "⊔" 65) where
  "A ⊔ _ = A"
| "B ⊔ x = (if x = B then B else A)"
| "C xs ⊔ x = (case x of C ys ⇒ C (supc sup_t xs ys) | _ ⇒ A)"
  by pat_completeness auto
termination
  apply auto

我必须证明以下子目标:

⋀a b. sup_t_dom (a, b)

如何展开sup_t_dom

1 个答案:

答案 0 :(得分:2)

请在下面的代码清单中找到可能可行的解决方案。


背景

亚历山大·克劳斯(Alexander Krauss)撰写的文档“在Isabelle / HOL中定义递归函数”(在Isabelle文档中也称为“函数定义教程”)中部分描述了您遇到的问题,在博士学位论文{ {3}}也是亚历山大·克劳斯(Alexander Krauss)撰写的。特别是,请参见教程的第4章和论文的3.3节。


t的大小

从前面提到的参考文献中,可以推断出证明sup_t终止的一种方法是提供合适的度量函数。在这种情况下,很明显,与数据类型的大小相关联的度量函数可能适用于该应用程序。不幸的是,t是一个嵌套类型,并且(在这种情况下)默认函数size似乎无法捕获数据类型的递归性质-并非总是如此(请参阅第3.3.2节)在论文中)。

第一步,我为t提供了一个新的size函数。该定义基于C中包含的x::t总数(该定义应易于修改以适合您对其他应用程序的需求)。


测量和终止

我发现度量函数(λ(xs, ys). size ys)适合证明sup_t的终止。此外,如果使用命令sup_t声明了fun,则在Isabelle中使用此度量函数来证明"size (the (fmlookup x k)) < size (C x)"的终止。但是,在这种情况下,无法证明递归调用的参数确实相对于由度量自动建立的关系而言确实减少了。但是,仅显示supc就足够了。

不幸的是,函数(λk x. f x (the (fmlookup ys k)))(如您的问题所述)相对于传递给ys的第一个参数在{{1 }}。因此,the (fmlookup ys k)可以取值the None。鉴于此问题似乎几乎与问题的主要主题正交,因此我决定不对其进行进一步调查,并对函数supc进行了修正,以确保可以保证返回{{ 1}}(您可能想明确证明以下指定的功能在行为上与您在问题中提供的功能相同,否则,提供一种可以自我验证的更好的选择):

t

此修改之后,先前的目标abbreviation "supc f xs ys ≡ fmmap_keys (λk x. if (k |∈| fmdom ys) then (f x (the (fmlookup ys k))) else A) (fmfilter (λk. k |∈| fmdom ys) xs)" 更改为"size (the (fmlookup x k)) < size (C x)",可以很容易地证明这一目标(请参阅引理"(k |∈| fmdom ys) ⟹ size (the (fmlookup x k)) < size (C x)")。如果将此引理声明为引入规则,则measure_cond的终止可以通过命令sup_t进行声明。


备注

我决定调查此问题并提供答案的主要原因是,我对该问题的一些主要主题了解甚少,并且想学习它们。结果,由于在这些领域缺乏经验/知识,我的回答可能不太理想。当然,如果您也对我在此处提出的解决方案是否最适合该应用程序有疑问,那么可能值得尝试在邮件列表上提出问题。


fun