coq - 如何在 Coq 中编写以下形式的函数?

标签 coq termination totality

f x = f (g subtermOfX)

只有当函数的 arg 是传递的 arg 的直接子项时才允许递归,以便 Coq 可以看到它实际上终止了吗?

最佳答案

如果函数 g 保留作为子项的属性,则可以编写这样的函数 f

一些标准函数具有此属性,例如pred, sub:

From Coq Require Import Arith List.
Import ListNotations.

Fixpoint foo (x : nat) : nat :=
  match x with
  | O => 42
  | S x' => foo (pred x'). (* foo (x' - 1) works too *)
  end.

另一方面,一些(标准)函数没有这个属性,但可以重写以弥补这个缺陷。例如。标准的 tl 函数不保留 subterm 属性,因此以下操作失败:

Fail Fixpoint bar (xs : list nat) : list nat :=
  match xs with
  | [] => []
  | x :: xs' => bar (tl xs')
  end.

但是如果我们像这样重新定义 tail 函数

Fixpoint new_tl {A : Type} (xs : list A) :=
  match xs with
  | [] => xs           (* `tl` returns `[]` here *) 
  | _ :: xs' => xs'
  end.

我们可以恢复所需的属性:

Fixpoint bar (xs : list nat) : list nat :=
  match xs with
  | [] => []
  | x :: xs' => bar (new_tl xs')
  end.

tlnew_tl 的唯一区别是,在输入列表为空的情况下,tl 返回[],但 new_tl 返回原始列表。

关于coq - 如何在 Coq 中编写以下形式的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47947777/

相关文章:

proof - 如果 idris 认为事情可能是完整的,但事实并非如此, idris 可以用来证明吗?

Coq:列表对的证明

boolean - 如何在 Coq 中编写 boolean 比较函数

c++ - 拦截 WM_CLOSE 进行清理操作

recursion - 通过重复除法进行有根据的递归

types - Agda 中的大小类型是什么?

coq - 如何在 Coq 中的列表末尾进行归纳

coq - 从 Coq 的定义中返回一条记录

coq - 减少参数(以及什么是程序固定点)

recursion - 嵌套递归和 `Program Fixpoint` 或 `Function`