Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
A proposition is decidable whenever it is reflected by a boolean.
Class Decidable (P : Prop) := {
Decidable_witness : bool;
Decidable_spec : Decidable_witness = true <-> P
}.
Alternative ways of specifying the reflection property.
forall (P : Prop) (H : Decidable P), Decidable_witness = true -> Pintros P H Hp; apply -> Decidable_spec; assumption. Qed.forall (P : Prop) (H : Decidable P), Decidable_witness = true -> Pforall (P : Prop) (H : Decidable P), P -> Decidable_witness = trueintros P H Hp; apply <- Decidable_spec; assumption. Qed.forall (P : Prop) (H : Decidable P), P -> Decidable_witness = trueforall (P : Prop) (H : Decidable P), ~ P -> Decidable_witness = falseintros P [wit spec] Hd; simpl; destruct wit; tauto. Qed.forall (P : Prop) (H : Decidable P), ~ P -> Decidable_witness = falseforall (P : Prop) (H : Decidable P), Decidable_witness = false -> ~ Pintros P [wit spec] Hd Hc; simpl in *; intuition congruence. Qed.forall (P : Prop) (H : Decidable P), Decidable_witness = false -> ~ P
The generic function that should be used to program, together with some
useful tactics.
Definition decide P {H : Decidable P} := Decidable_witness (Decidable:=H). Ltac _decide_ P H := let b := fresh "b" in set (b := decide P) in *; assert (H : decide P = b) by reflexivity; clearbody b; destruct b; [apply Decidable_sound in H|apply Decidable_complete_alt in H]. Tactic Notation "decide" constr(P) "as" ident(H) := _decide_ P H. Tactic Notation "decide" constr(P) := let H := fresh "H" in _decide_ P H.
Some usual instances.
Require Import Bool Arith ZArith. Instance Decidable_eq_bool : forall (x y : bool), Decidable (eq x y) := { Decidable_witness := Bool.eqb x y }.apply eqb_true_iff. Qed. Instance Decidable_eq_nat : forall (x y : nat), Decidable (eq x y) := { Decidable_witness := Nat.eqb x y }.x, y:booleqb x y = true <-> x = yapply Nat.eqb_eq. Qed. Instance Decidable_le_nat : forall (x y : nat), Decidable (x <= y) := { Decidable_witness := Nat.leb x y }.x, y:nat(x =? y) = true <-> x = yapply Nat.leb_le. Qed. Instance Decidable_eq_Z : forall (x y : Z), Decidable (eq x y) := { Decidable_witness := Z.eqb x y }.x, y:nat(x <=? y) = true <-> x <= yapply Z.eqb_eq. Qed.x, y:Z(x =? y)%Z = true <-> x = y