簡體   English   中英

檢查返回值的策略中的evars

[英]Check for evars in a tactic that returns a value

我正在嘗試編寫一個返回值的策略,並且在這樣做的過程中需要檢查某些東西是否為evar。

不幸的是,我不能使用is_evar因為這樣的策略不會被視為返回值(而是另一種策略)。 一個例子如下。

有什么建議?

Ltac reify_wrt values ls :=
  match ls with
  | nil => constr:(@nil nat)
  | ?a :: ?ls' => let i := lookup a values in
                 let idx := reify_wrt values ls' in
                 constr:(i :: idx)
  | ?e :: ?ls' => is_evar e; 
                  let i := constr:(100) in 
                  let idx := reify_wrt values ls' in
                  constr:(i :: idx)
  end.

這是Ltac的一個眾所周知的限制:你不能寫一個有時會返回一個值的策略,有時會返回另一個策略。 解決方案是以連續傳遞方式重寫你的策略。 不幸的是,我無法詳細解釋如何做到這一點,但Adam Chlipala的CDPT有一章關於Ltac描述了這個問題; 只需在文中尋找“延續”。

有一個整潔(或討厭)的小技巧,您可以使用它來將策略執行插入到Coq> = 8.5中的constr構造中:將其包裝在match goal

Ltac reify_wrt values ls :=
  match ls with
  | nil => constr:(@nil nat)
  | ?a :: ?ls' => let i := lookup a values in
                 let idx := reify_wrt values ls' in
                 constr:(i :: idx)
  | ?e :: ?ls' => let check := match goal with _ => is_evar e end in
                  let i := constr:(100) in 
                  let idx := reify_wrt values ls' in
                  constr:(i :: idx)
  end.

因為編程語言奧秘讓我着迷,我現在告訴你的不僅僅是你想知道Ltac的現在和過去的執行模型。

戰術評估分為兩個階段:策略表達評估和戰術運行。 在戰術運行期間,執行排序,細化,重寫等。 在戰術表達評估期間,如果在戰術表達的頭部位置找到,則評估以下構造:

  • 戰術呼叫被解決/跟隨/內聯/展開
  • let ... in ...將它的參數的表達式 - 評估與名稱綁定,並進行替換
  • constr:(...)進行評估和類型檢查
  • lazymaytch ... with ... end被評估(帶后向跟蹤),並返回第一個匹配的分支,該分支成功進行表達式評估
  • match ... with ... end評估(使用回溯) 並且急切地執行分支 請注意,在這張圖片中, match很奇怪,因為它迫使戰術的執行提前到來。 如果您曾在Coq <8.5中看到“本地定義中不允許立即匹配生成策略”,那么這是一條明確禁止我正在利用上述行為的錯誤消息。 我猜這是因為這種奇怪的match行為是原始開發者實施Ltac想要隱藏的疣。 因此,你可以在Coq 8.4中注意到的唯一一個地方就是如果你在lazymatch match並使用失敗級別,並注意到lazymatch會在你通常期望它失敗的情況下回溯內部match中戰術執行的失敗。

在Coq 8.5中,戰術引擎被重寫以處理依賴的子目標。 這引起了語義的細微變化; 這只能在使用多個目標之間共享的evars時才能觀察到。 在重寫中,開發者將lazymatch的語義改為“ match無回溯”,並解除了對“即時匹配生成策略”的限制。 因此你可以做一些奇怪的事情:

let dummy := match goal with _ => rewrite H end in
constr:(true)

並制定具有副作用的制定策略。 但是,你不能再做了:

let tac := lazymatch b with
                | true => tac1
                | false => tac2
                end in
tac long args.

因為在Coq> = 8.5中, lazymatch也急切地評估它的分支。

暫無
暫無

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

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