Eval compute is incomplete when own decidability is used in Coq
Question
The Eval compute command does not always evaluate to a simple expression. Consider the code:
Require Import Coq.Lists.List. Require Import Coq.Arith.Peano_dec. Import ListNotations. Inductive I : Set := a : nat -> I | b : nat -> nat -> I.forall x y : I, {x = y} + {x <> y}repeat decide equality. Qed.forall x y : I, {x = y} + {x <> y}
And, if I execute the following command:
Coq tells me that the result is 2. However, when I execute the following expression:
I get a long expression where the In-predicate seems to be unfolded, but no result is given.
What do I have to change to obtain the answer 1 in the last Eval compute line?
Answer
In Coq there are two terminator commands for proof scripts: Qed and Defined. The difference between them is that the former creates opaque terms, which cannot be unfolded, even by Eval compute. The latter creates transparent terms, which can then be unfolded as usual. Thus, you just have to put Defined in the place of Qed.:
Require Import Coq.Lists.List. Require Import Coq.Arith.Peano_dec. Import ListNotations. Inductive I : Set := a : nat -> I | b : nat -> nat -> I.forall x y : I, {x = y} + {x <> y}repeat decide equality. Defined.forall x y : I, {x = y} + {x <> y}
I personally find the sumbool type {A} + {B} not very nice for expressing decidable propositions, precisely because proofs and computation are too tangled together; in particular, proofs affect how terms reduce. I find it better to follow the Ssreflect style, separate proofs and computation and relate them via a special predicate:
Inductive reflect (P : Prop) : bool -> Set :=
| ReflectT of P : reflect P true
| ReflectF of ~ P : reflect P false.
this gives a convenient way for saying that a boolean computation returns true iff some property is true. Ssreflect provides support for conveniently switching between the computational boolean view and the logical view.