簡體   English   中英

Coq中的可擴展策略

[英]Extensible tactic in Coq

假設我有一種奇特的策略可以解決某種類型的引理:

Ltac solveFancy :=
  some_preparation;
  repeat (first [important_step1 | important_step2];
          some_cleanup);
  solve_basecase.

現在我使用這種策略來證明這種類型的進一步的引理,我后來想在這種策略中使用它。

Lemma fancy3 := …. Proof. … Qed.
Ltac important_step3 := apply fancy3;[some|specific|stuff].

現在我可以簡單地重新定義Ltac solveFancy ::= …並將important_step3添加到列表中,但這很快就會變舊。

有沒有現在擴展列表中選擇一個更優雅的方式important_step -tactics在solveFancy 我想象的是:

Add Hint SolveFancy important_step3.

這不是我所說的優雅,但這是一個純粹的Ltac解決方案。 您可以在后面重新定義的策略中留下一個鈎子,並且可以通過始終為下一個提示留下鈎子來遵循此模式:

Axiom P : nat -> Prop.
Axiom P0 : P 0.
Axiom P_ind : forall n, P n -> P (S n).

Ltac P_hook := fail.

Ltac solve_P :=
  try apply P_ind;
  exact P0 || P_hook.

Theorem ex_1 : P 1.
Proof.
  solve_P.
Qed.

Ltac P_hook2 := fail.
Ltac P_hook ::= exact ex_1 || P_hook2.

Theorem ex_2 : P 2.
Proof.
  solve_P.
Qed.

Ltac P_hook3 := fail.
Ltac P_hook ::= exact ex_2 || P_hook3.

Theorem ex_3 : P 3.
Proof.
  solve_P.
Qed.

應該有一種方法可以使用Hint Extern來做到這一點,但是控制這些提示的時間和順序將會更加困難,並且它們必須在最后完全解決目標。

我會為solveFancy添加一個參數,你可以使用它來傳遞另一種策略:

Ltac solveFancy hook :=
  some_preparation;
  repeat (first [important_step1 | important_step2 | hook];
          some_cleanup);
  solve_basecase.

(* use solveFancy without any extra available steps *)
[...] solveFancy fail [...]

Ltac important_step3 := [...]

(* use solveFancy with important_step3 *)
[...] solveFancy important_step3 [...]

這比重新定義一個鈎子更優雅,盡管它本身並不能解決可擴展性問題。 以下是使用模塊允許重新定義Ltac名稱而不覆蓋先前定義的事實,根據其自身的先前版本重復定義策略x的策略。

Ltac x := idtac "a".

Goal False.
  x. (* a *)
Abort.

Module K0.
  Ltac x' := x.
  Ltac x := x'; idtac "b".
End K0.
Import K0.

Goal False.
  x. (* a b *)
Abort.

Module K1.
  Ltac x' := x.
  Ltac x := x'; idtac "c".
End K1.
Import K1.

Goal False.
  x. (* a b c *)
Abort.

請注意,模塊的名稱K0K1無關緊要,可以根據需要重命名或重新排序。 這不是世界上最優雅的東西,但我認為這是一種改進。

暫無
暫無

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

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