Skip to content

Instantly share code, notes, and snippets.

@Blaisorblade
Last active December 4, 2019 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Blaisorblade/bc67dd7f395d9a0ab4e98002baa90c09 to your computer and use it in GitHub Desktop.
Save Blaisorblade/bc67dd7f395d9a0ab4e98002baa90c09 to your computer and use it in GitHub Desktop.
How to add Coq automation hints that can't be applied twice (for e.g. transitivity)
(** Support writing external hints for lemmas that must not be applied twice for a goal. *)
(* The usedLemma and un_usedLemma marker is taken from Crush.v (where they were called done and un_done). *)
(** Devious marker predicate to use for encoding state within proof goals *)
Definition usedLemma {T : Type} (x : T) := True.
(** After a round of application with the above, we will have a lot of junk [usedLemma] markers to clean up; hence this tactic. *)
Ltac un_usedLemma :=
repeat match goal with
| [ H : usedLemma _ |- _ ] => clear H
end.
Ltac markUsed H := assert (usedLemma H) by constructor.
Ltac try_once lm :=
match goal with
| H : usedLemma lm |- _ => fail 1
| _ => markUsed lm; eapply lm
end.
(** Example. *)
(* Hint Extern 10 => try_once Trans_stp : core. *)
Tactic Notation "try_once_tac" constr(T) tactic(tac) :=
match goal with
| H : usedLemma T |- _ => fail 1
| _ => markUsed T; tac
end.
(** Example. *)
(* Definition injectHyps_marker := 0. *)
(* Hint Extern 5 => try_once_tac injectHyps_marker injectHyps : core. *)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment