Souvent, rendre une preuve plus automatisée implique d'écrire un peu plus de code qu'au départ, afin de pouvoir traiter plus de cas. En adoptant cette approche, j'ai adapté une partie du code passe-partout de fiat-crypto :
Require Import Coq.Strings.Ascii Coq.Strings.String.
Class Decidable (P : Prop) := dec : {P} + {~P}.
Arguments dec _ {_}.
Notation DecidableRel R := (forall x y, Decidable (R x y)).
Global Instance dec_or {A B} {HA : Decidable A} {HB : Decidable B} : Decidable (A \/ B).
Proof. hnf in *; tauto. Defined.
Global Instance dec_eq_ascii : DecidableRel (@eq ascii) := ascii_dec.
Avec cette phrase passe-partout, votre preuve devient
Definition IsWhitespace (c : ascii) := (c = "009"%char) \/ (c = "032"%char).
Definition isWhitespace (c : ascii) : Decidable (IsWhitespace c) := _.
ce qui est à peu près aussi court qu'une preuve puisse l'être. (Notez que := _
est la même chose que . Proof. exact _. Defined.
qui est lui-même identique à . Proof. typeclasses eauto. Defined.
.)
Notez que ceci est assez similaire à la preuve d'ejgallego, puisque tauto
est la même chose que intuition fail
.
Notez également que l'original boilerplate en fiat-crypto est beaucoup plus long, mais aussi plus puissant que la simple utilisation de l'option hnf in *; tauto
et traite quelques dizaines de propositions décidables différentes.