(** So far, we have seen many examples of what we might call %``%#"#classical program verification.#"#%''% We write programs, write their specifications, and then prove that the programs satisfy their specifications. The programs that we have written in Coq have been normal functional programs that we could just as well have written in Haskell or ML. In this chapter, we start investigating uses of %\index{dependent types}%_dependent types_ to integrate programming, specification, and proving into a single phase. The techniques we will learn make it possible to reduce the cost of program verification dramatically. *)
(**Sofar,wehaveseenmanyexamplesofwhatwemightcall%``%#"#classical program verification.#"#%''%Wewriteprograms,writetheirspecifications,andthenprovethattheprogramssatisfytheirspecifications.TheprogramsthatwehavewritteninCoqhavebeennormalfunctionalprogramsthatwecouldjustaswellhavewritteninHaskellorML.Inthischapter,westartinvestigatingusesof%\index{dependenttypes}%_dependenttypes_tointegrateprogramming,specification,andprovingintoasinglephase.Thetechniqueswewilllearnmakeitpossibletoreducethecostofprogramverificationdramatically.*)
(** By making explicit the functional relationship between value [n] and the result type of the [match], we guide Coq toward proper type checking. The clause for this example follows by simple copying of the original annotation on the definition. In general, however, the [match] annotation inference problem is undecidable. The known undecidable problem of %\index{higher-order unification}%_higher-order unification_ %\cite{HOU}% reduces to the [match] type inference problem. Over time, Coq is enhanced with more and more heuristics to get around this problem, but there must always exist [match]es whose types Coq cannot infer without annotations.
We can reimplement our dependently typed [pred] based on %\index{subset types}%_subset types_, defined in the standard library with the type family %\index{Gallina terms!sig}%[sig]. *)
@@ -268,7 +270,7 @@ We can see that the first subgoal comes from the second underscore passed to [Fa
(*endthide*)
Defined.
(** We end the %``%#"#proof#"#%''% with %\index{Vernacular commands!Defined}%[Defined] instead of [Qed], so that the definition we constructed remains visible. This contrasts to the case of ending a proof with [Qed], where the details of the proof are hidden afterward. (More formally, [Defined] marks an identifier as %\index{transparent}%_transparent_, allowing it to be unfolded; while [Qed] marks an identifier as %\index{opaque}%_opaque_, preventing unfolding.) Let us see what our proof script constructed. *)