1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(* Decidable equivalences.
11
* Author: Matthieu Sozeau
12
* Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
13
* 91405 Orsay, France *)
15
(* $Id: EquivDec.v 12187 2009-06-13 19:36:59Z msozeau $ *)
17
(** Export notations. *)
19
Require Export Coq.Classes.Equivalence.
21
(** The [DecidableSetoid] class asserts decidability of a [Setoid]. It can be useful in proofs to reason more
24
Require Import Coq.Logic.Decidable.
26
Open Scope equiv_scope.
28
Class DecidableEquivalence `(equiv : Equivalence A) :=
29
setoid_decidable : forall x y : A, decidable (x === y).
31
(** The [EqDec] class gives a decision procedure for a particular setoid equality. *)
33
Class EqDec A R {equiv : Equivalence R} :=
34
equiv_dec : forall x y : A, { x === y } + { x =/= y }.
36
(** We define the [==] overloaded notation for deciding equality. It does not take precedence
37
of [==] defined in the type scope, hence we can have both at the same time. *)
39
Notation " x == y " := (equiv_dec (x :>) (y :>)) (no associativity, at level 70) : equiv_scope.
41
Definition swap_sumbool {A B} (x : { A } + { B }) : { B } + { A } :=
43
| left H => @right _ _ H
44
| right H => @left _ _ H
47
Require Import Coq.Program.Program.
49
Open Local Scope program_scope.
51
(** Invert the branches. *)
53
Program Definition nequiv_dec `{EqDec A} (x y : A) : { x =/= y } + { x === y } := swap_sumbool (x == y).
55
(** Overloaded notation for inequality. *)
57
Infix "<>" := nequiv_dec (no associativity, at level 70) : equiv_scope.
59
(** Define boolean versions, losing the logical information. *)
61
Definition equiv_decb `{EqDec A} (x y : A) : bool :=
62
if x == y then true else false.
64
Definition nequiv_decb `{EqDec A} (x y : A) : bool :=
65
negb (equiv_decb x y).
67
Infix "==b" := equiv_decb (no associativity, at level 70).
68
Infix "<>b" := nequiv_decb (no associativity, at level 70).
70
(** Decidable leibniz equality instances. *)
72
Require Import Coq.Arith.Peano_dec.
74
(** The equiv is burried inside the setoid, but we can recover it by specifying which setoid we're talking about. *)
76
Program Instance nat_eq_eqdec : EqDec nat eq := eq_nat_dec.
78
Require Import Coq.Bool.Bool.
80
Program Instance bool_eqdec : EqDec bool eq := bool_dec.
82
Program Instance unit_eqdec : EqDec unit eq := λ x y, in_left.
86
destruct x ; destruct y.
90
Program Instance prod_eqdec `(EqDec A eq, EqDec B eq) :
91
! EqDec (prod A B) eq :=
96
if x2 == y2 then in_left
100
Solve Obligations using unfold complement, equiv ; program_simpl.
102
Program Instance sum_eqdec `(EqDec A eq, EqDec B eq) :
103
EqDec (sum A B) eq := {
106
| inl a, inl b => if a == b then in_left else in_right
107
| inr a, inr b => if a == b then in_left else in_right
108
| inl _, inr _ | inr _, inl _ => in_right
111
Solve Obligations using unfold complement, equiv ; program_simpl.
113
(** Objects of function spaces with countable domains like bool have decidable equality.
114
Proving the reflection requires functional extensionality though. *)
116
Program Instance bool_function_eqdec `(EqDec A eq) : ! EqDec (bool -> A) eq :=
118
if f true == g true then
119
if f false == g false then in_left
123
Solve Obligations using try red ; unfold equiv, complement ; program_simpl.
133
Program Instance list_eqdec `(eqa : EqDec A eq) : ! EqDec (list A) eq :=
135
fix aux (x : list A) y { struct x } :=
137
| nil, nil => in_left
138
| cons hd tl, cons hd' tl' =>
140
if aux tl tl' then in_left else in_right
145
Solve Obligations using unfold equiv, complement in *; program_simpl;
146
intuition (discriminate || eauto).
148
Next Obligation. destruct x ; destruct y ; intuition eauto. Defined.
150
Solve Obligations using unfold equiv, complement in *; program_simpl;
151
intuition (discriminate || eauto).