如何说服Agda一个函数在对内以减少的数目终止?

如何说服Agda一个函数在对内以减少的数目终止?,agda,Agda,我正在为Agda中编译器的代码生成部分编码并证明其正确性。我很难说服Agda我的一些功能终止。我使用的高级语言有while循环,因此显然,对于任何给定的程序,都不能保证终止 正因为如此,我使用了一个“fuel”变量,它只是一个自然数,在执行每个表达式时递减一,限制了程序可以运行的步骤数 我很满意这保证了终止协议,但Agda并不那么容易被说服 data Stateᴴᴸ : Set where stateᴴᴸ : Store → (fuel : ℕ) → Stateᴴᴸ {-# TERM

我正在为Agda中编译器的代码生成部分编码并证明其正确性。我很难说服Agda我的一些功能终止。我使用的高级语言有while循环,因此显然,对于任何给定的程序,都不能保证终止

正因为如此,我使用了一个“fuel”变量,它只是一个自然数,在执行每个表达式时递减一,限制了程序可以运行的步骤数

我很满意这保证了终止协议,但Agda并不那么容易被说服

 data Stateᴴᴸ : Set where
   stateᴴᴸ : Store → (fuel : ℕ) → Stateᴴᴸ

 {-# TERMINATING #-}
 storeᴴᴸ' : IExp → Stateᴴᴸ → Stateᴴᴸ
 storeᴴᴸ' i (stateᴴᴸ σ 0)                           = stateᴴᴸ σ 0
 storeᴴᴸ' SKIP                  (stateᴴᴸ σ (suc f)) = stateᴴᴸ σ f
 storeᴴᴸ' (x ≔ a)               (stateᴴᴸ σ (suc f)) = stateᴴᴸ ((x ≔ aexe a σ) ∷ σ) f
 storeᴴᴸ' (P ⋯ Q)               state = storeᴴᴸ' Q (storeᴴᴸ' P state)
 storeᴴᴸ' (IF b THEN P ELSE Q) (stateᴴᴸ σ (suc f)) with bexe b σ
 ... | true  = storeᴴᴸ' P (stateᴴᴸ σ f)
 ... | false = storeᴴᴸ' Q (stateᴴᴸ σ f)
 storeᴴᴸ' (WHILE b DO c)       (stateᴴᴸ σ (suc f)) with bexe b σ
 ... | true  = storeᴴᴸ' (c ⋯ (WHILE b DO c)) (stateᴴᴸ σ f)
 ... | false = stateᴴᴸ σ f
在上述代码中,我必须使用终止pragma,否则Agda会提出以下投诉:

Termination checking failed for the following functions:
  storeᴴᴸ'
Problematic calls:
  storeᴴᴸ' Q (storeᴴᴸ' P state)
  storeᴴᴸ' P state
  storeᴴᴸ' (c ⋯ (WHILE b DO c)) (stateᴴᴸ σ f)
我最初认为这是因为我的
状态ᴴᴸ数据类型没有
可以。因此,我将其修改为以下内容:

  data Stateᴴᴸ : Set where
    stateᴴᴸ : Store  → Stateᴴᴸ
    sucstateᴴᴸ : Stateᴴᴸ → Stateᴴᴸ
并相应地改变了功能;但这并没有解决问题


我如何说服Agda该函数(以及使用相同想法的其他类似函数)将终止?(理想情况下,不需要对数据类型进行太多修改。)

可以对两个参数执行结构递归:表达式的结构和燃料。有时燃料会减少,有时表达式会减少,但另一个表达式不会保持不变。一般来说,这不是终止。您只能沿着顺序的词法积进行递归