chapter\High level syntax Invariants\ theory High_Level_Syntax_Invariants imports "Isabelle_DOF.Isa_DOF" begin 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 \invariants_checking\ theory attribute must be set:\ declare[[invariants_checking = true]] text\For example, let's define the following two classes:\ doc_class class_inv1 = int1 :: "int" invariant inv1 :: "int1 \ \ 3" doc_class class_inv2 = class_inv1 + int2 :: "int" invariant inv2 :: "int2 \ < 2" text\The symbol \<^term>\\\ is reserved and references the future instance class. By relying on the implementation of the Records in Isabelle/HOL~@{cite "wenzel:isabelle-isar:2020"}, one can reference an attribute of an instance using its selector function. For example, \<^term>\int1 \\ denotes the value of the \<^term>\int1\ attribute of the future instance of the class @{doc_class class_inv1}. Now let's define two instances, one of each class:\ text*[testinv1::class_inv1, int1=4]\lorem ipsum...\ text*[testinv2::class_inv2, int1=3, int2=1]\lorem ipsum...\ text\ The value of each attribute defined for the instances is checked against their classes invariants. As the class @{doc_class class_inv2} is a subsclass of the class @{doc_class class_inv1}, it inherits @{doc_class class_inv1} invariants. Hence the \<^term>\int1\ invariant is checked when the instance @{docitem testinv2} is defined.\ text\Now assume the following ontology:\ doc_class title = short_title :: "string option" <= "None" doc_class author = email :: "string" <= "''''" datatype classification = SIL0 | SIL1 | SIL2 | SIL3 | SIL4 doc_class abstract = keywordlist :: "string list" <= "[]" safety_level :: "classification" <= "SIL3" doc_class text_section = authored_by :: "author set" <= "{}" level :: "int option" <= "None" type_synonym notion = string doc_class introduction = text_section + authored_by :: "author set" <= "UNIV" uses :: "notion set" invariant author_finite :: "finite (authored_by \)" and force_level :: "the (level \) > 1" doc_class claim = introduction + based_on :: "notion list" doc_class technical = text_section + formal_results :: "thm list" doc_class "definition" = technical + is_formal :: "bool" property :: "term list" <= "[]" datatype kind = expert_opinion | argument | "proof" doc_class result = technical + evidence :: kind property :: "thm list" <= "[]" invariant has_property :: "evidence \ = proof \ property \ \ []" doc_class example = technical + referring_to :: "(notion + definition) set" <= "{}" doc_class conclusion = text_section + establish :: "(claim \ result) set" invariant establish_defined :: "\ x. x \ Domain (establish \) \ (\ y \ Range (establish \). (x, y) \ establish \)" text\Next we define some instances (docitems): \ declare[[invariants_checking_with_tactics = true]] text*[church::author, email="\church@lambda.org\"]\\ (*text*[introduction1::introduction, authored_by = "{@{author \church\}}", level = "Some 0"]\\*) text*[resultProof::result, evidence = "proof", property="[@{thm \HOL.refl\}]"]\\ text*[resultArgument::result, evidence = "argument"]\\ text\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:\ declare[[invariants_checking_with_tactics = true]] text*[curry::author, email="\curry@lambda.org\"]\\ text*[introduction2::introduction, authored_by = "{@{author \church\}}", level = "Some 2"]\\ text*[introduction3::introduction, authored_by = "{@{author \church\}}", level = "Some 2"]\\ text*[introduction4::introduction, authored_by = "{@{author \curry\}}", level = "Some 4"]\\ text*[resultProof2::result, evidence = "proof", property="[@{thm \HOL.sym\}]"]\\ text\Then we can evaluate expressions with instances:\ term*\authored_by @{introduction \introduction2\} = authored_by @{introduction \introduction3\}\ value*\authored_by @{introduction \introduction2\} = authored_by @{introduction \introduction3\}\ value*\authored_by @{introduction \introduction2\} = authored_by @{introduction \introduction4\}\ value*\@{introduction \introduction2\}\ value*\{@{author \curry\}} = {@{author \church\}}\ term*\property @{result \resultProof\} = property @{result \resultProof2\}\ value*\property @{result \resultProof\} = property @{result \resultProof2\}\ value*\evidence @{result \resultProof\} = evidence @{result \resultProof2\}\ declare[[invariants_checking_with_tactics = false]] end