簡體   English   中英

伊莎貝爾的 Function 終止證明

[英]Function termination proof in Isabelle

我的數據類型 stack_op 由幾個(~20)個案例組成。 我正在嘗試編寫 function,它會跳過列表中的一些案例:

function (sequential) skip_expr :: "stack_op list ⇒ stack_op list" where
"skip_expr []  = []" 
| "skip_expr ((stack_op.Unary _)#other) = (skip_expr other)" 
| "skip_expr ((stack_op.Binary _)#other)  = skip_expr (skip_expr other)" 
| "skip_expr ((stack_op.Value _)#other) = other" 
| "skip_expr other = other"   
by pat_completeness auto termination by lexicographic_order 

這似乎總是終止。 但是按字典順序嘗試會產生這樣未解決的情況:

Calls:
  c) stack_op.Binary uv_ # other ~> skip_expr other
Measures:
  1) size_list size
  2) length
Result matrix:
    1  2 
c:  ?  ?

(size_change 也不起作用)

我讀過https://isabelle.in.tum.de/dist/Isabelle2021/doc/functions.pdf ,但它無濟於事。 (也許有更復雜的使用tremination的例子?)

我試圖重寫 function 添加另一個參數:

function (sequential) skip_expr :: "stack_op list ⇒ nat ⇒ stack_op list" where 
  "skip_expr l 0 = l"
| "skip_expr [] _ = []"
| "skip_expr ((stack_op.Unary _)#other) depth = (skip_expr other (depth - 1))"
| "skip_expr ((stack_op.Binary _)#other) depth = 
    (let buff1 = (skip_expr other (depth - 1))
      in (skip_expr buff1 (length buff1)))"
| "skip_expr ((stack_op.Value _)#other) _ = other"
| "skip_expr other _ = other"
 by pat_completeness auto
termination by (relation "measure (λ(_,dep). dep)") auto

生成未解決的子目標:

 1. ⋀other v. skip_expr_dom (other, v) ⟹ length (skip_expr other v) < Suc v

我也不知道如何證明。

誰能解決這種情況(據我所知,在 stack_op.Binary 案例的右側進行兩級遞歸調用存在一些問題) 或者也許還有另一種方法可以跳過?

提前致謝

lexicographic_order方法只是嘗試用簡化器解決出現的目標,因此如果簡化器卡住,您最終會得到未解決的終止子目標。

在這種情況下,正如您正確識別的那樣,問題是您有一個嵌套的遞歸調用skip_expr (skip_expr other) 這總是有問題的,因為在這個階段,簡化器對skip_expr對輸入列表做了什么一無所知。 據我們所知,它可能只是返回未修改的列表,甚至是更長的列表,然后它肯定不會終止。

直面問題

解決方案是顯示一些有關length (skip_expr …) ,並使簡化器可以使用該信息。 因為我們還沒有顯示 function 的終止,我們必須使用skip_expr.psimps規則和部分歸納規則skip_expr.pinduct ,即我們對skip_expr xs所做的每條陳述總是有一個前提條件,即skip_expr實際上在輸入xs上終止. 為此,有謂詞skip_expr_dom

把它們放在一起,它看起來像這樣:

  lemma length_skip_expr [termination_simp]:
    "skip_expr_dom xs ⟹ length (skip_expr xs) ≤ length xs"
    by (induction xs rule: skip_expr.pinduct) (auto simp: skip_expr.psimps)

  termination skip_expr by lexicographic_order

規避問題

有時,完全規避這個問題也更容易。 在您的情況下,您可以定義一個更通用的 function skip_exprs ,它不僅跳過一條指令,而且跳過n條指令。 您可以在沒有嵌套歸納的情況下定義:

  fun skip_exprs :: "nat ⇒ stack_op list ⇒ stack_op list" where
    "skip_exprs 0 xs = xs"
  | "skip_exprs (Suc n) [] = []"
  | "skip_exprs (Suc n) (Unary _ # other) = skip_exprs (Suc n) other"
  | "skip_exprs (Suc n) (Binary _ # other) = skip_exprs (Suc (Suc n)) other"
  | "skip_exprs (Suc n) (Value _ # other) = skip_exprs n other"
  | "skip_exprs (Suc n) xs = xs"

然后可以直接證明與skip_expr等價:

  lemma skip_exprs_conv_skip_expr: "skip_exprs n xs = (skip_expr ^^ n) xs"
  proof -
    have [simp]: "(skip_expr ^^ n) [] = []" for n
      by (induction n) auto
    have [simp]: "(skip_expr ^^ n) (Other # xs) = Other # xs" for xs n
      by (induction n) auto
    show ?thesis
      by (induction n xs rule: skip_exprs.induct)
         (auto simp del: funpow.simps simp: funpow_Suc_right)
  qed
  
  lemma skip_expr_Suc_0 [simp]: "skip_exprs (Suc 0) xs = skip_expr xs"
    by (simp add: skip_exprs_conv_skip_expr)

就您而言,我認為這樣做實際上沒有意義,因為確定終止相當容易,但記住這一點可能會很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM