diff -r e4e35ffe1ccd -r f65ac4962b66 src/Doc/Implementation/Logic.thy --- a/src/Doc/Implementation/Logic.thy Mon Mar 03 13:19:23 2025 +0100 +++ b/src/Doc/Implementation/Logic.thy Sat Mar 08 22:19:49 2025 +0100 @@ -807,7 +807,9 @@ ; @@{ML_antiquotation thms} thms ; - @@{ML_antiquotation lemma} ('(' @'open' ')')? ((prop +) + @'and') \ + @@{ML_antiquotation lemma} @{syntax embedded_lemma} + ; + @{syntax_def embedded_lemma} ('(' @'open' ')')? ((prop +) + @'and') \ @{syntax for_fixes} @'by' method method? ; @@{ML_antiquotation oracle_name} embedded @@ -1359,4 +1361,128 @@ proof terms via XML/ML data representation. \ +section \Instantiation of formal entities \label{sec:instantiation}\ + +text \ + The construction of formal entities (types, terms, theorems) in Isabelle/ML + can be tedious, error-prone, and costly at run-time. Repeated certification + of types/terms, or proof steps for theorems should be minimized, when + performance is relevant. + + For example, consider a proof-producing decision procedure that refers to + certain term schemes and derived rules that need to be applied repeatedly. A + reasonably efficient approach is the subsequent separation of Isabelle/ML + \<^emph>\compile-time\ vs. \<^emph>\run-time\. Lets say there is an ML module that is + loaded into the theory context to provide a tool as proof method, to be used + later in a different context. + + \<^item> At compile-time, the ML module constructs templates for relevant formal + entities, e.g. as certified types/terms and proven theorems (with + parameters). This uses the source notation for types, terms, propositions, + inlined into Isabelle/ML. Formal parameters are taken from the template, + and turned into ML names (as in \<^verbatim>\let\ expressions). + + \<^item> At run-time, the ML tool takes concrete entities from the application + context, and instantiates the above templates accordingly. The formal + parameters of the compile-time template get assigned to concrete ML + values. ML names and types have already been properly checked by the ML + compiler, and the running program cannot go wrong in that respect. (It + \<^emph>\can\ go wrong, concerning types of the implemented logic, though). + + This approach is supported by ML antiquotations as follows. +\ + +text %mlantiq \ + \begin{matharray}{rcl} + @{ML_antiquotation_def "instantiate"} & : & \ML_antiquotation\ \\ + \end{matharray} + + \<^rail>\ + @@{ML_antiquotation instantiate} embedded + \ + + \<^descr> \@{instantiation source}\ refers to embedded source text to produce an + instantiation for a logical entity that is given literally in the text. The + content of the @{syntax embedded} argument follows the syntax category + @{syntax instantiation} defined below, using @{syntax embedded_ml} from + antiquotation @{ML_antiquotation Type} (\secref{sec:types}), and @{syntax + embedded_lemma} from antiquotation @{ML_antiquotation lemma} + (\secref{sec:thms}). + + \<^rail>\ + @{syntax_def instantiation}: no_beta? (inst + @'and') @'in' @{syntax body} + ; + no_beta: '(' 'no_beta' ')' + ; + schematic: '(' 'schematic' ')' + ; + inst: ((type_ident | name) ((@'=' @{syntax embedded_ml}))?) + ; + body: body_type | body_term | body_prop | body_lemma + ; + body_type: ('typ' | 'ctyp') schematic? embedded + ; + body_term: ('term' | 'cterm') schematic? embedded + ; + body_prop: ('prop' | 'cprop') schematic? embedded + ; + body_lemma: 'lemma' schematic? @{syntax embedded_lemma} + \ + + \<^item> An @{syntax inst} entry assigns a type/term variable to a suitable ML + value, given as ML expression in the current program context. The ML type + of the expression needs to fit to the situation: \<^verbatim>\'a =\~\ty\ refers to + \ty\\<^verbatim>\: typ\ or \ty\\<^verbatim>\: ctyp\, and \<^verbatim>\a =\~\tm\ refers to \tm\\<^verbatim>\: term\ or + \tm\\<^verbatim>\: cterm\. Only a body for uncertified \<^verbatim>\typ\ / \<^verbatim>\term\ / \<^verbatim>\prop\ + admits uncertified \<^ML_type>\typ\ or \<^ML_type>\term\ parameters. The + other cases require certified \<^ML_type>\ctyp\ or \<^ML_type>\cterm\ + parameters. + + If the RHS of the @{syntax inst} entry is omitted, it defaults to the LHS: + \<^verbatim>\a\ becomes \<^verbatim>\a = a\. This only works for term variables that happen to + be legal ML identifiers, and not for type variables. + + \<^item> The ``\(schematic)\'' option disables the usual check that all LHS names + in @{syntax inst} are exactly those present as free variables in the body + entity (type, term, prop, lemma statement). By default, omitted variables + cause an error, but with ``\(schematic)\'' they remain as schematic + variables. The latter needs to be used with care, because unexpected + variables may emerge, when the theory name space for constants changes + over time. + + \<^item> The ``\(no_beta)\'' option disables the usual \\\-normalization for + \body_term\ / \body_prop\ / \body_lemma\, but has no effect on + \body_type\. This is occasionally useful for low-level applications, where + \\\-conversion is treated explicitly in primitive inferences. +\ + +text %mlex \ + Below are some examples that demonstrate the antiquotation syntax. + Real-world applications may be found in the Isabelle sources, by searching + for the literal text ``\<^verbatim>\\<^instantiate>\''. +\ + +ML \ + \ \uncertified type parameters\ + fun make_assoc_type (A: typ, B: typ) : typ = + \<^instantiate>\'a = A and 'b = B in typ \('a \ 'b) list\\; + + \ \uncertified term parameters\ + val make_assoc_list : (term * term) list -> term list = + map (fn (x, y) => + \<^instantiate>\'a = \fastype_of x\ and 'b = \fastype_of y\ and + x and y in term \(x, y)\ for x :: 'a and y :: 'b\); + + \ \theorem with certified term parameters\ + fun symmetry (x: cterm) (y: cterm) : thm = + \<^instantiate>\'a = \Thm.ctyp_of_cterm x\ and x and y in + lemma \x = y \ y = x\ for x y :: 'a by simp\ + + \ \theorem with certified type parameter, and schematic result\ + fun symmetry_schematic (A: ctyp) : thm = + \<^instantiate>\'a = A in + lemma (schematic) \x = y \ y = x\ for x y :: 'a by simp\ +\ + + end