The
decide equality tactic can generate a term of type
forall (x y: A), {x=y} + {x<>y} if
A is an inductive type.
This term is a decidable equality function.
Similarly, this module defines a
boolean_equality tactic that generates
a term of type
A -> A -> bool. This term is a Boolean-valued equality
function over the inductive type
A. Two internal tactics generate
proofs that show the correctness of this equality function
f, namely
proofs of the following two properties:
-
forall (x: A), f x x = true
-
forall (x y: A), f x y = true -> x = y
Finally, the
decide_equality_from f tactic wraps
f (the Boolean equality
generated by
boolean_equality) and those proofs together, producing
a decidable equality of type
forall (x y: A), {x=y} + {x<>y}.
The advantage of the present tactics over the standard
decide equality
tactic is that the former produce smaller transparent definitions than
the latter.
For a type
A that has N constructors,
decide equality produces a
single term of size O(N^3), which must be kept transparent so that
it computes and extracts as expected. Given such a big transparent
definition, the virtual machine compiler of Coq produces very big
chunks of VM code, causing memory overflows on 32-bit platforms.
In contrast, the term produced by
boolean_equality has size O(N^2)
only (so to speak). The proofs that this term is a correct boolean
equality are still O(N^3), but those proofs are opaque and do not need
to be compiled to VM code. Only the boolean equality itself is defined
transparently and compiled.
The present tactics also have some restrictions:
-
Constructors must have at most 4 arguments.
-
Decidable equalities must be provided (as hypotheses in the context)
for all the types T of constructor arguments other than type A.
-
They probably do not work for mutually-defined inductive types.
.
Proof.
.
Proof.
.
Proof.
}.
Proof.
].