Isabelle是否等同于Haskell newtype?

时间:2014-12-10 22:34:01

标签: abstraction isabelle

我想创建一个形状像旧的数据类型,但是(与使用type_synonym不同)它应该被认为在其他理论中是独特的。

我的激励示例:我正在从列表中创建堆栈数据类型。我不希望我的其他理论将我的stack视为list,因此我可以对其执行自己的简化规则,但我发现的唯一解决方案是以下:

datatype 'a stk = S "'a list"

...

primrec index_of' :: "'a list => 'a => nat option"
where "index_of' [] b = None"
    | "index_of' (a # as) b = (
          if b = a then Some 0 
          else case index_of' as b of Some n => Some (Suc n) | None => None)"

primrec index_of :: "'a stk => 'a => nat option"
where "index_of (S as) x = index_of' as x"

...

lemma [simp]: "index_of' del v = Some m ==> m <= n ==> 
                  index_of' (insert_at' del n v) v = Some m"
<proof>

lemma [simp]: "index_of del v = Some m ==> m <= n ==> 
                  index_of (insert_at del n v) v = Some m"
by (induction del, simp)

它有效,但这意味着我的stack理论膨胀并充满了冗余:每个函数都有第二个版本剥离构造函数,每个定理都有第二个版本(证明是总是 by (induction del, simp),这让我觉得这是我在某个地方做太多工作的迹象。)

这里有什么有用的吗?

1 个答案:

答案 0 :(得分:3)

您想使用typedef

声明

typedef 'a stack = "{xs :: 'a list. True}" 
  morphisms list_of_stack as_stack
  by auto

引入了一个新类型,包含所有列表,以及'a stack'a list之间的函数以及一堆定理。以下是它们的选择(您可以在show_theorems命令后使用typedef查看所有内容):

theorems:
  as_stack_cases: (⋀y. ?x = as_stack y ⟹ y ∈ {xs. True} ⟹ ?P) ⟹ ?P
  as_stack_inject: ?x ∈ {xs. True} ⟹ ?y ∈ {xs. True} ⟹ (as_stack ?x = as_stack ?y) = (?x = ?y)
  as_stack_inverse: ?y ∈ {xs. True} ⟹ list_of_stack (as_stack ?y) = ?y
  list_of_stack: list_of_stack ?x ∈ {xs. True}
  list_of_stack_inject: (list_of_stack ?x = list_of_stack ?y) = (?x = ?y)
  list_of_stack_inverse: as_stack (list_of_stack ?x) = ?x
  type_definition_stack: type_definition list_of_stack as_stack {xs. True}

这里的?x ∈ {xs. True}假设很无聊,但您可以在那里指定所有列表的子集,例如:如果您的堆栈永远不会为空,并确保该属性适用于所有类型的类型级别。

type_definition_stack定理与lifting包一起使用很有用。声明后

setup_lifting type_definition_stack

你可以通过给出列表中的定义来定义堆栈上的函数,并通过证明它们在列表方面的等效命题来证明涉及堆栈的定理;比手动处理转换函数容易得多。