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?