2018-09-11 07:33:17 +00:00
|
|
|
chapter \<open>The Document Ontology Framework for Isabelle\<close>
|
|
|
|
|
|
|
|
text\<open> Offering
|
|
|
|
\<^item> text-elements that can be annotated with meta-information
|
|
|
|
\<^item> typed links to text-elements via specifically generated anti-quotations
|
|
|
|
\<^item> typed structure of this meta-information specifiable in an Ontology-Language ODL
|
|
|
|
\<^item> inner-syntax-antiquotations allowing to reference Isabelle-entities such as
|
|
|
|
types, terms, theorems inside the meta-information
|
|
|
|
\<^item> monitors allowing to enforce a specific textual structure of an Isabelle Document
|
|
|
|
\<^item> LaTeX support. \<close>
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
text\<open> In this section, we develop on the basis of a management of references Isar-markups
|
|
|
|
that provide direct support in the PIDE framework. \<close>
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-11-04 17:56:59 +00:00
|
|
|
theory Isa_DOF (* Isabelle Document Ontology Framework *)
|
|
|
|
imports Main
|
|
|
|
RegExpInterface (* Interface to functional regular automata for monitoring *)
|
2018-05-14 13:47:16 +00:00
|
|
|
Assert
|
2018-10-30 14:50:01 +00:00
|
|
|
|
2018-04-29 09:35:24 +00:00
|
|
|
keywords "+=" ":="
|
|
|
|
|
2018-06-11 15:35:12 +00:00
|
|
|
and "title*" "subtitle*"
|
2018-10-30 01:29:15 +00:00
|
|
|
"chapter*" "section*" "subsection*" "subsubsection*"
|
2018-09-17 19:32:11 +00:00
|
|
|
"text*"
|
2018-06-11 15:35:12 +00:00
|
|
|
"paragraph*" "subparagraph*"
|
2018-09-17 19:32:11 +00:00
|
|
|
"figure*"
|
|
|
|
"side_by_side_figure*"
|
|
|
|
:: document_body
|
2018-04-29 09:35:24 +00:00
|
|
|
|
|
|
|
and "open_monitor*" "close_monitor*" "declare_reference*"
|
2018-04-27 08:34:24 +00:00
|
|
|
"update_instance*" "doc_class" ::thy_decl
|
2018-04-29 09:35:24 +00:00
|
|
|
|
2018-06-27 07:12:50 +00:00
|
|
|
and "lemma*" "theorem*" "assert*" ::thy_decl
|
2018-08-19 08:17:17 +00:00
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
and "print_doc_classes" "print_doc_items" "gen_sty_template" :: diag
|
2018-04-29 09:35:24 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
begin
|
2018-09-11 06:50:51 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
section\<open>Primitive Markup Generators\<close>
|
|
|
|
ML\<open>
|
2018-02-28 13:06:52 +00:00
|
|
|
|
2018-03-28 15:05:01 +00:00
|
|
|
val docrefN = "docref";
|
|
|
|
val docclassN = "doc_class";
|
2018-02-28 13:06:52 +00:00
|
|
|
|
2018-03-28 11:08:55 +00:00
|
|
|
(* derived from: theory_markup *)
|
2018-03-28 15:05:01 +00:00
|
|
|
fun docref_markup_gen refN def name id pos =
|
2018-02-28 13:06:52 +00:00
|
|
|
if id = 0 then Markup.empty
|
|
|
|
else
|
|
|
|
Markup.properties (Position.entity_properties_of def id pos)
|
2018-03-28 15:05:01 +00:00
|
|
|
(Markup.entity refN name); (* or better store the thy-name as property ? ? ? *)
|
|
|
|
|
|
|
|
val docref_markup = docref_markup_gen docrefN
|
|
|
|
|
|
|
|
val docclass_markup = docref_markup_gen docclassN
|
2018-09-11 06:50:51 +00:00
|
|
|
\<close>
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-09-03 19:31:06 +00:00
|
|
|
|
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
section\<open> A HomeGrown Document Type Management (the ''Model'') \<close>
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
ML\<open>
|
2018-02-09 11:25:15 +00:00
|
|
|
structure DOF_core =
|
2018-02-07 18:44:27 +00:00
|
|
|
struct
|
2018-02-08 15:25:15 +00:00
|
|
|
type docclass_struct = {params : (string * sort) list, (*currently not used *)
|
|
|
|
name : binding, thy_name : string, id : serial, (* for pide *)
|
2018-11-04 17:56:59 +00:00
|
|
|
inherits_from : (typ list * string) option, (* imports *)
|
|
|
|
attribute_decl : (binding * typ * term option) list, (* class local *)
|
|
|
|
rex : term list } (* monitoring regexps --- product semantics*)
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
type docclass_tab = docclass_struct Symtab.table
|
|
|
|
|
|
|
|
val initial_docclass_tab = Symtab.empty:docclass_tab
|
|
|
|
|
|
|
|
fun merge_docclass_tab (otab,otab') = Symtab.merge (op =) (otab,otab')
|
|
|
|
|
2018-02-28 10:31:42 +00:00
|
|
|
|
2018-02-28 13:06:52 +00:00
|
|
|
val default_cid = "text" (* the top (default) document class: everything is a text.*)
|
2018-02-28 10:31:42 +00:00
|
|
|
|
|
|
|
fun is_subclass0 (tab:docclass_tab) s t =
|
2018-02-07 18:44:27 +00:00
|
|
|
let val _ = case Symtab.lookup tab t of
|
2018-02-28 10:31:42 +00:00
|
|
|
NONE => if t <> default_cid
|
2018-04-04 16:08:18 +00:00
|
|
|
then error ("document superclass not defined: "^t)
|
2018-02-28 10:31:42 +00:00
|
|
|
else default_cid
|
|
|
|
| SOME _ => ""
|
2018-02-07 18:44:27 +00:00
|
|
|
fun father_is_sub s = case Symtab.lookup tab s of
|
2018-04-04 16:08:18 +00:00
|
|
|
NONE => error ("document subclass not defined: "^s)
|
2018-02-08 15:25:15 +00:00
|
|
|
| SOME ({inherits_from=NONE, ...}) => s = t
|
2018-02-28 10:31:42 +00:00
|
|
|
| SOME ({inherits_from=SOME (_,s'), ...}) =>
|
|
|
|
s' = t orelse father_is_sub s'
|
|
|
|
in s = t orelse
|
2018-10-09 13:56:17 +00:00
|
|
|
(t = default_cid andalso Symtab.defined tab s ) orelse
|
|
|
|
(s <> default_cid andalso father_is_sub s)
|
2018-02-07 18:44:27 +00:00
|
|
|
end
|
|
|
|
|
2018-09-03 18:56:08 +00:00
|
|
|
type docobj = {pos : Position.T,
|
|
|
|
thy_name : string,
|
|
|
|
value : term,
|
|
|
|
id : serial, cid : string}
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
type docobj_tab ={tab : (docobj option) Symtab.table,
|
|
|
|
maxano : int
|
|
|
|
}
|
|
|
|
|
|
|
|
val initial_docobj_tab:docobj_tab = {tab = Symtab.empty, maxano = 0}
|
|
|
|
|
|
|
|
fun merge_docobj_tab ({tab=otab,maxano=m}, {tab=otab',maxano=m'}) =
|
|
|
|
(let fun X(NONE,NONE) = false
|
|
|
|
|X(SOME _, NONE) = false
|
|
|
|
|X(NONE, SOME _) = false
|
|
|
|
|X(SOME b, SOME b') = true (* b = b' *)
|
|
|
|
in {tab=Symtab.merge X (otab,otab'),maxano=Int.max(m,m')}
|
|
|
|
end)
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
type ISA_transformer_tab = (theory -> term * typ * Position.T -> term option) Symtab.table
|
2018-09-03 18:56:08 +00:00
|
|
|
|
|
|
|
val initial_ISA_tab:ISA_transformer_tab = Symtab.empty
|
|
|
|
|
2018-10-11 11:38:32 +00:00
|
|
|
type open_monitor_info = {accepted_cids : string list,
|
2018-10-08 13:13:47 +00:00
|
|
|
regexp_stack : term list list (* really ? *)}
|
2018-10-09 13:56:17 +00:00
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
type monitor_tab = open_monitor_info Symtab.table
|
|
|
|
|
|
|
|
val initial_monitor_tab:monitor_tab = Symtab.empty
|
|
|
|
|
|
|
|
|
2018-04-04 12:44:21 +00:00
|
|
|
(* registrating data of the Isa_DOF component *)
|
2018-02-07 18:44:27 +00:00
|
|
|
structure Data = Generic_Data
|
|
|
|
(
|
2018-10-08 13:13:47 +00:00
|
|
|
type T = {docobj_tab : docobj_tab,
|
|
|
|
docclass_tab : docclass_tab,
|
|
|
|
ISA_transformer_tab : ISA_transformer_tab,
|
|
|
|
monitor_tab : monitor_tab}
|
2018-10-05 07:45:24 +00:00
|
|
|
val empty = {docobj_tab = initial_docobj_tab,
|
|
|
|
docclass_tab = initial_docclass_tab,
|
2018-10-08 13:13:47 +00:00
|
|
|
ISA_transformer_tab = initial_ISA_tab,
|
|
|
|
monitor_tab = initial_monitor_tab
|
|
|
|
}
|
2018-10-05 07:45:24 +00:00
|
|
|
val extend = I
|
2018-10-08 13:13:47 +00:00
|
|
|
fun merge( {docobj_tab=d1,docclass_tab = c1,ISA_transformer_tab = e1, monitor_tab=m1},
|
|
|
|
{docobj_tab=d2,docclass_tab = c2,ISA_transformer_tab = e2, monitor_tab=m2}) =
|
2018-10-05 07:45:24 +00:00
|
|
|
{docobj_tab=merge_docobj_tab (d1,d2),
|
|
|
|
docclass_tab = merge_docclass_tab (c1,c2),
|
2018-10-08 13:13:47 +00:00
|
|
|
ISA_transformer_tab = Symtab.merge (fn (_ , _) => false)(e1,e2),
|
|
|
|
monitor_tab = Symtab.merge (op =)(m1,m2)
|
|
|
|
(* PROVISORY ... ITS A REAL QUESTION HOW TO DO THIS!*)
|
2018-10-09 07:59:46 +00:00
|
|
|
}
|
2018-02-07 18:44:27 +00:00
|
|
|
);
|
|
|
|
|
2018-09-03 18:56:08 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
val get_data = Data.get o Context.Proof;
|
|
|
|
val map_data = Data.map;
|
|
|
|
val get_data_global = Data.get o Context.Theory;
|
|
|
|
val map_data_global = Context.theory_map o map_data;
|
|
|
|
|
2018-10-08 08:30:53 +00:00
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
fun upd_docobj_tab f {docobj_tab,docclass_tab,ISA_transformer_tab, monitor_tab} =
|
|
|
|
{docobj_tab = f docobj_tab, docclass_tab=docclass_tab,
|
|
|
|
ISA_transformer_tab=ISA_transformer_tab, monitor_tab=monitor_tab};
|
|
|
|
fun upd_docclass_tab f {docobj_tab=x,docclass_tab = y,ISA_transformer_tab = z, monitor_tab} =
|
|
|
|
{docobj_tab=x,docclass_tab = f y,ISA_transformer_tab = z, monitor_tab=monitor_tab};
|
|
|
|
fun upd_ISA_transformers f{docobj_tab=x,docclass_tab = y,ISA_transformer_tab = z, monitor_tab} =
|
|
|
|
{docobj_tab=x,docclass_tab = y,ISA_transformer_tab = f z, monitor_tab=monitor_tab};
|
|
|
|
fun upd_monitor_tabs f {docobj_tab,docclass_tab,ISA_transformer_tab, monitor_tab} =
|
|
|
|
{docobj_tab = docobj_tab,docclass_tab = docclass_tab,
|
|
|
|
ISA_transformer_tab = ISA_transformer_tab, monitor_tab = f monitor_tab};
|
|
|
|
|
|
|
|
|
2018-10-11 11:38:32 +00:00
|
|
|
fun get_accepted_cids ({accepted_cids, regexp_stack }:open_monitor_info) = accepted_cids
|
2018-11-04 17:56:59 +00:00
|
|
|
fun get_regexp_stack ({accepted_cids, regexp_stack }:open_monitor_info) = regexp_stack
|
2018-10-09 13:56:17 +00:00
|
|
|
|
2018-02-27 11:02:19 +00:00
|
|
|
|
|
|
|
(* doc-class-name management: We still use the record-package for internally
|
|
|
|
representing doc-classes. The main motivation is that "links" to entities are
|
|
|
|
types over doc-classes, *types* in the Isabelle sense, enriched by additional data.
|
|
|
|
This has the advantage that the type-inference can be abused to infer long-names
|
|
|
|
for doc-class-names. Note, however, that doc-classes are currently implemented
|
|
|
|
by non-polymorphic records only; this means that the extensible "_ext" versions
|
|
|
|
of type names must be reduced to qualifier names only. The used Syntax.parse_typ
|
|
|
|
handling the identification does that already. *)
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_subclass (ctxt) s t = is_subclass0(#docclass_tab(get_data ctxt)) s t
|
2018-10-09 13:56:17 +00:00
|
|
|
fun is_subclass_global thy s t = is_subclass0(#docclass_tab(get_data_global thy)) s t
|
2018-02-28 10:31:42 +00:00
|
|
|
|
2018-02-27 11:02:19 +00:00
|
|
|
fun type_name2doc_class_name thy str = (* Long_Name.qualifier *) str
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun typ_to_cid (Type(s,[@{typ "unit"}])) = Long_Name.qualifier s
|
|
|
|
|typ_to_cid (Type(_,[T])) = typ_to_cid T
|
|
|
|
|typ_to_cid _ = error("type is not an ontological type.")
|
|
|
|
|
2018-02-27 11:02:19 +00:00
|
|
|
fun name2doc_class_name thy str =
|
|
|
|
case Syntax.parse_typ (Proof_Context.init_global thy) str of
|
|
|
|
Type(tyn, _) => type_name2doc_class_name thy tyn
|
|
|
|
| _ => error "illegal format for doc-class-name."
|
|
|
|
handle ERROR _ => ""
|
|
|
|
|
|
|
|
fun name2doc_class_name_local ctxt str =
|
|
|
|
(case Syntax.parse_typ ctxt str of
|
|
|
|
Type(tyn, _) => type_name2doc_class_name ctxt tyn
|
|
|
|
| _ => error "illegal format for doc-class-name.")
|
|
|
|
handle ERROR _ => ""
|
|
|
|
|
|
|
|
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_defined_cid_global cid thy = let val t = #docclass_tab(get_data_global thy)
|
2018-02-27 11:02:19 +00:00
|
|
|
in cid=default_cid orelse
|
|
|
|
Symtab.defined t (name2doc_class_name thy cid)
|
|
|
|
end
|
|
|
|
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_defined_cid_local cid ctxt = let val t = #docclass_tab(get_data ctxt)
|
2018-02-27 11:02:19 +00:00
|
|
|
in cid=default_cid orelse
|
|
|
|
Symtab.defined t (name2doc_class_name_local ctxt cid)
|
|
|
|
end
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_declared_oid_global oid thy = let val {tab,...} = #docobj_tab(get_data_global thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
in Symtab.defined tab oid end
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_declared_oid_local oid thy = let val {tab,...} = #docobj_tab(get_data thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
in Symtab.defined tab oid end
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_defined_oid_global oid thy = let val {tab,...} = #docobj_tab(get_data_global thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
in case Symtab.lookup tab oid of
|
2018-02-07 18:44:27 +00:00
|
|
|
NONE => false
|
|
|
|
|SOME(NONE) => false
|
|
|
|
|SOME _ => true
|
|
|
|
end
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_defined_oid_local oid thy = let val {tab,...} = #docobj_tab(get_data thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
in case Symtab.lookup tab oid of
|
2018-02-07 18:44:27 +00:00
|
|
|
NONE => false
|
|
|
|
|SOME(NONE) => false
|
|
|
|
|SOME _ => true
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2018-04-04 08:45:56 +00:00
|
|
|
fun declare_object_global oid thy =
|
|
|
|
let fun decl {tab=t,maxano=x} = {tab=Symtab.update_new(oid,NONE)t, maxano=x}
|
2018-10-08 08:30:53 +00:00
|
|
|
in (map_data_global (upd_docobj_tab(decl)) (thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
handle Symtab.DUP _ => error("multiple declaration of document reference"))
|
|
|
|
end
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-04-04 08:45:56 +00:00
|
|
|
fun declare_object_local oid ctxt =
|
|
|
|
let fun decl {tab,maxano} = {tab=Symtab.update_new(oid,NONE) tab, maxano=maxano}
|
2018-10-08 08:30:53 +00:00
|
|
|
in (map_data(upd_docobj_tab decl)(ctxt)
|
2018-04-04 08:45:56 +00:00
|
|
|
handle Symtab.DUP _ => error("multiple declaration of document reference"))
|
|
|
|
end
|
2018-02-28 13:06:52 +00:00
|
|
|
|
|
|
|
|
2018-10-08 08:30:53 +00:00
|
|
|
fun define_doc_class_global (params', binding) parent fields reg_exp thy =
|
2018-04-04 08:45:56 +00:00
|
|
|
let val nn = Context.theory_name thy (* in case that we need the thy-name to identify
|
|
|
|
the space where it is ... *)
|
|
|
|
val cid = (Binding.name_of binding)
|
|
|
|
val pos = (Binding.pos_of binding)
|
|
|
|
|
|
|
|
val _ = if is_defined_cid_global cid thy
|
|
|
|
then error("redefinition of document class")
|
|
|
|
else ()
|
|
|
|
|
|
|
|
val _ = case parent of (* the doc_class may be root, but must refer
|
|
|
|
to another doc_class and not just an
|
|
|
|
arbitrary type *)
|
|
|
|
NONE => ()
|
|
|
|
| SOME(_,cid_parent) =>
|
|
|
|
if not (is_defined_cid_global cid_parent thy)
|
|
|
|
then error("document class undefined : " ^ cid_parent)
|
|
|
|
else ()
|
|
|
|
val cid_long = name2doc_class_name thy cid
|
|
|
|
val id = serial ();
|
|
|
|
val _ = Position.report pos (docclass_markup true cid id pos);
|
|
|
|
|
|
|
|
val info = {params=params',
|
|
|
|
name = binding,
|
|
|
|
thy_name = nn,
|
|
|
|
id = id, (* for pide --- really fresh or better reconstruct
|
2018-04-04 12:44:21 +00:00
|
|
|
from prior record definition ? For the moment: own
|
|
|
|
generation of serials ... *)
|
2018-04-04 08:45:56 +00:00
|
|
|
inherits_from = parent,
|
2018-10-08 08:30:53 +00:00
|
|
|
attribute_decl = fields ,
|
|
|
|
rex = reg_exp }
|
2018-04-04 08:45:56 +00:00
|
|
|
|
2018-10-08 08:30:53 +00:00
|
|
|
in map_data_global(upd_docclass_tab(Symtab.update(cid_long,info)))(thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
end
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
fun define_object_global (oid, bbb) thy =
|
2018-04-04 08:45:56 +00:00
|
|
|
let val nn = Context.theory_name thy (* in case that we need the thy-name to identify
|
|
|
|
the space where it is ... *)
|
|
|
|
in if is_defined_oid_global oid thy
|
|
|
|
then error("multiple definition of document reference")
|
2018-10-08 08:30:53 +00:00
|
|
|
else map_data_global (upd_docobj_tab(fn {tab=t,maxano=x} =>
|
2018-04-04 08:45:56 +00:00
|
|
|
{tab=Symtab.update(oid,SOME bbb) t,
|
|
|
|
maxano=x}))
|
2018-08-18 12:44:39 +00:00
|
|
|
(thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
end
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
fun define_object_local (oid, bbb) ctxt =
|
2018-10-08 08:30:53 +00:00
|
|
|
map_data (upd_docobj_tab(fn{tab,maxano}=>{tab=Symtab.update(oid,SOME bbb)tab,maxano=maxano})) ctxt
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
(* declares an anonyme label of a given type and generates a unique reference ... *)
|
2018-04-04 08:45:56 +00:00
|
|
|
fun declare_anoobject_global thy cid =
|
|
|
|
let fun declare {tab,maxano} = let val str = cid^":"^Int.toString(maxano+1)
|
|
|
|
val _ = writeln("Anonymous doc-ref declared: " ^ str)
|
|
|
|
in {tab=Symtab.update(str,NONE)tab,maxano= maxano+1} end
|
2018-10-08 08:30:53 +00:00
|
|
|
in map_data_global (upd_docobj_tab declare) (thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
fun declare_anoobject_local ctxt cid =
|
|
|
|
let fun declare {tab,maxano} = let val str = cid^":"^Int.toString(maxano+1)
|
|
|
|
val _ = writeln("Anonymous doc-ref declared: " ^str)
|
|
|
|
in {tab=Symtab.update(str,NONE)tab, maxano=maxano+1} end
|
2018-10-08 08:30:53 +00:00
|
|
|
in map_data (upd_docobj_tab declare) (ctxt)
|
2018-04-04 08:45:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun get_object_global oid thy = let val {tab,...} = #docobj_tab(get_data_global thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
in case Symtab.lookup tab oid of
|
2018-04-27 08:34:24 +00:00
|
|
|
NONE => error("undefined reference: "^oid)
|
2018-04-04 08:45:56 +00:00
|
|
|
|SOME(bbb) => bbb
|
|
|
|
end
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun get_object_local oid ctxt = let val {tab,...} = #docobj_tab(get_data ctxt)
|
2018-04-04 08:45:56 +00:00
|
|
|
in case Symtab.lookup tab oid of
|
2018-04-27 08:34:24 +00:00
|
|
|
NONE => error("undefined reference: "^oid)
|
2018-04-04 08:45:56 +00:00
|
|
|
|SOME(bbb) => bbb
|
|
|
|
end
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-02-28 10:31:42 +00:00
|
|
|
fun get_doc_class_global cid thy =
|
2018-04-04 08:45:56 +00:00
|
|
|
if cid = default_cid then error("default doc class acces") (* TODO *)
|
2018-10-05 07:45:24 +00:00
|
|
|
else let val t = #docclass_tab(get_data_global thy)
|
2018-04-04 08:45:56 +00:00
|
|
|
in (Symtab.lookup t cid) end
|
|
|
|
|
2018-02-28 10:31:42 +00:00
|
|
|
|
|
|
|
fun get_doc_class_local cid ctxt =
|
2018-04-04 08:45:56 +00:00
|
|
|
if cid = default_cid then error("default doc class acces") (* TODO *)
|
2018-10-05 07:45:24 +00:00
|
|
|
else let val t = #docclass_tab(get_data ctxt)
|
2018-04-04 08:45:56 +00:00
|
|
|
in (Symtab.lookup t cid) end
|
2018-02-28 10:31:42 +00:00
|
|
|
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun is_defined_cid_local cid ctxt = let val t = #docclass_tab(get_data ctxt)
|
2018-02-28 10:31:42 +00:00
|
|
|
in cid=default_cid orelse
|
|
|
|
Symtab.defined t (name2doc_class_name_local ctxt cid)
|
|
|
|
end
|
|
|
|
|
2018-08-20 11:54:53 +00:00
|
|
|
|
2018-04-20 11:19:50 +00:00
|
|
|
fun get_attributes_local cid ctxt =
|
|
|
|
if cid = default_cid then []
|
2018-10-05 07:45:24 +00:00
|
|
|
else let val t = #docclass_tab(get_data ctxt)
|
2018-04-20 11:19:50 +00:00
|
|
|
val cid_long = name2doc_class_name_local ctxt cid
|
|
|
|
in case Symtab.lookup t cid_long of
|
|
|
|
NONE => error("undefined doc class id :"^cid)
|
|
|
|
| SOME ({inherits_from=NONE,
|
|
|
|
attribute_decl = X, ...}) => [(cid_long,X)]
|
|
|
|
| SOME ({inherits_from=SOME(_,father),
|
|
|
|
attribute_decl = X, ...}) => get_attributes_local father ctxt @ [(cid_long,X)]
|
|
|
|
end
|
|
|
|
|
|
|
|
fun get_attributes cid thy = get_attributes_local cid (Proof_Context.init_global thy)
|
|
|
|
|
2018-08-20 11:54:53 +00:00
|
|
|
type attributes_info = { def_occurrence : string,
|
2018-08-28 16:21:37 +00:00
|
|
|
def_pos : Position.T,
|
|
|
|
long_name : string,
|
|
|
|
typ : typ
|
2018-08-20 11:54:53 +00:00
|
|
|
}
|
|
|
|
|
2018-08-20 18:29:04 +00:00
|
|
|
fun get_attribute_info_local (*long*)cid attr ctxt : attributes_info option=
|
2018-04-20 11:19:50 +00:00
|
|
|
let val hierarchy = get_attributes_local cid ctxt (* search in order *)
|
2018-08-20 11:54:53 +00:00
|
|
|
fun found (s,L) = case find_first (fn (bind,_,_) => Binding.name_of bind = attr) L of
|
|
|
|
NONE => NONE
|
|
|
|
| SOME X => SOME(s,X)
|
2018-04-20 11:19:50 +00:00
|
|
|
in case get_first found hierarchy of
|
|
|
|
NONE => NONE
|
2018-08-20 11:54:53 +00:00
|
|
|
| SOME (cid',(bind, ty,_)) => SOME({def_occurrence = cid,
|
2018-08-22 20:06:15 +00:00
|
|
|
def_pos = Binding.pos_of bind,
|
2018-08-20 11:54:53 +00:00
|
|
|
long_name = cid'^"."^(Binding.name_of bind),
|
|
|
|
typ = ty})
|
2018-04-20 11:19:50 +00:00
|
|
|
end
|
|
|
|
|
2018-08-20 18:29:04 +00:00
|
|
|
fun get_attribute_info (*long*)cid attr thy =
|
|
|
|
get_attribute_info_local cid attr (Proof_Context.init_global thy)
|
2018-04-20 11:19:50 +00:00
|
|
|
|
2018-08-24 13:49:13 +00:00
|
|
|
fun get_attribute_defaults (* long*)cid thy =
|
|
|
|
let val attrS = flat(map snd (get_attributes cid thy))
|
|
|
|
fun trans (_,_,NONE) = NONE
|
|
|
|
|trans (na,ty,SOME def) =SOME(na,ty, def)
|
|
|
|
in map_filter trans attrS end
|
2018-04-27 08:34:24 +00:00
|
|
|
|
|
|
|
fun get_value_global oid thy = case get_object_global oid thy of
|
|
|
|
SOME{value=term,...} => SOME term
|
|
|
|
| NONE => NONE
|
|
|
|
|
|
|
|
fun get_value_local oid ctxt = case get_object_local oid ctxt of
|
|
|
|
SOME{value=term,...} => SOME term
|
|
|
|
| NONE => NONE
|
|
|
|
|
2018-06-07 11:56:15 +00:00
|
|
|
(* missing : setting terms to ground (no type-schema vars, no schema vars. )*)
|
2018-04-27 08:34:24 +00:00
|
|
|
fun update_value_global oid upd thy =
|
|
|
|
case get_object_global oid thy of
|
|
|
|
SOME{pos,thy_name,value,id,cid} =>
|
|
|
|
let val tab' = Symtab.update(oid,SOME{pos=pos,thy_name=thy_name,
|
|
|
|
value=upd value,id=id, cid=cid})
|
2018-10-08 08:30:53 +00:00
|
|
|
in map_data_global (upd_docobj_tab(fn{tab,maxano}=>{tab=tab' tab,maxano=maxano})) thy end
|
2018-04-27 08:34:24 +00:00
|
|
|
| NONE => error("undefined doc object: "^oid)
|
|
|
|
|
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
val ISA_prefix = "Isa_DOF.ISA_" (* ISA's must be declared in Isa_DOF.thy !!! *)
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun get_isa_global isa thy = case Symtab.lookup (#ISA_transformer_tab(get_data_global thy)) (ISA_prefix^isa) of
|
2018-09-03 19:31:06 +00:00
|
|
|
NONE => error("undefined inner syntax antiquotation: "^isa)
|
|
|
|
|SOME(bbb) => bbb
|
|
|
|
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun get_isa_local isa ctxt = case Symtab.lookup (#ISA_transformer_tab(get_data ctxt)) (ISA_prefix^isa) of
|
2018-09-03 19:31:06 +00:00
|
|
|
NONE => error("undefined inner syntax antiquotation: "^isa)
|
|
|
|
|SOME(bbb) => bbb
|
|
|
|
|
|
|
|
fun update_isa_local (isa, trans) ctxt =
|
2018-10-08 13:13:47 +00:00
|
|
|
map_data (upd_ISA_transformers(Symtab.update(ISA_prefix^isa,trans))) ctxt
|
2018-09-03 19:31:06 +00:00
|
|
|
|
|
|
|
fun update_isa_global (isa, trans) thy =
|
2018-10-08 13:13:47 +00:00
|
|
|
map_data_global (upd_ISA_transformers(Symtab.update(ISA_prefix^isa,trans))) thy
|
2018-09-03 19:31:06 +00:00
|
|
|
|
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
fun transduce_term_global (term,pos) thy =
|
2018-09-17 14:48:05 +00:00
|
|
|
(* pre: term should be fully typed in order to allow type-relqted term-transformations *)
|
2018-10-05 07:45:24 +00:00
|
|
|
let val tab = #ISA_transformer_tab(get_data_global thy)
|
2018-09-11 06:50:51 +00:00
|
|
|
fun T(Const(s,ty) $ t) = if String.isPrefix ISA_prefix s
|
2018-09-03 19:31:06 +00:00
|
|
|
then case Symtab.lookup tab s of
|
|
|
|
NONE => error("undefined inner syntax antiquotation: "^s)
|
2018-09-17 14:48:05 +00:00
|
|
|
| SOME(trans) => case trans thy (t,ty,pos) of
|
2018-09-03 19:31:06 +00:00
|
|
|
NONE => Const(s,ty) $ t
|
|
|
|
(* checking isa, may raise error though. *)
|
|
|
|
| SOME t => Const(s,ty) $ t
|
|
|
|
(* transforming isa *)
|
|
|
|
else (Const(s,ty) $ (T t))
|
|
|
|
|T(t1 $ t2) = T(t1) $ T(t2)
|
|
|
|
|T(Abs(s,ty,t)) = Abs(s,ty,T t)
|
|
|
|
|T t = t
|
|
|
|
in T term end
|
|
|
|
|
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun writeln_classrefs ctxt = let val tab = #docclass_tab(get_data ctxt)
|
2018-04-04 08:45:56 +00:00
|
|
|
in writeln (String.concatWith "," (Symtab.keys tab)) end
|
2018-02-28 13:06:52 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-10-05 07:45:24 +00:00
|
|
|
fun writeln_docrefs ctxt = let val {tab,...} = #docobj_tab(get_data ctxt)
|
2018-04-04 08:45:56 +00:00
|
|
|
in writeln (String.concatWith "," (Symtab.keys tab)) end
|
2018-08-19 08:17:17 +00:00
|
|
|
|
|
|
|
fun print_doc_items b ctxt =
|
2018-10-05 07:45:24 +00:00
|
|
|
let val {docobj_tab={tab = x, ...},...}= get_data ctxt;
|
2018-08-19 08:17:17 +00:00
|
|
|
val _ = writeln "=====================================";
|
|
|
|
fun print_item (n, SOME({cid,id,pos,thy_name,value})) =
|
2018-08-24 15:14:39 +00:00
|
|
|
(writeln ("docitem: "^n);
|
|
|
|
writeln (" type: "^cid);
|
|
|
|
writeln (" origine: "^thy_name);
|
2018-08-24 19:57:16 +00:00
|
|
|
writeln (" value: "^(Syntax.string_of_term ctxt value))
|
2018-08-24 15:14:39 +00:00
|
|
|
)
|
|
|
|
| print_item (n, NONE) =
|
|
|
|
(writeln ("forward reference for docitem: "^n));
|
2018-08-19 08:17:17 +00:00
|
|
|
in map print_item (Symtab.dest x);
|
|
|
|
writeln "=====================================\n\n\n" end;
|
|
|
|
|
|
|
|
fun print_doc_classes b ctxt =
|
2018-10-05 07:45:24 +00:00
|
|
|
let val {docobj_tab={tab = x, ...},docclass_tab, ...} = get_data ctxt;
|
2018-08-19 08:17:17 +00:00
|
|
|
val _ = writeln "=====================================";
|
|
|
|
fun print_attr (n, ty, NONE) = (Binding.print n)
|
|
|
|
| print_attr (n, ty, SOME t) = (Binding.print n^"("^Syntax.string_of_term ctxt t^")")
|
2018-10-08 08:30:53 +00:00
|
|
|
fun print_class (n, {attribute_decl, id, inherits_from, name, params, thy_name, rex}) =
|
2018-08-19 08:17:17 +00:00
|
|
|
(case inherits_from of
|
|
|
|
NONE => writeln ("docclass: "^n)
|
|
|
|
| SOME(_,nn) => writeln ("docclass: "^n^" = "^nn^" + ");
|
|
|
|
writeln (" name: "^(Binding.print name));
|
|
|
|
writeln (" origin: "^thy_name);
|
2018-08-22 20:06:15 +00:00
|
|
|
writeln (" attrs: "^commas (map print_attr attribute_decl))
|
2018-08-19 08:17:17 +00:00
|
|
|
);
|
2018-10-05 07:45:24 +00:00
|
|
|
in map print_class (Symtab.dest docclass_tab);
|
2018-08-19 08:17:17 +00:00
|
|
|
writeln "=====================================\n\n\n"
|
|
|
|
end;
|
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword print_doc_classes}
|
|
|
|
"print document classes"
|
|
|
|
(Parse.opt_bang >> (fn b =>
|
|
|
|
Toplevel.keep (print_doc_classes b o Toplevel.context_of)));
|
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword print_doc_items}
|
|
|
|
"print document items"
|
|
|
|
(Parse.opt_bang >> (fn b =>
|
|
|
|
Toplevel.keep (print_doc_items b o Toplevel.context_of)));
|
|
|
|
|
2018-10-02 16:29:18 +00:00
|
|
|
fun toStringLaTeXNewKeyCommand env long_name =
|
|
|
|
"\\expandafter\\newkeycommand\\csname"^" "^"isaDof."^env^"."^long_name^"\\endcsname%\n"
|
|
|
|
|
|
|
|
fun toStringMetaArgs true attr_long_names =
|
|
|
|
enclose "[" "][1]" (commas ("label=,type=%\n" :: attr_long_names))
|
|
|
|
|toStringMetaArgs false attr_long_names =
|
|
|
|
enclose "[" "][1]" (commas attr_long_names)
|
|
|
|
|
|
|
|
fun toStringDocItemBody env =
|
|
|
|
enclose "{%\n\\isamarkupfalse\\isamarkup"
|
|
|
|
"{#1}\\label{\\commandkey{label}}\\isamarkuptrue%\n}\n"
|
|
|
|
env
|
|
|
|
|
|
|
|
fun toStringDocItemCommand env long_name attr_long_names =
|
|
|
|
toStringLaTeXNewKeyCommand env long_name ^
|
|
|
|
toStringMetaArgs true attr_long_names ^
|
|
|
|
toStringDocItemBody env ^"\n"
|
|
|
|
|
|
|
|
fun toStringDocItemLabel long_name attr_long_names =
|
|
|
|
toStringLaTeXNewKeyCommand "Label" long_name ^
|
|
|
|
toStringMetaArgs false attr_long_names ^
|
|
|
|
"{%\n\\autoref{#1}\n}\n"
|
|
|
|
|
|
|
|
fun toStringDocItemRef long_name label attr_long_namesNvalues =
|
|
|
|
"\\isaDof.Label." ^ long_name ^
|
|
|
|
enclose "[" "]" (commas attr_long_namesNvalues) ^
|
|
|
|
enclose "{" "}" label
|
|
|
|
|
2018-10-08 21:28:44 +00:00
|
|
|
fun write_file thy filename content =
|
|
|
|
let
|
|
|
|
val filename = Path.explode filename
|
|
|
|
val master_dir = Resources.master_directory thy
|
|
|
|
val abs_filename = if (Path.is_absolute filename)
|
|
|
|
then filename
|
|
|
|
else Path.append master_dir filename
|
|
|
|
in
|
|
|
|
File.write (abs_filename) content
|
|
|
|
handle (IO.Io{name=name,...})
|
|
|
|
=> warning ("Could not write \""^(name)^"\".")
|
|
|
|
end
|
2018-10-02 16:29:18 +00:00
|
|
|
|
|
|
|
fun write_ontology_latex_sty_template thy =
|
2018-10-08 21:28:44 +00:00
|
|
|
let
|
|
|
|
(*
|
|
|
|
val raw_name = Context.theory_long_name thy
|
|
|
|
|
2018-10-02 16:29:18 +00:00
|
|
|
val curr_thy_name = if String.isPrefix "Draft." raw_name
|
|
|
|
then String.substring(raw_name, 6, (String.size raw_name)-6)
|
|
|
|
else error "Not in ontology definition context"
|
2018-10-08 21:28:44 +00:00
|
|
|
*)
|
|
|
|
val curr_thy_name = Context.theory_name thy
|
2018-10-05 07:45:24 +00:00
|
|
|
val {docobj_tab={tab = x, ...},docclass_tab,...}= get_data_global thy;
|
2018-10-02 16:29:18 +00:00
|
|
|
fun write_attr (n, ty, _) = YXML.content_of(Binding.print n)^ "=\n"
|
|
|
|
|
2018-10-08 08:30:53 +00:00
|
|
|
fun write_class (n, {attribute_decl, id, inherits_from, name, params, thy_name,rex}) =
|
2018-10-02 16:29:18 +00:00
|
|
|
if curr_thy_name = thy_name then
|
|
|
|
toStringDocItemCommand "section" n (map write_attr attribute_decl) ^
|
|
|
|
toStringDocItemCommand "text" n (map write_attr attribute_decl) ^
|
|
|
|
toStringDocItemLabel n (map write_attr attribute_decl)
|
|
|
|
(* or parameterising with "env" ? ? ?*)
|
|
|
|
else ""
|
2018-10-05 07:45:24 +00:00
|
|
|
val content = String.concat(map write_class (Symtab.dest docclass_tab))
|
2018-10-04 14:58:09 +00:00
|
|
|
(* val _ = writeln content -- for interactive testing only, breaks LaTeX compilation *)
|
2018-10-08 21:28:44 +00:00
|
|
|
in write_file thy ("Isa-DOF."^curr_thy_name^".template.sty") content
|
2018-10-02 16:29:18 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
val _ =
|
2018-10-04 13:58:20 +00:00
|
|
|
Outer_Syntax.command @{command_keyword gen_sty_template}
|
2018-10-02 16:29:18 +00:00
|
|
|
"generate a template LaTeX style file for this ontology"
|
|
|
|
(Parse.opt_bang >> (fn b =>
|
|
|
|
Toplevel.keep (write_ontology_latex_sty_template o Toplevel.theory_of)));
|
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
end (* struct *)
|
2018-09-11 06:50:51 +00:00
|
|
|
\<close>
|
|
|
|
|
|
|
|
section\<open> Syntax for Inner Syntax Antiquotations (ISA) \<close>
|
|
|
|
|
|
|
|
subsection\<open> Syntax \<close>
|
|
|
|
|
|
|
|
typedecl "doc_class"
|
|
|
|
typedecl "typ"
|
|
|
|
typedecl "term"
|
|
|
|
typedecl "thm"
|
|
|
|
typedecl "file"
|
|
|
|
typedecl "thy"
|
|
|
|
|
|
|
|
-- \<open> and others in the future : file, http, thy, ... \<close>
|
|
|
|
|
|
|
|
consts ISA_typ :: "string \<Rightarrow> typ" ("@{typ _}")
|
|
|
|
consts ISA_term :: "string \<Rightarrow> term" ("@{term _}")
|
|
|
|
consts ISA_thm :: "string \<Rightarrow> thm" ("@{thm _}")
|
|
|
|
consts ISA_file :: "string \<Rightarrow> file" ("@{file _}")
|
|
|
|
consts ISA_thy :: "string \<Rightarrow> thy" ("@{thy _}")
|
|
|
|
consts ISA_docitem :: "string \<Rightarrow> 'a" ("@{docitem _}")
|
|
|
|
consts ISA_docitem_attr :: "string \<Rightarrow> string \<Rightarrow> 'a" ("@{docitemattr (_) :: (_)}")
|
|
|
|
|
|
|
|
(* tests *)
|
|
|
|
term "@{typ ''int => int''}"
|
|
|
|
term "@{term ''Bound 0''}"
|
|
|
|
term "@{thm ''refl''}"
|
|
|
|
term "@{docitem ''<doc_ref>''}"
|
2018-09-11 11:51:25 +00:00
|
|
|
ML\<open> @{term "@{docitem ''<doc_ref>''}"}\<close>
|
2018-09-11 06:50:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
subsection\<open> Semantics \<close>
|
|
|
|
|
|
|
|
ML\<open>
|
|
|
|
structure ISA_core =
|
|
|
|
struct
|
|
|
|
|
|
|
|
fun err msg pos = error (msg ^ Position.here pos);
|
|
|
|
|
|
|
|
fun check_path check_file ctxt dir (name, pos) =
|
|
|
|
let
|
|
|
|
val _ = Context_Position.report ctxt pos Markup.language_path;
|
|
|
|
|
|
|
|
val path = Path.append dir (Path.explode name) handle ERROR msg => err msg pos;
|
|
|
|
val _ = Path.expand path handle ERROR msg => err msg pos;
|
|
|
|
val _ = Context_Position.report ctxt pos (Markup.path (Path.smart_implode path));
|
|
|
|
val _ =
|
|
|
|
(case check_file of
|
|
|
|
NONE => path
|
|
|
|
| SOME check => (check path handle ERROR msg => err msg pos));
|
|
|
|
in path end;
|
|
|
|
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun ML_isa_antiq check_file thy (name, _, pos) =
|
2018-09-11 06:50:51 +00:00
|
|
|
let val path = check_path check_file (Proof_Context.init_global thy) Path.current (name, pos);
|
|
|
|
in "Path.explode " ^ ML_Syntax.print_string (Path.implode path) end;
|
|
|
|
|
2018-08-16 14:52:08 +00:00
|
|
|
|
2018-09-11 10:08:25 +00:00
|
|
|
fun ML_isa_check_generic check thy (term, pos) =
|
2018-09-11 06:50:51 +00:00
|
|
|
let val name = (HOLogic.dest_string term
|
|
|
|
handle TERM(_,[t]) => error ("wrong term format: must be string constant: "
|
2018-09-11 10:08:25 +00:00
|
|
|
^ Syntax.string_of_term_global thy t ))
|
|
|
|
val _ = check thy (name,pos)
|
|
|
|
in SOME term end;
|
|
|
|
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun ML_isa_check_typ thy (term, _, pos) =
|
2018-09-11 10:08:25 +00:00
|
|
|
let fun check thy (name, _) = Syntax.parse_typ (Proof_Context.init_global thy) name
|
|
|
|
in ML_isa_check_generic check thy (term, pos) end
|
|
|
|
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun ML_isa_check_term thy (term, _, pos) =
|
2018-09-11 10:08:25 +00:00
|
|
|
let fun check thy (name, _) = Syntax.parse_term (Proof_Context.init_global thy) name
|
|
|
|
in ML_isa_check_generic check thy (term, pos) end
|
|
|
|
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun ML_isa_check_thm thy (term, _, pos) =
|
2018-09-11 11:51:25 +00:00
|
|
|
(* this works for long-names only *)
|
|
|
|
let fun check thy (name, _) = case Proof_Context.lookup_fact (Proof_Context.init_global thy) name of
|
|
|
|
NONE => err ("No Theorem:" ^name) pos
|
|
|
|
| SOME X => X
|
|
|
|
in ML_isa_check_generic check thy (term, pos) end
|
|
|
|
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun ML_isa_check_file thy (term, _, pos) =
|
2018-09-11 10:08:25 +00:00
|
|
|
let fun check thy (name, pos) = check_path (SOME File.check_file)
|
|
|
|
(Proof_Context.init_global thy)
|
|
|
|
(Path.current)
|
|
|
|
(name, pos);
|
|
|
|
in ML_isa_check_generic check thy (term, pos) end;
|
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
|
2018-09-11 09:35:25 +00:00
|
|
|
fun ML_isa_id thy (term,pos) = SOME term
|
|
|
|
|
2018-09-11 12:15:11 +00:00
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun ML_isa_check_docitem thy (term, req_ty, pos) =
|
|
|
|
let fun check thy (name, _) =
|
|
|
|
if DOF_core.is_declared_oid_global name thy
|
|
|
|
then case DOF_core.get_object_global name thy of
|
|
|
|
NONE => warning("oid declared, but not yet defined --- "^
|
|
|
|
" type-check incomplete")
|
|
|
|
| SOME {pos=pos_decl,cid,id,...} =>
|
|
|
|
let val ctxt = (Proof_Context.init_global thy)
|
|
|
|
val req_class = case req_ty of
|
|
|
|
Type("fun",[_,T]) => DOF_core.typ_to_cid T
|
|
|
|
| _ => error("can not infer type for: "^ name)
|
|
|
|
in if cid <> DOF_core.default_cid
|
|
|
|
andalso not(DOF_core.is_subclass ctxt cid req_class)
|
|
|
|
then error("reference ontologically inconsistent")
|
|
|
|
else ()
|
|
|
|
end
|
|
|
|
else err ("faulty reference to docitem: "^name) pos
|
2018-09-11 12:15:11 +00:00
|
|
|
in ML_isa_check_generic check thy (term, pos) end
|
|
|
|
|
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
end; (* struct *)
|
2018-09-11 07:33:17 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
\<close>
|
2018-09-11 10:08:25 +00:00
|
|
|
subsection\<open> Isar - Setup\<close>
|
2018-09-11 12:15:11 +00:00
|
|
|
|
2018-09-11 10:08:25 +00:00
|
|
|
setup\<open>DOF_core.update_isa_global("typ" ,ISA_core.ML_isa_check_typ) \<close>
|
|
|
|
setup\<open>DOF_core.update_isa_global("term" ,ISA_core.ML_isa_check_term) \<close>
|
2018-09-11 11:51:25 +00:00
|
|
|
setup\<open>DOF_core.update_isa_global("thm" ,ISA_core.ML_isa_check_thm) \<close>
|
|
|
|
setup\<open>DOF_core.update_isa_global("file" ,ISA_core.ML_isa_check_file) \<close>
|
2018-09-11 12:15:11 +00:00
|
|
|
setup\<open>DOF_core.update_isa_global("docitem",ISA_core.ML_isa_check_docitem)\<close>
|
2018-09-11 06:50:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
section\<open> Syntax for Annotated Documentation Commands (the '' View'' Part I) \<close>
|
|
|
|
ML\<open>
|
2018-08-24 13:49:13 +00:00
|
|
|
structure ODL_Command_Parser =
|
2018-02-07 18:44:27 +00:00
|
|
|
struct
|
|
|
|
|
2018-08-16 14:52:08 +00:00
|
|
|
type meta_args_t = (((string * Position.T) *
|
|
|
|
(string * Position.T) option)
|
|
|
|
* ((string * Position.T) * string) list)
|
|
|
|
|
2018-08-27 12:39:34 +00:00
|
|
|
fun meta_args_2_string thy ((((lab, _), cid_opt), attr_list) : meta_args_t) =
|
2018-08-18 12:44:39 +00:00
|
|
|
(* for the moment naive, i.e. without textual normalization of
|
|
|
|
attribute names and adapted term printing *)
|
|
|
|
let val l = "label = "^ (enclose "{" "}" lab)
|
2018-08-24 13:49:13 +00:00
|
|
|
val cid_long = case cid_opt of
|
2018-08-16 14:52:08 +00:00
|
|
|
NONE => DOF_core.default_cid
|
2018-08-24 13:49:13 +00:00
|
|
|
| SOME(cid,_) => DOF_core.name2doc_class_name thy cid
|
|
|
|
val cid_txt = "type = " ^ (enclose "{" "}" cid_long);
|
2018-09-18 14:34:18 +00:00
|
|
|
|
2018-09-18 16:17:02 +00:00
|
|
|
(* TODO: temp. hack *)
|
|
|
|
fun unquote_string s = if String.isPrefix "''" s then
|
|
|
|
String.substring(s,2,(String.size s)-4)
|
|
|
|
else s
|
|
|
|
fun markup2string s = unquote_string (String.concat (List.filter (fn c => c <> Symbol.DEL)
|
|
|
|
(Symbol.explode (YXML.content_of s))))
|
2018-09-18 14:34:18 +00:00
|
|
|
|
2018-09-11 09:35:25 +00:00
|
|
|
fun toLong n = #long_name(the(DOF_core.get_attribute_info cid_long (markup2string n) thy))
|
|
|
|
fun str ((lhs,_),rhs) = (toLong lhs)^" = "^(enclose "{" "}" (markup2string rhs))
|
2018-08-17 11:19:12 +00:00
|
|
|
(* no normalization on lhs (could be long-name)
|
|
|
|
no paraphrasing on rhs (could be fully paranthesized
|
|
|
|
pretty-printed formula in LaTeX notation ... *)
|
2018-09-18 13:26:19 +00:00
|
|
|
in
|
|
|
|
enclose "[" "]" (String.concat [ cid_txt, ", args={", (commas ([cid_txt,l] @ (map str attr_list ))), "}"])
|
|
|
|
end
|
2018-08-16 14:52:08 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
val semi = Scan.option (Parse.$$$ ";");
|
2018-10-04 13:58:20 +00:00
|
|
|
val is_improper = not o (Token.is_proper orf Token.is_begin_ignore orf Token.is_end_ignore);
|
2018-10-04 15:25:45 +00:00
|
|
|
val improper = Scan.many is_improper; (* parses white-space and comments *)
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
val attribute =
|
2018-10-04 14:58:09 +00:00
|
|
|
Parse.position Parse.const
|
|
|
|
--| improper
|
2018-10-04 15:25:45 +00:00
|
|
|
-- Scan.optional (Parse.$$$ "=" --| improper |-- Parse.!!! Parse.term --| improper) "True"
|
2018-10-04 14:58:09 +00:00
|
|
|
: ((string * Position.T) * string) parser;
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-04-27 15:12:42 +00:00
|
|
|
val attribute_upd : (((string * Position.T) * string) * string) parser =
|
2018-04-16 15:00:31 +00:00
|
|
|
Parse.position Parse.const
|
2018-10-04 15:25:45 +00:00
|
|
|
--| improper
|
|
|
|
-- ((@{keyword "+="} --| improper) || (@{keyword ":="} --| improper))
|
|
|
|
-- Parse.!!! Parse.term
|
|
|
|
--| improper
|
|
|
|
: (((string * Position.T) * string) * string) parser;
|
2018-04-29 09:35:24 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
val reference =
|
2018-04-04 08:45:56 +00:00
|
|
|
Parse.position Parse.name
|
2018-10-04 15:25:45 +00:00
|
|
|
--| improper
|
2018-10-04 15:45:39 +00:00
|
|
|
-- Scan.option (Parse.$$$ "::"
|
|
|
|
-- improper
|
|
|
|
|-- (Parse.!!! (Parse.position Parse.name))
|
|
|
|
)
|
|
|
|
--| improper;
|
2018-02-28 10:31:42 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-04-05 10:44:52 +00:00
|
|
|
val attributes =
|
2018-10-04 14:58:09 +00:00
|
|
|
((Parse.$$$ "["
|
2018-10-04 13:58:20 +00:00
|
|
|
-- improper
|
2018-04-05 10:44:52 +00:00
|
|
|
|-- (reference --
|
2018-10-04 14:58:09 +00:00
|
|
|
(Scan.optional(Parse.$$$ "," -- improper |-- (Parse.enum "," (improper |-- attribute)))) []))
|
|
|
|
--| Parse.$$$ "]"
|
|
|
|
--| improper) : meta_args_t parser
|
2018-04-05 10:44:52 +00:00
|
|
|
|
|
|
|
val attributes_upd =
|
2018-10-04 15:45:39 +00:00
|
|
|
((Parse.$$$ "["
|
2018-10-04 13:58:20 +00:00
|
|
|
-- improper
|
2018-04-05 10:44:52 +00:00
|
|
|
|-- (reference --
|
2018-10-04 14:58:09 +00:00
|
|
|
(Scan.optional(Parse.$$$ "," -- improper |-- (Parse.enum "," (improper |-- attribute_upd)))) []))
|
2018-10-04 15:45:39 +00:00
|
|
|
--| Parse.$$$ "]")
|
|
|
|
--| improper
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-06-14 13:35:14 +00:00
|
|
|
|
2018-04-27 08:34:24 +00:00
|
|
|
|
2018-08-24 14:58:06 +00:00
|
|
|
fun cid_2_cidType cid_long thy =
|
2018-08-22 20:06:15 +00:00
|
|
|
if cid_long = DOF_core.default_cid then @{typ "unit"}
|
2018-10-05 07:45:24 +00:00
|
|
|
else let val t = #docclass_tab(DOF_core.get_data_global thy)
|
2018-08-24 14:58:06 +00:00
|
|
|
fun ty_name cid = cid^"."^ Long_Name.base_name cid^"_ext"
|
|
|
|
fun fathers cid_long = case Symtab.lookup t cid_long of
|
|
|
|
NONE => error("undefined doc class id :"^cid_long)
|
|
|
|
| SOME ({inherits_from=NONE, ...}) => [cid_long]
|
|
|
|
| SOME ({inherits_from=SOME(_,father), ...}) =>
|
|
|
|
cid_long :: (fathers father)
|
|
|
|
in fold (fn x => fn y => Type(ty_name x,[y])) (fathers cid_long) @{typ "unit"}
|
|
|
|
end
|
2018-08-22 20:06:15 +00:00
|
|
|
|
2018-08-24 14:58:06 +00:00
|
|
|
fun base_default_term thy cid_long = Const(@{const_name "undefined"},cid_2_cidType thy cid_long)
|
2018-04-27 08:34:24 +00:00
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
fun check_classref is_monitor (SOME(cid,pos')) thy =
|
2018-04-27 08:34:24 +00:00
|
|
|
let val _ = if not (DOF_core.is_defined_cid_global cid thy)
|
|
|
|
then error("document class undefined") else ()
|
|
|
|
val cid_long = DOF_core.name2doc_class_name thy cid
|
2018-10-08 13:13:47 +00:00
|
|
|
val {id, name=bind_target,rex,...} = the(DOF_core.get_doc_class_global cid_long thy)
|
|
|
|
val _ = if is_monitor andalso (null rex orelse cid_long= DOF_core.default_cid )
|
|
|
|
then error("should be monitor class!")
|
|
|
|
else ()
|
2018-04-27 08:34:24 +00:00
|
|
|
val markup = docclass_markup false cid id (Binding.pos_of bind_target);
|
|
|
|
val ctxt = Context.Theory thy
|
|
|
|
val _ = Context_Position.report_generic ctxt pos' markup;
|
|
|
|
in cid_long
|
|
|
|
end
|
2018-10-08 13:13:47 +00:00
|
|
|
| check_classref _ NONE _ = DOF_core.default_cid
|
2018-04-27 08:34:24 +00:00
|
|
|
|
|
|
|
|
2018-04-27 15:12:42 +00:00
|
|
|
fun generalize_typ n = Term.map_type_tfree (fn (str,sort)=> Term.TVar((str,n),sort));
|
|
|
|
fun infer_type thy term = hd (Type_Infer_Context.infer_types (Proof_Context.init_global thy) [term])
|
2018-08-24 13:49:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
fun calc_update_term thy cid_long (S:(string * Position.T * string * term)list) term =
|
2018-08-24 14:58:06 +00:00
|
|
|
let val cid_ty = cid_2_cidType cid_long thy
|
2018-08-24 13:49:13 +00:00
|
|
|
val generalize_term = Term.map_types (generalize_typ 0)
|
|
|
|
fun toString t = Syntax.string_of_term (Proof_Context.init_global thy) t
|
|
|
|
fun instantiate_term S t = Term_Subst.map_types_same (Term_Subst.instantiateT S) (t)
|
2018-09-11 06:50:51 +00:00
|
|
|
fun read_assn (lhs, pos:Position.T, opr, rhs) term =
|
2018-08-27 12:39:34 +00:00
|
|
|
let val info_opt = DOF_core.get_attribute_info cid_long
|
2018-08-24 13:49:13 +00:00
|
|
|
(Long_Name.base_name lhs) thy
|
|
|
|
val (ln,lnt,lnu,lnut) = case info_opt of
|
|
|
|
NONE => error ("unknown attribute >"
|
|
|
|
^((Long_Name.base_name lhs))
|
|
|
|
^"< in class: "^cid_long)
|
|
|
|
| SOME{long_name, typ, ...} => (long_name, typ,
|
|
|
|
long_name ^"_update",
|
|
|
|
(typ --> typ)
|
|
|
|
--> cid_ty --> cid_ty)
|
|
|
|
val tyenv = Sign.typ_match thy ((generalize_typ 0)(type_of rhs), lnt) (Vartab.empty)
|
|
|
|
handle Type.TYPE_MATCH => error ("type of attribute: " ^ ln
|
|
|
|
^ " does not fit to term: "
|
|
|
|
^ toString rhs);
|
|
|
|
val tyenv' = (map (fn (s,(t,u)) => ((s,t),u)) (Vartab.dest tyenv))
|
|
|
|
val _ = if Long_Name.base_name lhs = lhs orelse ln = lhs then ()
|
|
|
|
else error("illegal notation for attribute of "^cid_long)
|
|
|
|
fun join (ttt as @{typ "int"})
|
|
|
|
= Const (@{const_name "plus"}, ttt --> ttt --> ttt)
|
|
|
|
|join (ttt as @{typ "string"})
|
|
|
|
= Const (@{const_name "append"}, ttt --> ttt --> ttt)
|
|
|
|
|join (ttt as Type(@{type_name "set"},_))
|
|
|
|
= Const (@{const_name "sup"}, ttt --> ttt --> ttt)
|
|
|
|
|join (ttt as Type(@{type_name "list"},_))
|
|
|
|
= Const (@{const_name "append"}, ttt --> ttt --> ttt)
|
|
|
|
|join _ = error("implicit fusion operation not defined for attribute: "^ lhs)
|
|
|
|
(* could be extended to bool, map, multisets, ... *)
|
2018-09-17 14:48:05 +00:00
|
|
|
val rhs' = instantiate_term tyenv' (generalize_term rhs)
|
|
|
|
val rhs'' = DOF_core.transduce_term_global (rhs',pos) thy
|
2018-08-24 13:49:13 +00:00
|
|
|
in case opr of
|
2018-09-17 14:48:05 +00:00
|
|
|
"=" => Const(lnu,lnut) $ Abs ("uu_", lnt, rhs'') $ term
|
|
|
|
| ":=" => Const(lnu,lnut) $ Abs ("uu_", lnt, rhs'') $ term
|
|
|
|
| "+=" => Const(lnu,lnut) $ Abs ("uu_", lnt, join lnt $ (Bound 0) $ rhs'') $ term
|
2018-08-24 13:49:13 +00:00
|
|
|
| _ => error "corrupted syntax - oops - this should not occur"
|
|
|
|
end
|
|
|
|
in Sign.certify_term thy (fold read_assn S term) end
|
|
|
|
|
2018-10-11 11:38:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
fun register_oid_cid_in_open_monitors oid pos cid_long thy =
|
2018-10-09 13:56:17 +00:00
|
|
|
let val {monitor_tab,...} = DOF_core.get_data_global thy
|
|
|
|
fun is_enabled (n, info) =
|
|
|
|
if exists (DOF_core.is_subclass_global thy cid_long)
|
2018-10-11 11:38:32 +00:00
|
|
|
(DOF_core.get_accepted_cids info)
|
2018-10-09 13:56:17 +00:00
|
|
|
then SOME n
|
|
|
|
else NONE
|
|
|
|
val enabled_monitors = List.mapPartial is_enabled (Symtab.dest monitor_tab)
|
2018-10-11 11:38:32 +00:00
|
|
|
fun markup2string x = XML.content_of (YXML.parse_body x)
|
|
|
|
fun conv_attrs (((lhs, pos), opn), rhs) = (markup2string lhs,pos,opn,
|
|
|
|
Syntax.read_term_global thy rhs)
|
2018-10-16 08:44:59 +00:00
|
|
|
val trace_attr = [((("trace", @{here}), "+="), "[("^cid_long^", ''"^oid^"'')]")]
|
2018-10-11 11:38:32 +00:00
|
|
|
val assns' = map conv_attrs trace_attr
|
|
|
|
fun cid_of oid = #cid(the(DOF_core.get_object_global oid thy))
|
|
|
|
fun def_trans oid = #1 o (calc_update_term thy (cid_of oid) assns')
|
|
|
|
val _ = if null enabled_monitors then () else writeln "registrating in monitors ..."
|
|
|
|
val _ = app (fn n => writeln(oid^" : "^cid_long^" ==> "^n)) enabled_monitors;
|
|
|
|
in thy |> fold (fn mon_oid => DOF_core.update_value_global mon_oid (def_trans mon_oid))(enabled_monitors)
|
|
|
|
end
|
2018-08-27 12:39:34 +00:00
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
fun create_and_check_docitem is_monitor oid pos cid_pos doc_attrs thy =
|
2018-08-27 12:39:34 +00:00
|
|
|
let val id = serial ();
|
|
|
|
val _ = Position.report pos (docref_markup true oid id pos);
|
|
|
|
(* creates a markup label for this position and reports it to the PIDE framework;
|
|
|
|
this label is used as jump-target for point-and-click feature. *)
|
2018-10-08 13:13:47 +00:00
|
|
|
val cid_long = check_classref is_monitor cid_pos thy
|
2018-08-27 12:39:34 +00:00
|
|
|
val defaults_init = base_default_term cid_long thy
|
|
|
|
fun conv (na, _(*ty*), term) = (Binding.name_of na, Binding.pos_of na, "=", term);
|
|
|
|
val S = map conv (DOF_core.get_attribute_defaults cid_long thy);
|
|
|
|
val (defaults, _(*ty*), _) = calc_update_term thy cid_long S defaults_init;
|
|
|
|
fun markup2string x = XML.content_of (YXML.parse_body x)
|
|
|
|
fun conv_attrs ((lhs, pos), rhs) = (markup2string lhs,pos,"=", Syntax.read_term_global thy rhs)
|
|
|
|
val assns' = map conv_attrs doc_attrs
|
|
|
|
val (value_term, _(*ty*), _) = calc_update_term thy cid_long assns' defaults
|
|
|
|
in thy |> DOF_core.define_object_global (oid, {pos = pos,
|
|
|
|
thy_name = Context.theory_name thy,
|
|
|
|
value = value_term,
|
|
|
|
id = id,
|
|
|
|
cid = cid_long})
|
2018-10-11 11:38:32 +00:00
|
|
|
|> register_oid_cid_in_open_monitors oid pos cid_long
|
2018-08-27 12:39:34 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
fun update_instance_command (((oid:string,pos),cid_pos),
|
|
|
|
doc_attrs: (((string*Position.T)*string)*string)list) thy
|
|
|
|
: theory =
|
|
|
|
let val cid = case DOF_core.get_object_global oid thy of
|
|
|
|
SOME{pos=pos_decl,cid,id,...} =>
|
|
|
|
let val markup = docref_markup false oid id pos_decl;
|
|
|
|
val ctxt = Proof_Context.init_global thy;
|
|
|
|
val _ = Context_Position.report ctxt pos markup;
|
|
|
|
in cid end
|
|
|
|
| NONE => error("undefined doc_class.")
|
|
|
|
val cid_long = check_classref false cid_pos thy
|
|
|
|
val _ = if cid_long = DOF_core.default_cid orelse cid = cid_long
|
|
|
|
then ()
|
|
|
|
else error("incompatible classes:"^cid^":"^cid_long)
|
|
|
|
fun markup2string x = XML.content_of (YXML.parse_body x)
|
|
|
|
|
|
|
|
fun conv_attrs (((lhs, pos), opn), rhs) = (markup2string lhs,pos,opn,
|
|
|
|
Syntax.read_term_global thy rhs)
|
|
|
|
val assns' = map conv_attrs doc_attrs
|
|
|
|
val def_trans = #1 o (calc_update_term thy cid_long assns')
|
|
|
|
in
|
|
|
|
thy |> DOF_core.update_value_global oid (def_trans)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2018-10-11 11:38:32 +00:00
|
|
|
fun enriched_document_command markdown (((((oid,pos),cid_pos), doc_attrs) : meta_args_t,
|
|
|
|
xstring_opt:(xstring * Position.T) option),
|
|
|
|
toks:Input.source)
|
|
|
|
: Toplevel.transition -> Toplevel.transition =
|
|
|
|
let
|
|
|
|
fun check_text thy = (Thy_Output.output_text(Toplevel.theory_toplevel thy) markdown toks; thy)
|
|
|
|
(* as side-effect, generates markup *)
|
|
|
|
in
|
|
|
|
Toplevel.theory(create_and_check_docitem false oid pos cid_pos doc_attrs #> check_text)
|
|
|
|
(* Thanks Frederic Tuong! ! ! *)
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-08-27 12:39:34 +00:00
|
|
|
fun open_monitor_command ((((oid,pos),cid_pos), doc_attrs) : meta_args_t) =
|
2018-10-16 08:44:59 +00:00
|
|
|
let fun o_m_c oid pos cid_pos doc_attrs thy = create_and_check_docitem true oid pos
|
|
|
|
cid_pos doc_attrs thy
|
2018-10-08 13:13:47 +00:00
|
|
|
val add_consts = fold_aterms (fn Const(c as (_,@{typ "doc_class rexp"})) => insert (op =) c
|
|
|
|
| _ => I);
|
|
|
|
fun compute_enabled_set cid thy =
|
|
|
|
case DOF_core.get_doc_class_global cid thy of
|
|
|
|
SOME X => map fst (fold add_consts (#rex X) [])
|
|
|
|
| NONE => error("Internal error: class id undefined. ");
|
|
|
|
|
|
|
|
fun create_monitor_entry thy =
|
|
|
|
let val {cid, ...} = the(DOF_core.get_object_global oid thy)
|
|
|
|
val S = compute_enabled_set cid thy
|
2018-10-11 11:38:32 +00:00
|
|
|
val info = {accepted_cids = S,
|
2018-10-08 13:13:47 +00:00
|
|
|
regexp_stack = []}
|
|
|
|
in DOF_core.map_data_global(DOF_core.upd_monitor_tabs(Symtab.update(oid, info )))(thy)
|
|
|
|
end
|
2018-10-08 08:30:53 +00:00
|
|
|
in
|
2018-10-08 13:13:47 +00:00
|
|
|
Toplevel.theory(o_m_c oid pos cid_pos doc_attrs #> create_monitor_entry )
|
2018-10-08 08:30:53 +00:00
|
|
|
end;
|
2018-08-27 12:39:34 +00:00
|
|
|
|
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
fun close_monitor_command (args as (((oid:string,pos),cid_pos),
|
|
|
|
doc_attrs: (((string*Position.T)*string)*string)list)) thy =
|
|
|
|
let val {monitor_tab,...} = DOF_core.get_data_global thy
|
2018-10-11 11:38:32 +00:00
|
|
|
fun check_if_final {accepted_cids, regexp_stack} = true (* check if final: TODO *)
|
2018-10-08 13:13:47 +00:00
|
|
|
val _ = case Symtab.lookup monitor_tab oid of
|
|
|
|
SOME X => check_if_final X
|
|
|
|
| NONE => error ("Not belonging to a monitor class: "^oid)
|
|
|
|
val delete_monitor_entry = DOF_core.map_data_global (DOF_core.upd_monitor_tabs (Symtab.delete oid))
|
|
|
|
in thy |> update_instance_command args
|
|
|
|
|> delete_monitor_entry
|
|
|
|
end
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-06-11 15:35:12 +00:00
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("title*", @{here}) "section heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("subtitle*", @{here}) "section heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
2018-10-30 01:29:15 +00:00
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("chapter*", @{here}) "section heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("section*", @{here}) "section heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
2018-06-11 15:35:12 +00:00
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("subsection*", @{here}) "subsection heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("subsubsection*", @{here}) "subsubsection heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("paragraph*", @{here}) "paragraph heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
2018-04-28 16:41:34 +00:00
|
|
|
>> enriched_document_command {markdown = false});
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("subparagraph*", @{here}) "subparagraph heading"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
2018-04-28 16:41:34 +00:00
|
|
|
>> enriched_document_command {markdown = false});
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-06-11 15:35:12 +00:00
|
|
|
val _ =
|
2018-08-22 20:06:15 +00:00
|
|
|
Outer_Syntax.command ("figure*", @{here}) "figure"
|
2018-06-11 15:35:12 +00:00
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
|
|
|
val _ =
|
2018-08-22 20:06:15 +00:00
|
|
|
Outer_Syntax.command ("side_by_side_figure*", @{here}) "multiple figures"
|
2018-06-11 15:35:12 +00:00
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source --| semi
|
|
|
|
>> enriched_document_command {markdown = false});
|
|
|
|
|
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command ("text*", @{here}) "formal comment (primary style)"
|
|
|
|
(attributes -- Parse.opt_target -- Parse.document_source
|
2018-06-19 15:37:31 +00:00
|
|
|
>> enriched_document_command {markdown = true});
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
val _ =
|
2018-04-05 10:44:52 +00:00
|
|
|
Outer_Syntax.command @{command_keyword "declare_reference*"}
|
|
|
|
"declare document reference"
|
|
|
|
(attributes >> (fn (((oid,pos),cid),doc_attrs) =>
|
|
|
|
(Toplevel.theory (DOF_core.declare_object_global oid))));
|
2018-09-11 06:50:51 +00:00
|
|
|
|
2018-08-27 12:39:34 +00:00
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword "open_monitor*"}
|
|
|
|
"open a document reference monitor"
|
|
|
|
(attributes >> open_monitor_command);
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-04-04 14:25:33 +00:00
|
|
|
val _ =
|
2018-04-05 10:44:52 +00:00
|
|
|
Outer_Syntax.command @{command_keyword "close_monitor*"}
|
|
|
|
"close a document reference monitor"
|
2018-10-08 13:13:47 +00:00
|
|
|
(attributes_upd >> (fn args => Toplevel.theory(close_monitor_command args)));
|
2018-04-29 09:35:24 +00:00
|
|
|
|
2018-06-27 07:12:50 +00:00
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword "update_instance*"}
|
|
|
|
"update meta-attributes of an instance of a document class"
|
2018-10-08 13:13:47 +00:00
|
|
|
(attributes_upd >> (fn args => Toplevel.theory(update_instance_command args)));
|
2018-06-27 07:12:50 +00:00
|
|
|
|
2018-04-29 09:35:24 +00:00
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword "lemma*"}
|
2018-06-27 07:12:50 +00:00
|
|
|
"lemma"
|
2018-04-29 09:35:24 +00:00
|
|
|
(attributes >> (fn (((oid,pos),cid),doc_attrs) =>
|
|
|
|
(Toplevel.theory (I)))); (* dummy/fake so far *)
|
2018-05-14 13:47:16 +00:00
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword "assert*"}
|
2018-06-27 07:12:50 +00:00
|
|
|
"evaluate and print term"
|
|
|
|
(attributes
|
|
|
|
-- opt_evaluator
|
|
|
|
-- opt_modes
|
|
|
|
-- Parse.term
|
|
|
|
>> (fn ((((((oid,pos),cid),doc_attrs),some_name:string option),modes : string list),t:string) =>
|
|
|
|
(Toplevel.keep (assert_cmd some_name modes t)))); (* dummy/fake so far *)
|
2018-04-29 09:35:24 +00:00
|
|
|
|
2018-08-16 14:52:08 +00:00
|
|
|
(* this sets parser and converter for LaTeX generation of meta-attributes.
|
|
|
|
Currently of *all* commands, no distinction between text* and text command.
|
|
|
|
*)
|
2018-08-17 11:19:12 +00:00
|
|
|
val _ = Thy_Output.set_meta_args_parser
|
|
|
|
(fn thy => (Scan.optional (attributes >> meta_args_2_string thy) ""))
|
2018-04-04 14:25:33 +00:00
|
|
|
|
2018-04-04 12:44:21 +00:00
|
|
|
end (* struct *)
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
\<close>
|
2018-06-27 07:12:50 +00:00
|
|
|
|
|
|
|
ML \<open>
|
|
|
|
local (* dull and dangerous copy from Pure.thy given that these functions are not
|
|
|
|
globally exported. *)
|
|
|
|
|
|
|
|
val long_keyword =
|
|
|
|
Parse_Spec.includes >> K "" ||
|
|
|
|
Parse_Spec.long_statement_keyword;
|
|
|
|
|
|
|
|
val long_statement =
|
|
|
|
Scan.optional (Parse_Spec.opt_thm_name ":" --| Scan.ahead long_keyword) Binding.empty_atts --
|
|
|
|
Scan.optional Parse_Spec.includes [] -- Parse_Spec.long_statement
|
|
|
|
>> (fn ((binding, includes), (elems, concl)) => (true, binding, includes, elems, concl));
|
|
|
|
|
|
|
|
val short_statement =
|
|
|
|
Parse_Spec.statement -- Parse_Spec.if_statement -- Parse.for_fixes
|
|
|
|
>> (fn ((shows, assumes), fixes) =>
|
|
|
|
(false, Binding.empty_atts, [], [Element.Fixes fixes, Element.Assumes assumes],
|
|
|
|
Element.Shows shows));
|
|
|
|
|
|
|
|
fun theorem spec schematic descr =
|
|
|
|
Outer_Syntax.local_theory_to_proof' spec ("state " ^ descr)
|
|
|
|
((long_statement || short_statement) >> (fn (long, binding, includes, elems, concl) =>
|
|
|
|
((if schematic then Specification.schematic_theorem_cmd else Specification.theorem_cmd )
|
|
|
|
long Thm.theoremK NONE (K I) binding includes elems concl)));
|
|
|
|
|
|
|
|
|
|
|
|
val _ = theorem @{command_keyword "theorem*"} false "theorem";
|
|
|
|
(* val _ = theorem @{command_keyword "lemma*"} false "lemma";
|
|
|
|
val _ = theorem @{command_keyword corollary} false "corollary";
|
|
|
|
val _ = theorem @{command_keyword proposition} false "proposition";
|
|
|
|
val _ = theorem @{command_keyword schematic_goal} true "schematic goal"; *)
|
|
|
|
|
|
|
|
in end\<close>
|
2018-08-24 20:02:04 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
|
|
|
|
section\<open> Syntax for Ontological Antiquotations (the '' View'' Part II) \<close>
|
2018-04-04 12:44:21 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
ML\<open>
|
2018-04-04 12:44:21 +00:00
|
|
|
structure OntoLinkParser =
|
|
|
|
struct
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-02-28 10:31:42 +00:00
|
|
|
fun check_and_mark ctxt cid_decl (str:{strict_checking: bool}) pos name =
|
2018-02-07 18:44:27 +00:00
|
|
|
let
|
|
|
|
val thy = Proof_Context.theory_of ctxt;
|
|
|
|
in
|
2018-02-09 11:25:15 +00:00
|
|
|
if DOF_core.is_defined_oid_global name thy
|
2018-02-28 10:31:42 +00:00
|
|
|
then let val {pos=pos_decl,id,cid,...} = the(DOF_core.get_object_global name thy)
|
2018-02-07 18:44:27 +00:00
|
|
|
val markup = docref_markup false name id pos_decl;
|
|
|
|
val _ = Context_Position.report ctxt pos markup;
|
2018-02-28 13:06:52 +00:00
|
|
|
(* this sends a report for a ref application to the PIDE interface ... *)
|
|
|
|
val _ = if cid <> DOF_core.default_cid
|
|
|
|
andalso not(DOF_core.is_subclass ctxt cid cid_decl)
|
2018-02-28 10:31:42 +00:00
|
|
|
then error("reference ontologically inconsistent")
|
2018-02-28 13:06:52 +00:00
|
|
|
else ()
|
2018-02-07 18:44:27 +00:00
|
|
|
in name end
|
2018-02-09 11:25:15 +00:00
|
|
|
else if DOF_core.is_declared_oid_global name thy
|
2018-04-04 12:44:21 +00:00
|
|
|
then (if #strict_checking str
|
|
|
|
then warning("declared but undefined document reference:"^name)
|
2018-02-07 18:44:27 +00:00
|
|
|
else (); name)
|
|
|
|
else error("undefined document reference:"^name)
|
|
|
|
end
|
|
|
|
|
2018-04-04 12:44:21 +00:00
|
|
|
|
2018-03-29 09:19:07 +00:00
|
|
|
(* generic syntax for doc_class links. *)
|
|
|
|
|
|
|
|
val defineN = "define"
|
|
|
|
val uncheckedN = "unchecked"
|
|
|
|
|
|
|
|
val doc_ref_modes = Scan.optional (Args.parens (Args.$$$ defineN || Args.$$$ uncheckedN)
|
|
|
|
>> (fn str => if str = defineN
|
|
|
|
then {unchecked = false, define= true}
|
|
|
|
else {unchecked = true, define= false}))
|
2018-04-04 12:44:21 +00:00
|
|
|
{unchecked = false, define= false} (* default *);
|
2018-03-29 09:19:07 +00:00
|
|
|
|
|
|
|
|
2018-09-17 14:48:05 +00:00
|
|
|
fun docitem_ref_antiquotation_generic enclose name cid_decl =
|
|
|
|
Thy_Output.antiquotation name (Scan.lift (doc_ref_modes -- Args.cartouche_input))
|
|
|
|
(fn {context = ctxt, source = src:Token.src, state} =>
|
|
|
|
fn ({unchecked = x, define= y}, source:Input.source) =>
|
|
|
|
(Thy_Output.output_text state {markdown=false} #>
|
|
|
|
check_and_mark ctxt
|
|
|
|
cid_decl
|
|
|
|
({strict_checking = not x})
|
|
|
|
(Input.pos_of source) #>
|
|
|
|
enclose y)
|
|
|
|
source)
|
|
|
|
|
|
|
|
|
2018-04-27 08:34:24 +00:00
|
|
|
fun docitem_ref_antiquotation name cid_decl =
|
2018-04-04 12:44:21 +00:00
|
|
|
let fun open_par x = if x then "\\label{"
|
2018-04-27 08:34:24 +00:00
|
|
|
else "\\autoref{"
|
2018-03-29 09:19:07 +00:00
|
|
|
val close = "}"
|
2018-09-17 14:48:05 +00:00
|
|
|
in docitem_ref_antiquotation_generic (fn y => enclose (open_par y) close) name cid_decl end
|
2018-02-28 13:06:52 +00:00
|
|
|
|
2018-04-27 08:34:24 +00:00
|
|
|
|
|
|
|
fun check_and_mark_term ctxt oid =
|
|
|
|
let val thy = Context.theory_of ctxt;
|
|
|
|
in if DOF_core.is_defined_oid_global oid thy
|
|
|
|
then let val {pos=pos_decl,id,cid,value,...} = the(DOF_core.get_object_global oid thy)
|
|
|
|
val markup = docref_markup false oid id pos_decl;
|
|
|
|
val _ = Context_Position.report_generic ctxt pos_decl markup;
|
|
|
|
(* this sends a report for a ref application to the PIDE interface ... *)
|
|
|
|
val _ = if cid = DOF_core.default_cid
|
|
|
|
then error("anonymous "^ DOF_core.default_cid ^ " class has no value" )
|
|
|
|
else ()
|
|
|
|
in value end
|
|
|
|
else error("undefined document reference:"^oid)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
fun docitem_value_ML_antiquotation binding =
|
|
|
|
ML_Antiquotation.inline binding
|
|
|
|
(fn (ctxt, toks) => (Scan.lift (Args.cartouche_input)
|
|
|
|
>> (fn inp => (ML_Syntax.atomic o ML_Syntax.print_term)
|
|
|
|
(check_and_mark_term ctxt (Input.source_content inp))))
|
|
|
|
(ctxt, toks))
|
|
|
|
|
|
|
|
|
2018-02-28 13:06:52 +00:00
|
|
|
(* Setup for general docrefs of the global DOF_core.default_cid - class ("text")*)
|
2018-04-27 08:34:24 +00:00
|
|
|
val _ = Theory.setup((docitem_ref_antiquotation @{binding docref} DOF_core.default_cid) #>
|
|
|
|
(* deprecated syntax ^^^^^^*)
|
|
|
|
(docitem_ref_antiquotation @{binding docitem_ref} DOF_core.default_cid) #>
|
2018-09-17 14:48:05 +00:00
|
|
|
(* deprecated syntax ^^^^^^^^^^*)
|
|
|
|
(docitem_ref_antiquotation @{binding docitem} DOF_core.default_cid) #>
|
|
|
|
|
2018-04-27 08:34:24 +00:00
|
|
|
docitem_value_ML_antiquotation @{binding docitem_value})
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
end (* struct *)
|
2018-09-11 06:50:51 +00:00
|
|
|
\<close>
|
2018-04-27 15:12:42 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
ML\<open>
|
2018-08-30 10:53:02 +00:00
|
|
|
structure AttributeAccess =
|
2018-08-24 14:58:06 +00:00
|
|
|
struct
|
|
|
|
|
2018-06-07 11:56:15 +00:00
|
|
|
fun calculate_attr_access ctxt proj_term term =
|
|
|
|
(* term assumed to be ground type, (f term) not necessarily *)
|
2018-08-24 14:58:06 +00:00
|
|
|
let val [subterm'] = Type_Infer_Context.infer_types ctxt [proj_term $ term]
|
2018-06-07 11:56:15 +00:00
|
|
|
val ty = type_of (subterm')
|
2018-08-30 10:53:02 +00:00
|
|
|
(* Debug :
|
|
|
|
val _ = writeln ("calculate_attr_access raw term: "
|
|
|
|
^ Syntax.string_of_term ctxt subterm')
|
|
|
|
*)
|
2018-06-07 11:56:15 +00:00
|
|
|
val term' = (Const(@{const_name "HOL.eq"}, ty --> ty --> HOLogic.boolT)
|
|
|
|
$ subterm'
|
|
|
|
$ Free("_XXXXXXX", ty))
|
|
|
|
val thm = simplify ctxt (Thm.assume(Thm.cterm_of ctxt (HOLogic.mk_Trueprop term')));
|
2018-08-24 19:57:16 +00:00
|
|
|
in case HOLogic.dest_Trueprop (Thm.concl_of thm) of
|
|
|
|
Free("_XXXXXXX", @{typ "bool"}) => @{const "True"}
|
|
|
|
| @{const "HOL.Not"} $ Free("_XXXXXXX", @{typ "bool"}) => @{const "False"}
|
|
|
|
| Const(@{const_name "HOL.eq"},_) $ lhs $ Free("_XXXXXXX", _ )=> lhs
|
|
|
|
| Const(@{const_name "HOL.eq"},_) $ Free("_XXXXXXX", _ ) $ rhs => rhs
|
|
|
|
| _ => error ("could not reduce attribute term: " ^
|
|
|
|
Syntax.string_of_term ctxt subterm')
|
|
|
|
end
|
2018-06-07 11:56:15 +00:00
|
|
|
|
2018-08-28 16:21:37 +00:00
|
|
|
fun calculate_attr_access_check ctxt attr oid pos = (* template *)
|
2018-08-18 12:44:39 +00:00
|
|
|
case DOF_core.get_value_local oid (Context.the_proof ctxt) of
|
|
|
|
SOME term => let val ctxt = Context.the_proof ctxt
|
2018-08-28 16:21:37 +00:00
|
|
|
val SOME{cid,pos=pos_decl,id,...} = DOF_core.get_object_local oid ctxt
|
|
|
|
val markup = docref_markup false oid id pos_decl;
|
|
|
|
val _ = Context_Position.report ctxt pos markup;
|
2018-08-20 11:54:53 +00:00
|
|
|
val (* (long_cid, attr_b,ty) = *)
|
2018-10-16 10:23:36 +00:00
|
|
|
{long_name, typ=ty,...} =
|
2018-08-20 11:54:53 +00:00
|
|
|
case DOF_core.get_attribute_info_local cid attr ctxt of
|
2018-06-26 15:40:08 +00:00
|
|
|
SOME f => f
|
|
|
|
| NONE => error ("attribute undefined for ref"^ oid)
|
2018-08-20 11:54:53 +00:00
|
|
|
val proj_term = Const(long_name,dummyT --> ty)
|
2018-10-16 10:23:36 +00:00
|
|
|
in calculate_attr_access ctxt proj_term term end
|
2018-06-26 15:40:08 +00:00
|
|
|
| NONE => error "identifier not a docitem reference"
|
2018-08-24 14:58:06 +00:00
|
|
|
|
2018-06-07 11:56:15 +00:00
|
|
|
val _ = Theory.setup
|
2018-10-17 10:22:25 +00:00
|
|
|
(ML_Antiquotation.inline @{binding docitem_attribute}
|
2018-06-26 15:40:08 +00:00
|
|
|
(fn (ctxt,toks) =>
|
2018-08-28 16:21:37 +00:00
|
|
|
(Scan.lift Args.name
|
|
|
|
--| (Scan.lift @{keyword "::"})
|
|
|
|
-- Scan.lift (Parse.position Args.name)
|
2018-06-26 15:40:08 +00:00
|
|
|
>>
|
2018-10-16 10:23:36 +00:00
|
|
|
(fn(attr:string,(oid:string,pos))
|
|
|
|
=> (ML_Syntax.atomic o ML_Syntax.print_term)
|
|
|
|
(calculate_attr_access_check ctxt attr oid pos))
|
2018-08-18 12:44:39 +00:00
|
|
|
: string context_parser
|
2018-06-26 15:40:08 +00:00
|
|
|
)
|
|
|
|
(ctxt, toks))
|
2018-10-16 10:23:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
fun calculate_trace ctxt oid pos =
|
2018-10-17 10:22:25 +00:00
|
|
|
(* grabs attribute, and converts its HOL-term into (textual) ML representation *)
|
2018-10-16 10:23:36 +00:00
|
|
|
let fun conv (Const(@{const_name "Pair"},_) $ Const(s,_) $ S) = (s, HOLogic.dest_string S)
|
|
|
|
val term = calculate_attr_access_check ctxt "trace" oid pos
|
|
|
|
val string_pair_list = map conv (HOLogic.dest_list term)
|
2018-10-17 10:22:25 +00:00
|
|
|
val print_string_pair = ML_Syntax.print_pair ML_Syntax.print_string ML_Syntax.print_string
|
|
|
|
in ML_Syntax.print_list print_string_pair string_pair_list end
|
2018-10-16 10:23:36 +00:00
|
|
|
|
|
|
|
val _ = Theory.setup
|
|
|
|
(ML_Antiquotation.inline @{binding trace_attribute}
|
|
|
|
(fn (ctxt,toks) =>
|
2018-10-17 10:22:25 +00:00
|
|
|
((Scan.lift (Parse.position Args.name)
|
|
|
|
>>
|
|
|
|
(fn(oid:string,pos) => ML_Syntax.atomic (calculate_trace ctxt oid pos))
|
|
|
|
) : string context_parser
|
2018-10-16 10:23:36 +00:00
|
|
|
)
|
|
|
|
(ctxt, toks))
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
\<close>
|
2018-08-18 12:44:39 +00:00
|
|
|
|
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
section\<open> Syntax for Ontologies (the '' View'' Part III) \<close>
|
|
|
|
ML\<open>
|
2018-04-04 12:44:21 +00:00
|
|
|
structure OntoParser =
|
|
|
|
struct
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
fun read_parent NONE ctxt = (NONE, ctxt)
|
|
|
|
| read_parent (SOME raw_T) ctxt =
|
|
|
|
(case Proof_Context.read_typ_abbrev ctxt raw_T of
|
|
|
|
Type (name, Ts) => (SOME (Ts, name), fold Variable.declare_typ Ts ctxt)
|
|
|
|
| T => error ("Bad parent record specification: " ^ Syntax.string_of_typ ctxt T));
|
|
|
|
|
2018-02-27 11:02:19 +00:00
|
|
|
fun map_option _ NONE = NONE
|
2018-04-16 15:00:31 +00:00
|
|
|
|map_option f (SOME x) = SOME (f x);
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-04-27 15:12:42 +00:00
|
|
|
|
|
|
|
|
2018-02-07 18:44:27 +00:00
|
|
|
fun read_fields raw_fields ctxt =
|
2018-04-05 10:09:58 +00:00
|
|
|
let
|
|
|
|
val Ts = Syntax.read_typs ctxt (map (fn ((_, raw_T, _),_) => raw_T) raw_fields);
|
|
|
|
val terms = map ((map_option (Syntax.read_term ctxt)) o snd) raw_fields
|
2018-04-27 15:12:42 +00:00
|
|
|
val count = Unsynchronized.ref (0 - 1);
|
|
|
|
fun incr () = Unsynchronized.inc count
|
|
|
|
fun test t1 t2 = Sign.typ_instance (Proof_Context.theory_of ctxt)
|
2018-08-24 13:49:13 +00:00
|
|
|
(t1, ODL_Command_Parser.generalize_typ 0 t2)
|
2018-04-17 15:39:16 +00:00
|
|
|
fun check_default (ty,SOME trm) =
|
|
|
|
let val ty' = (type_of trm)
|
|
|
|
in if test ty ty'
|
|
|
|
then ()
|
|
|
|
else error("type mismatch:"^
|
|
|
|
(Syntax.string_of_typ ctxt ty')^":"^
|
|
|
|
(Syntax.string_of_typ ctxt ty))
|
|
|
|
end
|
|
|
|
(* BAD STYLE : better would be catching exn. *)
|
|
|
|
|check_default (_,_) = ()
|
2018-04-05 10:09:58 +00:00
|
|
|
val fields = map2 (fn ((x, _, mx),_) => fn T => (x, T, mx)) raw_fields Ts;
|
2018-04-17 15:39:16 +00:00
|
|
|
val _ = map check_default (Ts ~~ terms) (* checking types conform to defaults *)
|
2018-04-05 10:09:58 +00:00
|
|
|
val ctxt' = fold Variable.declare_typ Ts ctxt;
|
|
|
|
in (fields, terms, ctxt') end;
|
2018-02-07 18:44:27 +00:00
|
|
|
|
2018-04-20 11:19:50 +00:00
|
|
|
|
|
|
|
val tag_attr = (Binding.make("tag_attribute",@{here}), @{typ "int"},Mixfix.NoSyn)
|
2018-10-16 08:44:59 +00:00
|
|
|
val trace_attr = ((Binding.make("trace",@{here}), "(doc_class rexp \<times> string) list",Mixfix.NoSyn),
|
2018-10-08 08:30:53 +00:00
|
|
|
SOME "[]"): ((binding * string * mixfix) * string option)
|
|
|
|
|
|
|
|
fun check_regexps term =
|
|
|
|
let val _ = case fold_aterms Term.add_free_names term [] of
|
|
|
|
n::_ => error("No free variables allowed in monitor regexp:" ^ n)
|
|
|
|
| _ => ()
|
|
|
|
val _ = case fold_aterms Term.add_var_names term [] of
|
|
|
|
(n,_)::_ => error("No schematic variables allowed in monitor regexp:" ^ n)
|
|
|
|
| _ => ()
|
|
|
|
(* Missing: Checks on constants such as undefined, ... *)
|
|
|
|
in term end
|
2018-04-20 11:19:50 +00:00
|
|
|
|
2018-05-11 13:51:26 +00:00
|
|
|
fun add_doc_class_cmd overloaded (raw_params, binding) raw_parent raw_fieldsNdefaults rexp thy =
|
2018-04-05 10:09:58 +00:00
|
|
|
let
|
|
|
|
val ctxt = Proof_Context.init_global thy;
|
2018-10-08 08:30:53 +00:00
|
|
|
val regexps = map (Syntax.read_term_global thy) rexp;
|
|
|
|
val _ = map check_regexps regexps
|
2018-04-05 10:09:58 +00:00
|
|
|
val params = map (apsnd (Typedecl.read_constraint ctxt)) raw_params;
|
|
|
|
val ctxt1 = fold (Variable.declare_typ o TFree) params ctxt;
|
2018-04-20 11:19:50 +00:00
|
|
|
fun cid thy = DOF_core.name2doc_class_name thy (Binding.name_of binding)
|
2018-04-05 10:09:58 +00:00
|
|
|
val (parent, ctxt2) = read_parent raw_parent ctxt1;
|
2018-04-20 11:19:50 +00:00
|
|
|
val parent_cid_long = case parent of
|
|
|
|
NONE => DOF_core.default_cid
|
|
|
|
| SOME(_,str) => str
|
2018-10-08 08:30:53 +00:00
|
|
|
val raw_fieldsNdefaults' = filter (fn((bi,_,_),_) => Binding.name_of bi <> "trace")
|
|
|
|
raw_fieldsNdefaults
|
|
|
|
val _ = if length raw_fieldsNdefaults' <> length raw_fieldsNdefaults
|
|
|
|
then warning("re-declaration of trace attribute in monitor --- ignored")
|
|
|
|
else ()
|
2018-10-11 11:38:32 +00:00
|
|
|
val raw_fieldsNdefaults'' = if null rexp
|
|
|
|
then raw_fieldsNdefaults'
|
|
|
|
else trace_attr::raw_fieldsNdefaults'
|
2018-10-08 08:30:53 +00:00
|
|
|
val (fields, terms, ctxt3) = read_fields raw_fieldsNdefaults'' ctxt2;
|
|
|
|
|
2018-04-05 10:09:58 +00:00
|
|
|
val fieldsNterms = (map (fn (a,b,_) => (a,b)) fields) ~~ terms
|
|
|
|
val fieldsNterms' = map (fn ((x,y),z) => (x,y,z)) fieldsNterms
|
|
|
|
val params' = map (Proof_Context.check_tfree ctxt3) params;
|
2018-04-20 11:19:50 +00:00
|
|
|
fun check_n_filter thy (bind,ty,mf) =
|
2018-08-20 11:54:53 +00:00
|
|
|
case DOF_core.get_attribute_info parent_cid_long (Binding.name_of bind) thy of
|
2018-04-20 11:19:50 +00:00
|
|
|
NONE => (* no prior declaration *) SOME(bind,ty,mf)
|
2018-08-22 20:06:15 +00:00
|
|
|
| SOME{def_occurrence,long_name,typ,def_pos} => if ty = typ
|
2018-08-20 11:54:53 +00:00
|
|
|
then (warning("overriding attribute:"^long_name^
|
|
|
|
" in doc class:" ^ def_occurrence);
|
2018-04-20 11:19:50 +00:00
|
|
|
SOME(bind,ty,mf))
|
|
|
|
else error("no overloading allowed.")
|
2018-04-27 08:34:24 +00:00
|
|
|
val gen_antiquotation = OntoLinkParser.docitem_ref_antiquotation
|
|
|
|
val _ = map_filter (check_n_filter thy) fields
|
2018-04-20 11:19:50 +00:00
|
|
|
in thy |> Record.add_record overloaded (params', binding) parent (tag_attr::fields)
|
2018-10-08 08:30:53 +00:00
|
|
|
|> DOF_core.define_doc_class_global (params', binding) parent fieldsNterms' regexps
|
2018-04-05 10:09:58 +00:00
|
|
|
|> (fn thy => gen_antiquotation binding (cid thy) thy)
|
|
|
|
(* defines the ontology-checked text antiquotation to this document class *)
|
2018-10-30 14:50:01 +00:00
|
|
|
|> (Sign.add_consts_cmd [(binding, "doc_class Regular_Exp.rexp", Mixfix.NoSyn)])
|
2018-05-28 14:10:20 +00:00
|
|
|
(* adding const symbol representing doc-class for Monitor-RegExps.*)
|
|
|
|
|
2018-04-05 10:09:58 +00:00
|
|
|
end;
|
2018-02-07 18:44:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword doc_class} "define document class"
|
2018-04-04 12:44:21 +00:00
|
|
|
((Parse_Spec.overloaded
|
|
|
|
-- (Parse.type_args_constrained -- Parse.binding)
|
|
|
|
-- (@{keyword "="}
|
|
|
|
|-- Scan.option (Parse.typ --| @{keyword "+"})
|
|
|
|
-- Scan.repeat1
|
|
|
|
(Parse.const_binding -- Scan.option (@{keyword "<="} |-- Parse.term)))
|
|
|
|
-- Scan.repeat (@{keyword "where"} |-- Parse.term))
|
2018-02-08 15:25:15 +00:00
|
|
|
>> (fn (((overloaded, x), (y, z)),rex) =>
|
2018-04-04 12:44:21 +00:00
|
|
|
Toplevel.theory (add_doc_class_cmd {overloaded = overloaded} x y z rex)));
|
|
|
|
|
|
|
|
end (* struct *)
|
2018-09-11 06:50:51 +00:00
|
|
|
\<close>
|
2018-02-08 15:25:15 +00:00
|
|
|
|
2018-09-11 06:50:51 +00:00
|
|
|
section\<open> Testing and Validation \<close>
|
|
|
|
|
|
|
|
text*[sdf] {* f @{thm refl}*}
|
|
|
|
text*[sdfg] {* fg @{thm refl}*}
|
|
|
|
|
|
|
|
text*[xxxy] {* dd @{docitem_ref \<open>sdfg\<close>} @{thm refl}*}
|
2018-08-12 06:58:21 +00:00
|
|
|
|
2018-10-08 08:30:53 +00:00
|
|
|
(* the following test crashes the LaTeX generation - however, without the latter this output is
|
|
|
|
instructive
|
2018-10-02 16:29:18 +00:00
|
|
|
ML\<open>
|
|
|
|
writeln (DOF_core.toStringDocItemCommand "section" "scholarly_paper.introduction" []);
|
|
|
|
writeln (DOF_core.toStringDocItemLabel "scholarly_paper.introduction" []);
|
|
|
|
writeln (DOF_core.toStringDocItemRef "scholarly_paper.introduction" "XX" []);
|
|
|
|
|
|
|
|
(DOF_core.write_ontology_latex_sty_template @{theory})
|
|
|
|
\<close>
|
2018-10-04 13:58:20 +00:00
|
|
|
*)
|
2018-10-08 08:30:53 +00:00
|
|
|
|
2018-10-08 13:13:47 +00:00
|
|
|
|
|
|
|
|
2018-04-28 16:41:34 +00:00
|
|
|
end
|