I want to structure my program as abstract modules, and write functions that use the abstract types. But I can't use match to destruct the abstract types, so I will have to create an inversion lemma of some sort, but I can't match on it either. I've tried to boil down my problem to this:
First create a Module Type that can be used by decidable types.
Require Import Decidable.
Module Type decType.
Parameter T : Type.
Axiom decT : forall (a b:T), decidable (a=b).
End decType.
Here is an example: nat is decidable. But the aim is to write plus etc. only addressing the abstract type. (I have removed the parameters zero, Succ and their requirements to make the example here minimal).
Require Peano_dec.
Module nat_dec <: decType.
Definition T := nat.
Definition decT := Peano_dec.dec_eq_nat.
End nat_dec.
Now to my question: I want to write a module parameterized on a decType module with a function that returns true if a=b and false otherwise. Since a and b are of a decType this should be decidable (and therefore computable, or?), but how to I write beq?
Module decBool (M: decType).
Import M.
Definition beq (a b:T) : bool :=
???
.
End decBool.
My thinking so far is that I have to add a boolean function to the decType module type, something like this:
Module Type decType.
Parameter T : Type.
Axiom decT : forall (a b:T), decidable (a=b).
Parameter decB : forall (a b:T), {a=b}+{a<>b}.
End decType.
and then define decB in the nat_dec module above.
Is this what one has to do (i.e. define the function decB)? Is it not possible at all to use the abstract fact that the type is decidable, without going through a function that returns bool?