diff --git a/examples/scholarly_paper/2018-cicm-isabelle_dof-applications/IsaDofApplications.thy b/examples/scholarly_paper/2018-cicm-isabelle_dof-applications/IsaDofApplications.thy index dec9a27..56f9a19 100644 --- a/examples/scholarly_paper/2018-cicm-isabelle_dof-applications/IsaDofApplications.thy +++ b/examples/scholarly_paper/2018-cicm-isabelle_dof-applications/IsaDofApplications.thy @@ -74,7 +74,7 @@ abstract*[abs::abstract, keywordlist="[''Ontology'',''Ontological Modeling'',''I \ section*[intro::introduction]\ Introduction \ -text*[introtext::introduction]\ +text*[introtext::introduction, level = "Some 1"]\ The linking of the \<^emph>\formal\ to the \<^emph>\informal\ is perhaps the most pervasive challenge in the digitization of knowledge and its propagation. This challenge incites numerous research efforts @@ -123,7 +123,7 @@ declare_reference*[ontomod::text_section] declare_reference*[ontopide::text_section] declare_reference*[conclusion::text_section] (*>*) -text*[plan::introduction]\ The plan of the paper is follows: we start by introducing the underlying +text*[plan::introduction, level="Some 1"]\ The plan of the paper is follows: we start by introducing the underlying Isabelle system (@{text_section (unchecked) \bgrnd\}) followed by presenting the essentials of \<^isadof> and its ontology language (@{text_section (unchecked) \isadof\}). It follows @{text_section (unchecked) \ontomod\}, where we present three application @@ -133,7 +133,7 @@ conclusions and discuss related work in @{text_section (unchecked) \conclu section*[bgrnd::text_section,main_author="Some(@{docitem ''bu''}::author)"] \ Background: The Isabelle System \ -text*[background::introduction]\ +text*[background::introduction, level="Some 1"]\ While Isabelle is widely perceived as an interactive theorem prover for HOL (Higher-order Logic)~@{cite "nipkow.ea:isabelle:2002"}, we would like to emphasize the view that Isabelle is far more than that: @@ -162,7 +162,7 @@ figure*[architecture::figure,relative_width="100",src="''figures/isabelle-archit asynchronous communication between the Isabelle system and the IDE (right-hand side). \ -text*[blug::introduction]\ The Isabelle system architecture shown in @{figure \architecture\} +text*[blug::introduction, level="Some 1"]\ The Isabelle system architecture shown in @{figure \architecture\} comes with many layers, with Standard ML (SML) at the bottom layer as implementation language. The architecture actually foresees a \<^emph>\Nano-Kernel\ (our terminology) which resides in the SML structure \<^ML_structure>\Context\. This structure provides a kind of container called @@ -194,7 +194,7 @@ For the antiquotation \inlineisar+\at{value "fac 5"}+ we assume the usual defin \inlineisar+fac+ in HOL. \ -text*[anti]\ Thus, antiquotations can refer to formal content, can be type-checked before being +text*[anti::introduction, level = "Some 1"]\ Thus, antiquotations can refer to formal content, can be type-checked before being displayed and can be used for calculations before actually being typeset. When editing, Isabelle's PIDE offers auto-completion and error-messages while typing the above \<^emph>\semi-formal\ content. \ diff --git a/examples/scholarly_paper/2020-iFM-CSP/paper.thy b/examples/scholarly_paper/2020-iFM-CSP/paper.thy index d3f6790..229c48a 100644 --- a/examples/scholarly_paper/2020-iFM-CSP/paper.thy +++ b/examples/scholarly_paper/2020-iFM-CSP/paper.thy @@ -52,7 +52,7 @@ abstract*[abs, keywordlist="[\Shallow Embedding\,\Process-Alg \ text\\ section*[introheader::introduction,main_author="Some(@{docitem ''bu''}::author)"]\ Introduction \ -text*[introtext::introduction]\ +text*[introtext::introduction, level="Some 1"]\ Communicating Sequential Processes (\<^csp>) is a language to specify and verify patterns of interaction of concurrent systems. Together with CCS and LOTOS, it belongs to the family of \<^emph>\process algebras\. @@ -154,7 +154,7 @@ processes \Skip\ (successful termination) and \Stop\ ( \\(Skip) = \(Stop) = {[]}\. Note that the trace sets, representing all \<^emph>\partial\ history, is in general prefix closed.\ -text*[ex1::math_example, status=semiformal] \ +text*[ex1::math_example, status=semiformal, level="Some 1"] \ Let two processes be defined as follows: \<^enum> \P\<^sub>d\<^sub>e\<^sub>t = (a \ Stop) \ (b \ Stop)\ @@ -354,7 +354,7 @@ Roscoe and Brooks @{cite "Roscoe1992AnAO"} finally proposed another ordering, ca that completeness could at least be assured for read-operations. This more complex ordering is based on the concept \<^emph>\refusals after\ a trace \s\ and defined by \\ P s \ {X | (s, X) \ \ P}\.\ -Definition*[process_ordering, short_name="''process ordering''"]\ +Definition*[process_ordering, level= "Some 2", short_name="''process ordering''"]\ We define \P \ Q \ \\<^sub>\ \ \\<^sub>\ \ \\<^sub>\ \, where \<^enum> \\\<^sub>\ = \ P \ \ Q \ \<^enum> \\\<^sub>\ = s \ \ P \ \ P s = \ Q s\ @@ -530,10 +530,10 @@ To handle termination better, we added two new processes \CHAOS\<^sub>S\<^ \ (*<*) (* a test ...*) -text*[X22 ::math_content ]\\RUN A \ \ X. \ x \ A \ X\ \ -text*[X32::"definition", mcc=defn]\\CHAOS A \ \ X. (STOP \ (\ x \ A \ X))\ \ -Definition*[X42]\\CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. (SKIP \ STOP \ (\ x \ A \ X))\ \ -Definition*[X52::"definition"]\\CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. (SKIP \ STOP \ (\ x \ A \ X))\ \ +text*[X22 ::math_content, level="Some 2" ]\\RUN A \ \ X. \ x \ A \ X\ \ +text*[X32::"definition", level="Some 2", mcc=defn]\\CHAOS A \ \ X. (STOP \ (\ x \ A \ X))\ \ +Definition*[X42, level="Some 2"]\\CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. (SKIP \ STOP \ (\ x \ A \ X))\ \ +Definition*[X52::"definition", level="Some 2"]\\CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. (SKIP \ STOP \ (\ x \ A \ X))\ \ text\ The \RUN\-process defined @{math_content X22} represents the process that accepts all events, but never stops nor deadlocks. The \CHAOS\-process comes in two variants shown in @@ -541,11 +541,11 @@ events, but never stops nor deadlocks. The \CHAOS\-process comes in stops or accepts any offered event, whereas \CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P\ can additionally terminate.\ (*>*) -Definition*[X2]\\RUN A \ \ X. \ x \ A \ X\ \ -Definition*[X3]\\CHAOS A \ \ X. (STOP \ (\ x \ A \ X))\ \ -Definition*[X4]\\CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. (SKIP \ STOP \ (\ x \ A \ X))\\ -Definition*[X5]\\DF A \ \ X. (\ x \ A \ X)\ \ -Definition*[X6]\\DF\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. ((\ x \ A \ X) \ SKIP)\ \ +Definition*[X2, level="Some 2"]\\RUN A \ \ X. \ x \ A \ X\ \ +Definition*[X3, level="Some 2"]\\CHAOS A \ \ X. (STOP \ (\ x \ A \ X))\ \ +Definition*[X4, level="Some 2"]\\CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. (SKIP \ STOP \ (\ x \ A \ X))\\ +Definition*[X5, level="Some 2"]\\DF A \ \ X. (\ x \ A \ X)\ \ +Definition*[X6, level="Some 2"]\\DF\<^sub>S\<^sub>K\<^sub>I\<^sub>P A \ \ X. ((\ x \ A \ X) \ SKIP)\ \ text\In the following, we denote \ \\

= {DF\<^sub>S\<^sub>K\<^sub>I\<^sub>P, DF, RUN, CHAOS, CHAOS\<^sub>S\<^sub>K\<^sub>I\<^sub>P}\. All five reference processes are divergence-free. @@ -607,16 +607,16 @@ handled separately. One contribution of our work is establish their precise rela the Failure/Divergence Semantics of \<^csp>.\ (* bizarre: Definition* does not work for this single case *) -text*[X10::"definition"]\ \deadlock\<^sub>-free P \ DF\<^sub>S\<^sub>K\<^sub>I\<^sub>P UNIV \\<^sub>\ P\ \ +text*[X10::"definition", level="Some 2"]\ \deadlock\<^sub>-free P \ DF\<^sub>S\<^sub>K\<^sub>I\<^sub>P UNIV \\<^sub>\ P\ \ text\\<^noindent> A process \P\ is deadlock-free if and only if after any trace \s\ without \\\, the union of \\\ and all events of \P\ can never be a refusal set associated to \s\, which means that \P\ cannot be deadlocked after any non-terminating trace. \ -Theorem*[T1, short_name="\DF definition captures deadlock-freeness\"] +Theorem*[T1, short_name="\DF definition captures deadlock-freeness\", level="Some 2"] \ \hfill \break \deadlock_free P \ (\s\\ P. tickFree s \ (s, {\}\events_of P) \ \ P)\ \ -Definition*[X11]\ \livelock\<^sub>-free P \ \ P = {} \ \ +Definition*[X11, level="Some 2"]\ \livelock\<^sub>-free P \ \ P = {} \ \ text\ Recall that all five reference processes are livelock-free. We also have the following lemmas about the @@ -630,7 +630,7 @@ text\ Finally, we proved the following theorem that confirms the relationship between the two vital properties: \ -Theorem*[T2, short_name="''DF implies LF''"] +Theorem*[T2, short_name="''DF implies LF''", level="Some 2"] \ \deadlock_free P \ livelock_free P\ \ text\ @@ -797,7 +797,7 @@ This normal form is closed under deterministic and communication operators. The advantage of this format is that we can mimick the well-known product automata construction for an arbitrary number of synchronized processes under normal form. We only show the case of the synchronous product of two processes: \ -text*[T3::"theorem", short_name="\Product Construction\"]\ +text*[T3::"theorem", short_name="\Product Construction\", level="Some 2"]\ Parallel composition translates to normal form: @{cartouche [display,indent=5]\(P\<^sub>n\<^sub>o\<^sub>r\<^sub>m\\\<^sub>1,\\<^sub>1\ \\<^sub>1) || (P\<^sub>n\<^sub>o\<^sub>r\<^sub>m\\\<^sub>2,\\<^sub>2\ \\<^sub>2) = P\<^sub>n\<^sub>o\<^sub>r\<^sub>m\\(\\<^sub>1,\\<^sub>2). \\<^sub>1 \\<^sub>1 \ \\<^sub>2 \\<^sub>2 , \(\\<^sub>1,\\<^sub>2).\e.(\\<^sub>1 \\<^sub>1 e, \\<^sub>2 \\<^sub>2 e)\ (\\<^sub>1,\\<^sub>2)\} @@ -817,7 +817,7 @@ states via the closure \\\, which is defined inductively over: Thus, normalization leads to a new characterization of deadlock-freeness inspired from automata theory. We formally proved the following theorem:\ -text*[T4::"theorem", short_name="\DF vs. Reacheability\"] +text*[T4::"theorem", short_name="\DF vs. Reacheability\", level="Some 2"] \ If each reachable state \s \ (\ \ \)\ has outgoing transitions, the \<^csp> process is deadlock-free: @{cartouche [display,indent=10] \\\ \ (\ \ \ \\<^sub>0). \ \ \ {} \ deadlock_free (P\<^sub>n\<^sub>o\<^sub>r\<^sub>m\\,\\ \\<^sub>0)\} diff --git a/examples/technical_report/Isabelle_DOF-Manual/04_RefMan.thy b/examples/technical_report/Isabelle_DOF-Manual/04_RefMan.thy index d12f494..170bddb 100644 --- a/examples/technical_report/Isabelle_DOF-Manual/04_RefMan.thy +++ b/examples/technical_report/Isabelle_DOF-Manual/04_RefMan.thy @@ -1041,10 +1041,11 @@ text\ Ontological classes as described so far are too liberal in many situations. There is a first high-level syntax implementation for class invariants. These invariants can be checked when an instance of the class is defined. - To enable the checking of the invariants, the \<^boxed_theory_text>\invariants_checking\ + To enable the strict checking of the invariants, + the \<^boxed_theory_text>\invariants_strict_checking\ theory attribute must be set: @{boxed_theory_text [display]\ - declare[[invariants_checking = true]]\} + declare[[invariants_strict_checking = true]]\} For example, let's define the following two classes: @{boxed_theory_text [display]\ @@ -1104,6 +1105,12 @@ text\ All specified constraints are already checked in the IDE of \<^dof> while editing. The invariant \<^boxed_theory_text>\author_finite\ enforces that the user sets the \<^boxed_theory_text>\authored_by\ set. + The invariants \<^theory_text>\author_finite\ and \<^theory_text>\establish_defined\ can not be checked directly + and need a little help. + We can set the \invariants_checking_with_tactics\ theory attribute to help the checking. + It will enable a basic tactic, using unfold and auto: + @{boxed_theory_text [display]\ + declare[[invariants_checking_with_tactics = true]]\} There are still some limitations with this high-level syntax. For now, the high-level syntax does not support monitors (see \<^technical>\sec:monitors\). For example, one would like to delay a final error message till the diff --git a/src/DOF/Isa_DOF.thy b/src/DOF/Isa_DOF.thy index 5cc5db8..d4a8a09 100644 --- a/src/DOF/Isa_DOF.thy +++ b/src/DOF/Isa_DOF.thy @@ -813,8 +813,8 @@ fun print_doc_class_tree ctxt P T = val (strict_monitor_checking, strict_monitor_checking_setup) = Attrib.config_bool \<^binding>\strict_monitor_checking\ (K false); -val (invariants_checking, invariants_checking_setup) - = Attrib.config_bool \<^binding>\invariants_checking\ (K false); +val (invariants_strict_checking, invariants_strict_checking_setup) + = Attrib.config_bool \<^binding>\invariants_strict_checking\ (K false); val (invariants_checking_with_tactics, invariants_checking_with_tactics_setup) = Attrib.config_bool \<^binding>\invariants_checking_with_tactics\ (K false); @@ -825,7 +825,7 @@ end (* struct *) \ setup\DOF_core.strict_monitor_checking_setup - #> DOF_core.invariants_checking_setup + #> DOF_core.invariants_strict_checking_setup #> DOF_core.invariants_checking_with_tactics_setup\ section\ Syntax for Term Annotation Antiquotations (TA)\ @@ -948,6 +948,7 @@ structure ISA_core = struct fun err msg pos = error (msg ^ Position.here pos); +fun warn msg pos = warning (msg ^ Position.here pos); fun check_path check_file ctxt dir (name, pos) = let @@ -1600,11 +1601,12 @@ fun check_invariants thy oid = end fun check_invariants' ((inv_name, pos), term) = let val ctxt = Proof_Context.init_global thy + val trivial_true = \<^term>\True\ |> HOLogic.mk_Trueprop |> Thm.cterm_of ctxt |> Thm.trivial val evaluated_term = value ctxt term handle ERROR e => if (String.isSubstring "Wellsortedness error" e) andalso (Config.get_global thy DOF_core.invariants_checking_with_tactics) - then (warning("Invariants checking uses proof tactics"); + then (warning("Invariants checking uses proof tactics"); let val prop_term = HOLogic.mk_Trueprop term val thms = Proof_Context.get_thms ctxt (inv_name ^ def_suffixN) (* Get the make definition (def(1) of the record) *) @@ -1614,22 +1616,37 @@ fun check_invariants thy oid = (K ((unfold_tac ctxt thms') THEN (auto_tac ctxt))) |> Thm.close_derivation \<^here> handle ERROR e => - ISA_core.err ("Invariant " + let + val msg_intro = "Invariant " ^ inv_name ^ " failed to be checked using proof tactics" - ^ " with error: " - ^ e) pos + ^ " with error:\n" + in + if Config.get_global thy DOF_core.invariants_strict_checking + then ISA_core.err (msg_intro ^ e) pos + else (ISA_core.warn (msg_intro ^ e) pos; trivial_true) end (* If Goal.prove does not fail, then the evaluation is considered True, else an error is triggered by Goal.prove *) in @{term True} end) - else ISA_core.err ("Fail to check invariant " - ^ inv_name - ^ ". Try to activate invariants_checking_with_tactics.") pos - in (if evaluated_term = \<^term>\True\ - then ((inv_name, pos), term) - else ISA_core.err ("Invariant " ^ inv_name ^ " violated") pos) + else \<^term>\True \ True\ + in case evaluated_term of + \<^term>\True\ => ((inv_name, pos), term) + | \<^term>\True \ True\ => + let val msg_intro = "Fail to check invariant " + ^ inv_name + ^ ".\nMaybe you can try " + ^ "to activate invariants_checking_with_tactics\n" + ^ "if your invariant is checked against doc_class algebraic " + ^ "types like 'doc_class list' or 'doc_class set'" + in if Config.get_global thy DOF_core.invariants_strict_checking + then ISA_core.err (msg_intro) pos + else (ISA_core.warn (msg_intro) pos; ((inv_name, pos), term)) end + | _ => let val msg_intro = "Invariant " ^ inv_name ^ " violated" + in if Config.get_global thy DOF_core.invariants_strict_checking + then ISA_core.err msg_intro pos + else (ISA_core.warn msg_intro pos; ((inv_name, pos), term)) end end - val _ = map check_invariants' inv_and_apply_list + val _ = map check_invariants' inv_and_apply_list in thy end fun create_and_check_docitem is_monitor {is_inline=is_inline} oid pos cid_pos doc_attrs thy = @@ -1639,20 +1656,19 @@ fun create_and_check_docitem is_monitor {is_inline=is_inline} oid pos cid_pos do (* 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. *) val cid_long = check_classref is_monitor cid_pos thy + val default_cid = cid_long = DOF_core.default_cid val vcid = case cid_pos of NONE => NONE | SOME (cid,_) => if (DOF_core.is_virtual cid thy) then SOME (DOF_core.parse_cid_global thy cid) else NONE - val value_terms = if (cid_long = DOF_core.default_cid) + val value_terms = if default_cid then let - val undefined_value = Free ("Undefined_Value", \<^Type>\unit\) + val undefined_value = Free ("Undefined_Value", \<^Type>\unit\) in (undefined_value, undefined_value) end - (* - Handle initialization of docitem without a class associated, - for example when you just want a document element to be referenceable - without using the burden of ontology classes. - ex: text*[sdf]\ Lorem ipsum @{thm refl}\ - *) + (* Handle initialization of docitem without a class associated, + for example when you just want a document element to be referenceable + without using the burden of ontology classes. + ex: text*[sdf]\ Lorem ipsum @{thm refl}\ *) else let val defaults_init = create_default_object thy cid_long fun conv (na, _(*ty*), term) =(Binding.name_of na, Binding.pos_of na, "=", term); @@ -1684,9 +1700,15 @@ fun create_and_check_docitem is_monitor {is_inline=is_inline} oid pos cid_pos do o Context.Theory) thy; thy) else thy) |> (fn thy => (check_inv thy; thy)) - |> (fn thy => if Config.get_global thy DOF_core.invariants_checking = true - then check_invariants thy oid - else thy) + (* Bypass checking of high-level invariants when the class default_cid = "text", + the top (default) document class. + We want the class default_cid to stay abstract + and not have the capability to be defined with attribute, invariants, etc. + Hence this bypass handles docitem without a class associated, + for example when you just want a document element to be referenceable + without using the burden of ontology classes. + ex: text*[sdf]\ Lorem ipsum @{thm refl}\ *) + |> (fn thy => if default_cid then thy else check_invariants thy oid) end end (* structure Docitem_Parser *) @@ -1870,9 +1892,7 @@ fun update_instance_command (((oid:string,pos),cid_pos), in thy |> DOF_core.update_value_global oid def_trans_input_term def_trans_value |> check_inv - |> (fn thy => if Config.get_global thy DOF_core.invariants_checking = true - then Value_Command.Docitem_Parser.check_invariants thy oid - else thy) + |> (fn thy => Value_Command.Docitem_Parser.check_invariants thy oid) end @@ -1932,9 +1952,7 @@ fun close_monitor_command (args as (((oid:string,pos),cid_pos), in thy |> (fn thy => (check_lazy_inv thy; thy)) |> update_instance_command args |> (fn thy => (check_inv thy; thy)) - |> (fn thy => if Config.get_global thy DOF_core.invariants_checking = true - then Value_Command.Docitem_Parser.check_invariants thy oid - else thy) + |> (fn thy => Value_Command.Docitem_Parser.check_invariants thy oid) |> delete_monitor_entry end diff --git a/src/ontologies/scholarly_paper/scholarly_paper.thy b/src/ontologies/scholarly_paper/scholarly_paper.thy index 4ae9a66..50c1850 100644 --- a/src/ontologies/scholarly_paper/scholarly_paper.thy +++ b/src/ontologies/scholarly_paper/scholarly_paper.thy @@ -69,7 +69,7 @@ which we formalize into:\ doc_class text_section = text_element + main_author :: "author option" <= None fixme_list :: "string list" <= "[]" - level :: "int option" <= "None" + level :: "int option" <= "None" (* this attribute enables doc-notation support section* etc. we follow LaTeX terminology on levels part = Some -1 diff --git a/src/tests/High_Level_Syntax_Invariants.thy b/src/tests/High_Level_Syntax_Invariants.thy index 204626f..50fe0f1 100644 --- a/src/tests/High_Level_Syntax_Invariants.thy +++ b/src/tests/High_Level_Syntax_Invariants.thy @@ -12,7 +12,7 @@ text\ theory attribute must be set:\ -declare[[invariants_checking = true]] +declare[[invariants_strict_checking = true]] text\For example, let's define the following two classes:\ @@ -144,6 +144,6 @@ value*\evidence @{result \resultProof\} = evidence @{result \ declare[[invariants_checking_with_tactics = false]] -declare[[invariants_checking = false]] +declare[[invariants_strict_checking = false]] end