In the interactive theorem prover Coq, any interactive proof or definition can be terminated with either Qed
or Defined
. There is some concept of "opacity" which Qed
enforces but Defined
does not. For instance, the book Certified Programming with Dependent Types, by Adam Chlipala, states:
We end the "proof" with
Defined
instead ofQed
, so that the definition we constructed remains visible. This contrasts to the case of ending a proof withQed
, where the details of the proof are hidden afterward. (More formally,Defined
marks an identifier as transparent, allowing it to be unfolded; whileQed
marks an identifier as opaque, preventing unfolding.)
However, I'm not quite sure what this means in practice. There is a later example in which it is necessary to use Defined
due to the need for Fix
to inspect the structure of a certain proof, but I don't understand exactly what this "inspection" entails, or why it would fail if Qed
were used instead. (Looking at the definition of Fix
wasn't exactly enlightening either).
Superficially, it's hard to tell what Qed
is actually doing. For instance, if I write:
Definition x : bool.
exact false.
Qed.
I can still see the value of x
by executing the command Print x.
In addition, I'm allowed later to pattern-match on the "opaque" value of x
:
Definition not_x : bool :=
match x with
| true => false
| false => true
end.
Therefore it seems like I'm able to use the value of x
just fine. What does Prof. Chlipala mean by "unfolding" here? What exactly is the difference between an opaque and a transparent difference? Most importantly, what is special about Fix
that makes this matter?