Isabelle 定义格式错误:顺序模式中不允许非线性模式

Isabelle 定义格式错误:顺序模式中不允许非线性模式,isabelle,Isabelle,我定义了以下函数: fun count:: "'a ⇒ 'a list ⇒ nat" where "count a Nil = 0" | "count a (Cons b xs) = (count a xs)" | "count a (Cons a xs) = (count a xs) + (Suc 0)" 它应该统计元素a在具有与a相同类型的元素的列表中的出现次数。我得到以下错误: Malformed definition: Nonlinear patterns not allowed in

我定义了以下函数:

fun count:: "'a ⇒ 'a list ⇒ nat" where
"count a Nil = 0" |
"count a (Cons b xs) = (count a xs)" |
"count a (Cons a xs) = (count a xs) + (Suc 0)"
它应该统计元素a在具有与a相同类型的元素的列表中的出现次数。我得到以下错误:

Malformed definition:
Nonlinear patterns not allowed in sequential mode.
⋀a xs. count a (a # xs) = count a xs + Suc 0 

关于模式,“线性”意味着每个自由变量只出现一次。在第三行中,左侧的图案包含两次
a
,这使其成为非线性。功能包的“顺序”模式不支持这一点。这是一种模式,在这种模式下,您可以一个接一个地指定可能重叠的函数方程,并且匹配的第一个方程是计数的方程。这也是“fun”命令使用的模式,也是像Haskell这样的函数式编程语言通常使用的模式(请注意,这些语言通常也不允许非线性模式)

这里基本上有两种可能性:如果您绝对想使用非线性模式,您可以编写

function count:: "'a ⇒ 'a list ⇒ nat" where
  "count a Nil = 0"
| "a ≠ b ⟹ count a (Cons b xs) = (count a xs)"
| "count a (Cons a xs) = (count a xs) + (Suc 0)"
  by (metis neq_Nil_conv surj_pair) auto
termination by lexicographic_order
请注意,您必须显示这样一个事实,即模式是详尽的、非手动重叠的,以及终止。”“乐趣”功能较弱,但所有这些功能都是自动完成的

更简单、更好的方法是以系统自动化更容易接受的方式重新定义定义:

fun count:: "'a ⇒ 'a list ⇒ nat" where
  "count a Nil = 0"
| "count a (Cons b xs) = (count a xs) + (if a = b then 1 else 0)‹›
出于各种原因,这几乎总是可取的(更短、更容易,代码生成效果更好)

有关功能包的更多信息,请参阅。这是一个功能强大、用途广泛的工具,但如果你只需要“乐趣”就能得到你想要的东西,那通常就是你想要的方式