forked from Isabelle_DOF/Isabelle_DOF
Revising Chapter 5.
This commit is contained in:
parent
018bfa4bcd
commit
e495a7b2fe
|
@ -1,7 +1,7 @@
|
||||||
(*************************************************************************
|
(*************************************************************************
|
||||||
* Copyright (C)
|
* Copyright (C)
|
||||||
* 2019-2020 University of Exeter
|
* 2019-2021 University of Exeter
|
||||||
* 2018-2019 University of Paris-Saclay
|
* 2018-2021 University of Paris-Saclay
|
||||||
* 2018 The University of Sheffield
|
* 2018 The University of Sheffield
|
||||||
*
|
*
|
||||||
* License:
|
* License:
|
||||||
|
@ -41,74 +41,55 @@ text\<open>
|
||||||
IDE support.
|
IDE support.
|
||||||
\<close>
|
\<close>
|
||||||
|
|
||||||
(* should work as text*, but doesn't. *)
|
section\<open>\<^isadof>: A User-Defined Plugin in Isabelle/Isar\<close>
|
||||||
(*
|
text\<open>
|
||||||
text*[xxx::SML]
|
A plugin in Isabelle starts with defining the local data and registering it in the framework. As
|
||||||
|
mentioned before, contexts are structures with independent cells/compartments having three
|
||||||
|
primitives \<^boxed_sml>\<open>init\<close>, \<^boxed_sml>\<open>extend\<close> and \<^boxed_sml>\<open>merge\<close>. Technically this is done by
|
||||||
|
instantiating a functor \<^boxed_sml>\<open>Generic_Data\<close>, and the following fairly typical code-fragment
|
||||||
|
is drawn from \<^isadof>:
|
||||||
|
|
||||||
|
@{boxed_sml [display]
|
||||||
\<open>structure Data = Generic_Data
|
\<open>structure Data = Generic_Data
|
||||||
( type T = docobj_tab * docclass_tab * ...
|
( type T = docobj_tab * docclass_tab * ...
|
||||||
val empty = (initial_docobj_tab, initial_docclass_tab, ...)
|
val empty = (initial_docobj_tab, initial_docclass_tab, ...)
|
||||||
val extend = I
|
val extend = I
|
||||||
fun merge((d1,c1,...),(d2,c2,...)) = (merge_docobj_tab (d1,d2,...),
|
fun merge((d1,c1,...),(d2,c2,...)) = (merge_docobj_tab (d1,d2,...),
|
||||||
merge_docclass_tab(c1,c2,...))
|
merge_docclass_tab(c1,c2,...))
|
||||||
);
|
);\<close>}
|
||||||
\<close>
|
where the table \<^boxed_sml>\<open>docobj_tab\<close> manages document classes and \<^boxed_sml>\<open>docclass_tab\<close> the
|
||||||
*)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
section\<open>\<^isadof>: A User-Defined Plugin in Isabelle/Isar\<close>
|
|
||||||
text\<open>
|
|
||||||
A plugin in Isabelle starts with defining the local data and registering it in the framework. As
|
|
||||||
mentioned before, contexts are structures with independent cells/compartments having three
|
|
||||||
primitives \inlinesml+init+, \inlinesml+extend+ and \inlinesml+merge+. Technically this is done by
|
|
||||||
instantiating a functor \inlinesml+Generic_Data+, and the following fairly typical code-fragment
|
|
||||||
is drawn from \<^isadof>:
|
|
||||||
|
|
||||||
\begin{sml}
|
|
||||||
structure Data = Generic_Data
|
|
||||||
( type T = docobj_tab * docclass_tab * ...
|
|
||||||
val empty = (initial_docobj_tab, initial_docclass_tab, ...)
|
|
||||||
val extend = I
|
|
||||||
fun merge((d1,c1,...),(d2,c2,...)) = (merge_docobj_tab (d1,d2,...),
|
|
||||||
merge_docclass_tab(c1,c2,...))
|
|
||||||
);
|
|
||||||
\end{sml}
|
|
||||||
where the table \inlinesml+docobj_tab+ manages document classes and \inlinesml+docclass_tab+ the
|
|
||||||
environment for class definitions (inducing the inheritance relation). Other tables capture, \eg,
|
environment for class definitions (inducing the inheritance relation). Other tables capture, \eg,
|
||||||
the class invariants, inner-syntax antiquotations. Operations follow the MVC-pattern, where
|
the class invariants, inner-syntax antiquotations. Operations follow the MVC-pattern, where
|
||||||
Isabelle/Isar provides the controller part. A typical model operation has the type:
|
Isabelle/Isar provides the controller part. A typical model operation has the type:
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
val opn :: <args_type> -> Context.generic -> Context.generic
|
\<open>val opn :: <args_type> -> Context.generic -> Context.generic\<close>}
|
||||||
\end{sml}
|
|
||||||
representing a transformation on system contexts. For example, the operation of declaring a local
|
representing a transformation on system contexts. For example, the operation of declaring a local
|
||||||
reference in the context is presented as follows:
|
reference in the context is presented as follows:
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
fun declare_object_local oid ctxt =
|
\<open>fun declare_object_local oid ctxt =
|
||||||
let fun decl {tab,maxano} = {tab=Symtab.update_new(oid,NONE) tab,
|
let fun decl {tab,maxano} = {tab=Symtab.update_new(oid,NONE) tab,
|
||||||
maxano=maxano}
|
maxano=maxano}
|
||||||
in (Data.map(apfst decl)(ctxt)
|
in (Data.map(apfst decl)(ctxt)
|
||||||
handle Symtab.DUP _ =>
|
handle Symtab.DUP _ =>
|
||||||
error("multiple declaration of document reference"))
|
error("multiple declaration of document reference"))
|
||||||
end
|
end\<close>}
|
||||||
\end{sml}
|
|
||||||
where \<^boxed_theory_text>\<open>Data.map\<close> is the update function resulting from the instantiation of the
|
where \<^boxed_theory_text>\<open>Data.map\<close> is the update function resulting from the instantiation of the
|
||||||
functor \inlinesml|Generic_Data|. This code fragment uses operations from a library structure
|
functor \<^boxed_sml>\<open>Generic_Data\<close>. This code fragment uses operations from a library structure
|
||||||
\inlinesml+Symtab+ that were used to update the appropriate table for document objects in
|
\<^boxed_sml>\<open>Symtab\<close> that were used to update the appropriate table for document objects in
|
||||||
the plugin-local state. Possible exceptions to the update operation were mapped to a system-global
|
the plugin-local state. Possible exceptions to the update operation were mapped to a system-global
|
||||||
error reporting function.
|
error reporting function.
|
||||||
|
|
||||||
Finally, the view-aspects were handled by an API for parsing-combinators. The library structure
|
Finally, the view-aspects were handled by an API for parsing-combinators. The library structure
|
||||||
\inlinesml+Scan+ provides the operators:
|
\<^boxed_sml>\<open>Scan\<close> provides the operators:
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
op || : ('a -> 'b) * ('a -> 'b) -> 'a -> 'b
|
\<open>op || : ('a -> 'b) * ('a -> 'b) -> 'a -> 'b
|
||||||
op -- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e
|
op -- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e
|
||||||
op >> : ('a -> 'b * 'c) * ('b -> 'd) -> 'a -> 'd * 'c
|
op >> : ('a -> 'b * 'c) * ('b -> 'd) -> 'a -> 'd * 'c
|
||||||
op option : ('a -> 'b * 'a) -> 'a -> 'b option * 'a
|
op option : ('a -> 'b * 'a) -> 'a -> 'b option * 'a
|
||||||
op repeat : ('a -> 'b * 'a) -> 'a -> 'b list * 'a
|
op repeat : ('a -> 'b * 'a) -> 'a -> 'b list * 'a \<close>}
|
||||||
\end{sml}
|
|
||||||
for alternative, sequence, and piping, as well as combinators for option and repeat. Parsing
|
for alternative, sequence, and piping, as well as combinators for option and repeat. Parsing
|
||||||
combinators have the advantage that they can be smoothlessly integrated into standard programs,
|
combinators have the advantage that they can be smoothlessly integrated into standard programs,
|
||||||
and they enable the dynamic extension of the grammar. There is a more high-level structure
|
and they enable the dynamic extension of the grammar. There is a more high-level structure
|
||||||
|
@ -128,13 +109,12 @@ val attributes =(Parse.$$$ "[" |-- (reference
|
||||||
The ``model'' \<^boxed_theory_text>\<open>declare_reference_opn\<close> and ``new'' \<^boxed_theory_text>\<open>attributes\<close> parts were
|
The ``model'' \<^boxed_theory_text>\<open>declare_reference_opn\<close> and ``new'' \<^boxed_theory_text>\<open>attributes\<close> parts were
|
||||||
combined via the piping operator and registered in the Isar toplevel:
|
combined via the piping operator and registered in the Isar toplevel:
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
fun declare_reference_opn (((oid,_),_),_) =
|
\<open>fun declare_reference_opn (((oid,_),_),_) =
|
||||||
(Toplevel.theory (DOF_core.declare_object_global oid))
|
(Toplevel.theory (DOF_core.declare_object_global oid))
|
||||||
val _ = Outer_Syntax.command <@>{command_keyword "declare_reference"}
|
val _ = Outer_Syntax.command <@>{command_keyword "declare_reference"}
|
||||||
"declare document reference"
|
"declare document reference"
|
||||||
(attributes >> declare_reference_opn);
|
(attributes >> declare_reference_opn);\<close>}
|
||||||
\end{sml}
|
|
||||||
|
|
||||||
Altogether, this gives the extension of Isabelle/HOL with Isar syntax and semantics for the
|
Altogether, this gives the extension of Isabelle/HOL with Isar syntax and semantics for the
|
||||||
new \emph{command}:
|
new \emph{command}:
|
||||||
|
@ -154,14 +134,13 @@ text\<open>
|
||||||
principle: based on a number of combinators, new user-defined antiquotation syntax and semantics
|
principle: based on a number of combinators, new user-defined antiquotation syntax and semantics
|
||||||
can be added to the system that works on the internal plugin-data freely. For example, in
|
can be added to the system that works on the internal plugin-data freely. For example, in
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
val _ = Theory.setup(
|
\<open>val _ = Theory.setup(
|
||||||
Thy_Output.antiquotation <@>{binding docitem}
|
Thy_Output.antiquotation <@>{binding docitem}
|
||||||
docitem_antiq_parser
|
docitem_antiq_parser
|
||||||
(docitem_antiq_gen default_cid) #>
|
(docitem_antiq_gen default_cid) #>
|
||||||
ML_Antiquotation.inline <@>{binding docitem_value}
|
ML_Antiquotation.inline <@>{binding docitem_value}
|
||||||
ML_antiq_docitem_value)
|
ML_antiq_docitem_value)\<close>}
|
||||||
\end{sml}
|
|
||||||
the text antiquotation \<^boxed_theory_text>\<open>docitem\<close> is declared and bounded to a parser for the argument
|
the text antiquotation \<^boxed_theory_text>\<open>docitem\<close> is declared and bounded to a parser for the argument
|
||||||
syntax and the overall semantics. This code defines a generic antiquotation to be used in text
|
syntax and the overall semantics. This code defines a generic antiquotation to be used in text
|
||||||
elements such as
|
elements such as
|
||||||
|
@ -188,9 +167,8 @@ text\<open>
|
||||||
late-binding table \<^boxed_theory_text>\<open>ISA_transformer_tab\<close>, we register for each inner-syntax-annotation
|
late-binding table \<^boxed_theory_text>\<open>ISA_transformer_tab\<close>, we register for each inner-syntax-annotation
|
||||||
(ISA's), a function of type
|
(ISA's), a function of type
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
theory -> term * typ * Position.T -> term option
|
\<open> theory -> term * typ * Position.T -> term option\<close>}
|
||||||
\end{sml}
|
|
||||||
|
|
||||||
Executed in a second pass of term parsing, ISA's may just return \<^boxed_theory_text>\<open>None\<close>. This is
|
Executed in a second pass of term parsing, ISA's may just return \<^boxed_theory_text>\<open>None\<close>. This is
|
||||||
adequate for ISA's just performing some checking in the logical context \<^boxed_theory_text>\<open>theory\<close>;
|
adequate for ISA's just performing some checking in the logical context \<^boxed_theory_text>\<open>theory\<close>;
|
||||||
|
@ -205,8 +183,8 @@ text\<open>
|
||||||
For the moment, there is no high-level syntax for the definition of class invariants. A
|
For the moment, there is no high-level syntax for the definition of class invariants. A
|
||||||
formulation, in SML, of the first class-invariant in @{docitem "sec:class_inv"} is straight-forward:
|
formulation, in SML, of the first class-invariant in @{docitem "sec:class_inv"} is straight-forward:
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
fun check_result_inv oid {is_monitor:bool} ctxt =
|
\<open>fun check_result_inv oid {is_monitor:bool} ctxt =
|
||||||
let val kind = compute_attr_access ctxt "kind" oid <@>{here} <@>{here}
|
let val kind = compute_attr_access ctxt "kind" oid <@>{here} <@>{here}
|
||||||
val prop = compute_attr_access ctxt "property" oid <@>{here} <@>{here}
|
val prop = compute_attr_access ctxt "property" oid <@>{here} <@>{here}
|
||||||
val tS = HOLogic.dest_list prop
|
val tS = HOLogic.dest_list prop
|
||||||
|
@ -216,10 +194,9 @@ fun check_result_inv oid {is_monitor:bool} ctxt =
|
||||||
| _ => false
|
| _ => false
|
||||||
end
|
end
|
||||||
val _ = Theory.setup (DOF_core.update_class_invariant
|
val _ = Theory.setup (DOF_core.update_class_invariant
|
||||||
"tiny_cert.result" check_result_inv)
|
"tiny_cert.result" check_result_inv)\<close>}
|
||||||
\end{sml}
|
|
||||||
|
|
||||||
The \inlinesml{setup}-command (last line) registers the \<^boxed_theory_text>\<open>check_result_inv\<close> function
|
The \<^boxed_sml>\<open>setup\<close>-command (last line) registers the \<^boxed_theory_text>\<open>check_result_inv\<close> function
|
||||||
into the \<^isadof> kernel, which activates any creation or modification of an instance of
|
into the \<^isadof> kernel, which activates any creation or modification of an instance of
|
||||||
\<^boxed_theory_text>\<open>result\<close>. We cannot replace \<^boxed_theory_text>\<open>compute_attr_access\<close> by the corresponding
|
\<^boxed_theory_text>\<open>result\<close>. We cannot replace \<^boxed_theory_text>\<open>compute_attr_access\<close> by the corresponding
|
||||||
antiquotation \<^boxed_theory_text>\<open>@{docitem_value kind::oid}\<close>, since \<^boxed_theory_text>\<open>oid\<close> is
|
antiquotation \<^boxed_theory_text>\<open>@{docitem_value kind::oid}\<close>, since \<^boxed_theory_text>\<open>oid\<close> is
|
||||||
|
@ -232,10 +209,9 @@ text\<open>
|
||||||
deterministic automata. These are stored in the \<^boxed_theory_text>\<open>docobj_tab\<close> for monitor-objects
|
deterministic automata. These are stored in the \<^boxed_theory_text>\<open>docobj_tab\<close> for monitor-objects
|
||||||
in the \<^isadof> component. We implemented the functions:
|
in the \<^isadof> component. We implemented the functions:
|
||||||
|
|
||||||
\begin{sml}
|
@{boxed_sml [display]
|
||||||
val enabled : automaton -> env -> cid list
|
\<open> val enabled : automaton -> env -> cid list
|
||||||
val next : automaton -> env -> cid -> automaton
|
val next : automaton -> env -> cid -> automaton\<close>}
|
||||||
\end{sml}
|
|
||||||
where \<^boxed_theory_text>\<open>env\<close> is basically a map between internal automaton states and class-id's
|
where \<^boxed_theory_text>\<open>env\<close> is basically a map between internal automaton states and class-id's
|
||||||
(\<^boxed_theory_text>\<open>cid\<close>'s). An automaton is said to be \<^emph>\<open>enabled\<close> for a class-id,
|
(\<^boxed_theory_text>\<open>cid\<close>'s). An automaton is said to be \<^emph>\<open>enabled\<close> for a class-id,
|
||||||
iff it either occurs in its accept-set or its reject-set (see @{docitem "sec:monitors"}). During
|
iff it either occurs in its accept-set or its reject-set (see @{docitem "sec:monitors"}). During
|
||||||
|
@ -252,41 +228,38 @@ text\<open>
|
||||||
``keycommand''~@{cite "chervet:keycommand:2010"} package. In fact, the core \<^isadof> \LaTeX-commands
|
``keycommand''~@{cite "chervet:keycommand:2010"} package. In fact, the core \<^isadof> \LaTeX-commands
|
||||||
are just wrappers for the corresponding commands from the keycommand package:
|
are just wrappers for the corresponding commands from the keycommand package:
|
||||||
|
|
||||||
\begin{ltx}
|
@{boxed_latex [display]
|
||||||
\newcommand\newisadof[1]{%
|
\<open>\newcommand\newisadof[1]{%
|
||||||
\expandafter\newkeycommand\csname isaDof.#1\endcsname}%
|
\expandafter\newkeycommand\csname isaDof.#1\endcsname}%
|
||||||
\newcommand\renewisadof[1]{%
|
\newcommand\renewisadof[1]{%
|
||||||
\expandafter\renewkeycommand\csname isaDof.#1\endcsname}%
|
\expandafter\renewkeycommand\csname isaDof.#1\endcsname}%
|
||||||
\newcommand\provideisadof[1]{%
|
\newcommand\provideisadof[1]{%
|
||||||
\expandafter\providekeycommand\csname isaDof.#1\endcsname}%
|
\expandafter\providekeycommand\csname isaDof.#1\endcsname}%\<close>}
|
||||||
\end{ltx}
|
|
||||||
|
|
||||||
The \LaTeX-generator of \<^isadof> maps each \<^boxed_theory_text>\<open>doc_item\<close> to an \LaTeX-environment (recall
|
The \LaTeX-generator of \<^isadof> maps each \<^boxed_theory_text>\<open>doc_item\<close> to an \LaTeX-environment (recall
|
||||||
@{docitem "text-elements"}). As generic \<^boxed_theory_text>\<open>doc_item\<close> are derived from the text element,
|
@{docitem "text-elements"}). As generic \<^boxed_theory_text>\<open>doc_item\<close> are derived from the text element,
|
||||||
the enviornment \inlineltx|{isamarkuptext*}| builds the core of \<^isadof>'s \LaTeX{} implementation.
|
the enviornment \inlineltx|{isamarkuptext*}| builds the core of \<^isadof>'s \LaTeX{} implementation.
|
||||||
For example, the @{docitem "ass123"} from page \pageref{ass123} is mapped to
|
For example, the @{docitem "ass123"} from page \pageref{ass123} is mapped to
|
||||||
|
|
||||||
\begin{ltx}
|
@{boxed_latex [display]
|
||||||
\begin{isamarkuptext*}%
|
\<open>\begin{isamarkuptext*}%
|
||||||
[label = {ass122},type = {CENELEC_50128.SRAC},
|
[label = {ass122},type = {CENELEC_50128.SRAC},
|
||||||
args={label = {ass122}, type = {CENELEC_50128.SRAC},
|
args={label = {ass122}, type = {CENELEC_50128.SRAC},
|
||||||
CENELEC_50128.EC.assumption_kind = {formal}}
|
CENELEC_50128.EC.assumption_kind = {formal}}
|
||||||
] The overall sampling frequence of the odometer subsystem is therefore
|
] The overall sampling frequence of the odometer subsystem is therefore
|
||||||
14 khz, which includes sampling, computing and result communication
|
14 khz, which includes sampling, computing and result communication
|
||||||
times ...
|
times ...
|
||||||
\end{isamarkuptext*}
|
\end{isamarkuptext*}\<close>}
|
||||||
\end{ltx}
|
|
||||||
|
|
||||||
This environment is mapped to a plain \LaTeX command via (again, recall @{docitem "text-elements"}):
|
This environment is mapped to a plain \LaTeX command via (again, recall @{docitem "text-elements"}):
|
||||||
\begin{ltx}
|
@{boxed_latex [display]
|
||||||
\NewEnviron{isamarkuptext*}[1][]{\isaDof[env={text},#1]{\BODY}}
|
\<open> \NewEnviron{isamarkuptext*}[1][]{\isaDof[env={text},#1]{\BODY}} \<close>}
|
||||||
\end{ltx}
|
|
||||||
|
|
||||||
For the command-based setup, \<^isadof> provides a dispatcher that selects the most specific
|
For the command-based setup, \<^isadof> provides a dispatcher that selects the most specific
|
||||||
implementation for a given \<^boxed_theory_text>\<open>doc_class\<close>:
|
implementation for a given \<^boxed_theory_text>\<open>doc_class\<close>:
|
||||||
|
|
||||||
\begin{ltx}
|
@{boxed_latex [display]
|
||||||
%% The Isabelle/DOF dispatcher:
|
\<open>%% The Isabelle/DOF dispatcher:
|
||||||
\newkeycommand+[\|]\isaDof[env={UNKNOWN},label=,type={dummyT},args={}][1]{%
|
\newkeycommand+[\|]\isaDof[env={UNKNOWN},label=,type={dummyT},args={}][1]{%
|
||||||
\ifcsname isaDof.\commandkey{type}\endcsname%
|
\ifcsname isaDof.\commandkey{type}\endcsname%
|
||||||
\csname isaDof.\commandkey{type}\endcsname%
|
\csname isaDof.\commandkey{type}\endcsname%
|
||||||
|
@ -307,8 +280,7 @@ implementation for a given \<^boxed_theory_text>\<open>doc_class\<close>:
|
||||||
definition for "\commandkey{env}" available either.}%
|
definition for "\commandkey{env}" available either.}%
|
||||||
\fi%
|
\fi%
|
||||||
\fi%
|
\fi%
|
||||||
}
|
}\<close>}
|
||||||
\end{ltx}
|
|
||||||
\<close>
|
\<close>
|
||||||
|
|
||||||
(*<*)
|
(*<*)
|
||||||
|
|
Loading…
Reference in New Issue