From 02c1e24f17685ff75b71b13e39b79b621a39fc73 Mon Sep 17 00:00:00 2001 From: "Achim D. Brucker" Date: Wed, 10 Aug 2016 11:22:14 +0100 Subject: [PATCH] Import of current (Isabelle 2016) release of Featherweight OCL. --- OCL_lib.thy | 3171 ----------------- OCL_main.thy | 57 - ROOT | 68 +- document/formalization.tex | 25 - document/introduction.tex | 1490 -------- document/root.tex | 150 - examples/Employee_AnalysisModel_OCLPart.thy | 143 - examples/Employee_DesignModel_OCLPart.thy | 143 - .../Employee_Model/Analysis/Analysis_OCL.thy | 362 ++ .../Analysis/Analysis_UML.thy} | 645 ++-- examples/Employee_Model/Design/Design_OCL.thy | 137 + .../Design/Design_UML.thy} | 578 +-- readme.txt | 76 + src/UML_Contracts.thy | 413 +++ src/UML_Library.thy | 260 ++ OCL_core.thy => src/UML_Logic.thy | 708 ++-- OCL_tools.thy => src/UML_Main.thy | 12 +- src/UML_PropertyProfiles.thy | 376 ++ OCL_state.thy => src/UML_State.thy | 681 ++-- src/UML_Tools.thy | 137 + src/UML_Types.thy | 653 ++++ src/basic_types/UML_Boolean.thy | 126 + src/basic_types/UML_Integer.thy | 288 ++ src/basic_types/UML_Real.thy | 287 ++ src/basic_types/UML_String.thy | 167 + src/basic_types/UML_Void.thy | 138 + src/collection_types/UML_Bag.thy | 1072 ++++++ src/collection_types/UML_Pair.thy | 219 ++ src/collection_types/UML_Sequence.thy | 572 +++ src/collection_types/UML_Set.thy | 3170 ++++++++++++++++ src/document/FOCL_Syntax.tex | 1085 ++++++ {document => src/document}/conclusion.tex | 43 +- .../document}/figures/AbstractSimpleChair.mp | 0 .../document}/figures/AbstractSimpleChair.pdf | Bin {document => src/document}/figures/jedit.png | Bin {document => src/document}/figures/pdf.png | Bin {document => src/document}/figures/person.png | Bin .../document}/figures/pre-post.pdf | Bin {document => src/document}/hol-ocl-isar.sty | 6 + src/document/introduction.tex | 2115 +++++++++++ {document => src/document}/lstisar.sty | 0 src/document/omg.sty | 28 + {document => src/document}/prooftree.sty | 0 {document => src/document}/root.bib | 87 +- src/document/root.tex | 283 ++ 45 files changed, 13515 insertions(+), 6456 deletions(-) delete mode 100644 OCL_lib.thy delete mode 100644 OCL_main.thy delete mode 100644 document/formalization.tex delete mode 100644 document/introduction.tex delete mode 100644 document/root.tex delete mode 100644 examples/Employee_AnalysisModel_OCLPart.thy delete mode 100644 examples/Employee_DesignModel_OCLPart.thy create mode 100644 examples/Employee_Model/Analysis/Analysis_OCL.thy rename examples/{Employee_AnalysisModel_UMLPart.thy => Employee_Model/Analysis/Analysis_UML.thy} (69%) create mode 100644 examples/Employee_Model/Design/Design_OCL.thy rename examples/{Employee_DesignModel_UMLPart.thy => Employee_Model/Design/Design_UML.thy} (70%) create mode 100644 readme.txt create mode 100644 src/UML_Contracts.thy create mode 100644 src/UML_Library.thy rename OCL_core.thy => src/UML_Logic.thy (77%) rename OCL_tools.thy => src/UML_Main.thy (90%) create mode 100644 src/UML_PropertyProfiles.thy rename OCL_state.thy => src/UML_State.thy (59%) create mode 100644 src/UML_Tools.thy create mode 100644 src/UML_Types.thy create mode 100644 src/basic_types/UML_Boolean.thy create mode 100644 src/basic_types/UML_Integer.thy create mode 100644 src/basic_types/UML_Real.thy create mode 100644 src/basic_types/UML_String.thy create mode 100644 src/basic_types/UML_Void.thy create mode 100644 src/collection_types/UML_Bag.thy create mode 100644 src/collection_types/UML_Pair.thy create mode 100644 src/collection_types/UML_Sequence.thy create mode 100644 src/collection_types/UML_Set.thy create mode 100644 src/document/FOCL_Syntax.tex rename {document => src/document}/conclusion.tex (88%) rename {document => src/document}/figures/AbstractSimpleChair.mp (100%) rename {document => src/document}/figures/AbstractSimpleChair.pdf (100%) rename {document => src/document}/figures/jedit.png (100%) rename {document => src/document}/figures/pdf.png (100%) rename {document => src/document}/figures/person.png (100%) rename {document => src/document}/figures/pre-post.pdf (100%) rename {document => src/document}/hol-ocl-isar.sty (99%) create mode 100644 src/document/introduction.tex rename {document => src/document}/lstisar.sty (100%) create mode 100644 src/document/omg.sty rename {document => src/document}/prooftree.sty (100%) rename {document => src/document}/root.bib (94%) create mode 100644 src/document/root.tex diff --git a/OCL_lib.thy b/OCL_lib.thy deleted file mode 100644 index d41664c..0000000 --- a/OCL_lib.thy +++ /dev/null @@ -1,3171 +0,0 @@ -(***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 - * for the OMG Standard. - * http://www.brucker.ch/projects/hol-testgen/ - * - * OCL_lib.thy --- Library definitions. - * This file is part of HOL-TestGen. - * - * Copyright (c) 2012-2013 Université Paris-Sud, France - * 2013 IRT SystemX, France - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************) - -chapter{* Formalization II: Library Definitions *} - -theory OCL_lib -imports OCL_core -begin - -text {* -The structure of this chapter roughly follows the structure of Chapter -10 of the OCL standard~\cite{omg:ocl:2012}, which introduces the OCL -Library. - *} - -section{* Basic Types: Void and Integer *} -subsection{* The Construction of the Void Type *} -type_synonym ('\)Void = "('\,unit option) val" -(* For technical reasons, the type does not contain to the null-class yet. *) -text {* This \emph{minimal} OCL type contains only two elements: -@{term "invalid"} and @{term "null"}. -@{term "Void"} could initially be defined as @{typ "unit option option"}, -however the cardinal of this type is more than two, so it would have the cost to consider - @{text "Some None"} and @{text "Some (Some ())"} seemingly everywhere.*} - - -subsection{* The Construction of the Integer Type *} -text{* Since @{term "Integer"} is again a basic type, we define its semantic domain -as the valuations over @{typ "int option option"}. *} -type_synonym ('\)Integer = "('\,int option option) val" - -text{* Although the remaining part of this library reasons about -integers abstractly, we provide here as example some convenient shortcuts. *} - -definition OclInt0 ::"('\)Integer" ("\") -where "\ = (\ _ . \\0::int\\)" - -definition OclInt1 ::"('\)Integer" ("\") -where "\ = (\ _ . \\1::int\\)" - -definition OclInt2 ::"('\)Integer" ("\") -where "\ = (\ _ . \\2::int\\)" - -definition OclInt3 ::"('\)Integer" ("\") -where "\ = (\ _ . \\3::int\\)" - -definition OclInt4 ::"('\)Integer" ("\") -where "\ = (\ _ . \\4::int\\)" - -definition OclInt5 ::"('\)Integer" ("\") -where "\ = (\ _ . \\5::int\\)" - -definition OclInt6 ::"('\)Integer" ("\") -where "\ = (\ _ . \\6::int\\)" - -definition OclInt7 ::"('\)Integer" ("\") -where "\ = (\ _ . \\7::int\\)" - -definition OclInt8 ::"('\)Integer" ("\") -where "\ = (\ _ . \\8::int\\)" - -definition OclInt9 ::"('\)Integer" ("\") -where "\ = (\ _ . \\9::int\\)" - -definition OclInt10 ::"('\)Integer" ("\\") -where "\\ = (\ _ . \\10::int\\)" - -subsection{* Validity and Definedness Properties *} - -lemma "\(null::('\)Integer) = false" by simp -lemma "\(null::('\)Integer) = true" by simp - -lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" -by(simp add:defined_def true_def - bot_fun_def bot_option_def null_fun_def null_option_def) - -lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" -by(simp add:valid_def true_def - bot_fun_def bot_option_def) - -(* ecclectic proofs to make examples executable *) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt0_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt0_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt1_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt1_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt2_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt2_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt6_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt6_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt8_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt8_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt9_def) -lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt9_def) - - -subsection{* Arithmetical Operations on Integer *} - -subsubsection{* Definition *} -text{* Here is a common case of a built-in operation on built-in types. -Note that the arguments must be both defined (non-null, non-bot). *} -text{* Note that we can not follow the lexis of the OCL Standard for Isabelle -technical reasons; these operators are heavily overloaded in the HOL library -that a further overloading would lead to heavy technical buzz in this -document. -*} -definition OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Integer" (infix "`+" 40) -where "x `+ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then \\\\x \\\ + \\y \\\\\ - else invalid \ " - -definition OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Boolean" (infix "`<" 40) -where "x `< y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then \\\\x \\\ < \\y \\\\\ - else invalid \ " - -definition OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Boolean" (infix "`\" 40) -where "x `\ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then \\\\x \\\ \ \\y \\\\\ - else invalid \ " - -subsubsection{* Basic Properties *} - -lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_commute: "(X `+ Y) = (Y `+ X)" - by(rule ext,auto simp:true_def false_def OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def invalid_def - split: option.split option.split_asm - bool.split bool.split_asm) - -subsubsection{* Execution with Invalid or Null or Zero as Argument *} - -lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict1[simp,code_unfold] : "(x `+ invalid) = invalid" -by(rule ext, simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def true_def false_def) - -lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict2[simp,code_unfold] : "(invalid `+ x) = invalid" -by(rule ext, simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def true_def false_def) - -lemma [simp,code_unfold] : "(x `+ null) = invalid" -by(rule ext, simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def true_def false_def) - -lemma [simp,code_unfold] : "(null `+ x) = invalid" -by(rule ext, simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def true_def false_def) - -lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_zero1[simp,code_unfold] : -"(x `+ \) = (if \ x and not (\ x) then invalid else x endif)" - proof (rule ext, rename_tac \, case_tac "(\ x and not (\ x)) \ = true \") - fix \ show "(\ x and not (\ x)) \ = true \ \ - (x `+ \) \ = (if \ x and not (\ x) then invalid else x endif) \" - apply(subst OclIf_true', simp add: OclValid_def) - by (metis OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def OclNot_defargs OclValid_def foundation5 foundation9) - apply_end assumption - next fix \ - have A: "\\. (\ \ not (\ x and not (\ x))) = (x \ = invalid \ \ \ \ \ x)" - by (metis OclNot_not OclOr_def defined5 defined6 defined_not_I foundation11 foundation18' - foundation6 foundation7 foundation9 invalid_def) - have B: "\ \ \ x \ \\\\x \\\\\ = x \" - apply(cases "x \", metis bot_option_def foundation17) - apply(rename_tac x', case_tac x', metis bot_option_def foundation16 null_option_def) - by(simp) - show "\ \ not (\ x and not (\ x)) \ - (x `+ \) \ = (if \ x and not (\ x) then invalid else x endif) \" - apply(subst OclIf_false', simp, simp add: A, auto simp: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def OclInt0_def) - (* *) - apply (metis OclValid_def foundation19 foundation20) - apply(simp add: B) - by(simp add: OclValid_def) - apply_end(metis OclValid_def defined5 defined6 defined_and_I defined_not_I foundation9) -qed - -lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_zero2[simp,code_unfold] : -"(\ `+ x) = (if \ x and not (\ x) then invalid else x endif)" -by(subst OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_commute, simp) - -subsubsection{* Context Passing *} - -lemma cp_OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r:"(X `+ Y) \ = ((\ _. X \) `+ (\ _. Y \)) \" -by(simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def cp_defined[symmetric]) - -lemma cp_OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r:"(X `< Y) \ = ((\ _. X \) `< (\ _. Y \)) \" -by(simp add: OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def cp_defined[symmetric]) - -lemma cp_OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r:"(X `\ Y) \ = ((\ _. X \) `\ (\ _. Y \)) \" -by(simp add: OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def cp_defined[symmetric]) - -subsubsection{* Test Statements *} -text{* Here follows a list of code-examples, that explain the meanings -of the above definitions by compilation to code and execution to @{term "True"}.*} - -value " \ \ ( \ `\ \\ )" -value " \ \ (( \ `+ \ ) `\ \\ )" -value "\(\ \ (( \ `+ ( \ `+ \ )) `< \\ ))" -value " \ \ not (\ (null `+ \)) " - -section{* Fundamental Predicates on Basic Types: Strict Equality *} - -subsection{* Definition *} - -text{* The last basic operation belonging to the fundamental infrastructure -of a value-type in OCL is the weak equality, which is defined similar -to the @{typ "('\)Boolean"}-case as strict extension of the strong equality:*} -defs (overloaded) StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[code_unfold] : - "(x::('\)Integer) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then (x \ y) \ - else invalid \" - -value "\ \ \ <> \" -value "\ \ \ <> \" -value "\ \ \ \ \" - -subsection{* Logic and Algebraic Layer on Basic Types *} - -subsubsection{* Validity and Definedness Properties (I) *} - -lemma StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_defined_args_valid: -"(\ \ \((x::('\)Boolean) \ y)) = ((\ \(\ x)) \ (\ \(\ y)))" -by(auto simp: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def null_fun_def bot_fun_def null_option_def bot_option_def - split: bool.split_asm HOL.split_if_asm option.split) - -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_defined_args_valid: -"(\ \ \((x::('\)Integer) \ y)) = ((\ \(\ x)) \ (\ \(\ y)))" -by(auto simp: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def null_fun_def bot_fun_def null_option_def bot_option_def - split: bool.split_asm HOL.split_if_asm option.split) - -subsubsection{* Validity and Definedness Properties (II) *} - -lemma StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_defargs: -"\ \ ((x::('\)Boolean) \ y) \ (\ \ (\ x)) \ (\ \(\ y))" -by(simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclValid_def true_def invalid_def - bot_option_def - split: bool.split_asm HOL.split_if_asm) - -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_defargs: -"\ \ ((x::('\)Integer) \ y) \ (\ \ (\ x)) \ (\ \ (\ y))" -by(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r OclValid_def true_def invalid_def valid_def bot_option_def - split: bool.split_asm HOL.split_if_asm) - -subsubsection{* Validity and Definedness Properties (III) Miscellaneous *} - -lemma StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_strict'' : "\ ((x::('\)Boolean) \ y) = (\(x) and \(y))" -by(auto intro!: transform2_rev defined_and_I simp:foundation10 StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_defined_args_valid) - -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict'' : "\ ((x::('\)Integer) \ y) = (\(x) and \(y))" -by(auto intro!: transform2_rev defined_and_I simp:foundation10 StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_defined_args_valid) - -(* Probably not very useful *) -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict : - assumes A: "\ (x::('\)Integer) = true" - and B: "\ y = true" - shows "\ (x \ y) = true" - apply(insert A B) - apply(rule ext, simp add: StrongEq_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r true_def valid_def defined_def - bot_fun_def bot_option_def) - done - - -(* Probably not very useful *) -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict' : - assumes A: "\ (((x::('\)Integer)) \ y) = true" - shows "\ x = true \ \ y = true" - apply(insert A, rule conjI) - apply(rule ext, rename_tac \, drule_tac x=\ in fun_cong) - prefer 2 - apply(rule ext, rename_tac \, drule_tac x=\ in fun_cong) - apply(simp_all add: StrongEq_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r - false_def true_def valid_def defined_def) - apply(case_tac "y \", auto) - apply(simp_all add: true_def invalid_def bot_fun_def) - done - -subsubsection{* Reflexivity *} - -lemma StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_refl[simp,code_unfold] : -"((x::('\)Boolean) \ x) = (if (\ x) then true else invalid endif)" -by(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclIf_def) - -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_refl[simp,code_unfold] : -"((x::('\)Integer) \ x) = (if (\ x) then true else invalid endif)" -by(rule ext, simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r OclIf_def) - -subsubsection{* Execution with Invalid or Null as Argument *} - -lemma StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_strict1[simp,code_unfold] : "((x::('\)Boolean) \ invalid) = invalid" -by(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n true_def false_def) - -lemma StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_strict2[simp,code_unfold] : "(invalid \ (x::('\)Boolean)) = invalid" -by(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n true_def false_def) - -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict1[simp,code_unfold] : "((x::('\)Integer) \ invalid) = invalid" -by(rule ext, simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r true_def false_def) - -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict2[simp,code_unfold] : "(invalid \ (x::('\)Integer)) = invalid" -by(rule ext, simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r true_def false_def) - -lemma integer_non_null [simp]: "((\_. \\n\\) \ (null::('\)Integer)) = false" -by(rule ext,auto simp: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def - bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) - -lemma null_non_integer [simp]: "((null::('\)Integer) \ (\_. \\n\\)) = false" -by(rule ext,auto simp: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def - bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) - -lemma OclInt0_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt0_def) -lemma null_non_OclInt0 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt0_def) -lemma OclInt1_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt1_def) -lemma null_non_OclInt1 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt1_def) -lemma OclInt2_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt2_def) -lemma null_non_OclInt2 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt2_def) -lemma OclInt6_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt6_def) -lemma null_non_OclInt6 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt6_def) -lemma OclInt8_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt8_def) -lemma null_non_OclInt8 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt8_def) -lemma OclInt9_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt9_def) -lemma null_non_OclInt9 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt9_def) - - -(* plus all the others ...*) - -subsubsection{* Const *} - -lemma [simp,code_unfold]: "const(\)" by(simp add: const_ss OclInt0_def) -lemma [simp,code_unfold]: "const(\)" by(simp add: const_ss OclInt1_def) -lemma [simp,code_unfold]: "const(\)" by(simp add: const_ss OclInt2_def) -lemma [simp,code_unfold]: "const(\)" by(simp add: const_ss OclInt6_def) -lemma [simp,code_unfold]: "const(\)" by(simp add: const_ss OclInt8_def) -lemma [simp,code_unfold]: "const(\)" by(simp add: const_ss OclInt9_def) - - -subsubsection{* Behavior vs StrongEq *} - -lemma StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_vs_StrongEq: -"\ \(\ x) \ \ \(\ y) \ (\ \ (((x::('\)Boolean) \ y) \ (x \ y)))" -apply(simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclValid_def) -apply(subst cp_StrongEq[of _ "(x \ y)"]) -by simp - - -lemma StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_vs_StrongEq: -"\ \(\ x) \ \ \(\ y) \ (\ \ (((x::('\)Integer) \ y) \ (x \ y)))" -apply(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r OclValid_def) -apply(subst cp_StrongEq[of _ "(x \ y)"]) -by simp - - -subsubsection{* Context Passing *} - -lemma cp_StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n: -"((X::('\)Boolean) \ Y) \ = ((\ _. X \) \ (\ _. Y \)) \" -by(auto simp: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def defined_def valid_def cp_defined[symmetric]) - -lemma cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r: -"((X::('\)Integer) \ Y) \ = ((\ _. X \) \ (\ _. Y \)) \" -by(auto simp: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def valid_def cp_defined[symmetric]) - - -lemmas cp_intro'[intro!,simp,code_unfold] = - cp_intro' - cp_StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "StrictRefEq"]] - cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "StrictRefEq"]] - cp_OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r"]] - cp_OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r"]] - cp_OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r"]] - - -subsection{* Test Statements on Basic Types. *} - -text{* Here follows a list of code-examples, that explain the meanings -of the above definitions by compilation to code and execution to @{term "True"}.*} - -text{* Elementary computations on Booleans *} -value "\ \ \(true)" -value "\ \ \(false)" -value "\(\ \ \(null))" -value "\(\ \ \(invalid))" -value "\ \ \((null::('\)Boolean))" -value "\(\ \ \(invalid))" -value "\ \ (true and true)" -value "\ \ (true and true \ true)" -value "\ \ ((null or null) \ null)" -value "\ \ ((null or null) \ null)" -value "\ \ ((true \ false) \ false)" -value "\ \ ((invalid \ false) \ false)" -value "\ \ ((invalid \ false) \ invalid)" - - -text{* Elementary computations on Integer *} -value " \ \ \ \" -value " \ \ \ \" -value " \ \ \ (null::('\)Integer)" -value " \ \ (invalid \ invalid)" -value " \ \ (null \ null)" -value " \ \ (\ \ \)" -value "\(\ \ (\ \ \\))" -value "\(\ \ (invalid \ \\))" -value "\(\ \ (null \ \\))" -value "\(\ \ (invalid \ (invalid::('\)Integer)))" (* Without typeconstraint not executable.*) -value "\(\ \ \ (invalid \ (invalid::('\)Integer)))" (* Without typeconstraint not executable.*) -value "\(\ \ (invalid <> (invalid::('\)Integer)))" (* Without typeconstraint not executable.*) -value "\(\ \ \ (invalid <> (invalid::('\)Integer)))" (* Without typeconstraint not executable.*) -value " \ \ (null \ (null::('\)Integer) )" (* Without typeconstraint not executable.*) -value " \ \ (null \ (null::('\)Integer) )" (* Without typeconstraint not executable.*) -value " \ \ (\ \ \)" -value "\(\ \ (\ <> \))" -value "\(\ \ (\ \ \\))" -value " \ \ (\ <> \\)" -value "\(\ \ (\ `< null))" -value "\(\ \ (\ (\ `< null)))" - - -section{* Complex Types: The Set-Collection Type (I) Core *} - -subsection{* The Construction of the Set Type *} - -no_notation None ("\") -notation bot ("\") - -text{* For the semantic construction of the collection types, we have two goals: -\begin{enumerate} -\item we want the types to be \emph{fully abstract}, \ie, the type should not - contain junk-elements that are not representable by OCL expressions, and -\item we want a possibility to nest collection types (so, we want the - potential to talking about @{text "Set(Set(Sequences(Pairs(X,Y))))"}). -\end{enumerate} -The former principle rules out the option to define @{text "'\ Set"} just by - @{text "('\, ('\ option option) set) val"}. This would allow sets to contain -junk elements such as @{text "{\}"} which we need to identify with undefinedness -itself. Abandoning fully abstractness of rules would later on produce all sorts -of problems when quantifying over the elements of a type. -However, if we build an own type, then it must conform to our abstract interface -in order to have nested types: arguments of type-constructors must conform to our -abstract interface, and the result type too. -*} - -text{* The core of an own type construction is done via a type - definition which provides the raw-type @{text "'\ Set_0"}. It - is shown that this type ``fits'' indeed into the abstract type - interface discussed in the previous section. *} - -typedef '\ Set_0 ="{X::('\\null) set option option. - X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by (rule_tac x="bot" in exI, simp) - -instantiation Set_0 :: (null)bot -begin - - definition bot_Set_0_def: "(bot::('a::null) Set_0) \ Abs_Set_0 None" - - instance proof show "\x\'a Set_0. x \ bot" - apply(rule_tac x="Abs_Set_0 \None\" in exI) - apply(simp add:bot_Set_0_def) - apply(subst Abs_Set_0_inject) - apply(simp_all add: bot_Set_0_def - null_option_def bot_option_def) - done - qed -end - - -instantiation Set_0 :: (null)null -begin - - definition null_Set_0_def: "(null::('a::null) Set_0) \ Abs_Set_0 \ None \" - - instance proof show "(null::('a::null) Set_0) \ bot" - apply(simp add:null_Set_0_def bot_Set_0_def) - apply(subst Abs_Set_0_inject) - apply(simp_all add: bot_Set_0_def - null_option_def bot_option_def) - done - qed -end - - -text{* ... and lifting this type to the format of a valuation gives us:*} -type_synonym ('\,'\) Set = "('\, '\ Set_0) val" - -subsection{* Validity and Definedness Properties *} - -text{* Every element in a defined set is valid. *} - -lemma Set_inv_lemma: "\ \ (\ X) \ \x\\\Rep_Set_0 (X \)\\. x \ bot" -apply(insert Rep_Set_0 [of "X \"], simp) -apply(auto simp: OclValid_def defined_def false_def true_def cp_def - bot_fun_def bot_Set_0_def null_Set_0_def null_fun_def - split:split_if_asm) - apply(erule contrapos_pp [of "Rep_Set_0 (X \) = bot"]) - apply(subst Abs_Set_0_inject[symmetric], rule Rep_Set_0, simp) - apply(simp add: Rep_Set_0_inverse bot_Set_0_def bot_option_def) -apply(erule contrapos_pp [of "Rep_Set_0 (X \) = null"]) -apply(subst Abs_Set_0_inject[symmetric], rule Rep_Set_0, simp) -apply(simp add: Rep_Set_0_inverse null_option_def) -by (simp add: bot_option_def) - -lemma Set_inv_lemma' : - assumes x_def : "\ \ \ X" - and e_mem : "e \ \\Rep_Set_0 (X \)\\" - shows "\ \ \ (\_. e)" - apply(rule Set_inv_lemma[OF x_def, THEN ballE[where x = e]]) - apply(simp add: foundation18') -by(simp add: e_mem) - -lemma abs_rep_simp' : - assumes S_all_def : "\ \ \ S" - shows "Abs_Set_0 \\\\Rep_Set_0 (S \)\\\\ = S \" -proof - - have discr_eq_false_true : "\\. (false \ = true \) = False" by(simp add: false_def true_def) - show ?thesis - apply(insert S_all_def, simp add: OclValid_def defined_def) - apply(rule mp[OF Abs_Set_0_induct[where P = "\S. (if S = \ \ \ S = null \ - then false \ else true \) = true \ \ - Abs_Set_0 \\\\Rep_Set_0 S\\\\ = S"]], - rename_tac S') - apply(simp add: Abs_Set_0_inverse discr_eq_false_true) - apply(case_tac S') apply(simp add: bot_fun_def bot_Set_0_def)+ - apply(rename_tac S'', case_tac S'') apply(simp add: null_fun_def null_Set_0_def)+ - done -qed - -lemma S_lift' : - assumes S_all_def : "(\ :: '\ st) \ \ S" - shows "\S'. (\a (_::'\ st). a) ` \\Rep_Set_0 (S \)\\ = (\a (_::'\ st). \a\) ` S'" - apply(rule_tac x = "(\a. \a\) ` \\Rep_Set_0 (S \)\\" in exI) - apply(simp only: image_comp) - apply(simp add: comp_def) - apply(rule image_cong, fast) - (* *) - apply(drule Set_inv_lemma'[OF S_all_def]) -by(case_tac x, (simp add: bot_option_def foundation18')+) - -lemma invalid_set_OclNot_defined [simp,code_unfold]:"\(invalid::('\,'\::null) Set) = false" by simp -lemma null_set_OclNot_defined [simp,code_unfold]:"\(null::('\,'\::null) Set) = false" -by(simp add: defined_def null_fun_def) -lemma invalid_set_valid [simp,code_unfold]:"\(invalid::('\,'\::null) Set) = false" -by simp -lemma null_set_valid [simp,code_unfold]:"\(null::('\,'\::null) Set) = true" -apply(simp add: valid_def null_fun_def bot_fun_def bot_Set_0_def null_Set_0_def) -apply(subst Abs_Set_0_inject,simp_all add: null_option_def bot_option_def) -done - -text{* ... which means that we can have a type @{text "('\,('\,('\) Integer) Set) Set"} -corresponding exactly to Set(Set(Integer)) in OCL notation. Note that the parameter -@{text "'\"} still refers to the object universe; making the OCL semantics entirely parametric -in the object universe makes it possible to study (and prove) its properties -independently from a concrete class diagram. *} - -subsection{* Constants on Sets *} -definition mtSet::"('\,'\::null) Set" ("Set{}") -where "Set{} \ (\ \. Abs_Set_0 \\{}::'\ set\\ )" - - -lemma mtSet_defined[simp,code_unfold]:"\(Set{}) = true" -apply(rule ext, auto simp: mtSet_def defined_def null_Set_0_def - bot_Set_0_def bot_fun_def null_fun_def) -by(simp_all add: Abs_Set_0_inject bot_option_def null_Set_0_def null_option_def) - -lemma mtSet_valid[simp,code_unfold]:"\(Set{}) = true" -apply(rule ext,auto simp: mtSet_def valid_def null_Set_0_def - bot_Set_0_def bot_fun_def null_fun_def) -by(simp_all add: Abs_Set_0_inject bot_option_def null_Set_0_def null_option_def) - -lemma mtSet_rep_set: "\\Rep_Set_0 (Set{} \)\\ = {}" - apply(simp add: mtSet_def, subst Abs_Set_0_inverse) -by(simp add: bot_option_def)+ - -lemma [simp,code_unfold]: "const Set{}" -by(simp add: const_def mtSet_def) - - -text{* Note that the collection types in OCL allow for null to be included; - however, there is the null-collection into which inclusion yields invalid. *} - -section{* Complex Types: The Set-Collection Type (II) Library *} - -text{* This part provides a collection of operators for the Set type. *} - -subsection{* Computational Operations on Set *} - -subsubsection{* Definition *} - -definition OclIncluding :: "[('\,'\::null) Set,('\,'\) val] \ ('\,'\) Set" -where "OclIncluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then Abs_Set_0 \\ \\Rep_Set_0 (x \)\\ \ {y \} \\ - else \ )" -notation OclIncluding ("_->including'(_')") - -syntax - "_OclFinset" :: "args => ('\,'a::null) Set" ("Set{(_)}") -translations - "Set{x, xs}" == "CONST OclIncluding (Set{xs}) x" - "Set{x}" == "CONST OclIncluding (Set{}) x " - -definition OclExcluding :: "[('\,'\::null) Set,('\,'\) val] \ ('\,'\) Set" -where "OclExcluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then Abs_Set_0 \\ \\Rep_Set_0 (x \)\\ - {y \} \\ - else \ )" -notation OclExcluding ("_->excluding'(_')") - -definition OclIncludes :: "[('\,'\::null) Set,('\,'\) val] \ '\ Boolean" -where "OclIncludes x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then \\(y \) \ \\Rep_Set_0 (x \)\\ \\ - else \ )" -notation OclIncludes ("_->includes'(_')" (*[66,65]65*)) - -definition OclExcludes :: "[('\,'\::null) Set,('\,'\) val] \ '\ Boolean" -where "OclExcludes x y = (not(OclIncludes x y))" -notation OclExcludes ("_->excludes'(_')" (*[66,65]65*)) - -text{* The case of the size definition is somewhat special, we admit -explicitly in Featherweight OCL the possibility of infinite sets. For -the size definition, this requires an extra condition that assures -that the cardinality of the set is actually a defined integer. *} - -definition OclSize :: "('\,'\::null)Set \ '\ Integer" -where "OclSize x = (\ \. if (\ x) \ = true \ \ finite(\\Rep_Set_0 (x \)\\) - then \\ int(card \\Rep_Set_0 (x \)\\) \\ - else \ )" -notation (* standard ascii syntax *) - OclSize ("_->size'(')" (*[66]*)) - -text{* The following definition follows the requirement of the -standard to treat null as neutral element of sets. It is -a well-documented exception from the general strictness -rule and the rule that the distinguished argument self should -be non-null. *} -definition OclIsEmpty :: "('\,'\::null) Set \ '\ Boolean" -where "OclIsEmpty x = ((\ x and not (\ x)) or ((OclSize x) \ \))" -notation OclIsEmpty ("_->isEmpty'(')" (*[66]*)) - -definition OclNotEmpty :: "('\,'\::null) Set \ '\ Boolean" -where "OclNotEmpty x = not(OclIsEmpty x)" -notation OclNotEmpty ("_->notEmpty'(')" (*[66]*)) - -(* Slight breach of naming convention in order to avoid naming conflict on constant.*) -definition OclANY :: "[('\,'\::null) Set] \ ('\,'\) val" -where "OclANY x = (\ \. if (\ x) \ = true \ - then if (\ x and OclNotEmpty x) \ = true \ - then SOME y. y \ \\Rep_Set_0 (x \)\\ - else null \ - else \ )" -notation OclANY ("_->any'(')") -(* actually, this definition covers only: X->any(true) of the standard, which foresees -a (totally correct) high-level definition -source->any(iterator | body) = -source->select(iterator | body)->asSequence()->first(). Since we don't have sequences, -we have to go for a direct---restricted---definition. *) - - -text{* The definition of OclForall mimics the one of @{term "OclAnd"}: -OclForall is not a strict operation. *} -definition OclForall :: "[('\,'\::null)Set,('\,'\)val\('\)Boolean] \ '\ Boolean" -where "OclForall S P = (\ \. if (\ S) \ = true \ - then if (\x\\\Rep_Set_0 (S \)\\. P(\ _. x) \ = false \) - then false \ - else if (\x\\\Rep_Set_0 (S \)\\. P(\ _. x) \ = \ \) - then \ \ - else if (\x\\\Rep_Set_0 (S \)\\. P(\ _. x) \ = null \) - then null \ - else true \ - else \)" -syntax - "_OclForall" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->forAll'(_|_')") -translations - "X->forAll(x | P)" == "CONST OclForall X (%x. P)" - -text{* Like OclForall, OclExists is also not strict. *} -definition OclExists :: "[('\,'\::null) Set,('\,'\)val\('\)Boolean] \ '\ Boolean" -where "OclExists S P = not(OclForall S (\ X. not (P X)))" - -syntax - "_OclExist" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->exists'(_|_')") -translations - "X->exists(x | P)" == "CONST OclExists X (%x. P)" - -definition OclIterate :: "[('\,'\::null) Set,('\,'\::null)val, - ('\,'\)val\('\,'\)val\('\,'\)val] \ ('\,'\)val" -where "OclIterate S A F = (\ \. if (\ S) \ = true \ \ (\ A) \ = true \ \ finite\\Rep_Set_0 (S \)\\ - then (Finite_Set.fold (F) (A) ((\a \. a) ` \\Rep_Set_0 (S \)\\))\ - else \)" -syntax - "_OclIterate" :: "[('\,'\::null) Set, idt, idt, '\, '\] => ('\,'\)val" - ("_ ->iterate'(_;_=_ | _')" (*[71,100,70]50*)) -translations - "X->iterate(a; x = A | P)" == "CONST OclIterate X A (%a. (% x. P))" - -definition OclSelect :: "[('\,'\::null)Set,('\,'\)val\('\)Boolean] \ ('\,'\)Set" -where "OclSelect S P = (\\. if (\ S) \ = true \ - then if (\x\\\Rep_Set_0 (S \)\\. P(\ _. x) \ = \ \) - then \ - else Abs_Set_0 \\{x\\\ Rep_Set_0 (S \)\\. P (\_. x) \ \ false \}\\ - else \)" -syntax - "_OclSelect" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->select'(_|_')") -translations - "X->select(x | P)" == "CONST OclSelect X (% x. P)" - -definition OclReject :: "[('\,'\::null)Set,('\,'\)val\('\)Boolean] \ ('\,'\::null)Set" -where "OclReject S P = OclSelect S (not o P)" -syntax - "_OclReject" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->reject'(_|_')") -translations - "X->reject(x | P)" == "CONST OclReject X (% x. P)" - -subsubsection{* Definition (futur operators) *} - -consts (* abstract set collection operations *) - OclCount :: "[('\,'\::null) Set,('\,'\) Set] \ '\ Integer" - OclSum :: " ('\,'\::null) Set \ '\ Integer" - OclIncludesAll :: "[('\,'\::null) Set,('\,'\) Set] \ '\ Boolean" - OclExcludesAll :: "[('\,'\::null) Set,('\,'\) Set] \ '\ Boolean" - OclComplement :: " ('\,'\::null) Set \ ('\,'\) Set" - OclUnion :: "[('\,'\::null) Set,('\,'\) Set] \ ('\,'\) Set" - OclIntersection:: "[('\,'\::null) Set,('\,'\) Set] \ ('\,'\) Set" - -notation - OclCount ("_->count'(_')" (*[66,65]65*)) -notation - OclSum ("_->sum'(')" (*[66]*)) -notation - OclIncludesAll ("_->includesAll'(_')" (*[66,65]65*)) -notation - OclExcludesAll ("_->excludesAll'(_')" (*[66,65]65*)) -notation - OclComplement ("_->complement'(')") -notation - OclUnion ("_->union'(_')" (*[66,65]65*)) -notation - OclIntersection("_->intersection'(_')" (*[71,70]70*)) - -subsection{* Validity and Definedness Properties *} - -subsubsection{* OclIncluding *} - -lemma OclIncluding_defined_args_valid: -"(\ \ \(X->including(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -proof - - have A : "\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: bot_option_def) - have B : "\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(simp add: null_option_def bot_option_def) - have C : "(\ \(\ X)) \ (\ \(\ x)) \ - \\insert (x \) \\Rep_Set_0 (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(frule Set_inv_lemma, simp add: foundation18 invalid_def) - have D: "(\ \ \(X->including(x))) \ ((\ \(\ X)) \ (\ \(\ x)))" - by(auto simp: OclIncluding_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - have E: "(\ \(\ X)) \ (\ \(\ x)) \ (\ \ \(X->including(x)))" - apply(subst OclIncluding_def, subst OclValid_def, subst defined_def) - apply(auto simp: OclValid_def null_Set_0_def bot_Set_0_def null_fun_def bot_fun_def) - apply(frule Abs_Set_0_inject[OF C A, simplified OclValid_def, THEN iffD1], - simp_all add: bot_option_def) - apply(frule Abs_Set_0_inject[OF C B, simplified OclValid_def, THEN iffD1], - simp_all add: bot_option_def) - done -show ?thesis by(auto dest:D intro:E) -qed - - - -lemma OclIncluding_valid_args_valid: -"(\ \ \(X->including(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -proof - - have D: "(\ \ \(X->including(x))) \ ((\ \(\ X)) \ (\ \(\ x)))" - by(auto simp: OclIncluding_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - have E: "(\ \(\ X)) \ (\ \(\ x)) \ (\ \ \(X->including(x)))" - by(simp add: foundation20 OclIncluding_defined_args_valid) -show ?thesis by(auto dest:D intro:E) -qed - -lemma OclIncluding_defined_args_valid'[simp,code_unfold]: -"\(X->including(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclIncluding_defined_args_valid foundation10 defined_and_I) - -lemma OclIncluding_valid_args_valid''[simp,code_unfold]: -"\(X->including(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclIncluding_valid_args_valid foundation10 defined_and_I) - - -subsubsection{* OclExcluding *} - -lemma OclExcluding_defined_args_valid: -"(\ \ \(X->excluding(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -proof - - have A : "\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: bot_option_def) - have B : "\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(simp add: null_option_def bot_option_def) - have C : "(\ \(\ X)) \ (\ \(\ x)) \ - \\\\Rep_Set_0 (X \)\\ - {x \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(frule Set_inv_lemma, simp add: foundation18 invalid_def) - have D: "(\ \ \(X->excluding(x))) \ ((\ \(\ X)) \ (\ \(\ x)))" - by(auto simp: OclExcluding_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - have E: "(\ \(\ X)) \ (\ \(\ x)) \ (\ \ \(X->excluding(x)))" - apply(subst OclExcluding_def, subst OclValid_def, subst defined_def) - apply(auto simp: OclValid_def null_Set_0_def bot_Set_0_def null_fun_def bot_fun_def) - apply(frule Abs_Set_0_inject[OF C A, simplified OclValid_def, THEN iffD1], - simp_all add: bot_option_def) - apply(frule Abs_Set_0_inject[OF C B, simplified OclValid_def, THEN iffD1], - simp_all add: bot_option_def) - done -show ?thesis by(auto dest:D intro:E) -qed - - -lemma OclExcluding_valid_args_valid: -"(\ \ \(X->excluding(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -proof - - have D: "(\ \ \(X->excluding(x))) \ ((\ \(\ X)) \ (\ \(\ x)))" - by(auto simp: OclExcluding_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - have E: "(\ \(\ X)) \ (\ \(\ x)) \ (\ \ \(X->excluding(x)))" - by(simp add: foundation20 OclExcluding_defined_args_valid) -show ?thesis by(auto dest:D intro:E) -qed - - -lemma OclExcluding_valid_args_valid'[simp,code_unfold]: -"\(X->excluding(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclExcluding_defined_args_valid foundation10 defined_and_I) - - -lemma OclExcluding_valid_args_valid''[simp,code_unfold]: -"\(X->excluding(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclExcluding_valid_args_valid foundation10 defined_and_I) - -subsubsection{* OclIncludes *} - -lemma OclIncludes_defined_args_valid: -"(\ \ \(X->includes(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -proof - - have A: "(\ \ \(X->includes(x))) \ ((\ \(\ X)) \ (\ \(\ x)))" - by(auto simp: OclIncludes_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - have B: "(\ \(\ X)) \ (\ \(\ x)) \ (\ \ \(X->includes(x)))" - by(auto simp: OclIncludes_def OclValid_def true_def false_def StrongEq_def - defined_def invalid_def valid_def bot_fun_def null_fun_def - bot_option_def null_option_def - split: bool.split_asm HOL.split_if_asm option.split) -show ?thesis by(auto dest:A intro:B) -qed - -lemma OclIncludes_valid_args_valid: -"(\ \ \(X->includes(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -proof - - have A: "(\ \ \(X->includes(x))) \ ((\ \(\ X)) \ (\ \(\ x)))" - by(auto simp: OclIncludes_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - have B: "(\ \(\ X)) \ (\ \(\ x)) \ (\ \ \(X->includes(x)))" - by(auto simp: OclIncludes_def OclValid_def true_def false_def StrongEq_def - defined_def invalid_def valid_def bot_fun_def null_fun_def - bot_option_def null_option_def - split: bool.split_asm HOL.split_if_asm option.split) -show ?thesis by(auto dest:A intro:B) -qed - -lemma OclIncludes_valid_args_valid'[simp,code_unfold]: -"\(X->includes(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclIncludes_defined_args_valid foundation10 defined_and_I) - -lemma OclIncludes_valid_args_valid''[simp,code_unfold]: -"\(X->includes(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclIncludes_valid_args_valid foundation10 defined_and_I) - -subsubsection{* OclExcludes *} - -lemma OclExcludes_defined_args_valid: -"(\ \ \(X->excludes(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -by (metis (hide_lams, no_types) - OclExcludes_def OclAnd_idem OclOr_def OclOr_idem defined_not_I OclIncludes_defined_args_valid) - -lemma OclExcludes_valid_args_valid: -"(\ \ \(X->excludes(x))) = ((\ \(\ X)) \ (\ \(\ x)))" -by (metis (hide_lams, no_types) - OclExcludes_def OclAnd_idem OclOr_def OclOr_idem valid_not_I OclIncludes_valid_args_valid) - -lemma OclExcludes_valid_args_valid'[simp,code_unfold]: -"\(X->excludes(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclExcludes_defined_args_valid foundation10 defined_and_I) - -lemma OclExcludes_valid_args_valid''[simp,code_unfold]: -"\(X->excludes(x)) = ((\ X) and (\ x))" -by(auto intro!: transform2_rev simp:OclExcludes_valid_args_valid foundation10 defined_and_I) - -subsubsection{* OclSize *} - -lemma OclSize_defined_args_valid: "\ \ \ (X->size()) \ \ \ \ X" -by(auto simp: OclSize_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - -lemma OclSize_infinite: -assumes non_finite:"\ \ not(\(S->size()))" -shows "(\ \ not(\(S))) \ \ finite \\Rep_Set_0 (S \)\\" -apply(insert non_finite, simp) -apply(rule impI) -apply(simp add: OclSize_def OclValid_def defined_def) -apply(case_tac "finite \\Rep_Set_0 (S \)\\", - simp_all add:null_fun_def null_option_def bot_fun_def bot_option_def) -done - -lemma "\ \ \ X \ \ finite \\Rep_Set_0 (X \)\\ \ \ \ \ \ (X->size())" -by(simp add: OclSize_def OclValid_def defined_def bot_fun_def false_def true_def) - -lemma size_defined: - assumes X_finite: "\\. finite \\Rep_Set_0 (X \)\\" - shows "\ (X->size()) = \ X" - apply(rule ext, simp add: cp_defined[of "X->size()"] OclSize_def) - apply(simp add: defined_def bot_option_def bot_fun_def null_option_def null_fun_def X_finite) -done - -lemma size_defined': - assumes X_finite: "finite \\Rep_Set_0 (X \)\\" - shows "(\ \ \ (X->size())) = (\ \ \ X)" - apply(simp add: cp_defined[of "X->size()"] OclSize_def OclValid_def) - apply(simp add: defined_def bot_option_def bot_fun_def null_option_def null_fun_def X_finite) -done - -subsubsection{* OclIsEmpty *} - -lemma OclIsEmpty_defined_args_valid:"\ \ \ (X->isEmpty()) \ \ \ \ X" - apply(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def - bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def - split: split_if_asm) - apply(case_tac "(X->size() \ \) \", simp add: bot_option_def, simp, rename_tac x) - apply(case_tac x, simp add: null_option_def bot_option_def, simp) - apply(simp add: OclSize_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def) -by (metis (hide_lams, no_types) - OCL_core.bot_fun_def OclValid_def defined_def foundation2 invalid_def) - -lemma "\ \ \ (null->isEmpty())" -by(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def - bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def null_is_valid - split: split_if_asm) - -lemma OclIsEmpty_infinite: "\ \ \ X \ \ finite \\Rep_Set_0 (X \)\\ \ \ \ \ \ (X->isEmpty())" - apply(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def - bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def - split: split_if_asm) - apply(case_tac "(X->size() \ \) \", simp add: bot_option_def, simp, rename_tac x) - apply(case_tac x, simp add: null_option_def bot_option_def, simp) -by(simp add: OclSize_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def bot_fun_def false_def true_def invalid_def) - -subsubsection{* OclNotEmpty *} - -lemma OclNotEmpty_defined_args_valid:"\ \ \ (X->notEmpty()) \ \ \ \ X" -by (metis (hide_lams, no_types) OclNotEmpty_def OclNot_defargs OclNot_not foundation6 foundation9 - OclIsEmpty_defined_args_valid) - -lemma "\ \ \ (null->notEmpty())" -by (metis (hide_lams, no_types) OclNotEmpty_def OclAnd_false1 OclAnd_idem OclIsEmpty_def - OclNot3 OclNot4 OclOr_def defined2 defined4 transform1 valid2) - -lemma OclNotEmpty_infinite: "\ \ \ X \ \ finite \\Rep_Set_0 (X \)\\ \ \ \ \ \ (X->notEmpty())" - apply(simp add: OclNotEmpty_def) - apply(drule OclIsEmpty_infinite, simp) -by (metis OclNot_defargs OclNot_not foundation6 foundation9) - -lemma OclNotEmpty_has_elt : "\ \ \ X \ - \ \ X->notEmpty() \ - \e. e \ \\Rep_Set_0 (X \)\\" - apply(simp add: OclNotEmpty_def OclIsEmpty_def deMorgan1 deMorgan2, drule foundation5) - apply(subst (asm) (2) OclNot_def, - simp add: OclValid_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def - split: split_if_asm) - prefer 2 - apply(simp add: invalid_def bot_option_def true_def) - apply(simp add: OclSize_def valid_def split: split_if_asm, - simp_all add: false_def true_def bot_option_def bot_fun_def OclInt0_def) -by (metis equals0I) - -subsubsection{* OclANY *} - -lemma OclANY_defined_args_valid: "\ \ \ (X->any()) \ \ \ \ X" -by(auto simp: OclANY_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def OclAnd_def - split: bool.split_asm HOL.split_if_asm option.split) - -lemma "\ \ \ X \ \ \ X->isEmpty() \ \ \ \ \ (X->any())" - apply(simp add: OclANY_def OclValid_def) - apply(subst cp_defined, subst cp_OclAnd, simp add: OclNotEmpty_def, subst (1 2) cp_OclNot, - simp add: cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_defined[symmetric], - simp add: false_def true_def) -by(drule foundation20[simplified OclValid_def true_def], simp) - -lemma OclANY_valid_args_valid: -"(\ \ \(X->any())) = (\ \ \ X)" -proof - - have A: "(\ \ \(X->any())) \ ((\ \(\ X)))" - by(auto simp: OclANY_def OclValid_def true_def valid_def false_def StrongEq_def - defined_def invalid_def bot_fun_def null_fun_def - split: bool.split_asm HOL.split_if_asm option.split) - have B: "(\ \(\ X)) \ (\ \ \(X->any()))" - apply(auto simp: OclANY_def OclValid_def true_def false_def StrongEq_def - defined_def invalid_def valid_def bot_fun_def null_fun_def - bot_option_def null_option_def null_is_valid - OclAnd_def - split: bool.split_asm HOL.split_if_asm option.split) - apply(frule Set_inv_lemma[OF foundation16[THEN iffD2], OF conjI], simp) - apply(subgoal_tac "(\ X) \ = true \") - prefer 2 - apply (metis (hide_lams, no_types) OclValid_def foundation16) - apply(simp add: true_def, - drule OclNotEmpty_has_elt[simplified OclValid_def true_def], simp) - by(erule exE, - insert someI2[where Q = "\x. x \ \" and P = "\y. y \ \\Rep_Set_0 (X \)\\"], - simp) - show ?thesis by(auto dest:A intro:B) -qed - -lemma OclANY_valid_args_valid''[simp,code_unfold]: -"\(X->any()) = (\ X)" -by(auto intro!: OclANY_valid_args_valid transform2_rev) - -(* and higher order ones : forall, exists, iterate, select, reject... *) - -subsection{* Execution with Invalid or Null or Infinite Set as Argument *} - - -subsubsection{* OclIncluding *} - -lemma OclIncluding_invalid[simp,code_unfold]:"(invalid->including(x)) = invalid" -by(simp add: bot_fun_def OclIncluding_def invalid_def defined_def valid_def false_def true_def) - -lemma OclIncluding_invalid_args[simp,code_unfold]:"(X->including(invalid)) = invalid" -by(simp add: OclIncluding_def invalid_def bot_fun_def defined_def valid_def false_def true_def) - -lemma OclIncluding_null[simp,code_unfold]:"(null->including(x)) = invalid" -by(simp add: OclIncluding_def invalid_def bot_fun_def defined_def valid_def false_def true_def) - - -subsubsection{* OclExcluding *} - -lemma OclExcluding_invalid[simp,code_unfold]:"(invalid->excluding(x)) = invalid" -by(simp add: bot_fun_def OclExcluding_def invalid_def defined_def valid_def false_def true_def) - -lemma OclExcluding_invalid_args[simp,code_unfold]:"(X->excluding(invalid)) = invalid" -by(simp add: OclExcluding_def invalid_def bot_fun_def defined_def valid_def false_def true_def) - -lemma OclExcluding_null[simp,code_unfold]:"(null->excluding(x)) = invalid" -by(simp add: OclExcluding_def invalid_def bot_fun_def defined_def valid_def false_def true_def) - -subsubsection{* OclIncludes *} - -lemma OclIncludes_invalid[simp,code_unfold]:"(invalid->includes(x)) = invalid" -by(simp add: bot_fun_def OclIncludes_def invalid_def defined_def valid_def false_def true_def) - -lemma OclIncludes_invalid_args[simp,code_unfold]:"(X->includes(invalid)) = invalid" -by(simp add: OclIncludes_def invalid_def bot_fun_def defined_def valid_def false_def true_def) - -lemma OclIncludes_null[simp,code_unfold]:"(null->includes(x)) = invalid" -by(simp add: OclIncludes_def invalid_def bot_fun_def defined_def valid_def false_def true_def) - -subsubsection{* OclExcludes *} - -lemma OclExcludes_invalid[simp,code_unfold]:"(invalid->excludes(x)) = invalid" -by(simp add: OclExcludes_def OclNot_def, simp add: invalid_def bot_option_def) - -lemma OclExcludes_invalid_args[simp,code_unfold]:"(X->excludes(invalid)) = invalid" -by(simp add: OclExcludes_def OclNot_def, simp add: invalid_def bot_option_def) - -lemma OclExcludes_null[simp,code_unfold]:"(null->excludes(x)) = invalid" -by(simp add: OclExcludes_def OclNot_def, simp add: invalid_def bot_option_def) - -subsubsection{* OclSize *} - -lemma OclSize_invalid[simp,code_unfold]:"(invalid->size()) = invalid" -by(simp add: bot_fun_def OclSize_def invalid_def defined_def valid_def false_def true_def) - -lemma OclSize_null[simp,code_unfold]:"(null->size()) = invalid" -by(rule ext, - simp add: bot_fun_def null_fun_def null_is_valid OclSize_def - invalid_def defined_def valid_def false_def true_def) - -subsubsection{* OclIsEmpty *} - -lemma OclIsEmpty_invalid[simp,code_unfold]:"(invalid->isEmpty()) = invalid" -by(simp add: OclIsEmpty_def) - -lemma OclIsEmpty_null[simp,code_unfold]:"(null->isEmpty()) = true" -by(simp add: OclIsEmpty_def) - -subsubsection{* OclNotEmpty *} - -lemma OclNotEmpty_invalid[simp,code_unfold]:"(invalid->notEmpty()) = invalid" -by(simp add: OclNotEmpty_def) - -lemma OclNotEmpty_null[simp,code_unfold]:"(null->notEmpty()) = false" -by(simp add: OclNotEmpty_def) - -subsubsection{* OclANY *} - -lemma OclANY_invalid[simp,code_unfold]:"(invalid->any()) = invalid" -by(simp add: bot_fun_def OclANY_def invalid_def defined_def valid_def false_def true_def) - -lemma OclANY_null[simp,code_unfold]:"(null->any()) = null" -by(simp add: OclANY_def false_def true_def) - -subsubsection{* OclForall *} - -lemma OclForall_invalid[simp,code_unfold]:"invalid->forAll(a| P a) = invalid" -by(simp add: bot_fun_def invalid_def OclForall_def defined_def valid_def false_def true_def) - -lemma OclForall_null[simp,code_unfold]:"null->forAll(a | P a) = invalid" -by(simp add: bot_fun_def invalid_def OclForall_def defined_def valid_def false_def true_def) - -subsubsection{* OclExists *} - -lemma OclExists_invalid[simp,code_unfold]:"invalid->exists(a| P a) = invalid" -by(simp add: OclExists_def) - -lemma OclExists_null[simp,code_unfold]:"null->exists(a | P a) = invalid" -by(simp add: OclExists_def) - -subsubsection{* OclIterate *} - -lemma OclIterate_invalid[simp,code_unfold]:"invalid->iterate(a; x = A | P a x) = invalid" -by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) - -lemma OclIterate_null[simp,code_unfold]:"null->iterate(a; x = A | P a x) = invalid" -by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) - - -lemma OclIterate_invalid_args[simp,code_unfold]:"S->iterate(a; x = invalid | P a x) = invalid" -by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) - -text{* An open question is this ... *} -lemma (*OclIterate_null_args[simp,code_unfold]:*) "S->iterate(a; x = null | P a x) = invalid" -oops -(* In the definition above, this does not hold in general. - And I believe, this is how it should be ... *) - -lemma OclIterate_infinite: -assumes non_finite: "\ \ not(\(S->size()))" -shows "(OclIterate S A F) \ = invalid \" -apply(insert non_finite [THEN OclSize_infinite]) -apply(subst (asm) foundation9, simp) -by(metis OclIterate_def OclValid_def invalid_def) - -subsubsection{* OclSelect *} - -lemma OclSelect_invalid[simp,code_unfold]:"invalid->select(a | P a) = invalid" -by(simp add: bot_fun_def invalid_def OclSelect_def defined_def valid_def false_def true_def) - -lemma OclSelect_null[simp,code_unfold]:"null->select(a | P a) = invalid" -by(simp add: bot_fun_def invalid_def OclSelect_def defined_def valid_def false_def true_def) - -subsubsection{* OclReject *} - -lemma OclReject_invalid[simp,code_unfold]:"invalid->reject(a | P a) = invalid" -by(simp add: OclReject_def) - -lemma OclReject_null[simp,code_unfold]:"null->reject(a | P a) = invalid" -by(simp add: OclReject_def) - -subsection{* Context Passing *} - -lemma cp_OclIncluding: -"(X->including(x)) \ = ((\ _. X \)->including(\ _. x \)) \" -by(auto simp: OclIncluding_def StrongEq_def invalid_def - cp_defined[symmetric] cp_valid[symmetric]) - -lemma cp_OclExcluding: -"(X->excluding(x)) \ = ((\ _. X \)->excluding(\ _. x \)) \" -by(auto simp: OclExcluding_def StrongEq_def invalid_def - cp_defined[symmetric] cp_valid[symmetric]) - -lemma cp_OclIncludes: -"(X->includes(x)) \ = ((\ _. X \)->includes(\ _. x \)) \" -by(auto simp: OclIncludes_def StrongEq_def invalid_def - cp_defined[symmetric] cp_valid[symmetric]) - -lemma cp_OclIncludes1: -"(X->includes(x)) \ = (X->includes(\ _. x \)) \" -by(auto simp: OclIncludes_def StrongEq_def invalid_def - cp_defined[symmetric] cp_valid[symmetric]) - -lemma cp_OclExcludes: -"(X->excludes(x)) \ = ((\ _. X \)->excludes(\ _. x \)) \" -by(simp add: OclExcludes_def OclNot_def, subst cp_OclIncludes, simp) - -lemma cp_OclSize: "X->size() \ = ((\_. X \)->size()) \" -by(simp add: OclSize_def cp_defined[symmetric]) - -lemma cp_OclIsEmpty: "X->isEmpty() \ = ((\_. X \)->isEmpty()) \" - apply(simp only: OclIsEmpty_def) - apply(subst (2) cp_OclOr, - subst cp_OclAnd, - subst cp_OclNot, - subst cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r) -by(simp add: cp_defined[symmetric] cp_valid[symmetric] cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[symmetric] - cp_OclSize[symmetric] cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) - -lemma cp_OclNotEmpty: "X->notEmpty() \ = ((\_. X \)->notEmpty()) \" - apply(simp only: OclNotEmpty_def) - apply(subst (2) cp_OclNot) -by(simp add: cp_OclNot[symmetric] cp_OclIsEmpty[symmetric]) - -lemma cp_OclANY: "X->any() \ = ((\_. X \)->any()) \" - apply(simp only: OclANY_def) - apply(subst (2) cp_OclAnd) -by(simp only: cp_OclAnd[symmetric] cp_defined[symmetric] cp_valid[symmetric] - cp_OclNotEmpty[symmetric]) - -lemma cp_OclForall: -"(S->forAll(x | P x)) \ = ((\ _. S \)->forAll(x | P (\ _. x \))) \" -by(simp add: OclForall_def cp_defined[symmetric]) - -(* first-order version !*) -lemma cp_OclForall1 [simp,intro!]: -"cp S \ cp (\X. ((S X)->forAll(x | P x)))" -apply(simp add: cp_def) -apply(erule exE, rule exI, intro allI) -apply(erule_tac x=X in allE) -by(subst cp_OclForall, simp) - -lemma (*cp_OclForall2 [simp,intro!]:*) -"cp (\X St x. P (\\. x) X St) \ cp S \ cp (\X. (S X)->forAll(x|P x X)) " -apply(simp only: cp_def) -oops - -lemma (*cp_OclForall:*) -"cp S \ - (\ x. cp(P x)) \ - cp(\X. ((S X)->forAll(x | P x X)))" -oops - -(* - -lemma cp_OclForall2 [simp,intro!]: -"\ cp (\ X St.(\x. P (\\. x) X St)); - cp (S :: (('a,'c)VAL \ ('a,('b::bot))Set)) \ - \ cp(\X. \ Y \ S X \ P (Y\'a \ 'b) X) " -apply(simp only: cp_def OclForAll_def) -apply(erule exE)+ -apply(rule exI, rule allI, rule allI) -apply (simp only:) -apply(rule_tac t = "(\x. P (\\. x) X \ )" and - s = "f (X \ ) \ " in subst) -prefer 2 -ML{* Unify.search_bound:=1000; *} -apply(rule refl) -ML{* Unify.search_bound:=20; *} -(* Miracle ! This works. Definitively a unification problem !!! *) -apply simp -done (* temporary solution. *) - (* TODO: improve !!! *) - -*) - -lemma cp_OclExists: -"(S->exists(x | P x)) \ = ((\ _. S \)->exists(x | P (\ _. x \))) \" -by(simp add: OclExists_def OclNot_def, subst cp_OclForall, simp) - -(* first-order version !*) -lemma cp_OclExists1 [simp,intro!]: -"cp S \ cp (\X. ((S X)->exists(x | P x)))" -apply(simp add: cp_def) -apply(erule exE, rule exI, intro allI) -apply(erule_tac x=X in allE) -by(subst cp_OclExists,simp) - -lemma cp_OclIterate: "(X->iterate(a; x = A | P a x)) \ = - ((\ _. X \)->iterate(a; x = A | P a x)) \" -by(simp add: OclIterate_def cp_defined[symmetric]) - -lemma cp_OclSelect: "(X->select(a | P a)) \ = - ((\ _. X \)->select(a | P a)) \" -by(simp add: OclSelect_def cp_defined[symmetric]) - -lemma cp_OclReject: "(X->reject(a | P a)) \ = - ((\ _. X \)->reject(a | P a)) \" -by(simp add: OclReject_def, subst cp_OclSelect, simp) - -lemmas cp_intro''[intro!,simp,code_unfold] = - cp_intro' - cp_OclIncluding [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclIncluding"]] - cp_OclExcluding [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclExcluding"]] - cp_OclIncludes [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclIncludes"]] - cp_OclExcludes [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclExcludes"]] - cp_OclSize [THEN allI[THEN allI[THEN cpI1], of "OclSize"]] - cp_OclIsEmpty [THEN allI[THEN allI[THEN cpI1], of "OclIsEmpty"]] - cp_OclNotEmpty [THEN allI[THEN allI[THEN cpI1], of "OclNotEmpty"]] - cp_OclANY [THEN allI[THEN allI[THEN cpI1], of "OclANY"]] - -subsection{* Const *} - -lemma const_OclIncluding[simp,code_unfold] : - assumes const_x : "const x" - and const_S : "const S" - shows "const (S->including(x))" - proof - - have A:"\\ \'. \ (\ \ \ x) \ (S->including(x) \) = (S->including(x) \')" - apply(simp add: foundation18) - apply(erule const_subst[OF const_x const_invalid],simp_all) - by(rule const_charn[OF const_invalid]) - have B: "\ \ \'. \ (\ \ \ S) \ (S->including(x) \) = (S->including(x) \')" - apply(simp add: foundation16', elim disjE) - apply(erule const_subst[OF const_S const_invalid],simp_all) - apply(rule const_charn[OF const_invalid]) - apply(erule const_subst[OF const_S const_null],simp_all) - by(rule const_charn[OF const_invalid]) - show ?thesis - apply(simp only: const_def,intro allI, rename_tac \ \') - apply(case_tac "\ (\ \ \ x)", simp add: A) - apply(case_tac "\ (\ \ \ S)", simp_all add: B) - apply(frule_tac \'1= \' in const_OclValid2[OF const_x, THEN iffD1]) - apply(frule_tac \'1= \' in const_OclValid1[OF const_S, THEN iffD1]) - apply(simp add: OclIncluding_def OclValid_def) - apply(subst const_charn[OF const_x]) - apply(subst const_charn[OF const_S]) - by simp -qed - -section{* Fundamental Predicates on Set: Strict Equality *} - -subsection{* Definition *} - -text{* After the part of foundational operations on sets, we detail here equality on sets. -Strong equality is inherited from the OCL core, but we have to consider -the case of the strict equality. We decide to overload strict equality in the -same way we do for other value's in OCL:*} - -defs (overloaded) StrictRefEq\<^sub>S\<^sub>e\<^sub>t : - "(x::('\,'\::null)Set) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then (x \ y)\ - else invalid \" - -text{* One might object here that for the case of objects, this is an empty definition. -The answer is no, we will restrain later on states and objects such that any object -has its oid stored inside the object (so the ref, under which an object can be referenced -in the store will represented in the object itself). For such well-formed stores that satisfy -this invariant (the WFF-invariant), the referential equality and the -strong equality---and therefore the strict equality on sets in the sense above---coincides.*} - -subsection{* Logic and Algebraic Layer on Set *} - -subsubsection{* Reflexivity *} - -text{* To become operational, we derive: *} - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_refl[simp,code_unfold]: -"((x::('\,'\::null)Set) \ x) = (if (\ x) then true else invalid endif)" -by(rule ext, simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t OclIf_def) - -subsubsection{* Symmetry *} - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_sym: -"((x::('\,'\::null)Set) \ y) = (y \ x)" -by(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t, subst StrongEq_sym, rule ext, simp) - -subsubsection{* Execution with Invalid or Null as Argument *} - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strict1[simp,code_unfold]: "((x::('\,'\::null)Set) \ invalid)= invalid" -by(simp add:StrictRefEq\<^sub>S\<^sub>e\<^sub>t false_def true_def) - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strict2[simp,code_unfold]: "(invalid \ (y::('\,'\::null)Set))= invalid" -by(simp add:StrictRefEq\<^sub>S\<^sub>e\<^sub>t false_def true_def) - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strictEq_valid_args_valid: -"(\ \ \ ((x::('\,'\::null)Set) \ y)) = ((\ \ (\ x)) \ (\ \ \ y))" -proof - - have A: "\ \ \ (x \ y) \ \ \ \ x \ \ \ \ y" - apply(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t valid_def OclValid_def defined_def) - apply(simp add: invalid_def bot_fun_def split: split_if_asm) - done - have B: "(\ \ \ x) \ (\ \ \ y) \ \ \ \ (x \ y)" - apply(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t, elim conjE) - apply(drule foundation13[THEN iffD2],drule foundation13[THEN iffD2]) - apply(rule cp_validity[THEN iffD2]) - apply(subst cp_defined, simp add: foundation22) - apply(simp add: cp_defined[symmetric] cp_validity[symmetric]) - done - show ?thesis by(auto intro!: A B) -qed - -subsubsection{* Behavior vs StrongEq *} - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_vs_StrongEq: -"\ \ \ x \ \ \ \ y \ (\ \ (((x::('\,'\::null)Set) \ y) \ (x \ y)))" -apply(drule foundation13[THEN iffD2],drule foundation13[THEN iffD2]) -by(simp add:StrictRefEq\<^sub>S\<^sub>e\<^sub>t foundation22) - -subsubsection{* Context Passing *} - - -lemma cp_StrictRefEq\<^sub>S\<^sub>e\<^sub>t:"((X::('\,'\::null)Set) \ Y) \ = ((\_. X \) \ (\_. Y \)) \" -by(simp add:StrictRefEq\<^sub>S\<^sub>e\<^sub>t cp_StrongEq[symmetric] cp_valid[symmetric]) - - -subsubsection{* Const *} - -lemma const_StrictRefEq\<^sub>S\<^sub>e\<^sub>t : - assumes "const (X :: (_,_::null) Set)" - assumes "const X'" - shows "const (X \ X')" - apply(simp only: const_def, intro allI) - proof - - fix \1 \2 show "(X \ X') \1 = (X \ X') \2" - apply(simp only: StrictRefEq\<^sub>S\<^sub>e\<^sub>t) - by(simp add: const_valid[OF assms(1), simplified const_def, THEN spec, THEN spec, of \1 \2] - const_valid[OF assms(2), simplified const_def, THEN spec, THEN spec, of \1 \2] - const_true[simplified const_def, THEN spec, THEN spec, of \1 \2] - const_invalid[simplified const_def, THEN spec, THEN spec, of \1 \2] - const_StrongEq[OF assms, simplified const_def, THEN spec, THEN spec]) -qed - - -section{* Execution on Set's Operators (with mtSet and recursive case as arguments) *} - -subsection{* OclIncluding *} - -lemma OclIncluding_finite_rep_set : - assumes X_def : "\ \ \ X" - and x_val : "\ \ \ x" - shows "finite \\Rep_Set_0 (X->including(x) \)\\ = finite \\Rep_Set_0 (X \)\\" - proof - - have C : "\\insert (x \) \\Rep_Set_0 (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(insert X_def x_val, frule Set_inv_lemma, simp add: foundation18 invalid_def) - show "?thesis" - by(insert X_def x_val, - auto simp: OclIncluding_def Abs_Set_0_inverse[OF C] - dest: foundation13[THEN iffD2, THEN foundation22[THEN iffD1]]) -qed - -lemma OclIncluding_rep_set: - assumes S_def: "\ \ \ S" - shows "\\Rep_Set_0 (S->including(\_. \\x\\) \)\\ = insert \\x\\ \\Rep_Set_0 (S \)\\" - apply(simp add: OclIncluding_def S_def[simplified OclValid_def]) - apply(subst Abs_Set_0_inverse, simp add: bot_option_def null_option_def) - apply(insert Set_inv_lemma[OF S_def], metis bot_option_def not_Some_eq) -by(simp) - -lemma OclIncluding_notempty_rep_set: -assumes X_def: "\ \ \ X" - and a_val: "\ \ \ a" - shows "\\Rep_Set_0 (X->including(a) \)\\ \ {}" - apply(simp add: OclIncluding_def X_def[simplified OclValid_def] a_val[simplified OclValid_def]) - apply(subst Abs_Set_0_inverse, simp add: bot_option_def null_option_def) - apply(insert Set_inv_lemma[OF X_def], metis a_val foundation18') -by(simp) - -lemma OclIncluding_includes: - assumes "\ \ X->includes(x)" - shows "X->including(x) \ = X \" -proof - - have includes_def: "\ \ X->includes(x) \ \ \ \ X" - by (metis OCL_core.bot_fun_def OclIncludes_def OclValid_def defined3 foundation16) - - have includes_val: "\ \ X->includes(x) \ \ \ \ x" - by (metis (hide_lams, no_types) foundation6 - OclIncludes_valid_args_valid' OclIncluding_valid_args_valid OclIncluding_valid_args_valid'') - - show ?thesis - apply(insert includes_def[OF assms] includes_val[OF assms] assms, - simp add: OclIncluding_def OclIncludes_def OclValid_def true_def) - apply(drule insert_absorb, simp, subst abs_rep_simp') - by(simp_all add: OclValid_def true_def) -qed - - -subsection{* OclExcluding *} - -lemma OclExcluding_charn0[simp]: -assumes val_x:"\ \ (\ x)" -shows "\ \ ((Set{}->excluding(x)) \ Set{})" -proof - - have A : "\None\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(simp add: null_option_def bot_option_def) - have B : "\\{}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: mtSet_def) - - show ?thesis using val_x - apply(auto simp: OclValid_def OclIncludes_def OclNot_def false_def true_def StrongEq_def - OclExcluding_def mtSet_def defined_def bot_fun_def null_fun_def null_Set_0_def) - apply(auto simp: mtSet_def OCL_lib.Set_0.Abs_Set_0_inverse - OCL_lib.Set_0.Abs_Set_0_inject[OF B A]) - done -qed - - -lemma OclExcluding_charn0_exec[simp,code_unfold]: -"(Set{}->excluding(x)) = (if (\ x) then Set{} else invalid endif)" -proof - - have A: "\ \. (Set{}->excluding(invalid)) \ = (if (\ invalid) then Set{} else invalid endif) \" - by simp - have B: "\ \ x. \ \ (\ x) \ - (Set{}->excluding(x)) \ = (if (\ x) then Set{} else invalid endif) \" - by(simp add: OclExcluding_charn0[THEN foundation22[THEN iffD1]]) - show ?thesis - apply(rule ext, rename_tac \) - apply(case_tac "\ \ (\ x)") - apply(simp add: B) - apply(simp add: foundation18) - apply(subst cp_OclExcluding, simp) - apply(simp add: cp_OclIf[symmetric] cp_OclExcluding[symmetric] cp_valid[symmetric] A) - done -qed - -lemma OclExcluding_charn1: -assumes def_X:"\ \ (\ X)" -and val_x:"\ \ (\ x)" -and val_y:"\ \ (\ y)" -and neq :"\ \ not(x \ y)" -shows "\ \ ((X->including(x))->excluding(y)) \ ((X->excluding(y))->including(x))" -proof - - have C : "\\insert (x \) \\Rep_Set_0 (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) - have D : "\\\\Rep_Set_0 (X \)\\ - {y \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) - have E : "x \ \ y \" - by(insert neq, - auto simp: OclValid_def bot_fun_def OclIncluding_def OclIncludes_def - false_def true_def defined_def valid_def bot_Set_0_def - null_fun_def null_Set_0_def StrongEq_def OclNot_def) - - have G1 : "Abs_Set_0 \\insert (x \) \\Rep_Set_0 (X \)\\\\ \ Abs_Set_0 None" - by(insert C, simp add: Abs_Set_0_inject bot_option_def null_option_def) - have G2 : "Abs_Set_0 \\insert (x \) \\Rep_Set_0 (X \)\\\\ \ Abs_Set_0 \None\" - by(insert C, simp add: Abs_Set_0_inject bot_option_def null_option_def) - have G : "(\ (\_. Abs_Set_0 \\insert (x \) \\Rep_Set_0 (X \)\\\\)) \ = true \" - by(auto simp: OclValid_def false_def true_def defined_def - bot_fun_def bot_Set_0_def null_fun_def null_Set_0_def G1 G2) - - have H1 : "Abs_Set_0 \\\\Rep_Set_0 (X \)\\ - {y \}\\ \ Abs_Set_0 None" - by(insert D, simp add: Abs_Set_0_inject bot_option_def null_option_def) - have H2 : "Abs_Set_0 \\\\Rep_Set_0 (X \)\\ - {y \}\\ \ Abs_Set_0 \None\" - by(insert D, simp add: Abs_Set_0_inject bot_option_def null_option_def) - have H : "(\ (\_. Abs_Set_0 \\\\Rep_Set_0 (X \)\\ - {y \}\\)) \ = true \" - by(auto simp: OclValid_def false_def true_def defined_def - bot_fun_def bot_Set_0_def null_fun_def null_Set_0_def H1 H2) - - have Z : "insert (x \) \\Rep_Set_0 (X \)\\ - {y \} = insert (x \) (\\Rep_Set_0 (X \)\\ - {y \})" - by(auto simp: E) - show ?thesis - apply(insert def_X[THEN foundation13[THEN iffD2]] val_x[THEN foundation13[THEN iffD2]] - val_y[THEN foundation13[THEN iffD2]]) - apply(simp add: foundation22 OclIncluding_def OclExcluding_def def_X[THEN foundation17]) - apply(subst cp_defined, simp)+ - apply(simp add: G H Abs_Set_0_inverse[OF C] Abs_Set_0_inverse[OF D] Z) - done -qed - -lemma OclExcluding_charn2: -assumes def_X:"\ \ (\ X)" -and val_x:"\ \ (\ x)" -shows "\ \ (((X->including(x))->excluding(x)) \ (X->excluding(x)))" -proof - - have C : "\\insert (x \) \\Rep_Set_0 (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) - have G1 : "Abs_Set_0 \\insert (x \) \\Rep_Set_0 (X \)\\\\ \ Abs_Set_0 None" - by(insert C, simp add: Abs_Set_0_inject bot_option_def null_option_def) - have G2 : "Abs_Set_0 \\insert (x \) \\Rep_Set_0 (X \)\\\\ \ Abs_Set_0 \None\" - by(insert C, simp add: Abs_Set_0_inject bot_option_def null_option_def) - show ?thesis - apply(insert def_X[THEN foundation17] val_x[THEN foundation19]) - apply(auto simp: OclValid_def bot_fun_def OclIncluding_def OclIncludes_def false_def true_def - invalid_def defined_def valid_def bot_Set_0_def null_fun_def null_Set_0_def - StrongEq_def) - apply(subst cp_OclExcluding) - apply(auto simp:OclExcluding_def) - apply(simp add: Abs_Set_0_inverse[OF C]) - apply(simp_all add: false_def true_def defined_def valid_def - null_fun_def bot_fun_def null_Set_0_def bot_Set_0_def - split: bool.split_asm HOL.split_if_asm option.split) - apply(auto simp: G1 G2) - done -qed - -text{* One would like a generic theorem of the form: -\begin{isar}[mathescape] -lemma OclExcluding_charn_exec: - "(X->including(x::('$\mathfrak{A}$,'a::null)val)->excluding(y)) = - (if \ X then if x \ y - then X->excluding(y) - else X->excluding(y)->including(x) - endif - else invalid endif)" -\end{isar} -Unfortunately, this does not hold in general, since referential equality is -an overloaded concept and has to be defined for each type individually. -Consequently, it is only valid for concrete type instances for Boolean, -Integer, and Sets thereof... -*} - - -text{* The computational law \emph{OclExcluding-charn-exec} becomes generic since it -uses strict equality which in itself is generic. It is possible to prove -the following generic theorem and instantiate it later (using properties -that link the polymorphic logical strong equality with the concrete instance -of strict quality).*} -lemma OclExcluding_charn_exec: - assumes strict1: "(x \ invalid) = invalid" - and strict2: "(invalid \ y) = invalid" - and StrictRefEq_valid_args_valid: "\ (x::('\,'a::null)val) y \. - (\ \ \ (x \ y)) = ((\ \ (\ x)) \ (\ \ \ y))" - and cp_StrictRefEq: "\ (X::('\,'a::null)val) Y \. (X \ Y) \ = ((\_. X \) \ (\_. Y \)) \" - and StrictRefEq_vs_StrongEq: "\ (x::('\,'a::null)val) y \. - \ \ \ x \ \ \ \ y \ (\ \ ((x \ y) \ (x \ y)))" - shows "(X->including(x::('\,'a::null)val)->excluding(y)) = - (if \ X then if x \ y - then X->excluding(y) - else X->excluding(y)->including(x) - endif - else invalid endif)" -proof - - (* Lifting theorems, largely analogous OclIncludes_execute_generic, - with the same problems wrt. strict equality. *) - have A1: "\\. \ \ (X \ invalid) \ - (X->including(x)->includes(y)) \ = invalid \" - apply(rule foundation22[THEN iffD1]) - by(erule StrongEq_L_subst2_rev, simp,simp) - - have B1: "\\. \ \ (X \ null) \ - (X->including(x)->includes(y)) \ = invalid \" - apply(rule foundation22[THEN iffD1]) - by(erule StrongEq_L_subst2_rev, simp,simp) - - have A2: "\\. \ \ (X \ invalid) \ X->including(x)->excluding(y) \ = invalid \" - apply(rule foundation22[THEN iffD1]) - by(erule StrongEq_L_subst2_rev, simp,simp) - - have B2: "\\. \ \ (X \ null) \ X->including(x)->excluding(y) \ = invalid \" - apply(rule foundation22[THEN iffD1]) - by(erule StrongEq_L_subst2_rev, simp,simp) - - note [simp] = cp_StrictRefEq [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "StrictRefEq"]] - - have C: "\\. \ \ (x \ invalid) \ - (X->including(x)->excluding(y)) \ = - (if x \ y then X->excluding(y) else X->excluding(y)->including(x) endif) \" - apply(rule foundation22[THEN iffD1]) - apply(erule StrongEq_L_subst2_rev,simp,simp) - by(simp add: strict2) - - have D: "\\. \ \ (y \ invalid) \ - (X->including(x)->excluding(y)) \ = - (if x \ y then X->excluding(y) else X->excluding(y)->including(x) endif) \" - apply(rule foundation22[THEN iffD1]) - apply(erule StrongEq_L_subst2_rev,simp,simp) - by (simp add: strict1) - - have E: "\\. \ \ \ x \ \ \ \ y \ - (if x \ y then X->excluding(y) else X->excluding(y)->including(x) endif) \ = - (if x \ y then X->excluding(y) else X->excluding(y)->including(x) endif) \" - apply(subst cp_OclIf) - apply(subst StrictRefEq_vs_StrongEq[THEN foundation22[THEN iffD1]]) - by(simp_all add: cp_OclIf[symmetric]) - - have F: "\\. \ \ \ X \ \ \ \ x \ \ \ (x \ y) \ - (X->including(x)->excluding(y) \) = (X->excluding(y) \)" - apply(drule StrongEq_L_sym) - apply(rule foundation22[THEN iffD1]) - apply(erule StrongEq_L_subst2_rev,simp) - by(simp add: OclExcluding_charn2) - - show ?thesis - apply(rule ext, rename_tac "\") - apply(case_tac "\ (\ \ (\ X))", simp add:def_split_local,elim disjE A1 B1 A2 B2) - apply(case_tac "\ (\ \ (\ x))", - simp add:foundation18 foundation22[symmetric], - drule StrongEq_L_sym) - apply(simp add: foundation22 C) - apply(case_tac "\ (\ \ (\ y))", - simp add:foundation18 foundation22[symmetric], - drule StrongEq_L_sym, simp add: foundation22 D, simp) - apply(subst E,simp_all) - apply(case_tac "\ \ not (x \ y)") - apply(simp add: OclExcluding_charn1[simplified foundation22] - OclExcluding_charn2[simplified foundation22]) - apply(simp add: foundation9 F) - done -qed - -(* Hack to work around OF-Bug *) -schematic_lemma OclExcluding_charn_exec\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[simp,code_unfold]: "?X" -by(rule OclExcluding_charn_exec[OF StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict1 StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict2 - StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_defined_args_valid - cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_vs_StrongEq], simp_all) - -schematic_lemma OclExcluding_charn_exec\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[simp,code_unfold]: "?X" -by(rule OclExcluding_charn_exec[OF StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_strict1 StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_strict2 - StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_defined_args_valid - cp_StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_vs_StrongEq], simp_all) - -schematic_lemma OclExcluding_charn_exec\<^sub>S\<^sub>e\<^sub>t[simp,code_unfold]: "?X" -by(rule OclExcluding_charn_exec[OF StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strict1 StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strict2 - StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strictEq_valid_args_valid - cp_StrictRefEq\<^sub>S\<^sub>e\<^sub>t StrictRefEq\<^sub>S\<^sub>e\<^sub>t_vs_StrongEq], simp_all) - - -lemma OclExcluding_finite_rep_set : - assumes X_def : "\ \ \ X" - and x_val : "\ \ \ x" - shows "finite \\Rep_Set_0 (X->excluding(x) \)\\ = finite \\Rep_Set_0 (X \)\\" - proof - - have C : "\\\\Rep_Set_0 (X \)\\ - {x \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - apply(insert X_def x_val, frule Set_inv_lemma) - apply(simp add: foundation18 invalid_def) - done - show "?thesis" - by(insert X_def x_val, - auto simp: OclExcluding_def Abs_Set_0_inverse[OF C] - dest: foundation13[THEN iffD2, THEN foundation22[THEN iffD1]]) -qed - -lemma OclExcluding_rep_set: - assumes S_def: "\ \ \ S" - shows "\\Rep_Set_0 (S->excluding(\_. \\x\\) \)\\ = \\Rep_Set_0 (S \)\\ - {\\x\\}" - apply(simp add: OclExcluding_def S_def[simplified OclValid_def]) - apply(subst Abs_Set_0_inverse, simp add: bot_option_def null_option_def) - apply(insert Set_inv_lemma[OF S_def], metis Diff_iff bot_option_def not_None_eq) -by(simp) - -subsection{* OclIncludes *} - - -lemma OclIncludes_charn0[simp]: -assumes val_x:"\ \ (\ x)" -shows "\ \ not(Set{}->includes(x))" -using val_x -apply(auto simp: OclValid_def OclIncludes_def OclNot_def false_def true_def) -apply(auto simp: mtSet_def OCL_lib.Set_0.Abs_Set_0_inverse) -done - - -lemma OclIncludes_charn0'[simp,code_unfold]: -"Set{}->includes(x) = (if \ x then false else invalid endif)" -proof - - have A: "\ \. (Set{}->includes(invalid)) \ = (if (\ invalid) then false else invalid endif) \" - by simp - have B: "\ \ x. \ \ (\ x) \ (Set{}->includes(x)) \ = (if \ x then false else invalid endif) \" - apply(frule OclIncludes_charn0, simp add: OclValid_def) - apply(rule foundation21[THEN fun_cong, simplified StrongEq_def,simplified, - THEN iffD1, of _ _ "false"]) - by simp - show ?thesis - apply(rule ext, rename_tac \) - apply(case_tac "\ \ (\ x)") - apply(simp_all add: B foundation18) - apply(subst cp_OclIncludes, simp add: cp_OclIncludes[symmetric] A) - done -qed - -lemma OclIncludes_charn1: -assumes def_X:"\ \ (\ X)" -assumes val_x:"\ \ (\ x)" -shows "\ \ (X->including(x)->includes(x))" -proof - - have C : "\\insert (x \) \\Rep_Set_0 (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) - show ?thesis - apply(subst OclIncludes_def, simp add: foundation10[simplified OclValid_def] OclValid_def - def_X[simplified OclValid_def] val_x[simplified OclValid_def]) - apply(simp add: OclIncluding_def def_X[simplified OclValid_def] val_x[simplified OclValid_def] - Abs_Set_0_inverse[OF C] true_def) - done -qed - - - -lemma OclIncludes_charn2: -assumes def_X:"\ \ (\ X)" -and val_x:"\ \ (\ x)" -and val_y:"\ \ (\ y)" -and neq :"\ \ not(x \ y)" -shows "\ \ (X->including(x)->includes(y)) \ (X->includes(y))" -proof - - have C : "\\insert (x \) \\Rep_Set_0 (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) - show ?thesis - apply(subst OclIncludes_def, - simp add: def_X[simplified OclValid_def] val_x[simplified OclValid_def] - val_y[simplified OclValid_def] foundation10[simplified OclValid_def] - OclValid_def StrongEq_def) - apply(simp add: OclIncluding_def OclIncludes_def def_X[simplified OclValid_def] - val_x[simplified OclValid_def] val_y[simplified OclValid_def] - Abs_Set_0_inverse[OF C] true_def) - by(metis foundation22 foundation6 foundation9 neq) -qed - -text{* Here is again a generic theorem similar as above. *} - -lemma OclIncludes_execute_generic: -assumes strict1: "(x \ invalid) = invalid" -and strict2: "(invalid \ y) = invalid" -and cp_StrictRefEq: "\ (X::('\,'a::null)val) Y \. (X \ Y) \ = ((\_. X \) \ (\_. Y \)) \" -and StrictRefEq_vs_StrongEq: "\ (x::('\,'a::null)val) y \. - \ \ \ x \ \ \ \ y \ (\ \ ((x \ y) \ (x \ y)))" -shows - "(X->including(x::('\,'a::null)val)->includes(y)) = - (if \ X then if x \ y then true else X->includes(y) endif else invalid endif)" -proof - - have A: "\\. \ \ (X \ invalid) \ - (X->including(x)->includes(y)) \ = invalid \" - apply(rule foundation22[THEN iffD1]) - by(erule StrongEq_L_subst2_rev,simp,simp) - have B: "\\. \ \ (X \ null) \ - (X->including(x)->includes(y)) \ = invalid \" - apply(rule foundation22[THEN iffD1]) - by(erule StrongEq_L_subst2_rev,simp,simp) - - note [simp] = cp_StrictRefEq [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "StrictRefEq"]] - - have C: "\\. \ \ (x \ invalid) \ - (X->including(x)->includes(y)) \ = - (if x \ y then true else X->includes(y) endif) \" - apply(rule foundation22[THEN iffD1]) - apply(erule StrongEq_L_subst2_rev,simp,simp) - by (simp add: strict2) - have D:"\\. \ \ (y \ invalid) \ - (X->including(x)->includes(y)) \ = - (if x \ y then true else X->includes(y) endif) \" - apply(rule foundation22[THEN iffD1]) - apply(erule StrongEq_L_subst2_rev,simp,simp) - by (simp add: strict1) - have E: "\\. \ \ \ x \ \ \ \ y \ - (if x \ y then true else X->includes(y) endif) \ = - (if x \ y then true else X->includes(y) endif) \" - apply(subst cp_OclIf) - apply(subst StrictRefEq_vs_StrongEq[THEN foundation22[THEN iffD1]]) - by(simp_all add: cp_OclIf[symmetric]) - have F: "\\. \ \ (x \ y) \ - (X->including(x)->includes(y)) \ = (X->including(x)->includes(x)) \" - apply(rule foundation22[THEN iffD1]) - by(erule StrongEq_L_subst2_rev,simp, simp) - show ?thesis - apply(rule ext, rename_tac "\") - apply(case_tac "\ (\ \ (\ X))", simp add:def_split_local,elim disjE A B) - apply(case_tac "\ (\ \ (\ x))", - simp add:foundation18 foundation22[symmetric], - drule StrongEq_L_sym) - apply(simp add: foundation22 C) - apply(case_tac "\ (\ \ (\ y))", - simp add:foundation18 foundation22[symmetric], - drule StrongEq_L_sym, simp add: foundation22 D, simp) - apply(subst E,simp_all) - apply(case_tac "\ \ not(x \ y)") - apply(simp add: OclIncludes_charn2[simplified foundation22]) - apply(simp add: foundation9 F - OclIncludes_charn1[THEN foundation13[THEN iffD2], - THEN foundation22[THEN iffD1]]) - done -qed - - -(* Hack to work around OF-Bug *) -schematic_lemma OclIncludes_execute\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[simp,code_unfold]: "?X" -by(rule OclIncludes_execute_generic[OF StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict1 StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict2 - cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r - StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_vs_StrongEq], simp_all) - - -schematic_lemma OclIncludes_execute\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[simp,code_unfold]: "?X" -by(rule OclIncludes_execute_generic[OF StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_strict1 StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_strict2 - cp_StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n - StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n_vs_StrongEq], simp_all) - - -schematic_lemma OclIncludes_execute\<^sub>S\<^sub>e\<^sub>t[simp,code_unfold]: "?X" -by(rule OclIncludes_execute_generic[OF StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strict1 StrictRefEq\<^sub>S\<^sub>e\<^sub>t_strict2 - cp_StrictRefEq\<^sub>S\<^sub>e\<^sub>t - StrictRefEq\<^sub>S\<^sub>e\<^sub>t_vs_StrongEq], simp_all) - -lemma OclIncludes_including_generic : - assumes OclIncludes_execute_generic [simp] : "\X x y. - (X->including(x::('\,'a::null)val)->includes(y)) = - (if \ X then if x \ y then true else X->includes(y) endif else invalid endif)" - and StrictRefEq_strict'' : "\x y. \ ((x::('\,'a::null)val) \ y) = (\(x) and \(y))" - and a_val : "\ \ \ a" - and x_val : "\ \ \ x" - and S_incl : "\ \ (S)->includes((x::('\,'a::null)val))" - shows "\ \ S->including((a::('\,'a::null)val))->includes(x)" -proof - - have discr_eq_bot1_true : "\\. (\ \ = true \) = False" - by (metis OCL_core.bot_fun_def foundation1 foundation18' valid3) - have discr_eq_bot2_true : "\\. (\ = true \) = False" - by (metis bot_fun_def discr_eq_bot1_true) - have discr_neq_invalid_true : "\\. (invalid \ \ true \) = True" - by (metis discr_eq_bot2_true invalid_def) - have discr_eq_invalid_true : "\\. (invalid \ = true \) = False" - by (metis bot_option_def invalid_def option.simps(2) true_def) -show ?thesis - apply(simp) - apply(subgoal_tac "\ \ \ S") - prefer 2 - apply(insert S_incl[simplified OclIncludes_def], simp add: OclValid_def) - apply(metis discr_eq_bot2_true) - apply(simp add: cp_OclIf[of "\ S"] OclValid_def OclIf_def x_val[simplified OclValid_def] - discr_neq_invalid_true discr_eq_invalid_true) - by (metis OclValid_def S_incl StrictRefEq_strict'' a_val foundation10 foundation6 x_val) -qed - -lemmas OclIncludes_including\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r = - OclIncludes_including_generic[OF OclIncludes_execute\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict''] - -subsection{* OclExcludes *} - -subsection{* OclSize *} - -lemma [simp,code_unfold]: "Set{} ->size() = \" - apply(rule ext) - apply(simp add: defined_def mtSet_def OclSize_def - bot_Set_0_def bot_fun_def - null_Set_0_def null_fun_def) - apply(subst Abs_Set_0_inject, simp_all add: bot_option_def null_option_def) + -by(simp add: Abs_Set_0_inverse bot_option_def null_option_def OclInt0_def) - -lemma OclSize_including_exec[simp,code_unfold]: - "((X ->including(x)) ->size()) = (if \ X and \ x then - X ->size() `+ if X ->includes(x) then \ else \ endif - else - invalid - endif)" -proof - - - have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac "P \ = \", simp_all add: true_def) - have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) - - show ?thesis - apply(rule ext, rename_tac \) - proof - - fix \ - have includes_notin: "\ \ \ X->includes(x) \ (\ X) \ = true \ \ (\ x) \ = true \ \ - x \ \ \\Rep_Set_0 (X \)\\" - by(simp add: OclIncludes_def OclValid_def true_def) - - have includes_def: "\ \ X->includes(x) \ \ \ \ X" - by (metis OCL_core.bot_fun_def OclIncludes_def OclValid_def defined3 foundation16) - - have includes_val: "\ \ X->includes(x) \ \ \ \ x" - by (metis (hide_lams, no_types) foundation6 - OclIncludes_valid_args_valid' OclIncluding_valid_args_valid OclIncluding_valid_args_valid'') - - have ins_in_Set_0: "\ \ \ X \ \ \ \ x \ - \\insert (x \) \\Rep_Set_0 (X \)\\\\ \ {X. X = \ \ X = null \ (\x\\\X\\. x \ \)}" - apply(simp add: bot_option_def null_option_def) - by (metis (hide_lams, no_types) Set_inv_lemma foundation18' foundation5) - - show "X->including(x)->size() \ = (if \ X and \ x - then X->size() `+ if X->includes(x) then \ else \ endif - else invalid endif) \" - apply(case_tac "\ \ \ X and \ x", simp) - apply(subst cp_OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r) - apply(case_tac "\ \ X->includes(x)", simp add: cp_OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[symmetric]) - apply(case_tac "\ \ ((\ (X->size())) and not (\ (X->size())))", simp) - apply(drule foundation5[where P = "\ X->size()"], erule conjE) - apply(drule OclSize_infinite) - apply(frule includes_def, drule includes_val, simp) - apply(subst OclSize_def, subst OclIncluding_finite_rep_set, assumption+) - apply (metis (hide_lams, no_types) invalid_def) - - apply(subst OclIf_false', - metis (hide_lams, no_types) defined5 defined6 defined_and_I defined_not_I - foundation1 foundation9) - apply(subst cp_OclSize, simp add: OclIncluding_includes cp_OclSize[symmetric]) - (* *) - apply(subst OclIf_false', subst foundation9, - metis (hide_lams, no_types) OclIncludes_valid_args_valid', simp, simp add: OclSize_def) - apply(drule foundation5) - apply(subst (1 2) OclIncluding_finite_rep_set, fast+) - apply(subst (1 2) cp_OclAnd, subst (1 2) cp_OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r, simp) - apply(rule conjI) - apply(simp add: OclIncluding_def) - apply(subst Abs_Set_0_inverse[OF ins_in_Set_0], fast+) - apply(subst (asm) (2 3) OclValid_def, simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def OclInt1_def) - apply(rule impI) - apply(drule Finite_Set.card.insert[where x = "x \"]) - apply(rule includes_notin, simp, simp) - apply (metis Suc_eq_plus1 int_1 of_nat_add) - - - apply(subst (1 2) OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict2[simplified invalid_def], simp) - apply(subst OclIncluding_finite_rep_set, fast+, simp add: OclValid_def) - (* *) - apply(subst OclIf_false', metis (hide_lams, no_types) defined6 foundation1 foundation9 - OclExcluding_valid_args_valid'') - by (metis cp_OclSize foundation18' OclIncluding_valid_args_valid'' invalid_def OclSize_invalid) - qed -qed - -subsection{* OclIsEmpty *} - -lemma [simp,code_unfold]: "Set{}->isEmpty() = true" -by(simp add: OclIsEmpty_def) - -lemma OclIsEmpty_including [simp]: -assumes X_def: "\ \ \ X" - and X_finite: "finite \\Rep_Set_0 (X \)\\" - and a_val: "\ \ \ a" -shows "X->including(a)->isEmpty() \ = false \" -proof - - have A1 : "\\ X. X \ = true \ \ X \ = false \ \ (X and not X) \ = false \" - by (metis (no_types) OclAnd_false1 OclAnd_idem OclImplies_def OclNot3 OclNot_not OclOr_false1 - cp_OclAnd cp_OclNot deMorgan1 deMorgan2) - - have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) - - have B : "\X \. \ \ \ X \ X \ \ \ \ \ (X \ \) \ = false \" - by (metis OclAnd_true2 OclValid_def Sem_def foundation16 foundation22 valid4 - StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict' StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_strict'' - StrongEq_sym bool_split invalid_def null_fun_def null_non_OclInt0) - - show ?thesis - apply(simp add: OclIsEmpty_def del: OclSize_including_exec) - apply(subst cp_OclOr, subst A1) - apply(metis (hide_lams, no_types) defined_inject_true OclExcluding_valid_args_valid') - apply(simp add: cp_OclOr[symmetric] del: OclSize_including_exec) - apply(rule B, - rule foundation20, - metis (hide_lams, no_types) OclIncluding_defined_args_valid OclIncluding_finite_rep_set - X_def X_finite a_val size_defined') - apply(simp add: OclSize_def OclIncluding_finite_rep_set[OF X_def a_val] X_finite OclInt0_def) - by (metis OclValid_def X_def a_val foundation10 foundation6 - OclIncluding_notempty_rep_set[OF X_def a_val]) -qed - -subsection{* OclNotEmpty *} - -lemma [simp,code_unfold]: "Set{}->notEmpty() = false" -by(simp add: OclNotEmpty_def) - -lemma OclNotEmpty_including [simp,code_unfold]: -assumes X_def: "\ \ \ X" - and X_finite: "finite \\Rep_Set_0 (X \)\\" - and a_val: "\ \ \ a" -shows "X->including(a)->notEmpty() \ = true \" - apply(simp add: OclNotEmpty_def) - apply(subst cp_OclNot, subst OclIsEmpty_including, simp_all add: assms) -by (metis OclNot4 cp_OclNot) - -subsection{* OclANY *} - -lemma [simp,code_unfold]: "Set{}->any() = null" -by(rule ext, simp add: OclANY_def, simp add: false_def true_def) - -lemma OclANY_singleton_exec[simp,code_unfold]: - "(Set{}->including(a))->any() = a" - apply(rule ext, rename_tac \, simp add: mtSet_def OclANY_def) - apply(case_tac "\ \ \ a") - apply(simp add: OclValid_def mtSet_defined[simplified mtSet_def] - mtSet_valid[simplified mtSet_def] mtSet_rep_set[simplified mtSet_def]) - apply(subst (1 2) cp_OclAnd, - subst (1 2) OclNotEmpty_including[where X = "Set{}", simplified mtSet_def]) - apply(simp add: mtSet_defined[simplified mtSet_def]) - apply(metis (hide_lams, no_types) finite.emptyI mtSet_def mtSet_rep_set) - apply(simp add: OclValid_def) - apply(simp add: OclIncluding_def) - apply(rule conjI) - apply(subst (1 2) Abs_Set_0_inverse, simp add: bot_option_def null_option_def) - apply(simp, metis OclValid_def foundation18') - apply(simp) - apply(simp add: mtSet_defined[simplified mtSet_def]) - (* *) - apply(subgoal_tac "a \ = \") - prefer 2 - apply(simp add: OclValid_def valid_def bot_fun_def split: split_if_asm) - apply(simp) - apply(subst (1 2 3 4) cp_OclAnd, - simp add: mtSet_defined[simplified mtSet_def] valid_def bot_fun_def) -by(simp add: cp_OclAnd[symmetric], rule impI, simp add: false_def true_def) - -subsection{* OclForall *} - -lemma OclForall_mtSet_exec[simp,code_unfold] : -"((Set{})->forAll(z| P(z))) = true" -apply(simp add: OclForall_def) -apply(subst mtSet_def)+ -apply(subst Abs_Set_0_inverse, simp_all add: true_def)+ -done - -lemma OclForall_including_exec[simp,code_unfold] : - assumes cp0 : "cp P" - shows "((S->including(x))->forAll(z | P(z))) = (if \ S and \ x - then P x and (S->forAll(z | P(z))) - else invalid - endif)" -proof - - have cp: "\\. P x \ = P (\_. x \) \" - by(insert cp0, auto simp: cp_def) - - have insert_in_Set_0 : "\\. (\ \(\ S)) \ (\ \(\ x)) \ - \\insert (x \) \\Rep_Set_0 (S \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(frule Set_inv_lemma, simp add: foundation18 invalid_def) - - have forall_including_invert : "\\ f. (f x \ = f (\ _. x \) \) \ - \ \ (\ S and \ x) \ - (\x\\\Rep_Set_0 (S->including(x) \)\\. f (\_. x) \) = - (f x \ \ (\x\\\Rep_Set_0 (S \)\\. f (\_. x) \))" - apply(drule foundation5, simp add: OclIncluding_def) - apply(subst Abs_Set_0_inverse) - apply(rule insert_in_Set_0, fast+) - by(simp add: OclValid_def) - - have exists_including_invert : "\\ f. (f x \ = f (\ _. x \) \) \ - \ \ (\ S and \ x) \ - (\x\\\Rep_Set_0 (S->including(x) \)\\. f (\_. x) \) = - (f x \ \ (\x\\\Rep_Set_0 (S \)\\. f (\_. x) \))" - apply(subst arg_cong[where f = "\x. \x", - OF forall_including_invert[where f = "\x \. \ (f x \)"], - simplified]) - by simp_all - - have cp_eq : "\\ v. (P x \ = v) = (P (\_. x \) \ = v)" by(subst cp, simp) - have cp_OclNot_eq : "\\ v. (P x \ \ v) = (P (\_. x \) \ \ v)" by(subst cp, simp) - - have foundation10': "\\ x y. (\ \ x) \ (\ \ y) \ \ \ (x and y)" - apply(erule conjE, subst foundation10) - by((rule foundation6)?, simp)+ - - have contradict_Rep_Set_0: "\\ S f. - \x\\\Rep_Set_0 S\\. f (\_. x) \ \ - (\x\\\Rep_Set_0 S\\. \ (f (\_. x) \)) = False" - by(case_tac "(\x\\\Rep_Set_0 S\\. \ (f (\_. x) \)) = True", simp_all) - - show ?thesis - apply(rule ext, rename_tac \) - apply(simp add: OclIf_def) - apply(simp add: cp_defined[of "\ S and \ x"] cp_defined[THEN sym]) - apply(intro conjI impI) - - apply(subgoal_tac "\ \ \ S") - prefer 2 - apply(drule foundation5[simplified OclValid_def], erule conjE)+ apply(simp add: OclValid_def) - - apply(subst OclForall_def) - apply(simp add: cp_OclAnd[THEN sym] OclValid_def - foundation10'[where x = "\ S" and y = "\ x", simplified OclValid_def]) - - apply(subgoal_tac "\ \ (\ S and \ x)") - prefer 2 - apply(simp add: OclValid_def) - - (* false *) - (* false YES *) - apply(case_tac "\x\\\Rep_Set_0 (S->including(x) \)\\. P (\_. x) \ = false \", simp_all) - apply(subst contradict_Rep_Set_0[where f1 = "\ x \. P x \ = false \"], simp)+ - apply(simp add: exists_including_invert[where f = "\ x \. P x \ = false \", OF cp_eq]) - - apply(simp add: cp_OclAnd[of "P x"]) - apply(erule disjE) - apply(simp only: cp_OclAnd[symmetric], simp) - - apply(subgoal_tac "OclForall S P \ = false \") - apply(simp only: cp_OclAnd[symmetric], simp) - apply(simp add: OclForall_def) - - (* false NO *) - apply(simp add: forall_including_invert[where f = "\ x \. P x \ \ false \", OF cp_OclNot_eq], - erule conjE) - - (* bot *) - (* bot YES *) - apply(case_tac "\x\\\Rep_Set_0 (S->including(x) \)\\. P (\_. x) \ = bot \", simp_all) - apply(subst contradict_Rep_Set_0[where f1 = "\ x \. P x \ = bot \"], simp)+ - apply(simp add: exists_including_invert[where f = "\ x \. P x \ = bot \", OF cp_eq]) - - apply(simp add: cp_OclAnd[of "P x"]) - apply(erule disjE) - - apply(subgoal_tac "OclForall S P \ \ false \") - apply(simp only: cp_OclAnd[symmetric], simp) - apply(simp add: OclForall_def true_def false_def - null_fun_def null_option_def bot_fun_def bot_option_def) - - apply(subgoal_tac "OclForall S P \ = bot \") - apply(simp only: cp_OclAnd[symmetric], simp) - apply(simp add: OclForall_def true_def false_def - null_fun_def null_option_def bot_fun_def bot_option_def) - - (* bot NO *) - apply(simp add: forall_including_invert[where f = "\ x \. P x \ \ bot \", OF cp_OclNot_eq], - erule conjE) - - (* null *) - (* null YES *) - apply(case_tac "\x\\\Rep_Set_0 (S->including(x) \)\\. P (\_. x) \ = null \", simp_all) - apply(subst contradict_Rep_Set_0[where f1 = "\ x \. P x \ = null \"], simp)+ - apply(simp add: exists_including_invert[where f = "\ x \. P x \ = null \", OF cp_eq]) - - apply(simp add: cp_OclAnd[of "P x"]) - apply(erule disjE) - - apply(subgoal_tac "OclForall S P \ \ false \ \ OclForall S P \ \ bot \") - apply(simp only: cp_OclAnd[symmetric], simp) - apply(simp add: OclForall_def true_def false_def - null_fun_def null_option_def bot_fun_def bot_option_def) - - apply(subgoal_tac "OclForall S P \ = null \") - apply(simp only: cp_OclAnd[symmetric], simp) - apply(simp add: OclForall_def true_def false_def - null_fun_def null_option_def bot_fun_def bot_option_def) - - (* null NO *) - apply(simp add: forall_including_invert[where f = "\ x \. P x \ \ null \", OF cp_OclNot_eq], - erule conjE) - - (* true *) - apply(simp add: cp_OclAnd[of "P x"] OclForall_def) - apply(subgoal_tac "P x \ = true \", simp) - apply(metis bot_fun_def bool_split foundation18' foundation2 valid1) - - (* invalid *) - by(metis OclForall_def OclIncluding_defined_args_valid' invalid_def) -qed - -subsection{* OclExists *} - -lemma OclExists_mtSet_exec[simp,code_unfold] : -"((Set{})->exists(z | P(z))) = false" -by(simp add: OclExists_def) - -lemma OclExists_including_exec[simp,code_unfold] : - assumes cp: "cp P" - shows "((S->including(x))->exists(z | P(z))) = (if \ S and \ x - then P x or (S->exists(z | P(z))) - else invalid - endif)" - by(simp add: OclExists_def OclOr_def OclForall_including_exec cp OclNot_inject) - - -subsection{* OclIterate *} - -lemma OclIterate_empty[simp,code_unfold]: "((Set{})->iterate(a; x = A | P a x)) = A" -proof - - have C : "\ \. (\ (\\. Abs_Set_0 \\{}\\)) \ = true \" - by (metis (no_types) defined_def mtSet_def mtSet_defined null_fun_def) - show ?thesis - apply(simp add: OclIterate_def mtSet_def Abs_Set_0_inverse valid_def C) - apply(rule ext, rename_tac \) - apply(case_tac "A \ = \ \", simp_all, simp add:true_def false_def bot_fun_def) - apply(simp add: Abs_Set_0_inverse) - done -qed - -text{* In particular, this does hold for A = null. *} - -lemma OclIterate_including: -assumes S_finite: "\ \ \(S->size())" -and F_valid_arg: "(\ A) \ = (\ (F a A)) \" -and F_commute: "comp_fun_commute F" -and F_cp: "\ x y \. F x y \ = F (\ _. x \) y \" -shows "((S->including(a))->iterate(a; x = A | F a x)) \ = - ((S->excluding(a))->iterate(a; x = F a A | F a x)) \" -proof - - have insert_in_Set_0 : "\\. (\ \(\ S)) \ (\ \(\ a)) \ - \\insert (a \) \\Rep_Set_0 (S \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(frule Set_inv_lemma, simp add: foundation18 invalid_def) - - have insert_defined : "\\. (\ \(\ S)) \ (\ \(\ a)) \ - (\ (\_. Abs_Set_0 \\insert (a \) \\Rep_Set_0 (S \)\\\\)) \ = true \" - apply(subst defined_def) - apply(simp add: bot_Set_0_def bot_fun_def null_Set_0_def null_fun_def) - by(subst Abs_Set_0_inject, - rule insert_in_Set_0, simp_all add: null_option_def bot_option_def)+ - - have remove_finite : "finite \\Rep_Set_0 (S \)\\ \ - finite ((\a \. a) ` (\\Rep_Set_0 (S \)\\ - {a \}))" - by(simp) - - have remove_in_Set_0 : "\\. (\ \(\ S)) \ (\ \(\ a)) \ - \\\\Rep_Set_0 (S \)\\ - {a \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" - by(frule Set_inv_lemma, simp add: foundation18 invalid_def) - - have remove_defined : "\\. (\ \(\ S)) \ (\ \(\ a)) \ - (\ (\_. Abs_Set_0 \\\\Rep_Set_0 (S \)\\ - {a \}\\)) \ = true \" - apply(subst defined_def) - apply(simp add: bot_Set_0_def bot_fun_def null_Set_0_def null_fun_def) - by(subst Abs_Set_0_inject, - rule remove_in_Set_0, simp_all add: null_option_def bot_option_def)+ - - have abs_rep: "\x. \\x\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)} \ - \\Rep_Set_0 (Abs_Set_0 \\x\\)\\ = x" - by(subst Abs_Set_0_inverse, simp_all) - - have inject : "inj (\a \. a)" - by(rule inj_fun, simp) - - show ?thesis - apply(subst (1 2) cp_OclIterate, subst OclIncluding_def, subst OclExcluding_def) - apply(case_tac "\ ((\ S) \ = true \ \ (\ a) \ = true \)", simp) - - apply(subgoal_tac "OclIterate (\_. \) A F \ = OclIterate (\_. \) (F a A) F \", simp) - apply(rule conjI, blast+) - apply(simp add: OclIterate_def defined_def bot_option_def bot_fun_def false_def true_def) - - apply(simp add: OclIterate_def) - apply((subst abs_rep[OF insert_in_Set_0[simplified OclValid_def], of \], simp_all)+, - (subst abs_rep[OF remove_in_Set_0[simplified OclValid_def], of \], simp_all)+, - (subst insert_defined, simp_all add: OclValid_def)+, - (subst remove_defined, simp_all add: OclValid_def)+) - - apply(case_tac "\ ((\ A) \ = true \)", (simp add: F_valid_arg)+) - apply(rule impI, - subst Finite_Set.comp_fun_commute.fold_fun_left_comm[symmetric, OF F_commute], - rule remove_finite, simp) - - apply(subst image_set_diff[OF inject], simp) - apply(subgoal_tac "Finite_Set.fold F A (insert (\\'. a \) ((\a \. a) ` \\Rep_Set_0 (S \)\\)) \ = - F (\\'. a \) (Finite_Set.fold F A ((\a \. a) ` \\Rep_Set_0 (S \)\\ - {\\'. a \})) \") - apply(subst F_cp, simp) - - by(subst Finite_Set.comp_fun_commute.fold_insert_remove[OF F_commute], simp+) -qed - -subsection{* OclSelect *} - -lemma OclSelect_mtSet_exec[simp,code_unfold]: "OclSelect mtSet P = mtSet" - apply(rule ext, rename_tac \) - apply(simp add: OclSelect_def mtSet_def defined_def false_def true_def - bot_Set_0_def bot_fun_def null_Set_0_def null_fun_def) -by(( subst (1 2 3 4 5) Abs_Set_0_inverse - | subst Abs_Set_0_inject), (simp add: null_option_def bot_option_def)+)+ - -definition "OclSelect_body :: _ \ _ \ _ \ ('\, 'a option option) Set - \ (\P x acc. if P x \ false then acc else acc->including(x) endif)" - -lemma OclSelect_including_exec[simp,code_unfold]: - assumes P_cp : "cp P" - shows "OclSelect (X->including(y)) P = OclSelect_body P y (OclSelect (X->excluding(y)) P)" - (is "_ = ?select") -proof - - have P_cp: "\x \. P x \ = P (\_. x \) \" - by(insert P_cp, auto simp: cp_def) - - have ex_including : "\f X y \. \ \ \ X \ \ \ \ y \ - (\x\\\Rep_Set_0 (X->including(y) \)\\. f (P (\_. x)) \) = - (f (P (\_. y \)) \ \ (\x\\\Rep_Set_0 (X \)\\. f (P (\_. x)) \))" - apply(simp add: OclIncluding_def OclValid_def) - apply(subst Abs_Set_0_inverse, simp, (rule disjI2)+) - apply (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') - by(simp) - have al_including : "\f X y \. \ \ \ X \ \ \ \ y \ - (\x\\\Rep_Set_0 (X->including(y) \)\\. f (P (\_. x)) \) = - (f (P (\_. y \)) \ \ (\x\\\Rep_Set_0 (X \)\\. f (P (\_. x)) \))" - apply(simp add: OclIncluding_def OclValid_def) - apply(subst Abs_Set_0_inverse, simp, (rule disjI2)+) - apply (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') - by(simp) - have ex_excluding1 : "\f X y \. \ \ \ X \ \ \ \ y \ \ (f (P (\_. y \)) \) \ - (\x\\\Rep_Set_0 (X \)\\. f (P (\_. x)) \) = - (\x\\\Rep_Set_0 (X->excluding(y) \)\\. f (P (\_. x)) \)" - apply(simp add: OclExcluding_def OclValid_def) - apply(subst Abs_Set_0_inverse, simp, (rule disjI2)+) - apply (metis (no_types) Diff_iff OclValid_def Set_inv_lemma) - by(auto) - have al_excluding1 : "\f X y \. \ \ \ X \ \ \ \ y \ f (P (\_. y \)) \ \ - (\x\\\Rep_Set_0 (X \)\\. f (P (\_. x)) \) = - (\x\\\Rep_Set_0 (X->excluding(y) \)\\. f (P (\_. x)) \)" - apply(simp add: OclExcluding_def OclValid_def) - apply(subst Abs_Set_0_inverse, simp, (rule disjI2)+) - apply (metis (no_types) Diff_iff OclValid_def Set_inv_lemma) - by(auto) - have in_including : "\f X y \. \ \ \ X \ \ \ \ y \ - {x \ \\Rep_Set_0 (X->including(y) \)\\. f (P (\_. x) \)} = - (let s = {x \ \\Rep_Set_0 (X \)\\. f (P (\_. x) \)} in - if f (P (\_. y \) \) then insert (y \) s else s)" - apply(simp add: OclIncluding_def OclValid_def) - apply(subst Abs_Set_0_inverse, simp, (rule disjI2)+) - apply (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') - by(simp add: Let_def, auto) - - let ?OclSet = "\S. \\S\\ \ {X. X = \ \ X = null \ (\x\\\X\\. x \ \)}" - have diff_in_Set_0 : "\\. (\ X) \ = true \ \ - ?OclSet (\\Rep_Set_0 (X \)\\ - {y \})" - apply(simp, (rule disjI2)+) - by (metis (mono_tags) Diff_iff OclValid_def Set_inv_lemma) - have ins_in_Set_0 : "\\. (\ X) \ = true \ \ (\ y) \ = true \ \ - ?OclSet (insert (y \) {x \ \\Rep_Set_0 (X \)\\. P (\_. x) \ \ false \})" - apply(simp, (rule disjI2)+) - by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') - have ins_in_Set_0' : "\\. (\ X) \ = true \ \ (\ y) \ = true \ \ - ?OclSet (insert (y \) {x \ \\Rep_Set_0 (X \)\\. x \ y \ \ P (\_. x) \ \ false \})" - apply(simp, (rule disjI2)+) - by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') - have ins_in_Set_0'' : "\\. (\ X) \ = true \ \ - ?OclSet {x \ \\Rep_Set_0 (X \)\\. P (\_. x) \ \ false \}" - apply(simp, (rule disjI2)+) - by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') - have ins_in_Set_0''' : "\\. (\ X) \ = true \ \ - ?OclSet {x \ \\Rep_Set_0 (X \)\\. x \ y \ \ P (\_. x) \ \ false \}" - apply(simp, (rule disjI2)+) - by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') - - have if_same : "\a b c d \. \ \ \ a \ b \ = d \ \ c \ = d \ \ - (if a then b else c endif) \ = d \" - by(simp add: OclIf_def OclValid_def) - - have invert_including : "\P y \. P \ = \ \ P->including(y) \ = \" - by (metis (hide_lams, no_types) foundation17 foundation18' OclIncluding_valid_args_valid) - - have exclude_defined : "\\. \ \ \ X \ - (\ (\_. Abs_Set_0 \\{x \ \\Rep_Set_0 (X \)\\. x \ y \ \ P (\_. x) \ \ false \}\\)) \ = true \" - apply(subst defined_def, - simp add: false_def true_def bot_Set_0_def bot_fun_def null_Set_0_def null_fun_def) - by(subst Abs_Set_0_inject[OF ins_in_Set_0'''[simplified false_def]], - (simp add: OclValid_def bot_option_def null_option_def)+)+ - - have if_eq : "\x A B \. \ \ \ x \ \ \ (if x \ false then A else B endif) \ - (if x \ false then A else B endif)" - apply(simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclValid_def) - apply(subst (2) StrongEq_def) - by(subst cp_OclIf, simp add: cp_OclIf[symmetric] true_def) - - have OclSelect_body_bot: "\\. \ \ \ X \ \ \ \ y \ P y \ \ \ \ - (\x\\\Rep_Set_0 (X \)\\. P (\_. x) \ = \) \ \ = ?select \" - apply(drule ex_excluding1[where X2 = X and y2 = y and f2 = "\x \. x \ = \"], - (simp add: P_cp[symmetric])+) - apply(subgoal_tac "\ \ (\ \ ?select)", simp add: OclValid_def StrongEq_def true_def bot_fun_def) - apply(simp add: OclSelect_body_def) - apply(subst StrongEq_L_subst3[OF _ if_eq], simp, metis foundation18') - apply(simp add: OclValid_def, subst StrongEq_def, subst true_def, simp) - apply(subgoal_tac "\x\\\Rep_Set_0 (X->excluding(y) \)\\. P (\_. x) \ = \ \") - prefer 2 - apply (metis OCL_core.bot_fun_def foundation18') - apply(subst if_same[where d5 = "\"]) - apply (metis defined7 transform1) - apply(simp add: OclSelect_def bot_option_def bot_fun_def) - apply(subst invert_including) - by(simp add: OclSelect_def bot_option_def bot_fun_def)+ - - have d_and_v_inject : "\\ X y. (\ X and \ y) \ \ true \ \ (\ X and \ y) \ = false \" - by (metis bool_split defined5 defined6 defined_and_I foundation16 transform1 - invalid_def null_fun_def) - - have OclSelect_body_bot': "\\. (\ X and \ y) \ \ true \ \ \ = ?select \" - apply(drule d_and_v_inject) - apply(simp add: OclSelect_def OclSelect_body_def) - apply(subst cp_OclIf, subst cp_OclIncluding, simp add: false_def true_def) - apply(subst cp_OclIf[symmetric], subst cp_OclIncluding[symmetric]) - by (metis (lifting, no_types) OclIf_def foundation18 foundation18' invert_including) - - have conj_split2 : "\a b c \. ((a \ false) \ = false \ \ b) \ ((a \ false) \ = true \ \ c) \ - (a \ \ false \ \ b) \ (a \ = false \ \ c)" - by (metis OclValid_def defined7 foundation14 foundation22 foundation9) - - have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) - - have cp_OclSelect_body : "\\. ?select \ = OclSelect_body P y (\_. OclSelect X->excluding(y) P \) \" - apply(simp add: OclSelect_body_def) - by(subst (1 2) cp_OclIf, subst (1 2) cp_OclIncluding, blast) - - have OclSelect_body_strict1 : "OclSelect_body P y invalid = invalid" - by(rule ext, simp add: OclSelect_body_def OclIf_def) - - have bool_invalid: "\(x::('\)Boolean) y \. \ (\ \ \ x) \ \ \ (x \ y) \ invalid" - by(simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclValid_def StrongEq_def true_def) - - have conj_comm : "\p q r. (p \ q \ r) = ((p \ q) \ r)" - by blast - - show ?thesis - apply(rule ext, rename_tac \) - apply(subst OclSelect_def) - apply(case_tac "(\ X->including(y)) \ = true \", simp) - apply(( subst ex_including - | subst in_including), - metis OclValid_def foundation5, - metis OclValid_def foundation5)+ - apply(simp add: Let_def) - - apply(subst (4) false_def, subst (4) bot_fun_def, simp add: bot_option_def P_cp[symmetric]) - (* *) - apply(case_tac "\ (\ \ (\ P y))") - apply(subgoal_tac "P y \ \ false \") - prefer 2 - apply (metis (hide_lams, no_types) foundation1 foundation18' valid4) - apply(simp) - (* *) - apply(subst conj_comm, rule conjI) - apply(drule_tac y11 = false in bool_invalid) - apply(simp only: OclSelect_body_def, - metis OclIf_def OclValid_def defined_def foundation2 foundation22 - bot_fun_def invalid_def) - (* *) - apply(drule foundation5[simplified OclValid_def], - subst al_including[simplified OclValid_def], - simp, - simp) - apply(simp add: P_cp[symmetric]) - apply (metis OCL_core.bot_fun_def foundation18') - - apply(simp add: foundation18' bot_fun_def OclSelect_body_bot OclSelect_body_bot') - (* *) - apply(subst (1 2) al_including, metis OclValid_def foundation5, metis OclValid_def foundation5) - apply(simp add: P_cp[symmetric], subst (4) false_def, subst (4) bot_option_def, simp) - apply(simp add: OclSelect_def OclSelect_body_def StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n) - apply(subst (1 2 3 4) cp_OclIf, - subst (1 2 3 4) foundation18'[THEN iffD2, simplified OclValid_def], - simp, - simp only: cp_OclIf[symmetric] refl if_True) - apply(subst (1 2) cp_OclIncluding, rule conj_split2, simp add: cp_OclIf[symmetric]) - apply(subst (1 2 3 4 5 6 7 8) cp_OclIf[symmetric], simp) - apply(( subst ex_excluding1[symmetric] - | subst al_excluding1[symmetric] ), - metis OclValid_def foundation5, - metis OclValid_def foundation5, - simp add: P_cp[symmetric] bot_fun_def)+ - apply(simp add: bot_fun_def) - apply(subst (1 2) invert_including, simp+) - (* *) - apply(rule conjI, blast) - apply(intro impI conjI) - apply(subst OclExcluding_def) - apply(drule foundation5[simplified OclValid_def], simp) - apply(subst Abs_Set_0_inverse[OF diff_in_Set_0], fast) - apply(simp add: OclIncluding_def cp_valid[symmetric]) - apply((erule conjE)+, frule exclude_defined[simplified OclValid_def], simp) - apply(subst Abs_Set_0_inverse[OF ins_in_Set_0'''], simp+) - apply(subst Abs_Set_0_inject[OF ins_in_Set_0 ins_in_Set_0'], fast+) - (* *) - apply(simp add: OclExcluding_def) - apply(simp add: foundation10[simplified OclValid_def]) - apply(subst Abs_Set_0_inverse[OF diff_in_Set_0], simp+) - apply(subst Abs_Set_0_inject[OF ins_in_Set_0'' ins_in_Set_0'''], simp+) - apply(subgoal_tac "P (\_. y \) \ = false \") - prefer 2 - apply(subst P_cp[symmetric], metis OclValid_def foundation22) - apply(rule equalityI) - apply(rule subsetI, simp, metis) - apply(rule subsetI, simp) - (* *) - apply(drule defined_inject_true) - apply(subgoal_tac "\ (\ \ \ X) \ \ (\ \ \ y)") - prefer 2 - apply (metis bot_fun_def OclValid_def foundation18' OclIncluding_defined_args_valid valid_def) - apply(subst cp_OclSelect_body, subst cp_OclSelect, subst OclExcluding_def) - apply(simp add: OclValid_def false_def true_def, rule conjI, blast) - apply(simp add: OclSelect_invalid[simplified invalid_def] - OclSelect_body_strict1[simplified invalid_def]) - done -qed - -subsection{* OclReject *} - -lemma OclReject_mtSet_exec[simp,code_unfold]: "OclReject mtSet P = mtSet" -by(simp add: OclReject_def) - -lemma OclReject_including_exec[simp,code_unfold]: - assumes P_cp : "cp P" - shows "OclReject (X->including(y)) P = OclSelect_body (not o P) y (OclReject (X->excluding(y)) P)" - apply(simp add: OclReject_def comp_def, rule OclSelect_including_exec) -by (metis assms cp_intro''(5)) - -section{* Execution on Set's Operators (higher composition) *} - -subsection{* OclIncludes *} - -lemma OclIncludes_any[simp,code_unfold]: - "X->includes(X->any()) = (if \ X then - if \ (X->size()) then not(X->isEmpty()) - else X->includes(null) endif - else invalid endif)" -proof - - have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) - - have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac "P \ = \", simp_all add: true_def) - - have notempty': "\\ X. \ \ \ X \ finite \\Rep_Set_0 (X \)\\ \ not (X->isEmpty()) \ \ true \ \ - X \ = Set{} \" - apply(case_tac "X \", rename_tac X', simp add: mtSet_def Abs_Set_0_inject) - apply(erule disjE, metis (hide_lams, no_types) bot_Set_0_def bot_option_def foundation17) - apply(erule disjE, metis (hide_lams, no_types) bot_option_def - null_Set_0_def null_option_def foundation17) - apply(case_tac X', simp, metis (hide_lams, no_types) bot_Set_0_def foundation17) - apply(rename_tac X'', case_tac X'', simp) - apply (metis (hide_lams, no_types) foundation17 null_Set_0_def) - apply(simp add: OclIsEmpty_def OclSize_def) - apply(subst (asm) cp_OclNot, subst (asm) cp_OclOr, subst (asm) cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r, - subst (asm) cp_OclAnd, subst (asm) cp_OclNot) - apply(simp only: OclValid_def foundation20[simplified OclValid_def] - cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) - apply(simp add: Abs_Set_0_inverse split: split_if_asm) - by(simp add: true_def OclInt0_def OclNot_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def) - - have B: "\X \. \ finite \\Rep_Set_0 (X \)\\ \ (\ (X->size())) \ = false \" - apply(subst cp_defined) - apply(simp add: OclSize_def) - by (metis OCL_core.bot_fun_def defined_def) - - show ?thesis - apply(rule ext, rename_tac \, simp only: OclIncludes_def OclANY_def) - apply(subst cp_OclIf, subst (2) cp_valid) - apply(case_tac "(\ X) \ = true \", - simp only: foundation20[simplified OclValid_def] cp_OclIf[symmetric], simp, - subst (1 2) cp_OclAnd, simp add: cp_OclAnd[symmetric]) - apply(case_tac "finite \\Rep_Set_0 (X \)\\") - apply(frule size_defined'[THEN iffD2, simplified OclValid_def], assumption) - apply(subst (1 2 3 4) cp_OclIf, simp) - apply(subst (1 2 3 4) cp_OclIf[symmetric], simp) - apply(case_tac "(X->notEmpty()) \ = true \", simp) - apply(frule OclNotEmpty_has_elt[simplified OclValid_def], simp) - apply(simp add: OclNotEmpty_def cp_OclIf[symmetric]) - apply(subgoal_tac "(SOME y. y \ \\Rep_Set_0 (X \)\\) \ \\Rep_Set_0 (X \)\\", simp add: true_def) - apply(metis OclValid_def Set_inv_lemma foundation18' null_option_def true_def) - apply(rule someI_ex, simp) - apply(simp add: OclNotEmpty_def cp_valid[symmetric]) - apply(subgoal_tac "\ (null \ \ \\Rep_Set_0 (X \)\\)", simp) - apply(subst OclIsEmpty_def, simp add: OclSize_def) - apply(subst cp_OclNot, subst cp_OclOr, subst cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r, subst cp_OclAnd, - subst cp_OclNot, simp add: OclValid_def foundation20[simplified OclValid_def] - cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) - apply(frule notempty'[simplified OclValid_def], - (simp add: mtSet_def Abs_Set_0_inverse OclInt0_def false_def)+) - apply(drule notempty'[simplified OclValid_def], simp, simp) - apply (metis (hide_lams, no_types) empty_iff mtSet_rep_set) - (* *) - apply(frule B) - apply(subst (1 2 3 4) cp_OclIf, simp) - apply(subst (1 2 3 4) cp_OclIf[symmetric], simp) - apply(case_tac "(X->notEmpty()) \ = true \", simp) - apply(frule OclNotEmpty_has_elt[simplified OclValid_def], simp) - apply(simp add: OclNotEmpty_def OclIsEmpty_def) - apply(subgoal_tac "X->size() \ = \") - prefer 2 - apply (metis (hide_lams, no_types) OclSize_def) - apply(subst (asm) cp_OclNot, subst (asm) cp_OclOr, subst (asm) cp_StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r, - subst (asm) cp_OclAnd, subst (asm) cp_OclNot) - apply(simp add: OclValid_def foundation20[simplified OclValid_def] - cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) - apply(simp add: OclNot_def StrongEq_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def false_def true_def - bot_option_def bot_fun_def invalid_def) - - apply (metis OCL_core.bot_fun_def null_fun_def null_is_valid valid_def) - by(drule defined_inject_true, - simp add: false_def true_def OclIf_false[simplified false_def] invalid_def) -qed - -subsection{* OclSize *} - -lemma [simp,code_unfold]: "\ (Set{} ->size()) = true" -by simp - - -lemma [simp,code_unfold]: "\ ((X ->including(x)) ->size()) = (\(X->size()) and \(x))" -proof - - have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) - - have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac "P \ = \", simp_all add: true_def) - - have OclIncluding_finite_rep_set : "\\. (\ X and \ x) \ = true \ \ - finite \\Rep_Set_0 (X->including(x) \)\\ = finite \\Rep_Set_0 (X \)\\" - apply(rule OclIncluding_finite_rep_set) - by(metis OclValid_def foundation5)+ - - have card_including_exec : "\\. (\ (\_. \\int (card \\Rep_Set_0 (X->including(x) \)\\)\\)) \ = - (\ (\_. \\int (card \\Rep_Set_0 (X \)\\)\\)) \" - by(simp add: defined_def bot_fun_def bot_option_def null_fun_def null_option_def) - - show ?thesis - apply(rule ext, rename_tac \) - apply(case_tac "(\ (X->including(x)->size())) \ = true \", simp del: OclSize_including_exec) - apply(subst cp_OclAnd, subst cp_defined, simp only: cp_defined[of "X->including(x)->size()"], - simp add: OclSize_def) - apply(case_tac "((\ X and \ x) \ = true \ \ finite \\Rep_Set_0 (X->including(x) \)\\)", simp) - apply(erule conjE, - simp add: OclIncluding_finite_rep_set[simplified OclValid_def] card_including_exec - cp_OclAnd[of "\ X" "\ x"] - cp_OclAnd[of "true", THEN sym]) - apply(subgoal_tac "(\ X) \ = true \ \ (\ x) \ = true \", simp) - apply(rule foundation5[of _ "\ X" "\ x", simplified OclValid_def], - simp only: cp_OclAnd[THEN sym]) - apply(simp, simp add: defined_def true_def false_def bot_fun_def bot_option_def) - - apply(drule defined_inject_true[of "X->including(x)->size()"], - simp del: OclSize_including_exec, - simp only: cp_OclAnd[of "\ (X->size())" "\ x"], - simp add: cp_defined[of "X->including(x)->size()" ] cp_defined[of "X->size()" ] - del: OclSize_including_exec, - simp add: OclSize_def card_including_exec - del: OclSize_including_exec) - apply(case_tac "(\ X and \ x) \ = true \ \ finite \\Rep_Set_0 (X \)\\", - simp add: OclIncluding_finite_rep_set[simplified OclValid_def] card_including_exec, - simp only: cp_OclAnd[THEN sym], - simp add: defined_def bot_fun_def) - - apply(split split_if_asm) - apply(simp add: OclIncluding_finite_rep_set[simplified OclValid_def] card_including_exec)+ - apply(simp only: cp_OclAnd[THEN sym], simp, rule impI, erule conjE) - apply(case_tac "(\ x) \ = true \", simp add: cp_OclAnd[of "\ X" "\ x"]) - by(drule valid_inject_true[of "x"], simp add: cp_OclAnd[of _ "\ x"]) -qed - -lemma [simp,code_unfold]: "\ ((X ->excluding(x)) ->size()) = (\(X->size()) and \(x))" -proof - - have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) - - have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" - apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def - null_fun_def null_option_def) - by (case_tac "P \ = \", simp_all add: true_def) - - have OclExcluding_finite_rep_set : "\\. (\ X and \ x) \ = true \ \ - finite \\Rep_Set_0 (X->excluding(x) \)\\ = - finite \\Rep_Set_0 (X \)\\" - apply(rule OclExcluding_finite_rep_set) - by(metis OclValid_def foundation5)+ - - have card_excluding_exec : "\\. (\ (\_. \\int (card \\Rep_Set_0 (X->excluding(x) \)\\)\\)) \ = - (\ (\_. \\int (card \\Rep_Set_0 (X \)\\)\\)) \" - by(simp add: defined_def bot_fun_def bot_option_def null_fun_def null_option_def) - - show ?thesis - apply(rule ext, rename_tac \) - apply(case_tac "(\ (X->excluding(x)->size())) \ = true \", simp) - apply(subst cp_OclAnd, subst cp_defined, simp only: cp_defined[of "X->excluding(x)->size()"], - simp add: OclSize_def) - apply(case_tac "((\ X and \ x) \ = true \ \ finite \\Rep_Set_0 (X->excluding(x) \)\\)", simp) - apply(erule conjE, - simp add: OclExcluding_finite_rep_set[simplified OclValid_def] card_excluding_exec - cp_OclAnd[of "\ X" "\ x"] - cp_OclAnd[of "true", THEN sym]) - apply(subgoal_tac "(\ X) \ = true \ \ (\ x) \ = true \", simp) - apply(rule foundation5[of _ "\ X" "\ x", simplified OclValid_def], - simp only: cp_OclAnd[THEN sym]) - apply(simp, simp add: defined_def true_def false_def bot_fun_def bot_option_def) - - apply(drule defined_inject_true[of "X->excluding(x)->size()"], - simp, - simp only: cp_OclAnd[of "\ (X->size())" "\ x"], - simp add: cp_defined[of "X->excluding(x)->size()" ] cp_defined[of "X->size()" ], - simp add: OclSize_def card_excluding_exec) - apply(case_tac "(\ X and \ x) \ = true \ \ finite \\Rep_Set_0 (X \)\\", - simp add: OclExcluding_finite_rep_set[simplified OclValid_def] card_excluding_exec, - simp only: cp_OclAnd[THEN sym], - simp add: defined_def bot_fun_def) - - apply(split split_if_asm) - apply(simp add: OclExcluding_finite_rep_set[simplified OclValid_def] card_excluding_exec)+ - apply(simp only: cp_OclAnd[THEN sym], simp, rule impI, erule conjE) - apply(case_tac "(\ x) \ = true \", simp add: cp_OclAnd[of "\ X" "\ x"]) - by(drule valid_inject_true[of "x"], simp add: cp_OclAnd[of _ "\ x"]) -qed - -lemma [simp]: - assumes X_finite: "\\. finite \\Rep_Set_0 (X \)\\" - shows "\ ((X ->including(x)) ->size()) = (\(X) and \(x))" -by(simp add: size_defined[OF X_finite] del: OclSize_including_exec) - - -subsection{* OclForall *} - -lemma OclForall_rep_set_false: - assumes "\ \ \ X" - shows "(OclForall X P \ = false \) = (\x \ \\Rep_Set_0 (X \)\\. P (\\. x) \ = false \)" -by(insert assms, simp add: OclForall_def OclValid_def false_def true_def - bot_fun_def bot_option_def null_fun_def null_option_def) - -lemma OclForall_rep_set_true: - assumes "\ \ \ X" - shows "(\ \ OclForall X P) = (\x \ \\Rep_Set_0 (X \)\\. \ \ P (\\. x))" -proof - - have destruct_ocl : "\x \. x = true \ \ x = false \ \ x = null \ \ x = \ \" - apply(case_tac x) apply (metis bot_Boolean_def) - apply(rename_tac x', case_tac x') apply (metis null_Boolean_def) - apply(rename_tac x'', case_tac x'') apply (metis (full_types) true_def) - by (metis (full_types) false_def) - - have disjE4 : "\ P1 P2 P3 P4 R. - (P1 \ P2 \ P3 \ P4) \ (P1 \ R) \ (P2 \ R) \ (P3 \ R) \ (P4 \ R) \ R" - by metis - show ?thesis - apply(simp add: OclForall_def OclValid_def true_def false_def - bot_fun_def bot_option_def null_fun_def null_option_def split: split_if_asm) - apply(rule conjI, rule impI) apply (metis OCL_core.drop.simps option.distinct(1)) - apply(rule impI, rule conjI, rule impI) apply (metis option.distinct(1)) - apply(rule impI, rule conjI, rule impI) apply (metis OCL_core.drop.simps) - apply(intro conjI impI ballI) - proof - fix x show "\x\\\Rep_Set_0 (X \)\\. P (\_. x) \ \ \None\ \ - \x\\\Rep_Set_0 (X \)\\. \y. P (\_. x) \ = \y\ \ - \x\\\Rep_Set_0 (X \)\\. P (\_. x) \ \ \\False\\ \ - x \ \\Rep_Set_0 (X \)\\ \ P (\\. x) \ = \\True\\" - apply(erule_tac x = x in ballE)+ - by(rule disjE4[OF destruct_ocl[of "P (\\. x) \"]], - (simp add: true_def false_def null_fun_def null_option_def bot_fun_def bot_option_def)+) - apply_end(simp add: assms[simplified OclValid_def true_def])+ - qed -qed - -lemma OclForall_includes : - assumes x_def : "\ \ \ x" - and y_def : "\ \ \ y" - shows "(\ \ OclForall x (OclIncludes y)) = (\\Rep_Set_0 (x \)\\ \ \\Rep_Set_0 (y \)\\)" - apply(simp add: OclForall_rep_set_true[OF x_def], - simp add: OclIncludes_def OclValid_def y_def[simplified OclValid_def]) - apply(insert Set_inv_lemma[OF x_def], simp add: valid_def false_def true_def bot_fun_def) -by(rule iffI, simp add: subsetI, simp add: subsetD) - -lemma OclForall_not_includes : - assumes x_def : "\ \ \ x" - and y_def : "\ \ \ y" - shows "(OclForall x (OclIncludes y) \ = false \) = (\ \\Rep_Set_0 (x \)\\ \ \\Rep_Set_0 (y \)\\)" - apply(simp add: OclForall_rep_set_false[OF x_def], - simp add: OclIncludes_def OclValid_def y_def[simplified OclValid_def]) - apply(insert Set_inv_lemma[OF x_def], simp add: valid_def false_def true_def bot_fun_def) -by(rule iffI, metis set_rev_mp, metis subsetI) - -lemma OclForall_iterate: - assumes S_finite: "finite \\Rep_Set_0 (S \)\\" - shows "S->forAll(x | P x) \ = (S->iterate(x; acc = true | acc and P x)) \" -proof - - have and_comm : "comp_fun_commute (\x acc. acc and P x)" - apply(simp add: comp_fun_commute_def comp_def) - by (metis OclAnd_assoc OclAnd_commute) - - have ex_insert : "\x F P. (\x\insert x F. P x) = (P x \ (\x\F. P x))" - by (metis insert_iff) - - have destruct_ocl : "\x \. x = true \ \ x = false \ \ x = null \ \ x = \ \" - apply(case_tac x) apply (metis bot_Boolean_def) - apply(rename_tac x', case_tac x') apply (metis null_Boolean_def) - apply(rename_tac x'', case_tac x'') apply (metis (full_types) true_def) - by (metis (full_types) false_def) - - have disjE4 : "\ P1 P2 P3 P4 R. - (P1 \ P2 \ P3 \ P4) \ (P1 \ R) \ (P2 \ R) \ (P3 \ R) \ (P4 \ R) \ R" - by metis - - let ?P_eq = "\x b \. P (\_. x) \ = b \" - let ?P = "\set b \. \x\set. ?P_eq x b \" - let ?if = "\f b c. if f b \ then b \ else c" - let ?forall = "\P. ?if P false (?if P \ (?if P null (true \)))" - show ?thesis - apply(simp only: OclForall_def OclIterate_def) - apply(case_tac "\ \ \ S", simp only: OclValid_def) - apply(subgoal_tac "let set = \\Rep_Set_0 (S \)\\ in - ?forall (?P set) = - Finite_Set.fold (\x acc. acc and P x) true ((\a \. a) ` set) \", - simp only: Let_def, simp add: S_finite, simp only: Let_def) - apply(case_tac "\\Rep_Set_0 (S \)\\ = {}", simp) - apply(rule finite_ne_induct[OF S_finite], simp) - (* *) - apply(simp only: image_insert) - apply(subst comp_fun_commute.fold_insert[OF and_comm], simp) - apply (metis empty_iff image_empty) - apply(simp) - apply (metis OCL_core.bot_fun_def destruct_ocl null_fun_def) - (* *) - apply(simp only: image_insert) - apply(subst comp_fun_commute.fold_insert[OF and_comm], simp) - apply (metis (mono_tags) imageE) - - (* *) - apply(subst cp_OclAnd) apply(drule sym, drule sym, simp only:, drule sym, simp only:) - apply(simp only: ex_insert) - apply(subgoal_tac "\x. x\F") prefer 2 - apply(metis all_not_in_conv) - proof - fix x F show "(\ S) \ = true \ \ \x. x \ F \ - ?forall (\b \. ?P_eq x b \ \ ?P F b \) = - ((\_. ?forall (?P F)) and (\_. P (\\. x) \)) \" - apply(rule disjE4[OF destruct_ocl[where x1 = "P (\\. x) \"]]) - apply(simp_all add: true_def false_def OclAnd_def - null_fun_def null_option_def bot_fun_def bot_option_def) - by (metis (lifting) option.distinct(1))+ - apply_end(simp add: OclValid_def)+ - qed -qed - -lemma OclForall_cong: - assumes "\x. x \ \\Rep_Set_0 (X \)\\ \ \ \ P (\\. x) \ \ \ Q (\\. x)" - assumes P: "\ \ OclForall X P" - shows "\ \ OclForall X Q" -proof - - have def_X: "\ \ \ X" - by(insert P, simp add: OclForall_def OclValid_def bot_option_def true_def split: split_if_asm) - show ?thesis - apply(insert P) - apply(subst (asm) OclForall_rep_set_true[OF def_X], subst OclForall_rep_set_true[OF def_X]) - by (simp add: assms) -qed - -lemma OclForall_cong': - assumes "\x. x \ \\Rep_Set_0 (X \)\\ \ \ \ P (\\. x) \ \ \ Q (\\. x) \ \ \ R (\\. x)" - assumes P: "\ \ OclForall X P" - assumes Q: "\ \ OclForall X Q" - shows "\ \ OclForall X R" -proof - - have def_X: "\ \ \ X" - by(insert P, simp add: OclForall_def OclValid_def bot_option_def true_def split: split_if_asm) - show ?thesis - apply(insert P Q) - apply(subst (asm) (1 2) OclForall_rep_set_true[OF def_X], subst OclForall_rep_set_true[OF def_X]) - by (simp add: assms) -qed - -subsection{* Strict Equality *} - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_defined : - assumes x_def: "\ \ \ x" - assumes y_def: "\ \ \ y" - shows "((x::('\,'\::null)Set) \ y) \ = - (x->forAll(z| y->includes(z)) and (y->forAll(z| x->includes(z)))) \" -proof - - have rep_set_inj : "\\. (\ x) \ = true \ \ - (\ y) \ = true \ \ - x \ \ y \ \ - \\Rep_Set_0 (y \)\\ \ \\Rep_Set_0 (x \)\\" - apply(simp add: defined_def) - apply(split split_if_asm, simp add: false_def true_def)+ - apply(simp add: null_fun_def null_Set_0_def bot_fun_def bot_Set_0_def) - - apply(case_tac "x \", rename_tac x') - apply(case_tac x', simp_all, rename_tac x'') - apply(case_tac x'', simp_all) - - apply(case_tac "y \", rename_tac y') - apply(case_tac y', simp_all, rename_tac y'') - apply(case_tac y'', simp_all) - - apply(simp add: Abs_Set_0_inverse) - by(blast) - - show ?thesis - apply(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t StrongEq_def - foundation20[OF x_def, simplified OclValid_def] - foundation20[OF y_def, simplified OclValid_def]) - apply(subgoal_tac "\\x \ = y \\\ = true \ \ \\x \ = y \\\ = false \") - prefer 2 - apply(simp add: false_def true_def) - (* *) - apply(erule disjE) - apply(simp add: true_def) - - apply(subgoal_tac "(\ \ OclForall x (OclIncludes y)) \ (\ \ OclForall y (OclIncludes x))") - apply(subst cp_OclAnd, simp add: true_def OclValid_def) - apply(simp add: OclForall_includes[OF x_def y_def] - OclForall_includes[OF y_def x_def]) - - (* *) - apply(simp) - - apply(subgoal_tac "OclForall x (OclIncludes y) \ = false \ \ - OclForall y (OclIncludes x) \ = false \") - apply(subst cp_OclAnd, metis OclAnd_false1 OclAnd_false2 cp_OclAnd) - apply(simp only: OclForall_not_includes[OF x_def y_def, simplified OclValid_def] - OclForall_not_includes[OF y_def x_def, simplified OclValid_def], - simp add: false_def) - by (metis OclValid_def rep_set_inj subset_antisym x_def y_def) -qed - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_exec[simp,code_unfold] : -"((x::('\,'\::null)Set) \ y) = - (if \ x then (if \ y - then ((x->forAll(z| y->includes(z)) and (y->forAll(z| x->includes(z))))) - else if \ y - then false (* x'->includes = null *) - else invalid - endif - endif) - else if \ x (* null = ??? *) - then if \ y then not(\ y) else invalid endif - else invalid - endif - endif)" -proof - - have defined_inject_true : "\\ P. (\ (\ \ \ P)) = ((\ P) \ = false \)" - by (metis bot_fun_def OclValid_def defined_def foundation16 null_fun_def) - - have valid_inject_true : "\\ P. (\ (\ \ \ P)) = ((\ P) \ = false \)" - by (metis bot_fun_def OclIf_true' OclIncludes_charn0 OclIncludes_charn0' OclValid_def valid_def - foundation6 foundation9) - show ?thesis - apply(rule ext, rename_tac \) - (* *) - apply(simp add: OclIf_def - defined_inject_true[simplified OclValid_def] - valid_inject_true[simplified OclValid_def], - subst false_def, subst true_def, simp) - apply(subst (1 2) cp_OclNot, simp, simp add: cp_OclNot[symmetric]) - apply(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t_defined[simplified OclValid_def]) - by(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t StrongEq_def false_def true_def valid_def defined_def) -qed - -lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_L_subst1 : "cp P \ \ \ \ x \ \ \ \ y \ \ \ \ P x \ \ \ \ P y \ - \ \ (x::('\,'\::null)Set) \ y \ \ \ (P x ::('\,'\::null)Set) \ P y" - apply(simp only: StrictRefEq\<^sub>S\<^sub>e\<^sub>t OclValid_def) - apply(split split_if_asm) - apply(simp add: StrongEq_L_subst1[simplified OclValid_def]) -by (simp add: invalid_def bot_option_def true_def) - -lemma OclIncluding_cong' : -shows "\ \ \ s \ \ \ \ t \ \ \ \ x \ - \ \ ((s::('\,'a::null)Set) \ t) \ \ \ (s->including(x) \ (t->including(x)))" -proof - - have cp: "cp (\s. (s->including(x)))" - apply(simp add: cp_def, subst cp_OclIncluding) - by (rule_tac x = "(\xab ab. ((\_. xab)->including(\_. x ab)) ab)" in exI, simp) - - show "\ \ \ s \ \ \ \ t \ \ \ \ x \ \ \ (s \ t) \ ?thesis" - apply(rule_tac P = "\s. (s->including(x))" in StrictRefEq\<^sub>S\<^sub>e\<^sub>t_L_subst1) - apply(rule cp) - apply(simp add: foundation20) apply(simp add: foundation20) - apply (simp add: foundation10 foundation6)+ - done -qed - -lemma OclIncluding_cong : "\(s::('\,'a::null)Set) t x y \. \ \ \ t \ \ \ \ y \ - \ \ s \ t \ x = y \ \ \ s->including(x) \ (t->including(y))" - apply(simp only:) - apply(rule OclIncluding_cong', simp_all only:) -by(auto simp: OclValid_def OclIf_def invalid_def bot_option_def OclNot_def split : split_if_asm) - -lemma const_StrictRefEq\<^sub>S\<^sub>e\<^sub>t_including : "const a \ const S \ const X \ - const (X \ S->including(a))" - apply(rule const_StrictRefEq\<^sub>S\<^sub>e\<^sub>t, assumption) -by(rule const_OclIncluding) - -section{* Test Statements *} - -lemma syntax_test: "Set{\,\} = (Set{}->including(\)->including(\))" -by (rule refl) - -text{* Here is an example of a nested collection. Note that we have -to use the abstract null (since we did not (yet) define a concrete -constant @{term null} for the non-existing Sets) :*} -lemma semantic_test2: -assumes H:"(Set{\} \ null) = (false::('\)Boolean)" -shows "(\::('\)st) \ (Set{Set{\},null}->includes(null))" -by(simp add: OclIncludes_execute\<^sub>S\<^sub>e\<^sub>t H) - -(* legacy---still better names ? -lemmas defined_charn = foundation16 -lemmas definedD = foundation17 -lemmas valid_charn = -lemmas validD = foundation19 -lemmas valid_implies_defined = foundation20 - end legacy *) - -lemma short_cut'[simp,code_unfold]: "(\ \ \) = false" - apply(rule ext) - apply(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def OclInt8_def OclInt6_def - true_def false_def invalid_def bot_option_def) -done - -lemma short_cut''[simp,code_unfold]: "(\ \ \) = false" - apply(rule ext) - apply(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def OclInt2_def OclInt1_def - true_def false_def invalid_def bot_option_def) -done -lemma short_cut'''[simp,code_unfold]: "(\ \ \) = false" - apply(rule ext) - apply(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def OclInt2_def OclInt1_def - true_def false_def invalid_def bot_option_def) -done - -text{* Elementary computations on Sets.*} - -declare OclSelect_body_def [simp] - -value "\ (\ \ \(invalid::('\,'\::null) Set))" -value "\ \ \(null::('\,'\::null) Set)" -value "\ (\ \ \(null::('\,'\::null) Set))" -value "\ \ \(Set{})" -value "\ \ \(Set{Set{\},null})" -value "\ \ \(Set{Set{\},null})" -value "\ \ (Set{\,\}->includes(\))" -value "\ (\ \ (Set{\}->includes(\)))" -value "\ (\ \ (Set{\,\}->includes(null)))" -value "\ \ (Set{\,null}->includes(null))" -value "\ \ (Set{null,\}->includes(null))" - -value "\ \ ((Set{})->forAll(z | \ `< z))" - -value "\ \ ((Set{\,\})->forAll(z | \ `< z))" -value "\ (\ \ ((Set{\,\})->exists(z | z `< \ )))" -value "\ (\ \ \(Set{\,null})->forAll(z | \ `< z))" -value "\ (\ \ ((Set{\,null})->forAll(z | \ `< z)))" -value "\ \ ((Set{\,null})->exists(z | \ `< z))" - -value "\ (\ \ (Set{null::'a Boolean} \ Set{}))" -value "\ (\ \ (Set{null::'a Integer} \ Set{}))" - -value "(\ \ (Set{\_. \\x\\} \ Set{\_. \\x\\}))" -value "(\ \ (Set{\_. \x\} \ Set{\_. \x\}))" - -(* TO BE DONE - why does this not work ? ? ? - une regle importante est dans simp, mais pas dans code_unfold ... *) - -lemma "\ (\ \ (Set{true} \ Set{false}))" by simp -lemma "\ (\ \ (Set{true,true} \ Set{false}))" by simp -lemma "\ (\ \ (Set{\} \ Set{\}))" by simp -lemma "\ \ (Set{\,null,\} \ Set{null,\})" by simp -lemma "\ \ (Set{\,null,\} <> Set{null,\})" by simp -lemma "\ \ (Set{Set{\,null}} \ Set{Set{null,\}})" by simp -lemma "\ \ (Set{Set{\,null}} <> Set{Set{null,\},null})" by simp -lemma "\ \ (Set{null}->select(x | not x) \ Set{null})" by simp -lemma "\ \ (Set{null}->reject(x | not x) \ Set{null})" by simp - -lemma "const (Set{Set{\,null}, invalid})" by(simp add: const_ss) - -(* -value "\ (\ \ (Set{true} \ Set{false}))" -value "\ (\ \ (Set{true,true} \ Set{false}))" -value "\ (\ \ (Set{\} \ Set{\}))" -value "\ \ (Set{\,null,\} \ Set{null,\})" -value "\ \ (Set{\,null,\} <> Set{null,\})" -value "\ \ (Set{Set{\,null}} \ Set{Set{null,\}})" -value "\ \ (Set{Set{\,null}} <> Set{Set{null,\},null})" -value "\ \ (Set{null}->select(x | not x) \ Set{null})" -value "\ \ (Set{null}->reject(x | not x) \ Set{null})" -*) -end diff --git a/OCL_main.thy b/OCL_main.thy deleted file mode 100644 index 426ee1b..0000000 --- a/OCL_main.thy +++ /dev/null @@ -1,57 +0,0 @@ -(***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 - * for the OMG Standard. - * http://www.brucker.ch/projects/hol-testgen/ - * - * OCL_main.thy --- - * This file is part of HOL-TestGen. - * - * Copyright (c) 2012-2013 Université Paris-Sud, France - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************) - -theory OCL_main -imports OCL_lib OCL_state OCL_tools -begin - - - -end - - - - - - - - - diff --git a/ROOT b/ROOT index 98a503e..3030b52 100644 --- a/ROOT +++ b/ROOT @@ -1,24 +1,68 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * This file is part of HOL-TestGen. + * + * Copyright (c) 2013-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * 2013-2015 Achim D. Brucker, Germany + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + chapter AFP -session Featherweight_OCL (AFP) = HOL + +session Featherweight_OCL (AFP) in "src" = HOL + description {* Featherweight-OCL *} - options [document_variants = "document:outline=/proof,/ML"] + options [document_variants = "annex-a=annexa,-theory,-afp,-proof,-ML:document=afp,-annexa:outline=-annexa,afp,/proof,/ML", + show_question_marks = false] theories - "OCL_main" - "examples/Employee_AnalysisModel_OCLPart" - "examples/Employee_DesignModel_OCLPart" + "UML_Main" + "../examples/Employee_Model/Analysis/Analysis_OCL" + "../examples/Employee_Model/Design/Design_OCL" document_files "conclusion.tex" - "formalization.tex" - "hol-ocl-isar.sty" - "introduction.tex" - "lstisar.sty" - "prooftree.sty" - "root.bib" - "root.tex" "figures/AbstractSimpleChair.pdf" "figures/jedit.png" "figures/pdf.png" "figures/person.png" "figures/pre-post.pdf" + "hol-ocl-isar.sty" + "introduction.tex" + "lstisar.sty" + "omg.sty" + "prooftree.sty" + "root.bib" + "root.tex" + "FOCL_Syntax.tex" diff --git a/document/formalization.tex b/document/formalization.tex deleted file mode 100644 index 1f9f024..0000000 --- a/document/formalization.tex +++ /dev/null @@ -1,25 +0,0 @@ -\part{A Proposal for Formal Semantics of OCL 2.5} - - -\input{OCL_core.tex} -\input{OCL_lib.tex} -\input{OCL_state.tex} -\input{OCL_tools.tex} -\input{OCL_main.tex} - - -\part{Examples} -\chapter{The Employee Analysis Model} -\label{ex:employee-analysis} -\input{Employee_AnalysisModel_UMLPart.tex} -\input{Employee_AnalysisModel_OCLPart.tex} -\chapter{The Employee Design Model} -\label{ex:employee-design} -\input{Employee_DesignModel_UMLPart.tex} -\input{Employee_DesignModel_OCLPart.tex} - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "root" -%%% End: diff --git a/document/introduction.tex b/document/introduction.tex deleted file mode 100644 index f91b96b..0000000 --- a/document/introduction.tex +++ /dev/null @@ -1,1490 +0,0 @@ -\part{Introduction} -\chapter{Motivation} -The Unified Modeling Language -(UML)~\cite{omg:uml-infrastructure:2011,omg:uml-superstructure:2011} -is one of the few modeling languages that is widely used in -industry. UML is defined, in an open process, by the Object Management -Group (OMG), \ie, an industry consortium. While UML is mostly known -as diagrammatic modeling language (\eg, visualizing class models), it -also comprises a textual language, called Object Constraint Language -(OCL)~\cite{omg:ocl:2012}. OCL is a textual annotation language, -originally conceived as a three-valued logic, that turns substantial -parts of UML into a formal language. Unfortunately the semantics of -this specification language, captured in the ``Annex A'' (originally, -based on the work of \citet{richters:precise:2002}) of the OCL -standard leads to different interpretations of corner cases. Many of -these corner cases had been subject to formal analysis since more than -nearly fifteen years (see, -\eg,~\cite{brucker.ea:semantic:2006-b,brucker.ea:proposal:2002,mandel.ea:ocl:1999, - hamie.ea:reflections:1998,cook.ea::amsterdam:2002}). - -At its origins~\cite{richters:precise:2002,omg:ocl:1997}, OCL was -conceived as a strict semantics for undefinedness (\eg, denoted by the -element \inlineocl{invalid}\footnote{In earlier versions of the OCL - standard, this element was called \inlineocl{OclUndefined}.}), with -the exception of the logical connectives of type \inlineocl{Boolean} -that constitute a three-valued propositional logic. At its core, OCL -comprises four layers: -\begin{enumerate} -\item Operators (\eg, \inlineocl{_ and _}, \inlineocl{_ + _}) on - built-in data structures such as \inlineocl{Boolean}, - \inlineocl{Integer}, or typed sets (\inlineocl{Set(_)}. -\item Operators on the user-defined data model (\eg, defined as part - of a UML class model) such as accessors, type casts and tests. -\item Arbitrary, user-defined, side-effect-free methods, -\item Specification for invariants on states and contracts for - operations to be specified via pre- and post-conditions. -\end{enumerate} - -Motivated by the need for aligning OCL closer with UML, recent -versions of the OCL standard~\cite{omg:ocl:2006,omg:ocl:2012} added a -second exception element. While the first exception element -\inlineocl{invalid} has a strict semantics, \inlineocl{null} has a non -strict semantic interpretation. Unfortunately, this extension results -in several inconsistencies and contradictions. These problems are -reflected in difficulties to define interpreters, code-generators, -specification animators or theorem provers for OCL in a uniform manner -and resulting incompatibilities of various tools. - -For the OCL community, the semantics of \inlineocl{invalid} and -\inlineocl{null} as well as many related issues resulted in the -challenge to define a consistent version of the OCL standard that is -well aligned with the recent developments of the UML\@. A syntactical -and semantical consistent standard requires a major revision of both -the informal and formal parts of the standard. To discuss the future -directions of the standard, several OCL experts met in November 2013 -in Aachen to discuss possible mid-term improvements of OCL, strategies -of standardization of OCL within the OMG, and a vision for possible -long-term developments of the -language~\cite{brucker.ea:summary-aachen:2013}. During this meeting, a -Request for Proposals (RFP) for OCL 2.5 was finalized and meanwhile -proposed. In particular, this RFP requires that the future OCL 2.5 -standard document shall be generated from a machine-checked -source. This will ensure -\begin{itemize} -\item the absence of syntax errors, -\item the consistency of the formal semantics, -\item a suite of corner-cases relevant for OCL tool implementors. -\end{itemize} - -In this document, we present a formalization using -Isabelle/HOL~\cite{nipkow.ea:isabelle:2002} of a core language of -OCL\@. The semantic theory, based on a ``shallow embedding'', is -called \emph{Featherweight OCL}, since it focuses on a formal -treatment of the key-elements of the language (rather than a full -treatment of all operators and thus, a ``complete'' -implementation). In contrast to full OCL, it comprises just the logic -captured in \verb+Boolean+, the basic data type \verb+Integer+, the -collection type \verb+Set+, as well as the generic construction -principle of class models, which is instantiated and demonstrated for -two examples (an automated support for this type-safe construction is -again out of the scope of Featherweight OCL). This formal semantics -definition is intended to be a proposal for the standardization -process of OCL 2.5, which should ultimately replace parts of the -mandatory part of the standard document~\cite{omg:ocl:2012} as well as -replace completely its informative ``Annex A.'' - - -\chapter{Background} -\section{A Guided Tour Through UML/OCL} -\label{sec:guidedtour} -The Unified Modeling Language -(UML)~\cite{omg:uml-infrastructure:2011,omg:uml-superstructure:2011} -comprises a variety of model types for describing static (\eg, class -models, object models) and dynamic (\eg, state-machines, activity -graphs) system properties. -\begin{figure*} - \centering\scalebox{1}{\includegraphics{figures/AbstractSimpleChair}}% - \caption{A simple UML class model representing a conference - system for organizing conference sessions: persons can - participate, in different roles, in a session. \label{fig:uml}} -\end{figure*} -One of the more prominent model types of the UML is the -\emph{class model} (visualized as \emph{class diagram}) for modeling -the underlying data model of a system in an object-oriented manner. As -a running example, we model a part of a conference management -system. Such a system usually supports the conference organizing -process, \eg, creating a conference Website, reviewing submissions, -registering attendees, organizing the different sessions and tracks, -and indexing and producing the resulting proceedings. In this example, -we constrain ourselves to the process of organizing conference -sessions; \autoref{fig:uml} shows the class model. We model the -hierarchy of roles of our system as a hierarchy of classes (\eg, -\inlineocl{Hearer}, \inlineocl{Speaker}, or \inlineocl{Chair}) using -an \emph{inheritance} relation (also called \emph{generalization}). In -particular, \emph{inheritance} establishes a \emph{subtyping} -relationship, \ie, every \inlineocl{Speaker} (\emph{subclass}) is also -a \inlineocl{Hearer} (\emph{superclass}). - -A class does not only describe a set of \emph{instances} (called -\emph{objects}), \ie, record-like data consisting of \emph{attributes} -such as \inlineocl{name} of class \inlineocl{Session}, but also -\emph{operations} defined over them. For example, for the class -\inlineocl{Session}, representing a conference session, we model an -operation \inlineocl{findRole(p:Person):Role} that should return the -role of a \inlineocl{Person} in the context of a specific session; -later, we will describe the behavior of this operation in more detail -using UML\@. In the following, the term object describes a -(run-time) instance of a class or one of its subclasses. - -Relations between classes (called \emph{associations} in UML) -can be represented in a class diagram by connecting lines, \eg, -\inlineocl{Participant} and \inlineocl{Session} or \inlineocl{Person} -and \inlineocl{Role}. Associations may be labeled by a particular -constraint called \emph{multiplicity}, \eg, \inlineocl+0..*+ or -\inlineocl+0..1+, which means that in a relation between participants -and sessions, each \inlineocl{Participant} object is associated to at -most one \inlineocl{Session} object, while each \inlineocl{Session} -object may be associated to arbitrarily many \inlineocl{Participant} -objects. Furthermore, associations may be labeled by projection -functions like \inlineocl{person} and \inlineocl{role}; these implicit -function definitions allow for OCL-expressions like -\inlineocl+self.person+, where \inlineocl+self+ is a variable of the -class \inlineocl{Role}. The expression \inlineocl+self.person+ denotes -persons being related to the specific object \inlineocl{self} of -type role. A particular feature of the UML are \emph{association - classes} (\inlineocl{Participant} in our example) which represent a -concrete tuple of the relation within a system state as an object; -\ie, associations classes allow also for defining attributes and -operations for such tuples. In a class diagram, association classes -are represented by a dotted line connecting the class with the -association. Associations classes can take part in other associations. -Moreover, UML supports also $n$-ary associations (not shown in -our example). - -We refine this data model using the Object Constraint Language (OCL) -for specifying additional invariants, preconditions and postconditions -of operations. For example, we specify that objects of the class -\inlineocl{Person} are uniquely determined by the value of the -\inlineocl{name} attribute and that the attribute \inlineocl{name} is -not equal to the empty string (denoted by \inlineocl{''}): -\begin{ocl} -context Person - inv: name <> '' and - Person::allInstances()->isUnique(p:Person | p.name) -\end{ocl} -Moreover, we specify that every session has exactly one chair by the -following invariant (called \inlineocl{onlyOneChair}) of the class -\inlineocl{Session}: -\begin{ocl} -context Session - inv onlyOneChair: self.participants->one( p:Participant | - p.role.oclIsTypeOf(Chair)) -\end{ocl} -where \inlineocl{p.role.oclIsTypeOf(Chair)} evaluates to true, if -\inlineocl{p.role} is of \emph{dynamic type} -\inlineocl{Chair}. Besides the usual \emph{static types} (\ie, the -types inferred by a static type inference), objects in UML and other -object-oriented languages have a second \emph{dynamic} type concept. -This is a consequence of a family of \emph{casting functions} (written -$\typeCast{o}{C}$ for an object $o$ into another class type $C$) that -allows for converting the static type of objects along the class -hierarchy. The dynamic type of an object can be understood as its -``initial static type'' and is unchanged by casts. We complete our -example by describing the behavior of the operation -\inlineocl{findRole} as follows: -\begin{ocl} -context Session::findRole(person:Person):Role - pre: self.participates.person->includes(person) - post: result=self.participants->one(p:Participant | - p.person = person ).role - and self.participants = self.participants@pre - and self.name = self.name@pre -\end{ocl} -where in post-conditions, the operator \inlineocl{@pre} allows for -accessing the previous state. - -In UML, classes can contain attributes of the type of the -defining class. Thus, UML can represent (mutually) recursive -datatypes. Moreover, OCL introduces also recursively specified -operations. - -A key idea of defining the semantics of UML and extensions like -SecureUML~\cite{brucker.ea:transformation:2006} is to translate the -diagrammatic UML features into a combination of more elementary -features of UML and OCL -expressions~\cite{gogolla.ea:expressing:2001}. For example, -associations are usually represented by collection-valued class -attributes together with OCL constraints expressing the -multiplicity. Thus, having a semantics for a subset of UML and OCL is -tantamount for the foundation of the entire method. - - - - - - -\section{Formal Foundation} - - -\subsection{Isabelle} -Isabelle~\cite{nipkow.ea:isabelle:2002} is a \emph{generic} theorem -prover. New object logics can be introduced by specifying their syntax -and natural deduction inference rules. Among other logics, Isabelle -supports first-order logic, Zermelo-Fraenkel set theory and the -instance for Church's higher-order logic (HOL). - -Isabelle's inference rules are based on the built-in meta-level -implication $\_ \Implies \_$ allowing to form constructs like $A_1 -\Implies \cdots \Implies A_n \Implies A_{n+1}$, which are viewed as a -\emph{rule} of the form ``from assumptions $A_1$ to $A_n$, infer -conclusion $A_{n+1}$'' and which is written in Isabelle as -\begin{gather} - \semantics{A_1 ; \ldots; A_n}\Implies A_{n+1} - \qquad - \text{or, in mathematical notation,} - \qquad - \begin{prooftree} - A_1 \qquad \cdots \qquad A_n - \justifies - A_{n+1} - \ptmi{.} - \end{prooftree} -\end{gather} -The built-in meta-level quantification $\Forall x\spot x$ captures -the usual side-constraints ``$x$ must not occur free in the -assumptions'' for quantifier rules; meta-quantified variables can be -considered as ``fresh'' free variables. Meta-level quantification -leads to a generalization of Horn-clauses of the form: -\begin{gather} -\Forall x_1, \ldots, x_m\spot \semantics{A_1 ; \ldots; A_n}\Implies -A_{n+1}\mi{.} -\end{gather} - -Isabelle supports forward- and backward reasoning on rules. For -backward-reasoning, a \emph{proof-state} can be initialized and -further transformed into others. For example, a proof of $\phi$, using -the Isar~\cite{wenzel:isabelleisar:2002} language, will look as -follows in Isabelle: -\begin{gather} - \begin{array}{l} - \Lemma{label} \phi\\ - \quad\apply{case\_tac}\\ - \quad\apply{simp\_all}\\ - \done - \end{array} -\end{gather} -This proof script instructs Isabelle to prove $\phi$ by case -distinction followed by a simplification of the resulting proof state. -Such a proof state is an implicitly conjoint sequence of generalized -Horn-clauses (called \emph{subgoals}) $\phi_1$, \ldots,$\phi_n$ and a -\emph{goal} $\phi$. Proof states were usually denoted by: -\begin{gather} -\begin{array}{rl} -\pglabel{label}:& \phi \\ - 1.& \phi_1 \\ - &\vdots \\ - n.& \phi_n\\ -\end{array} -\end{gather} -Subgoals and goals may be extracted from the proof state into theorems -of the form $\semantics{\phi_1 ; \ldots; \phi_n}\Implies \phi$ at any -time; this mechanism helps to generate test theorems. Further, -Isabelle supports meta-variables (written $\meta{x}, \meta{y}, -\ldots$), which can be seen as ``holes in a term'' that can still be -substituted. Meta-variables are instantiated by Isabelle's built-in -higher-order unification. - -\subsection{Higher-order Logic (HOL)} -\emph{Higher-order logic} -(HOL)~\cite{church:types:1940,andrews:introduction:2002} is a -classical logic based on a simple type system. It provides the usual -logical connectives like $\_ \land \_$, $\_ \implies\_$, $\lnot \_ $ -as well as the object-logical quantifiers $\forall x\spot P\ap x$ and -$\exists x\spot P\ap x$; in contrast to first-order logic, quantifiers -may range over arbitrary types, including total functions -$f\ofType\alpha \Rightarrow \beta$. HOL is centered around -extensional equality $\_ = \_ \ofType \alpha \Rightarrow \alpha -\Rightarrow \text{bool}$. HOL is more expressive than first-order -logic, since, \eg, induction schemes can be expressed inside the -logic. Being based on some polymorphically typed $\lambda$-calculus, -HOL can be viewed as a combination of a programming language -like SML or Haskell and a specification language providing -powerful logical quantifiers ranging over elementary and function -types. - -Isabelle/HOL is a logical embedding of HOL into Isabelle. The -(original) simple-type system underlying HOL has been extended by -Hindley-Milner style polymorphism with type-classes similar to -Haskell. While Isabelle/HOL is usually seen as proof assistant, we -use it as symbolic computation environment. Implementations on top of -Isabelle/HOL can re-use existing powerful deduction mechanisms such as -higher-order resolution, tableaux-based reasoners, rewriting -procedures, Presburger arithmetic, and via various integration -mechanisms, also external provers such as -Vampire~\cite{riazanov.ea:vampire:1999} and the SMT-solver -Z3~\cite{moura.ea:z3:2008}. - -Isabelle/HOL offers support for a particular methodology to extend -given theories in a logically safe way: A theory-extension is -\emph{conservative} if the extended theory is consistent provided that -the original theory was consistent. Conservative extensions can be -\emph{constant definitions}, \emph{type definitions}, \emph{datatype - definitions}, \emph{primitive recursive definitions} and -\emph{wellfounded recursive definitions}. - -For instance, the library includes the type constructor $\up{\tau} := -\isasymbottom ~ | ~ \lift{\_} : \alpha$ that assigns to each type -$\tau$ a type $\up{\tau}$ \emph{disjointly extended} by the -exceptional element $\isasymbottom$. The function $\drop{\_} : -\up{\alpha} \to \alpha$ is the inverse of $\lift{\_}$ (unspecified for -$\isasymbottom$). Partial functions $\alpha \isasymrightharpoonup -\beta$ are defined as functions $\alpha \isasymRightarrow \up{\beta}$ -supporting the usual concepts of domain ($\dom\;\_$) and range -($\ran\;\_$). - -As another example of a conservative extension, typed sets were built -in the Isabelle libraries conservatively on top of the kernel of HOL -as functions to $\HolBoolean$; consequently, the constant definitions -for membership is as follows:\footnote{To increase readability, we use - a slightly simplified presentation.} -\begin{gather} - \begin{array}{lrll} - \types& \alpha \HolSet &= \alpha \Rightarrow \HolBoolean\\[.5ex] - \definitionS &\operatorname{Collect}&\ofType (\alpha \Rightarrow - \HolBoolean) \Rightarrow \HolSet{\alpha} &\qquad\text{--- set comprehension}\\ - \where &\operatorname{Collect}\ap S &\equiv S\\[.5ex] - \definitionS &\operatorname{member} &\ofType \alpha \Rightarrow - \alpha \Rightarrow \HolBoolean &\qquad\text{--- - membership test}\\ - \where &\operatorname{member}\ap s\ap S &\equiv S s\\ - \end{array} -\end{gather} -Isabelle's syntax engine is instructed to accept the notation -$\{x \mid P\}$ for $\operatorname{Collect}\ap\lambda x\spot P$ and the -notation $s \in S$ for $\operatorname{member}\ap s\ap S$. As can be -inferred from the example, constant definitions are axioms that -introduce a fresh constant symbol by some closed, non-recursive -expressions; this type of axiom is logically safe since it works -like an abbreviation. The syntactic side conditions of this axiom are -mechanically checked, of course. It is straightforward to express the -usual operations on sets like $\_ \cup \_, -\_\cap\_\ofType\HolSet{\alpha} \Rightarrow \HolSet{\alpha} \Rightarrow -\HolSet{\alpha}$ as conservative extensions, too, while the rules of -typed set theory were derived by proofs from these definitions. - -Similarly, a logical compiler is invoked for the following statements introducing -the types option and list: -\begin{gather} - \begin{array}{lrll} - \datatype & \HolOption &= \HolNone \mid \HolSome{\alpha}\\[.5ex] - \datatype & \HolList{\alpha} &= \operatorname{Nil} \mid - \operatorname{Cons}\ap a\ap l - \end{array} -\end{gather} -Here, $[]$ or $a\#l$ are an alternative syntax for $\operatorname{Nil}$ -or $\operatorname{Cons}\ap a ~l$; moreover, $[a, b, c]$ is defined as -alternative syntax for $a\#b\#c\#[]$. These (recursive) statements -were internally represented in by internal type and constant -definitions. Besides the \emph{constructors} $\HolNone$, $\HolSome$, -$[]$ and $\operatorname{Cons}$, there is the match operation -\begin{gather} -\HolCase\ap x\ap\HolOf~\HolNone \isasymRightarrow F\ap \mid -\HolSome{a} \isasymRightarrow G\ap a -\end{gather} -respectively -\begin{gather} -\HolCase\ap x\ap\HolOf~[] \isasymRightarrow F\ap \mid \operatorname{Cons}\ap a\ap -r \isasymRightarrow G\ap a\ap r\mi{.} -\end{gather} -From the internal definitions (not shown here) several properties were -automatically derived. We show only the case for lists: -\begin{gather}\label{eq:datatype-rules} - \begin{array}{ll} - (\HolCase\ap[]\ap\HolOf\ap[] \Rightarrow F \ap | \ap (a\#r) \Rightarrow - G\ap a\ap r) = F &\\ - (\HolCase \ap b\#t \ap \HolOf \ap [] \Rightarrow F \ap | \ap - (a\#r) \Rightarrow G\ap a\ap r) = G~b~t &\\ % - \mbox{}[] \neq a\#t &\text{-- distinctness} \\ - \semantics{ a = [] \implies P ; \exists~x~t\spot a = x\#t \implies P } \Longrightarrow P &\text{-- exhaust} \\ - \semantics{ P [] ; \forall~at\spot P t \implies P (a\#t) } \Longrightarrow P x &\text{-- induct} - \end{array} -\end{gather} -Finally, there is a compiler for primitive and wellfounded recursive -function definitions. For example, we may define the -$\operatorname{sort}$ operation of our running test example by: -\begin{gather}\label{eq:sortdef} - \begin{array}{lll} - \fun - &\enspace\operatorname{ins} & \ofType - [\alpha\ofType\mathrm{linorder}, \HolList{\alpha}] - \Rightarrow - \HolList{\alpha}\\ - \where - &\enspace \operatorname{ins}\ap x \ap [\;] &= [x]\\ - &\enspace \operatorname{ins}\ap x \ap (y\#\mathit{ys})&= - \HolIf x < y - \HolThen x\# y \# ys - \HolElse y\#(\operatorname{ins} \ap x \ap ys) - \end{array}\\ - \begin{array}{lll} - \fun - &\enspace\operatorname{sort} & \ofType - \HolList{(\alpha\ofType\mathrm{linorder})} - \Rightarrow - \HolList{\alpha}\\ - \where - &\enspace \operatorname{sort}\ap [\;] &= [\;]\\ - &\enspace \operatorname{sort} (x\#\mathit{xs})&= - \operatorname{ins}\ap x\ap (\operatorname{sort}\ap xs) - \end{array} -\end{gather} -The internal (non-recursive) constant definition for these operations -is quite involved; however, the logical compiler will finally derive -all the equations in the statements above from this definition and -make them available for automated simplification. - -Thus, Isabelle/HOL also provides a large collection of theories like -sets, lists, multisets, orderings, and various arithmetic theories -which only contain rules derived from conservative definitions. In -particular, Isabelle manages a set of \emph{executable types and - operators}, \ie, types and operators for which a compilation to -SML, OCaml or Haskell is possible. Setups for arithmetic types -such as $\text{int}$ have been done; moreover any datatype and any -recursive function were included in this executable set (providing -that they only consist of executable operators). Similarly, Isabelle -manages a large set of (higher-order) rewrite rules into which -recursive function definitions were included. Provided that this -rule set represents a terminating and confluent rewrite system, the -Isabelle simplifier provides also a highly potent decision procedure -for many fragments of theories underlying the constraints to be -processed when constructing test theorems. - -\section{Featherweight OCL: Design Goals} -Featherweight OCL is a formalization of the core of OCL -aiming at formally investigating the relationship between the -various concepts. At present, it does not attempt to define the complete -OCL library. Instead, it concentrates on the core concepts of -OCL as well as the types \inlineocl{Boolean}, -\inlineocl{Integer}, and typed sets (\inlineocl|Set(T)|). Following -the tradition of -HOL-OCL~\cite{brucker.ea:hol-ocl:2008,brucker.ea:hol-ocl-book:2006}, -Featherweight OCL is based on the following principles: -\begin{enumerate} -\item It is an embedding into a powerful semantic meta-language and - environment, namely - Isabelle/HOL~\cite{nipkow.ea:isabelle:2002}. -\item It is a \emph{shallow embedding} in HOL; types - in OCL were injectively mapped to types in Featherweight - OCL\@. Ill-typed OCL specifications cannot be represented in - Featherweight OCL and a type in Featherweight OCL contains exactly - the values that are possible in OCL\@. Thus, sets may contain - \inlineocl{null} (\inlineocl|Set{null}| is a defined set) but not - \inlineocl{invalid} (\inlineocl|Set{invalid}| is just - \inlineocl{invalid}). -\item Any Featherweight OCL type contains at least - \inlineocl{invalid} and \inlineocl{null} (the type \inlineocl{Void} - contains only these instances). The logic is consequently - four-valued, and there is a \inlineocl{null}-element in the type - \inlineocl{Set(A)}. -\item It is a strongly typed language in the Hindley-Milner tradition. - We assume that a pre-process eliminates all implicit conversions due - to subtyping by introducing explicit casts (\eg, - \inlineocl{oclAsType()}). The details of such a pre-processing are - described in~\cite{brucker:interactive:2007}. Casts are semantic - functions, typically injections, that may convert data between the - different Featherweight OCL types. -\item All objects are represented in an object universe in the HOL-OCL - tradition~\cite{brucker.ea:extensible:2008-b}. The universe - construction also gives semantics to type casts, dynamic type - tests, as well as functions such as \inlineocl{oclAllInstances()}, - or \inlineocl{oclIsNew()}. -\item Featherweight OCL types may be arbitrarily nested. For example, - the expression - \inlineocl|Set{Set{1,2}} = Set{Set{2,1}}| is legal and true. -\item For demonstration purposes, the set type in Featherweight OCL - may be infinite, allowing infinite quantification and a constant - that contains the set of all Integers. Arithmetic laws like - commutativity may therefore be expressed in OCL itself. The - iterator is only defined on finite sets. -\item It supports equational reasoning and congruence reasoning, but - this requires a differentiation of the different equalities like - strict equality, strong equality, meta-equality (HOL). Strict - equality and strong equality require a subcalculus, ``cp'' (a - detailed discussion of the different equalities as well as the - subcalculus ``cp''---for three-valued OCL 2.0---is given - in~\cite{brucker.ea:semantics:2009}), which is nasty but can be - hidden from the user inside tools. -\end{enumerate} - -\section{The Theory Organization} -The semantic theory is organized in a quite conventional manner in -three layers. The first layer, called the \emph{denotational - semantics} comprises a set of definitions of the operators of the -language. Presented as \emph{definitional axioms} inside -Isabelle/HOL, this part assures the logically consistency of the -overall construction. The second layer, called \emph{logical layer}, -is derived from the former and centered around the notion of validity -of an OCL formula $P$ for a state-transition from pre-state $\sigma$ -to post-state $\sigma'$, validity statements were written $(\sigma, -\sigma') \models P$. The third layer, called \emph{algebraic layer}, -also derived from the former layers, tries to establish algebraic laws -of the form $P = P'$; such laws are amenable to equational reasoning -and also help for automated reasoning and code-generation. - -For space reasons, we will restrict ourselves in this paper to a few -operators and make a traversal through all three layers to give a -high-level description of our formalization. Especially, the details -of the semantic construction for sets and the handling of objects and -object universes were excluded from a presentation here. - -\subsection{Denotational Semantics} - OCL is composed of - \begin{enumerate} - \item operators on built-in data structures such as - \inlineocl{Boolean}, \inlineocl{Integer}, or \inlineocl{Set(A)}, - \item operators of the user-defined data-model such as accessors, - type-casts and tests, and - \item user-defined, side-effect-free methods. - \end{enumerate} - Conceptually, an OCL expression in general and Boolean expressions in - particular (\ie, \emph{formulae}) depends on the pair $(\sigma, - \sigma')$ of pre-and post-state. The precise form of states is - irrelevant for this paper (compare~\cite{brucker.ea:ocl-null:2009}) - and will be left abstract in this presentation. We construct in - Isabelle a type-class $\TCnull$ that contains two distinguishable - elements $\HolBot$ and $\HolNull$. Any type of the form - $\up{(\up{\alpha})}$ is an instance of this type-class with $\HolBot - \equiv \isasymbottom$ and $\HolNull \equiv \lfloor \isasymbottom \rfloor$. -Now, any OCL type can be represented by an HOL type of the form: -\begin{equation*} - \V{}{\alpha} \defeq \state{} \times \state{} \to \alpha \ofType \TCnull \mi{.} -\end{equation*} -On this basis, we define $\V{}{\up{(\up{\HolBoolean })}}$ as the HOL -type for the OCL type $\mocl{Boolean}$ and define: -\begin{gather*} -\begin{alignedat}{3} -I\semantics{\mocl{invalid}\ofType V(\alpha)} \tau &\equiv \HolBot & -\qquad I\semantics{\mocl{null}\ofType V(\alpha)} \tau &\equiv \HolNull\\ -I\semantics{\mocl{true}\ofType\mocl{Boolean}} \tau &=\lfloor\lfloor -\HolTrue\rfloor\rfloor & -I\semantics{\mocl{false}} \tau &= \lfloor\lfloor\HolFalse\rfloor\rfloor\\ -\end{alignedat}\\ -I\semantics{X\mocl{.oclIsUndefined()}} \tau = - (\HolIf I\semantics{X}\tau \in \{\HolBot, \HolNull\} \HolThen I\semantics{\mocl{true}}\tau \HolElse I\semantics{\mocl{false}}\tau)\\ - I\semantics{X\mocl{.oclIsInvalid()}} \tau = - (\HolIf I\semantics{X}\tau = \HolBot \HolThen I\semantics{\mocl{true}}\tau \HolElse I\semantics{\mocl{false}}\tau) -\end{gather*} -where $I\semantics{E}$ is the semantic interpretation function -commonly used in mathematical textbooks and $\tau$ stands for pairs of -pre- and post state $(\sigma, \sigma')$. For reasons of conciseness, -we will write $\delta~X$ for $\mocl{not}\;X\mocl{.oclIsUndefined()}$ -and $\upsilon~X$ for $\mocl{not}\;X\mocl{.oclIsInvalid()}$ throughout -this paper. - -Due to the used style of -semantic representation (a shallow embedding) $I$ is in fact -superfluous and defined semantically as the identity; instead of: -\begin{gather*} -I\semantics{\mocl{true}\ofType\mocl{Boolean}} \tau =\lfloor\lfloor \HolTrue\rfloor\rfloor -\shortintertext{we can therefore write:} -\mocl{true}\ofType\mocl{Boolean} = \lambda \tau. \lfloor\lfloor -\HolTrue\rfloor\rfloor -\end{gather*} -In Isabelle theories, this particular presentation of definitions -paves the way for an automatic check that the underlying equation -has the form of an \emph{axiomatic -definition} and is therefore logically safe. -Since all operators of the assertion language depend on the context $\tau$ = $(\sigma, -\sigma')$ and result in values that can be $\isasymbottom$, all expressions can -be viewed as \emph{evaluations} from $(\sigma, \sigma')$ to a type $\alpha$ -which must posses a $\bottom$ and a $\text{null}$-element. Given that such -constraints can be expressed in Isabelle/HOL via \emph{type classes} (written: $\alpha::\kappa$), -all types for OCL-expressions are of a form captured by - \begin{equation*} - \V{}{\alpha} \defeq \state{} \times \state{} \to \alpha::\{bot,null\} \mi{,} - \end{equation*} -where $\state{}$ stands for the system state and $\state{} \times -\state{}$ describes the pair of pre-state and post-state and -$\_\defeq\_$ denotes the type abbreviation. - -The current OCL semantics~\cite[Annex A]{omg:ocl:2003} uses different -interpretation functions for invariants and pre-conditions; we achieve -their semantic effect by a syntactic transformation $\__\text{pre}$ -which replaces, for example, all accessor functions -$\getAttrib{\_}{a}$ by their counterparts -$\getAttrib{\_}{a\isasymOclATpre}$. For example, -$(\getAttrib{\self}{a} > 5)_\text{pre}$ is just -$(\getAttrib{\self}{a\isasymOclATpre} > 5)$. This way, also invariants -and pre-conditions can be interpreted by the same interpretation -function and have the same type of an evaluation $\V{}{\alpha}$. - - -On this basis, one can define the core logical operators $\mocl{not}$ -and $\mocl{and}$ as follows: -\begin{gather*} - \begin{array}{ll} - I\semantics{\mocl{not}\; X} \tau - &= (\HolCase I\semantics{X} \tau \HolOf\\ - &\quad\begin{array}{ll} - ~ \bottom &\Rightarrow \bottom \\ - | \lfloor \bottom \rfloor &\Rightarrow \lfloor \bottom \rfloor \\ - | \lfloor \lfloor x \rfloor \rfloor &\Rightarrow \lfloor \lfloor \lnot x \rfloor \rfloor ) - \end{array} - \end{array} -\end{gather*} - -\begin{gather*} - \begin{array}{ll} - I\semantics{X\;\mocl{and}\; Y} \tau - &= (\HolCase I\semantics{X} \tau \HolOf\\ - &\quad\begin{array}{ll} - ~ \bottom &\Rightarrow - (\HolCase I\semantics{Y} \tau \HolOf\\ - &\quad\begin{array}{ll} - ~ \bottom &\Rightarrow \bottom \\ - | \lfloor \bottom \rfloor &\Rightarrow \bottom \\ - | \lfloor \lfloor \HolTrue \rfloor \rfloor - &\Rightarrow \bottom\\ - | \lfloor \lfloor \HolFalse \rfloor \rfloor - &\Rightarrow \lfloor \lfloor \HolFalse \rfloor \rfloor )\\ - \end{array} - \\ - | \lfloor \bottom \rfloor &\Rightarrow - (\HolCase I\semantics{Y} \tau \HolOf\\ - &\quad\begin{array}{ll} - ~ \bottom &\Rightarrow - \bottom \\ - | \lfloor \bottom \rfloor &\Rightarrow \lfloor - \bottom \rfloor \\ - | \lfloor \lfloor \HolTrue \rfloor \rfloor - &\Rightarrow \lfloor \bottom\rfloor\\ - | \lfloor \lfloor \HolFalse \rfloor \rfloor - &\Rightarrow \lfloor \lfloor \HolFalse \rfloor \rfloor )\\ - \end{array} - \\ - | \lfloor \lfloor \HolTrue \rfloor \rfloor &\Rightarrow - (\HolCase I\semantics{Y} \tau \HolOf\\ - &\quad\begin{array}{ll} - ~ \bottom &\Rightarrow - \bottom \\ - | \lfloor \bottom \rfloor &\Rightarrow \lfloor - \bottom \rfloor \\ - | \lfloor \lfloor y \rfloor \rfloor - &\Rightarrow \lfloor \lfloor y \rfloor \rfloor )\\ - \end{array} - \\ - | \lfloor \lfloor \HolFalse \rfloor \rfloor - &\Rightarrow \lfloor \lfloor \HolFalse \rfloor - \rfloor )\\ - \end{array}\\ -\end{array} -\end{gather*} -These non-strict operations were used to define the other logical connectives in the -usual classical way: $X\; \mocl{or}\; Y \equiv (\mocl{not}\; X)\; -\mocl{and}\; (\mocl{not}\; Y)$ or -$X\;\mocl{implies}\;Y \equiv (\mocl{not}\; X)\;\mocl{or}\; Y$. - -The default semantics for an OCL library operator is strict -semantics; this means that the result of an operation $f$ is -\inlineisar+invalid+ if one of its arguments is \inlineisar+invalid+. -For a semantics comprising \inlineisar+null+, we suggest to stay -conform to the standard and define the addition for integers as -follows: - \begin{gather*} - \begin{array}{rl} - I\semantics{x \;\mocl{+}\; y}\tau = &\HolIf I\semantics{\delta ~ x}\tau =\lfloor \lfloor \HolTrue\rfloor \rfloor \land I\semantics{\delta ~ y}\tau =\lfloor \lfloor \HolTrue\rfloor \rfloor \\ - &\HolThen \lfloor \lfloor \lceil \lceil I\semantics{x}\tau \rceil \rceil + \lceil \lceil I\semantics{y}\tau \rceil \rceil \rfloor \rfloor\\ - &\HolElse \bottom - \end{array} - \end{gather*} - where the operator ``\mocl{+}'' on the left-hand - side of the equation denotes the OCL addition of type - $[\V{}{\up{(\up{\HolInteger})}}, \V{}{\up{(\up{\HolInteger})}}] \Rightarrow - \V{}{\up{(\up{\HolInteger})}}$ while the ``$+$'' on the right-hand side of - the equation of type $[\HolInteger,\HolInteger]\Rightarrow - \HolInteger$ denotes the integer-addition from the HOL library. - -\subsection{Logical Layer} -The topmost goal of the logic for OCL is to define the \emph{validity statement}: -\begin{equation*} - (\sigma, \sigma') \isasymMathOclValid P\mi{,} -\end{equation*} -where $\sigma$ is the pre-state and $\sigma'$ the post-state of the -underlying system and $P$ is a formula. -Informally, a formula $P$ is valid if and only if its evaluation in -$(\sigma, \sigma')$ (\ie, $\tau$ for short) yields true. Formally this means: -\begin{equation*} -\tau \isasymMathOclValid P \equiv \bigl(I\semantics{P} \tau = \lfloor \lfloor \HolTrue \rfloor \rfloor \bigr)\mi{.} -\end{equation*} -On this basis, classical, two-valued inference rules can be established for -reasoning over the logical connective, the different notions of equality, -definedness and validity. Generally speaking, rules over logical validity can -relate bits and pieces in various OCL terms and allow---via strong -logical equality discussed below---the replacement -of semantically equivalent sub-expressions. The core inference rules are: -\begin{gather*} -\begin{array}{lccr} - \tau \models \mocl{true} &\quad - \lnot(\tau \models \mocl{false})&\quad - \lnot(\tau \models \mocl{invalid})&\quad - \lnot(\tau \models \mocl{null}) -\end{array}\\ - \tau \models \mocl{not}\; P \Longrightarrow \lnot (\tau \models P)\\ -\begin{array}{lcr} - \tau \models P \;\mocl{and}\; Q \Longrightarrow \tau \models P&\qquad& - \tau \models P \;\mocl{and}\; Q \Longrightarrow \tau \models Q -\end{array}\\ - \tau \models P \Longrightarrow - (\mocl{if}\; P \;\mocl{then}\; B_1 \;\mocl{else}\; B_2 \;\mocl{endif})\tau = B_1\ap \tau\\ - \tau \models \mocl{not}\; P \Longrightarrow - (\mocl{if}\; P \;\mocl{then}\; B_1 \;\mocl{else}\; B_2 \;\mocl{endif})\tau = B_2\ap \tau\\ -\begin{array}[lcr]{lcr} - \tau \models P \Longrightarrow \tau \models \delta \ap P &\qquad& - \tau \models \delta \ap X \Longrightarrow \tau \models \upsilon \ap X -\end{array} -\end{gather*} -By the latter two properties it can be inferred that any valid -property $P$ (so for example: a valid invariant) is defined, which -allows to infer for terms composed by strict operations that their -arguments and finally the variables occurring in it are valid or -defined. - -We propose to distinguish the \emph{strong logical equality} (written -$\_ \isasymMathOclStrongEq \_$), which follows the general principle -that ``equals can be replaced by equals,'' from the \emph{strict - referential equality} (written $\_ \isasymMathOclStrictEq \_$), -which is an object-oriented concept that attempts to approximate and -to implement the former. Strict referential equality, which is the -default in the OCL language and is written \inlineocl|_ = _| -in the standard, is an overloaded concept and has to be defined for -each OCL type individually; for objects resulting from class -definitions, it is implemented by comparing the references to -the objects. In contrast, strong logical equality is a polymorphic -concept which is defined once and for all by: -\begin{gather*} - I\semantics{X \triangleq Y} \tau \equiv \lfloor \lfloor - I\semantics{X} \tau= - I\semantics{Y} \tau \rfloor \rfloor -\shortintertext{It enjoys nearly the laws of a congruence:} -\tau \models (x \triangleq x)\\ -\tau \models (x \triangleq y) \Longrightarrow \tau \models (y \triangleq x)\\ -\tau \models (x \triangleq y) \Longrightarrow \tau \models (y \triangleq z) \Longrightarrow \tau \models (x \triangleq z)\\ -\HolOclCp P \Longrightarrow \tau \models (x \triangleq y) \Longrightarrow \tau \models (P\ap x) \Longrightarrow \tau \models (P\ap y) -\end{gather*} -where the predicate $\HolOclCp$ stands for \emph{context-passing}, a -property that is characterized by $P(X)$ equals $\lambda \tau\spot -P(\lambda \_\spot X \tau) \tau$. It means that the state tuple $\tau = -(\sigma, \sigma')$ is passed unchanged from surrounding expressions to -sub-expressions. it is true for all pure OCL expressions (but not -arbitrary mixtures of OCL and HOL) in Featherweight OCL\@. The -necessary side-calculus for establishing $\HolOclCp$ can be fully -automated. - -The logical layer of the Featherweight OCL rules gives also a means -to convert an OCL formula living in its four-valued world into a -representation that is classically two-valued and can be processed by -standard SMT solvers such as CVC3~\cite{barrett.ea:cvc3:2007} or -Z3~\cite{moura.ea:z3:2008}. $\delta$-closure rules for all logical -connectives have the following format, \eg: -\begin{gather*} -\tau \models \delta \ap x \Longrightarrow (\tau \models \ap\mocl{not}\ap x) = (\lnot (\tau \models x))\\ -\tau \models \delta \ap x \Longrightarrow \tau \models \delta \ap y \Longrightarrow (\tau \models x \ap\mocl{and}\ap y) = ( \tau \models x \land \tau \models y)\\ -\begin{multlined} -\tau \models \delta \ap x \Longrightarrow \tau \models \delta \ap y \\ -\Longrightarrow (\tau \models (x \ap\mocl{implies}\ap y)) = ( (\tau \models x) \longrightarrow (\tau \models y)) -\end{multlined} -\end{gather*} -Together with the general case-distinction -\begin{gather*} - \tau \models \delta \ap x \lor \tau \models x \triangleq \mocl{invalid} \lor \tau \models x \triangleq \mocl{null} \mi{,} -\end{gather*} -which is possible for any OCL type, a case distinction on the -variables in a formula can be performed; due to strictness rules, -formulae containing somewhere a variable $x$ that is known to be -$\mocl{invalid}$ or $\mocl{null}$ reduce usually quickly to -contradictions. For example, we can infer from an invariant $\tau -\models x \isasymMathOclStrictEq y \;\mocl{-}\; \mocl{3}$ that we have $\tau -\models x \isasymMathOclStrictEq y \;\mocl{-}\; \mocl{3} \land \tau \models -\delta \ap x \land \tau \models \delta \ap y$. We call the latter formula the -$\delta$-closure of the former. Now, we can convert a formula like -$\tau \models x \;\mocl{>}\; \mocl{0} \ap\mocl{or}\ap \mocl{3} \;\mocl{*}\; y \;\mocl{>}\; -x \;\mocl{*}\; x$ into the equivalent formula -$\tau \models x \;\mocl{>}\; \mocl{0} \lor \tau -\models \mocl{3} \;\mocl{*}\; y \;\mocl{>}\; x \;\mocl{*}\; x$ and thus internalize the -OCL-logic into a classical (and more tool-conform) logic. This -works---for the price of a potential, but due to the usually ``rich'' -$\delta$-closures of invariants rare---exponential blow-up of the -formula for all OCL formulas. - -\subsection{Algebraic Layer} -Based on the logical layer, we build a system with simpler rules which -are amenable to automated reasoning. We restrict ourselves to pure -equations on OCL expressions, where the used equality is the -meta-(HOL-)equality. - -Our denotational definitions on \inlineocl+not+ and \inlineocl+and+ -can be re-formulated in the following ground equations: -\begin{gather*} - \begin{aligned} - \upsilon\; \mocl{invalid} &= \mocl{false}&\qquad - \upsilon\; \mocl{null} &= \mocl{true}\\ - \upsilon\; \mocl{true} &= \mocl{true}&\qquad - \upsilon\; \mocl{false} &= \mocl{true}\\ -\end{aligned}\\[.04\baselineskip] -\begin{aligned} - % - \delta\; \mocl{invalid} &= \mocl{false}&\qquad - \delta\; \mocl{null} &= \mocl{false}\\ - \delta\; \mocl{true} &= \mocl{true}&\qquad - \delta\; \mocl{false} &= \mocl{true}\\ -\end{aligned}\\[.04\baselineskip] -\begin{aligned} - % - \mocl{not}\; \mocl{invalid} &= \mocl{invalid}&\qquad - \mocl{not}\; \mocl{null} &= \mocl{null}\\ - \mocl{not}\; \mocl{true} &= \mocl{false}&\qquad - \mocl{not}\; \mocl{false} &= \mocl{true}\\ -\end{aligned}\\[.04\baselineskip] -\begin{aligned} - % - (\mocl{null} \;\mocl{and}\; \mocl{true}) &= \mocl{null}&\qquad - (\mocl{null} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ - (\mocl{null} \;\mocl{and}\; \mocl{null}) &= \mocl{null}&\qquad - (\mocl{null} \;\mocl{and}\; \mocl{invalid}) &= \mocl{invalid}\\ -\end{aligned}\\[.04\baselineskip] -\begin{aligned} - % - (\mocl{false} \;\mocl{and}\; \mocl{true}) &= \mocl{false}&\qquad - (\mocl{false} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ - (\mocl{false} \;\mocl{and}\; \mocl{null}) &= \mocl{false}&\qquad - (\mocl{false} \;\mocl{and}\; \mocl{invalid}) &= \mocl{false}\\ -\end{aligned}\\[.04\baselineskip] -\begin{aligned} - % - (\mocl{true} \;\mocl{and}\; \mocl{true}) &= \mocl{true}&\qquad - (\mocl{true} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ - (\mocl{true} \;\mocl{and}\; \mocl{null}) &= \mocl{null}&\qquad - (\mocl{true} \;\mocl{and}\; \mocl{invalid}) &= \mocl{invalid} -\end{aligned}\\[.04\baselineskip] -\begin{aligned} - (\mocl{invalid} \;\mocl{and}\; \mocl{true}) &= \mocl{invalid} \\ - (\mocl{invalid} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ - (\mocl{invalid} \;\mocl{and}\; \mocl{null}) &= \mocl{invalid} \\ - (\mocl{invalid} \;\mocl{and}\; \mocl{invalid}) &= \mocl{invalid}\\ -\end{aligned} -\shortintertext{On this core, the structure of a conventional lattice arises:} - \begin{aligned} - X \;\mocl{and}\; X &= X &\qquad X \;\mocl{and}\; Y &= Y \;\mocl{and}\; X - \end{aligned}\\ - \begin{aligned} - \mocl{false} \;\mocl{and}\; X &= \mocl{false} &\qquad - X \;\mocl{and}\; \mocl{false} &= \mocl{false} \\ - \mocl{true} \;\mocl{and}\; X &= X &\qquad - X \;\mocl{and}\; \mocl{true} &= X - \end{aligned}\\ - \begin{aligned} - X \;\mocl{and}\; (Y \;\mocl{and}\; Z) &= X \;\mocl{and}\; Y \;\mocl{and}\; Z - \end{aligned} -\end{gather*} -as well as the dual equalities for \inlineocl|_ or _| and the De Morgan -rules. This wealth of algebraic properties makes the understanding of -the logic easier as well as automated analysis possible: it allows -for, for example, computing a DNF of invariant systems (by -clever term-rewriting techniques) which are a prerequisite for -$\delta$-closures. - -The above equations explain the behavior for the most-important -non-strict operations. The clarification of the exceptional behaviors -is of key-importance for a semantic definition the standard and the -major deviation point from -HOL-OCL~\cite{brucker.ea:hol-ocl:2008,brucker.ea:hol-ocl-book:2006}, -to Featherweight OCL as presented here. The -standard expresses at many places that most operations are strict, -\ie, enjoy the properties (exemplary for \inlineocl{_ + _}): -\begin{gather*} - \begin{aligned} - \mocl{invalid}\;\mocl{+}\; X &= \mocl{invalid}&\qquad - X \;\mocl{+}\; \mocl{invalid} &= \mocl{invalid}\\ - X \;\mocl{+}\; \mocl{null} &= \mocl{invalid}&\qquad - \mocl{null} \;\mocl{+}\; X &= \mocl{invalid} - \end{aligned}\\ - \mocl{null.oclAsType(}X\mocl{)} = \mocl{invalid} -\shortintertext{besides ``classical'' exceptional behavior:} - \begin{aligned} - \mocl{1} \;\mocl{/}\; \mocl{0} &= \mocl{invalid} \quad &\quad - \mocl{1} \;\mocl{/}\; \mocl{null} &= \mocl{invalid} - \end{aligned}\\ - \mocl{null->isEmpty()}=\mocl{true} -\end{gather*} - -Moreover, there is also the proposal to use \inlineocl+null+ as a kind -of ``don't know'' value for all strict operations, not only in the -semantics of the logical connectives. Expressed in algebraic -equations, this semantic alternative (this is \emph{not} -Featherweight OCL at present) would boil down to: -\begin{gather*} - \begin{aligned} - \mocl{invalid} \;\mocl{+}\; X &= \mocl{invalid} &\qquad - X \;\mocl{+}\; \mocl{invalid} &= \mocl{invalid}\\ - X \;\mocl{+}\; \mocl{null} &= \mocl{null}&\qquad - \mocl{null} \;\mocl{+}\; X &= \mocl{null} - \end{aligned}\\ - \mocl{null.oclAsType(}X\mocl{)} = \mocl{null}\\ - \begin{aligned} - \mocl{1} \;\mocl{/}\; \mocl{0} &= \mocl{invalid} \quad &\quad - \mocl{1} \;\mocl{/}\; \mocl{null} &= \mocl{null} - \end{aligned}\\ - \mocl{null->isEmpty()}=\mocl{null} -\end{gather*} - -While this is logically perfectly possible, while it can be argued -that this semantics is ``intuitive'', and although we do not expect a -too heavy cost in deduction when computing $\delta$-closures, we -object that there are other, also ``intuitive'' interpretations that -are even more wide-spread: In classical spreadsheet programs, for -example, the semantics tends to interpret \inlineocl+null+ -(representing empty cells in a sheet) as the neutral element of the -type, so \inlineocl{0} or the empty string, for example.\footnote{In - spreadsheet programs the interpretation of \inlineisar+null+ varies - from operation to operation; \eg, the \inlineocl+average+ - function treats \inlineocl+null+ as non-existing value and not as - \inlineocl{0}.} This semantic alternative (this is -\emph{not} Featherweight OCL at present) would yield: -\begin{gather*} - \begin{aligned} - \mocl{invalid} \;\mocl{+}\; X &= \mocl{invalid} &\qquad - X \;\mocl{+}\; \mocl{invalid} &= \mocl{invalid}\\ - X \;\mocl{+}\; \mocl{null} &= X&\qquad - \mocl{null} \;\mocl{+}\; X &= X - \end{aligned}\\ - \mocl{null.oclAsType(}X\mocl{)} = \mocl{invalid}\\ - \begin{aligned} - \mocl{1} \;\mocl{/}\; \mocl{0} &= \mocl{invalid} \quad &\quad - \mocl{1} \;\mocl{/}\; \mocl{null} &= \mocl{invalid} -\end{aligned}\\ - \mocl{null->isEmpty()}=\mocl{true} -\end{gather*} - -Algebraic rules are also the key for execution and compilation -of Featherweight OCL expressions. We derived, \eg: -\begin{gather*} -\delta\; \mocl{Set\{\}} = \mocl{true}\\ -\delta\; (X\mocl{->including(}x\mocl{)}) = \delta \ap X \;\mocl{and}\; -\delta \ap x\\ -\begin{aligned} -\mocl{Set\{\}->includes(}x\mocl{)} = (\mocl{if}\; \upsilon\; x\; &\mocl{then false}\\ -&\mocl{else invalid endif}) -\end{aligned}\\ -\begin{multlined} - {(X\mocl{->including(}x\mocl{)->includes(}y\mocl{)})=}\\ - \mbox{\hspace{3.2cm}}\qquad{\begin{aligned} - (&\mocl{if}\; \delta\; X\\ - &\mocl{then}\; -\begin{array}[t]{l} -\mocl{if}\; x \doteq y\\ -\mocl{then}\ap \mocl{true} \\ -\mocl{else}\ap X\mocl{->includes(}y\mocl{)}\\ -\mocl{endif} - \end{array}\\ -&\mocl{else invalid} \\ - &\mocl{endif}) - \end{aligned}} -\end{multlined} -\end{gather*} -As \inlineocl+Set{1,2}+ is only syntactic sugar for -\begin{ocl} - Set{}->including(1)->including(2) -\end{ocl} -an expression like \inlineocl+Set{1,2}->includes(null)+ becomes -decidable in Featherweight OCL by a combination of -rewriting and code-generation and execution. The generated -documentation from the theory files can thus be enriched by numerous -``test-statements'' like: -\begin{isar}[mathescape] -value "\ \ ($\mathtt{Set\{Set\{2,null\}\}}$ \ $\;\mathtt{Set\{Set\{null,2\}\}}$)" -\end{isar} -which have been machine-checked and which present a high-level and in -our opinion fairly readable information for OCL tool manufactures and -users. - - -\section{Object-oriented Datatype Theories} -As mentioned earlier, the OCL is composed of -\begin{enumerate} -\item operators on built-in data structures such as Boolean, Integer or Set(\_), - and -\item operators of the user-defined data model such as accessors, - type casts and tests. -\end{enumerate} - -In the following, we will refine the concepts of a user-defined -data-model (implied by a \emph{class-model}, visualized by a class-diagram) -as well as the notion of $\state{}$ used in the -previous section to much more detail. In contrast to wide-spread -opinions, UML class diagrams represent in a compact and visual manner -quite complex, object-oriented data-types with a surprisingly rich -theory. It is part of our endeavor here to make this theory explicit -and to point out corner cases. A UML class diagram---underlying a -given OCL formula---produces several implicit operations which -become accessible via appropriate OCL syntax: - -\begin{enumerate} -\item Classes and class names (written as $C_1$, \ldots, $C_n$), which - become types of data in OCL\@. Class names declare two projector - functions to the set of all objects in a state: - $C_i$\inlineocl{.allInstances()} and - $C_i$\inlineocl{.allInstances}$\isasymOclATpre$\inlineocl{()}, -\item an inheritance relation $\_ < \_$ on classes and a collection of - attributes $A$ associated to classes, -\item two families of accessors; for each attribute $a$ in a - class definition (denoted - $\getAttrib{X}{\text{$a$}} :: C_i \rightarrow A $ and - $\getAttrib{X}{\text{$a$}\isasymOclATpre}:: C_i \rightarrow A $ for - $A\in \{\V{}{\up{\ldots}}, C_1, \ldots, C_n\}$), -\item type casts that can change the static type of an object of a - class ($\getAttrib{X}{\mocl{oclAsType(}\text{$C_i$}\mocl{)}}$ of type - $C_j \rightarrow C_i$) -\item two dynamic type tests ($\getAttrib{X}{\mocl{oclIsTypeOf(}\text{$C_i$}\mocl{)}}$ and - $\getAttrib{X}{\mocl{oclIsKindOf(}\text{$C_i$}\mocl{)}}$ ), -\item and last but not least, for each class name $C_i$ there is an - instance of the overloaded referential equality (written $\_ - \isasymMathOclStrictEq \_$). -\end{enumerate} - - -Assuming a strong static type discipline in the sense of -Hindley-Milner types, Featherweight OCL has no ``syntactic -subtyping.'' This does not mean that subtyping cannot be expressed -\emph{semantically} in Featherweight OCL; by giving a formal semantics -to type-casts, subtyping becomes an issue of the front-end that can -make implicit type-coersions explicit by introducing explicit -type-casts. Our perspective shifts the emphasis on the semantic -properties of casting, and the necessary universe of object -representations (induced by a class model) that allows to establish -them. - - -\subsection{Object Universes} - -It is natural to construct system states by a set of partial functions -$f$ that map object identifiers $\oid$ to some representations of -objects: -\begin{gather} - \typedef \qquad \alpha~\state{} \defeq \{ \sigma :: - \oid \isasymrightharpoonup \alpha \ap|\ap \inv_\sigma(\sigma) \} -\end{gather} -where $\inv_\sigma$ is a to be discussed invariant on states. - -The key point is that we need a common type $\alpha$ for the set of all -possible \emph{object representations}. Object representations model -``a piece of typed memory,'' \ie, a kind of record comprising -administration information and the information for all attributes of -an object; here, the primitive types as well as collections over them -are stored directly in the object representations, class types and -collections over them are represented by $\oid$'s (respectively lifted -collections over them). - -In a shallow embedding which must represent -UML types injectively by HOL types, there are two fundamentally -different ways to construct such a set of object representations, -which we call an \emph{object universe} $\mathfrak{A}$: -\begin{enumerate} -\item an object universe can be constructed for a given class model, - leading to \emph{closed world semantics}, and -\item an object universe can be constructed for a given class model - \emph{and all its extensions by new classes added into the leaves of - the class hierarchy}, leading to an \emph{open world semantics}. -\end{enumerate} -For the sake of simplicity, we chose the first option for -Featherweight OCL, while HOL-OCL~\cite{brucker.ea:extensible:2008-b} -used an involved construction allowing the latter. - -A na\"ive attempt to construct $\mathfrak{A}$ would look like this: -the class type $C_i$ induced by a class will be the type of such an -object representation: $C_i \defeq (\oid \times A_{i_1} \times \cdots -\times A_{i_k} )$ where the types $A_{i_1}$, \ldots, $A_{i_k}$ are the -attribute types (including inherited attributes) with class types -substituted by $\oid$. The function $\HolOclOidOf$ projects the first -component, the $\oid$, out of an object representation. Then the -object universe will be constructed by the type definition: -\begin{gather} -\mathfrak{A} := C_1 + \cdots + C_n\mi{.} -\end{gather} -It is possible to define constructors, accessors, and the referential -equality on this object universe. However, the treatment of type casts -and type tests cannot be faithful with common object-oriented -semantics, be it in UML or Java: casting up along the class hierarchy -can only be implemented by loosing information, such that casting up -and casting down will \emph{not} give the required identity: - -\begin{gather} - X.\mocl{oclIsTypeOf(}C_k\mocl{)} ~ ~ \mocl{implies} ~ ~ X\mocl{.oclAsType(}C_i\mocl{)}\mocl{.oclAsType(}C_k\mocl{)} \isasymMathOclStrictEq - X \\ - \qquad \qquad \qquad \qquad \qquad \qquad \text{whenever $C_k < C_i$ and $X$ is valid.} -\end{gather} - - -To overcome this limitation, we introduce an auxiliary type -$C_{i\text{ext}}$ for \emph{class type extension}; together, they were -inductively defined for a given class diagram: - -Let $C_i$ be a class with a possibly empty set of subclasses -$\{C_{j_{1}}, \ldots, C_{j_{m}}\}$. -\begin{itemize} -\item Then the \emph{class type extension} $C_{i\text{ext}}$ - associated to $C_i$ is - $A_{i_{1}} \times \cdots \times A_{i_{n}} \times \up{(C_{j_{1}\text{ext}} + \cdots + C_{j_{m}\text{ext}})}$ - where $A_{i_{k}}$ ranges over the local - attribute types of $C_i$ and $C_{j_{l}\text{ext}}$ - ranges over all class type extensions of the subclass $C_{j}$ of $C_i$. -\item Then the \emph{class type} for $C_i$ is - $oid \times A_{i_{1}} \times \cdots \times A_{i_{n}} \times \up{(C_{j_{1}\text{ext}} + \cdots + C_{j_{m}\text{ext}})}$ - where $A_{i_{k}}$ ranges over the inherited \emph{and} local - attribute types of $C_i$ and $C_{j_{l}\text{ext}}$ - ranges over all class type extensions of the subclass $C_{j}$ of $C_i$. -\end{itemize} - -Example instances of this scheme---outlining a compiler---can be found -in \autoref{ex:employee-analysis:uml} and \autoref{ex:employee-design:uml}. - -This construction can \emph{not} be done in HOL itself since it -involves quantifications and iterations over the ``set of class-types''; -rather, it is a meta-level construction. Technically, this means that -we need a compiler to be done in SML on the syntactic -``meta-model''-level of a class model. - -With respect to our semantic construction here, -which above all means is intended to be type-safe, this has the following consequences: -\begin{itemize} -\item there is a generic theory of states, which must be formulated independently - from a concrete object universe, -\item there is a principle of translation (captured by the inductive scheme for - class type extensions and class types above) that converts a given class model - into an concrete object universe, -\item there are fixed principles that allow to derive the semantic theory of any - concrete object universe, called the \emph{object-oriented datatype theory.} -\end{itemize} -We will work out concrete examples for the construction of the -object-universes in \autoref{ex:employee-analysis:uml} and \autoref{ex:employee-design:uml} and the -derivation of the respective datatype theories. While an -automatization is clearly possible and desirable for concrete -applications of Featherweight OCL, we consider this out of the scope -of this paper which has a focus on the semantic construction and its -presentation. - - -\subsection{Accessors on Objects and Associations} -Our choice to use a shallow embedding of OCL in HOL and, thus having -an injective mapping from OCL types to HOL types, results in -type-safety of Featherweight OCL\@. Arguments and results of accessors -are based on type-safe object representations and \emph{not} $\oid$'s. -This implies the following scheme for an accessor: -\begin{itemize} -\item The \emph{evaluation and extraction} phase. If the argument - evaluation results in an object representation, the $\oid$ is - extracted, if not, exceptional cases like \inlineocl{invalid} are - reported. -\item The \emph{dereferentiation} phase. The $\oid$ is interpreted in - the pre- or post-state, %(depending on the suffix of accessor), - the resulting object is casted to the expected format. The - exceptional case of nonexistence in this state must be treated. -\item The \emph{selection} phase. The corresponding attribute is - extracted from the object representation. -\item The \emph{re-construction} phase. The resulting value has to be - embedded in the adequate HOL type. If an attribute has the type of - an object (not value), it is represented by an optional (set of) - $\oid$, which must be converted via dereferentiation in one of the - states to produce an object representation again. The - exceptional case of nonexistence in this state must be treated. -\end{itemize} - -The first phase directly translates into the following formalization: -\begin{multline} - \shoveleft{\definitionS}\quad\\ - \begin{array}{rllr} - \operatorname{eval\_extract} X\ap f = (\lambda \tau\spot \HolCase - X\ap - \tau \HolOf & \bottom &\Rightarrow - \mocl{invalid}\ap\tau&\text{exception}\\ - |& \lift{\bottom} &\Rightarrow - \mocl{invalid}\ap\tau&\text{deref. null}\\ - |& \lift{\lift{\mathit{obj}}} &\Rightarrow f\ap (\operatorname{oid\_of} \ap \mathit{obj})\ap\tau)& - \end{array} -\end{multline} - -For each class $C$, we introduce the dereferentiation phase of this -form: -\begin{multline} - \definitionS \ap - \operatorname{deref\_oid}_C \ap \mathit{fst\_snd}\ap f\ap \mathit{oid} = - (\lambda \tau\spot \HolCase\ap (\operatorname{heap}\ap - (\mathit{fst\_snd}\ap \tau))\ap \mathit{oid}\ap - \HolOf\\ - \begin{array}{ll} - \phantom{|}\ap \lift{\operatorname{in}_C obj} &\Rightarrow f\ap - \mathit{obj} \ap \tau\\ - |\ap \_ &\Rightarrow \mocl{invalid}\ap \tau) - \end{array} - \end{multline} - -The operation yields undefined if the $\oid$ is uninterpretable in the -state or referencing an object representation not conforming to the -expected type. - -We turn to the selection phase: for each class $C$ in the class model -with at least one attribute, -and each attribute $a$ in this class, -we introduce the selection phase of this form: -\begin{gather} - \begin{array}{rlcll} - \definitionS \ap - \operatorname{select}_a \ap f = (\lambda & - \operatorname{mk}_C \ap oid & \cdots \bottom \cdots & C_{X\text{ext}} & \Rightarrow \mocl{null}\\ - |& \operatorname{mk}_C \ap oid & \cdots \lift{a} \cdots & C_{X\text{ext}} - &\Rightarrow f\ap (\lambda \ap x \ap \_\spot - \lift{\lift{x}})\ap a) - \end{array} -\end{gather} - -This works for definitions of basic values as well as for object -references in which the $a$ is of type $\oid$. To increase -readability, we introduce the functions: -\begin{gather} -\begin{array}{llrlr} -\qquad\qquad&\definitionS\enspace&\operatorname{in\_pre\_state} &= \operatorname{fst} & \qquad \text{first component}\\ -\qquad\qquad&\definitionS\enspace&\operatorname{in\_post\_state} &= \operatorname{snd} & \qquad \text{second component} \\ -\qquad\qquad&\definitionS\enspace&\operatorname{reconst\_basetype} &= \operatorname{id} & \qquad \text{identity function} -\end{array} -\end{gather} - - -Let \_\inlineocl{.getBase} be an accessor of class $C$ yielding a -value of base-type $A_{base}$. Then its definition is of the form: -\begin{gather} - \begin{array}{lll} -\definitionS&\_\mocl{.getBase} &\ofType \ap C \Rightarrow A_{base}\\ -\where\enspace&X\mocl{.getBase} &= \operatorname{eval\_extract}\ap X\ap - (\operatorname{deref\_oid}_C\ap \operatorname{in\_post\_state}\ap\\ - & &\quad (\operatorname{select}_\text{getBase}\ap \operatorname{reconst\_basetype})) - \end{array} -\end{gather} - -Let \_\inlineocl{.getObject} be an accessor of class $C$ yielding a -value of object-type $A_{object}$. Then its definition is of the form: -\begin{gather} - \begin{array}{lll} -\definitionS&\_\mocl{.getObject} &\ofType \ap C \Rightarrow A_{object}\\ -\where\enspace&X\mocl{.getObject} &= \operatorname{eval\_extract}\ap X\ap - (\operatorname{deref\_oid}_C\ap \operatorname{in\_post\_state}\ap\\ - & &\quad (\operatorname{select}_\text{getObject}\ap - (\operatorname{deref\_oid}_C\ap\operatorname{in\_post\_state}))) - \end{array} -\end{gather} -The variant for an accessor yielding a collection is omitted here; its -construction follows by the application of the principles of the -former two. The respective variants -$\getAttrib{\_}{\text{$a$}\isasymOclATpre}$ were produced when -\inlineisar+in_post_state+ is replaced by -$\operatorname{in\_pre\_state}$. - -Examples for the construction of accessors via associations can be found in -\autoref{sec:eam-accessors}, the construction of accessors via attributes in -\autoref{sec:edm-accessors}. The construction of casts and type tests \verb+->oclIsTypeOf()+ and -\verb+->oclIsKindOf()+ is similarly. - -In the following, we discuss the role of multiplicities on the types of the -accessors. -Depending on the specified multiplicity, the evaluation of an attribute can -yield just a value (multiplicity \inlineocl{0..1} or \inlineocl{1}) -or a collection type like Set or Sequence of values (otherwise). -A multiplicity defines a lower bound as well as a possibly infinite upper -bound on the cardinality of the attribute's values. - - -\subsubsection{Single-Valued Attributes}\label{sec:single-valued-properties} -If the upper bound specified by the attribute's multiplicity is one, -then an evaluation of the attribute yields a single value. -Thus, the evaluation result is \emph{not} a collection. If the lower bound specified by the -multiplicity is zero, the evaluation is not required to yield a non-null value. In this case an -evaluation of the attribute can return $\isasymOclNull$ to indicate an -absence of value. - -To facilitate accessing attributes with multiplicity \inlineocl{0..1}, the OCL -standard states that single values can be used as sets by calling collection -operations on them. This implicit conversion of a value to a -\inlineocl{Set} is not defined by the standard. We argue that the resulting set -cannot be constructed the same way as when evaluating a \inlineocl{Set} -literal. Otherwise, $\isasymOclNull$ would be mapped to the singleton set -containing $\isasymOclNull$, but the standard demands that -the resulting set is empty in this case. The conversion should instead -be defined as follows: -\begin{ocl} -context OclAny::asSet():T - post: if self = null then result = Set{} - else result = Set{self} endif -\end{ocl} -% Changed self.isTypeOf(OCLVoid) to self = null to make it easier for the superficial reader - -\subsubsection{Collection-Valued Attributes}\label{sec:collection-valued-properties} -If the upper bound specified by the attribute's multiplicity is larger than one, -then an evaluation of the attribute yields a collection of values. This raises -the question whether $\isasymOclNull$ can belong to this collection. The OCL -standard states that $\isasymOclNull$ can be owned by collections. However, if -an attribute can evaluate to a collection containing $\isasymOclNull$, it is not -clear how multiplicity constraints should be interpreted for this attribute. The -question arises whether the $\isasymOclNull$ element should be counted or not -when determining the cardinality of the collection. Recall that $\isasymOclNull$ -denotes the absence of value in the case of a cardinality upper bound of one, so -we would assume that $\isasymOclNull$ is not counted. On the other hand, the -operation \inlineocl{size} defined for collections in OCL does count -$\isasymOclNull$. - -We propose to resolve this dilemma by regarding multiplicities as optional. This -point of view complies with the UML standard, that does not require lower and -upper bounds to be defined for multiplicities.\footnote{We are however aware - that a well-formedness rule of the UML standard does define a default bound - of one in case a lower or upper bound is not specified.} In case a -multiplicity is specified for an attribute, \ie, a lower and an upper bound -are provided, we require any collection the attribute evaluates to not -contain $\isasymOclNull$. This allows for a straightforward interpretation of -the multiplicity constraint. If bounds are not provided for an attribute, we -consider the attribute values to not be restricted in any way. Because in -particular the cardinality of the attribute's values is not bounded, the result -of an evaluation of the attribute is of collection type. As the range of values -that the attribute can assume is not restricted, the attribute can evaluate to a -collection containing $\isasymOclNull$. The attribute can also evaluate to -$\isasymOclInvalid$. Allowing multiplicities to be optional in this way gives -the modeler the freedom to define attributes that can assume the full ranges of -values provided by their types. However, we do not permit the omission of -multiplicities for association ends, since the values of association ends are -not only restricted by multiplicities, but also by other constraints enforcing -the semantics of associations. Hence, the values of association ends cannot be -completely unrestricted. - -\subsubsection{The Precise Meaning of Multiplicity Constraints} -We are now ready to define the meaning of multiplicity constraints by giving -equivalent invariants written in OCL\@. Let \inlineocl{a} be an attribute of a -class \inlineocl{C} with a multiplicity specifying a lower bound $m$ and an -upper bound $n$. Then we can define the multiplicity constraint on the values of -attribute \inlineocl{a} to be equivalent to the following invariants written in -OCL: -\begin{ocl} -context C inv lowerBound: a->size() >= m - inv upperBound: a->size() <= n - inv notNull: not a->includes(null) -\end{ocl} -If the upper bound $n$ is infinite, the second invariant is omitted. For the -definition of these invariants we are making use of the conversion of single -values to sets described in \autoref{sec:single-valued-properties}. If $n -\leq 1$, the attribute \inlineocl{a} evaluates to a single value, which is then -converted to a \inlineocl{Set} on which the \inlineocl{size} operation is -called. - -If a value of the attribute \inlineocl{a} includes a reference to a non-existent -object, the attribute call evaluates to $\isasymOclInvalid$. As a result, the -entire expressions evaluate to $\isasymOclInvalid$, and the invariants are not -satisfied. Thus, references to non-existent objects are ruled out by these -invariants. We believe that this result is appropriate, since we argue that the -presence of such references in a system state is usually not intended and likely -to be the result of an error. If the modeler wishes to allow references to -non-existent objects, she can make use of the possibility described above to -omit the multiplicity. - - -\subsection{Other Operations on States} -Defining $\_\isasymOclAllInstances$ -is straight-forward; the only difference is the property -$T\isasymOclAllInstances\isasymOclExcludes(\isasymOclNull)$ which is a -consequence of the fact that $\Null{}$'s are values and do not ``live'' in the -state. In our semantics which admits states with ``dangling references,'' it is -possible to define a counterpart to \inlineocl+_.oclIsNew()+ called -\inlineocl+_.oclIsDeleted()+ which asks if an object id (represented by an object -representation) is contained in the pre-state, but not the post-state. - -OCL does not guarantee that an operation only modifies the path-expressions -mentioned in the postcondition, \ie, it allows arbitrary relations from -pre-states to post-states. This framing problem is well-known (one of the -suggested solutions is~\cite{kosiuczenko:specification:2006}). We define -\begin{ocl} - (S:Set(OclAny))->oclIsModifiedOnly():Boolean -\end{ocl} -where \inlineocl|S| is a set of object representations, encoding -a set of $\oid$'s. The semantics of this operator is defined such that -for any object whose $\oid$ is \emph{not }represented in \inlineocl|S| -and that is defined in pre and post state, the corresponding object representation will not change -in the state transition. A simplified presentation is as follows: -\begin{gather*} -I\semantics{X\isasymMathOclIsModifiedOnly} (\sigma, \sigma') \equiv - \begin{cases} - \isasymbottom & \text{if $X' = \bottom \lor \text{null}\in X'$} \\ - \lift{\isasymforall i \isasymin M\spot - \sigma~i = \sigma'~i} & \text{otherwise}\mi{.} - \end{cases} -\end{gather*} -where $X' = I\semantics{X} (\sigma, \sigma')$ and $M= -(\dom~\sigma\cap\dom~\sigma') - \{ \HolOclOidOf x |~x \in\drop{X'}\}$. Thus, if -we require in a postcondition \inlineocl|Set{}->oclIsModifiedOnly()| and exclude via -\inlineocl+_.oclIsNew()+ and \inlineocl+_.oclIsDeleted()+ the existence of new -or deleted objects, the operation is a query in the sense of the OCL standard, \ie, -the \inlineocl|isQuery| property is true. So, whenever we have $ \tau -\isasymMathOclValid X\isasymOclExcluding(s.a)\isasymMathOclIsModifiedOnly$ and $ \tau -\isasymMathOclValid X\mocl{->forAll(}x\mocl{|not}(x \doteq s.a) \mocl{)}$, we can infer that $\tau -\isasymMathOclValid s.a \triangleq s.a\isasymOclATpre$. - - - - -\section{A Machine-checked Annex A} -\begin{figure*}[tb] - \mbox{}\hfill - \subfloat% - [The Isabelle jEdit environment. ]% - {\label{fig:jedit} \includegraphics[height=6.2cm]{jedit}}% - \hfill% - \hfill% - \subfloat[The generated formal document.]% - {\label{fig:pdf} \includegraphics[height=6.2cm]{pdf}} - \hfill\mbox{} - \caption{Generating documents with guaranteed syntactical and - semantical consistency.} - \label{fig:gener-docum-where} -\end{figure*} -Isabelle, as a framework for building formal -tools~\cite{wenzel.ea:building:2007}, provides the means for -generating \emph{formal documents}. With formal documents (such as -the one you are currently reading) we refer to documents that are -machine-generated and ensure certain formal guarantees. In particular, -all formal content (\eg, definitions, formulae, types) are checked for -consistency during the document generation. - -For writing documents, Isabelle supports the embedding of informal -texts using a \LaTeX-based markup language within the theory files. To -ensure the consistency, Isabelle supports to use, within these -informal texts, \emph{antiquotations} that refer to the formal parts -and that are checked while generating the actual document as -PDF\@. For example, in an informal text, the antiquotation -\inlineisar|@{$\text{thm}$ "not_not"}| will instruct Isabelle to -lock-up the (formally proven) theorem of name \inlineisar"ocl_not_not" -and to replace the antiquotation with the actual theorem, \ie, -\inlineocl{not (not x) $=$ x}. - -\autoref{fig:gener-docum-where} -illustrates this approach: \autoref{fig:jedit} shows the jEdit-based -development environment of Isabelle with an excerpt of one of the core -theories of Featherweight OCL\@. \autoref{fig:pdf} shows the generated -PDF document where all antiquotations are replaced. Moreover, -the document generation tools allows for defining syntactic sugar as -well as skipping technical details of the formalization. - - -Thus, applying the Featherweight OCL approach to writing an updated -Annex A that provides a formal semantics of the most fundamental -concepts of OCL would ensure -\begin{enumerate} -\item that all formal context is syntactically correct and well-typed, - and -\item all formal definitions and the derived logical rules are - semantically consistent. -\end{enumerate} -Overall, this would contribute to one of the main goals of the OCL 2.5 -RFP, as discussed at the OCL meeting in -Aachen~\cite{brucker.ea:summary-aachen:2013}. - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "root" -%%% End: - -% LocalWords: UML OCL implementors RFP OMG provers invariants -% LocalWords: wellfounded Denotational equalities diff --git a/document/root.tex b/document/root.tex deleted file mode 100644 index 40336cc..0000000 --- a/document/root.tex +++ /dev/null @@ -1,150 +0,0 @@ -\documentclass[fontsize=11pt,paper=a4,open=right,twoside,abstract=true]{scrreprt} -\usepackage{fixltx2e} -\usepackage{isabelle,isabellesym} -\usepackage[nocolortable, noaclist]{hol-ocl-isar} -\usepackage{booktabs} -\usepackage{graphicx} -\usepackage{amssymb} -\usepackage[numbers, sort&compress, sectionbib]{natbib} -\usepackage[caption=false]{subfig} -\usepackage{lstisar} -\usepackage{tabu} -\usepackage[]{mathtools} -\usepackage{prooftree} -\usepackage[english]{babel} -\usepackage[pdfpagelabels, pageanchor=false, plainpages=false]{hyperref} -% \usepackage[draft]{fixme} - -% MathOCl expressions -\colorlet{MathOclColor}{Black} -\colorlet{HolOclColor}{Black} -\colorlet{OclColor}{Black} -% -\sloppy - -\uchyph=0 -\graphicspath{{data/},{figures/}} -\allowdisplaybreaks - -\renewcommand{\HolTrue}{\mathrm{true}} -\renewcommand{\HolFalse}{\mathrm{false}} -\newcommand{\ptmi}[1]{\using{\mi{#1}}} -\newcommand{\Lemma}[1]{{\color{BrickRed}% - \mathbf{\operatorname{lemma}}}~\text{#1:}\quad} -\newcommand{\done}{{\color{OliveGreen}\operatorname{done}}} -\newcommand{\apply}[1]{{\holoclthykeywordstyle% - \operatorname{apply}}(\text{#1})} -\newcommand{\fun} {{\holoclthykeywordstyle\operatorname{fun}}} -\newcommand{\definitionS} {{\holoclthykeywordstyle\operatorname{definition}}} -\newcommand{\where} {{\holoclthykeywordstyle\operatorname{where}}} -\newcommand{\datatype} {{\holoclthykeywordstyle\operatorname{datatype}}} -\newcommand{\types} {{\holoclthykeywordstyle\operatorname{types}}} -\newcommand{\pglabel}[1]{\text{#1}} -\renewcommand{\isasymOclUndefined}{\ensuremath{\mathtt{invalid}}} -\newcommand{\isasymOclNull}{\ensuremath{\mathtt{null}}} -\newcommand{\isasymOclInvalid}{\isasymOclUndefined} -\DeclareMathOperator{\inv}{inv} -\newcommand{\Null}[1]{{\ensuremath{\mathtt{null}_\text{{#1}}}}} -\newcommand{\testgen}{HOL-TestGen\xspace} -\newcommand{\HolOption}{\mathrm{option}} -\newcommand{\ran}{\mathrm{ran}} -\newcommand{\dom}{\mathrm{dom}} -\newcommand{\typedef}{\mathrm{typedef}} -\newcommand{\mi}[1]{\,\text{#1}} -\newcommand{\state}[1]{\ifthenelse{\equal{}{#1}}% - {\operatorname{state}}% - {\operatorname{\mathit{state}}(#1)}% -} -\newcommand{\mocl}[1]{\text{\inlineocl|#1|}} -\DeclareMathOperator{\TCnull}{null} -\DeclareMathOperator{\HolNull}{null} -\DeclareMathOperator{\HolBot}{bot} - - -% urls in roman style, theory text in math-similar italics -\urlstyle{rm} -\isabellestyle{it} -\newcommand{\ie}{i.\,e.\xspace} -\newcommand{\eg}{e.\,g.\xspace} - -\begin{document} -\renewcommand{\subsubsectionautorefname}{Section} -\renewcommand{\subsectionautorefname}{Section} -\renewcommand{\sectionautorefname}{Section} -\renewcommand{\chapterautorefname}{Chapter} -\newcommand{\subtableautorefname}{\tableautorefname} -\newcommand{\subfigureautorefname}{\figureautorefname} - -\title{Featherweight OCL} -\subtitle{A Proposal for a Machine-Checked Formal Semantics for OCL 2.5} -\author{% - \href{http://www.brucker.ch/}{Achim D. Brucker}\footnotemark[1] - \and - \href{https://www.lri.fr/~tuong/}{Fr\'ed\'eric Tuong}\footnotemark[3] - \and - \href{https://www.lri.fr/~wolff/}{Burkhart Wolff}\footnotemark[2]} -\publishers{% - \footnotemark[1]~SAP AG, Vincenz-Priessnitz-Str. 1, 76131 Karlsruhe, - Germany \texorpdfstring{\\}{} \href{mailto:"Achim D. Brucker" - }{achim.brucker@sap.com}\\[2em] - % - \footnotemark[3]~Univ. Paris-Sud, IRT SystemX, 8 av.~de la Vauve, \\ - 91120 Palaiseau, France\\ - frederic.tuong@\{u-psud, irt-systemx\}.fr\\[2em] - % - \footnotemark[2]~Univ. Paris-Sud, Laboratoire LRI, UMR8623, 91405 Orsay, France\\ - CNRS, 91405 Orsay, France\texorpdfstring{\\}{} - \href{mailto:"Burkhart Wolff" }{burkhart.wolff@lri.fr} -} - - -\maketitle - -\begin{abstract} - The Unified Modeling Language (UML) is one of the few modeling - languages that is widely used in industry. While UML is mostly known - as diagrammatic modeling language (\eg, visualizing class models), - it is complemented by a textual language, called Object Constraint - Language (OCL). OCL is a textual annotation language, based on a - three-valued logic, that turns UML into a formal language. - Unfortunately the semantics of this specification language, captured - in the ``Annex A'' of the OCL standard, leads to different - interpretations of corner cases. Many of these corner cases had - been subject to formal analysis since more than ten years. - - The situation complicated when with version 2.3 the OCL was aligned - with the latest version of UML: this led to the extension of the - three-valued logic by a second exception element, called - \inlineocl{null}. While the first exception element - \inlineocl{invalid} has a strict semantics, \inlineocl{null} has a - non strict semantic interpretation. These semantic difficulties lead - to remarkable confusion for implementors of OCL compilers and - interpreters. - - In this paper, we provide a formalization of the core of OCL in - HOL\@. It provides denotational definitions, a logical calculus and - operational rules that allow for the execution of OCL expressions by - a mixture of term rewriting and code compilation. Our formalization - reveals several inconsistencies and contradictions in the current - version of the OCL standard. They reflect a challenge to define and - implement OCL tools in a uniform manner. Overall, this document is - intended to provide the basis for a machine-checked text ``Annex A'' - of the OCL standard targeting at tool implementors. - -\end{abstract} - -\tableofcontents -\include{introduction} -\include{formalization} -\include{conclusion} -\bibliographystyle{abbrvnat} -\bibliography{root} - -\end{document} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: t -%%% End: - -% LocalWords: implementors denotational OCL UML diff --git a/examples/Employee_AnalysisModel_OCLPart.thy b/examples/Employee_AnalysisModel_OCLPart.thy deleted file mode 100644 index 09b143d..0000000 --- a/examples/Employee_AnalysisModel_OCLPart.thy +++ /dev/null @@ -1,143 +0,0 @@ -(***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 - * for the OMG Standard. - * http://www.brucker.ch/projects/hol-testgen/ - * - * Employee_DesignModel_OCLPart.thy --- OCL Contracts and an Example. - * This file is part of HOL-TestGen. - * - * Copyright (c) 2012-2013 Université Paris-Sud, France - * 2013 IRT SystemX, France - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************) - -section{* The Employee Analysis Model (OCL) *} - -theory - Employee_AnalysisModel_OCLPart -imports - Employee_AnalysisModel_UMLPart -begin -text {* \label{ex:employee-analysis:ocl} *} -subsection{* Standard State Infrastructure *} -text{* Ideally, these definitions are automatically generated from the class model. *} - -subsection{* Invariant *} -text{* These recursive predicates can be defined conservatively -by greatest fix-point -constructions---automatically. See~\cite{brucker.ea:hol-ocl-book:2006,brucker:interactive:2007} -for details. For the purpose of this example, we state them as axioms -here. *} -axiomatization inv_Person :: "Person \ Boolean" -where A : "(\ \ (\ self)) \ - (\ \ inv_Person(self)) = - ((\ \ (self .boss \ null)) \ - ( \ \ (self .boss <> null) \ (\ \ ((self .salary) `\ (self .boss .salary))) \ - (\ \ (inv_Person(self .boss))))) " - - -axiomatization inv_Person_at_pre :: "Person \ Boolean" -where B : "(\ \ (\ self)) \ - (\ \ inv_Person_at_pre(self)) = - ((\ \ (self .boss@pre \ null)) \ - ( \ \ (self .boss@pre <> null) \ - (\ \ (self .boss@pre .salary@pre `\ self .salary@pre)) \ - (\ \ (inv_Person_at_pre(self .boss@pre))))) " - -text{* A very first attempt to characterize the axiomatization by an inductive -definition - this can not be the last word since too weak (should be equality!) *} -coinductive inv :: "Person \ (\)st \ bool" where - "(\ \ (\ self)) \ ((\ \ (self .boss \ null)) \ - (\ \ (self .boss <> null) \ (\ \ (self .boss .salary `\ self .salary)) \ - ( (inv(self .boss))\ ))) - \ ( inv self \)" - -subsection{* The Contract of a Recursive Query *} -text{* The original specification of a recursive query : -\begin{ocl} -context Person::contents():Set(Integer) -post: result = if self.boss = null - then Set{i} - else self.boss.contents()->including(i) - endif -\end{ocl} *} - - -consts dot_contents :: "Person \ Set_Integer" ("(1(_).contents'('))" 50) - -axiomatization where dot_contents_def: -"(\ \ ((self).contents() \ result)) = - (if (\ self) \ = true \ - then ((\ \ true) \ - (\ \ (result \ if (self .boss \ null) - then (Set{self .salary}) - else (self .boss .contents()->including(self .salary)) - endif))) - else \ \ result \ invalid)" - - -consts dot_contents_AT_pre :: "Person \ Set_Integer" ("(1(_).contents@pre'('))" 50) - -axiomatization where dot_contents_AT_pre_def: -"(\ \ (self).contents@pre() \ result) = - (if (\ self) \ = true \ - then \ \ true \ (* pre *) - \ \ (result \ if (self).boss@pre \ null (* post *) - then Set{(self).salary@pre} - else (self).boss@pre .contents@pre()->including(self .salary@pre) - endif) - else \ \ result \ invalid)" - -text{* These \inlineocl{@pre} variants on methods are only available on queries, \ie, -operations without side-effect. *} - - -subsection{* The Contract of a Method *} -text{* -The specification in high-level OCL input syntax reads as follows: -\begin{ocl} -context Person::insert(x:Integer) -post: contents():Set(Integer) -contents() = contents@pre()->including(x) -\end{ocl} -*} - -consts dot_insert :: "Person \ Integer \ Void" ("(1(_).insert'(_'))" 50) - -axiomatization where dot_insert_def: -"(\ \ ((self).insert(x) \ result)) = - (if (\ self) \ = true \ \ (\ x) \ = true \ - then \ \ true \ - \ \ ((self).contents() \ (self).contents@pre()->including(x)) - else \ \ ((self).insert(x) \ invalid))" - -end diff --git a/examples/Employee_DesignModel_OCLPart.thy b/examples/Employee_DesignModel_OCLPart.thy deleted file mode 100644 index 1b4a586..0000000 --- a/examples/Employee_DesignModel_OCLPart.thy +++ /dev/null @@ -1,143 +0,0 @@ -(***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 - * for the OMG Standard. - * http://www.brucker.ch/projects/hol-testgen/ - * - * Employee_DesignModel_OCLPart.thy --- OCL Contracts and an Example. - * This file is part of HOL-TestGen. - * - * Copyright (c) 2012-2013 Université Paris-Sud, France - * 2013 IRT SystemX, France - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************) - -section{* The Employee Design Model (OCL) *} - -theory - Employee_DesignModel_OCLPart -imports - Employee_DesignModel_UMLPart -begin -text {* \label{ex:employee-design:ocl} *} -subsection{* Standard State Infrastructure *} -text{* Ideally, these definitions are automatically generated from the class model. *} - -subsection{* Invariant *} -text{* These recursive predicates can be defined conservatively -by greatest fix-point -constructions---automatically. See~\cite{brucker.ea:hol-ocl-book:2006,brucker:interactive:2007} -for details. For the purpose of this example, we state them as axioms -here. *} -axiomatization inv_Person :: "Person \ Boolean" -where A : "(\ \ (\ self)) \ - (\ \ inv_Person(self)) = - ((\ \ (self .boss \ null)) \ - ( \ \ (self .boss <> null) \ (\ \ ((self .salary) `\ (self .boss .salary))) \ - (\ \ (inv_Person(self .boss))))) " - - -axiomatization inv_Person_at_pre :: "Person \ Boolean" -where B : "(\ \ (\ self)) \ - (\ \ inv_Person_at_pre(self)) = - ((\ \ (self .boss@pre \ null)) \ - ( \ \ (self .boss@pre <> null) \ - (\ \ (self .boss@pre .salary@pre `\ self .salary@pre)) \ - (\ \ (inv_Person_at_pre(self .boss@pre))))) " - -text{* A very first attempt to characterize the axiomatization by an inductive -definition - this can not be the last word since too weak (should be equality!) *} -coinductive inv :: "Person \ (\)st \ bool" where - "(\ \ (\ self)) \ ((\ \ (self .boss \ null)) \ - (\ \ (self .boss <> null) \ (\ \ (self .boss .salary `\ self .salary)) \ - ( (inv(self .boss))\ ))) - \ ( inv self \)" - -subsection{* The Contract of a Recursive Query *} -text{* The original specification of a recursive query : -\begin{ocl} -context Person::contents():Set(Integer) -post: result = if self.boss = null - then Set{i} - else self.boss.contents()->including(i) - endif -\end{ocl} *} - - -consts dot_contents :: "Person \ Set_Integer" ("(1(_).contents'('))" 50) - -axiomatization where dot_contents_def: -"(\ \ ((self).contents() \ result)) = - (if (\ self) \ = true \ - then ((\ \ true) \ - (\ \ (result \ if (self .boss \ null) - then (Set{self .salary}) - else (self .boss .contents()->including(self .salary)) - endif))) - else \ \ result \ invalid)" - - -consts dot_contents_AT_pre :: "Person \ Set_Integer" ("(1(_).contents@pre'('))" 50) - -axiomatization where dot_contents_AT_pre_def: -"(\ \ (self).contents@pre() \ result) = - (if (\ self) \ = true \ - then \ \ true \ (* pre *) - \ \ (result \ if (self).boss@pre \ null (* post *) - then Set{(self).salary@pre} - else (self).boss@pre .contents@pre()->including(self .salary@pre) - endif) - else \ \ result \ invalid)" - -text{* These \inlineocl{@pre} variants on methods are only available on queries, \ie, -operations without side-effect. *} - - -subsection{* The Contract of a Method *} -text{* -The specification in high-level OCL input syntax reads as follows: -\begin{ocl} -context Person::insert(x:Integer) -post: contents():Set(Integer) -contents() = contents@pre()->including(x) -\end{ocl} -*} - -consts dot_insert :: "Person \ Integer \ Void" ("(1(_).insert'(_'))" 50) - -axiomatization where dot_insert_def: -"(\ \ ((self).insert(x) \ result)) = - (if (\ self) \ = true \ \ (\ x) \ = true \ - then \ \ true \ - \ \ ((self).contents() \ (self).contents@pre()->including(x)) - else \ \ ((self).insert(x) \ invalid))" - -end diff --git a/examples/Employee_Model/Analysis/Analysis_OCL.thy b/examples/Employee_Model/Analysis/Analysis_OCL.thy new file mode 100644 index 0000000..b656ea5 --- /dev/null +++ b/examples/Employee_Model/Analysis/Analysis_OCL.thy @@ -0,0 +1,362 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * Analysis_OCL.thy --- OCL Contracts and an Example. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory + Analysis_OCL +imports + Analysis_UML +begin +text {* \label{ex:employee-analysis:ocl} *} + +section{* OCL Part: Invariant *} +text{* These recursive predicates can be defined conservatively +by greatest fix-point +constructions---automatically. See~\cite{brucker.ea:hol-ocl-book:2006,brucker:interactive:2007} +for details. For the purpose of this example, we state them as axioms +here. + +\begin{ocl} +context Person + inv label : self .boss <> null implies (self .salary \ ((self .boss) .salary)) +\end{ocl} +*} + +definition Person_label\<^sub>i\<^sub>n\<^sub>v :: "Person \ Boolean" +where "Person_label\<^sub>i\<^sub>n\<^sub>v (self) \ + (self .boss <> null implies (self .salary \\<^sub>i\<^sub>n\<^sub>t ((self .boss) .salary)))" + + +definition Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e :: "Person \ Boolean" +where "Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e (self) \ + (self .boss@pre <> null implies (self .salary@pre \\<^sub>i\<^sub>n\<^sub>t ((self .boss@pre) .salary@pre)))" + +definition Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v :: "Boolean" +where "Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(x | Person_label\<^sub>i\<^sub>n\<^sub>v (x)) and + (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(x | Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e (x))))" + + +lemma "\ \ \ (X .boss) \ \ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X .boss) \ + \ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X) " +oops +(* To be generated generically ... hard, but crucial lemma that should hold. + It means that X and it successor are object representation that actually + occur in the state. *) + +lemma REC_pre : "\ \ Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v + \ \ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X) (* X represented object in state *) + \ \ REC. \ \ REC(X) \ (Person_label\<^sub>i\<^sub>n\<^sub>v (X) and (X .boss <> null implies REC(X .boss)))" +oops (* Attempt to allegiate the burden of he following axiomatizations: could be + a witness for a constant specification ...*) + +text{* This allows to state a predicate: *} + +axiomatization inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l :: "Person \ Boolean" +where inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l_def: +"(\ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self) \ (self .boss <> null implies + (self .salary \\<^sub>i\<^sub>n\<^sub>t ((self .boss) .salary)) and + inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self .boss))))" + +axiomatization inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e :: "Person \ Boolean" +where inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e_def: +"(\ \ Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self) \ (self .boss@pre <> null implies + (self .salary@pre \\<^sub>i\<^sub>n\<^sub>t ((self .boss@pre) .salary@pre)) and + inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self .boss@pre))))" + + +lemma inv_1 : +"(\ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self) = ((\ \ (self .boss \ null)) \ + ( \ \ (self .boss <> null) \ + \ \ ((self .salary) \\<^sub>i\<^sub>n\<^sub>t (self .boss .salary)) \ + \ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self .boss))))) " +oops (* Let's hope that this holds ... *) + + +lemma inv_2 : +"(\ \ Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self)) = ((\ \ (self .boss@pre \ null)) \ + (\ \ (self .boss@pre <> null) \ + (\ \ (self .boss@pre .salary@pre \\<^sub>i\<^sub>n\<^sub>t self .salary@pre)) \ + (\ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self .boss@pre)))))" +oops (* Let's hope that this holds ... *) + +text{* A very first attempt to characterize the axiomatization by an inductive +definition - this can not be the last word since too weak (should be equality!) *} +coinductive inv :: "Person \ (\)st \ bool" where + "(\ \ (\ self)) \ ((\ \ (self .boss \ null)) \ + (\ \ (self .boss <> null) \ (\ \ (self .boss .salary \\<^sub>i\<^sub>n\<^sub>t self .salary)) \ + ( (inv(self .boss))\ ))) + \ ( inv self \)" + + +section{* OCL Part: The Contract of a Recursive Query *} +text{* The original specification of a recursive query : +\begin{ocl} +context Person::contents():Set(Integer) +pre: true +post: result = if self.boss = null + then Set{i} + else self.boss.contents()->including(i) + endif +\end{ocl} *} + + + +text{* For the case of recursive queries, we use at present just axiomatizations: *} + +axiomatization contents :: "Person \ Set_Integer" ("(1(_).contents'('))" 50) +where contents_def: +"(self .contents()) = (\ \. SOME res. let res = \ _. res in + if \ \ (\ self) + then ((\ \ true) \ + (\ \ res \ if (self .boss \ null) + then (Set{self .salary}) + else (self .boss .contents() + ->including\<^sub>S\<^sub>e\<^sub>t(self .salary)) + endif)) + else \ \ res \ invalid)" +and cp0_contents:"(X .contents()) \ = ((\_. X \) .contents()) \" + +interpretation contents : contract0 "contents" "\ self. true" + "\ self res. res \ if (self .boss \ null) + then (Set{self .salary}) + else (self .boss .contents() + ->including\<^sub>S\<^sub>e\<^sub>t(self .salary)) + endif" + proof (unfold_locales) + show "\self \. true \ = true \" by auto + next + show "\self. \\ \' \''. ((\, \') \ true) = ((\, \'') \ true)" by auto + next + show "\self. self .contents() \ + \ \. SOME res. let res = \ _. res in + if \ \ (\ self) + then ((\ \ true) \ + (\ \ res \ if (self .boss \ null) + then (Set{self .salary}) + else (self .boss .contents() + ->including\<^sub>S\<^sub>e\<^sub>t(self .salary)) + endif)) + else \ \ res \ invalid" + by(auto simp: contents_def ) + next + have A:"\self \. ((\_. self \) .boss \ null) \ = (\_. (self .boss \ null) \) \" + by (metis (no_types) StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n cp_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\) + have B:"\self \. (\_. Set{(\_. self \) .salary} \) = (\_. Set{self .salary} \)" + apply(subst UML_Set.OclIncluding.cp0) + apply(subst (2) UML_Set.OclIncluding.cp0) + apply(subst (2) Analysis_UML.cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\) by simp + have C:"\self \. ((\_. self \).boss .contents()->including\<^sub>S\<^sub>e\<^sub>t((\_. self \).salary) \) = + (self .boss .contents() ->including\<^sub>S\<^sub>e\<^sub>t(self .salary) \)" + apply(subst UML_Set.OclIncluding.cp0) apply(subst (2) UML_Set.OclIncluding.cp0) + apply(subst (2) Analysis_UML.cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\) + apply(subst cp0_contents) apply(subst (2) cp0_contents) + apply(subst (2) cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\) by simp + show "\self res \. + (res \ if (self .boss) \ null then Set{self .salary} + else self .boss .contents()->including\<^sub>S\<^sub>e\<^sub>t(self .salary) endif) \ = + ((\_. res \) \ if (\_. self \) .boss \ null then Set{(\_. self \) .salary} + else(\_. self \) .boss .contents()->including\<^sub>S\<^sub>e\<^sub>t((\_. self \) .salary) endif) \" + apply(subst cp_StrongEq) + apply(subst (2) cp_StrongEq) + apply(subst cp_OclIf) + apply(subst (2)cp_OclIf) + by(simp add: A B C) + qed + + +text{* Specializing @{thm contents.unfold2}, one gets the following more practical rewrite +rule that is amenable to symbolic evaluation: *} +theorem unfold_contents : + assumes "cp E" + and "\ \ \ self" + shows "(\ \ E (self .contents())) = + (\ \ E (if self .boss \ null + then Set{self .salary} + else self .boss .contents()->including\<^sub>S\<^sub>e\<^sub>t(self .salary) endif))" +by(rule contents.unfold2[of _ _ _ "\ X. true"], simp_all add: assms) + + +text{* Since we have only one interpretation function, we need the corresponding +operation on the pre-state: *} + +consts contentsATpre :: "Person \ Set_Integer" ("(1(_).contents@pre'('))" 50) + +axiomatization where contentsATpre_def: +" (self).contents@pre() = (\ \. + SOME res. let res = \ _. res in + if \ \ (\ self) + then ((\ \ true) \ (* pre *) + (\ \ (res \ if (self).boss@pre \ null (* post *) + then Set{(self).salary@pre} + else (self).boss@pre .contents@pre() + ->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre) + endif))) + else \ \ res \ invalid)" +and cp0_contents_at_pre:"(X .contents@pre()) \ = ((\_. X \) .contents@pre()) \" + +interpretation contentsATpre : contract0 "contentsATpre" "\ self. true" + "\ self res. res \ if (self .boss@pre \ null) + then (Set{self .salary@pre}) + else (self .boss@pre .contents@pre() + ->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre)) + endif" + proof (unfold_locales) + show "\self \. true \ = true \" by auto + next + show "\self. \\ \' \''. ((\, \') \ true) = ((\, \'') \ true)" by auto + next + show "\self. self .contents@pre() \ + \\. SOME res. let res = \ _. res in + if \ \ \ self + then \ \ true \ + \ \ res \ (if self .boss@pre \ null then Set{self .salary@pre} + else self .boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre) + endif) + else \ \ res \ invalid" + by(auto simp: contentsATpre_def) + next + have A:"\self \. ((\_. self \) .boss@pre \ null) \ = (\_. (self .boss@pre \ null) \) \" + by (metis StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n cp_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre) + have B:"\self \. (\_. Set{(\_. self \) .salary@pre} \) = (\_. Set{self .salary@pre} \)" + apply(subst UML_Set.OclIncluding.cp0) + apply(subst (2) UML_Set.OclIncluding.cp0) + apply(subst (2) Analysis_UML.cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre) by simp + have C:"\self \. ((\_. self \).boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t((\_. self \).salary@pre) \) = + (self .boss@pre .contents@pre() ->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre) \)" + apply(subst UML_Set.OclIncluding.cp0) apply(subst (2) UML_Set.OclIncluding.cp0) + apply(subst (2) Analysis_UML.cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre) + apply(subst cp0_contents_at_pre) apply(subst (2) cp0_contents_at_pre) + apply(subst (2) cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre) by simp + show "\self res \. + (res \ if (self .boss@pre) \ null then Set{self .salary@pre} + else self .boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre) endif) \ = + ((\_. res \) \ if (\_. self \) .boss@pre \ null then Set{(\_. self \) .salary@pre} + else(\_. self \) .boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t((\_. self \) .salary@pre) endif) \" + apply(subst cp_StrongEq) + apply(subst (2) cp_StrongEq) + apply(subst cp_OclIf) + apply(subst (2)cp_OclIf) + by(simp add: A B C) + qed + +text{* Again, we derive via @{thm [source] contents.unfold2} a Knaster-Tarski like Fixpoint rule +that is amenable to symbolic evaluation: *} +theorem unfold_contentsATpre : + assumes "cp E" + and "\ \ \ self" + shows "(\ \ E (self .contents@pre())) = + (\ \ E (if self .boss@pre \ null + then Set{self .salary@pre} + else self .boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre) endif))" +by(rule contentsATpre.unfold2[of _ _ _ "\ X. true"], simp_all add: assms) + + +text{* Note that these \inlineocl{@pre} variants on methods are only available on queries, \ie, +operations without side-effect. *} + +section{* OCL Part: The Contract of a User-defined Method *} +text{* +The example specification in high-level OCL input syntax reads as follows: +\begin{ocl} +context Person::insert(x:Integer) +pre: true +post: contents():Set(Integer) +contents() = contents@pre()->including(x) +\end{ocl} + +This boils down to: +*} + +definition insert :: "Person \Integer \ Void" ("(1(_).insert'(_'))" 50) +where "self .insert(x) \ + (\ \. SOME res. let res = \ _. res in + if (\ \ (\ self)) \ (\ \ \ x) + then (\ \ true \ + (\ \ ((self).contents() \ (self).contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(x)))) + else \ \ res \ invalid)" + +text{* The semantic consequences of this definition were computed inside this locale interpretation:*} +interpretation insert : contract1 "insert" "\ self x. true" + "\ self x res. ((self .contents()) \ + (self .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(x)))" + apply unfold_locales apply(auto simp:insert_def) + apply(subst cp_StrongEq) apply(subst (2) cp_StrongEq) + apply(subst contents.cp0) + apply(subst UML_Set.OclIncluding.cp0) + apply(subst (2) UML_Set.OclIncluding.cp0) + apply(subst contentsATpre.cp0) + by(simp) (* an extremely hacky proof that cries for reformulation and automation - bu *) + + +text{* The result of this locale interpretation for our @{term insert} contract is the following +set of properties, which serves as basis for automated deduction on them: + +\begin{table}[htbp] + \centering + \begin{tabu}{lX[,c,]} + \toprule + Name & Theorem \\ + \midrule + @{thm [source] insert.strict0} & @{thm [display=false] insert.strict0} \\ + @{thm [source] insert.nullstrict0} & @{thm [display=false] insert.nullstrict0} \\ + @{thm [source] insert.strict1} & @{thm [display=false] insert.strict1} \\ + @{thm [source] insert.cp\<^sub>P\<^sub>R\<^sub>E} & @{thm [display=false] insert.cp\<^sub>P\<^sub>R\<^sub>E} \\ + @{thm [source] insert.cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T} & @{thm [display=false] insert.cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T} \\ + @{thm [source] insert.cp_pre} & @{thm [display=false] insert.cp_pre} \\ + @{thm [source] insert.cp_post} & @{thm [display=false] insert.cp_post} \\ + @{thm [source] insert.cp} & @{thm [display=false] insert.cp} \\ + @{thm [source] insert.cp0} & @{thm [display=false] insert.cp0} \\ + @{thm [source] insert.def_scheme} & @{thm [display=false] insert.def_scheme} \\ + @{thm [source] insert.unfold} & @{thm [display=false] insert.unfold} \\ + @{thm [source] insert.unfold2} & @{thm [display=false] insert.unfold2} \\ + \bottomrule + \end{tabu} + \caption{Semantic properties resulting from a user-defined operation contract.} + \label{tab:sem_operation_contract} +\end{table} + +*} + +end diff --git a/examples/Employee_AnalysisModel_UMLPart.thy b/examples/Employee_Model/Analysis/Analysis_UML.thy similarity index 69% rename from examples/Employee_AnalysisModel_UMLPart.thy rename to examples/Employee_Model/Analysis/Analysis_UML.thy index 0484178..2768998 100644 --- a/examples/Employee_AnalysisModel_UMLPart.thy +++ b/examples/Employee_Model/Analysis/Analysis_UML.thy @@ -1,13 +1,13 @@ (***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 * for the OMG Standard. * http://www.brucker.ch/projects/hol-testgen/ * - * Employee_DesignModel_UMLPart.thy --- OCL Contracts and an Example. + * Analysis_UML.thy --- OCL Contracts and an Example. * This file is part of HOL-TestGen. * - * Copyright (c) 2012-2013 Universite Paris-Sud, France - * 2013 IRT SystemX, France + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France * * All rights reserved. * @@ -40,18 +40,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************) -section{* The Employee Analysis Model (UML) *} +chapter{* Example: The Employee Analysis Model *} (* UML part *) theory - Employee_AnalysisModel_UMLPart + Analysis_UML imports - "../OCL_main" + "../../../src/UML_Main" begin text {* \label{ex:employee-analysis:uml} *} -subsection{* Introduction *} -text{* +section{* Introduction *} +text{* For certain concepts like classes and class-types, only a generic definition for its resulting semantics can be given. Generic means, there is a function outside HOL that ``compiles'' a concrete, @@ -69,15 +69,21 @@ text{* Such generic function or ``compiler'' can be implemented in concepts of the compilation informally, and present a concrete example which is verified in Isabelle/HOL. *} -subsubsection{* Outlining the Example *} +subsection{* Outlining the Example *} text{* We are presenting here an ``analysis-model'' of the (slightly modified) example Figure 7.3, page 20 of -the OCL standard~\cite{omg:ocl:2012}. +the OCL standard~\cite{omg:ocl:2012}. Here, analysis model means that associations were really represented as relation on objects on the state---as is intended by the standard---rather by pointers between objects as is -done in our ``design model'' (see \autoref{ex:employee-design:uml}). +done in our ``design model'' +\isatagafp +(see \autoref{ex:employee-design:uml}). +\endisatagafp +\isatagannexa +(see \url{http://afp.sourceforge.net/entries/Featherweight_OCL.shtml}). +\endisatagannexa To be precise, this theory contains the formalization of the data-part covered by the UML class model (see \autoref{fig:person-ana}):*} @@ -95,10 +101,9 @@ by the attribute \inlineocl+boss+ and the operation \inlineocl+employees+ (to b captured by the subsequent theory). *} -subsection{* Example Data-Universe and its Infrastructure *} +section{* Example Data-Universe and its Infrastructure *} text{* Ideally, the following is generated automatically from a UML class model. *} -(* @{text "'\"} -- \mathfrak{A} *) text{* Our data universe consists in the concrete class diagram just of node's, and implicitly of the class object. Each class implies the existence of a class type defined for the corresponding object representations as follows: *} @@ -109,8 +114,8 @@ datatype type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n = mk\<^sub>P\<^sub datatype type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y = mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid (* the oid to the oclany itself *) "(int option) option" - (* the extensions to "person"; used to denote - objects of actual type "person" casted to "oclany"; + (* the extensions to "person"; used to denote + objects of actual type "person" casted to "oclany"; in case of existence of several subclasses of oclany, sums of extensions have to be provided. *) @@ -160,14 +165,21 @@ end -subsection{* Instantiation of the Generic Strict Equality *} +section{* Instantiation of the Generic Strict Equality *} text{* We instantiate the referential equality on @{text "Person"} and @{text "OclAny"} *} -defs(overloaded) StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n : "(x::Person) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" -defs(overloaded) StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y : "(x::OclAny) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" +overloading StrictRefEq \ "StrictRefEq :: [Person,Person] \ Boolean" +begin + definition StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n : "(x::Person) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" +end -lemmas +overloading StrictRefEq \ "StrictRefEq :: [OclAny,OclAny] \ Boolean" +begin + definition StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y : "(x::OclAny) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" +end + +lemmas cps23 = cp_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t[of "x::Person" "y::Person" "\", simplified StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n[symmetric]] cp_intro(9) [of "P::Person \Person""Q::Person \Person", @@ -183,8 +195,6 @@ lemmas [of "x::Person", simplified StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n[symmetric]] - - text{* For each Class \emph{C}, we will have a casting operation \inlineocl{.oclAsType($C$)}, a test on the actual type \inlineocl{.oclIsTypeOf($C$)} as well as its relaxed form \inlineocl{.oclIsKindOf($C$)} (corresponding exactly to Java's \verb+instanceof+-operator. @@ -194,49 +204,62 @@ two operations to declare and to provide two overloading definitions for the two *} -subsection{* OclAsType *} -subsubsection{* Definition *} +section{* OclAsType *} +subsection{* Definition *} consts OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: "'\ \ OclAny" ("(_) .oclAsType'(OclAny')") consts OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "'\ \ Person" ("(_) .oclAsType'(Person')") definition "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\ = (\u. \case u of in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y a \ a - | in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n (mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a) \ mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\\)" + | in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n (mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a) \ mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\\)" lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\_some: "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\ x \ None" by(simp add: OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\_def) -defs (overloaded) OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: +overloading OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: OclAny \ OclAny" +begin + definition OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: "(X::OclAny) .oclAsType(OclAny) \ X" +end -defs (overloaded) OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: +overloading OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: Person \ OclAny" +begin + definition OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: "(X::Person) .oclAsType(OclAny) \ (\\. case X \ of \ \ invalid \ | \\\ \ null \ | \\mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a \\ \ \\ (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\) \\)" +end -definition "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_\ = (\u. case u of in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n p \ \p\ - | in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\) \ \mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a\ - | _ \ None)" +definition "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_\ = + (\u. case u of in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n p \ \p\ + | in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\) \ \mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a\ + | _ \ None)" -defs (overloaded) OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: +overloading OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: OclAny \ Person" +begin + definition OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: "(X::OclAny) .oclAsType(Person) \ (\\. case X \ of \ \ invalid \ | \\\ \ null \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ invalid \ (* down-cast exception *) | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\ \\ \ \\mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a\\)" +end -defs (overloaded) OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: +overloading OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: Person \ Person" +begin + definition OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: "(X::Person) .oclAsType(Person) \ X " (* to avoid identity for null ? *) +end +text_raw{* \isatagafp *} lemmas [simp] = OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person - -subsubsection{* Context Passing *} +subsection{* Context Passing *} lemma cp_OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_Person: "cp P \ cp(\X. (P (X::Person)::Person) .oclAsType(OclAny))" by(rule cpI1, simp_all add: OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) @@ -267,72 +290,93 @@ lemmas [simp] = cp_OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_OclAny cp_OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_Person -subsubsection{* Execution with Invalid or Null as Argument *} +text_raw{* \endisatagafp*} -lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict : "(invalid::OclAny) .oclAsType(OclAny) = invalid" -by(simp) - -lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_nullstrict : "(null::OclAny) .oclAsType(OclAny) = null" -by(simp) +subsection{* Execution with Invalid or Null as Argument *} +lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict : "(invalid::OclAny) .oclAsType(OclAny) = invalid" by(simp) +lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_nullstrict : "(null::OclAny) .oclAsType(OclAny) = null" by(simp) lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_strict[simp] : "(invalid::Person) .oclAsType(OclAny) = invalid" -by(rule ext, simp add: bot_option_def invalid_def - OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - + by(rule ext, simp add: bot_option_def invalid_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_nullstrict[simp] : "(null::Person) .oclAsType(OclAny) = null" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def - OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - + by(rule ext, simp add: null_fun_def null_option_def bot_option_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_strict[simp] : "(invalid::OclAny) .oclAsType(Person) = invalid" -by(rule ext, simp add: bot_option_def invalid_def - OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) - + by(rule ext, simp add: bot_option_def invalid_def OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_nullstrict[simp] : "(null::OclAny) .oclAsType(Person) = null" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def - OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) + by(rule ext, simp add: null_fun_def null_option_def bot_option_def OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) +lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict : "(invalid::Person) .oclAsType(Person) = invalid" by(simp) +lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_nullstrict : "(null::Person) .oclAsType(Person) = null" by(simp) -lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict : "(invalid::Person) .oclAsType(Person) = invalid" -by(simp) -lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_nullstrict : "(null::Person) .oclAsType(Person) = null" -by(simp) +section{* OclIsTypeOf *} -subsection{* OclIsTypeOf *} -subsubsection{* Definition *} +subsection{* Definition *} consts OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: "'\ \ Boolean" ("(_).oclIsTypeOf'(OclAny')") consts OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "'\ \ Boolean" ("(_).oclIsTypeOf'(Person')") -defs (overloaded) OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: +overloading OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: OclAny \ Boolean" +begin + definition OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: "(X::OclAny) .oclIsTypeOf(OclAny) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ (* invalid ?? *) | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ true \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ false \)" +end +lemma OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny': + "(X::OclAny) .oclIsTypeOf(OclAny) = + (\ \. if \ \ \ X then (case X \ of + \\\ \ true \ (* invalid ?? *) + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ true \ + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ false \) + else invalid \)" + apply(rule ext, simp add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) + by(case_tac "\ \ \ X", auto simp: foundation18' bot_option_def) -defs (overloaded) OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: +interpretation OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny : + profile_mono_schemeV + "OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y::OclAny \ Boolean" + "\ X. (case X of + \None\ \ \\True\\ (* invalid ?? *) + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid None \\ \ \\True\\ + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ \\False\\)" + apply(unfold_locales, simp add: atomize_eq, rule ext) + by(auto simp: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny' OclValid_def true_def false_def + split: option.split type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y.split) + +overloading OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: Person \ Boolean" +begin + definition OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: "(X::Person) .oclIsTypeOf(OclAny) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ (* invalid ?? *) | \\ _ \\ \ false \)" (* must have actual type Person otherwise *) +end -defs (overloaded) OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: +overloading OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: OclAny \ Boolean" +begin + definition OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: "(X::OclAny) .oclIsTypeOf(Person) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ false \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ true \)" +end -defs (overloaded) OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: +overloading OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: Person \ Boolean" +begin + definition OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: "(X::Person) .oclIsTypeOf(Person) \ (\\. case X \ of \ \ invalid \ - | _ \ true \)" - -subsubsection{* Context Passing *} + | _ \ true \)" (* for (* \\ _ \\ \ true \ *) : must have actual type Node otherwise *) +end +text_raw{* \isatagafp *} +subsection{* Context Passing *} lemma cp_OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_Person: "cp P \ cp(\X.(P(X::Person)::Person).oclIsTypeOf(OclAny))" by(rule cpI1, simp_all add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) @@ -363,8 +407,9 @@ lemmas [simp] = cp_OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_Person cp_OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_OclAny cp_OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_Person +text_raw{* \endisatagafp *} -subsubsection{* Execution with Invalid or Null as Argument *} +subsection{* Execution with Invalid or Null as Argument *} lemma OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict1[simp]: "(invalid::OclAny) .oclIsTypeOf(OclAny) = invalid" @@ -399,7 +444,7 @@ lemma OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict2 by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) -subsubsection{* Up Down Casting *} +subsection{* Up Down Casting *} lemma actualType_larger_staticType: assumes isdef: "\ \ (\ X)" @@ -438,57 +483,72 @@ shows "((X::Person) .oclAsType(OclAny) .oclAsType(Person) = X)" apply(rule ext, rename_tac \) apply(rule foundation22[THEN iffD1]) apply(case_tac "\ \ (\ X)", simp add: up_down_cast) - apply(simp add: def_split_local, elim disjE) + apply(simp add: defined_split, elim disjE) apply(erule StrongEq_L_subst2_rev, simp, simp)+ done -lemma up_down_cast_Person_OclAny_Person': assumes "\ \ \ X" -shows "\ \ (((X :: Person) .oclAsType(OclAny) .oclAsType(Person)) \ X)" +lemma up_down_cast_Person_OclAny_Person': +assumes "\ \ \ X" +shows "\ \ (((X :: Person) .oclAsType(OclAny) .oclAsType(Person)) \ X)" apply(simp only: up_down_cast_Person_OclAny_Person StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) by(rule StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_sym, simp add: assms) -lemma up_down_cast_Person_OclAny_Person'': assumes "\ \ \ (X :: Person)" -shows "\ \ (X .oclIsTypeOf(Person) implies (X .oclAsType(OclAny) .oclAsType(Person)) \ X)" +lemma up_down_cast_Person_OclAny_Person'': +assumes "\ \ \ (X :: Person)" +shows "\ \ (X .oclIsTypeOf(Person) implies (X .oclAsType(OclAny) .oclAsType(Person)) \ X)" apply(simp add: OclValid_def) apply(subst cp_OclImplies) apply(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_sym[OF assms, simplified OclValid_def]) apply(subst cp_OclImplies[symmetric]) -by (simp add: OclImplies_true) +by simp -subsection{* OclIsKindOf *} -subsubsection{* Definition *} +section{* OclIsKindOf *} +subsection{* Definition *} consts OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: "'\ \ Boolean" ("(_).oclIsKindOf'(OclAny')") consts OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "'\ \ Boolean" ("(_).oclIsKindOf'(Person')") -defs (overloaded) OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: +overloading OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: OclAny \ Boolean" +begin + definition OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: "(X::OclAny) .oclIsKindOf(OclAny) \ (\\. case X \ of \ \ invalid \ | _ \ true \)" +end -defs (overloaded) OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: +overloading OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: Person \ Boolean" +begin + definition OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: "(X::Person) .oclIsKindOf(OclAny) \ (\\. case X \ of \ \ invalid \ | _\ true \)" +(* for (* \\mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n e oid _ \\ \ true \ *) : must have actual type Person otherwise *) +end -defs (overloaded) OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: +overloading OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: OclAny \ Boolean" +begin + definition OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: "(X::OclAny) .oclIsKindOf(Person) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ false \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ true \)" +end -defs (overloaded) OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: +overloading OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: Person \ Boolean" +begin + definition OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: "(X::Person) .oclIsKindOf(Person) \ (\\. case X \ of \ \ invalid \ | _ \ true \)" - -subsubsection{* Context Passing *} +end +text_raw{* \isatagafp *} +subsection{* Context Passing *} lemma cp_OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_Person: "cp P \ cp(\X.(P(X::Person)::Person).oclIsKindOf(OclAny))" by(rule cpI1, simp_all add: OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) @@ -518,63 +578,56 @@ lemmas [simp] = cp_OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_Person cp_OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_OclAny cp_OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_Person - -subsubsection{* Execution with Invalid or Null as Argument *} +text_raw{* \endisatagafp *} +subsection{* Execution with Invalid or Null as Argument *} lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict1[simp] : "(invalid::OclAny) .oclIsKindOf(OclAny) = invalid" by(rule ext, simp add: invalid_def bot_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) - lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict2[simp] : "(null::OclAny) .oclIsKindOf(OclAny) = true" by(rule ext, simp add: null_fun_def null_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) - lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_strict1[simp] : "(invalid::Person) .oclIsKindOf(OclAny) = invalid" by(rule ext, simp add: bot_option_def invalid_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_strict2[simp] : "(null::Person) .oclIsKindOf(OclAny) = true" by(rule ext, simp add: null_fun_def null_option_def bot_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_strict1[simp]: "(invalid::OclAny) .oclIsKindOf(Person) = invalid" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_strict2[simp]: "(null::OclAny) .oclIsKindOf(Person) = true" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict1[simp]: "(invalid::Person) .oclIsKindOf(Person) = invalid" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict2[simp]: "(null::Person) .oclIsKindOf(Person) = true" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) -subsubsection{* Up Down Casting *} +subsection{* Up Down Casting *} lemma actualKind_larger_staticKind: assumes isdef: "\ \ (\ X)" -shows "\ \ (X::Person) .oclIsKindOf(OclAny) \ true" +shows "\ \ ((X::Person) .oclIsKindOf(OclAny) \ true)" using isdef by(auto simp : bot_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person foundation22 foundation16) lemma down_cast_kind: -assumes isOclAny: "\ \ \ (X::OclAny) .oclIsKindOf(Person)" +assumes isOclAny: "\ (\ \ ((X::OclAny).oclIsKindOf(Person)))" and non_null: "\ \ (\ X)" -shows "\ \ (X .oclAsType(Person)) \ invalid" +shows "\ \ ((X .oclAsType(Person)) \ invalid)" using isOclAny non_null apply(auto simp : bot_fun_def null_fun_def null_option_def bot_option_def null_def invalid_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny foundation22 foundation16 split: option.split type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y.split type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n.split) by(simp add: OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny OclValid_def false_def true_def) -subsection{* OclAllInstances *} +section{* OclAllInstances *} -text{* To denote OCL-types occuring in OCL expressions syntactically---as, for example, as +text{* To denote OCL-types occuring in OCL expressions syntactically---as, for example, as ``argument'' of \inlineisar{oclAllInstances()}---we use the inverses of the injection functions into the object universes; we show that this is sufficient ``characterization.'' *} @@ -583,7 +636,7 @@ definition "OclAny \ OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^ lemmas [simp] = Person_def OclAny_def lemma OclAllInstances_generic\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec: "OclAllInstances_generic pre_post OclAny = - (\\. Abs_Set_0 \\ Some ` OclAny ` ran (heap (pre_post \)) \\)" + (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ Some ` OclAny ` ran (heap (pre_post \)) \\)" proof - let ?S1 = "\\. OclAny ` ran (heap (pre_post \))" let ?S2 = "\\. ?S1 \ - {None}" @@ -594,147 +647,147 @@ proof - qed lemma OclAllInstances_at_post\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec: "OclAny .allInstances() = - (\\. Abs_Set_0 \\ Some ` OclAny ` ran (heap (snd \)) \\)" + (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ Some ` OclAny ` ran (heap (snd \)) \\)" unfolding OclAllInstances_at_post_def by(rule OclAllInstances_generic\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec) lemma OclAllInstances_at_pre\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec: "OclAny .allInstances@pre() = - (\\. Abs_Set_0 \\ Some ` OclAny ` ran (heap (fst \)) \\) " + (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ Some ` OclAny ` ran (heap (fst \)) \\) " unfolding OclAllInstances_at_pre_def by(rule OclAllInstances_generic\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec) -subsubsection{* OclIsTypeOf *} +subsection{* OclIsTypeOf *} lemma OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1: assumes [simp]: "\x. pre_post (x, x) = x" -shows "\\. (\ \ ((OclAllInstances_generic pre_post OclAny)->forAll(X|X .oclIsTypeOf(OclAny))))" +shows "\\. (\ \ ((OclAllInstances_generic pre_post OclAny)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" apply(rule_tac x = \\<^sub>0 in exI, simp add: \\<^sub>0_def OclValid_def del: OclAllInstances_generic_def) - apply(simp only: assms OclForall_def refl if_True + apply(simp only: assms UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) lemma OclAny_allInstances_at_post_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1: -"\\. (\ \ (OclAny .allInstances()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ (OclAny .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_post_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1, simp) lemma OclAny_allInstances_at_pre_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1: -"\\. (\ \ (OclAny .allInstances@pre()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ (OclAny .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_pre_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1, simp) lemma OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2: assumes [simp]: "\x. pre_post (x, x) = x" -shows "\\. (\ \ not ((OclAllInstances_generic pre_post OclAny)->forAll(X|X .oclIsTypeOf(OclAny))))" +shows "\\. (\ \ not ((OclAllInstances_generic pre_post OclAny)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" proof - fix oid a let ?t0 = "\heap = empty(oid \ in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\)), - assocs\<^sub>2 = empty, assocs\<^sub>3 = empty\" show ?thesis + assocs = empty\" show ?thesis apply(rule_tac x = "(?t0, ?t0)" in exI, simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny OclNot_def OclAny_def) qed lemma OclAny_allInstances_at_post_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2: -"\\. (\ \ not (OclAny .allInstances()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ not (OclAny .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_post_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2, simp) lemma OclAny_allInstances_at_pre_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2: -"\\. (\ \ not (OclAny .allInstances@pre()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ not (OclAny .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_pre_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2, simp) lemma Person_allInstances_generic_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ ((OclAllInstances_generic pre_post Person)->forAll(X|X .oclIsTypeOf(Person)))" +"\ \ ((OclAllInstances_generic pre_post Person)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(Person)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) lemma Person_allInstances_at_post_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances()->forAll(X|X .oclIsTypeOf(Person)))" +"\ \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(Person)))" unfolding OclAllInstances_at_post_def by(rule Person_allInstances_generic_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) lemma Person_allInstances_at_pre_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances@pre()->forAll(X|X .oclIsTypeOf(Person)))" +"\ \ (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(Person)))" unfolding OclAllInstances_at_pre_def by(rule Person_allInstances_generic_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) -subsubsection{* OclIsKindOf *} +subsection{* OclIsKindOf *} lemma OclAny_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ ((OclAllInstances_generic pre_post OclAny)->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ ((OclAllInstances_generic pre_post OclAny)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) lemma OclAny_allInstances_at_post_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (OclAny .allInstances()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (OclAny .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_post_def by(rule OclAny_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma OclAny_allInstances_at_pre_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (OclAny .allInstances@pre()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (OclAny .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_pre_def by(rule OclAny_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma Person_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ ((OclAllInstances_generic pre_post Person)->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ ((OclAllInstances_generic pre_post Person)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) lemma Person_allInstances_at_post_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (Person .allInstances()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_post_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma Person_allInstances_at_pre_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (Person .allInstances@pre()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_pre_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma Person_allInstances_generic_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ ((OclAllInstances_generic pre_post Person)->forAll(X|X .oclIsKindOf(Person)))" +"\ \ ((OclAllInstances_generic pre_post Person)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(Person)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) lemma Person_allInstances_at_post_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances()->forAll(X|X .oclIsKindOf(Person)))" +"\ \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(Person)))" unfolding OclAllInstances_at_post_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) lemma Person_allInstances_at_pre_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances@pre()->forAll(X|X .oclIsKindOf(Person)))" +"\ \ (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(Person)))" unfolding OclAllInstances_at_pre_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) -subsection{* The Accessors (any, boss, salary) *} +section{* The Accessors (any, boss, salary) *} text{*\label{sec:eam-accessors}*} text{* Should be generated entirely from a class-diagram. *} -subsubsection{* Definition (of the association Employee-Boss) *} +subsection{* Definition (of the association Employee-Boss) *} text{* We start with a oid for the association; this oid can be used in presence of association classes to represent the association inside an object, -pretty much similar to the \inlineisar+Employee_DesignModel_UMLPart+, where we stored +pretty much similar to the \inlineisar+Design_UML+, where we stored an \verb+oid+ inside the class as ``pointer.'' *} definition oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ ::"oid" where "oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ = 10" @@ -751,65 +804,44 @@ where "eval_extract X f = (\ \. case X \ of \ \ invalid \ (* exception propagation *) | \ \ \ \ invalid \ (* dereferencing null pointer *) | \\ obj \\ \ f (oid_of obj) \)" -(* TODO: rephrasing as if-then-else and shifting to OCL_state. *) definition "choose\<^sub>2_1 = fst" definition "choose\<^sub>2_2 = snd" -definition "choose\<^sub>3_1 = fst" -definition "choose\<^sub>3_2 = fst o snd" -definition "choose\<^sub>3_3 = snd o snd" +definition "List_flatten = (\l. (foldl ((\acc. (\l. (foldl ((\acc. (\l. (Cons (l) (acc))))) (acc) ((rev (l))))))) (Nil) ((rev (l)))))" definition "deref_assocs\<^sub>2" :: "('\ state \ '\ state \ '\ state) - \ (oid \ oid \ oid \ oid) + \ (oid list list \ oid list \ oid list) \ oid - \ (oid list \ oid \ ('\,'f)val) + \ (oid list \ ('\,'f)val) \ oid \ ('\, 'f::null)val" where "deref_assocs\<^sub>2 pre_post to_from assoc_oid f oid = - (\\. case (assocs\<^sub>2 (pre_post \)) assoc_oid of - \ S \ \ f (map (choose\<^sub>2_2 \ to_from) - (filter (\ p. choose\<^sub>2_1(to_from p)=oid) S)) - oid \ + (\\. case (assocs (pre_post \)) assoc_oid of + \ S \ \ f (List_flatten (map (choose\<^sub>2_2 \ to_from) + (filter (\ p. List.member (choose\<^sub>2_1 (to_from p)) oid) S))) + \ | _ \ invalid \)" text{* The @{text pre_post}-parameter is configured with @{text fst} or @{text snd}, the @{text to_from}-parameter either with the identity @{term id} or the following combinator @{text switch}: *} -definition "switch\<^sub>2_1 = id" -definition "switch\<^sub>2_2 = (\(x,y). (y,x))" -definition "switch\<^sub>3_1 = id" -definition "switch\<^sub>3_2 = (\(x,y,z). (x,z,y))" -definition "switch\<^sub>3_3 = (\(x,y,z). (y,x,z))" -definition "switch\<^sub>3_4 = (\(x,y,z). (y,z,x))" -definition "switch\<^sub>3_5 = (\(x,y,z). (z,x,y))" -definition "switch\<^sub>3_6 = (\(x,y,z). (z,y,x))" - -definition select_object ::" (('\, 'b::null)val) - \ (('\,'b)val \ ('\,'c)val \ ('\, 'b)val) - \ (('\, 'b)val \ ('\, 'd)val) - \ (oid \ ('\,'c::null)val) - \ oid list - \ oid - \ ('\, 'd)val" -where "select_object mt incl smash deref l oid = smash(foldl incl mt (map deref l)) - (* smash returns null with mt in input (in this case, object contains null pointer) *)" - - -text{* The continuation @{text f} is usually instantiated with a smashing -function which is either the identity @{term id} or, for \inlineocl{0..1} cardinalities -of associations, the @{term OclANY}-selector which also handles the -@{term null}-cases appropriately. A standard use-case for this combinator -is for example: *} -term "(select_object mtSet OclIncluding OclANY f l oid )::('\, 'a::null)val" +definition "switch\<^sub>2_1 = (\[x,y]\ (x,y))" +definition "switch\<^sub>2_2 = (\[x,y]\ (y,x))" +definition "switch\<^sub>3_1 = (\[x,y,z]\ (x,y))" +definition "switch\<^sub>3_2 = (\[x,y,z]\ (x,z))" +definition "switch\<^sub>3_3 = (\[x,y,z]\ (y,x))" +definition "switch\<^sub>3_4 = (\[x,y,z]\ (y,z))" +definition "switch\<^sub>3_5 = (\[x,y,z]\ (z,x))" +definition "switch\<^sub>3_6 = (\[x,y,z]\ (z,y))" definition deref_oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "(\ state \ \ state \ \ state) \ (type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ (\, 'c::null)val) \ oid \ (\, 'c::null)val" where "deref_oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n fst_snd f oid = (\\. case (heap (fst_snd \)) oid of - \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n obj \ \ f obj \ - | _ \ invalid \)" + \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n obj \ \ f obj \ + | _ \ invalid \)" @@ -829,7 +861,7 @@ definition "select\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\ f | (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y _ \any\) \ f (\x _. \\x\\) any)" -definition "select\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ f = select_object mtSet OclIncluding OclANY (f (\x _. \\x\\))" +definition "select\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ f = select_object mtSet UML_Set.OclIncluding UML_Set.OclANY (f (\x _. \\x\\))" definition "select\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\ f = (\ X. case X of @@ -883,7 +915,7 @@ definition dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\< (select\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\ reconst_basetype))" -lemmas [simp] = +lemmas dot_accessor = dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_def dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_def @@ -891,17 +923,17 @@ lemmas [simp] = dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre_def dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre_def -subsubsection{* Context Passing *} +subsection{* Context Passing *} lemmas [simp] = eval_extract_def -lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\: "((X).any) \ = ((\_. X \).any) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\: "((X).boss) \ = ((\_. X \).boss) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\: "((X).salary) \ = ((\_. X \).salary) \" by simp +lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\: "((X).any) \ = ((\_. X \).any) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\: "((X).boss) \ = ((\_. X \).boss) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\: "((X).salary) \ = ((\_. X \).salary) \" by (simp add: dot_accessor) -lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre: "((X).any@pre) \ = ((\_. X \).any@pre) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre: "((X).boss@pre) \ = ((\_. X \).boss@pre) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre: "((X).salary@pre) \ = ((\_. X \).salary@pre) \" by simp +lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre: "((X).any@pre) \ = ((\_. X \).any@pre) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre: "((X).boss@pre) \ = ((\_. X \).boss@pre) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre: "((X).salary@pre) \ = ((\_. X \).salary@pre) \" by (simp add: dot_accessor) lemmas cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_I [simp, intro!]= cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\[THEN allI[THEN allI], @@ -924,39 +956,59 @@ lemmas cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre[THEN allI[THEN allI], of "\ X _. X" "\ _ \. \", THEN cpI1] -subsubsection{* Execution with Invalid or Null as Argument *} +subsection{* Execution with Invalid or Null as Argument *} lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_nullstrict [simp]: "(null).any = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre_nullstrict [simp] : "(null).any@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_strict [simp] : "(invalid).any = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre_strict [simp] : "(invalid).any@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_nullstrict [simp]: "(null).boss = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre_nullstrict [simp] : "(null).boss@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_strict [simp] : "(invalid).boss = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre_strict [simp] : "(invalid).boss@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_nullstrict [simp]: "(null).salary = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre_nullstrict [simp] : "(null).salary@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_strict [simp] : "(invalid).salary = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre_strict [simp] : "(invalid).salary@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) +subsection{* Representation in States *} -subsection{* A Little Infra-structure on Example States *} +lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def_mono:"\ \ \(X .boss) \ \ \ \(X)" + apply(case_tac "\ \ (X \ invalid)", insert StrongEq_L_subst2[where P = "(\x. (\ (x .boss)))" and \ = "\" and x = "X" and y = "invalid"], simp add: foundation16') + apply(case_tac "\ \ (X \ null)", insert StrongEq_L_subst2[where P = "(\x. (\ (x .boss)))" and \ = "\" and x = "X" and y = "null"], simp add: foundation16') +by(simp add: defined_split) + +lemma repr_boss: +assumes A : "\ \ \(x .boss)" +shows "is_represented_in_state in_post_state (x .boss) Person \" + apply(insert A[simplified foundation16] + A[THEN dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def_mono, simplified foundation16]) + unfolding is_represented_in_state_def + dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def eval_extract_def select\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def in_post_state_def + oops + +lemma repr_bossX : +assumes A: "\ \ \(x .boss)" +shows "\ \ ((Person .allInstances()) ->includes\<^sub>S\<^sub>e\<^sub>t(x .boss))" +oops + +section{* A Little Infra-structure on Example States *} text{* The example we are defining in this section comes from the figure~\ref{fig:eam1_system-states}. @@ -968,6 +1020,8 @@ The example we are defining in this section comes from the figure~\ref{fig:eam1_ \end{figure} *} +text_raw{* \isatagafp*} + definition OclInt1000 ("\\\\") where "OclInt1000 = (\ _ . \\1000\\)" definition OclInt1200 ("\\\\") where "OclInt1200 = (\ _ . \\1200\\)" definition OclInt1300 ("\\\\") where "OclInt1300 = (\ _ . \\1300\\)" @@ -997,6 +1051,8 @@ definition "person7 \ mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y definition "person8 \ mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid7 None" definition "person9 \ mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid8 \0\" +text_raw{* \endisatagafp*} + definition "\\<^sub>1 \ \ heap = empty(oid0 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n (mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid0 \1000\)) (oid1 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n (mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid1 \1200\)) @@ -1007,8 +1063,7 @@ definition (*oid6*) (*oid7*) (oid8 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person9), - assocs\<^sub>2 = empty(oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ \ [(oid0,oid1),(oid3,oid4),(oid5,oid3)]), - assocs\<^sub>3 = empty \" + assocs = empty(oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ \ [[[oid0],[oid1]],[[oid3],[oid4]],[[oid5],[oid3]]]) \" definition "\\<^sub>1' \ \ heap = empty(oid0 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person1) @@ -1020,10 +1075,9 @@ definition (oid6 \ in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y person7) (oid7 \ in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y person8) (oid8 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person9), - assocs\<^sub>2 = empty(oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ \ [(oid0,oid1),(oid1,oid1),(oid5,oid6),(oid6,oid6)]), - assocs\<^sub>3 = empty \" + assocs = empty(oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\ \ [[[oid0],[oid1]],[[oid1],[oid1]],[[oid5],[oid6]],[[oid6],[oid6]]]) \" -definition "\\<^sub>0 \ \ heap = empty, assocs\<^sub>2 = empty, assocs\<^sub>3 = empty \" +definition "\\<^sub>0 \ \ heap = empty, assocs = empty \" lemma basic_\_wff: "WFF(\\<^sub>1,\\<^sub>1')" @@ -1039,6 +1093,8 @@ by(auto simp: \\<^sub>1_def) lemma [simp,code_unfold]: "dom (heap \\<^sub>1') = {oid0,oid1,oid2,oid3,(*,oid4*)oid5,oid6,oid7,oid8}" by(auto simp: \\<^sub>1'_def) +text_raw{* \isatagafp *} + definition "X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 :: Person \ \ _ .\\ person1 \\" definition "X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 :: Person \ \ _ .\\ person2 \\" definition "X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 :: Person \ \ _ .\\ person3 \\" @@ -1067,23 +1123,23 @@ lemmas [simp,code_unfold] = OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person +text_raw{* \endisatagafp *} - -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary <> \\\\)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre <> \\\\)" -(*value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .salary \ \\\\)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre <> \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre .boss@pre))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary <> \\\\)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre <> \\\\)" +(*Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .salary \ \\\\)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre <> \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre .boss@pre))" *) lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsMaintained())" by(simp add: OclValid_def OclIsMaintained_def @@ -1094,104 +1150,91 @@ by(simp add: OclValid_def OclIsMaintained_def lemma "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) .oclAsType(Person)) \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" by(rule up_down_cast_Person_OclAny_Person', simp add: X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1_def) -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) .oclIsTypeOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) .oclIsTypeOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary@pre \ \\\\)" -(*value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .salary@pre \ \\\\)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .boss@pre \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .boss))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .salary@pre))" -*)lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .oclIsMaintained())" -by(simp add: OclValid_def OclIsMaintained_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2_def person2_def +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary@pre \ \\\\)" +(*Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .salary@pre \ \\\\)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .boss@pre \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .boss))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .salary@pre))" +*) +lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .oclIsMaintained())" +by(simp add: OclValid_def OclIsMaintained_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2_def person2_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary@pre))" -(*value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss \ null)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss .salary))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss@pre))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary@pre))" +(*Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss \ null)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss .salary))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss@pre))" *)lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .oclIsNew())" -by(simp add: OclValid_def OclIsNew_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3_def person3_def +by(simp add: OclValid_def OclIsNew_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3_def person3_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid8_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) -(*value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" -value " (\\<^sub>1,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary@pre \ \\\\)" -*)lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .oclIsMaintained())" -by(simp add: OclValid_def OclIsMaintained_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4_def person4_def +(*Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" +Assert " (\\<^sub>1,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary@pre \ \\\\)" +*) +lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .oclIsMaintained())" +by(simp add: OclValid_def OclIsMaintained_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4_def person4_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary@pre \ \\\\)" -(*value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .boss))" -*)lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .oclIsDeleted())" -by(simp add: OclNot_def OclValid_def OclIsDeleted_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5_def person5_def +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary@pre \ \\\\)" +(*Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .boss))" +*) +lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .oclIsDeleted())" +by(simp add: OclNot_def OclValid_def OclIsDeleted_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5_def person5_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid7_def oid8_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary) \ \\\\ )"*) -(*value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary@pre))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary@pre \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" -*)lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .oclIsMaintained())" -by(simp add: OclValid_def OclIsMaintained_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6_def person6_def +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary) \ \\\\ )"*) +(*Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary@pre))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary@pre \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" +*) +lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .oclIsMaintained())" +by(simp add: OclValid_def OclIsMaintained_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6_def person6_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss)))" *) -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person)) )" *) -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss .salary) \ \\\\ )" *) -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ \(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person))" -(*value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss@pre))" -*)lemma "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .oclAsType(OclAny) +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss)))" *) +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person)) )" *) +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss .salary) \ \\\\ )" *) +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ \(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person))" +(*Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss@pre))" +*) +lemma "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .oclAsType(OclAny) .oclAsType(Person)) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person)))" by(rule up_down_cast_Person_OclAny_Person', simp add: X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7_def OclValid_def valid_def person7_def) lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclIsNew())" -by(simp add: OclValid_def OclIsNew_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7_def person7_def +by(simp add: OclValid_def OclIsNew_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7_def person7_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid8_def oid_of_option_def oid_of_type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_def) - -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7)" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclAsType(Person)))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(OclAny))" - +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclAsType(Person)))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(OclAny))" lemma \_modifiedonly: "(\\<^sub>1,\\<^sub>1') \ (Set{ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) , X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .oclAsType(OclAny) @@ -1228,21 +1271,22 @@ lemma "(\\<^sub>1,\\<^sub>1') \ (((X\<^sub>P\<^sub>e\<^ proof - have including4 : "\a b c d \. - Set{\\. \\a\\, \\. \\b\\, \\. \\c\\, \\. \\d\\} \ = Abs_Set_0 \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\" + Set{\\. \\a\\, \\. \\b\\, \\. \\c\\, \\. \\d\\} \ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\" apply(subst abs_rep_simp'[symmetric], simp) - by(simp add: OclIncluding_rep_set mtSet_rep_set) + apply(simp add: OclIncluding_rep_set mtSet_rep_set) + by(rule arg_cong[of _ _ "\x. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(\\ x \\))"], auto) have excluding1: "\S a b c d e \. - (\_. Abs_Set_0 \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\)->excluding(\\. \\e\\) \ = - Abs_Set_0 \\ {\\a\\, \\b\\, \\c\\, \\d\\} - {\\e\\} \\" - apply(simp add: OclExcluding_def) + (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\)->excluding\<^sub>S\<^sub>e\<^sub>t(\\. \\e\\) \ = + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ {\\a\\, \\b\\, \\c\\, \\d\\} - {\\e\\} \\" + apply(simp add: UML_Set.OclExcluding_def) apply(simp add: defined_def OclValid_def false_def true_def - bot_fun_def bot_Set_0_def null_fun_def null_Set_0_def) + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) apply(rule conjI) - apply(rule impI, subst (asm) Abs_Set_0_inject) apply( simp add: bot_option_def)+ + apply(rule impI, subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) apply( simp add: bot_option_def)+ apply(rule conjI) - apply(rule impI, subst (asm) Abs_Set_0_inject) apply( simp add: bot_option_def null_option_def)+ - apply(subst Abs_Set_0_inverse, simp add: bot_option_def, simp) + apply(rule impI, subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) apply( simp add: bot_option_def null_option_def)+ + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def, simp) done show ?thesis @@ -1262,7 +1306,7 @@ proof - person1_def person2_def person3_def person4_def person5_def person6_def person7_def person8_def person9_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - apply(subst cp_OclIsModifiedOnly, subst cp_OclExcluding, + apply(subst cp_OclIsModifiedOnly, subst UML_Set.OclExcluding.cp0, subst (asm) cp_OclIsModifiedOnly, simp add: including4 excluding1) apply(simp only: X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4_def @@ -1286,8 +1330,7 @@ lemma perm_\\<^sub>1' : "\\<^sub>1' = \ heap = empty (oid2 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person3) (oid1 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person2) (oid0 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person1) - , assocs\<^sub>2 = assocs\<^sub>2 \\<^sub>1' - , assocs\<^sub>3 = assocs\<^sub>3 \\<^sub>1' \" + , assocs = assocs \\<^sub>1' \" proof - note P = fun_upd_twist show ?thesis @@ -1328,7 +1371,7 @@ by(simp_all add: OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_\ lemma "\\\<^sub>1. (\\<^sub>1,\\<^sub>1') \ (OclAny .allInstances() \ Set{ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .oclAsType(OclAny) - (*, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5*), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .oclAsType(OclAny), + (*, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5*), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n9 .oclAsType(OclAny) })" apply(subst perm_\\<^sub>1') apply(simp only: oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid7_def oid8_def diff --git a/examples/Employee_Model/Design/Design_OCL.thy b/examples/Employee_Model/Design/Design_OCL.thy new file mode 100644 index 0000000..6e7fb56 --- /dev/null +++ b/examples/Employee_Model/Design/Design_OCL.thy @@ -0,0 +1,137 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * Design_OCL.thy --- OCL Contracts and an Example. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory + Design_OCL +imports + Design_UML +begin +text {* \label{ex:employee-design:ocl} *} + +section{* OCL Part: Invariant *} +text{* These recursive predicates can be defined conservatively +by greatest fix-point +constructions---automatically. See~\cite{brucker.ea:hol-ocl-book:2006,brucker:interactive:2007} +for details. For the purpose of this example, we state them as axioms +here. + +\begin{ocl} +context Person + inv label : self .boss <> null implies (self .salary \ ((self .boss) .salary)) +\end{ocl} +*} + +definition Person_label\<^sub>i\<^sub>n\<^sub>v :: "Person \ Boolean" +where "Person_label\<^sub>i\<^sub>n\<^sub>v (self) \ + (self .boss <> null implies (self .salary \\<^sub>i\<^sub>n\<^sub>t ((self .boss) .salary)))" + + +definition Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e :: "Person \ Boolean" +where "Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e (self) \ + (self .boss@pre <> null implies (self .salary@pre \\<^sub>i\<^sub>n\<^sub>t ((self .boss@pre) .salary@pre)))" + +definition Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v :: "Boolean" +where "Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(x | Person_label\<^sub>i\<^sub>n\<^sub>v (x)) and + (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(x | Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e (x))))" + + +lemma "\ \ \ (X .boss) \ \ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X .boss) \ + \ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X) " +oops +(* To be generated generically ... hard, but crucial lemma that should hold. + It means that X and it successor are object representation that actually + occur in the state. *) + +lemma REC_pre : "\ \ Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v + \ \ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X) (* X represented object in state *) + \ \ REC. \ \ REC(X) \ (Person_label\<^sub>i\<^sub>n\<^sub>v (X) and (X .boss <> null implies REC(X .boss)))" +oops (* Attempt to allegiate the burden of he following axiomatizations: could be + a witness for a constant specification ...*) + +text{* This allows to state a predicate: *} + +axiomatization inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l :: "Person \ Boolean" +where inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l_def: +"(\ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self) \ (self .boss <> null implies + (self .salary \\<^sub>i\<^sub>n\<^sub>t ((self .boss) .salary)) and + inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self .boss))))" + +axiomatization inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e :: "Person \ Boolean" +where inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e_def: +"(\ \ Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self) \ (self .boss@pre <> null implies + (self .salary@pre \\<^sub>i\<^sub>n\<^sub>t ((self .boss@pre) .salary@pre)) and + inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self .boss@pre))))" + + +lemma inv_1 : +"(\ \ Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self) = ((\ \ (self .boss \ null)) \ + ( \ \ (self .boss <> null) \ + \ \ ((self .salary) \\<^sub>i\<^sub>n\<^sub>t (self .boss .salary)) \ + \ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l(self .boss))))) " +oops (* Let's hope that this holds ... *) + + +lemma inv_2 : +"(\ \ Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \ + (\ \ inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self)) = ((\ \ (self .boss@pre \ null)) \ + (\ \ (self .boss@pre <> null) \ + (\ \ (self .boss@pre .salary@pre \\<^sub>i\<^sub>n\<^sub>t self .salary@pre)) \ + (\ \ (inv\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\<^sub>_\<^sub>l\<^sub>a\<^sub>b\<^sub>e\<^sub>l\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e(self .boss@pre)))))" +oops (* Let's hope that this holds ... *) + +text{* A very first attempt to characterize the axiomatization by an inductive +definition - this can not be the last word since too weak (should be equality!) *} +coinductive inv :: "Person \ (\)st \ bool" where + "(\ \ (\ self)) \ ((\ \ (self .boss \ null)) \ + (\ \ (self .boss <> null) \ (\ \ (self .boss .salary \\<^sub>i\<^sub>n\<^sub>t self .salary)) \ + ( (inv(self .boss))\ ))) + \ ( inv self \)" + + +section{* OCL Part: The Contract of a Recursive Query *} +text{* This part is analogous to the Analysis Model and skipped here. *} + + +end diff --git a/examples/Employee_DesignModel_UMLPart.thy b/examples/Employee_Model/Design/Design_UML.thy similarity index 70% rename from examples/Employee_DesignModel_UMLPart.thy rename to examples/Employee_Model/Design/Design_UML.thy index c446788..e1da591 100644 --- a/examples/Employee_DesignModel_UMLPart.thy +++ b/examples/Employee_Model/Design/Design_UML.thy @@ -1,13 +1,13 @@ (***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 * for the OMG Standard. * http://www.brucker.ch/projects/hol-testgen/ * - * Employee_DesignModel_UMLPart.thy --- OCL Contracts and an Example. + * Design_UML.thy --- OCL Contracts and an Example. * This file is part of HOL-TestGen. * - * Copyright (c) 2012-2013 Universite Paris-Sud, France - * 2013 IRT SystemX, France + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France * * All rights reserved. * @@ -40,18 +40,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************) -section{* The Employee Design Model (UML) *} +chapter{* Example: The Employee Design Model *} (* UML part *) theory - Employee_DesignModel_UMLPart + Design_UML imports - "../OCL_main" + "../../../src/UML_Main" begin text {* \label{ex:employee-design:uml} *} -subsection{* Introduction *} -text{* +section{* Introduction *} +text{* For certain concepts like classes and class-types, only a generic definition for its resulting semantics can be given. Generic means, there is a function outside HOL that ``compiles'' a concrete, @@ -69,7 +69,7 @@ text{* Such generic function or ``compiler'' can be implemented in concepts of the compilation informally, and present a concrete example which is verified in Isabelle/HOL. *} -subsubsection{* Outlining the Example *} +subsection{* Outlining the Example *} text{* We are presenting here a ``design-model'' of the (slightly modified) example Figure 7.3, page 20 of @@ -90,10 +90,9 @@ by the attribute \inlineocl+boss+ and the operation \inlineocl+employees+ (to b captured by the subsequent theory). *} -subsection{* Example Data-Universe and its Infrastructure *} +section{* Example Data-Universe and its Infrastructure *} text{* Ideally, the following is generated automatically from a UML class model. *} -(* @{text "'\"} -- \mathfrak{A} *) text{* Our data universe consists in the concrete class diagram just of node's, and implicitly of the class object. Each class implies the existence of a class type defined for the corresponding object representations as follows: *} @@ -105,8 +104,8 @@ datatype type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n = mk\<^sub>P\<^sub datatype type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y = mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid (* the oid to the oclany itself *) "(int option \ oid option) option" - (* the extensions to "person"; used to denote - objects of actual type "person" casted to "oclany"; + (* the extensions to "person"; used to denote + objects of actual type "person" casted to "oclany"; in case of existence of several subclasses of oclany, sums of extensions have to be provided. *) @@ -156,14 +155,21 @@ end -subsection{* Instantiation of the Generic Strict Equality *} +section{* Instantiation of the Generic Strict Equality *} text{* We instantiate the referential equality on @{text "Person"} and @{text "OclAny"} *} -defs(overloaded) StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n : "(x::Person) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" -defs(overloaded) StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y : "(x::OclAny) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" +overloading StrictRefEq \ "StrictRefEq :: [Person,Person] \ Boolean" +begin + definition StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n : "(x::Person) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" +end -lemmas +overloading StrictRefEq \ "StrictRefEq :: [OclAny,OclAny] \ Boolean" +begin + definition StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y : "(x::OclAny) \ y \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y" +end + +lemmas cps23 = cp_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t[of "x::Person" "y::Person" "\", simplified StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n[symmetric]] cp_intro(9) [of "P::Person \Person""Q::Person \Person", @@ -179,8 +185,6 @@ lemmas [of "x::Person", simplified StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n[symmetric]] - - text{* For each Class \emph{C}, we will have a casting operation \inlineocl{.oclAsType($C$)}, a test on the actual type \inlineocl{.oclIsTypeOf($C$)} as well as its relaxed form \inlineocl{.oclIsKindOf($C$)} (corresponding exactly to Java's \verb+instanceof+-operator. @@ -190,8 +194,8 @@ two operations to declare and to provide two overloading definitions for the two *} -subsection{* OclAsType *} -subsubsection{* Definition *} +section{* OclAsType *} +subsection{* Definition *} consts OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: "'\ \ OclAny" ("(_) .oclAsType'(OclAny')") consts OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "'\ \ Person" ("(_) .oclAsType'(Person')") @@ -202,37 +206,49 @@ definition "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\ = (\ lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\_some: "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\ x \ None" by(simp add: OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\_def) -defs (overloaded) OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: +overloading OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: OclAny \ OclAny" +begin + definition OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: "(X::OclAny) .oclAsType(OclAny) \ X" +end -defs (overloaded) OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: +overloading OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: Person \ OclAny" +begin + definition OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: "(X::Person) .oclAsType(OclAny) \ (\\. case X \ of \ \ invalid \ | \\\ \ null \ | \\mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a b \\ \ \\ (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \(a,b)\) \\)" +end -definition "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_\ = (\u. case u of in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n p \ \p\ - | in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \(a,b)\) \ \mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a b\ - | _ \ None)" +definition "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_\ = + (\u. case u of in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n p \ \p\ + | in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \(a,b)\) \ \mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a b\ + | _ \ None)" -defs (overloaded) OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: +overloading OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: OclAny \ Person" +begin + definition OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: "(X::OclAny) .oclAsType(Person) \ (\\. case X \ of \ \ invalid \ | \\\ \ null \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ invalid \ (* down-cast exception *) | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \(a,b)\ \\ \ \\mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n oid a b \\)" +end -defs (overloaded) OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: +overloading OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: Person \ Person" +begin + definition OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: "(X::Person) .oclAsType(Person) \ X " (* to avoid identity for null ? *) - +end +text_raw{* \isatagafp *} lemmas [simp] = OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person - -subsubsection{* Context Passing *} +subsection{* Context Passing *} lemma cp_OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_Person: "cp P \ cp(\X. (P (X::Person)::Person) .oclAsType(OclAny))" by(rule cpI1, simp_all add: OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) @@ -263,72 +279,93 @@ lemmas [simp] = cp_OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_OclAny cp_OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_Person -subsubsection{* Execution with Invalid or Null as Argument *} +text_raw{* \endisatagafp*} -lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict : "(invalid::OclAny) .oclAsType(OclAny) = invalid" -by(simp) - -lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_nullstrict : "(null::OclAny) .oclAsType(OclAny) = null" -by(simp) +subsection{* Execution with Invalid or Null as Argument *} +lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict : "(invalid::OclAny) .oclAsType(OclAny) = invalid" by(simp) +lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_nullstrict : "(null::OclAny) .oclAsType(OclAny) = null" by(simp) lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_strict[simp] : "(invalid::Person) .oclAsType(OclAny) = invalid" -by(rule ext, simp add: bot_option_def invalid_def - OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - + by(rule ext, simp add: bot_option_def invalid_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) lemma OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_nullstrict[simp] : "(null::Person) .oclAsType(OclAny) = null" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def - OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - + by(rule ext, simp add: null_fun_def null_option_def bot_option_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_strict[simp] : "(invalid::OclAny) .oclAsType(Person) = invalid" -by(rule ext, simp add: bot_option_def invalid_def - OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) - + by(rule ext, simp add: bot_option_def invalid_def OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_nullstrict[simp] : "(null::OclAny) .oclAsType(Person) = null" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def - OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) + by(rule ext, simp add: null_fun_def null_option_def bot_option_def OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) +lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict : "(invalid::Person) .oclAsType(Person) = invalid" by(simp) +lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_nullstrict : "(null::Person) .oclAsType(Person) = null" by(simp) -lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict : "(invalid::Person) .oclAsType(Person) = invalid" -by(simp) -lemma OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_nullstrict : "(null::Person) .oclAsType(Person) = null" -by(simp) +section{* OclIsTypeOf *} -subsection{* OclIsTypeOf *} -subsubsection{* Definition *} +subsection{* Definition *} consts OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: "'\ \ Boolean" ("(_).oclIsTypeOf'(OclAny')") consts OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "'\ \ Boolean" ("(_).oclIsTypeOf'(Person')") -defs (overloaded) OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: +overloading OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: OclAny \ Boolean" +begin + definition OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: "(X::OclAny) .oclIsTypeOf(OclAny) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ (* invalid ?? *) | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ true \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ false \)" +end +lemma OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny': + "(X::OclAny) .oclIsTypeOf(OclAny) = + (\ \. if \ \ \ X then (case X \ of + \\\ \ true \ (* invalid ?? *) + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ true \ + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ false \) + else invalid \)" + apply(rule ext, simp add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) + by(case_tac "\ \ \ X", auto simp: foundation18' bot_option_def) -defs (overloaded) OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: +interpretation OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny : + profile_mono_schemeV + "OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y::OclAny \ Boolean" + "\ X. (case X of + \None\ \ \\True\\ (* invalid ?? *) + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid None \\ \ \\True\\ + | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ \\False\\)" + apply(unfold_locales, simp add: atomize_eq, rule ext) + by(auto simp: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny' OclValid_def true_def false_def + split: option.split type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y.split) + +overloading OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: Person \ Boolean" +begin + definition OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: "(X::Person) .oclIsTypeOf(OclAny) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ (* invalid ?? *) | \\ _ \\ \ false \)" (* must have actual type Person otherwise *) +end -defs (overloaded) OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: +overloading OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: OclAny \ Boolean" +begin + definition OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: "(X::OclAny) .oclIsTypeOf(Person) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ false \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ true \)" +end -defs (overloaded) OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: +overloading OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: Person \ Boolean" +begin + definition OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: "(X::Person) .oclIsTypeOf(Person) \ (\\. case X \ of \ \ invalid \ - | _ \ true \)" - -subsubsection{* Context Passing *} + | _ \ true \)" (* for (* \\ _ \\ \ true \ *) : must have actual type Node otherwise *) +end +text_raw{* \isatagafp *} +subsection{* Context Passing *} lemma cp_OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_Person: "cp P \ cp(\X.(P(X::Person)::Person).oclIsTypeOf(OclAny))" by(rule cpI1, simp_all add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) @@ -359,8 +396,9 @@ lemmas [simp] = cp_OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_Person cp_OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_OclAny cp_OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_Person +text_raw{* \endisatagafp *} -subsubsection{* Execution with Invalid or Null as Argument *} +subsection{* Execution with Invalid or Null as Argument *} lemma OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict1[simp]: "(invalid::OclAny) .oclIsTypeOf(OclAny) = invalid" @@ -395,7 +433,7 @@ lemma OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict2 by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) -subsubsection{* Up Down Casting *} +subsection{* Up Down Casting *} lemma actualType_larger_staticType: assumes isdef: "\ \ (\ X)" @@ -434,57 +472,72 @@ shows "((X::Person) .oclAsType(OclAny) .oclAsType(Person) = X)" apply(rule ext, rename_tac \) apply(rule foundation22[THEN iffD1]) apply(case_tac "\ \ (\ X)", simp add: up_down_cast) - apply(simp add: def_split_local, elim disjE) + apply(simp add: defined_split, elim disjE) apply(erule StrongEq_L_subst2_rev, simp, simp)+ done -lemma up_down_cast_Person_OclAny_Person': assumes "\ \ \ X" -shows "\ \ (((X :: Person) .oclAsType(OclAny) .oclAsType(Person)) \ X)" +lemma up_down_cast_Person_OclAny_Person': +assumes "\ \ \ X" +shows "\ \ (((X :: Person) .oclAsType(OclAny) .oclAsType(Person)) \ X)" apply(simp only: up_down_cast_Person_OclAny_Person StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) by(rule StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_sym, simp add: assms) -lemma up_down_cast_Person_OclAny_Person'': assumes "\ \ \ (X :: Person)" -shows "\ \ (X .oclIsTypeOf(Person) implies (X .oclAsType(OclAny) .oclAsType(Person)) \ X)" +lemma up_down_cast_Person_OclAny_Person'': +assumes "\ \ \ (X :: Person)" +shows "\ \ (X .oclIsTypeOf(Person) implies (X .oclAsType(OclAny) .oclAsType(Person)) \ X)" apply(simp add: OclValid_def) apply(subst cp_OclImplies) apply(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_sym[OF assms, simplified OclValid_def]) apply(subst cp_OclImplies[symmetric]) -by (simp add: OclImplies_true) +by simp -subsection{* OclIsKindOf *} -subsubsection{* Definition *} +section{* OclIsKindOf *} +subsection{* Definition *} consts OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: "'\ \ Boolean" ("(_).oclIsKindOf'(OclAny')") consts OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "'\ \ Boolean" ("(_).oclIsKindOf'(Person')") -defs (overloaded) OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: +overloading OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: OclAny \ Boolean" +begin + definition OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny: "(X::OclAny) .oclIsKindOf(OclAny) \ (\\. case X \ of \ \ invalid \ | _ \ true \)" +end -defs (overloaded) OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: +overloading OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y \ "OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y :: Person \ Boolean" +begin + definition OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person: "(X::Person) .oclIsKindOf(OclAny) \ (\\. case X \ of \ \ invalid \ | _\ true \)" +(* for (* \\mk\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n e oid _ \\ \ true \ *) : must have actual type Person otherwise *) +end -defs (overloaded) OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: +overloading OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: OclAny \ Boolean" +begin + definition OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny: "(X::OclAny) .oclIsKindOf(Person) \ (\\. case X \ of \ \ invalid \ | \\\ \ true \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \ \\ \ false \ | \\mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \_\ \\ \ true \)" +end -defs (overloaded) OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: +overloading OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n \ "OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: Person \ Boolean" +begin + definition OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person: "(X::Person) .oclIsKindOf(Person) \ (\\. case X \ of \ \ invalid \ | _ \ true \)" - -subsubsection{* Context Passing *} +end +text_raw{* \isatagafp *} +subsection{* Context Passing *} lemma cp_OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_Person: "cp P \ cp(\X.(P(X::Person)::Person).oclIsKindOf(OclAny))" by(rule cpI1, simp_all add: OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) @@ -514,63 +567,56 @@ lemmas [simp] = cp_OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_Person cp_OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_OclAny cp_OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_Person - -subsubsection{* Execution with Invalid or Null as Argument *} +text_raw{* \endisatagafp *} +subsection{* Execution with Invalid or Null as Argument *} lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict1[simp] : "(invalid::OclAny) .oclIsKindOf(OclAny) = invalid" by(rule ext, simp add: invalid_def bot_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) - lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny_strict2[simp] : "(null::OclAny) .oclIsKindOf(OclAny) = true" by(rule ext, simp add: null_fun_def null_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) - lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_strict1[simp] : "(invalid::Person) .oclIsKindOf(OclAny) = invalid" by(rule ext, simp add: bot_option_def invalid_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - lemma OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person_strict2[simp] : "(null::Person) .oclIsKindOf(OclAny) = true" by(rule ext, simp add: null_fun_def null_option_def bot_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_strict1[simp]: "(invalid::OclAny) .oclIsKindOf(Person) = invalid" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny_strict2[simp]: "(null::OclAny) .oclIsKindOf(Person) = true" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict1[simp]: "(invalid::Person) .oclIsKindOf(Person) = invalid" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) - lemma OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person_strict2[simp]: "(null::Person) .oclIsKindOf(Person) = true" by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) -subsubsection{* Up Down Casting *} +subsection{* Up Down Casting *} lemma actualKind_larger_staticKind: assumes isdef: "\ \ (\ X)" -shows "\ \ (X::Person) .oclIsKindOf(OclAny) \ true" +shows "\ \ ((X::Person) .oclIsKindOf(OclAny) \ true)" using isdef by(auto simp : bot_option_def OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person foundation22 foundation16) lemma down_cast_kind: -assumes isOclAny: "\ \ \ (X::OclAny) .oclIsKindOf(Person)" +assumes isOclAny: "\ (\ \ ((X::OclAny).oclIsKindOf(Person)))" and non_null: "\ \ (\ X)" -shows "\ \ (X .oclAsType(Person)) \ invalid" +shows "\ \ ((X .oclAsType(Person)) \ invalid)" using isOclAny non_null apply(auto simp : bot_fun_def null_fun_def null_option_def bot_option_def null_def invalid_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny foundation22 foundation16 split: option.split type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y.split type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n.split) by(simp add: OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny OclValid_def false_def true_def) -subsection{* OclAllInstances *} +section{* OclAllInstances *} -text{* To denote OCL-types occuring in OCL expressions syntactically---as, for example, as +text{* To denote OCL-types occuring in OCL expressions syntactically---as, for example, as ``argument'' of \inlineisar{oclAllInstances()}---we use the inverses of the injection functions into the object universes; we show that this is sufficient ``characterization.'' *} @@ -579,7 +625,7 @@ definition "OclAny \ OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^ lemmas [simp] = Person_def OclAny_def lemma OclAllInstances_generic\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec: "OclAllInstances_generic pre_post OclAny = - (\\. Abs_Set_0 \\ Some ` OclAny ` ran (heap (pre_post \)) \\)" + (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ Some ` OclAny ` ran (heap (pre_post \)) \\)" proof - let ?S1 = "\\. OclAny ` ran (heap (pre_post \))" let ?S2 = "\\. ?S1 \ - {None}" @@ -590,143 +636,143 @@ proof - qed lemma OclAllInstances_at_post\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec: "OclAny .allInstances() = - (\\. Abs_Set_0 \\ Some ` OclAny ` ran (heap (snd \)) \\)" + (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ Some ` OclAny ` ran (heap (snd \)) \\)" unfolding OclAllInstances_at_post_def by(rule OclAllInstances_generic\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec) lemma OclAllInstances_at_pre\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec: "OclAny .allInstances@pre() = - (\\. Abs_Set_0 \\ Some ` OclAny ` ran (heap (fst \)) \\) " + (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ Some ` OclAny ` ran (heap (fst \)) \\) " unfolding OclAllInstances_at_pre_def by(rule OclAllInstances_generic\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_exec) -subsubsection{* OclIsTypeOf *} +subsection{* OclIsTypeOf *} lemma OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1: assumes [simp]: "\x. pre_post (x, x) = x" -shows "\\. (\ \ ((OclAllInstances_generic pre_post OclAny)->forAll(X|X .oclIsTypeOf(OclAny))))" +shows "\\. (\ \ ((OclAllInstances_generic pre_post OclAny)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" apply(rule_tac x = \\<^sub>0 in exI, simp add: \\<^sub>0_def OclValid_def del: OclAllInstances_generic_def) - apply(simp only: assms OclForall_def refl if_True + apply(simp only: assms UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) lemma OclAny_allInstances_at_post_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1: -"\\. (\ \ (OclAny .allInstances()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ (OclAny .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_post_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1, simp) lemma OclAny_allInstances_at_pre_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1: -"\\. (\ \ (OclAny .allInstances@pre()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ (OclAny .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_pre_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y1, simp) lemma OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2: assumes [simp]: "\x. pre_post (x, x) = x" -shows "\\. (\ \ not ((OclAllInstances_generic pre_post OclAny)->forAll(X|X .oclIsTypeOf(OclAny))))" +shows "\\. (\ \ not ((OclAllInstances_generic pre_post OclAny)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" proof - fix oid a let ?t0 = "\heap = empty(oid \ in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y (mk\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y oid \a\)), - assocs\<^sub>2 = empty, assocs\<^sub>3 = empty\" show ?thesis + assocs = empty\" show ?thesis apply(rule_tac x = "(?t0, ?t0)" in exI, simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_\_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny OclNot_def OclAny_def) qed lemma OclAny_allInstances_at_post_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2: -"\\. (\ \ not (OclAny .allInstances()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ not (OclAny .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_post_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2, simp) lemma OclAny_allInstances_at_pre_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2: -"\\. (\ \ not (OclAny .allInstances@pre()->forAll(X|X .oclIsTypeOf(OclAny))))" +"\\. (\ \ not (OclAny .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(OclAny))))" unfolding OclAllInstances_at_pre_def by(rule OclAny_allInstances_generic_oclIsTypeOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y2, simp) lemma Person_allInstances_generic_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ ((OclAllInstances_generic pre_post Person)->forAll(X|X .oclIsTypeOf(Person)))" +"\ \ ((OclAllInstances_generic pre_post Person)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(Person)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) lemma Person_allInstances_at_post_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances()->forAll(X|X .oclIsTypeOf(Person)))" +"\ \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(Person)))" unfolding OclAllInstances_at_post_def by(rule Person_allInstances_generic_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) lemma Person_allInstances_at_pre_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances@pre()->forAll(X|X .oclIsTypeOf(Person)))" +"\ \ (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsTypeOf(Person)))" unfolding OclAllInstances_at_pre_def by(rule Person_allInstances_generic_oclIsTypeOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) -subsubsection{* OclIsKindOf *} +subsection{* OclIsKindOf *} lemma OclAny_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ ((OclAllInstances_generic pre_post OclAny)->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ ((OclAllInstances_generic pre_post OclAny)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_OclAny) lemma OclAny_allInstances_at_post_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (OclAny .allInstances()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (OclAny .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_post_def by(rule OclAny_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma OclAny_allInstances_at_pre_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (OclAny .allInstances@pre()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (OclAny .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_pre_def by(rule OclAny_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma Person_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ ((OclAllInstances_generic pre_post Person)->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ ((OclAllInstances_generic pre_post Person)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) lemma Person_allInstances_at_post_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (Person .allInstances()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_post_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma Person_allInstances_at_pre_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y: -"\ \ (Person .allInstances@pre()->forAll(X|X .oclIsKindOf(OclAny)))" +"\ \ (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(OclAny)))" unfolding OclAllInstances_at_pre_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y) lemma Person_allInstances_generic_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ ((OclAllInstances_generic pre_post Person)->forAll(X|X .oclIsKindOf(Person)))" +"\ \ ((OclAllInstances_generic pre_post Person)->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(Person)))" apply(simp add: OclValid_def del: OclAllInstances_generic_def) - apply(simp only: OclForall_def refl if_True + apply(simp only: UML_Set.OclForall_def refl if_True OclAllInstances_generic_defined[simplified OclValid_def]) apply(simp only: OclAllInstances_generic_def) - apply(subst (1 2 3) Abs_Set_0_inverse, simp add: bot_option_def) + apply(subst (1 2 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def) by(simp add: OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person) lemma Person_allInstances_at_post_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances()->forAll(X|X .oclIsKindOf(Person)))" +"\ \ (Person .allInstances()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(Person)))" unfolding OclAllInstances_at_post_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) lemma Person_allInstances_at_pre_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n: -"\ \ (Person .allInstances@pre()->forAll(X|X .oclIsKindOf(Person)))" +"\ \ (Person .allInstances@pre()->forAll\<^sub>S\<^sub>e\<^sub>t(X|X .oclIsKindOf(Person)))" unfolding OclAllInstances_at_pre_def by(rule Person_allInstances_generic_oclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n) -subsection{* The Accessors (any, boss, salary) *} +section{* The Accessors (any, boss, salary) *} text{*\label{sec:edm-accessors}*} text{* Should be generated entirely from a class-diagram. *} -subsubsection{* Definition *} +subsection{* Definition *} definition eval_extract :: "('\,('a::object) option option) val \ (oid \ ('\,'c::null) val) @@ -735,7 +781,6 @@ where "eval_extract X f = (\ \. case X \ of \ \ invalid \ (* exception propagation *) | \ \ \ \ invalid \ (* dereferencing null pointer *) | \\ obj \\ \ f (oid_of obj) \)" -(* TODO: rephrasing as if-then-else and shifting to OCL_state. *) definition deref_oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "(\ state \ \ state \ \ state) @@ -743,8 +788,8 @@ definition deref_oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n :: "(\ \ oid \ (\, 'c::null)val" where "deref_oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n fst_snd f oid = (\\. case (heap (fst_snd \)) oid of - \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n obj \ \ f obj \ - | _ \ invalid \)" + \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n obj \ \ f obj \ + | _ \ invalid \)" @@ -815,7 +860,7 @@ definition dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\< (select\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\ reconst_basetype))" -lemmas [simp] = +lemmas dot_accessor = dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_def dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_def @@ -823,17 +868,17 @@ lemmas [simp] = dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre_def dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre_def -subsubsection{* Context Passing *} +subsection{* Context Passing *} lemmas [simp] = eval_extract_def -lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\: "((X).any) \ = ((\_. X \).any) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\: "((X).boss) \ = ((\_. X \).boss) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\: "((X).salary) \ = ((\_. X \).salary) \" by simp +lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\: "((X).any) \ = ((\_. X \).any) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\: "((X).boss) \ = ((\_. X \).boss) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\: "((X).salary) \ = ((\_. X \).salary) \" by (simp add: dot_accessor) -lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre: "((X).any@pre) \ = ((\_. X \).any@pre) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre: "((X).boss@pre) \ = ((\_. X \).boss@pre) \" by simp -lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre: "((X).salary@pre) \ = ((\_. X \).salary@pre) \" by simp +lemma cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre: "((X).any@pre) \ = ((\_. X \).any@pre) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre: "((X).boss@pre) \ = ((\_. X \).boss@pre) \" by (simp add: dot_accessor) +lemma cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre: "((X).salary@pre) \ = ((\_. X \).salary@pre) \" by (simp add: dot_accessor) lemmas cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_I [simp, intro!]= cp_dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\[THEN allI[THEN allI], @@ -856,39 +901,74 @@ lemmas cp_dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre[THEN allI[THEN allI], of "\ X _. X" "\ _ \. \", THEN cpI1] -subsubsection{* Execution with Invalid or Null as Argument *} +subsection{* Execution with Invalid or Null as Argument *} lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_nullstrict [simp]: "(null).any = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre_nullstrict [simp] : "(null).any@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_strict [simp] : "(invalid).any = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y\\\_at_pre_strict [simp] : "(invalid).any@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_nullstrict [simp]: "(null).boss = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre_nullstrict [simp] : "(null).boss@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_strict [simp] : "(invalid).boss = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_at_pre_strict [simp] : "(invalid).boss@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_nullstrict [simp]: "(null).salary = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre_nullstrict [simp] : "(null).salary@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_strict [simp] : "(invalid).salary = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\\\_at_pre_strict [simp] : "(invalid).salary@pre = invalid" -by(rule ext, simp add: null_fun_def null_option_def bot_option_def null_def invalid_def) +by(rule ext, simp add: dot_accessor null_fun_def null_option_def bot_option_def null_def invalid_def) +subsection{* Representation in States *} -subsection{* A Little Infra-structure on Example States *} +lemma dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def_mono:"\ \ \(X .boss) \ \ \ \(X)" + apply(case_tac "\ \ (X \ invalid)", insert StrongEq_L_subst2[where P = "(\x. (\ (x .boss)))" and \ = "\" and x = "X" and y = "invalid"], simp add: foundation16') + apply(case_tac "\ \ (X \ null)", insert StrongEq_L_subst2[where P = "(\x. (\ (x .boss)))" and \ = "\" and x = "X" and y = "null"], simp add: foundation16') +by(simp add: defined_split) + +lemma repr_boss: +assumes A : "\ \ \(x .boss)" +shows "is_represented_in_state in_post_state (x .boss) Person \" + apply(insert A[simplified foundation16] + A[THEN dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def_mono, simplified foundation16]) + unfolding is_represented_in_state_def + dot\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def eval_extract_def select\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n\\\\_def in_post_state_def + by(auto simp: deref_oid\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def bot_fun_def bot_option_def null_option_def null_fun_def invalid_def + OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_\_def image_def ran_def + split: type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n.split option.split \.split) + +lemma repr_bossX : +assumes A: "\ \ \(x .boss)" +shows "\ \ ((Person .allInstances()) ->includes\<^sub>S\<^sub>e\<^sub>t(x .boss))" +proof - + have B : "\S f. (x .boss) \ \ (Some ` f ` S) \ + (x .boss) \ \ (Some ` (f ` S - {None}))" + apply(auto simp: image_def ran_def, metis) + by(insert A[simplified foundation16], simp add: null_option_def bot_option_def) + show ?thesis + apply(insert repr_boss[OF A] OclAllInstances_at_post_defined[where H = Person and \ = \]) + unfolding is_represented_in_state_def OclValid_def + OclAllInstances_at_post_def OclAllInstances_generic_def OclIncludes_def + in_post_state_def + apply(simp add: A[THEN foundation20, simplified OclValid_def]) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, metis bot_option_def option.distinct(1)) + by(simp add: image_comp B true_def) +qed + +section{* A Little Infra-structure on Example States *} text{* The example we are defining in this section comes from the figure~\ref{fig:edm1_system-states}. @@ -900,6 +980,8 @@ The example we are defining in this section comes from the figure~\ref{fig:edm1_ \end{figure} *} +text_raw{* \isatagafp*} + definition OclInt1000 ("\\\\") where "OclInt1000 = (\ _ . \\1000\\)" definition OclInt1200 ("\\\\") where "OclInt1200 = (\ _ . \\1200\\)" definition OclInt1300 ("\\\\") where "OclInt1300 = (\ _ . \\1300\\)" @@ -939,8 +1021,7 @@ definition (*oid6*) (*oid7*) (oid8 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person9), - assocs\<^sub>2 = empty, - assocs\<^sub>3 = empty \" + assocs = empty \" definition "\\<^sub>1' \ \ heap = empty(oid0 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person1) @@ -952,10 +1033,9 @@ definition (oid6 \ in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y person7) (oid7 \ in\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y person8) (oid8 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person9), - assocs\<^sub>2 = empty, - assocs\<^sub>3 = empty \" + assocs = empty \" -definition "\\<^sub>0 \ \ heap = empty, assocs\<^sub>2 = empty, assocs\<^sub>3 = empty \" +definition "\\<^sub>0 \ \ heap = empty, assocs = empty \" lemma basic_\_wff: "WFF(\\<^sub>1,\\<^sub>1')" @@ -971,6 +1051,8 @@ by(auto simp: \\<^sub>1_def) lemma [simp,code_unfold]: "dom (heap \\<^sub>1') = {oid0,oid1,oid2,oid3,(*,oid4*)oid5,oid6,oid7,oid8}" by(auto simp: \\<^sub>1'_def) +text_raw{* \isatagafp *} + definition "X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 :: Person \ \ _ .\\ person1 \\" definition "X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 :: Person \ \ _ .\\ person2 \\" definition "X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 :: Person \ \ _ .\\ person3 \\" @@ -999,23 +1081,23 @@ lemmas [simp,code_unfold] = OclIsKindOf\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_OclAny OclIsKindOf\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_Person +text_raw{* \endisatagafp *} - -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary <> \\\\)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre <> \\\\)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .salary \ \\\\)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre <> \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre .boss@pre))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary <> \\\\)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .salary@pre <> \\\\)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .salary \ \\\\)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .salary@pre <> \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .boss@pre .boss@pre .boss@pre))" lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsMaintained())" by(simp add: OclValid_def OclIsMaintained_def @@ -1026,104 +1108,86 @@ by(simp add: OclValid_def OclIsMaintained_def lemma "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) .oclAsType(Person)) \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1)" by(rule up_down_cast_Person_OclAny_Person', simp add: X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1_def) -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) .oclIsTypeOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsTypeOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclIsKindOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) .oclIsTypeOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary@pre \ \\\\)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .salary@pre \ \\\\)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .boss@pre \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .boss))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .salary@pre))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .salary@pre \ \\\\)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .salary@pre \ \\\\)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss .boss@pre \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre <> (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .boss))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .boss@pre .salary@pre))" lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .oclIsMaintained())" -by(simp add: OclValid_def OclIsMaintained_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2_def person2_def +by(simp add: OclValid_def OclIsMaintained_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2_def person2_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary \ null)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary@pre))" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss \ null)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss .salary))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss@pre))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary \ null)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .salary@pre))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss \ null)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss .salary))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .boss@pre))" lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .oclIsNew())" -by(simp add: OclValid_def OclIsNew_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3_def person3_def +by(simp add: OclValid_def OclIsNew_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3_def person3_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid8_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" -value " (\\<^sub>1,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary@pre \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" +Assert " (\\<^sub>1,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .boss@pre .salary@pre \ \\\\)" lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .oclIsMaintained())" -by(simp add: OclValid_def OclIsMaintained_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4_def person4_def +by(simp add: OclValid_def OclIsMaintained_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4_def person4_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary@pre \ \\\\)" -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .boss))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .salary@pre \ \\\\)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .boss))" lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5 .oclIsDeleted())" -by(simp add: OclNot_def OclValid_def OclIsDeleted_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5_def person5_def +by(simp add: OclNot_def OclValid_def OclIsDeleted_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5_def person5_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid7_def oid8_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary) \ \\\\ )"*) -value "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary@pre))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4)" -value " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary@pre \ \\\\)" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary) \ \\\\ )"*) +Assert "\s\<^sub>p\<^sub>r\<^sub>e . (s\<^sub>p\<^sub>r\<^sub>e,\\<^sub>1') \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss .salary@pre))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4)" +Assert " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .salary@pre \ \\\\)" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss@pre .boss@pre \ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5)" lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .oclIsMaintained())" -by(simp add: OclValid_def OclIsMaintained_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6_def person6_def +by(simp add: OclValid_def OclIsMaintained_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6_def person6_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid_of_option_def oid_of_type\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_def) - -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss)))" *) -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person)) )" *) -(* (* access to an oclany object not yet supported *) value " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss .salary) \ \\\\ )" *) -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ \(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person))" -value "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss@pre))" +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .boss)))" *) +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person)) )" *) +(* (* access to an oclany object not yet supported *) Assert " (\\<^sub>1,\\<^sub>1') \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss .salary) \ \\\\ )" *) +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ \(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person))" +Assert "\ s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (\\<^sub>1,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .boss@pre))" lemma "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ ((X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person) .oclAsType(OclAny) .oclAsType(Person)) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclAsType(Person)))" by(rule up_down_cast_Person_OclAny_Person', simp add: X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7_def OclValid_def valid_def person7_def) lemma " (\\<^sub>1,\\<^sub>1') \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7 .oclIsNew())" -by(simp add: OclValid_def OclIsNew_def - \\<^sub>1_def \\<^sub>1'_def - X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7_def person7_def +by(simp add: OclValid_def OclIsNew_def \\<^sub>1_def \\<^sub>1'_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7_def person7_def oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid8_def oid_of_option_def oid_of_type\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_def) - -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7)" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclAsType(Person)))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(OclAny))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(Person))" -value "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(OclAny))" - +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 <> X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7)" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(\(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclAsType(Person)))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(OclAny))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsTypeOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ not(X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(Person))" +Assert "\s\<^sub>p\<^sub>r\<^sub>e s\<^sub>p\<^sub>o\<^sub>s\<^sub>t. (s\<^sub>p\<^sub>r\<^sub>e,s\<^sub>p\<^sub>o\<^sub>s\<^sub>t) \ (X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8 .oclIsKindOf(OclAny))" lemma \_modifiedonly: "(\\<^sub>1,\\<^sub>1') \ (Set{ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny) , X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .oclAsType(OclAny) @@ -1160,21 +1224,22 @@ lemma "(\\<^sub>1,\\<^sub>1') \ (((X\<^sub>P\<^sub>e\<^ proof - have including4 : "\a b c d \. - Set{\\. \\a\\, \\. \\b\\, \\. \\c\\, \\. \\d\\} \ = Abs_Set_0 \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\" + Set{\\. \\a\\, \\. \\b\\, \\. \\c\\, \\. \\d\\} \ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\" apply(subst abs_rep_simp'[symmetric], simp) - by(simp add: OclIncluding_rep_set mtSet_rep_set) + apply(simp add: OclIncluding_rep_set mtSet_rep_set) + by(rule arg_cong[of _ _ "\x. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(\\ x \\))"], auto) have excluding1: "\S a b c d e \. - (\_. Abs_Set_0 \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\)->excluding(\\. \\e\\) \ = - Abs_Set_0 \\ {\\a\\, \\b\\, \\c\\, \\d\\} - {\\e\\} \\" - apply(simp add: OclExcluding_def) + (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ {\\a\\, \\b\\, \\c\\, \\d\\} \\)->excluding\<^sub>S\<^sub>e\<^sub>t(\\. \\e\\) \ = + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ {\\a\\, \\b\\, \\c\\, \\d\\} - {\\e\\} \\" + apply(simp add: UML_Set.OclExcluding_def) apply(simp add: defined_def OclValid_def false_def true_def - bot_fun_def bot_Set_0_def null_fun_def null_Set_0_def) + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) apply(rule conjI) - apply(rule impI, subst (asm) Abs_Set_0_inject) apply( simp add: bot_option_def)+ + apply(rule impI, subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) apply( simp add: bot_option_def)+ apply(rule conjI) - apply(rule impI, subst (asm) Abs_Set_0_inject) apply( simp add: bot_option_def null_option_def)+ - apply(subst Abs_Set_0_inverse, simp add: bot_option_def, simp) + apply(rule impI, subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) apply( simp add: bot_option_def null_option_def)+ + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def, simp) done show ?thesis @@ -1194,7 +1259,7 @@ proof - person1_def person2_def person3_def person4_def person5_def person6_def person7_def person8_def person9_def OclAsType\<^sub>O\<^sub>c\<^sub>l\<^sub>A\<^sub>n\<^sub>y_Person) - apply(subst cp_OclIsModifiedOnly, subst cp_OclExcluding, + apply(subst cp_OclIsModifiedOnly, subst UML_Set.OclExcluding.cp0, subst (asm) cp_OclIsModifiedOnly, simp add: including4 excluding1) apply(simp only: X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3_def X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4_def @@ -1218,8 +1283,7 @@ lemma perm_\\<^sub>1' : "\\<^sub>1' = \ heap = empty (oid2 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person3) (oid1 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person2) (oid0 \ in\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n person1) - , assocs\<^sub>2 = assocs\<^sub>2 \\<^sub>1' - , assocs\<^sub>3 = assocs\<^sub>3 \\<^sub>1' \" + , assocs = assocs \\<^sub>1' \" proof - note P = fun_upd_twist show ?thesis @@ -1260,7 +1324,7 @@ by(simp_all add: OclAsType\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n_\ lemma "\\\<^sub>1. (\\<^sub>1,\\<^sub>1') \ (OclAny .allInstances() \ Set{ X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n1 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n2 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n3 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n4 .oclAsType(OclAny) - (*, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5*), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .oclAsType(OclAny), + (*, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n5*), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n6 .oclAsType(OclAny), X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n7, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n8, X\<^sub>P\<^sub>e\<^sub>r\<^sub>s\<^sub>o\<^sub>n9 .oclAsType(OclAny) })" apply(subst perm_\\<^sub>1') apply(simp only: oid0_def oid1_def oid2_def oid3_def oid4_def oid5_def oid6_def oid7_def oid8_def diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..6ab844b --- /dev/null +++ b/readme.txt @@ -0,0 +1,76 @@ +This directory contains the detailed AFP submission of the +"Featherweight OCL" semantics for OCL as well as our proposal +for Appendix A of the OCL standard. + +Beyond the standard mechanism + +(* < *) +<> +(* > *) + +The two main targets of this Isabelle project are: +- check everything and generate all documents allowing "sorry"'s, i.e., + using Isabelles "quick-and-dirty"-mode: + + isabelle build -c -d . -v -b OCL-dirty + +- check everything and generate all documents, ensuring that + no "sorry"'s are used: + + isabelle build -c -d . -v -b OCL + +In your LaTeX text, you can use the following two PlainTeX +environments for selecting in which version your text should +appear: + +\isatagafp + This text will only be visible in the AFP submission, i.e., + document.pdf and outline.pdf. +\endisatagafp + +\isatagannexa + This text will only be visible in the Annex A, i.e., annex-a.pdf. +\endisatagannexa + + +Note that these tags only work within regular Isabelle/Isar "text" +commands if they are complete, i.e.: + + text {* ... \isatagafp ... \endisatagafp ...*} + +Only opening or closing such a tag in Isabelle/Isar "text" commands +will not work. For this, you need to use the "text_raw" command: + + text_raw {* \isatagafp *} + ... + text_raw {* \endisatagafp *} + + +For working, these tags rely on the file comment.sty, which +is automatically added by Isabelle during the document generation. +However at the time of writing, the current comment.sty included by +Isabelle (version 3.6) mentions: + "The opening and closing commands should appear on a line + of their own. No starting spaces, nothing after it." +In particular, it is not advised to put these tags in a single line: +\isatagafp ... \endisatagafp % wrong +otherwise as side effects some parts occuring after these tags may be +skipped. The recommanded solution is to always write each tag in a +separate line: +\isatagafp + ... +\endisatagafp + + +Warning: +======= +Please check twice that you are using \isatagX and \endisatagX +properly, i.e., +- always pairwise matching +- not separating other envirments. +Not using these PlainTeX environments (which are, generally, +obsolete and discouraged but used by the Isabelle LaTeX setup +anyhow. We only use them to avoid introducing a parallel setup to +the one that we cannot avoid due to design decisions by the +Isabelle maintainer) carefully, will result in LaTeX errors that +are close to not debug-able. diff --git a/src/UML_Contracts.thy b/src/UML_Contracts.thy new file mode 100644 index 0000000..0a154c4 --- /dev/null +++ b/src/UML_Contracts.thy @@ -0,0 +1,413 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Contracts.thy --- + * This file is part of HOL-TestGen. + * + * Copyright (c) 2013-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory UML_Contracts +imports UML_State +begin + +text{* Modeling of an operation contract for an operation with 2 arguments, + (so depending on three parameters if one takes "self" into account). *} + +locale contract_scheme = + fixes f_\ + fixes f_lam + fixes f :: "('\,'\0::null)val \ + 'b \ + ('\,'res::null)val" + fixes PRE + fixes POST + assumes def_scheme': "f self x \ (\ \. SOME res. let res = \ _. res in + if (\ \ (\ self)) \ f_\ x \ + then (\ \ PRE self x) \ + (\ \ POST self x res) + else \ \ res \ invalid)" + assumes all_post': "\ \ \' \''. ((\,\') \ PRE self x) = ((\,\'') \ PRE self x)" + (* PRE is really a pre-condition semantically, + i.e. it does not depend on the post-state. ... *) + assumes cp\<^sub>P\<^sub>R\<^sub>E': "PRE (self) x \ = PRE (\ _. self \) (f_lam x \) \ " + (* this interface is preferable than : + assumes "cp self' \ cp a1' \ cp a2' \ cp (\X. PRE (self' X) (a1' X) (a2' X) )" + which is too polymorphic. *) + assumes cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T':"POST (self) x (res) \ = POST (\ _. self \) (f_lam x \) (\ _. res \) \" + assumes f_\_val: "\a1. f_\ (f_lam a1 \) \ = f_\ a1 \" +begin + lemma strict0 [simp]: "f invalid X = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme' StrongEq_def OclValid_def false_def true_def) + + lemma nullstrict0[simp]: "f null X = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme' StrongEq_def OclValid_def false_def true_def) + + lemma cp0 : "f self a1 \ = f (\ _. self \) (f_lam a1 \) \" + proof - + have A: "(\ \ \ (\_. self \)) = (\ \ \ self)" by(simp add: OclValid_def cp_defined[symmetric]) + have B: "f_\ (f_lam a1 \) \ = f_\ a1 \" by (rule f_\_val) + have D: "(\ \ PRE (\_. self \) (f_lam a1 \)) = ( \ \ PRE self a1 )" + by(simp add: OclValid_def cp\<^sub>P\<^sub>R\<^sub>E'[symmetric]) + show ?thesis + apply(auto simp: def_scheme' A B D) + apply(simp add: OclValid_def) + by(subst cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T', simp) + qed + + theorem unfold' : + assumes context_ok: "cp E" + and args_def_or_valid: "(\ \ \ self) \ f_\ a1 \" + and pre_satisfied: "\ \ PRE self a1" + and post_satisfiable: " \res. (\ \ POST self a1 (\ _. res))" + and sat_for_sols_post: "(\res. \ \ POST self a1 (\ _. res) \ \ \ E (\ _. res))" + shows "\ \ E(f self a1)" + proof - + have cp0: "\ X \. E X \ = E (\_. X \) \" by(insert context_ok[simplified cp_def], auto) + show ?thesis + apply(simp add: OclValid_def, subst cp0, fold OclValid_def) + apply(simp add:def_scheme' args_def_or_valid pre_satisfied) + apply(insert post_satisfiable, elim exE) + apply(rule Hilbert_Choice.someI2, assumption) + by(rule sat_for_sols_post, simp) + qed + + lemma unfold2' : + assumes context_ok: "cp E" + and args_def_or_valid: "(\ \ \ self) \ (f_\ a1 \)" + and pre_satisfied: "\ \ PRE self a1" + and postsplit_satisfied: "\ \ POST' self a1" (* split constraint holds on post-state *) + and post_decomposable : "\ res. (POST self a1 res) = + ((POST' self a1) and (res \ (BODY self a1)))" + shows "(\ \ E(f self a1)) = (\ \ E(BODY self a1))" + proof - + have cp0: "\ X \. E X \ = E (\_. X \) \" by(insert context_ok[simplified cp_def], auto) + show ?thesis + apply(simp add: OclValid_def, subst cp0, fold OclValid_def) + apply(simp add:def_scheme' args_def_or_valid pre_satisfied + post_decomposable postsplit_satisfied foundation10') + apply(subst some_equality) + apply(simp add: OclValid_def StrongEq_def true_def)+ + by(subst (2) cp0, rule refl) + qed +end + + +locale contract0 = + fixes f :: "('\,'\0::null)val \ + ('\,'res::null)val" + fixes PRE + fixes POST + assumes def_scheme: "f self \ (\ \. SOME res. let res = \ _. res in + if (\ \ (\ self)) + then (\ \ PRE self) \ + (\ \ POST self res) + else \ \ res \ invalid)" + assumes all_post: "\ \ \' \''. ((\,\') \ PRE self) = ((\,\'') \ PRE self)" + (* PRE is really a pre-condition semantically, + i.e. it does not depend on the post-state. ... *) + assumes cp\<^sub>P\<^sub>R\<^sub>E: "PRE (self) \ = PRE (\ _. self \) \ " + (* this interface is preferable than : + assumes "cp self' \ cp a1' \ cp a2' \ cp (\X. PRE (self' X) (a1' X) (a2' X) )" + which is too polymorphic. *) + assumes cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T:"POST (self) (res) \ = POST (\ _. self \) (\ _. res \) \" + +sublocale contract0 < contract_scheme "\_ _. True" "\x _. x" "\x _. f x" "\x _. PRE x" "\x _. POST x" + apply(unfold_locales) + apply(simp add: def_scheme, rule all_post, rule cp\<^sub>P\<^sub>R\<^sub>E, rule cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T) +by simp + +context contract0 +begin + lemma cp_pre: "cp self' \ cp (\X. PRE (self' X) )" + by(rule_tac f=PRE in cpI1, auto intro: cp\<^sub>P\<^sub>R\<^sub>E) + + lemma cp_post: "cp self' \ cp res' \ cp (\X. POST (self' X) (res' X))" + by(rule_tac f=POST in cpI2, auto intro: cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T) + + lemma cp [simp]: "cp self' \ cp res' \ cp (\X. f (self' X) )" + by(rule_tac f=f in cpI1, auto intro:cp0) + + lemmas unfold = unfold'[simplified] + + lemma unfold2 : + assumes "cp E" + and "(\ \ \ self)" + and "\ \ PRE self" + and "\ \ POST' self" (* split constraint holds on post-state *) + and "\ res. (POST self res) = + ((POST' self) and (res \ (BODY self)))" + shows "(\ \ E(f self)) = (\ \ E(BODY self))" + apply(rule unfold2'[simplified]) + by((rule assms)+) + +end + +locale contract1 = + fixes f :: "('\,'\0::null)val \ + ('\,'\1::null)val \ + ('\,'res::null)val" + fixes PRE + fixes POST + assumes def_scheme: "f self a1 \ + (\ \. SOME res. let res = \ _. res in + if (\ \ (\ self)) \ (\ \ \ a1) + then (\ \ PRE self a1) \ + (\ \ POST self a1 res) + else \ \ res \ invalid) " + assumes all_post: "\ \ \' \''. ((\,\') \ PRE self a1) = ((\,\'') \ PRE self a1)" + (* PRE is really a pre-condition semantically, + i.e. it does not depend on the post-state. ... *) + assumes cp\<^sub>P\<^sub>R\<^sub>E: "PRE (self) (a1) \ = PRE (\ _. self \) (\ _. a1 \) \ " + (* this interface is preferable than : + assumes "cp self' \ cp a1' \ cp a2' \ cp (\X. PRE (self' X) (a1' X) (a2' X) )" + which is too polymorphic. *) + assumes cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T:"POST (self) (a1) (res) \ = POST (\ _. self \)(\ _. a1 \) (\ _. res \) \" + +sublocale contract1 < contract_scheme "\a1 \. (\ \ \ a1)" "\a1 \. (\ _. a1 \)" + apply(unfold_locales) + apply(rule def_scheme, rule all_post, rule cp\<^sub>P\<^sub>R\<^sub>E, rule cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T) +by(simp add: OclValid_def cp_valid[symmetric]) + +context contract1 +begin + lemma strict1[simp]: "f self invalid = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme StrongEq_def OclValid_def false_def true_def) + + lemma defined_mono : "\ \\(f Y Z) \ (\ \\ Y) \ (\ \\ Z)" + by(auto simp: valid_def bot_fun_def invalid_def + def_scheme StrongEq_def OclValid_def false_def true_def + split: split_if_asm) + + lemma cp_pre: "cp self' \ cp a1' \ cp (\X. PRE (self' X) (a1' X) )" + by(rule_tac f=PRE in cpI2, auto intro: cp\<^sub>P\<^sub>R\<^sub>E) + + lemma cp_post: "cp self' \ cp a1' \ cp res' + \ cp (\X. POST (self' X) (a1' X) (res' X))" + by(rule_tac f=POST in cpI3, auto intro: cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T) + + lemma cp [simp]: "cp self' \ cp a1' \ cp res' \ cp (\X. f (self' X) (a1' X))" + by(rule_tac f=f in cpI2, auto intro:cp0) + + lemmas unfold = unfold' + lemmas unfold2 = unfold2' +end + +locale contract2 = + fixes f :: "('\,'\0::null)val \ + ('\,'\1::null)val \ ('\,'\2::null)val \ + ('\,'res::null)val" + fixes PRE + fixes POST + assumes def_scheme: "f self a1 a2 \ + (\ \. SOME res. let res = \ _. res in + if (\ \ (\ self)) \ (\ \ \ a1) \ (\ \ \ a2) + then (\ \ PRE self a1 a2) \ + (\ \ POST self a1 a2 res) + else \ \ res \ invalid) " + assumes all_post: "\ \ \' \''. ((\,\') \ PRE self a1 a2) = ((\,\'') \ PRE self a1 a2)" + (* PRE is really a pre-condition semantically, + i.e. it does not depend on the post-state. ... *) + assumes cp\<^sub>P\<^sub>R\<^sub>E: "PRE (self) (a1) (a2) \ = PRE (\ _. self \) (\ _. a1 \) (\ _. a2 \) \ " + (* this interface is preferable than : + assumes "cp self' \ cp a1' \ cp a2' \ cp (\X. PRE (self' X) (a1' X) (a2' X) )" + which is too polymorphic. *) + assumes cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T:"\res. POST (self) (a1) (a2) (res) \ = + POST (\ _. self \)(\ _. a1 \)(\ _. a2 \) (\ _. res \) \" + + +sublocale contract2 < contract_scheme "\(a1,a2) \. (\ \ \ a1) \ (\ \ \ a2)" + "\(a1,a2) \. (\ _.a1 \, \ _.a2 \)" + "(\x (a,b). f x a b)" + "(\x (a,b). PRE x a b)" + "(\x (a,b). POST x a b)" + apply(unfold_locales) + apply(auto simp add: def_scheme) + apply (metis all_post, metis all_post) + apply(subst cp\<^sub>P\<^sub>R\<^sub>E, simp) + apply(subst cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T, simp) +by(simp_all add: OclValid_def cp_valid[symmetric]) + +context contract2 +begin + lemma strict0'[simp] : "f invalid X Y = invalid" + by(insert strict0[of "(X,Y)"], simp) + + lemma nullstrict0'[simp]: "f null X Y = invalid" + by(insert nullstrict0[of "(X,Y)"], simp) + + lemma strict1[simp]: "f self invalid Y = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme StrongEq_def OclValid_def false_def true_def) + + lemma strict2[simp]: "f self X invalid = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme StrongEq_def OclValid_def false_def true_def) + + lemma defined_mono : "\ \\(f X Y Z) \ (\ \\ X) \ (\ \\ Y) \ (\ \\ Z)" + by(auto simp: valid_def bot_fun_def invalid_def + def_scheme StrongEq_def OclValid_def false_def true_def + split: split_if_asm) + + lemma cp_pre: "cp self' \ cp a1' \ cp a2' \ cp (\X. PRE (self' X) (a1' X) (a2' X) )" + by(rule_tac f=PRE in cpI3, auto intro: cp\<^sub>P\<^sub>R\<^sub>E) + + lemma cp_post: "cp self' \ cp a1' \ cp a2' \ cp res' + \ cp (\X. POST (self' X) (a1' X) (a2' X) (res' X))" + by(rule_tac f=POST in cpI4, auto intro: cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T) + + lemma cp0' : "f self a1 a2 \ = f (\ _. self \) (\ _. a1 \) (\ _. a2 \) \" + by (rule cp0[of _ "(a1,a2)", simplified]) + + lemma cp [simp]: "cp self' \ cp a1' \ cp a2' \ cp res' + \ cp (\X. f (self' X) (a1' X) (a2' X))" + by(rule_tac f=f in cpI3, auto intro:cp0') + + theorem unfold : + assumes "cp E" + and "(\ \ \ self) \ (\ \ \ a1) \ (\ \ \ a2)" + and "\ \ PRE self a1 a2" + and " \res. (\ \ POST self a1 a2 (\ _. res))" + and "(\res. \ \ POST self a1 a2 (\ _. res) \ \ \ E (\ _. res))" + shows "\ \ E(f self a1 a2)" + apply(rule unfold'[of _ _ _ "(a1, a2)", simplified]) + by((rule assms)+) + + lemma unfold2 : + assumes "cp E" + and "(\ \ \ self) \ (\ \ \ a1) \ (\ \ \ a2)" + and "\ \ PRE self a1 a2" + and "\ \ POST' self a1 a2" (* split constraint holds on post-state *) + and "\ res. (POST self a1 a2 res) = + ((POST' self a1 a2) and (res \ (BODY self a1 a2)))" + shows "(\ \ E(f self a1 a2)) = (\ \ E(BODY self a1 a2))" + apply(rule unfold2'[of _ _ _ "(a1, a2)", simplified]) + by((rule assms)+) +end + +locale contract3 = + fixes f :: "('\,'\0::null)val \ + ('\,'\1::null)val \ + ('\,'\2::null)val \ + ('\,'\3::null)val \ + ('\,'res::null)val" + fixes PRE + fixes POST + assumes def_scheme: "f self a1 a2 a3 \ + (\ \. SOME res. let res = \ _. res in + if (\ \ (\ self)) \ (\ \ \ a1) \ (\ \ \ a2) \ (\ \ \ a3) + then (\ \ PRE self a1 a2 a3) \ + (\ \ POST self a1 a2 a3 res) + else \ \ res \ invalid) " + assumes all_post: "\ \ \' \''. ((\,\') \ PRE self a1 a2 a3) = ((\,\'') \ PRE self a1 a2 a3)" + (* PRE is really a pre-condition semantically, + i.e. it does not depend on the post-state. ... *) + assumes cp\<^sub>P\<^sub>R\<^sub>E: "PRE (self) (a1) (a2) (a3) \ = PRE (\ _. self \) (\ _. a1 \) (\ _. a2 \) (\ _. a3 \) \ " + (* this interface is preferable than : + assumes "cp self' \ cp a1' \ cp a2' \ cp a3' \ cp (\X. PRE (self' X) (a1' X) (a2' X) (a3' X) )" + which is too polymorphic. *) + assumes cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T:"\res. POST (self) (a1) (a2) (a3) (res) \ = + POST (\ _. self \)(\ _. a1 \)(\ _. a2 \)(\ _. a3 \) (\ _. res \) \" + + +sublocale contract3 < contract_scheme "\(a1,a2,a3) \. (\ \ \ a1) \ (\ \ \ a2)\ (\ \ \ a3)" + "\(a1,a2,a3) \. (\ _.a1 \, \ _.a2 \, \ _.a3 \)" + "(\x (a,b,c). f x a b c)" + "(\x (a,b,c). PRE x a b c)" + "(\x (a,b,c). POST x a b c)" + apply(unfold_locales) + apply(auto simp add: def_scheme) + apply (metis all_post, metis all_post) + apply(subst cp\<^sub>P\<^sub>R\<^sub>E, simp) + apply(subst cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T, simp) +by(simp_all add: OclValid_def cp_valid[symmetric]) + +context contract3 +begin + lemma strict0'[simp] : "f invalid X Y Z = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme StrongEq_def OclValid_def false_def true_def) + + lemma nullstrict0'[simp]: "f null X Y Z = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme StrongEq_def OclValid_def false_def true_def) + + lemma strict1[simp]: "f self invalid Y Z = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme StrongEq_def OclValid_def false_def true_def) + + lemma strict2[simp]: "f self X invalid Z = invalid" + by(rule ext, rename_tac "\", simp add: def_scheme StrongEq_def OclValid_def false_def true_def) + + lemma defined_mono : "\ \\(f W X Y Z) \ (\ \\ W) \ (\ \\ X) \ (\ \\ Y) \ (\ \\ Z)" + by(auto simp: valid_def bot_fun_def invalid_def + def_scheme StrongEq_def OclValid_def false_def true_def + split: split_if_asm) + + lemma cp_pre: "cp self' \ cp a1' \ cp a2'\ cp a3' + \ cp (\X. PRE (self' X) (a1' X) (a2' X) (a3' X) )" + by(rule_tac f=PRE in cpI4, auto intro: cp\<^sub>P\<^sub>R\<^sub>E) + + lemma cp_post: "cp self' \ cp a1' \ cp a2' \ cp a3' \ cp res' + \ cp (\X. POST (self' X) (a1' X) (a2' X) (a3' X) (res' X))" + by(rule_tac f=POST in cpI5, auto intro: cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T) + + lemma cp0' : "f self a1 a2 a3 \ = f (\ _. self \) (\ _. a1 \) (\ _. a2 \) (\ _. a3 \) \" + by (rule cp0[of _ "(a1,a2,a3)", simplified]) + + lemma cp [simp]: "cp self' \ cp a1' \ cp a2' \ cp a3' \ cp res' + \ cp (\X. f (self' X) (a1' X) (a2' X) (a3' X))" + by(rule_tac f=f in cpI4, auto intro:cp0') + + theorem unfold : + assumes "cp E" + and "(\ \ \ self) \ (\ \ \ a1) \ (\ \ \ a2) \ (\ \ \ a3)" + and "\ \ PRE self a1 a2 a3" + and " \res. (\ \ POST self a1 a2 a3 (\ _. res))" + and "(\res. \ \ POST self a1 a2 a3 (\ _. res) \ \ \ E (\ _. res))" + shows "\ \ E(f self a1 a2 a3)" + apply(rule unfold'[of _ _ _ "(a1, a2, a3)", simplified]) + by((rule assms)+) + + lemma unfold2 : + assumes "cp E" + and "(\ \ \ self) \ (\ \ \ a1) \ (\ \ \ a2) \ (\ \ \ a3)" + and "\ \ PRE self a1 a2 a3" + and "\ \ POST' self a1 a2 a3" (* split constraint holds on post-state *) + and "\ res. (POST self a1 a2 a3 res) = + ((POST' self a1 a2 a3) and (res \ (BODY self a1 a2 a3)))" + shows "(\ \ E(f self a1 a2 a3)) = (\ \ E(BODY self a1 a2 a3))" + apply(rule unfold2'[of _ _ _ "(a1, a2, a3)", simplified]) + by((rule assms)+) +end + + +end diff --git a/src/UML_Library.thy b/src/UML_Library.thy new file mode 100644 index 0000000..1f7cd2a --- /dev/null +++ b/src/UML_Library.thy @@ -0,0 +1,260 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Library.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + + +theory UML_Library +imports (* Basic Type Operations *) + "basic_types/UML_Boolean" + "basic_types/UML_Void" + "basic_types/UML_Integer" + "basic_types/UML_Real" + "basic_types/UML_String" + + (* Collection Type Operations *) + "collection_types/UML_Pair" + "collection_types/UML_Bag" + "collection_types/UML_Set" + "collection_types/UML_Sequence" +begin + +section{* Miscellaneous Stuff*} + +subsection{* Definition: asBoolean *} + +definition OclAsBoolean\<^sub>I\<^sub>n\<^sub>t :: "('\) Integer \ ('\) Boolean" ("(_)->oclAsType\<^sub>I\<^sub>n\<^sub>t'(Boolean')") +where "OclAsBoolean\<^sub>I\<^sub>n\<^sub>t X = (\\. if (\ X) \ = true \ + then \\\\X \\\ \ 0\\ + else invalid \)" + +interpretation OclAsBoolean\<^sub>I\<^sub>n\<^sub>t : profile_mono\<^sub>d OclAsBoolean\<^sub>I\<^sub>n\<^sub>t "\x. \\\\x\\ \ 0\\" + by unfold_locales (auto simp: OclAsBoolean\<^sub>I\<^sub>n\<^sub>t_def bot_option_def) + +definition OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l :: "('\) Real \ ('\) Boolean" ("(_)->oclAsType\<^sub>R\<^sub>e\<^sub>a\<^sub>l'(Boolean')") +where "OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l X = (\\. if (\ X) \ = true \ + then \\\\X \\\ \ 0\\ + else invalid \)" + +interpretation OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_mono\<^sub>d OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l "\x. \\\\x\\ \ 0\\" + by unfold_locales (auto simp: OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def) + +subsection{* Definition: asInteger *} + +definition OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l :: "('\) Real \ ('\) Integer" ("(_)->oclAsType\<^sub>R\<^sub>e\<^sub>a\<^sub>l'(Integer')") +where "OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l X = (\\. if (\ X) \ = true \ + then \\floor \\X \\\\\ + else invalid \)" + +interpretation OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_mono\<^sub>d OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l "\x. \\floor \\x\\\\" + by unfold_locales (auto simp: OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def) + +subsection{* Definition: asReal *} + +definition OclAsReal\<^sub>I\<^sub>n\<^sub>t :: "('\) Integer \ ('\) Real" ("(_)->oclAsType\<^sub>I\<^sub>n\<^sub>t'(Real')") +where "OclAsReal\<^sub>I\<^sub>n\<^sub>t X = (\\. if (\ X) \ = true \ + then \\real_of_int \\X \\\\\ + else invalid \)" + +interpretation OclAsReal\<^sub>I\<^sub>n\<^sub>t : profile_mono\<^sub>d OclAsReal\<^sub>I\<^sub>n\<^sub>t "\x. \\real_of_int \\x\\\\" + by unfold_locales (auto simp: OclAsReal\<^sub>I\<^sub>n\<^sub>t_def bot_option_def) + +lemma Integer_subtype_of_Real: + assumes "\ \ \ X" + shows "\ \ X ->oclAsType\<^sub>I\<^sub>n\<^sub>t(Real) ->oclAsType\<^sub>R\<^sub>e\<^sub>a\<^sub>l(Integer) \ X" + apply(insert assms, simp add: OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def OclAsReal\<^sub>I\<^sub>n\<^sub>t_def OclValid_def StrongEq_def) + apply(subst (2 4) cp_defined, simp add: true_def) + by (metis assms bot_option_def drop.elims foundation16 null_option_def) + +subsection{* Definition: asPair *} + +definition OclAsPair\<^sub>S\<^sub>e\<^sub>q :: "[('\,'\::null)Sequence]\('\,'\::null,'\::null) Pair" ("(_)->asPair\<^sub>S\<^sub>e\<^sub>q'(')") +where "OclAsPair\<^sub>S\<^sub>e\<^sub>q S = (if S->size\<^sub>S\<^sub>e\<^sub>q() \ \ + then Pair{S->at\<^sub>S\<^sub>e\<^sub>q(\),S->at\<^sub>S\<^sub>e\<^sub>q(\)} + else invalid + endif)" + +definition OclAsPair\<^sub>S\<^sub>e\<^sub>t :: "[('\,'\::null)Set]\('\,'\::null,'\::null) Pair" ("(_)->asPair\<^sub>S\<^sub>e\<^sub>t'(')") +where "OclAsPair\<^sub>S\<^sub>e\<^sub>t S = (if S->size\<^sub>S\<^sub>e\<^sub>t() \ \ + then let v = S->any\<^sub>S\<^sub>e\<^sub>t() in + Pair{v,S->excluding\<^sub>S\<^sub>e\<^sub>t(v)->any\<^sub>S\<^sub>e\<^sub>t()} + else invalid + endif)" + +definition OclAsPair\<^sub>B\<^sub>a\<^sub>g :: "[('\,'\::null)Bag]\('\,'\::null,'\::null) Pair" ("(_)->asPair\<^sub>B\<^sub>a\<^sub>g'(')") +where "OclAsPair\<^sub>B\<^sub>a\<^sub>g S = (if S->size\<^sub>B\<^sub>a\<^sub>g() \ \ + then let v = S->any\<^sub>B\<^sub>a\<^sub>g() in + Pair{v,S->excluding\<^sub>B\<^sub>a\<^sub>g(v)->any\<^sub>B\<^sub>a\<^sub>g()} + else invalid + endif)" + +subsection{* Definition: asSet *} + +definition OclAsSet\<^sub>S\<^sub>e\<^sub>q :: "[('\,'\::null)Sequence]\('\,'\)Set" ("(_)->asSet\<^sub>S\<^sub>e\<^sub>q'(')") +where "OclAsSet\<^sub>S\<^sub>e\<^sub>q S = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = Set{} | x ->including\<^sub>S\<^sub>e\<^sub>t(b)))" + +definition OclAsSet\<^sub>P\<^sub>a\<^sub>i\<^sub>r :: "[('\,'\::null,'\::null) Pair]\('\,'\)Set" ("(_)->asSet\<^sub>P\<^sub>a\<^sub>i\<^sub>r'(')") +where "OclAsSet\<^sub>P\<^sub>a\<^sub>i\<^sub>r S = Set{S .First(), S .Second()}" + +definition OclAsSet\<^sub>B\<^sub>a\<^sub>g :: "('\,'\::null) Bag\('\,'\)Set" ("(_)->asSet\<^sub>B\<^sub>a\<^sub>g'(')") +where "OclAsSet\<^sub>B\<^sub>a\<^sub>g S = (\ \. if (\ S) \ = true \ + then Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\ Rep_Set_base S \ \\ + else if (\ S) \ = true \ then null \ + else invalid \)" + +subsection{* Definition: asSequence *} + +definition OclAsSeq\<^sub>S\<^sub>e\<^sub>t :: "[('\,'\::null)Set]\('\,'\)Sequence" ("(_)->asSequence\<^sub>S\<^sub>e\<^sub>t'(')") +where "OclAsSeq\<^sub>S\<^sub>e\<^sub>t S = (S->iterate\<^sub>S\<^sub>e\<^sub>t(b; x = Sequence{} | x ->including\<^sub>S\<^sub>e\<^sub>q(b)))" + +definition OclAsSeq\<^sub>B\<^sub>a\<^sub>g :: "[('\,'\::null)Bag]\('\,'\)Sequence" ("(_)->asSequence\<^sub>B\<^sub>a\<^sub>g'(')") +where "OclAsSeq\<^sub>B\<^sub>a\<^sub>g S = (S->iterate\<^sub>B\<^sub>a\<^sub>g(b; x = Sequence{} | x ->including\<^sub>S\<^sub>e\<^sub>q(b)))" + +definition OclAsSeq\<^sub>P\<^sub>a\<^sub>i\<^sub>r :: "[('\,'\::null,'\::null) Pair]\('\,'\)Sequence" ("(_)->asSequence\<^sub>P\<^sub>a\<^sub>i\<^sub>r'(')") +where "OclAsSeq\<^sub>P\<^sub>a\<^sub>i\<^sub>r S = Sequence{S .First(), S .Second()}" + +subsection{* Definition: asBag *} + +definition OclAsBag\<^sub>S\<^sub>e\<^sub>q :: "[('\,'\::null)Sequence]\('\,'\)Bag" ("(_)->asBag\<^sub>S\<^sub>e\<^sub>q'(')") +where "OclAsBag\<^sub>S\<^sub>e\<^sub>q S = (\\. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\s. if list_ex (op = s) \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ then 1 else 0\\)" + +definition OclAsBag\<^sub>S\<^sub>e\<^sub>t :: "[('\,'\::null)Set]\('\,'\)Bag" ("(_)->asBag\<^sub>S\<^sub>e\<^sub>t'(')") +where "OclAsBag\<^sub>S\<^sub>e\<^sub>t S = (\\. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\s. if s \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ then 1 else 0\\)" + +lemma assumes "\ \ \ (S ->size\<^sub>S\<^sub>e\<^sub>t())" (* S is finite *) + shows "OclAsBag\<^sub>S\<^sub>e\<^sub>t S = (S->iterate\<^sub>S\<^sub>e\<^sub>t(b; x = Bag{} | x ->including\<^sub>B\<^sub>a\<^sub>g(b)))" +oops + +definition OclAsBag\<^sub>P\<^sub>a\<^sub>i\<^sub>r :: "[('\,'\::null,'\::null) Pair]\('\,'\)Bag" ("(_)->asBag\<^sub>P\<^sub>a\<^sub>i\<^sub>r'(')") +where "OclAsBag\<^sub>P\<^sub>a\<^sub>i\<^sub>r S = Bag{S .First(), S .Second()}" + +text_raw{* \isatagafp *} +subsection{* Collection Types *} +lemmas cp_intro'' [intro!,simp,code_unfold] = + cp_intro' + (* cp_intro''\<^sub>P\<^sub>a\<^sub>i\<^sub>r *) + cp_intro''\<^sub>S\<^sub>e\<^sub>t + cp_intro''\<^sub>S\<^sub>e\<^sub>q +text_raw{* \endisatagafp *} + +subsection{* Test Statements *} + +lemma syntax_test: "Set{\,\} = (Set{}->including\<^sub>S\<^sub>e\<^sub>t(\)->including\<^sub>S\<^sub>e\<^sub>t(\))" +by (rule refl) + +text{* Here is an example of a nested collection. *} +lemma semantic_test2: +assumes H:"(Set{\} \ null) = (false::('\)Boolean)" +shows "(\::('\)st) \ (Set{Set{\},null}->includes\<^sub>S\<^sub>e\<^sub>t(null))" +by(simp add: OclIncludes_execute\<^sub>S\<^sub>e\<^sub>t H) + + + +lemma short_cut'[simp,code_unfold]: "(\ \ \) = false" + apply(rule ext) + apply(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def OclInt8_def OclInt6_def + true_def false_def invalid_def bot_option_def) +done + +lemma short_cut''[simp,code_unfold]: "(\ \ \) = false" + apply(rule ext) + apply(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def OclInt2_def OclInt1_def + true_def false_def invalid_def bot_option_def) +done +lemma short_cut'''[simp,code_unfold]: "(\ \ \) = false" + apply(rule ext) + apply(simp add: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def OclInt2_def OclInt1_def + true_def false_def invalid_def bot_option_def) +done + +Assert "\ \ (\ <\<^sub>i\<^sub>n\<^sub>t \) and (\ <\<^sub>i\<^sub>n\<^sub>t \) " + + +text{* Elementary computations on Sets.*} + +declare OclSelect_body_def [simp] + +Assert "\ (\ \ \(invalid::('\,'\::null) Set))" +Assert "\ \ \(null::('\,'\::null) Set)" +Assert "\ (\ \ \(null::('\,'\::null) Set))" +Assert "\ \ \(Set{})" +Assert "\ \ \(Set{Set{\},null})" +Assert "\ \ \(Set{Set{\},null})" +Assert "\ \ (Set{\,\}->includes\<^sub>S\<^sub>e\<^sub>t(\))" +Assert "\ (\ \ (Set{\}->includes\<^sub>S\<^sub>e\<^sub>t(\)))" +Assert "\ (\ \ (Set{\,\}->includes\<^sub>S\<^sub>e\<^sub>t(null)))" +Assert "\ \ (Set{\,null}->includes\<^sub>S\<^sub>e\<^sub>t(null))" +Assert "\ \ (Set{null,\}->includes\<^sub>S\<^sub>e\<^sub>t(null))" + +Assert "\ \ ((Set{})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \ <\<^sub>i\<^sub>n\<^sub>t z))" + +Assert "\ \ ((Set{\,\})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \ <\<^sub>i\<^sub>n\<^sub>t z))" +Assert "\ (\ \ ((Set{\,\})->exists\<^sub>S\<^sub>e\<^sub>t(z | z <\<^sub>i\<^sub>n\<^sub>t \ )))" +Assert "\ (\ \ (\(Set{\,null})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \ <\<^sub>i\<^sub>n\<^sub>t z)))" +Assert "\ (\ \ ((Set{\,null})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \ <\<^sub>i\<^sub>n\<^sub>t z)))" +Assert "\ \ ((Set{\,null})->exists\<^sub>S\<^sub>e\<^sub>t(z | \ <\<^sub>i\<^sub>n\<^sub>t z))" + + +Assert "\ (\ \ (Set{null::'a Boolean} \ Set{}))" +Assert "\ (\ \ (Set{null::'a Integer} \ Set{}))" + +Assert "\ (\ \ (Set{true} \ Set{false}))" +Assert "\ (\ \ (Set{true,true} \ Set{false}))" +Assert "\ (\ \ (Set{\} \ Set{\}))" +Assert "\ \ (Set{\,null,\} \ Set{null,\})" +Assert "\ \ (Set{\,null,\} <> Set{null,\})" +Assert "\ \ (Set{Set{\,null}} \ Set{Set{null,\}})" +Assert "\ \ (Set{Set{\,null}} <> Set{Set{null,\},null})" +Assert "\ \ (Set{null}->select\<^sub>S\<^sub>e\<^sub>t(x | not x) \ Set{null})" +Assert "\ \ (Set{null}->reject\<^sub>S\<^sub>e\<^sub>t(x | not x) \ Set{null})" + +lemma "const (Set{Set{\,null}, invalid})" by(simp add: const_ss) + + +text{* Elementary computations on Sequences.*} + +Assert "\ (\ \ \(invalid::('\,'\::null) Sequence))" +Assert "\ \ \(null::('\,'\::null) Sequence)" +Assert "\ (\ \ \(null::('\,'\::null) Sequence))" +Assert "\ \ \(Sequence{})" + +lemma "const (Sequence{Sequence{\,null}, invalid})" by(simp add: const_ss) + +end diff --git a/OCL_core.thy b/src/UML_Logic.thy similarity index 77% rename from OCL_core.thy rename to src/UML_Logic.thy index a108385..1f4cfe3 100644 --- a/OCL_core.thy +++ b/src/UML_Logic.thy @@ -1,13 +1,13 @@ (***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 * for the OMG Standard. * http://www.brucker.ch/projects/hol-testgen/ * - * OCL_core.thy --- Core definitions. + * UML_Logic.thy --- Core definitions. * This file is part of HOL-TestGen. * - * Copyright (c) 2012-2013 Université Paris-Sud, France - * 2013 IRT SystemX, France + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France * * All rights reserved. * @@ -40,220 +40,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************) -chapter{* Formalization I: Core Definitions *} +chapter{* Formalization II: OCL Terms and Library Operations *} -theory - OCL_core -imports - Main +theory UML_Logic +imports UML_Types begin -section{* Preliminaries *} -subsection{* Notations for the Option Type *} - -text{* - First of all, we will use a more compact notation for the library - option type which occur all over in our definitions and which will make - the presentation more like a textbook: -*} -notation Some ("\(_)\") -notation None ("\") - -text{* - The following function (corresponding to @{term the} in the Isabelle/HOL library) - is defined as the inverse of the injection @{term Some}. -*} -fun drop :: "'\ option \ '\" ("\(_)\") -where drop_lift[simp]: "\\v\\ = v" - - -subsection{* Minimal Notions of State and State Transitions *} -text{* Next we will introduce the foundational concept of an object id (oid), -which is just some infinite set. *} - -text{* In order to assure executability of as much as possible formulas, we fixed the -type of object id's to just natural numbers.*} -type_synonym oid = nat - -text{* We refrained from the alternative: -\begin{isar}[mathescape] -$\text{\textbf{type-synonym}}$ $\mathit{oid = ind}$ -\end{isar} -which is slightly more abstract but non-executable. -*} - -text{* - States are just a partial map from oid's to elements of an object - universe @{text "'\"}, and state transitions pairs of states - \ldots -*} -record ('\)state = - heap :: "oid \ '\ " - assocs\<^sub>2 :: "oid \ (oid \ oid) list" (* binary associations *) - assocs\<^sub>3 :: "oid \ (oid \ oid \ oid) list" (* ternary associations *) - - -type_synonym ('\)st = "'\ state \ '\ state" - -subsection{* Prerequisite: An Abstract Interface for OCL Types *} - -text {* - To have the possibility to nest collection types, - such that we can give semantics to expressions like @{text "Set{Set{\},null}"}, - it is necessary to introduce a uniform interface for types having - the @{text "invalid"} (= bottom) element. The reason is that we impose - a data-invariant on raw-collection \inlineisar|types_code| which assures - that the @{text "invalid"} element is not allowed inside the collection; - all raw-collections of this form were identified with the @{text "invalid"} element - itself. The construction requires that the new collection type is - not comparable with the raw-types (consisting of nested option type constructions), - such that the data-invariant must be expressed in terms of the interface. - In a second step, our base-types will be shown to be instances of this interface. - *} - -text{* - This uniform interface consists in a type class requiring the existence - of a bot and a null element. The construction proceeds by - abstracting the null (defined by @{text "\ \ \"} on - @{text "'a option option"}) to a @{text null} element, which may - have an arbitrary semantic structure, and an undefinedness element @{text "\ "} - to an abstract undefinedness element @{text "bot"} (also written - @{text "\ "} whenever no confusion arises). As a consequence, it is necessary - to redefine the notions of invalid, defined, valuation etc. - on top of this interface. *} - -text{* - This interface consists in two abstract type classes @{text bot} - and @{text null} for the class of all types comprising a bot and a - distinct null element. *} - -class bot = - fixes bot :: "'a" - assumes nonEmpty : "\ x. x \ bot" - - -class null = bot + - fixes null :: "'a" - assumes null_is_valid : "null \ bot" - - -subsection{* Accommodation of Basic Types to the Abstract Interface *} - -text{* - In the following it is shown that the ``option-option'' type is - in fact in the @{text null} class and that function spaces over these - classes again ``live'' in these classes. This motivates the default construction - of the semantic domain for the basic types (\inlineocl{Boolean}, - \inlineocl{Integer}, \inlineocl{Real}, \ldots). -*} - -instantiation option :: (type)bot -begin - definition bot_option_def: "(bot::'a option) \ (None::'a option)" - instance proof show "\x\'a option. x \ bot" - by(rule_tac x="Some x" in exI, simp add:bot_option_def) - qed -end - - -instantiation option :: (bot)null -begin - definition null_option_def: "(null::'a\bot option) \ \ bot \" - instance proof show "(null::'a\bot option) \ bot" - by( simp add:null_option_def bot_option_def) - qed -end - - -instantiation "fun" :: (type,bot) bot -begin - definition bot_fun_def: "bot \ (\ x. bot)" - - instance proof show "\(x::'a \ 'b). x \ bot" - apply(rule_tac x="\ _. (SOME y. y \ bot)" in exI, auto) - apply(drule_tac x=x in fun_cong,auto simp:bot_fun_def) - apply(erule contrapos_pp, simp) - apply(rule some_eq_ex[THEN iffD2]) - apply(simp add: nonEmpty) - done - qed -end - - -instantiation "fun" :: (type,null) null -begin - definition null_fun_def: "(null::'a \ 'b::null) \ (\ x. null)" - - instance proof - show "(null::'a \ 'b::null) \ bot" - apply(auto simp: null_fun_def bot_fun_def) - apply(drule_tac x=x in fun_cong) - apply(erule contrapos_pp, simp add: null_is_valid) - done - qed -end - -text{* A trivial consequence of this adaption of the interface is that -abstract and concrete versions of null are the same on base types -(as could be expected). *} - -subsection{* The Semantic Space of OCL Types: Valuations *} - -text{* Valuations are now functions from a state pair (built upon -data universe @{typ "'\"}) to an arbitrary null-type (\ie, containing -at least a destinguished @{text "null"} and @{text "invalid"} element). *} - -type_synonym ('\,'\) val = "'\ st \ '\::null" - -text{* The definitions for the constants and operations based on valuations -will be geared towards a format that Isabelle can check to be a ``conservative'' -(\ie, logically safe) axiomatic definition. By introducing an explicit -interpretation function (which happens to be defined just as the identity -since we are using a shallow embedding of OCL into HOL), all these definitions -can be rewritten into the conventional semantic textbook format as follows: *} - -definition Sem :: "'a \ 'a" ("I\_\") -where "I\x\ \ x" - -text{* As a consequence of semantic domain definition, any OCL type will -have the two semantic constants @{text "invalid"} (for exceptional, aborted -computation) and @{text "null"}: - *} - -definition invalid :: "('\,'\::bot) val" -where "invalid \ \ \. bot" - -text{* This conservative Isabelle definition of the polymorphic constant -@{const invalid} is equivalent with the textbook definition: *} - -lemma textbook_invalid: "I\invalid\\ = bot" -by(simp add: invalid_def Sem_def) - - -text {* Note that the definition : -{\small -\begin{isar}[mathescape] -definition null :: "('$\mathfrak{A}$,'\::null) val" -where "null \ \ \. null" -\end{isar} -} is not necessary since we defined the entire function space over null types -again as null-types; the crucial definition is @{thm "null_fun_def"}. -Thus, the polymorphic constant @{const null} is simply the result of -a general type class construction. Nevertheless, we can derive the -semantic textbook definition for the OCL null constant based on the -abstract null: -*} - -lemma textbook_null_fun: "I\null::('\,'\::null) val\ \ = (null::'\::null)" -by(simp add: null_fun_def Sem_def) - - -section{* Definition of the Boolean Type *} - -text{* The semantic domain of the (basic) boolean type is now defined as the Standard: -the space of valuation to @{typ "bool option option"}:*} - -type_synonym ('\)Boolean = "('\,bool option option) val" +section{* The Operations of the Boolean Type and the OCL Logic*} subsection{* Basic Constants *} @@ -270,7 +63,7 @@ where "true \ \ \. \\True\\)Boolean" where "false \ \ \. \\False\\" -lemma bool_split: "X \ = invalid \ \ X \ = null \ \ +lemma bool_split_0: "X \ = invalid \ \ X \ = null \ \ X \ = true \ \ X \ = false \" apply(simp add: invalid_def null_def true_def false_def) apply(case_tac "X \",simp_all add: null_fun_def null_option_def bot_option_def) @@ -306,7 +99,7 @@ text {* @{thm [source] textbook_false} & @{thm [display=false] textbook_false} \\ \bottomrule \end{tabu} - \caption{Basic semantic constant definitions of the logic (except @{term null})} + \caption{Basic semantic constant definitions of the logic} \label{tab:sem_basic_constants} \end{table} *} @@ -314,7 +107,7 @@ text {* subsection{* Validity and Definedness *} text{* However, this has also the consequence that core concepts like definedness, -validness and even cp have to be redefined on this type class:*} +validity and even cp have to be redefined on this type class:*} definition valid :: "('\,'a::null)val \ ('\)Boolean" ("\ _" [100]100) where "\ X \ \ \ . if X \ = bot \ then false \ else true \" @@ -322,24 +115,19 @@ where "\ X \ \ \ . if X \ = bot \ then lemma valid1[simp]: "\ invalid = false" by(rule ext,simp add: valid_def bot_fun_def bot_option_def invalid_def true_def false_def) - lemma valid2[simp]: "\ null = true" by(rule ext,simp add: valid_def bot_fun_def bot_option_def null_is_valid null_fun_def invalid_def true_def false_def) - lemma valid3[simp]: "\ true = true" by(rule ext,simp add: valid_def bot_fun_def bot_option_def null_is_valid null_fun_def invalid_def true_def false_def) - lemma valid4[simp]: "\ false = true" by(rule ext,simp add: valid_def bot_fun_def bot_option_def null_is_valid null_fun_def invalid_def true_def false_def) - - +text_raw{* \isatagafp *} lemma cp_valid: "(\ X) \ = (\ (\ _. X \)) \" by(simp add: valid_def) - - +text_raw{* \endisatagafp *} definition defined :: "('\,'a::null)val \ ('\)Boolean" ("\ _" [100]100) where "\ X \ \ \ . if X \ = bot \ \ X \ = null \ then false \ else true \" @@ -349,44 +137,35 @@ properties as the old ones : *} lemma defined1[simp]: "\ invalid = false" by(rule ext,simp add: defined_def bot_fun_def bot_option_def null_def invalid_def true_def false_def) - lemma defined2[simp]: "\ null = false" by(rule ext,simp add: defined_def bot_fun_def bot_option_def null_def null_option_def null_fun_def invalid_def true_def false_def) - - lemma defined3[simp]: "\ true = true" by(rule ext,simp add: defined_def bot_fun_def bot_option_def null_is_valid null_option_def null_fun_def invalid_def true_def false_def) - lemma defined4[simp]: "\ false = true" by(rule ext,simp add: defined_def bot_fun_def bot_option_def null_is_valid null_option_def null_fun_def invalid_def true_def false_def) - - lemma defined5[simp]: "\ \ X = true" by(rule ext, auto simp: defined_def true_def false_def bot_fun_def bot_option_def null_option_def null_fun_def) - lemma defined6[simp]: "\ \ X = true" by(rule ext, auto simp: valid_def defined_def true_def false_def bot_fun_def bot_option_def null_option_def null_fun_def) - lemma valid5[simp]: "\ \ X = true" by(rule ext, auto simp: valid_def true_def false_def bot_fun_def bot_option_def null_option_def null_fun_def) - lemma valid6[simp]: "\ \ X = true" by(rule ext, auto simp: valid_def defined_def true_def false_def bot_fun_def bot_option_def null_option_def null_fun_def) - - +text_raw{* \isatagafp *} lemma cp_defined:"(\ X)\ = (\ (\ _. X \)) \" by(simp add: defined_def) +text_raw{* \endisatagafp *} text{* The definitions above for the constants @{const defined} and @{const valid} can be rewritten into the conventional semantic "textbook" format as follows: *} @@ -402,9 +181,9 @@ lemma textbook_valid: "I\\(X)\ \ = (if I\X by(simp add: Sem_def valid_def) -text {* +text {* \autoref{tab:sem_definedness} and \autoref{tab:alglaws_definedness} -summarize the results of this section. +summarize the results of this section. \begin{table}[htbp] \centering \begin{tabu}{lX[,c,]} @@ -437,7 +216,7 @@ summarize the results of this section. \end{table} *} -section{* The Equalities of OCL *} +subsection{* The Equalities of OCL \label{sec:equality}*} text{* The OCL contains a particular version of equality, written in Standard documents \inlineocl+_ = _+ and \inlineocl+_ <> _+ for its @@ -460,7 +239,7 @@ text{* these two. *} text{* Strong equality has two motivations: a pragmatic one and a fundamental one. \begin{enumerate} - \item The pragmatic reason is fairly simple: users of object-oriented languages want + \item The pragmatic reason is fairly simple: users of object-oriented languages want something like a ``shallow object value equality''. You will want to say \inlineisar+ a.boss \ b.boss@pre + @@ -511,7 +290,7 @@ text{* they mean the same thing can therefore not be taken for granted. *} -subsection{* Definition *} +subsubsection{* Definition *} text{* The strict equality on basic types (actually on all types) must be exceptionally defined on @{term "null"}---otherwise the entire @@ -541,66 +320,7 @@ lemma [simp,code_unfold]: "(false \ true) = false" by(rule ext, auto simp: StrongEq_def) -text{* - In contrast, referential equality behaves differently for all - types---on value types, it is basically strong equality for defined - values, but on object types it will compare references---we - introduce it as an \emph{overloaded} concept and will handle it for - each type instance individually. -*} -consts StrictRefEq :: "[('\,'a)val,('\,'a)val] \ ('\)Boolean" (infixl "\" 30) - - -text{* - Here is a first instance of a definition of weak equality---for - the special case of the type @{typ "('\)Boolean"}, it is just - the strict extension of the logical - equality: -*} -defs (overloaded) StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[code_unfold] : - "(x::('\)Boolean) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ - then (x \ y)\ - else invalid \" - -text{* which implies elementary properties like: *} -lemma [simp,code_unfold] : "(true \ false) = false" -by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n) -lemma [simp,code_unfold] : "(false \ true) = false" -by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n) - -lemma [simp,code_unfold] : "(invalid \ false) = invalid" -by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n false_def true_def) -lemma [simp,code_unfold] : "(invalid \ true) = invalid" -by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n false_def true_def) - -lemma [simp,code_unfold] : "(false \ invalid) = invalid" -by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n false_def true_def) -lemma [simp,code_unfold] : "(true \ invalid) = invalid" -by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n false_def true_def) - -lemma [simp,code_unfold] : "((invalid::('\)Boolean) \ invalid) = invalid" -by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n false_def true_def) -text{* Thus, the weak equality is \emph{not} reflexive. *} - -lemma null_non_false [simp,code_unfold]:"(null \ false) = false" - apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) -by (metis OCL_core.drop.simps cp_valid false_def is_none_code(2) is_none_def valid4 - bot_option_def null_fun_def null_option_def) - -lemma null_non_true [simp,code_unfold]:"(null \ true) = false" - apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) -by(simp add: true_def bot_option_def null_fun_def null_option_def) - -lemma false_non_null [simp,code_unfold]:"(false \ null) = false" - apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) -by (metis OCL_core.drop.simps cp_valid false_def is_none_code(2) is_none_def valid4 - bot_option_def null_fun_def null_option_def ) - -lemma true_non_null [simp,code_unfold]:"(true \ null) = false" - apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) -by(simp add: true_def bot_option_def null_fun_def null_option_def) - -subsection{* Fundamental Predicates on Strong Equality *} +subsubsection{* Fundamental Predicates on Strong Equality *} text{* Equality reasoning in OCL is not humpty dumpty. While strong equality is clearly an equivalence: *} @@ -655,7 +375,7 @@ lemma valid7[simp]: "\ (X \ Y) = true" lemma cp_StrongEq: "(X \ Y) \ = ((\ _. X \) \ (\ _. Y \)) \" by(simp add: StrongEq_def) -section{* Logical Connectives and their Universal Properties *} +subsection{* Logical Connectives and their Universal Properties *} text{* It is a design goal to give OCL a semantics that is as closely as possible to a ``logical system'' in a known sense; a specification @@ -686,15 +406,8 @@ where "not X \ \ \ . case X \ of | \ \ \ \ \ \ \ | \\ x \\ \ \\ \ x \\" -text{* with {term "not"} we can express the notation:*} - -syntax - "notequal" :: "('\)Boolean \ ('\)Boolean \ ('\)Boolean" (infix "<>" 40) -translations - "a <> b" == "CONST OclNot( a \ b)" - lemma cp_OclNot: "(not X)\ = (not (\ _. X \)) \" by(simp add: OclNot_def) @@ -914,7 +627,7 @@ lemma OclOr7[simp]: "(null or null) = null" by(rule ext, simp add: OclOr_def OclNot_def OclAnd_def null_def invalid_def true_def false_def bot_option_def null_fun_def null_option_def) lemma OclOr8[simp]: "(null or invalid) = invalid" -by(rule ext, simp add: OclOr_def OclNot_def OclAnd_def null_def invalid_def true_def false_def +by(rule ext, simp add: OclOr_def OclNot_def OclAnd_def null_def invalid_def true_def false_def bot_option_def null_fun_def null_option_def) lemma OclOr_idem[simp]: "(X or X) = X" @@ -957,24 +670,31 @@ lemma OclOr_null2[simp]: "\\. X \ \ true \ \)st, ('\)Boolean] \ bool" ("(1(_)/ \ (_))" 50) where "\ \ P \ ((P \) = true \)" -value "\ \ true <> false" -value "\ \ false <> true" +syntax OclNonValid :: "[('\)st, ('\)Boolean] \ bool" ("(1(_)/ |\ (_))" 50) -subsection{* Global vs. Local Judgements*} +translations "\ |\ P" == "\(\ \ P)" + +subsubsection{* Global vs. Local Judgements*} lemma transform1: "P = true \ \ \ P" by(simp add: OclValid_def) @@ -992,8 +712,6 @@ apply(erule_tac x=b in allE) apply(auto simp: false_def true_def defined_def bot_Boolean_def null_Boolean_def split: option.split_asm HOL.split_if_asm) done -(* Something stronger is possible here (consider P null, Q invalid), - but this thingi should do for our purpose *) text{* However, certain properties (like transitivity) can not be \emph{transformed} from the global level to the local one, @@ -1007,7 +725,7 @@ apply(rule H[THEN fun_cong]) apply(rule ext) oops -subsection{* Local Validity and Meta-logic*} +subsubsection{* Local Validity and Meta-logic*} text{* \label{sec:localVal} *} lemma foundation1[simp]: "\ \ true" @@ -1022,17 +740,27 @@ by(auto simp: OclValid_def true_def false_def invalid_def bot_option_def) lemma foundation4[simp]: "\(\ \ null)" by(auto simp: OclValid_def true_def false_def null_def null_fun_def null_option_def bot_option_def) -lemma bool_split_local[simp]: +lemma bool_split[simp]: "(\ \ (x \ invalid)) \ (\ \ (x \ null)) \ (\ \ (x \ true)) \ (\ \ (x \ false))" -apply(insert bool_split[of x \], auto) +apply(insert bool_split_0[of x \], auto) apply(simp_all add: OclValid_def StrongEq_def true_def null_def invalid_def) done -lemma def_split_local: +lemma defined_split: "(\ \ \ x) = ((\(\ \ (x \ invalid))) \ (\ (\ \ (x \ null))))" by(simp add:defined_def true_def false_def invalid_def null_def StrongEq_def OclValid_def bot_fun_def null_fun_def) +lemma valid_bool_split: "(\ \ \ A) = ((\ \ A \ null) \ (\ \ A) \ (\ \ not A)) " +by(auto simp:valid_def true_def false_def invalid_def null_def OclNot_def + StrongEq_def OclValid_def bot_fun_def bot_option_def null_option_def null_fun_def) + +lemma defined_bool_split: "(\ \ \ A) = ((\ \ A) \ (\ \ not A))" +by(auto simp:defined_def true_def false_def invalid_def null_def OclNot_def + StrongEq_def OclValid_def bot_fun_def bot_option_def null_option_def null_fun_def) + + + lemma foundation5: "\ \ (P and Q) \ (\ \ P) \ (\ \ Q)" by(simp add: OclAnd_def OclValid_def true_def false_def defined_def @@ -1062,33 +790,45 @@ text{* see below) by @{text invalid} or @{text null}. Strictness-reduction rules will usually reduce these substituted terms drastically. *} + + lemma foundation8: "(\ \ \ x) \ (\ \ (x \ invalid)) \ (\ \ (x \ null))" proof - have 1 : "(\ \ \ x) \ (\(\ \ \ x))" by auto have 2 : "(\(\ \ \ x)) = ((\ \ (x \ invalid)) \ (\ \ (x \ null)))" - by(simp only: def_split_local, simp) + by(simp only: defined_split, simp) show ?thesis by(insert 1, simp add:2) qed + lemma foundation9: "\ \ \ x \ (\ \ not x) = (\ (\ \ x))" -apply(simp add: def_split_local ) +apply(simp add: defined_split ) by(auto simp: OclNot_def null_fun_def null_option_def bot_option_def OclValid_def invalid_def true_def null_def StrongEq_def) +lemma foundation9': +"\ \ not x \ \ (\ \ x)" +by(auto simp: foundation6 foundation9) + +lemma foundation9'': +" \ \ not x \ \ \ \ x" +by(metis OclNot3 OclNot_not OclValid_def cp_OclNot cp_defined defined4) lemma foundation10: "\ \ \ x \ \ \ \ y \ (\ \ (x and y)) = ( (\ \ x) \ (\ \ y))" -apply(simp add: def_split_local) +apply(simp add: defined_split) by(auto simp: OclAnd_def OclValid_def invalid_def true_def null_def StrongEq_def null_fun_def null_option_def bot_option_def split:bool.split_asm) +lemma foundation10': "(\ \ (A and B)) = ((\ \ A) \ (\ \ B))" (* stronger than foundation !*) +by(auto dest:foundation5 simp:foundation6 foundation10) lemma foundation11: "\ \ \ x \ \ \ \ y \ (\ \ (x or y)) = ( (\ \ x) \ (\ \ y))" -apply(simp add: def_split_local) +apply(simp add: defined_split) by(auto simp: OclNot_def OclOr_def OclAnd_def OclValid_def invalid_def true_def null_def StrongEq_def null_fun_def null_option_def bot_option_def split:bool.split_asm bool.split) @@ -1096,15 +836,15 @@ by(auto simp: OclNot_def OclOr_def OclAnd_def OclValid_def invalid_def lemma foundation12: -"\ \ \ x \ \ \ \ y \ (\ \ (x implies y)) = ( (\ \ x) \ (\ \ y))" -apply(simp add: def_split_local) +"\ \ \ x \ (\ \ (x implies y)) = ( (\ \ x) \ (\ \ y))" +apply(simp add: defined_split) by(auto simp: OclNot_def OclOr_def OclAnd_def OclImplies_def bot_option_def OclValid_def invalid_def true_def null_def StrongEq_def null_fun_def null_option_def - split:bool.split_asm bool.split) + split:bool.split_asm bool.split option.split_asm) lemma foundation13:"(\ \ A \ true) = (\ \ A)" by(auto simp: OclNot_def OclValid_def invalid_def true_def null_def StrongEq_def - split:bool.split_asm bool.split) + split:bool.split_asm bool.split) lemma foundation14:"(\ \ A \ false) = (\ \ not A)" by(auto simp: OclNot_def OclValid_def invalid_def false_def true_def null_def StrongEq_def @@ -1121,27 +861,30 @@ lemma foundation16: "\ \ (\ X) = (X \ \ bot \ by(auto simp: OclValid_def defined_def false_def true_def bot_fun_def null_fun_def split:split_if_asm) +lemma foundation16'': "\(\ \ (\ X)) = ((\ \ (X \ invalid)) \ (\ \ (X \ null)))" +apply(simp add: foundation16) +by(auto simp:defined_def false_def true_def bot_fun_def null_fun_def OclValid_def StrongEq_def invalid_def) + (* correcter rule; the previous is deprecated *) lemma foundation16': "(\ \ (\ X)) = (X \ \ invalid \ \ X \ \ null \)" apply(simp add:invalid_def null_def null_fun_def) by(auto simp: OclValid_def defined_def false_def true_def bot_fun_def null_fun_def split:split_if_asm) -lemmas foundation17 = foundation16[THEN iffD1] -(* correcter rule; the previous is deprecated *) -lemmas foundation17' = foundation16'[THEN iffD1] -lemma foundation18: "\ \ (\ X) = (X \ \ invalid \)" + +lemma foundation18: "(\ \ (\ X)) = (X \ \ invalid \)" by(auto simp: OclValid_def valid_def false_def true_def bot_fun_def invalid_def split:split_if_asm) (*legacy*) -lemma foundation18': "\ \ (\ X) = (X \ \ bot)" +lemma foundation18': "(\ \ (\ X)) = (X \ \ bot)" by(auto simp: OclValid_def valid_def false_def true_def bot_fun_def split:split_if_asm) +lemma foundation18'': "(\ \ (\ X) )= (\(\ \ (X \ invalid)))" +by(auto simp:foundation15) -lemmas foundation19 = foundation18[THEN iffD1] lemma foundation20 : "\ \ (\ X) \ \ \ \ X" by(simp add: foundation18 foundation16 invalid_def) @@ -1156,11 +899,29 @@ by(auto simp: StrongEq_def OclValid_def true_def) lemma foundation23: "(\ \ P) = (\ \ (\ _ . P \))" by(auto simp: OclValid_def true_def) -lemmas cp_validity=foundation23 + lemma foundation24:"(\ \ not(X \ Y)) = (X \ \ Y \)" by(simp add: StrongEq_def OclValid_def OclNot_def true_def) +lemma foundation25: "\ \ P \ \ \ (P or Q)" +by(simp add: OclOr_def OclNot_def OclAnd_def OclValid_def true_def) + +lemma foundation25': "\ \ Q \ \ \ (P or Q)" +by(subst OclOr_commute, simp add: foundation25) + + +lemma foundation26: +assumes defP: "\ \ \ P" +assumes defQ: "\ \ \ Q" +assumes H: "\ \ (P or Q)" +assumes P: "\ \ P \ R" +assumes Q: "\ \ Q \ R" +shows "R" +by(insert H, subst (asm) foundation11[OF defP defQ], erule disjE, simp_all add: P Q) + +lemma foundation27: "\ \ A \ (\ \ A implies B) = (\ \ B)" +by (simp add: foundation12 foundation6) lemma defined_not_I : "\ \ \ (x) \ \ \ \ (not x)" by(auto simp: OclNot_def null_def invalid_def defined_def valid_def OclValid_def @@ -1185,9 +946,13 @@ lemma valid_and_I : "\ \ \ (x) \ \ \ \ (x) \ \ \ \ (y) \ \ \ \ (x or y)" +by(simp add: OclOr_def defined_and_I defined_not_I) +lemma valid_or_I : "\ \ \ (x) \ \ \ \ (y) \ \ \ \ (x or y)" +by(simp add: OclOr_def valid_and_I valid_not_I) -subsection{* Local Judgements and Strong Equality *} +subsubsection{* Local Judgements and Strong Equality *} lemma StrongEq_L_refl: "\ \ (x \ x)" by(simp add: OclValid_def StrongEq_def) @@ -1223,18 +988,31 @@ by(auto simp: OclValid_def StrongEq_def true_def cp_def) lemma StrongEq_L_subst2_rev: "\ \ y \ x \ cp P \ \ \ P x \ \ \ P y" apply(erule StrongEq_L_subst2) -apply(erule StrongEq_L_sym) +apply(erule StrongEq_L_sym) by assumption lemma StrongEq_L_subst3: assumes cp: "cp P" -and eq: "\ \ x \ y" +and eq: "\ \ (x \ y)" shows "(\ \ P x) = (\ \ P y)" apply(rule iffI) -apply(rule OCL_core.StrongEq_L_subst2[OF cp,OF eq],simp) -apply(rule OCL_core.StrongEq_L_subst2[OF cp,OF eq[THEN StrongEq_L_sym]],simp) +apply(rule StrongEq_L_subst2[OF cp,OF eq],simp) +apply(rule StrongEq_L_subst2[OF cp,OF eq[THEN StrongEq_L_sym]],simp) done +lemma StrongEq_L_subst3_rev: +assumes eq: "\ \ (x \ y)" +and cp: "cp P" +shows "(\ \ P x) = (\ \ P y)" +by(insert cp, erule StrongEq_L_subst3, rule eq) + +lemma StrongEq_L_subst4_rev: +assumes eq: "\ \ (x \ y)" +and cp: "cp P" +shows "(\(\ \ P x)) = (\(\ \ P y))" +thm arg_cong[of _ _ "Not"] +apply(rule arg_cong[of _ _ "Not"]) +by(insert cp, erule StrongEq_L_subst3, rule eq) lemma cpI1: "(\ X \. f X \ = f(\_. X \) \) \ cp P \ cp(\X. f (P X))" @@ -1248,7 +1026,7 @@ lemma cpI2: apply(auto simp: true_def cp_def) apply(rule exI, (rule allI)+) by(erule_tac x="P X" in allE, auto) - + lemma cpI3: "(\ X Y Z \. f X Y Z \ = f(\_. X \)(\_. Y \)(\_. Z \) \) \ cp P \ cp Q \ cp R \ cp(\X. f (P X) (Q X) (R X))" @@ -1263,12 +1041,22 @@ apply(auto simp: cp_def) apply(rule exI, (rule allI)+) by(erule_tac x="P X" in allE, auto) +lemma cpI5: +"(\ V W X Y Z \. f V W X Y Z \ = f(\_. V \) (\_. W \)(\_. X \)(\_. Y \)(\_. Z \) \) \ + cp N \ cp P \ cp Q \ cp R \ cp S \ cp(\X. f (N X) (P X) (Q X) (R X) (S X))" +apply(auto simp: cp_def) +apply(rule exI, (rule allI)+) +by(erule_tac x="N X" in allE, auto) + + lemma cp_const : "cp(\_. c)" by (simp add: cp_def, fast) lemma cp_id : "cp(\X. X)" by (simp add: cp_def, fast) +text_raw{* \isatagafp *} + lemmas cp_intro[intro!,simp,code_unfold] = cp_const cp_id @@ -1279,37 +1067,11 @@ lemmas cp_intro[intro!,simp,code_unfold] = cp_OclOr[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "op or"]] cp_OclImplies[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "op implies"]] cp_StrongEq[THEN allI[THEN allI[THEN allI[THEN cpI2]], - of "StrongEq"]] - -subsection{* Laws to Establish Definedness ($\delta$-closure) *} - -text{* For the logical connectives, we have --- beyond -@{thm foundation6} --- the following facts: *} -lemma OclNot_defargs: -"\ \ (not P) \ \ \ \ P" -by(auto simp: OclNot_def OclValid_def true_def invalid_def defined_def false_def - bot_fun_def bot_option_def null_fun_def null_option_def - split: bool.split_asm HOL.split_if_asm option.split option.split_asm) - -lemma OclNot_contrapos_nn: - assumes "\ \ \ A" - assumes "\ \ not B" - assumes "\ \ A \ \ \ B" - shows "\ \ not A" -proof - - have change_not : "\a b. (not a \ = b \) = (a \ = not b \)" - by (metis OclNot_not cp_OclNot) - show ?thesis - apply(insert assms, simp add: OclValid_def, subst change_not, subst (asm) change_not) - apply(simp add: OclNot_def true_def) - by (metis OclValid_def bool_split defined_def false_def foundation2 true_def - bot_fun_def invalid_def) -qed - -text{* So far, we have only one strict Boolean predicate (-family): the strict equality. *} - -section{* Miscellaneous *} + of "StrongEq"]] +text_raw{* \endisatagafp *} + + subsection{* OCL's if then else endif *} definition OclIf :: "[('\)Boolean , ('\,'\::null) val, ('\,'\) val] \ ('\,'\) val" @@ -1324,10 +1086,12 @@ where "(if C then B\<^sub>1 else B\<^sub>2 endif) = (\ \. if (\1 else B\<^sub>2 endif) \ = (if (\ _. C \) then (\ _. B\<^sub>1 \) else (\ _. B\<^sub>2 \) endif) \)" by(simp only: OclIf_def, subst cp_defined, rule refl) +text_raw{* \isatagafp *} lemmas cp_intro'[intro!,simp,code_unfold] = cp_intro cp_OclIf[THEN allI[THEN allI[THEN allI[THEN allI[THEN cpI3]]], of "OclIf"]] +text_raw{* \endisatagafp *} lemma OclIf_invalid [simp]: "(if invalid then B\<^sub>1 else B\<^sub>2 endif) = invalid" by(rule ext, auto simp: OclIf_def) @@ -1342,6 +1106,9 @@ lemma OclIf_true' [simp]: "\ \ P \ (if P then B\ apply(subst cp_OclIf,auto simp: OclValid_def) by(simp add:cp_OclIf[symmetric]) +lemma OclIf_true'' [simp]: "\ \ P \ \ \ (if P then B\<^sub>1 else B\<^sub>2 endif) \ B\<^sub>1" +by(subst OclValid_def, simp add: StrongEq_def true_def) + lemma OclIf_false [simp]: "(if false then B\<^sub>1 else B\<^sub>2 endif) = B\<^sub>2" by(rule ext, auto simp: OclIf_def) @@ -1367,7 +1134,54 @@ lemma OclNot_if[simp]: by simp -subsection{* A Side-calculus for (Boolean) Constant Terms *} + +subsection{* Fundamental Predicates on Basic Types: Strict (Referential) Equality *} + +text{* + In contrast to logical equality, the OCL standard defines an equality operation + which we call ``strict referential equality''. It behaves differently for all + types---on value types, it is basically a strict version of strong equality, + for defined values it behaves identical. But on object types it will compare + their references within the store. We introduce strict referential equality + as an \emph{overloaded} concept and will handle it for + each type instance individually. +*} +consts StrictRefEq :: "[('\,'a)val,('\,'a)val] \ ('\)Boolean" (infixl "\" 30) + +text{* with {term "not"} we can express the notation:*} + +syntax + "notequal" :: "('\)Boolean \ ('\)Boolean \ ('\)Boolean" (infix "<>" 40) +translations + "a <> b" == "CONST OclNot(a \ b)" + +text{* We will define instances of this equality in a case-by-case basis.*} + +subsection{* Laws to Establish Definedness (\texorpdfstring{$\delta$}{d}-closure) *} + +text{* For the logical connectives, we have --- beyond +@{thm foundation6} --- the following facts: *} +lemma OclNot_defargs: +"\ \ (not P) \ \ \ \ P" +by(auto simp: OclNot_def OclValid_def true_def invalid_def defined_def false_def + bot_fun_def bot_option_def null_fun_def null_option_def + split: bool.split_asm HOL.split_if_asm option.split option.split_asm) + + +lemma OclNot_contrapos_nn: + assumes A: "\ \ \ A" + assumes B: "\ \ not B" + assumes C: "\ \ A \ \ \ B" + shows "\ \ not A" +proof - + have D : "\ \ \ B" by(rule B[THEN OclNot_defargs]) + show ?thesis + apply(insert B,simp add: A D foundation9) + by(erule contrapos_nn, auto intro: C) +qed + + +subsection{* A Side-calculus for Constant Terms *} definition "const X \ \ \ \'. X \ = X \'" @@ -1391,7 +1205,7 @@ proof - apply(insert cp_P, unfold cp_def) apply(elim exE, erule_tac x=Y in allE', erule_tac x=\' in allE) apply(erule_tac x="(\_. Y \')" in allE, erule_tac x=\' in allE) - by simp + by simp have C: "X \' = Y \'" apply(rule trans, subst const_charn[OF const_X],rule eq) by(rule const_charn[OF const_Y]) @@ -1403,17 +1217,17 @@ qed lemma const_imply2 : - assumes "\\1 \2. P \1 = P \2 \ Q \1 = Q \2" + assumes "\\ \'. P \ = P \' \ Q \ = Q \'" shows "const P \ const Q" by(simp add: const_def, insert assms, blast) lemma const_imply3 : - assumes "\\1 \2. P \1 = P \2 \ Q \1 = Q \2 \ R \1 = R \2" + assumes "\\ \'. P \ = P \' \ Q \ = Q \' \ R \ = R \'" shows "const P \ const Q \ const R" by(simp add: const_def, insert assms, blast) lemma const_imply4 : - assumes "\\1 \2. P \1 = P \2 \ Q \1 = Q \2 \ R \1 = R \2 \ S \1 = S \2" + assumes "\\ \'. P \ = P \' \ Q \ = Q \' \ R \ = R \' \ S \ = S \'" shows "const P \ const Q \ const R \ const S" by(simp add: const_def, insert assms, blast) @@ -1421,35 +1235,86 @@ lemma const_lam : "const (\_. e)" by(simp add: const_def) -lemma const_true : "const true" +lemma const_true[simp] : "const true" by(simp add: const_def true_def) -lemma const_false : "const false" +lemma const_false[simp] : "const false" by(simp add: const_def false_def) -lemma const_null : "const null" +lemma const_null[simp] : "const null" by(simp add: const_def null_fun_def) -lemma const_invalid : "const invalid" +lemma const_invalid [simp]: "const invalid" by(simp add: const_def invalid_def) -lemma const_bot : "const bot" +lemma const_bot[simp] : "const bot" by(simp add: const_def bot_fun_def) lemma const_defined : assumes "const X" - shows "const (\ X)" + shows "const (\ X)" by(rule const_imply2[OF _ assms], simp add: defined_def false_def true_def bot_fun_def bot_option_def null_fun_def null_option_def) lemma const_valid : assumes "const X" - shows "const (\ X)" + shows "const (\ X)" by(rule const_imply2[OF _ assms], simp add: valid_def false_def true_def bot_fun_def null_fun_def assms) + +lemma const_OclAnd : + assumes "const X" + assumes "const X'" + shows "const (X and X')" +by(rule const_imply3[OF _ assms], subst (1 2) cp_OclAnd, simp add: assms OclAnd_def) + + +lemma const_OclNot : + assumes "const X" + shows "const (not X)" +by(rule const_imply2[OF _ assms],subst cp_OclNot,simp add: assms OclNot_def) + +lemma const_OclOr : + assumes "const X" + assumes "const X'" + shows "const (X or X')" +by(simp add: assms OclOr_def const_OclNot const_OclAnd) + +lemma const_OclImplies : + assumes "const X" + assumes "const X'" + shows "const (X implies X')" +by(simp add: assms OclImplies_def const_OclNot const_OclOr) + +lemma const_StrongEq: + assumes "const X" + assumes "const X'" + shows "const(X \ X')" + apply(simp only: StrongEq_def const_def, intro allI) + apply(subst assms(1)[THEN const_charn]) + apply(subst assms(2)[THEN const_charn]) + by simp + + +lemma const_OclIf : + assumes "const B" + and "const C1" + and "const C2" + shows "const (if B then C1 else C2 endif)" + apply(rule const_imply4[OF _ assms], + subst (1 2) cp_OclIf, simp only: OclIf_def cp_defined[symmetric]) + apply(simp add: const_defined[OF assms(1), simplified const_def, THEN spec, THEN spec] + const_true[simplified const_def, THEN spec, THEN spec] + assms[simplified const_def, THEN spec, THEN spec] + const_invalid[simplified const_def, THEN spec, THEN spec]) +by (metis (no_types) bot_fun_def OclValid_def const_def const_true defined_def + foundation16[THEN iffD1] null_fun_def) + + + lemma const_OclValid1: assumes "const x" shows "(\ \ \ x) = (\' \ \ x)" @@ -1464,56 +1329,33 @@ lemma const_OclValid2: apply(subst const_valid[OF assms, THEN const_charn]) by(simp add: true_def) - -lemma const_OclAnd : - assumes "const X" - assumes "const X'" - shows "const (X and X')" -by(rule const_imply3[OF _ assms], subst (1 2) cp_OclAnd, simp add: assms OclAnd_def) +lemma const_HOL_if : "const C \ const D \ const F \ const (\\. if C \ then D \ else F \)" + by(auto simp: const_def) +lemma const_HOL_and: "const C \ const D \ const (\\. C \ \ D \)" + by(auto simp: const_def) +lemma const_HOL_eq : "const C \ const D \ const (\\. C \ = D \)" + apply(auto simp: const_def) + apply(erule_tac x=\ in allE) + apply(erule_tac x=\ in allE) + apply(erule_tac x=\' in allE) + apply(erule_tac x=\' in allE) + apply simp + apply(erule_tac x=\ in allE) + apply(erule_tac x=\ in allE) + apply(erule_tac x=\' in allE) + apply(erule_tac x=\' in allE) + by simp -lemma const_OclNot : - assumes "const X" - shows "const (not X)" -by(rule const_imply2[OF _ assms],subst cp_OclNot,simp add: assms OclNot_def) - -lemma const_OclOr : - assumes "const X" - assumes "const X'" - shows "const (X or X')" -by(simp add: assms OclOr_def const_OclNot const_OclAnd) - -lemma const_OclImplies : - assumes "const X" - assumes "const X'" - shows "const (X implies X')" -by(simp add: assms OclImplies_def const_OclNot const_OclOr) - -lemma const_StrongEq: - assumes "const X" - assumes "const X'" - shows "const(X \ X')" - apply(simp only: StrongEq_def const_def, intro allI) - apply(subst assms(1)[THEN const_charn]) - apply(subst assms(2)[THEN const_charn]) - by simp - -lemma const_OclIf : - assumes "const B" - and "const C1" - and "const C2" - shows "const (if B then C1 else C2 endif)" - apply(rule const_imply4[OF _ assms], - subst (1 2) cp_OclIf, simp only: OclIf_def cp_defined[symmetric]) - apply(simp add: const_defined[OF assms(1), simplified const_def, THEN spec, THEN spec] - const_true[simplified const_def, THEN spec, THEN spec] - assms[simplified const_def, THEN spec, THEN spec] - const_invalid[simplified const_def, THEN spec, THEN spec]) -by (metis (no_types) OCL_core.bot_fun_def OclValid_def const_def const_true defined_def foundation17 - null_fun_def) - lemmas const_ss = const_bot const_null const_invalid const_false const_true const_lam - const_defined const_valid const_StrongEq const_OclNot const_OclAnd + const_defined const_valid const_StrongEq const_OclNot const_OclAnd const_OclOr const_OclImplies const_OclIf + const_HOL_if const_HOL_and const_HOL_eq + + +text{* Miscellaneous: Overloading the syntax of ``bottom'' *} + +notation bot ("\") + end diff --git a/OCL_tools.thy b/src/UML_Main.thy similarity index 90% rename from OCL_tools.thy rename to src/UML_Main.thy index 9b6fba1..7df3296 100644 --- a/OCL_tools.thy +++ b/src/UML_Main.thy @@ -1,12 +1,13 @@ (***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 * for the OMG Standard. * http://www.brucker.ch/projects/hol-testgen/ * - * OCL_tools.thy --- + * UML_Main.thy --- * This file is part of HOL-TestGen. * - * Copyright (c) 2012 Université Paris-Sud, France + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France * * All rights reserved. * @@ -39,8 +40,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************) -theory OCL_tools -imports OCL_core +theory UML_Main +imports UML_Contracts UML_Tools begin - end diff --git a/src/UML_PropertyProfiles.thy b/src/UML_PropertyProfiles.thy new file mode 100644 index 0000000..c6e0aef --- /dev/null +++ b/src/UML_PropertyProfiles.thy @@ -0,0 +1,376 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_PropertyProfiles.thy --- + * This file is part of HOL-TestGen. + * + * Copyright (c) 2013-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + + + + +theory UML_PropertyProfiles +imports UML_Logic +begin + +section{* Property Profiles for OCL Operators via Isabelle Locales *} + +text{* We use the Isabelle mechanism of a \emph{Locale} to generate the +common lemmas for each type and operator; Locales can be seen as a +functor that takes a local theory and generates a number of theorems. +In our case, we will instantiate later these locales by the local theory +of an operator definition and obtain the common rules for strictness, definedness +propagation, context-passingness and constance in a systematic way. +*} + +subsection{* Property Profiles for Monadic Operators *} + +locale profile_mono_scheme_defined = + fixes f :: "('\,'\::null)val \ ('\,'\::null)val" + fixes g + assumes def_scheme: "(f x) \ \ \. if (\ x) \ = true \ then g (x \) else invalid \" +begin + lemma strict[simp,code_unfold]: " f invalid = invalid" + by(rule ext, simp add: def_scheme true_def false_def) + + lemma null_strict[simp,code_unfold]: " f null = invalid" + by(rule ext, simp add: def_scheme true_def false_def) + + lemma cp0 : "f X \ = f (\ _. X \) \" + by(simp add: def_scheme cp_defined[symmetric]) + + lemma cp[simp,code_unfold] : " cp P \ cp (\X. f (P X) )" + by(rule cpI1[of "f"], intro allI, rule cp0, simp_all) + +end + +locale profile_mono_schemeV = + fixes f :: "('\,'\::null)val \ ('\,'\::null)val" + fixes g + assumes def_scheme: "(f x) \ \ \. if (\ x) \ = true \ then g (x \) else invalid \" +begin + lemma strict[simp,code_unfold]: " f invalid = invalid" + by(rule ext, simp add: def_scheme true_def false_def) + + lemma cp0 : "f X \ = f (\ _. X \) \" + by(simp add: def_scheme cp_valid[symmetric]) + + lemma cp[simp,code_unfold] : " cp P \ cp (\X. f (P X) )" + by(rule cpI1[of "f"], intro allI, rule cp0, simp_all) + +end + +locale profile_mono\<^sub>d = profile_mono_scheme_defined + + assumes "\ x. x \ bot \ x \ null \ g x \ bot" +begin + + lemma const[simp,code_unfold] : + assumes C1 :"const X" + shows "const(f X)" + proof - + have const_g : "const (\\. g (X \))" by(insert C1, auto simp:const_def, metis) + show ?thesis by(simp_all add : def_scheme const_ss C1 const_g) + qed +end + +locale profile_mono0 = profile_mono_scheme_defined + + assumes def_body: "\ x. x \ bot \ x \ null \ g x \ bot \ g x \ null" + +sublocale profile_mono0 < profile_mono\<^sub>d +by(unfold_locales, simp add: def_scheme, simp add: def_body) + +context profile_mono0 +begin + lemma def_homo[simp,code_unfold]: "\(f x) = (\ x)" + apply(rule ext, rename_tac "\",subst foundation22[symmetric]) + apply(case_tac "\(\ \ \ x)", simp add:defined_split, elim disjE) + apply(erule StrongEq_L_subst2_rev, simp,simp) + apply(erule StrongEq_L_subst2_rev, simp,simp) + apply(simp) + apply(rule foundation13[THEN iffD2,THEN StrongEq_L_subst2_rev, where y ="\ x"]) + apply(simp_all add:def_scheme) + apply(simp add: OclValid_def) + by(auto simp:foundation13 StrongEq_def false_def true_def defined_def bot_fun_def null_fun_def def_body + split: split_if_asm) + + lemma def_valid_then_def: "\(f x) = (\(f x))" + apply(rule ext, rename_tac "\",subst foundation22[symmetric]) + apply(case_tac "\(\ \ \ x)", simp add:defined_split, elim disjE) + apply(erule StrongEq_L_subst2_rev, simp,simp) + apply(erule StrongEq_L_subst2_rev, simp,simp) + apply simp + apply(simp_all add:def_scheme) + apply(simp add: OclValid_def valid_def, subst cp_StrongEq) + apply(subst (2) cp_defined, simp, simp add: cp_defined[symmetric]) + by(auto simp:foundation13 StrongEq_def false_def true_def defined_def bot_fun_def null_fun_def def_body + split: split_if_asm) +end + +subsection{* Property Profiles for Single *} + +locale profile_single = + fixes d:: "('\,'a::null)val \ '\ Boolean" + assumes d_strict[simp,code_unfold]: "d invalid = false" + assumes d_cp0: "d X \ = d (\ _. X \) \" + assumes d_const[simp,code_unfold]: "const X \ const (d X)" + +subsection{* Property Profiles for Binary Operators *} + +definition "bin' f g d\<^sub>x d\<^sub>y X Y = + (f X Y = (\ \. if (d\<^sub>x X) \ = true \ \ (d\<^sub>y Y) \ = true \ + then g X Y \ + else invalid \ ))" + +definition "bin f g = bin' f (\X Y \. g (X \) (Y \))" + +lemmas [simp,code_unfold] = bin'_def bin_def + +locale profile_bin_scheme = + fixes d\<^sub>x:: "('\,'a::null)val \ '\ Boolean" + fixes d\<^sub>y:: "('\,'b::null)val \ '\ Boolean" + fixes f::"('\,'a::null)val \ ('\,'b::null)val \ ('\,'c::null)val" + fixes g + assumes d\<^sub>x' : "profile_single d\<^sub>x" + assumes d\<^sub>y' : "profile_single d\<^sub>y" + assumes d\<^sub>x_d\<^sub>y_homo[simp,code_unfold]: "cp (f X) \ + cp (\x. f x Y) \ + f X invalid = invalid \ + f invalid Y = invalid \ + (\ (\ \ d\<^sub>x X) \ \ (\ \ d\<^sub>y Y)) \ + \ \ (\ f X Y \ (d\<^sub>x X and d\<^sub>y Y))" + assumes def_scheme''[simplified]: "bin f g d\<^sub>x d\<^sub>y X Y" + assumes 1: "\ \ d\<^sub>x X \ \ \ d\<^sub>y Y \ \ \ \ f X Y" +begin + interpretation d\<^sub>x : profile_single d\<^sub>x by (rule d\<^sub>x') + interpretation d\<^sub>y : profile_single d\<^sub>y by (rule d\<^sub>y') + + lemma strict1[simp,code_unfold]: " f invalid y = invalid" + by(rule ext, simp add: def_scheme'' true_def false_def) + + lemma strict2[simp,code_unfold]: " f x invalid = invalid" + by(rule ext, simp add: def_scheme'' true_def false_def) + + lemma cp0 : "f X Y \ = f (\ _. X \) (\ _. Y \) \" + by(simp add: def_scheme'' d\<^sub>x.d_cp0[symmetric] d\<^sub>y.d_cp0[symmetric] cp_defined[symmetric]) + + lemma cp[simp,code_unfold] : " cp P \ cp Q \ cp (\X. f (P X) (Q X))" + by(rule cpI2[of "f"], intro allI, rule cp0, simp_all) + + lemma def_homo[simp,code_unfold]: "\(f x y) = (d\<^sub>x x and d\<^sub>y y)" + apply(rule ext, rename_tac "\",subst foundation22[symmetric]) + apply(case_tac "\(\ \ d\<^sub>x x)", simp) + apply(case_tac "\(\ \ d\<^sub>y y)", simp) + apply(simp) + apply(rule foundation13[THEN iffD2,THEN StrongEq_L_subst2_rev, where y ="d\<^sub>x x"]) + apply(simp_all) + apply(rule foundation13[THEN iffD2,THEN StrongEq_L_subst2_rev, where y ="d\<^sub>y y"]) + apply(simp_all add: 1 foundation13) + done + + lemma def_valid_then_def: "\(f x y) = (\(f x y))" (* [simp,code_unfold] ? *) + apply(rule ext, rename_tac "\") + apply(simp_all add: valid_def defined_def def_scheme'' + true_def false_def invalid_def + null_def null_fun_def null_option_def bot_fun_def) + by (metis "1" OclValid_def def_scheme'' foundation16 true_def) + + lemma defined_args_valid: "(\ \ \ (f x y)) = ((\ \ d\<^sub>x x) \ (\ \ d\<^sub>y y))" + by(simp add: foundation10') + + lemma const[simp,code_unfold] : + assumes C1 :"const X" and C2 : "const Y" + shows "const(f X Y)" + proof - + have const_g : "const (\\. g (X \) (Y \))" + by(insert C1 C2, auto simp:const_def, metis) + show ?thesis + by(simp_all add : def_scheme'' const_ss C1 C2 const_g) + qed +end + + +text{* +In our context, we will use Locales as ``Property Profiles'' for OCL operators; +if an operator @{term "f"} is of profile @{term "profile_bin_scheme defined f g"} we know +that it satisfies a number of properties like @{text "strict1"} or @{text "strict2"} +\ie{} @{term "f invalid y = invalid"} and @{term "f null y = invalid"}. +Since some of the more advanced Locales come with 10 - 15 theorems, property profiles +represent a major structuring mechanism for the OCL library. +*} + + +locale profile_bin_scheme_defined = + fixes d\<^sub>y:: "('\,'b::null)val \ '\ Boolean" + fixes f::"('\,'a::null)val \ ('\,'b::null)val \ ('\,'c::null)val" + fixes g + assumes d\<^sub>y : "profile_single d\<^sub>y" + assumes d\<^sub>y_homo[simp,code_unfold]: "cp (f X) \ + f X invalid = invalid \ + \ \ \ d\<^sub>y Y \ + \ \ \ f X Y \ (\ X and d\<^sub>y Y)" + assumes def_scheme'[simplified]: "bin f g defined d\<^sub>y X Y" + assumes def_body': "\ x y \. x\bot \ x\null \ (d\<^sub>y y) \ = true \ \ g x (y \) \ bot \ g x (y \) \ null " +begin + lemma strict3[simp,code_unfold]: " f null y = invalid" + by(rule ext, simp add: def_scheme' true_def false_def) +end + +sublocale profile_bin_scheme_defined < profile_bin_scheme defined +proof - + interpret d\<^sub>y : profile_single d\<^sub>y by (rule d\<^sub>y) + show "profile_bin_scheme defined d\<^sub>y f g" + apply(unfold_locales) + apply(simp)+ + apply(subst cp_defined, simp) + apply(rule const_defined, simp) + apply(simp add:defined_split, elim disjE) + apply(erule StrongEq_L_subst2_rev, simp, simp)+ + apply(simp) + apply(simp add: def_scheme') + apply(simp add: defined_def OclValid_def false_def true_def + bot_fun_def null_fun_def def_scheme' split: split_if_asm, rule def_body') + by(simp add: true_def)+ +qed + +locale profile_bin\<^sub>d_\<^sub>d = + fixes f::"('\,'a::null)val \ ('\,'b::null)val \ ('\,'c::null)val" + fixes g + assumes def_scheme[simplified]: "bin f g defined defined X Y" + assumes def_body: "\ x y. x\bot \ x\null \ y\bot \ y\null \ + g x y \ bot \ g x y \ null " +begin + lemma strict4[simp,code_unfold]: " f x null = invalid" + by(rule ext, simp add: def_scheme true_def false_def) +end + +sublocale profile_bin\<^sub>d_\<^sub>d < profile_bin_scheme_defined defined + apply(unfold_locales) + apply(simp)+ + apply(subst cp_defined, simp)+ + apply(rule const_defined, simp)+ + apply(simp add:defined_split, elim disjE) + apply(erule StrongEq_L_subst2_rev, simp, simp)+ + apply(simp add: def_scheme) + apply(simp add: defined_def OclValid_def false_def true_def bot_fun_def null_fun_def def_scheme) + apply(rule def_body, simp_all add: true_def false_def split:split_if_asm) +done + +locale profile_bin\<^sub>d_\<^sub>v = + fixes f::"('\,'a::null)val \ ('\,'b::null)val \ ('\,'c::null)val" + fixes g + assumes def_scheme[simplified]: "bin f g defined valid X Y" + assumes def_body: "\ x y. x\bot \ x\null \ y\bot \ g x y \ bot \ g x y \ null" + +sublocale profile_bin\<^sub>d_\<^sub>v < profile_bin_scheme_defined valid + apply(unfold_locales) + apply(simp) + apply(subst cp_valid, simp) + apply(rule const_valid, simp) + apply(simp add:foundation18'') + apply(erule StrongEq_L_subst2_rev, simp, simp) + apply(simp add: def_scheme) + by (metis OclValid_def def_body foundation18') + +locale profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v = + fixes f :: "('\,'\::null)val \ ('\,'\::null)val \ ('\) Boolean" + assumes def_scheme[simplified]: "bin' f StrongEq valid valid X Y" + +sublocale profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v < profile_bin_scheme valid valid f "\x y. \\x = y\\" + apply(unfold_locales) + apply(simp) + apply(subst cp_valid, simp) + apply (simp add: const_valid) + apply (metis (hide_lams, mono_tags) OclValid_def def_scheme defined5 defined6 defined_and_I foundation1 foundation10' foundation16' foundation18 foundation21 foundation22 foundation9) + apply(simp add: def_scheme, subst StrongEq_def, simp) + by (metis OclValid_def def_scheme defined7 foundation16) + +context profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v + begin + lemma idem[simp,code_unfold]: " f null null = true" + by(rule ext, simp add: def_scheme true_def false_def) + + (* definedness *) + lemma defargs: "\ \ f x y \ (\ \ \ x) \ (\ \ \ y)" + by(simp add: def_scheme OclValid_def true_def invalid_def valid_def bot_option_def + split: bool.split_asm HOL.split_if_asm) + + lemma defined_args_valid' : "\ (f x y) = (\ x and \ y)" + by(auto intro!: transform2_rev defined_and_I simp:foundation10 defined_args_valid) + + (* logic and algebraic properties *) + lemma refl_ext[simp,code_unfold] : "(f x x) = (if (\ x) then true else invalid endif)" + by(rule ext, simp add: def_scheme OclIf_def) + + lemma sym : "\ \ (f x y) \ \ \ (f y x)" + apply(case_tac "\ \ \ x") + apply(auto simp: def_scheme OclValid_def) + by(fold OclValid_def, erule StrongEq_L_sym) + + lemma symmetric : "(f x y) = (f y x)" + by(rule ext, rename_tac \, auto simp: def_scheme StrongEq_sym) + + lemma trans : "\ \ (f x y) \ \ \ (f y z) \ \ \ (f x z)" + apply(case_tac "\ \ \ x") + apply(case_tac "\ \ \ y") + apply(auto simp: def_scheme OclValid_def) + by(fold OclValid_def, auto elim: StrongEq_L_trans) + + lemma StrictRefEq_vs_StrongEq: "\ \(\ x) \ \ \(\ y) \ (\ \ ((f x y) \ (x \ y)))" + apply(simp add: def_scheme OclValid_def) + apply(subst cp_StrongEq[of _ "(x \ y)"]) + by simp + + end + + +locale profile_bin\<^sub>v_\<^sub>v = + fixes f :: "('\,'\::null)val \ ('\,'\::null)val \ ('\,'\::null)val" + fixes g + assumes def_scheme[simplified]: "bin f g valid valid X Y" + assumes def_body: "\ x y. x\bot \ y\bot \ g x y \ bot \ g x y \ null" + +sublocale profile_bin\<^sub>v_\<^sub>v < profile_bin_scheme valid valid + apply(unfold_locales) + apply(simp, subst cp_valid, simp, rule const_valid, simp)+ + apply (metis (hide_lams, mono_tags) OclValid_def def_scheme defined5 defined6 defined_and_I + foundation1 foundation10' foundation16' foundation18 foundation21 foundation22 foundation9) + apply(simp add: def_scheme) + apply(simp add: defined_def OclValid_def false_def true_def + bot_fun_def null_fun_def def_scheme split: split_if_asm, rule def_body) + by (metis OclValid_def foundation18' true_def)+ + +end diff --git a/OCL_state.thy b/src/UML_State.thy similarity index 59% rename from OCL_state.thy rename to src/UML_State.thy index e5f184c..426036e 100644 --- a/OCL_state.thy +++ b/src/UML_State.thy @@ -1,13 +1,13 @@ (***************************************************************************** - * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.4 + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 * for the OMG Standard. * http://www.brucker.ch/projects/hol-testgen/ * - * OCL_state.thy --- State Operations and Objects. + * UML_State.thy --- State Operations and Objects. * This file is part of HOL-TestGen. * - * Copyright (c) 2012-2013 Université Paris-Sud, France - * 2013 IRT SystemX, France + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France * * All rights reserved. * @@ -40,15 +40,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************) -chapter{* Formalization III: State Operations and Objects *} +chapter{* Formalization III: UML/OCL constructs: State Operations and Objects *} -theory OCL_state -imports OCL_lib +theory UML_State +imports UML_Library begin +no_notation None ("\") section{* Introduction: States over Typed Object Universes *} -text{* +text{* \label{sec:universe} In the following, we will refine the concepts of a user-defined data-model (implied by a class-diagram) as well as the notion of $\state{}$ used in the previous section to much more detail. @@ -59,52 +60,7 @@ text{* -subsection{* Recall: The Generic Structure of States *} -text{* Recall the foundational concept of an object id (oid), -which is just some infinite set.*} - -text{* -\begin{isar}[mathescape] -$\text{\textbf{type-synonym}}$ $\mathit{oid = nat}$ -\end{isar} -*} - -text{* Further, recall that states are pair of a partial map from oid's to elements of an -object universe @{text "'\"}---the heap---and a map to relations of objects. -The relations were encoded as lists of pairs to leave the possibility to have Bags, -OrderedSets or Sequences as association ends. *} -text{* This leads to the definitions: -\begin{isar}[mathescape] -record ('\)state = - heap :: "oid \ '\ " - assocs\<^sub>2 :: "oid \ (oid \ oid) list" - assocs\<^sub>3 :: "oid \ (oid \ oid \ oid) list" - -$\text{\textbf{type-synonym}}$ ('\)st = "'\ state \ '\ state" -\end{isar} -*} - -text{* Now we refine our state-interface. -In certain contexts, we will require that the elements of the object universe have -a particular structure; more precisely, we will require that there is a function that -reconstructs the oid of an object in the state (we will settle the question how to define -this function later). *} - -class object = fixes oid_of :: "'a \ oid" - -text{* Thus, if needed, we can constrain the object universe to objects by adding -the following type class constraint:*} -typ "'\ :: object" - -text{* The major instance needed are instances constructed over options: once an object, -options of objects are also objects. *} -instantiation option :: (object)object -begin - definition oid_of_option_def: "oid_of x = oid_of (the x)" - instance .. -end - -section{* Fundamental Predicates on Object: Strict Equality *} +subsection{* Fundamental Properties on Objects: Core Referential Equality *} subsubsection{* Definition *} text{* Generic referential equality - to be used for instantiations @@ -117,25 +73,7 @@ where "StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y else \\(oid_of (x \)) = (oid_of (y \)) \\ else invalid \" -subsection{* Logic and Algebraic Layer on Object *} -subsubsection{* Validity and Definedness Properties *} - -text{* We derive the usual laws on definedness for (generic) object equality:*} -lemma StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_defargs: -"\ \ (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x (y::('\,'a::{null,object})val))\ (\ \(\ x)) \ (\ \(\ y))" -by(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def OclValid_def true_def invalid_def bot_option_def - split: bool.split_asm HOL.split_if_asm) - - -subsubsection{* Symmetry *} - -lemma StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_sym : -assumes x_val : "\ \ \ x" -shows "\ \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x x" -by(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def true_def OclValid_def - x_val[simplified OclValid_def]) - -subsubsection{* Execution with Invalid or Null as Argument *} +subsubsection{* Strictness and context passing *} lemma StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_strict1[simp,code_unfold] : "(StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x invalid) = invalid" @@ -145,17 +83,51 @@ lemma StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_strict2[simp,c "(StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t invalid x) = invalid" by(rule ext, simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def true_def false_def) -subsubsection{* Context Passing *} lemma cp_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t: "(StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y \) = (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (\_. x \) (\_. y \)) \" by(auto simp: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def cp_valid[symmetric]) +text_raw{* \isatagafp *} +lemmas cp0_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t= cp_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t[THEN allI[THEN allI[THEN allI[THEN cpI2]], + of "StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t"]] + lemmas cp_intro''[intro!,simp,code_unfold] = cp_intro'' cp_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t[THEN allI[THEN allI[THEN allI[THEN cpI2]], of "StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t"]] +text_raw{* \endisatagafp *} + +subsection{* Logic and Algebraic Layer on Object *} +subsubsection{* Validity and Definedness Properties *} + +text{* We derive the usual laws on definedness for (generic) object equality:*} +lemma StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_defargs: +"\ \ (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x (y::('\,'a::{null,object})val))\ (\ \(\ x)) \ (\ \(\ y))" +by(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def OclValid_def true_def invalid_def bot_option_def + split: bool.split_asm HOL.split_if_asm) + +lemma defined_StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_I: + assumes val_x : "\ \ \ x" + assumes val_x : "\ \ \ y" + shows "\ \ \ (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y)" + apply(insert assms, simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def OclValid_def) +by(subst cp_defined, simp add: true_def) + +lemma StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def_homo : +"\(StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x (y::('\,'a::{null,object})val)) = ((\ x) and (\ y))" +oops (* sorry *) + +subsubsection{* Symmetry *} + +lemma StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_sym : +assumes x_val : "\ \ \ x" +shows "\ \ StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x x" +by(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def true_def OclValid_def + x_val[simplified OclValid_def]) + + subsubsection{* Behavior vs StrongEq *} text{* It remains to clarify the role of the state invariant @@ -233,8 +205,8 @@ section{* Operations on Object *} subsection{* Initial States (for testing and code generation) *} definition \\<^sub>0 :: "('\)st" -where "\\<^sub>0 \ (\heap=Map.empty, assocs\<^sub>2= Map.empty, assocs\<^sub>3= Map.empty\, - \heap=Map.empty, assocs\<^sub>2= Map.empty, assocs\<^sub>3= Map.empty\)" +where "\\<^sub>0 \ (\heap=Map.empty, assocs = Map.empty\, + \heap=Map.empty, assocs = Map.empty\)" subsection{* OclAllInstances *} @@ -245,13 +217,13 @@ universes; we show that this is a sufficient ``characterization.'' *} definition OclAllInstances_generic :: "(('\::object) st \ '\ state) \ ('\::object \ '\) \ ('\, '\ option option) Set" where "OclAllInstances_generic fst_snd H = - (\\. Abs_Set_0 \\ Some ` ((H ` ran (heap (fst_snd \))) - { None }) \\)" + (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ Some ` ((H ` ran (heap (fst_snd \))) - { None }) \\)" lemma OclAllInstances_generic_defined: "\ \ \ (OclAllInstances_generic pre_post H)" apply(simp add: defined_def OclValid_def OclAllInstances_generic_def false_def true_def - bot_fun_def bot_Set_0_def null_fun_def null_Set_0_def) + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) apply(rule conjI) - apply(rule notI, subst (asm) Abs_Set_0_inject, simp, + apply(rule notI, subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, simp, (rule disjI2)+, metis bot_option_def option.distinct(1), (simp add: bot_option_def null_option_def)+)+ @@ -263,15 +235,14 @@ lemma OclAllInstances_generic_init_empty: by(simp add: StrongEq_def OclAllInstances_generic_def OclValid_def \\<^sub>0_def mtSet_def) lemma represented_generic_objects_nonnull: -assumes A: "\ \ ((OclAllInstances_generic pre_post (H::('\::object \ '\))) ->includes(x))" +assumes A: "\ \ ((OclAllInstances_generic pre_post (H::('\::object \ '\))) ->includes\<^sub>S\<^sub>e\<^sub>t(x))" shows "\ \ not(x \ null)" proof - have B: "\ \ \ (OclAllInstances_generic pre_post H)" - by(insert A[THEN OCL_core.foundation6, - simplified OCL_lib.OclIncludes_defined_args_valid], auto) + by (simp add: OclAllInstances_generic_defined) have C: "\ \ \ x" - by(insert A[THEN OCL_core.foundation6, - simplified OCL_lib.OclIncludes_defined_args_valid], auto) + by (metis OclIncludes.def_valid_then_def + OclIncludes_valid_args_valid A foundation6) show ?thesis apply(insert A) apply(simp add: StrongEq_def OclValid_def @@ -279,40 +250,38 @@ proof - C[simplified OclValid_def]) apply(simp add:OclAllInstances_generic_def) apply(erule contrapos_pn) - apply(subst OCL_lib.Set_0.Abs_Set_0_inverse, + apply(subst Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, auto simp: null_fun_def null_option_def bot_option_def) done qed lemma represented_generic_objects_defined: -assumes A: "\ \ ((OclAllInstances_generic pre_post (H::('\::object \ '\))) ->includes(x))" +assumes A: "\ \ ((OclAllInstances_generic pre_post (H::('\::object \ '\))) ->includes\<^sub>S\<^sub>e\<^sub>t(x))" shows "\ \ \ (OclAllInstances_generic pre_post H) \ \ \ \ x" -apply(insert A[THEN OCL_core.foundation6, - simplified OCL_lib.OclIncludes_defined_args_valid]) -apply(simp add: OCL_core.foundation16 OCL_core.foundation18 invalid_def, erule conjE) -apply(insert A[THEN represented_generic_objects_nonnull]) -by(simp add: foundation24 null_fun_def) +by (metis OclAllInstances_generic_defined + A[THEN represented_generic_objects_nonnull] OclIncludes.defined_args_valid + A foundation16' foundation18 foundation24 foundation6) text{* One way to establish the actual presence of an object representation in a state is:*} +definition "is_represented_in_state fst_snd x H \ = (x \ \ (Some o H) ` ran (heap (fst_snd \)))" + lemma represented_generic_objects_in_state: -assumes A: "\ \ (OclAllInstances_generic pre_post H)->includes(x)" -shows "x \ \ (Some o H) ` ran (heap(pre_post \))" +assumes A: "\ \ (OclAllInstances_generic pre_post H)->includes\<^sub>S\<^sub>e\<^sub>t(x)" +shows "is_represented_in_state pre_post x H \" proof - have B: "(\ (OclAllInstances_generic pre_post H)) \ = true \" - by(simp add: OCL_core.OclValid_def[symmetric] OclAllInstances_generic_defined) + by(simp add: OclValid_def[symmetric] OclAllInstances_generic_defined) have C: "(\ x) \ = true \" - by(insert A[THEN OCL_core.foundation6, - simplified OCL_lib.OclIncludes_defined_args_valid], - auto simp: OclValid_def) - have F: "Rep_Set_0 (Abs_Set_0 \\Some ` (H ` ran (heap (pre_post \)) - {None})\\) = + by (metis OclValid_def UML_Set.OclIncludes_def assms bot_option_def option.distinct(1) true_def) + have F: "Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\Some ` (H ` ran (heap (pre_post \)) - {None})\\) = \\Some ` (H ` ran (heap (pre_post \)) - {None})\\" - by(subst OCL_lib.Set_0.Abs_Set_0_inverse,simp_all add: bot_option_def) + by(subst Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse,simp_all add: bot_option_def) show ?thesis apply(insert A) - apply(simp add: OclIncludes_def OclValid_def ran_def B C image_def true_def) + apply(simp add: is_represented_in_state_def OclIncludes_def OclValid_def ran_def B C image_def true_def) apply(simp add: OclAllInstances_generic_def) apply(simp add: F) apply(simp add: ran_def) @@ -322,18 +291,18 @@ qed lemma state_update_vs_allInstances_generic_empty: assumes [simp]: "\a. pre_post (mk a) = a" -shows "(mk \heap=empty, assocs\<^sub>2=A, assocs\<^sub>3=B\) \ OclAllInstances_generic pre_post Type \ Set{}" +shows "(mk \heap=empty, assocs=A\) \ OclAllInstances_generic pre_post Type \ Set{}" proof - have state_update_vs_allInstances_empty: - "(OclAllInstances_generic pre_post Type) (mk \heap=empty, assocs\<^sub>2=A, assocs\<^sub>3=B\) = - Set{} (mk \heap=empty, assocs\<^sub>2=A, assocs\<^sub>3=B\)" + "(OclAllInstances_generic pre_post Type) (mk \heap=empty, assocs=A\) = + Set{} (mk \heap=empty, assocs=A\)" by(simp add: OclAllInstances_generic_def mtSet_def) show ?thesis - apply(simp only: OclValid_def, subst cp_StrictRefEq\<^sub>S\<^sub>e\<^sub>t, - simp add: state_update_vs_allInstances_empty) - apply(simp add: OclIf_def valid_def mtSet_def defined_def - bot_fun_def null_fun_def null_option_def bot_Set_0_def) - by(subst Abs_Set_0_inject, (simp add: bot_option_def true_def)+) + apply(simp only: OclValid_def, subst StrictRefEq\<^sub>S\<^sub>e\<^sub>t.cp0, + simp only: state_update_vs_allInstances_empty StrictRefEq\<^sub>S\<^sub>e\<^sub>t.refl_ext) + apply(simp add: OclIf_def valid_def mtSet_def defined_def + bot_fun_def null_fun_def null_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + by(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, (simp add: bot_option_def true_def)+) qed text{* Here comes a couple of operational rules that allow to infer the value @@ -349,10 +318,10 @@ assumes [simp]: "\a. pre_post (mk a) = a" assumes "\x. \' oid = Some x \ x = Object" and "Type Object \ None" shows "(OclAllInstances_generic pre_post Type) - (mk \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\) + (mk \heap=\'(oid\Object), assocs=A\) = - ((OclAllInstances_generic pre_post Type)->including(\ _. \\ drop (Type Object) \\)) - (mk \heap=\',assocs\<^sub>2=A, assocs\<^sub>3=B\)" + ((OclAllInstances_generic pre_post Type)->including\<^sub>S\<^sub>e\<^sub>t(\ _. \\ drop (Type Object) \\)) + (mk \heap=\',assocs=A\)" proof - have drop_none : "\x. x \ None \ \\x\\ = x" by(case_tac x, simp+) @@ -361,9 +330,9 @@ proof - by (metis insert_Diff_if option.distinct(1) singletonE) show ?thesis - apply(simp add: OclIncluding_def OclAllInstances_generic_defined[simplified OclValid_def], + apply(simp add: UML_Set.OclIncluding_def OclAllInstances_generic_defined[simplified OclValid_def], simp add: OclAllInstances_generic_def) - apply(subst Abs_Set_0_inverse, simp add: bot_option_def, simp add: comp_def, + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def, simp add: comp_def, subst image_insert[symmetric], subst drop_none, simp add: assms) apply(case_tac "Type Object", simp add: assms, simp only:, @@ -375,6 +344,7 @@ proof - apply(subgoal_tac "Object \ ran \'") prefer 2 apply(rule ranI, simp) by(subst insert_absorb, simp, metis fun_upd_apply) + qed @@ -383,20 +353,20 @@ assumes [simp]: "\a. pre_post (mk a) = a" assumes "\x. \' oid = Some x \ x = Object" and "Type Object \ None" shows "(OclAllInstances_generic pre_post Type) - (mk \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\) + (mk \heap=\'(oid\Object), assocs=A\) = ((\_. (OclAllInstances_generic pre_post Type) - (mk \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\))->including(\ _. \\ drop (Type Object) \\)) - (mk \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\)" + (mk \heap=\', assocs=A\))->including\<^sub>S\<^sub>e\<^sub>t(\ _. \\ drop (Type Object) \\)) + (mk \heap=\'(oid\Object), assocs=A\)" apply(subst state_update_vs_allInstances_generic_including', (simp add: assms)+, - subst cp_OclIncluding, - simp add: OclIncluding_def) - apply(subst (1 3) cp_defined[symmetric], + subst UML_Set.OclIncluding.cp0, + simp add: UML_Set.OclIncluding_def) + apply(subst (1 3) cp_defined[symmetric], simp add: OclAllInstances_generic_defined[simplified OclValid_def]) - apply(simp add: defined_def OclValid_def OclAllInstances_generic_def - bot_fun_def null_fun_def bot_Set_0_def null_Set_0_def) - apply(subst (1 3) Abs_Set_0_inject) + apply(simp add: defined_def OclValid_def OclAllInstances_generic_def invalid_def + bot_fun_def null_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + apply(subst (1 3) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) by(simp add: bot_option_def null_option_def)+ @@ -406,10 +376,10 @@ assumes [simp]: "\a. pre_post (mk a) = a" assumes "\x. \' oid = Some x \ x = Object" and "Type Object = None" shows "(OclAllInstances_generic pre_post Type) - (mk \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\) + (mk \heap=\'(oid\Object), assocs=A\) = (OclAllInstances_generic pre_post Type) - (mk \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\)" + (mk \heap=\', assocs=A\)" proof - have drop_none : "\x. x \ None \ \\x\\ = x" by(case_tac x, simp+) @@ -436,8 +406,8 @@ assumes oid_def: "oid\dom \'" and non_type_conform: "Type Object = None " and cp_ctxt: "cp P" and const_ctxt: "\X. const X \ const (P X)" -shows "(mk \heap=\'(oid\Object),assocs\<^sub>2=A,assocs\<^sub>3=B\ \ P (OclAllInstances_generic pre_post Type)) = - (mk \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\ \ P (OclAllInstances_generic pre_post Type))" +shows "(mk \heap=\'(oid\Object),assocs=A\ \ P (OclAllInstances_generic pre_post Type)) = + (mk \heap=\', assocs=A\ \ P (OclAllInstances_generic pre_post Type))" (is "(?\ \ P ?\) = (?\' \ P ?\)") proof - have P_cp : "\x \. P x \ = P (\_. x \) \" @@ -445,7 +415,7 @@ proof - have A : "const (P (\_. ?\ ?\))" by(simp add: const_ctxt const_ss) have "(?\ \ P ?\) = (?\ \ \_. P ?\ ?\)" - by(subst OCL_core.cp_validity, rule refl) + by(subst foundation23, rule refl) also have "... = (?\ \ \_. P (\_. ?\ ?\) ?\)" by(subst P_cp, rule refl) also have "... = (?\' \ \_. P (\_. ?\ ?\) ?\')" @@ -454,7 +424,7 @@ proof - finally have X: "(?\ \ P ?\) = (?\' \ \_. P (\_. ?\ ?\) ?\')" by simp show ?thesis - apply(subst X) apply(subst OCL_core.cp_validity[symmetric]) + apply(subst X) apply(subst foundation23[symmetric]) apply(rule StrongEq_L_subst3[OF cp_ctxt]) apply(simp add: OclValid_def StrongEq_def true_def) apply(rule state_update_vs_allInstances_generic_noincluding') @@ -467,9 +437,9 @@ assumes oid_def: "oid\dom \'" and type_conform: "Type Object \ None " and cp_ctxt: "cp P" and const_ctxt: "\X. const X \ const (P X)" -shows "(mk \heap=\'(oid\Object),assocs\<^sub>2=A,assocs\<^sub>3=B\ \ P (OclAllInstances_generic pre_post Type)) = - (mk \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\ \ P ((OclAllInstances_generic pre_post Type) - ->including(\ _. \(Type Object)\)))" +shows "(mk \heap=\'(oid\Object),assocs=A\ \ P (OclAllInstances_generic pre_post Type)) = + (mk \heap=\', assocs=A\ \ P ((OclAllInstances_generic pre_post Type) + ->including\<^sub>S\<^sub>e\<^sub>t(\ _. \(Type Object)\)))" (is "(?\ \ P ?\) = (?\' \ P ?\')") proof - have P_cp : "\x \. P x \ = P (\_. x \) \" @@ -477,7 +447,7 @@ proof - have A : "const (P (\_. ?\ ?\))" by(simp add: const_ctxt const_ss) have "(?\ \ P ?\) = (?\ \ \_. P ?\ ?\)" - by(subst OCL_core.cp_validity, rule refl) + by(subst foundation23, rule refl) also have "... = (?\ \ \_. P (\_. ?\ ?\) ?\)" by(subst P_cp, rule refl) also have "... = (?\' \ \_. P (\_. ?\ ?\) ?\')" @@ -486,18 +456,18 @@ proof - finally have X: "(?\ \ P ?\) = (?\' \ \_. P (\_. ?\ ?\) ?\')" by simp let ?allInstances = "OclAllInstances_generic pre_post Type" - have "?allInstances ?\ = \_. ?allInstances ?\'->including(\_.\\\Type Object\\\) ?\" + have "?allInstances ?\ = \_. ?allInstances ?\'->including\<^sub>S\<^sub>e\<^sub>t(\_.\\\Type Object\\\) ?\" apply(rule state_update_vs_allInstances_generic_including) by(insert oid_def, auto simp: type_conform) - also have "... = ((\_. ?allInstances ?\')->including(\_. (\_.\\\Type Object\\\) ?\') ?\')" + also have "... = ((\_. ?allInstances ?\')->including\<^sub>S\<^sub>e\<^sub>t(\_. (\_.\\\Type Object\\\) ?\') ?\')" by(subst const_OclIncluding[simplified const_def], simp+) - also have "... = (?allInstances->including(\ _. \Type Object\) ?\')" - apply(subst OCL_lib.cp_OclIncluding[symmetric]) + also have "... = (?allInstances->including\<^sub>S\<^sub>e\<^sub>t(\ _. \Type Object\) ?\')" + apply(subst UML_Set.OclIncluding.cp0[symmetric]) by(insert type_conform, auto) - finally have Y : "?allInstances ?\ = (?allInstances->including(\ _. \Type Object\) ?\')" + finally have Y : "?allInstances ?\ = (?allInstances->including\<^sub>S\<^sub>e\<^sub>t(\ _. \Type Object\) ?\')" by auto show ?thesis - apply(subst X) apply(subst OCL_core.cp_validity[symmetric]) + apply(subst X) apply(subst foundation23[symmetric]) apply(rule StrongEq_L_subst3[OF cp_ctxt]) apply(simp add: OclValid_def StrongEq_def Y true_def) done @@ -521,28 +491,28 @@ by(rule OclAllInstances_generic_init_empty, simp) lemma represented_at_post_objects_nonnull: -assumes A: "\ \ (((H::('\::object \ '\)).allInstances()) ->includes(x))" +assumes A: "\ \ (((H::('\::object \ '\)).allInstances()) ->includes\<^sub>S\<^sub>e\<^sub>t(x))" shows "\ \ not(x \ null)" by(rule represented_generic_objects_nonnull[OF A[simplified OclAllInstances_at_post_def]]) lemma represented_at_post_objects_defined: -assumes A: "\ \ (((H::('\::object \ '\)).allInstances()) ->includes(x))" +assumes A: "\ \ (((H::('\::object \ '\)).allInstances()) ->includes\<^sub>S\<^sub>e\<^sub>t(x))" shows "\ \ \ (H .allInstances()) \ \ \ \ x" -unfolding OclAllInstances_at_post_def +unfolding OclAllInstances_at_post_def by(rule represented_generic_objects_defined[OF A[simplified OclAllInstances_at_post_def]]) text{* One way to establish the actual presence of an object representation in a state is:*} lemma -assumes A: "\ \ H .allInstances()->includes(x)" -shows "x \ \ (Some o H) ` ran (heap(snd \))" +assumes A: "\ \ H .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(x)" +shows "is_represented_in_state snd x H \" by(rule represented_generic_objects_in_state[OF A[simplified OclAllInstances_at_post_def]]) lemma state_update_vs_allInstances_at_post_empty: -shows "(\, \heap=empty, assocs\<^sub>2=A, assocs\<^sub>3=B\) \ Type .allInstances() \ Set{}" -unfolding OclAllInstances_at_post_def +shows "(\, \heap=empty, assocs=A\) \ Type .allInstances() \ Set{}" +unfolding OclAllInstances_at_post_def by(rule state_update_vs_allInstances_generic_empty[OF snd_conv]) text{* Here comes a couple of operational rules that allow to infer the value @@ -557,11 +527,11 @@ lemma state_update_vs_allInstances_at_post_including': assumes "\x. \' oid = Some x \ x = Object" and "Type Object \ None" shows "(Type .allInstances()) - (\, \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\) + (\, \heap=\'(oid\Object), assocs=A\) = - ((Type .allInstances())->including(\ _. \\ drop (Type Object) \\)) - (\, \heap=\',assocs\<^sub>2=A, assocs\<^sub>3=B\)" -unfolding OclAllInstances_at_post_def + ((Type .allInstances())->including\<^sub>S\<^sub>e\<^sub>t(\ _. \\ drop (Type Object) \\)) + (\, \heap=\',assocs=A\)" +unfolding OclAllInstances_at_post_def by(rule state_update_vs_allInstances_generic_including'[OF snd_conv], insert assms) @@ -569,12 +539,12 @@ lemma state_update_vs_allInstances_at_post_including: assumes "\x. \' oid = Some x \ x = Object" and "Type Object \ None" shows "(Type .allInstances()) - (\, \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\) + (\, \heap=\'(oid\Object), assocs=A\) = ((\_. (Type .allInstances()) - (\, \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\))->including(\ _. \\ drop (Type Object) \\)) - (\, \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\)" -unfolding OclAllInstances_at_post_def + (\, \heap=\', assocs=A\))->including\<^sub>S\<^sub>e\<^sub>t(\ _. \\ drop (Type Object) \\)) + (\, \heap=\'(oid\Object), assocs=A\)" +unfolding OclAllInstances_at_post_def by(rule state_update_vs_allInstances_generic_including[OF snd_conv], insert assms) @@ -583,11 +553,11 @@ lemma state_update_vs_allInstances_at_post_noincluding': assumes "\x. \' oid = Some x \ x = Object" and "Type Object = None" shows "(Type .allInstances()) - (\, \heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\) + (\, \heap=\'(oid\Object), assocs=A\) = (Type .allInstances()) - (\, \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\)" -unfolding OclAllInstances_at_post_def + (\, \heap=\', assocs=A\)" +unfolding OclAllInstances_at_post_def by(rule state_update_vs_allInstances_generic_noincluding'[OF snd_conv], insert assms) theorem state_update_vs_allInstances_at_post_ntc: @@ -595,9 +565,9 @@ assumes oid_def: "oid\dom \'" and non_type_conform: "Type Object = None " and cp_ctxt: "cp P" and const_ctxt: "\X. const X \ const (P X)" -shows "((\, \heap=\'(oid\Object),assocs\<^sub>2=A,assocs\<^sub>3=B\) \ (P(Type .allInstances()))) = - ((\, \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\) \ (P(Type .allInstances())))" -unfolding OclAllInstances_at_post_def +shows "((\, \heap=\'(oid\Object),assocs=A\) \ (P(Type .allInstances()))) = + ((\, \heap=\', assocs=A\) \ (P(Type .allInstances())))" +unfolding OclAllInstances_at_post_def by(rule state_update_vs_allInstances_generic_ntc[OF snd_conv], insert assms) theorem state_update_vs_allInstances_at_post_tc: @@ -605,10 +575,10 @@ assumes oid_def: "oid\dom \'" and type_conform: "Type Object \ None " and cp_ctxt: "cp P" and const_ctxt: "\X. const X \ const (P X)" -shows "((\, \heap=\'(oid\Object),assocs\<^sub>2=A,assocs\<^sub>3=B\) \ (P(Type .allInstances()))) = - ((\, \heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\) \ (P((Type .allInstances()) - ->including(\ _. \(Type Object)\))))" -unfolding OclAllInstances_at_post_def +shows "((\, \heap=\'(oid\Object),assocs=A\) \ (P(Type .allInstances()))) = + ((\, \heap=\', assocs=A\) \ (P((Type .allInstances()) + ->including\<^sub>S\<^sub>e\<^sub>t(\ _. \(Type Object)\))))" +unfolding OclAllInstances_at_post_def by(rule state_update_vs_allInstances_generic_tc[OF snd_conv], insert assms) subsubsection{* OclAllInstances (@pre) *} @@ -627,28 +597,28 @@ by(rule OclAllInstances_generic_init_empty, simp) lemma represented_at_pre_objects_nonnull: -assumes A: "\ \ (((H::('\::object \ '\)).allInstances@pre()) ->includes(x))" +assumes A: "\ \ (((H::('\::object \ '\)).allInstances@pre()) ->includes\<^sub>S\<^sub>e\<^sub>t(x))" shows "\ \ not(x \ null)" by(rule represented_generic_objects_nonnull[OF A[simplified OclAllInstances_at_pre_def]]) lemma represented_at_pre_objects_defined: -assumes A: "\ \ (((H::('\::object \ '\)).allInstances@pre()) ->includes(x))" +assumes A: "\ \ (((H::('\::object \ '\)).allInstances@pre()) ->includes\<^sub>S\<^sub>e\<^sub>t(x))" shows "\ \ \ (H .allInstances@pre()) \ \ \ \ x" -unfolding OclAllInstances_at_pre_def +unfolding OclAllInstances_at_pre_def by(rule represented_generic_objects_defined[OF A[simplified OclAllInstances_at_pre_def]]) text{* One way to establish the actual presence of an object representation in a state is:*} lemma -assumes A: "\ \ H .allInstances@pre()->includes(x)" -shows "x \ \ (Some o H) ` ran (heap(fst \))" +assumes A: "\ \ H .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(x)" +shows "is_represented_in_state fst x H \" by(rule represented_generic_objects_in_state[OF A[simplified OclAllInstances_at_pre_def]]) lemma state_update_vs_allInstances_at_pre_empty: -shows "(\heap=empty, assocs\<^sub>2=A, assocs\<^sub>3=B\, \) \ Type .allInstances@pre() \ Set{}" -unfolding OclAllInstances_at_pre_def +shows "(\heap=empty, assocs=A\, \) \ Type .allInstances@pre() \ Set{}" +unfolding OclAllInstances_at_pre_def by(rule state_update_vs_allInstances_generic_empty[OF fst_conv]) text{* Here comes a couple of operational rules that allow to infer the value @@ -663,11 +633,11 @@ lemma state_update_vs_allInstances_at_pre_including': assumes "\x. \' oid = Some x \ x = Object" and "Type Object \ None" shows "(Type .allInstances@pre()) - (\heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\, \) + (\heap=\'(oid\Object), assocs=A\, \) = - ((Type .allInstances@pre())->including(\ _. \\ drop (Type Object) \\)) - (\heap=\',assocs\<^sub>2=A, assocs\<^sub>3=B\, \)" -unfolding OclAllInstances_at_pre_def + ((Type .allInstances@pre())->including\<^sub>S\<^sub>e\<^sub>t(\ _. \\ drop (Type Object) \\)) + (\heap=\',assocs=A\, \)" +unfolding OclAllInstances_at_pre_def by(rule state_update_vs_allInstances_generic_including'[OF fst_conv], insert assms) @@ -675,12 +645,12 @@ lemma state_update_vs_allInstances_at_pre_including: assumes "\x. \' oid = Some x \ x = Object" and "Type Object \ None" shows "(Type .allInstances@pre()) - (\heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\, \) + (\heap=\'(oid\Object), assocs=A\, \) = ((\_. (Type .allInstances@pre()) - (\heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\, \))->including(\ _. \\ drop (Type Object) \\)) - (\heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\, \)" -unfolding OclAllInstances_at_pre_def + (\heap=\', assocs=A\, \))->including\<^sub>S\<^sub>e\<^sub>t(\ _. \\ drop (Type Object) \\)) + (\heap=\'(oid\Object), assocs=A\, \)" +unfolding OclAllInstances_at_pre_def by(rule state_update_vs_allInstances_generic_including[OF fst_conv], insert assms) @@ -689,11 +659,11 @@ lemma state_update_vs_allInstances_at_pre_noincluding': assumes "\x. \' oid = Some x \ x = Object" and "Type Object = None" shows "(Type .allInstances@pre()) - (\heap=\'(oid\Object), assocs\<^sub>2=A, assocs\<^sub>3=B\, \) + (\heap=\'(oid\Object), assocs=A\, \) = (Type .allInstances@pre()) - (\heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\, \)" -unfolding OclAllInstances_at_pre_def + (\heap=\', assocs=A\, \)" +unfolding OclAllInstances_at_pre_def by(rule state_update_vs_allInstances_generic_noincluding'[OF fst_conv], insert assms) theorem state_update_vs_allInstances_at_pre_ntc: @@ -701,9 +671,9 @@ assumes oid_def: "oid\dom \'" and non_type_conform: "Type Object = None " and cp_ctxt: "cp P" and const_ctxt: "\X. const X \ const (P X)" -shows "((\heap=\'(oid\Object),assocs\<^sub>2=A,assocs\<^sub>3=B\, \) \ (P(Type .allInstances@pre()))) = - ((\heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\, \) \ (P(Type .allInstances@pre())))" -unfolding OclAllInstances_at_pre_def +shows "((\heap=\'(oid\Object),assocs=A\, \) \ (P(Type .allInstances@pre()))) = + ((\heap=\', assocs=A\, \) \ (P(Type .allInstances@pre())))" +unfolding OclAllInstances_at_pre_def by(rule state_update_vs_allInstances_generic_ntc[OF fst_conv], insert assms) theorem state_update_vs_allInstances_at_pre_tc: @@ -711,10 +681,10 @@ assumes oid_def: "oid\dom \'" and type_conform: "Type Object \ None " and cp_ctxt: "cp P" and const_ctxt: "\X. const X \ const (P X)" -shows "((\heap=\'(oid\Object),assocs\<^sub>2=A,assocs\<^sub>3=B\, \) \ (P(Type .allInstances@pre()))) = - ((\heap=\', assocs\<^sub>2=A, assocs\<^sub>3=B\, \) \ (P((Type .allInstances@pre()) - ->including(\ _. \(Type Object)\))))" -unfolding OclAllInstances_at_pre_def +shows "((\heap=\'(oid\Object),assocs=A\, \) \ (P(Type .allInstances@pre()))) = + ((\heap=\', assocs=A\, \) \ (P((Type .allInstances@pre()) + ->including\<^sub>S\<^sub>e\<^sub>t(\ _. \(Type Object)\))))" +unfolding OclAllInstances_at_pre_def by(rule state_update_vs_allInstances_generic_tc[OF fst_conv], insert assms) subsubsection{* @post or @pre *} @@ -725,25 +695,25 @@ and valid_x: "\ \(\ (x :: ('\::object,'\::ob and valid_y: "\ \(\ y)" and oid_preserve: "\x. x \ ran (heap(fst \)) \ x \ ran (heap(snd \)) \ oid_of (H x) = oid_of x" -and xy_together: "\ \ ((H .allInstances()->includes(x) and H .allInstances()->includes(y)) or - (H .allInstances@pre()->includes(x) and H .allInstances@pre()->includes(y)))" +and xy_together: "\ \ ((H .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(x) and H .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(y)) or + (H .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(x) and H .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(y)))" (* x and y must be object representations that exist in either the pre or post state *) shows "(\ \ (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x y)) = (\ \ (x \ y))" proof - - have at_post_def : "\x. \ \ \ x \ \ \ \ (H .allInstances()->includes(x))" + have at_post_def : "\x. \ \ \ x \ \ \ \ (H .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(x))" apply(simp add: OclIncludes_def OclValid_def OclAllInstances_at_post_defined[simplified OclValid_def]) by(subst cp_defined, simp) - have at_pre_def : "\x. \ \ \ x \ \ \ \ (H .allInstances@pre()->includes(x))" + have at_pre_def : "\x. \ \ \ x \ \ \ \ (H .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(x))" apply(simp add: OclIncludes_def OclValid_def OclAllInstances_at_pre_defined[simplified OclValid_def]) by(subst cp_defined, simp) - have F: "Rep_Set_0 (Abs_Set_0 \\Some ` (H ` ran (heap (fst \)) - {None})\\) = + have F: "Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\Some ` (H ` ran (heap (fst \)) - {None})\\) = \\Some ` (H ` ran (heap (fst \)) - {None})\\" - by(subst OCL_lib.Set_0.Abs_Set_0_inverse,simp_all add: bot_option_def) - have F': "Rep_Set_0 (Abs_Set_0 \\Some ` (H ` ran (heap (snd \)) - {None})\\) = + by(subst Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse,simp_all add: bot_option_def) + have F': "Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\Some ` (H ` ran (heap (snd \)) - {None})\\) = \\Some ` (H ` ran (heap (snd \)) - {None})\\" - by(subst OCL_lib.Set_0.Abs_Set_0_inverse,simp_all add: bot_option_def) + by(subst Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse,simp_all add: bot_option_def) show ?thesis apply(rule StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_vs_StrongEq'[OF WFF valid_x valid_y, where H = "Some o H"]) apply(subst oid_preserve[symmetric], simp, simp add: oid_of_option_def) @@ -817,9 +787,9 @@ both states), with the exception of those objects. *} definition OclIsModifiedOnly ::"('\::object,'\::{null,object})Set \ '\ Boolean" ("_->oclIsModifiedOnly'(')") where "X->oclIsModifiedOnly() \ (\(\,\'). - let X' = (oid_of ` \\Rep_Set_0(X(\,\'))\\); + let X' = (oid_of ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(X(\,\'))\\); S = ((dom (heap \) \ dom (heap \')) - X') - in if (\ X) (\,\') = true (\,\') \ (\x\\\Rep_Set_0(X(\,\'))\\. x \ null) + in if (\ X) (\,\') = true (\,\') \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(X(\,\'))\\. x \ null) then \\\ x \ S. (heap \) x = (heap \') x\\ else invalid (\,\'))" @@ -832,7 +802,7 @@ lemma "null->oclIsModifiedOnly() = invalid" by(simp add: OclIsModifiedOnly_def) lemma - assumes X_null : "\ \ X->includes(null)" + assumes X_null : "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(null)" shows "\ \ X->oclIsModifiedOnly() \ invalid" apply(insert X_null, simp add : OclIncludes_def OclIsModifiedOnly_def StrongEq_def OclValid_def true_def) @@ -872,58 +842,59 @@ subsection{* Framing Theorem *} lemma all_oid_diff: assumes def_x : "\ \ \ x" assumes def_X : "\ \ \ X" - assumes def_X' : "\x. x \ \\Rep_Set_0 (X \)\\ \ x \ null" + assumes def_X' : "\x. x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ x \ null" defines "P \ (\a. not (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x a))" - shows "(\ \ X->forAll(a| P a)) = (oid_of (x \) \ oid_of ` \\Rep_Set_0 (X \)\\)" + shows "(\ \ X->forAll\<^sub>S\<^sub>e\<^sub>t(a| P a)) = (oid_of (x \) \ oid_of ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\)" proof - - have P_null_bot: "\b. b = null \ b = \ \ - \ (\x\\\Rep_Set_0 (X \)\\. P (\(_:: 'a state \ 'a state). x) \ = b \)" + have P_null_bot: "\b. b = null \ b = \ \ + \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\(_:: 'a state \ 'a state). x) \ = b \)" apply(erule disjE) apply(simp, rule ballI, simp add: P_def StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def, rename_tac x', subst cp_OclNot, simp, subgoal_tac "x \ \ null \ x' \ null", simp, simp add: OclNot_def null_fun_def null_option_def bot_option_def bot_fun_def invalid_def, - ( metis def_X' def_x foundation17 - | (metis OCL_core.bot_fun_def OclValid_def Set_inv_lemma def_X def_x defined_def valid_def, - metis def_X' def_x foundation17)))+ + ( metis def_X' def_x foundation16[THEN iffD1] + | (metis bot_fun_def OclValid_def Set_inv_lemma def_X def_x defined_def valid_def, + metis def_X' def_x foundation16[THEN iffD1])))+ done + have not_inj : "\x y. ((not x) \ = (not y) \) = (x \ = y \)" by (metis foundation21 foundation22) - have P_false : "\x\\\Rep_Set_0 (X \)\\. P (\_. x) \ = false \ \ - oid_of (x \) \ oid_of ` \\Rep_Set_0 (X \)\\" + have P_false : "\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ = false \ \ + oid_of (x \) \ oid_of ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" apply(erule bexE, rename_tac x') apply(simp add: P_def) apply(simp only: OclNot3[symmetric], simp only: not_inj) apply(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: split_if_asm) apply(subgoal_tac "x \ \ null \ x' \ null", simp) - apply (metis (mono_tags) OCL_core.drop.simps def_x foundation17 true_def) + apply (metis (mono_tags) drop.simps def_x foundation16[THEN iffD1] true_def) by(simp add: invalid_def bot_option_def true_def)+ - have P_true : "\x\\\Rep_Set_0 (X \)\\. P (\_. x) \ = true \ \ - oid_of (x \) \ oid_of ` \\Rep_Set_0 (X \)\\" - apply(subgoal_tac "\x'\\\Rep_Set_0 (X \)\\. oid_of x' \ oid_of (x \)") + have P_true : "\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ = true \ \ + oid_of (x \) \ oid_of ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + apply(subgoal_tac "\x'\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. oid_of x' \ oid_of (x \)") apply (metis imageE) apply(rule ballI, drule_tac x = "x'" in ballE) prefer 3 apply assumption apply(simp add: P_def) apply(simp only: OclNot4[symmetric], simp only: not_inj) apply(simp add: StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def false_def split: split_if_asm) apply(subgoal_tac "x \ \ null \ x' \ null", simp) - apply (metis def_X' def_x foundation17) + apply (metis def_X' def_x foundation16[THEN iffD1]) by(simp add: invalid_def bot_option_def false_def)+ - have bool_split : "\x\\\Rep_Set_0 (X \)\\. P (\_. x) \ \ null \ \ - \x\\\Rep_Set_0 (X \)\\. P (\_. x) \ \ \ \ \ - \x\\\Rep_Set_0 (X \)\\. P (\_. x) \ \ false \ \ - \x\\\Rep_Set_0 (X \)\\. P (\_. x) \ = true \" + have bool_split : "\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ \ null \ \ + \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ \ \ \ \ + \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ \ false \ \ + \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ = true \" apply(rule ballI) apply(drule_tac x = x in ballE) prefer 3 apply assumption apply(drule_tac x = x in ballE) prefer 3 apply assumption apply(drule_tac x = x in ballE) prefer 3 apply assumption - apply (metis (full_types) OCL_core.bot_fun_def OclNot4 OclValid_def foundation16 foundation18' + apply (metis (full_types) bot_fun_def OclNot4 OclValid_def foundation16 foundation9 not_inj null_fun_def) by(fast+) @@ -934,32 +905,32 @@ proof - qed theorem framing: - assumes modifiesclause:"\ \ (X->excluding(x))->oclIsModifiedOnly()" - and oid_is_typerepr : "\ \ X->forAll(a| not (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x a))" + assumes modifiesclause:"\ \ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x))->oclIsModifiedOnly()" + and oid_is_typerepr : "\ \ X->forAll\<^sub>S\<^sub>e\<^sub>t(a| not (StrictRefEq\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x a))" shows "\ \ (x @pre P \ (x @post P))" apply(case_tac "\ \ \ x") proof - show "\ \ \ x \ ?thesis" proof - assume def_x : "\ \ \ x" show ?thesis proof - have def_X : "\ \ \ X" - apply(insert oid_is_typerepr, simp add: OclForall_def OclValid_def split: split_if_asm) + apply(insert oid_is_typerepr, simp add: UML_Set.OclForall_def OclValid_def split: split_if_asm) by(simp add: bot_option_def true_def) - have def_X' : "\x. x \ \\Rep_Set_0 (X \)\\ \ x \ null" + have def_X' : "\x. x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ x \ null" apply(insert modifiesclause, simp add: OclIsModifiedOnly_def OclValid_def split: split_if_asm) apply(case_tac \, simp split: split_if_asm) - apply(simp add: OclExcluding_def split: split_if_asm) - apply(subst (asm) (2) Abs_Set_0_inverse) + apply(simp add: UML_Set.OclExcluding_def split: split_if_asm) + apply(subst (asm) (2) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) apply(simp, (rule disjI2)+) apply (metis (hide_lams, mono_tags) Diff_iff Set_inv_lemma def_X) apply(simp) apply(erule ballE[where P = "\x. x \ null"]) apply(assumption) apply(simp) - apply (metis (hide_lams, no_types) def_x foundation17) + apply (metis (hide_lams, no_types) def_x foundation16[THEN iffD1]) apply (metis (hide_lams, no_types) OclValid_def def_X def_x foundation20 OclExcluding_valid_args_valid OclExcluding_valid_args_valid'') by(simp add: invalid_def bot_option_def) - have oid_is_typerepr : "oid_of (x \) \ oid_of ` \\Rep_Set_0 (X \)\\" + have oid_is_typerepr : "oid_of (x \) \ oid_of ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" by(rule all_oid_diff[THEN iffD1, OF def_x def_X def_X' oid_is_typerepr]) show ?thesis @@ -969,9 +940,9 @@ theorem framing: apply(rule_tac f = "\x. P \x\" in arg_cong) apply(insert modifiesclause[simplified OclIsModifiedOnly_def OclValid_def]) apply(case_tac \, rename_tac \ \', simp split: split_if_asm) - apply(subst (asm) (2) OclExcluding_def) + apply(subst (asm) (2) UML_Set.OclExcluding_def) apply(drule foundation5[simplified OclValid_def true_def], simp) - apply(subst (asm) Abs_Set_0_inverse, simp) + apply(subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp) apply(rule disjI2)+ apply (metis (hide_lams, no_types) DiffD1 OclValid_def Set_inv_lemma def_x foundation16 foundation18') @@ -982,8 +953,7 @@ theorem framing: apply(simp add: invalid_def bot_option_def)+ by blast qed qed - apply_end(simp add: OclSelf_at_post_def OclSelf_at_pre_def OclValid_def StrongEq_def true_def)+ -qed +qed(simp add: OclSelf_at_post_def OclSelf_at_pre_def OclValid_def StrongEq_def true_def)+ text{* As corollary, the framing property can be expressed with only the strong equality @@ -991,17 +961,17 @@ as comparison operator. *} theorem framing': assumes wff : "WFF \" - assumes modifiesclause:"\ \ (X->excluding(x))->oclIsModifiedOnly()" - and oid_is_typerepr : "\ \ X->forAll(a| not (x \ a))" + assumes modifiesclause:"\ \ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x))->oclIsModifiedOnly()" + and oid_is_typerepr : "\ \ X->forAll\<^sub>S\<^sub>e\<^sub>t(a| not (x \ a))" and oid_preserve: "\x. x \ ran (heap(fst \)) \ x \ ran (heap(snd \)) \ oid_of (H x) = oid_of x" and xy_together: - "\ \ X->forAll(y | (H .allInstances()->includes(x) and H .allInstances()->includes(y)) or - (H .allInstances@pre()->includes(x) and H .allInstances@pre()->includes(y)))" + "\ \ X->forAll\<^sub>S\<^sub>e\<^sub>t(y | (H .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(x) and H .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(y)) or + (H .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(x) and H .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(y)))" shows "\ \ (x @pre P \ (x @post P))" proof - have def_X : "\ \ \ X" - apply(insert oid_is_typerepr, simp add: OclForall_def OclValid_def split: split_if_asm) + apply(insert oid_is_typerepr, simp add: UML_Set.OclForall_def OclValid_def split: split_if_asm) by(simp add: bot_option_def true_def) show ?thesis apply(case_tac "\ \ \ x", drule foundation20) @@ -1051,4 +1021,245 @@ by(simp add: OclIsMaintained_def OclSelf_at_pre_def OclSelf_at_post_def lemma framing_same_state: "(\, \) \ (x @pre H \ (x @post H))" by(simp add: OclSelf_at_pre_def OclSelf_at_post_def OclValid_def StrongEq_def) +section{* Accessors on Object *} +subsection{* Definition *} + +definition "select_object mt incl smash deref l = smash (foldl incl mt (map deref l)) + (* smash returns null with mt in input (in this case, object contains null pointer) *)" + +text{* The continuation @{text f} is usually instantiated with a smashing +function which is either the identity @{term id} or, for \inlineocl{0..1} cardinalities +of associations, the @{term OclANY}-selector which also handles the +@{term null}-cases appropriately. A standard use-case for this combinator +is for example: *} +term "(select_object mtSet UML_Set.OclIncluding UML_Set.OclANY f l oid )::('\, 'a::null)val" + +definition "select_object\<^sub>S\<^sub>e\<^sub>t = select_object mtSet UML_Set.OclIncluding id" +definition "select_object_any0\<^sub>S\<^sub>e\<^sub>t f s_set = UML_Set.OclANY (select_object\<^sub>S\<^sub>e\<^sub>t f s_set)" +definition "select_object_any\<^sub>S\<^sub>e\<^sub>t f s_set = + (let s = select_object\<^sub>S\<^sub>e\<^sub>t f s_set in + if s->size\<^sub>S\<^sub>e\<^sub>t() \ \ then + s->any\<^sub>S\<^sub>e\<^sub>t() + else + \ + endif)" +definition "select_object\<^sub>S\<^sub>e\<^sub>q = select_object mtSequence UML_Sequence.OclIncluding id" +definition "select_object_any\<^sub>S\<^sub>e\<^sub>q f s_set = UML_Sequence.OclANY (select_object\<^sub>S\<^sub>e\<^sub>q f s_set)" +definition "select_object\<^sub>P\<^sub>a\<^sub>i\<^sub>r f1 f2 = (\(a,b). OclPair (f1 a) (f2 b))" + +subsection{* Validity and Definedness Properties *} + +lemma select_fold_exec\<^sub>S\<^sub>e\<^sub>q: + assumes "list_all (\f. (\ \ \ f)) l" + shows "\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (foldl UML_Sequence.OclIncluding Sequence{} l \)\\ = List.map (\f. f \) l" +proof - + have def_fold: "\l. list_all (\f. \ \ \ f) l \ + \ \ (\ foldl UML_Sequence.OclIncluding Sequence{} l)" + apply(rule rev_induct[where P = "\l. list_all (\f. (\ \ \ f)) l \ \ \ (\ foldl UML_Sequence.OclIncluding Sequence{} l)", THEN mp], simp) + by(simp add: foundation10') + show ?thesis + apply(rule rev_induct[where P = "\l. list_all (\f. (\ \ \ f)) l \ \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (foldl UML_Sequence.OclIncluding Sequence{} l \)\\ = List.map (\f. f \) l", THEN mp], simp) + apply(simp add: mtSequence_def) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, (simp | intro impI)+) + apply(simp add: UML_Sequence.OclIncluding_def, intro conjI impI) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, (rule disjI2)+) + apply(simp add: list_all_iff foundation18', simp) + apply(subst (asm) def_fold[simplified (no_asm) OclValid_def], simp, simp add: OclValid_def) + by (rule assms) +qed + +lemma select_fold_exec\<^sub>S\<^sub>e\<^sub>t: + assumes "list_all (\f. (\ \ \ f)) l" + shows "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (foldl UML_Set.OclIncluding Set{} l \)\\ = set (List.map (\f. f \) l)" +proof - + have def_fold: "\l. list_all (\f. \ \ \ f) l \ + \ \ (\ foldl UML_Set.OclIncluding Set{} l)" + apply(rule rev_induct[where P = "\l. list_all (\f. (\ \ \ f)) l \ \ \ (\ foldl UML_Set.OclIncluding Set{} l)", THEN mp], simp) + by(simp add: foundation10') + show ?thesis + apply(rule rev_induct[where P = "\l. list_all (\f. (\ \ \ f)) l \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (foldl UML_Set.OclIncluding Set{} l \)\\ = set (List.map (\f. f \) l)", THEN mp], simp) + apply(simp add: mtSet_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, (simp | intro impI)+) + apply(simp add: UML_Set.OclIncluding_def, intro conjI impI) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, (rule disjI2)+) + apply(simp add: list_all_iff foundation18', simp) + apply(subst (asm) def_fold[simplified (no_asm) OclValid_def], simp, simp add: OclValid_def) + by (rule assms) +qed + +lemma fold_val_elem\<^sub>S\<^sub>e\<^sub>q: + assumes "\ \ \ (foldl UML_Sequence.OclIncluding Sequence{} (List.map (f p) s_set))" + shows "list_all (\x. (\ \ \ (f p x))) s_set" + apply(rule rev_induct[where P = "\s_set. \ \ \ foldl UML_Sequence.OclIncluding Sequence{} (List.map (f p) s_set) \ list_all (\x. \ \ \ f p x) s_set", THEN mp]) + apply(simp, auto) + apply (metis (hide_lams, mono_tags) UML_Sequence.OclIncluding.def_valid_then_def UML_Sequence.OclIncluding.defined_args_valid foundation20)+ +by(simp add: assms) + +lemma fold_val_elem\<^sub>S\<^sub>e\<^sub>t: + assumes "\ \ \ (foldl UML_Set.OclIncluding Set{} (List.map (f p) s_set))" + shows "list_all (\x. (\ \ \ (f p x))) s_set" + apply(rule rev_induct[where P = "\s_set. \ \ \ foldl UML_Set.OclIncluding Set{} (List.map (f p) s_set) \ list_all (\x. \ \ \ f p x) s_set", THEN mp]) + apply(simp, auto) + apply (metis (hide_lams, mono_tags) foundation10' foundation20)+ +by(simp add: assms) + +lemma select_object_any_defined\<^sub>S\<^sub>e\<^sub>q: + assumes def_sel: "\ \ \ (select_object_any\<^sub>S\<^sub>e\<^sub>q f s_set)" + shows "s_set \ []" + apply(insert def_sel, case_tac s_set) + apply(simp add: select_object_any\<^sub>S\<^sub>e\<^sub>q_def UML_Sequence.OclANY_def select_object\<^sub>S\<^sub>e\<^sub>q_def select_object_def + defined_def OclValid_def + false_def true_def bot_fun_def bot_option_def + split: split_if_asm) + apply(simp add: mtSequence_def, subst (asm) Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, simp) +by(simp) + +lemma (*select_object_any_defined\<^sub>S\<^sub>e\<^sub>t:*) + assumes def_sel: "\ \ \ (select_object_any0\<^sub>S\<^sub>e\<^sub>t f s_set)" + shows "s_set \ []" + apply(insert def_sel, case_tac s_set) + apply(simp add: select_object_any0\<^sub>S\<^sub>e\<^sub>t_def UML_Sequence.OclANY_def select_object\<^sub>S\<^sub>e\<^sub>t_def select_object_def + defined_def OclValid_def + false_def true_def bot_fun_def bot_option_def + split: split_if_asm) +by(simp) + +lemma select_object_any_defined\<^sub>S\<^sub>e\<^sub>t: + assumes def_sel: "\ \ \ (select_object_any\<^sub>S\<^sub>e\<^sub>t f s_set)" + shows "s_set \ []" + apply(insert def_sel, case_tac s_set) + apply(simp add: select_object_any\<^sub>S\<^sub>e\<^sub>t_def UML_Sequence.OclANY_def select_object\<^sub>S\<^sub>e\<^sub>t_def select_object_def + defined_def OclValid_def + false_def true_def bot_fun_def bot_option_def + OclInt0_def OclInt1_def StrongEq_def OclIf_def null_fun_def null_option_def + split: split_if_asm) +by(simp) + +lemma select_object_any_exec0\<^sub>S\<^sub>e\<^sub>q: + assumes def_sel: "\ \ \ (select_object_any\<^sub>S\<^sub>e\<^sub>q f s_set)" + shows "\ \ (select_object_any\<^sub>S\<^sub>e\<^sub>q f s_set \ f (hd s_set))" + apply(insert def_sel[simplified foundation16], + simp add: select_object_any\<^sub>S\<^sub>e\<^sub>q_def foundation22 UML_Sequence.OclANY_def split: split_if_asm) + apply(case_tac "\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (select_object\<^sub>S\<^sub>e\<^sub>q f s_set \)\\", simp add: bot_option_def, simp) + apply(simp add: select_object\<^sub>S\<^sub>e\<^sub>q_def select_object_def) + apply(subst (asm) select_fold_exec\<^sub>S\<^sub>e\<^sub>q) + apply(rule fold_val_elem\<^sub>S\<^sub>e\<^sub>q, simp add: foundation18' invalid_def) + apply(simp) +by(drule arg_cong[where f = hd], subst (asm) hd_map, simp add: select_object_any_defined\<^sub>S\<^sub>e\<^sub>q[OF def_sel], simp) + +lemma select_object_any_exec\<^sub>S\<^sub>e\<^sub>q: + assumes def_sel: "\ \ \ (select_object_any\<^sub>S\<^sub>e\<^sub>q f s_set)" + shows "\e. List.member s_set e \ (\ \ (select_object_any\<^sub>S\<^sub>e\<^sub>q f s_set \ f e))" + apply(insert select_object_any_exec0\<^sub>S\<^sub>e\<^sub>q[OF def_sel]) + apply(rule exI[where x = "hd s_set"], simp) + apply(case_tac s_set, simp add: select_object_any_defined\<^sub>S\<^sub>e\<^sub>q[OF def_sel]) +by (metis list.sel member_rec(1)) + +lemma (*select_object_any_exec\<^sub>S\<^sub>e\<^sub>t:*) + assumes def_sel: "\ \ \ (select_object_any0\<^sub>S\<^sub>e\<^sub>t f s_set)" + shows "\ e. List.member s_set e \ (\ \ (select_object_any0\<^sub>S\<^sub>e\<^sub>t f s_set \ f e))" +proof - + have list_all_map: "\P f l. list_all P (List.map f l) = list_all (P o f) l" + by(induct_tac l, simp_all) + + fix z + show ?thesis + when "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (select_object\<^sub>S\<^sub>e\<^sub>t f s_set \)\\ = z" + apply(insert that def_sel[simplified foundation16], + simp add: select_object_any0\<^sub>S\<^sub>e\<^sub>t_def foundation22 UML_Set.OclANY_def null_fun_def split: split_if_asm) + + apply(simp add: select_object\<^sub>S\<^sub>e\<^sub>t_def select_object_def) + apply(subst (asm) select_fold_exec\<^sub>S\<^sub>e\<^sub>t) + apply(rule fold_val_elem\<^sub>S\<^sub>e\<^sub>t, simp add: OclValid_def) + apply(simp add: comp_def) + + apply(case_tac s_set, simp, simp add: false_def true_def, simp) + + proof - fix a l + show "insert (f a \) ((\x. f x \) ` set l) = z \ + \e. List.member (a # l) e \ (SOME y. y \ z) = f e \" + apply(rule list.induct[where P = "\l. \z a. insert (f a \) ((\x. f x \) ` set l) = z \ + (\e. List.member (a # l) e \ ((SOME y. y \ z) = f e \))", THEN spec, THEN spec, THEN mp], intro allI impI) + proof - fix x xa show "insert (f xa \) ((\x. f x \) ` set []) = x \ \e. List.member [xa] e \ (SOME y. y \ x) = f e \" + apply(rule exI[where x = xa], simp add: List.member_def) + apply(subst some_equality[where a = "f xa \"]) + apply (metis (mono_tags) insertI1) + apply (metis (mono_tags) empty_iff insert_iff) + by(simp) + apply_end(intro allI impI, simp) + fix x list xa xb + show " \x. \e. List.member (x # list) e \ (SOME y. y = f x \ \ y \ (\x. f x \) ` set list) = f e \ \ + insert (f xb \) (insert (f x \) ((\x. f x \) ` set list)) = xa \ + \e. List.member (xb # x # list) e \ (SOME y. y \ xa) = f e \" + apply(case_tac "x = xb", simp) + apply(erule allE[where x = xb]) + apply(erule exE) + proof - fix e show "insert (f xb \) ((\x. f x \) ` set list) = xa \ + x = xb \ + List.member (xb # list) e \ (SOME y. y = f xb \ \ y \ (\x. f x \) ` set list) = f e \ \ + \e. List.member (xb # xb # list) e \ (SOME y. y \ xa) = f e \" + apply(rule exI[where x = e], auto) + by (metis member_rec(1)) + apply_end(case_tac "List.member list x") + apply_end(erule allE[where x = xb]) + apply_end(erule exE) + fix e + let ?P = "\y. y = f xb \ \ y \ (\x. f x \) ` set list" + show "insert (f xb \) (insert (f x \) ((\x. f x \) ` set list)) = xa \ + x \ xb \ + List.member list x \ + List.member (xb # list) e \ (SOME y. y = f xb \ \ y \ (\x. f x \) ` set list) = f e \ \ + \e. List.member (xb # x # list) e \ (SOME y. y \ xa) = f e \" + apply(rule exI[where x = e], auto) + apply (metis member_rec(1)) + + apply(subgoal_tac "?P (f e \)") + prefer 2 + apply(case_tac "xb = e", simp) + apply (metis (mono_tags) image_eqI in_set_member member_rec(1)) + + apply(rule someI2[where a = "f e \"]) + apply(erule disjE, simp)+ + apply(rule disjI2)+ apply(simp) +oops + +lemma select_object_any_exec\<^sub>S\<^sub>e\<^sub>t: + assumes def_sel: "\ \ \ (select_object_any\<^sub>S\<^sub>e\<^sub>t f s_set)" + shows "\ e. List.member s_set e \ (\ \ (select_object_any\<^sub>S\<^sub>e\<^sub>t f s_set \ f e))" +proof - + have card_singl: "\A a. finite A \ card (insert a A) = 1 \ A \ {a}" + by (auto, metis Suc_inject card_Suc_eq card_eq_0_iff insert_absorb insert_not_empty singleton_iff) + + have list_same: "\f s_set z' x. f ` set s_set = {z'} \ List.member s_set x \ f x = z'" + by (metis (full_types) empty_iff imageI in_set_member insert_iff) + + fix z + show ?thesis + when "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (select_object\<^sub>S\<^sub>e\<^sub>t f s_set \)\\ = z" + apply(insert that def_sel[simplified foundation16], + simp add: select_object_any\<^sub>S\<^sub>e\<^sub>t_def foundation22 + Let_def null_fun_def bot_fun_def OclIf_def + split: split_if_asm) + apply(simp add: StrongEq_def OclInt1_def true_def UML_Set.OclSize_def + bot_option_def UML_Set.OclANY_def null_fun_def + split: split_if_asm) + apply(subgoal_tac "\z'. z = {z'}") + prefer 2 + apply(rule finite.cases[where a = z], simp, simp, simp) + apply(rule card_singl, simp, simp) + apply(erule exE, clarsimp) + + apply(simp add: select_object\<^sub>S\<^sub>e\<^sub>t_def select_object_def) + apply(subst (asm) select_fold_exec\<^sub>S\<^sub>e\<^sub>t) + apply(rule fold_val_elem\<^sub>S\<^sub>e\<^sub>t, simp add: OclValid_def true_def) + apply(simp add: comp_def) + + apply(case_tac s_set, simp) + proof - fix z' a list show "(\x. f x \) ` set s_set = {z'} \ s_set = a # list \ \e. List.member s_set e \ z' = f e \" + apply(drule list_same[where x1 = a]) + apply (metis member_rec(1)) + by (metis (hide_lams, mono_tags) ListMem_iff elem in_set_member) + qed +qed blast+ + end diff --git a/src/UML_Tools.thy b/src/UML_Tools.thy new file mode 100644 index 0000000..5b6f728 --- /dev/null +++ b/src/UML_Tools.thy @@ -0,0 +1,137 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Tools.thy --- + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +(* < *) +theory UML_Tools +imports UML_Logic +begin + + +lemmas substs1 = StrongEq_L_subst2_rev + foundation15[THEN iffD2, THEN StrongEq_L_subst2_rev] + foundation7'[THEN iffD2, THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst2_rev]] + foundation14[THEN iffD2, THEN StrongEq_L_subst2_rev] + foundation13[THEN iffD2, THEN StrongEq_L_subst2_rev] + +lemmas substs2 = StrongEq_L_subst3_rev + foundation15[THEN iffD2, THEN StrongEq_L_subst3_rev] + foundation7'[THEN iffD2, THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst3_rev]] + foundation14[THEN iffD2, THEN StrongEq_L_subst3_rev] + foundation13[THEN iffD2, THEN StrongEq_L_subst3_rev] + +lemmas substs4 = StrongEq_L_subst4_rev + foundation15[THEN iffD2, THEN StrongEq_L_subst4_rev] + foundation7'[THEN iffD2, THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst4_rev]] + foundation14[THEN iffD2, THEN StrongEq_L_subst4_rev] + foundation13[THEN iffD2, THEN StrongEq_L_subst4_rev] + + +lemmas substs = substs1 substs2 substs4 [THEN iffD2] substs4 +thm substs +ML{* +fun ocl_subst_asm_tac ctxt = FIRST'(map (fn C => (eresolve0_tac [C]) THEN' (simp_tac ctxt)) + @{thms "substs"}) + +val ocl_subst_asm = fn ctxt => SIMPLE_METHOD (ocl_subst_asm_tac ctxt 1); + +val _ = Theory.setup + (Method.setup (Binding.name "ocl_subst_asm") + (Scan.succeed (ocl_subst_asm)) + "ocl substition step") + +*} + +lemma test1 : "\ \ A \ \ \ (A and B \ B)" +apply(tactic "ocl_subst_asm_tac @{context} 1") +apply(simp) +done + +lemma test2 : "\ \ A \ \ \ (A and B \ B)" +by(ocl_subst_asm, simp) + +lemma test3 : "\ \ A \ \ \ (A and A)" +by(ocl_subst_asm, simp) + +lemma test4 : "\ \ not A \ \ \ (A and B \ false)" +by(ocl_subst_asm, simp) + +lemma test5 : "\ \ (A \ null) \ \ \ (B \ null) \ \ (\ \ (A and B))" +by(ocl_subst_asm,ocl_subst_asm,simp) + +lemma test6 : "\ \ not A \ \ (\ \ (A and B))" +by(ocl_subst_asm, simp) + +lemma test7 : "\ (\ \ (\ A)) \ \ \ (not B) \ \ (\ \ (A and B))" +by(ocl_subst_asm,ocl_subst_asm,simp) + + + + + +(* a proof that shows that not everything is humpty dumpty ... *) +lemma X: "\ (\ \ (invalid and B))" +apply(insert foundation8[of "\" "B"], elim disjE, + simp add:defined_bool_split, elim disjE) +apply(ocl_subst_asm, simp) +apply(ocl_subst_asm, simp) +apply(ocl_subst_asm, simp) +apply(ocl_subst_asm, simp) +done + +(* easier is: *) +(* just to show the power of this extremely useful foundational rule:*) +lemma X': "\ (\ \ (invalid and B))" +by(simp add:foundation10') +lemma Y: "\ (\ \ (null and B))" +by(simp add: foundation10') +lemma Z: "\ (\ \ (false and B))" +by(simp add: foundation10') +lemma Z': "(\ \ (true and B)) = (\ \ B)" +by(simp) + + +end + +(* > *) diff --git a/src/UML_Types.thy b/src/UML_Types.thy new file mode 100644 index 0000000..fd5dfbc --- /dev/null +++ b/src/UML_Types.thy @@ -0,0 +1,653 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Types.thy --- Types definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +chapter{* Formalization I: OCL Types and Core Definitions \label{sec:focl-types}*} + +theory UML_Types +imports Transcendental +keywords "Assert" :: thy_decl + and "Assert_local" :: thy_decl +begin + +section{* Preliminaries *} +subsection{* Notations for the Option Type *} + +text{* + First of all, we will use a more compact notation for the library + option type which occur all over in our definitions and which will make + the presentation more like a textbook: +*} + +no_notation ceiling ("\_\") (* For Real Numbers only ... Otherwise has unfortunate side-effects on syntax. *) +no_notation floor ("\_\") (* For Real Numbers only ... Otherwise has unfortunate side-effects on syntax. *) + +type_notation option ("\_\\<^sub>\") (* NOTE: "_\<^sub>\" also works *) +notation Some ("\(_)\") +notation None ("\") + +text{* These commands introduce an alternative, more compact notation for the type constructor + @{typ "'\ option"}, namely @{typ "\'\\\<^sub>\"}. Furthermore, the constructors @{term "Some X"} and + @{term "None"} of the type @{typ "'\ option"}, namely @{term "\X\"} and @{term "\"}. *} + +text{* + The following function (corresponding to @{term the} in the Isabelle/HOL library) + is defined as the inverse of the injection @{term Some}. +*} +fun drop :: "'\ option \ '\" ("\(_)\") +where drop_lift[simp]: "\\v\\ = v" + +text{* The definitions for the constants and operations based on functions +will be geared towards a format that Isabelle can check to be a ``conservative'' +(\ie, logically safe) axiomatic definition. By introducing an explicit +interpretation function (which happens to be defined just as the identity +since we are using a shallow embedding of OCL into HOL), all these definitions +can be rewritten into the conventional semantic textbook format. +To say it in other words: The interpretation function @{text Sem} as defined +below is just a textual marker for presentation purposes, i.e. intended for readers +used to conventional textbook notations on semantics. Since we use a ``shallow embedding'', +i.e. since we represent the syntax of OCL directly by HOL constants, the interpretation function +is semantically not only superfluous, but from an Isabelle perspective strictly in +the way for certain consistency checks performed by the definitional packages. +*} + +definition Sem :: "'a \ 'a" ("I\_\") +where "I\x\ \ x" + + +subsection{* Common Infrastructure for all OCL Types \label{sec:focl-common-types}*} + +text {* In order to have the possibility to nest collection types, + such that we can give semantics to expressions like @{text "Set{Set{\},null}"}, + it is necessary to introduce a uniform interface for types having + the @{text "invalid"} (= bottom) element. The reason is that we impose + a data-invariant on raw-collection \inlineisar|types_code| which assures + that the @{text "invalid"} element is not allowed inside the collection; + all raw-collections of this form were identified with the @{text "invalid"} element + itself. The construction requires that the new collection type is + not comparable with the raw-types (consisting of nested option type constructions), + such that the data-invariant must be expressed in terms of the interface. + In a second step, our base-types will be shown to be instances of this interface. + *} + +text{* + This uniform interface consists in a type class requiring the existence + of a bot and a null element. The construction proceeds by + abstracting the null (defined by @{text "\ \ \"} on + @{text "'a option option"}) to a @{text null} element, which may + have an arbitrary semantic structure, and an undefinedness element @{text "\"} + to an abstract undefinedness element @{text "bot"} (also written + @{text "\"} whenever no confusion arises). As a consequence, it is necessary + to redefine the notions of invalid, defined, valuation etc. + on top of this interface. *} + +text{* + This interface consists in two abstract type classes @{text bot} + and @{text null} for the class of all types comprising a bot and a + distinct null element. *} + +class bot = + fixes bot :: "'a" + assumes nonEmpty : "\ x. x \ bot" + + +class null = bot + + fixes null :: "'a" + assumes null_is_valid : "null \ bot" + + +subsection{* Accommodation of Basic Types to the Abstract Interface *} + +text{* + In the following it is shown that the ``option-option'' type is + in fact in the @{text null} class and that function spaces over these + classes again ``live'' in these classes. This motivates the default construction + of the semantic domain for the basic types (\inlineocl{Boolean}, + \inlineocl{Integer}, \inlineocl{Real}, \ldots). +*} + +instantiation option :: (type)bot +begin + definition bot_option_def: "(bot::'a option) \ (None::'a option)" + instance proof show "\x::'a option. x \ bot" + by(rule_tac x="Some x" in exI, simp add:bot_option_def) + qed +end + + +instantiation option :: (bot)null +begin + definition null_option_def: "(null::'a::bot option) \ \ bot \" + instance proof show "(null::'a::bot option) \ bot" + by( simp add : null_option_def bot_option_def) + qed +end + + +instantiation "fun" :: (type,bot) bot +begin + definition bot_fun_def: "bot \ (\ x. bot)" + instance proof show "\(x::'a \ 'b). x \ bot" + apply(rule_tac x="\ _. (SOME y. y \ bot)" in exI, auto) + apply(drule_tac x=x in fun_cong,auto simp:bot_fun_def) + apply(erule contrapos_pp, simp) + apply(rule some_eq_ex[THEN iffD2]) + apply(simp add: nonEmpty) + done + qed +end + + +instantiation "fun" :: (type,null) null +begin + definition null_fun_def: "(null::'a \ 'b::null) \ (\ x. null)" + instance proof + show "(null::'a \ 'b::null) \ bot" + apply(auto simp: null_fun_def bot_fun_def) + apply(drule_tac x=x in fun_cong) + apply(erule contrapos_pp, simp add: null_is_valid) + done + qed +end + +text{* A trivial consequence of this adaption of the interface is that +abstract and concrete versions of null are the same on base types +(as could be expected). *} + +subsection{* The Common Infrastructure of Object Types (Class Types) and States. *} + +text{* Recall that OCL is a textual extension of the UML; in particular, we use OCL as means to +annotate UML class models. Thus, OCL inherits a notion of \emph{data} in the UML: UML class +models provide classes, inheritance, types of objects, and subtypes connecting them along +the inheritance hierarchie. +*} + +text{* For the moment, we formalize the most common notions of objects, in particular +the existance of object-identifiers (oid) for each object under which it can +be referenced in a \emph{state}. *} + +type_synonym oid = nat + +text{* We refrained from the alternative: +\begin{isar}[mathescape] +$\text{\textbf{type-synonym}}$ $\mathit{oid = ind}$ +\end{isar} +which is slightly more abstract but non-executable. +*} + +text{* \emph{States} in UML/OCL are a pair of +\begin{itemize} +\item a partial map from oid's to elements of an \emph{object universe}, + \ie{} the set of all possible object representations. +\item and an oid-indexed family of \emph{associations}, \ie{} finite relations between + objects living in a state. These relations can be n-ary which we model by nested lists. +\end{itemize} +For the moment we do not have to describe the concrete structure of the object universe and denote +it by the polymorphic variable @{text "'\"}.*} + +record ('\)state = + heap :: "oid \ '\ " + assocs :: "oid \ ((oid list) list) list" + +text{* In general, OCL operations are functions implicitly depending on a pair +of pre- and post-state, \ie{} \emph{state transitions}. Since this will be reflected in our +representation of OCL Types within HOL, we need to introduce the foundational concept of an +object id (oid), which is just some infinite set, and some abstract notion of state. *} + +type_synonym ('\)st = "'\ state \ '\ state" + +text{* We will require for all objects that there is a function that +projects the oid of an object in the state (we will settle the question how to define +this function later). We will use the Isabelle type class mechanism~\cite{haftmann.ea:constructive:2006} +to capture this: *} + +class object = fixes oid_of :: "'a \ oid" + +text{* Thus, if needed, we can constrain the object universe to objects by adding +the following type class constraint:*} +typ "'\ :: object" + +text{* The major instance needed are instances constructed over options: once an object, +options of objects are also objects. *} +instantiation option :: (object)object +begin + definition oid_of_option_def: "oid_of x = oid_of (the x)" + instance .. +end + + +subsection{* Common Infrastructure for all OCL Types (II): Valuations as OCL Types *} +text{* Since OCL operations in general depend on pre- and post-states, we will +represent OCL types as \emph{functions} from pre- and post-state to some +HOL raw-type that contains exactly the data in the OCL type --- see below. +This gives rise to the idea that we represent OCL types by \emph{Valuations}. +*} +text{* Valuations are functions from a state pair (built upon +data universe @{typ "'\"}) to an arbitrary null-type (\ie, containing +at least a destinguished @{text "null"} and @{text "invalid"} element). *} + +type_synonym ('\,'\) val = "'\ st \ '\::null" + +text{* The definitions for the constants and operations based on valuations +will be geared towards a format that Isabelle can check to be a ``conservative'' +(\ie, logically safe) axiomatic definition. By introducing an explicit +interpretation function (which happens to be defined just as the identity +since we are using a shallow embedding of OCL into HOL), all these definitions +can be rewritten into the conventional semantic textbook format as follows: *} + +subsection{* The fundamental constants 'invalid' and 'null' in all OCL Types *} + +text{* As a consequence of semantic domain definition, any OCL type will +have the two semantic constants @{text "invalid"} (for exceptional, aborted +computation) and @{text "null"}: + *} + +definition invalid :: "('\,'\::bot) val" +where "invalid \ \ \. bot" + +text{* This conservative Isabelle definition of the polymorphic constant +@{const invalid} is equivalent with the textbook definition: *} + +lemma textbook_invalid: "I\invalid\\ = bot" +by(simp add: invalid_def Sem_def) + + +text {* Note that the definition : +{\small +\begin{isar}[mathescape] +definition null :: "('$\mathfrak{A}$,'\::null) val" +where "null \ \ \. null" +\end{isar} +} is not necessary since we defined the entire function space over null types +again as null-types; the crucial definition is @{thm "null_fun_def"}. +Thus, the polymorphic constant @{const null} is simply the result of +a general type class construction. Nevertheless, we can derive the +semantic textbook definition for the OCL null constant based on the +abstract null: +*} + +lemma textbook_null_fun: "I\null::('\,'\::null) val\ \ = (null::('\::null))" +by(simp add: null_fun_def Sem_def) + +section{* Basic OCL Value Types *} + +text {* The structure of this section roughly follows the structure of Chapter +11 of the OCL standard~\cite{omg:ocl:2012}, which introduces the OCL +Library. *} + +text{* The semantic domain of the (basic) boolean type is now defined as the Standard: +the space of valuation to @{typ "bool option option"}, \ie{} the Boolean base type:*} + +type_synonym Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e = "bool option option" +type_synonym ('\)Boolean = "('\,Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" + +text{* Because of the previous class definitions, Isabelle type-inference establishes that +@{typ "('\)Boolean"} lives actually both in the type class @{term bot} and @{term null}; +this type is sufficiently rich to contain at least these two elements. +Analogously we build: *} +type_synonym Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e = "int option option" +type_synonym ('\)Integer = "('\,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" + +type_synonym String\<^sub>b\<^sub>a\<^sub>s\<^sub>e = "string option option" +type_synonym ('\)String = "('\,String\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" + +type_synonym Real\<^sub>b\<^sub>a\<^sub>s\<^sub>e = "real option option" +type_synonym ('\)Real = "('\,Real\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" + +text{* Since @{term "Real"} is again a basic type, we define its semantic domain +as the valuations over @{text "real option option"} --- i.e. the mathematical type of real numbers. +The HOL-theory for @{text real} ``Real'' transcendental numbers such as $\pi$ and $e$ as well as +infrastructure to reason over infinite convergent Cauchy-sequences (it is thus possible, in principle, +to reason in Featherweight OCL that the sum of inverted two-s exponentials is actually 2. + +If needed, a code-generator to compile @{text "Real"} to floating-point +numbers can be added; this allows for mapping reals to an efficient machine representation; +of course, this feature would be logically unsafe.*} + +text{* For technical reasons related to the Isabelle type inference for type-classes +(we don't get the properties in the right order that class instantiation provides them, +if we would follow the previous scheme), we give a slightly atypic definition:*} + +typedef Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e = "{X::unit option option. X = bot \ X = null }" by(rule_tac x="bot" in exI, simp) + +type_synonym ('\)Void = "('\,Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" + + + + +section{* Some OCL Collection Types *} + +text{* For the semantic construction of the collection types, we have two goals: +\begin{enumerate} +\item we want the types to be \emph{fully abstract}, \ie, the type should not + contain junk-elements that are not representable by OCL expressions, and +\item we want a possibility to nest collection types (so, we want the + potential of talking about @{text "Set(Set(Sequences(Pairs(X,Y))))"}). +\end{enumerate} +The former principle rules out the option to define @{text "'\ Set"} just by + @{text "('\, ('\ option option) set) val"}. This would allow sets to contain +junk elements such as @{text "{\}"} which we need to identify with undefinedness +itself. Abandoning fully abstractness of rules would later on produce all sorts +of problems when quantifying over the elements of a type. +However, if we build an own type, then it must conform to our abstract interface +in order to have nested types: arguments of type-constructors must conform to our +abstract interface, and the result type too. +*} + +subsection{* The Construction of the Pair Type (Tuples) *} + +text{* The core of an own type construction is done via a type + definition which provides the base-type @{text "('\, '\) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e"}. It + is shown that this type ``fits'' indeed into the abstract type + interface discussed in the previous section. *} + +typedef (overloaded) ('\, '\) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e = "{X::('\::null \ '\::null) option option. + X = bot \ X = null \ (fst\\X\\ \ bot \ snd\\X\\ \ bot)}" + by (rule_tac x="bot" in exI, simp) + +text{* We ``carve'' out from the concrete type @{typ "('\::null \ '\::null) option option"} +the new fully abstract type, which will not contain representations like @{term "\\(\,a)\\"} +or @{term "\\(b,\)\\"}. The type constuctor @{text "Pair{x,y}"} to be defined later will +identify these with @{term "invalid"}. +*} + +instantiation Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null,null)bot +begin + definition bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(bot_class.bot :: ('a::null,'b::null) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + + instance proof show "\x::('a,'b) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \ bot" + apply(rule_tac x="Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in exI) + by(simp add: bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject null_option_def bot_option_def) + qed +end + +instantiation Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null,null)null +begin + definition null_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(null::('a::null,'b::null) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \ None \" + + instance proof show "(null::('a::null,'b::null) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ bot" + by(simp add: bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject + null_option_def bot_option_def) + qed +end + + +text{* ... and lifting this type to the format of a valuation gives us:*} +type_synonym ('\,'\,'\) Pair = "('\, ('\,'\) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" +type_notation Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e ("Pair'(_,_')") + +subsection{* The Construction of the Set Type *} + +text{* The core of an own type construction is done via a type + definition which provides the raw-type @{text "'\ Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e"}. It + is shown that this type ``fits'' indeed into the abstract type + interface discussed in the previous section. Note that we make + no restriction whatsoever to \emph{finite} sets; while with + the standards type-constructors only finite sets can be denoted, + there is the possibility to define in fact infinite + type constructors in \FOCL (c.f. \autoref{sec:type-extensions}). *} + +typedef (overloaded) '\ Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e ="{X::('\::null) set option option. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by (rule_tac x="bot" in exI, simp) + +instantiation Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null)bot +begin + + definition bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(bot::('a::null) Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + + instance proof show "\x::'a Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \ bot" + apply(rule_tac x="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in exI) + by(simp add: bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject null_option_def bot_option_def) + qed +end + +instantiation Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null)null +begin + + definition null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(null::('a::null) Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \ None \" + + instance proof show "(null::('a::null) Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ bot" + by(simp add:null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject + null_option_def bot_option_def) + qed +end + +text{* ... and lifting this type to the format of a valuation gives us:*} +type_synonym ('\,'\) Set = "('\, '\ Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" +type_notation Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e ("Set'(_')") + +subsection{* The Construction of the Bag Type *} +text{* The core of an own type construction is done via a type + definition which provides the raw-type @{text "'\ Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e"} + based on multi-sets from the \HOL library. As in Sets, it + is shown that this type ``fits'' indeed into the abstract type + interface discussed in the previous section, and as in sets, we make + no restriction whatsoever to \emph{finite} multi-sets; while with + the standards type-constructors only finite sets can be denoted, + there is the possibility to define in fact infinite + type constructors in \FOCL (c.f. \autoref{sec:type-extensions}). + However, while several @{text null} elements are possible in a Bag, there + can't be no bottom (invalid) element in them. +*} + +typedef (overloaded) '\ Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e ="{X::('\::null \ nat) option option. X = bot \ X = null \ \\X\\ bot = 0 }" + by (rule_tac x="bot" in exI, simp) + +instantiation Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null)bot +begin + + definition bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(bot::('a::null) Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + + instance proof show "\x::'a Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \ bot" + apply(rule_tac x="Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in exI) + by(simp add: bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject + null_option_def bot_option_def) + qed +end + +instantiation Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null)null +begin + + definition null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(null::('a::null) Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \ None \" + + instance proof show "(null::('a::null) Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ bot" + by(simp add:null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject + null_option_def bot_option_def) + qed +end + +text{* ... and lifting this type to the format of a valuation gives us:*} +type_synonym ('\,'\) Bag = "('\, '\ Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" +type_notation Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e ("Bag'(_')") + +subsection{* The Construction of the Sequence Type *} + +text{* The core of an own type construction is done via a type + definition which provides the base-type @{text "'\ Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e"}. It + is shown that this type ``fits'' indeed into the abstract type + interface discussed in the previous section. *} + +typedef (overloaded) '\ Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e ="{X::('\::null) list option option. + X = bot \ X = null \ (\x\set \\X\\. x \ bot)}" + by (rule_tac x="bot" in exI, simp) + +instantiation Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null)bot +begin + + definition bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(bot::('a::null) Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + + instance proof show "\x::'a Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \ bot" + apply(rule_tac x="Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in exI) + by(auto simp:bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject + null_option_def bot_option_def) + qed +end + + +instantiation Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (null)null +begin + + definition null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def: "(null::('a::null) Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \ None \" + + instance proof show "(null::('a::null) Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ bot" + by(auto simp:bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject + null_option_def bot_option_def) + qed +end + + +text{* ... and lifting this type to the format of a valuation gives us:*} +type_synonym ('\,'\) Sequence = "('\, '\ Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val" +type_notation Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e ("Sequence'(_')") + +subsection{* Discussion: The Representation of UML/OCL Types in Featherweight OCL *} +text{* In the introduction, we mentioned that there is an ``injective representation +mapping'' between the types of OCL and the types of Featherweight OCL (and its +meta-language: HOL). This injectivity is at the heart of our representation technique +--- a so-called \emph{shallow embedding} --- and means: OCL types were mapped one-to-one +to types in HOL, ruling out a resentation where +everything is mapped on some common HOL-type, say ``OCL-expression'', in which we +would have to sort out the typing of OCL and its impact on the semantic representation +function in an own, quite heavy side-calculus. +*} + +text{* After the previous sections, we are now able to exemplify this representation as follows: + +\begin{table}[htbp] + \centering + \begin{tabu}{lX[,c,]} + \toprule + OCL Type & HOL Type \\ + \midrule + \inlineocl|Boolean| & @{typ "('\)Boolean"} \\ + \inlineocl|Boolean -> Boolean| & @{typ "('\)Boolean \ ('\)Boolean"} \\ + \inlineocl|(Integer,Integer) -> Boolean| & @{typ "('\)Integer \ ('\)Integer \ ('\)Boolean"} \\ + \inlineocl|Set(Integer)| & @{typ "('\,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e)Set"} \\ + \inlineocl|Set(Integer)-> Real| & @{typ "('\,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e)Set \ ('\)Real"} \\ + \inlineocl|Set(Pair(Integer,Boolean))| & @{typ "('\,(Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e, Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e)Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e)Set"} \\ + \inlineocl|Set()| & @{typ "('\,'\::null)Set"} \\ + \bottomrule + \end{tabu} + \caption{Correspondance between \OCL types and \HOL types} + \label{tab:types} +\end{table} +We do not formalize the representation map here; however, its principles are quite straight-forward: +\begin{enumerate} +\item cartesion products of arguments were curried, +\item constants of type \inlineocl{T} were mapped to valuations over the + HOL-type for \inlineocl{T}, +\item functions \inlineocl{T -> T'} were mapped to functions in HOL, where + \inlineocl{T} and \inlineocl{T'} were mapped to the valuations for them, and +\item the arguments of type constructors \inlineocl{Set(T)} remain corresponding HOL base-types. +\end{enumerate} + +*} + +text{* Note, furthermore, that our construction of ``fully abstract types'' (no junk, no confusion) +assures that the logical equality to be defined in the next section works correctly and comes +as element of the ``lingua franca'', \ie{} HOL. *} + +(*<*) +section{* Miscelleaneous: ML assertions *} + +text{* We introduce here a new command \emph{Assert} similar as \emph{value} for proving + that the given term in argument is a true proposition. The difference with \emph{value} is that +\emph{Assert} fails if the normal form of the term evaluated is not equal to @{term True}. +Moreover, in case \emph{value} could not normalize the given term, as another strategy of reduction + we try to prove it with a single ``simp'' tactic. *} + +ML{* +fun disp_msg title msg status = title ^ ": '" ^ msg ^ "' " ^ status + +fun lemma msg specification_theorem concl in_local thy = + SOME + (in_local (fn lthy => + specification_theorem Thm.theoremK NONE (K I) (@{binding ""}, []) [] [] + (Element.Shows [((@{binding ""}, []),[(concl lthy, [])])]) + false lthy + |> Proof.global_terminal_proof + ((Method.Combinator ( Method.no_combinator_info + , Method.Then + , [Method.Basic (fn ctxt => SIMPLE_METHOD (asm_full_simp_tac ctxt 1))]), + (Position.none, Position.none)), NONE)) + thy) + handle ERROR s => + (warning s; writeln (disp_msg "KO" msg "failed to normalize"); NONE) + +fun outer_syntax_command command_spec theory in_local = + Outer_Syntax.command command_spec "assert that the given specification is true" + (Parse.term >> (fn elems_concl => theory (fn thy => + case + lemma "code_unfold" Specification.theorem + (fn lthy => + let val expr = Value.value lthy (Syntax.read_term lthy elems_concl) + val thy = Proof_Context.theory_of lthy + open HOLogic in + if Sign.typ_equiv thy (fastype_of expr, @{typ "prop"}) then + expr + else mk_Trueprop (mk_eq (@{term "True"}, expr)) + end) + in_local + thy + of NONE => + let val attr_simp = "simp" in + case lemma attr_simp Specification.theorem_cmd (K elems_concl) in_local thy of + NONE => raise (ERROR "Assertion failed") + | SOME thy => + (writeln (disp_msg "OK" "simp" "finished the normalization"); + thy) + end + | SOME thy => thy))) + +fun in_local decl thy = + thy + |> Named_Target.init "" + |> decl + |> Local_Theory.exit_global + +val () = outer_syntax_command @{command_keyword Assert} Toplevel.theory in_local +val () = outer_syntax_command @{command_keyword Assert_local} (Toplevel.local_theory NONE NONE) I +*} +(*>*) + + +end + diff --git a/src/basic_types/UML_Boolean.thy b/src/basic_types/UML_Boolean.thy new file mode 100644 index 0000000..a7b244e --- /dev/null +++ b/src/basic_types/UML_Boolean.thy @@ -0,0 +1,126 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Boolean.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory UML_Boolean +imports "../UML_PropertyProfiles" +begin + + +subsection{* Fundamental Predicates on Basic Types: Strict (Referential) Equality *} +text{* + Here is a first instance of a definition of strict value equality---for + the special case of the type @{typ "('\)Boolean"}, it is just + the strict extension of the logical + equality: +*} +overloading StrictRefEq \ "StrictRefEq :: [('\)Boolean,('\)Boolean] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[code_unfold] : + "(x::('\)Boolean) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y)\ + else invalid \" +end + +text{* which implies elementary properties like: *} +lemma [simp,code_unfold] : "(true \ false) = false" +by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n) +lemma [simp,code_unfold] : "(false \ true) = false" +by(simp add:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n) + +lemma null_non_false [simp,code_unfold]:"(null \ false) = false" + apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) + by (metis drop.simps cp_valid false_def is_none_code(2) Option.is_none_def valid4 + bot_option_def null_fun_def null_option_def) + +lemma null_non_true [simp,code_unfold]:"(null \ true) = false" + apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) + by(simp add: true_def bot_option_def null_fun_def null_option_def) + +lemma false_non_null [simp,code_unfold]:"(false \ null) = false" + apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) + by(metis drop.simps cp_valid false_def is_none_code(2) Option.is_none_def valid4 + bot_option_def null_fun_def null_option_def ) + +lemma true_non_null [simp,code_unfold]:"(true \ null) = false" + apply(rule ext, simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n StrongEq_def false_def) + by(simp add: true_def bot_option_def null_fun_def null_option_def) + +text{* With respect to strictness properties and miscelleaneous side-calculi, +strict referential equality behaves on booleans as described in the +@{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}:*} +interpretation StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\)Boolean) \ y" + by unfold_locales (auto simp:StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n) + +text{* In particular, it is strict, cp-preserving and const-preserving. In particular, +it generates the simplifier rules for terms like:*} +lemma "(invalid \ false) = invalid" by(simp) +lemma "(invalid \ true) = invalid" by(simp) +lemma "(false \ invalid) = invalid" by(simp) +lemma "(true \ invalid) = invalid" by(simp) +lemma "((invalid::('\)Boolean) \ invalid) = invalid" by(simp) +text{* Thus, the weak equality is \emph{not} reflexive. *} + + + +subsection{* Test Statements on Boolean Operations. *} +text{* Here follows a list of code-examples, that explain the meanings +of the above definitions by compilation to code and execution to @{term "True"}.*} + +text{* Elementary computations on Boolean *} +Assert "\ \ \(true)" +Assert "\ \ \(false)" +Assert "\ |\ \(null)" +Assert "\ |\ \(invalid)" +Assert "\ \ \((null::('\)Boolean))" +Assert "\ |\ \(invalid)" +Assert "\ \ (true and true)" +Assert "\ \ (true and true \ true)" +Assert "\ \ ((null or null) \ null)" +Assert "\ \ ((null or null) \ null)" +Assert "\ \ ((true \ false) \ false)" +Assert "\ \ ((invalid \ false) \ false)" +Assert "\ \ ((invalid \ false) \ invalid)" +Assert "\ \ (true <> false)" +Assert "\ \ (false <> true)" + + +end diff --git a/src/basic_types/UML_Integer.thy b/src/basic_types/UML_Integer.thy new file mode 100644 index 0000000..f48349b --- /dev/null +++ b/src/basic_types/UML_Integer.thy @@ -0,0 +1,288 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Integer.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory UML_Integer +imports "../UML_PropertyProfiles" +begin + +section{* Basic Type Integer: Operations *} + +subsection{* Fundamental Predicates on Integers: Strict Equality \label{sec:integer-strict-eq}*} + +text{* The last basic operation belonging to the fundamental infrastructure +of a value-type in OCL is the weak equality, which is defined similar +to the @{typ "('\)Boolean"}-case as strict extension of the strong equality:*} +overloading StrictRefEq \ "StrictRefEq :: [('\)Integer,('\)Integer] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[code_unfold] : + "(x::('\)Integer) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y) \ + else invalid \" +end + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\)Integer) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r) + +subsection{* Basic Integer Constants *} + +text{* Although the remaining part of this library reasons about +integers abstractly, we provide here as example some convenient shortcuts. *} + +definition OclInt0 ::"('\)Integer" ("\") where "\ = (\ _ . \\0::int\\)" +definition OclInt1 ::"('\)Integer" ("\") where "\ = (\ _ . \\1::int\\)" +definition OclInt2 ::"('\)Integer" ("\") where "\ = (\ _ . \\2::int\\)" +text{* Etc. *} +text_raw{* \isatagafp *} +definition OclInt3 ::"('\)Integer" ("\") where "\ = (\ _ . \\3::int\\)" +definition OclInt4 ::"('\)Integer" ("\") where "\ = (\ _ . \\4::int\\)" +definition OclInt5 ::"('\)Integer" ("\") where "\ = (\ _ . \\5::int\\)" +definition OclInt6 ::"('\)Integer" ("\") where "\ = (\ _ . \\6::int\\)" +definition OclInt7 ::"('\)Integer" ("\") where "\ = (\ _ . \\7::int\\)" +definition OclInt8 ::"('\)Integer" ("\") where "\ = (\ _ . \\8::int\\)" +definition OclInt9 ::"('\)Integer" ("\") where "\ = (\ _ . \\9::int\\)" +definition OclInt10 ::"('\)Integer" ("\\")where "\\ = (\ _ . \\10::int\\)" + +subsection{* Validity and Definedness Properties *} + +lemma "\(null::('\)Integer) = false" by simp +lemma "\(null::('\)Integer) = true" by simp + +lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" +by(simp add:defined_def true_def + bot_fun_def bot_option_def null_fun_def null_option_def) + +lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" +by(simp add:valid_def true_def + bot_fun_def bot_option_def) + +(* ecclectic proofs to make examples executable *) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt0_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt0_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt1_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt1_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt2_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt2_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt6_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt6_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt8_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt8_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt9_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclInt9_def) + +text_raw{* \endisatagafp *} + +subsection{* Arithmetical Operations *} + +subsubsection{* Definition *} +text{* Here is a common case of a built-in operation on built-in types. +Note that the arguments must be both defined (non-null, non-bot). *} +text{* Note that we can not follow the lexis of the OCL Standard for Isabelle +technical reasons; these operators are heavily overloaded in the HOL library +that a further overloading would lead to heavy technical buzz in this +document. +*} +definition OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Integer" (infix "+\<^sub>i\<^sub>n\<^sub>t" 40) +where "x +\<^sub>i\<^sub>n\<^sub>t y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ + \\y \\\\\ + else invalid \ " +interpretation OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r : profile_bin\<^sub>d_\<^sub>d "op +\<^sub>i\<^sub>n\<^sub>t" "\ x y. \\\\x\\ + \\y\\\\" + by unfold_locales (auto simp:OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def bot_option_def null_option_def) + + +definition OclMinus\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Integer" (infix "-\<^sub>i\<^sub>n\<^sub>t" 41) +where "x -\<^sub>i\<^sub>n\<^sub>t y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ - \\y \\\\\ + else invalid \ " +interpretation OclMinus\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r : profile_bin\<^sub>d_\<^sub>d "op -\<^sub>i\<^sub>n\<^sub>t" "\ x y. \\\\x\\ - \\y\\\\" + by unfold_locales (auto simp:OclMinus\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def bot_option_def null_option_def) + + +definition OclMult\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Integer" (infix "*\<^sub>i\<^sub>n\<^sub>t" 45) +where "x *\<^sub>i\<^sub>n\<^sub>t y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ * \\y \\\\\ + else invalid \" +interpretation OclMult\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r : profile_bin\<^sub>d_\<^sub>d "op *\<^sub>i\<^sub>n\<^sub>t" "\ x y. \\\\x\\ * \\y\\\\" + by unfold_locales (auto simp:OclMult\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def bot_option_def null_option_def) + +text{* Here is the special case of division, which is defined as invalid for division +by zero. *} +definition OclDivision\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Integer" (infix "div\<^sub>i\<^sub>n\<^sub>t" 45) +where "x div\<^sub>i\<^sub>n\<^sub>t y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then if y \ \ OclInt0 \ then \\\\x \\\ div \\y \\\\\ else invalid \ + else invalid \ " +(* TODO: special locale setup.*) + +definition OclModulus\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Integer" (infix "mod\<^sub>i\<^sub>n\<^sub>t" 45) +where "x mod\<^sub>i\<^sub>n\<^sub>t y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then if y \ \ OclInt0 \ then \\\\x \\\ mod \\y \\\\\ else invalid \ + else invalid \ " +(* TODO: special locale setup.*) + + +definition OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Boolean" (infix "<\<^sub>i\<^sub>n\<^sub>t" 35) +where "x <\<^sub>i\<^sub>n\<^sub>t y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ < \\y \\\\\ + else invalid \ " +interpretation OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r : profile_bin\<^sub>d_\<^sub>d "op <\<^sub>i\<^sub>n\<^sub>t" "\ x y. \\\\x\\ < \\y\\\\" + by unfold_locales (auto simp:OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def bot_option_def null_option_def) + +definition OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\)Integer \ ('\)Integer \ ('\)Boolean" (infix "\\<^sub>i\<^sub>n\<^sub>t" 35) +where "x \\<^sub>i\<^sub>n\<^sub>t y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ \ \\y \\\\\ + else invalid \ " +interpretation OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r : profile_bin\<^sub>d_\<^sub>d "op \\<^sub>i\<^sub>n\<^sub>t" "\ x y. \\\\x\\ \ \\y\\\\" + by unfold_locales (auto simp:OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def bot_option_def null_option_def) + +subsubsection{* Basic Properties *} + +lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_commute: "(X +\<^sub>i\<^sub>n\<^sub>t Y) = (Y +\<^sub>i\<^sub>n\<^sub>t X)" + by(rule ext,auto simp:true_def false_def OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def invalid_def + split: option.split option.split_asm + bool.split bool.split_asm) + +subsubsection{* Execution with Invalid or Null or Zero as Argument *} + +lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_zero1[simp,code_unfold] : +"(x +\<^sub>i\<^sub>n\<^sub>t \) = (if \ x and not (\ x) then invalid else x endif)" + proof (rule ext, rename_tac \, case_tac "(\ x and not (\ x)) \ = true \") + fix \ show "(\ x and not (\ x)) \ = true \ \ + (x +\<^sub>i\<^sub>n\<^sub>t \) \ = (if \ x and not (\ x) then invalid else x endif) \" + apply(subst OclIf_true', simp add: OclValid_def) + by (metis OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def OclNot_defargs OclValid_def foundation5 foundation9) + next fix \ + have A: "\\. (\ \ not (\ x and not (\ x))) = (x \ = invalid \ \ \ \ \ x)" + by (metis OclNot_not OclOr_def defined5 defined6 defined_not_I foundation11 foundation18' + foundation6 foundation7 foundation9 invalid_def) + have B: "\ \ \ x \ \\\\x \\\\\ = x \" + apply(cases "x \", metis bot_option_def foundation16) + apply(rename_tac x', case_tac x', metis bot_option_def foundation16 null_option_def) + by(simp) + show "(x +\<^sub>i\<^sub>n\<^sub>t \) \ = (if \ x and not (\ x) then invalid else x endif) \" + when "\ \ not (\ x and not (\ x))" + apply(insert that, subst OclIf_false', simp, simp add: A, auto simp: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def OclInt0_def) + (* *) + apply(simp add: foundation16'[simplified OclValid_def]) + apply(simp add: B) + by(simp add: OclValid_def) +qed(metis OclValid_def defined5 defined6 defined_and_I defined_not_I foundation9) + +lemma OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_zero2[simp,code_unfold] : +"(\ +\<^sub>i\<^sub>n\<^sub>t x) = (if \ x and not (\ x) then invalid else x endif)" +by(subst OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_commute, simp) + +(* TODO Basic proproperties for multiplication, division, modulus. *) + + + +subsection{* Test Statements *} +text{* Here follows a list of code-examples, that explain the meanings +of the above definitions by compilation to code and execution to @{term "True"}.*} + +Assert "\ \ ( \ \\<^sub>i\<^sub>n\<^sub>t \\ )" +Assert "\ \ (( \ +\<^sub>i\<^sub>n\<^sub>t \ ) \\<^sub>i\<^sub>n\<^sub>t \\ )" +Assert "\ |\ (( \ +\<^sub>i\<^sub>n\<^sub>t ( \ +\<^sub>i\<^sub>n\<^sub>t \ )) <\<^sub>i\<^sub>n\<^sub>t \\ )" +Assert "\ \ not (\ (null +\<^sub>i\<^sub>n\<^sub>t \)) " +Assert "\ \ (((\ *\<^sub>i\<^sub>n\<^sub>t \) div\<^sub>i\<^sub>n\<^sub>t \\) \\<^sub>i\<^sub>n\<^sub>t \) " +Assert "\ \ not (\ (\ div\<^sub>i\<^sub>n\<^sub>t \)) " +Assert "\ \ not (\ (\ div\<^sub>i\<^sub>n\<^sub>t \)) " + + + +lemma integer_non_null [simp]: "((\_. \\n\\) \ (null::('\)Integer)) = false" +by(rule ext,auto simp: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def + bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) + +lemma null_non_integer [simp]: "((null::('\)Integer) \ (\_. \\n\\)) = false" +by(rule ext,auto simp: StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def + bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) + +lemma OclInt0_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt0_def) +lemma null_non_OclInt0 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt0_def) +lemma OclInt1_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt1_def) +lemma null_non_OclInt1 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt1_def) +lemma OclInt2_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt2_def) +lemma null_non_OclInt2 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt2_def) +lemma OclInt6_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt6_def) +lemma null_non_OclInt6 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt6_def) +lemma OclInt8_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt8_def) +lemma null_non_OclInt8 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt8_def) +lemma OclInt9_non_null [simp,code_unfold]: "(\ \ null) = false" by(simp add: OclInt9_def) +lemma null_non_OclInt9 [simp,code_unfold]: "(null \ \) = false" by(simp add: OclInt9_def) + + +text{* Here follows a list of code-examples, that explain the meanings +of the above definitions by compilation to code and execution to @{term "True"}.*} + + +text{* Elementary computations on Integer *} + +Assert "\ \ ((\ <\<^sub>i\<^sub>n\<^sub>t \) and (\ <\<^sub>i\<^sub>n\<^sub>t \))" + +Assert "\ \ \ <> \" +Assert "\ \ \ <> \" +Assert "\ \ \ \ \" + +Assert "\ \ \ \" +Assert "\ \ \ \" +Assert "\ \ \ (null::('\)Integer)" +Assert "\ \ (invalid \ invalid)" +Assert "\ \ (null \ null)" +Assert "\ \ (\ \ \)" +Assert "\ |\ (\ \ \\)" +Assert "\ |\ (invalid \ \\)" +Assert "\ |\ (null \ \\)" +Assert "\ |\ (invalid \ (invalid::('\)Integer))" (* Without typeconstraint not executable.*) +Assert "\ |\ \ (invalid \ (invalid::('\)Integer))" (* Without typeconstraint not executable.*) +Assert "\ |\ (invalid <> (invalid::('\)Integer))" (* Without typeconstraint not executable.*) +Assert "\ |\ \ (invalid <> (invalid::('\)Integer))" (* Without typeconstraint not executable.*) +Assert "\ \ (null \ (null::('\)Integer) )" (* Without typeconstraint not executable.*) +Assert "\ \ (null \ (null::('\)Integer) )" (* Without typeconstraint not executable.*) +Assert "\ \ (\ \ \)" +Assert "\ |\ (\ <> \)" +Assert "\ |\ (\ \ \\)" +Assert "\ \ (\ <> \\)" +Assert "\ |\ (\ <\<^sub>i\<^sub>n\<^sub>t null)" +Assert "\ |\ (\ (\ <\<^sub>i\<^sub>n\<^sub>t null))" + + +end diff --git a/src/basic_types/UML_Real.thy b/src/basic_types/UML_Real.thy new file mode 100644 index 0000000..b1a2ff6 --- /dev/null +++ b/src/basic_types/UML_Real.thy @@ -0,0 +1,287 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Real.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory UML_Real +imports "../UML_PropertyProfiles" +begin + +section{* Basic Type Real: Operations *} + +subsection{* Fundamental Predicates on Reals: Strict Equality \label{sec:real-strict-eq}*} + +text{* The last basic operation belonging to the fundamental infrastructure +of a value-type in OCL is the weak equality, which is defined similar +to the @{typ "('\)Boolean"}-case as strict extension of the strong equality:*} +overloading StrictRefEq \ "StrictRefEq :: [('\)Real,('\)Real] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l [code_unfold] : + "(x::('\)Real) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y) \ + else invalid \" +end + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\)Real) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l) + +subsection{* Basic Real Constants *} + +text{* Although the remaining part of this library reasons about +reals abstractly, we provide here as example some convenient shortcuts. *} + +definition OclReal0 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\0::real\\)" +definition OclReal1 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\1::real\\)" +definition OclReal2 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\2::real\\)" +text{* Etc. *} +text_raw{* \isatagafp *} +definition OclReal3 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\3::real\\)" +definition OclReal4 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\4::real\\)" +definition OclReal5 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\5::real\\)" +definition OclReal6 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\6::real\\)" +definition OclReal7 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\7::real\\)" +definition OclReal8 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\8::real\\)" +definition OclReal9 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\9::real\\)" +definition OclReal10 ::"('\)Real" ("\\.\") where "\\.\ = (\ _ . \\10::real\\)" +definition OclRealpi ::"('\)Real" ("\") where "\ = (\ _ . \\pi\\)" + +subsection{* Validity and Definedness Properties *} + +lemma "\(null::('\)Real) = false" by simp +lemma "\(null::('\)Real) = true" by simp + +lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" +by(simp add:defined_def true_def + bot_fun_def bot_option_def null_fun_def null_option_def) + +lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" +by(simp add:valid_def true_def + bot_fun_def bot_option_def) + +(* ecclectic proofs to make examples executable *) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal0_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal0_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal1_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal1_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal2_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal2_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal6_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal6_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal8_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal8_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal9_def) +lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal9_def) +text_raw{* \endisatagafp *} + +subsection{* Arithmetical Operations *} + +subsubsection{* Definition *} +text{* Here is a common case of a built-in operation on built-in types. +Note that the arguments must be both defined (non-null, non-bot). *} +text{* Note that we can not follow the lexis of the OCL Standard for Isabelle +technical reasons; these operators are heavily overloaded in the HOL library +that a further overloading would lead to heavy technical buzz in this +document. +*} +definition OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "+\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 40) +where "x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ + \\y \\\\\ + else invalid \ " +interpretation OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "op +\<^sub>r\<^sub>e\<^sub>a\<^sub>l" "\ x y. \\\\x\\ + \\y\\\\" + by unfold_locales (auto simp:OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) + + +definition OclMinus\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "-\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 41) +where "x -\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ - \\y \\\\\ + else invalid \ " +interpretation OclMinus\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "op -\<^sub>r\<^sub>e\<^sub>a\<^sub>l" "\ x y. \\\\x\\ - \\y\\\\" + by unfold_locales (auto simp:OclMinus\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) + + +definition OclMult\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "*\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45) +where "x *\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ * \\y \\\\\ + else invalid \" +interpretation OclMult\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "op *\<^sub>r\<^sub>e\<^sub>a\<^sub>l" "\ x y. \\\\x\\ * \\y\\\\" + by unfold_locales (auto simp:OclMult\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) + +text{* Here is the special case of division, which is defined as invalid for division +by zero. *} +definition OclDivision\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "div\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45) +where "x div\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then if y \ \ OclReal0 \ then \\\\x \\\ / \\y \\\\\ else invalid \ + else invalid \ " +(* TODO: special locale setup.*) + +definition "mod_float a b = a - real_of_int (floor (a / b)) * b" +definition OclModulus\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "mod\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45) +where "x mod\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then if y \ \ OclReal0 \ then \\mod_float \\x \\\ \\y \\\\\ else invalid \ + else invalid \ " +(* TODO: special locale setup.*) + + +definition OclLess\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Boolean" (infix "<\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 35) +where "x <\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ < \\y \\\\\ + else invalid \ " +interpretation OclLess\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "op <\<^sub>r\<^sub>e\<^sub>a\<^sub>l" "\ x y. \\\\x\\ < \\y\\\\" + by unfold_locales (auto simp:OclLess\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) + +definition OclLe\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Boolean" (infix "\\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 35) +where "x \\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\x \\\ \ \\y \\\\\ + else invalid \ " +interpretation OclLe\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "op \\<^sub>r\<^sub>e\<^sub>a\<^sub>l" "\ x y. \\\\x\\ \ \\y\\\\" + by unfold_locales (auto simp:OclLe\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) + +subsubsection{* Basic Properties *} + +lemma OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_commute: "(X +\<^sub>r\<^sub>e\<^sub>a\<^sub>l Y) = (Y +\<^sub>r\<^sub>e\<^sub>a\<^sub>l X)" + by(rule ext,auto simp:true_def false_def OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def invalid_def + split: option.split option.split_asm + bool.split bool.split_asm) + +subsubsection{* Execution with Invalid or Null or Zero as Argument *} + +lemma OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_zero1[simp,code_unfold] : +"(x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) = (if \ x and not (\ x) then invalid else x endif)" + proof (rule ext, rename_tac \, case_tac "(\ x and not (\ x)) \ = true \") + fix \ show "(\ x and not (\ x)) \ = true \ \ + (x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) \ = (if \ x and not (\ x) then invalid else x endif) \" + apply(subst OclIf_true', simp add: OclValid_def) + by (metis OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def OclNot_defargs OclValid_def foundation5 foundation9) + next fix \ + have A: "\\. (\ \ not (\ x and not (\ x))) = (x \ = invalid \ \ \ \ \ x)" + by (metis OclNot_not OclOr_def defined5 defined6 defined_not_I foundation11 foundation18' + foundation6 foundation7 foundation9 invalid_def) + have B: "\ \ \ x \ \\\\x \\\\\ = x \" + apply(cases "x \", metis bot_option_def foundation16) + apply(rename_tac x', case_tac x', metis bot_option_def foundation16 null_option_def) + by(simp) + show "(x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) \ = (if \ x and not (\ x) then invalid else x endif) \" + when "\ \ not (\ x and not (\ x))" + apply(insert that, subst OclIf_false', simp, simp add: A, auto simp: OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def OclReal0_def) + (* *) + apply(simp add: foundation16'[simplified OclValid_def]) + apply(simp add: B) + by(simp add: OclValid_def) +qed(metis OclValid_def defined5 defined6 defined_and_I defined_not_I foundation9) + +lemma OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_zero2[simp,code_unfold] : +"(\.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l x) = (if \ x and not (\ x) then invalid else x endif)" +by(subst OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_commute, simp) + +(* TODO Basic proproperties for multiplication, division, modulus. *) + + + +subsection{* Test Statements *} +text{* Here follows a list of code-examples, that explain the meanings +of the above definitions by compilation to code and execution to @{term "True"}.*} + +Assert "\ \ ( \.\ \\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\ )" +Assert "\ \ (( \.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\ ) \\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\ )" +Assert "\ |\ (( \.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l ( \.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\ )) <\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\ )" +Assert "\ \ not (\ (null +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\)) " +Assert "\ \ (((\.\ *\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\) \\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) " +Assert "\ \ not (\ (\.\ div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\)) " +Assert "\ \ not (\ (\.\ div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\)) " + + + +lemma real_non_null [simp]: "((\_. \\n\\) \ (null::('\)Real)) = false" +by(rule ext,auto simp: StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l valid_def + bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) + +lemma null_non_real [simp]: "((null::('\)Real) \ (\_. \\n\\)) = false" +by(rule ext,auto simp: StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l valid_def + bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) + +lemma OclReal0_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal0_def) +lemma null_non_OclReal0 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal0_def) +lemma OclReal1_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal1_def) +lemma null_non_OclReal1 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal1_def) +lemma OclReal2_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal2_def) +lemma null_non_OclReal2 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal2_def) +lemma OclReal6_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal6_def) +lemma null_non_OclReal6 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal6_def) +lemma OclReal8_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal8_def) +lemma null_non_OclReal8 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal8_def) +lemma OclReal9_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal9_def) +lemma null_non_OclReal9 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal9_def) + + +text{* Here follows a list of code-examples, that explain the meanings +of the above definitions by compilation to code and execution to @{term "True"}.*} + + +text{* Elementary computations on Real *} + +Assert "\ \ \.\ <> \.\" +Assert "\ \ \.\ <> \.\" +Assert "\ \ \.\ \ \.\" + +Assert "\ \ \ \.\" +Assert "\ \ \ \.\" +Assert "\ \ \ (null::('\)Real)" +Assert "\ \ (invalid \ invalid)" +Assert "\ \ (null \ null)" +Assert "\ \ (\.\ \ \.\)" +Assert "\ |\ (\.\ \ \\.\)" +Assert "\ |\ (invalid \ \\.\)" +Assert "\ |\ (null \ \\.\)" +Assert "\ |\ (invalid \ (invalid::('\)Real))" (* Without typeconstraint not executable.*) +Assert "\ |\ \ (invalid \ (invalid::('\)Real))" (* Without typeconstraint not executable.*) +Assert "\ |\ (invalid <> (invalid::('\)Real))" (* Without typeconstraint not executable.*) +Assert "\ |\ \ (invalid <> (invalid::('\)Real))" (* Without typeconstraint not executable.*) +Assert "\ \ (null \ (null::('\)Real) )" (* Without typeconstraint not executable.*) +Assert "\ \ (null \ (null::('\)Real) )" (* Without typeconstraint not executable.*) +Assert "\ \ (\.\ \ \.\)" +Assert "\ |\ (\.\ <> \.\)" +Assert "\ |\ (\.\ \ \\.\)" +Assert "\ \ (\.\ <> \\.\)" +Assert "\ |\ (\.\ <\<^sub>r\<^sub>e\<^sub>a\<^sub>l null)" +Assert "\ |\ (\ (\.\ <\<^sub>r\<^sub>e\<^sub>a\<^sub>l null))" + + +end diff --git a/src/basic_types/UML_String.thy b/src/basic_types/UML_String.thy new file mode 100644 index 0000000..b8905bd --- /dev/null +++ b/src/basic_types/UML_String.thy @@ -0,0 +1,167 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_String.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory UML_String +imports "../UML_PropertyProfiles" +begin + +section{* Basic Type String: Operations *} + +subsection{* Fundamental Properties on Strings: Strict Equality \label{sec:string-strict-eq}*} + +text{* The last basic operation belonging to the fundamental infrastructure +of a value-type in OCL is the weak equality, which is defined similar +to the @{typ "('\)Boolean"}-case as strict extension of the strong equality:*} +overloading StrictRefEq \ "StrictRefEq :: [('\)String,('\)String] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g[code_unfold] : + "(x::('\)String) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y) \ + else invalid \" +end + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\)String) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g) + +subsection{* Basic String Constants *} + +text{* Although the remaining part of this library reasons about +integers abstractly, we provide here as example some convenient shortcuts. *} + +definition OclStringa ::"('\)String" ("\") where "\ = (\ _ . \\''a''\\)" +definition OclStringb ::"('\)String" ("\") where "\ = (\ _ . \\''b''\\)" +definition OclStringc ::"('\)String" ("\") where "\ = (\ _ . \\''c''\\)" +text{* Etc.*} +text_raw{* \isatagafp *} + +subsection{* Validity and Definedness Properties *} + +lemma "\(null::('\)String) = false" by simp +lemma "\(null::('\)String) = true" by simp + +lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" +by(simp add:defined_def true_def + bot_fun_def bot_option_def null_fun_def null_option_def) + +lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" +by(simp add:valid_def true_def + bot_fun_def bot_option_def) + +(* ecclectic proofs to make examples executable *) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclStringa_def) +lemma [simp,code_unfold]: "\ \ = true" by(simp add:OclStringa_def) +text_raw{* \endisatagafp *} + +subsection{* String Operations *} + +subsubsection{* Definition *} +text{* Here is a common case of a built-in operation on built-in types. +Note that the arguments must be both defined (non-null, non-bot). *} +text{* Note that we can not follow the lexis of the OCL Standard for Isabelle +technical reasons; these operators are heavily overloaded in the HOL library +that a further overloading would lead to heavy technical buzz in this +document. +*} +definition OclAdd\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g ::"('\)String \ ('\)String \ ('\)String" (infix "+\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g" 40) +where "x +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\concat [\\x \\\, \\y \\\]\\ + else invalid \ " +interpretation OclAdd\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g : profile_bin\<^sub>d_\<^sub>d "op +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g" "\ x y. \\concat [\\x\\, \\y\\]\\" + by unfold_locales (auto simp:OclAdd\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g_def bot_option_def null_option_def) + +(* TODO : size(), concat, substring(s:string) toInteger, toReal, at(i:Integer), characters() etc. *) + + +subsubsection{* Basic Properties *} + +lemma OclAdd\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g_not_commute: "\X Y. (X +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g Y) \ (Y +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g X)" + apply(rule_tac x = "\_. \\''b''\\" in exI) + apply(rule_tac x = "\_. \\''a''\\" in exI) + apply(simp_all add:OclAdd\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g_def) + by(auto, drule fun_cong, auto) + + +subsection{* Test Statements *} +text{* Here follows a list of code-examples, that explain the meanings +of the above definitions by compilation to code and execution to @{term "True"}.*} +(* +Assert "\ \ ( \ \\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \\ )" +Assert "\ \ (( \ +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \ ) \\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \\ )" +Assert "\ |\ (( \ +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g ( \ +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \ )) <\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \\ )" +Assert "\ \ not (\ (null +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \)) " +*) + +text{* Here follows a list of code-examples, that explain the meanings +of the above definitions by compilation to code and execution to @{term "True"}.*} + + +text{* Elementary computations on String *} + +Assert "\ \ \ <> \" +Assert "\ \ \ <> \" +Assert "\ \ \ \ \" + +Assert "\ \ \ \" +Assert "\ \ \ \" +Assert "\ \ \ (null::('\)String)" +Assert "\ \ (invalid \ invalid)" +Assert "\ \ (null \ null)" +Assert "\ \ (\ \ \)" +Assert "\ |\ (\ \ \)" +Assert "\ |\ (invalid \ \)" +Assert "\ |\ (null \ \)" +Assert "\ |\ (invalid \ (invalid::('\)String))" (* Without typeconstraint not executable.*) +Assert "\ |\ \ (invalid \ (invalid::('\)String))" (* Without typeconstraint not executable.*) +Assert "\ |\ (invalid <> (invalid::('\)String))" (* Without typeconstraint not executable.*) +Assert "\ |\ \ (invalid <> (invalid::('\)String))" (* Without typeconstraint not executable.*) +Assert "\ \ (null \ (null::('\)String) )" (* Without typeconstraint not executable.*) +Assert "\ \ (null \ (null::('\)String) )" (* Without typeconstraint not executable.*) +Assert "\ \ (\ \ \)" +Assert "\ |\ (\ <> \)" +Assert "\ |\ (\ \ \)" +Assert "\ \ (\ <> \)" +(*Assert "\ |\ (\ <\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g null)" +Assert "\ |\ (\ (\ <\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g null))" +*) + +end diff --git a/src/basic_types/UML_Void.thy b/src/basic_types/UML_Void.thy new file mode 100644 index 0000000..35e5678 --- /dev/null +++ b/src/basic_types/UML_Void.thy @@ -0,0 +1,138 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Void.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory UML_Void +imports "../UML_PropertyProfiles" +begin + +section{* Basic Type Void: Operations *} + +(* For technical reasons, the type does not contain to the null-class yet. *) +text {* This \emph{minimal} OCL type contains only two elements: +@{term "invalid"} and @{term "null"}. +@{term "Void"} could initially be defined as @{typ "unit option option"}, +however the cardinal of this type is more than two, so it would have the cost to consider + @{text "Some None"} and @{text "Some (Some ())"} seemingly everywhere.*} + +subsection{* Fundamental Properties on Voids: Strict Equality *} + +subsubsection{* Definition *} + +instantiation Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: bot +begin + definition bot_Void_def: "(bot_class.bot :: Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + + instance proof show "\x:: Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \ bot" + apply(rule_tac x="Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in exI) + apply(simp add:bot_Void_def, subst Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) + apply(simp_all add: null_option_def bot_option_def) + done + qed +end + +instantiation Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: null +begin + definition null_Void_def: "(null::Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \ None \" + + instance proof show "(null:: Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ bot" + apply(simp add:null_Void_def bot_Void_def, subst Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) + apply(simp_all add: null_option_def bot_option_def) + done + qed +end + + +text{* The last basic operation belonging to the fundamental infrastructure +of a value-type in OCL is the weak equality, which is defined similar +to the @{typ "('\)Void"}-case as strict extension of the strong equality:*} +overloading StrictRefEq \ "StrictRefEq :: [('\)Void,('\)Void] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>V\<^sub>o\<^sub>i\<^sub>d[code_unfold] : + "(x::('\)Void) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y) \ + else invalid \" +end + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>V\<^sub>o\<^sub>i\<^sub>d : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\)Void) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>V\<^sub>o\<^sub>i\<^sub>d) + + +subsection{* Basic Void Constants *} + + +subsection{* Validity and Definedness Properties *} + +lemma "\(null::('\)Void) = false" by simp +lemma "\(null::('\)Void) = true" by simp + +lemma [simp,code_unfold]: "\ (\_. Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e None) = false" +apply(simp add:defined_def true_def + bot_fun_def bot_option_def) +apply(rule ext, simp split:, intro conjI impI) +by(simp add: bot_Void_def) + +lemma [simp,code_unfold]: "\ (\_. Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e None) = false" +apply(simp add:valid_def true_def + bot_fun_def bot_option_def) +apply(rule ext, simp split:, intro conjI impI) +by(simp add: bot_Void_def) + +lemma [simp,code_unfold]: "\ (\_. Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\) = false" +apply(simp add:defined_def true_def + bot_fun_def bot_option_def null_fun_def null_option_def) +apply(rule ext, simp split:, intro conjI impI) +by(simp add: null_Void_def) + +lemma [simp,code_unfold]: "\ (\_. Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\) = true" +apply(simp add:valid_def true_def + bot_fun_def bot_option_def) +apply(rule ext, simp split:, intro conjI impI) +by(metis null_Void_def null_is_valid, simp add: true_def) + + +subsection{* Test Statements *} + +Assert "\ \ ((null::('\)Void) \ null)" + + +end diff --git a/src/collection_types/UML_Bag.thy b/src/collection_types/UML_Bag.thy new file mode 100644 index 0000000..f9dd7cb --- /dev/null +++ b/src/collection_types/UML_Bag.thy @@ -0,0 +1,1072 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Bag.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + + +theory UML_Bag +imports "../basic_types/UML_Void" + "../basic_types/UML_Boolean" + "../basic_types/UML_Integer" + "../basic_types/UML_String" + "../basic_types/UML_Real" +begin + +no_notation None ("\") +section{* Collection Type Bag: Operations *} + +definition "Rep_Bag_base' x = {(x0, y). y < \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ x0 }" +definition "Rep_Bag_base x \ = {(x0, y). y < \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ x0 }" +definition "Rep_Set_base x \ = fst ` {(x0, y). y < \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ x0 }" + +definition ApproxEq (infixl "\" 30) +where "X \ Y \ \ \. \\Rep_Set_base X \ = Rep_Set_base Y \ \\" + + +subsection{* As a Motivation for the (infinite) Type Construction: Type-Extensions as Bags + \label{sec:type-extensions}*} + +text{* Our notion of typed bag goes beyond the usual notion of a finite executable bag and +is powerful enough to capture \emph{the extension of a type} in UML and OCL. This means +we can have in Featherweight OCL Bags containing all possible elements of a type, not only +those (finite) ones representable in a state. This holds for base types as well as class types, +although the notion for class-types --- involving object id's not occuring in a state --- +requires some care. + +In a world with @{term invalid} and @{term null}, there are two notions extensions possible: +\begin{enumerate} +\item the bag of all \emph{defined} values of a type @{term T} + (for which we will introduce the constant @{term T}) +\item the bag of all \emph{valid} values of a type @{term T}, so including @{term null} + (for which we will introduce the constant @{term T\<^sub>n\<^sub>u\<^sub>l\<^sub>l}). +\end{enumerate} +*} + +text{* We define the bag extensions for the base type @{term Integer} as follows: *} +definition Integer :: "('\,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Integer \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | Some None \ 0 | _ \ 1))" + +definition Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | _ \ 1))" + +lemma Integer_defined : "\ Integer = true" +apply(rule ext, auto simp: Integer_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +text{* This allows the theorems: + + @{text "\ \ \ x \ \ \ (Integer->includes\<^sub>B\<^sub>a\<^sub>g(x))"} + @{text "\ \ \ x \ \ \ Integer \ (Integer->including\<^sub>B\<^sub>a\<^sub>g(x))"} + +and + + @{text "\ \ \ x \ \ \ (Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l->includes\<^sub>B\<^sub>a\<^sub>g(x))"} + @{text "\ \ \ x \ \ \ Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l->including\<^sub>B\<^sub>a\<^sub>g(x))"} + +which characterize the infiniteness of these bags by a recursive property on these bags. +*} + +text{* In the same spirit, we proceed similarly for the remaining base types: *} + +definition Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ x. if x = Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Some None) then 1 else 0))" + +definition Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y :: "('\,Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\_. 0))" + +lemma Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def + bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +by((subst (asm) Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, auto simp add: bot_option_def null_option_def bot_Void_def), + (subst (asm) Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, auto simp add: bot_option_def null_option_def))+ + +lemma Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y_defined : "\ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y = true" +apply(rule ext, auto simp: Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def + bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +by((subst (asm) Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, auto simp add: bot_option_def null_option_def bot_Void_def))+ + +lemma assumes "\ \ \ (V :: ('\,Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag)" + shows "\ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" +proof - + have A:"\x y. x \ {} \ \y. y\ x" + by (metis all_not_in_conv) +show "?thesis" + apply(case_tac "V \") + proof - fix y show "V \ = Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e y \ + y \ {X. X = \ \ X = null \ \\X\\ \ = 0} \ + \ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" + apply(insert assms, case_tac y, simp add: bot_option_def, simp add: bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def foundation16) + apply(simp add: bot_option_def null_option_def) + apply(erule disjE, metis OclValid_def defined_def foundation2 null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def true_def) + proof - fix a show "V \ = Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \a\ \ \a\ \ = 0 \ \ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" + apply(case_tac a, simp, insert assms, metis OclValid_def foundation16 null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def true_def) + apply(simp) + proof - fix aa show " V \ = Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\aa\\ \ aa \ = 0 \ \ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" + apply(case_tac "aa (Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\) = 0", + rule disjI2, + insert assms, + simp add: Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y_def OclValid_def ApproxEq_def Rep_Set_base_def true_def Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse image_def) + apply(intro allI) + proof - fix x fix b show " V \ = Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\aa\\ \ aa \ = 0 \ aa (Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\) = 0 \ (\ V) \ = \\True\\ \ \ b < aa x" + apply (case_tac x, auto) + apply (simp add: bot_Void_def bot_option_def) + apply (simp add: bot_option_def null_option_def) + done + apply_end(simp+, rule disjI1) + show "V \ = Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\aa\\ \ aa \ = 0 \ 0 < aa (Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\) \ \ \ \ V \ \ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l" + apply(simp add: Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def OclValid_def ApproxEq_def Rep_Set_base_def true_def Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse image_def, + subst Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp) + using bot_Void_def apply auto[1] + apply(simp) + apply(rule equalityI, rule subsetI, simp) + proof - fix x show "V \ = Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\aa\\ \ + aa \ = 0 \ 0 < aa (Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\) \ (\ V) \ = \\True\\ \ \b. b < aa x \ x = Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + apply( case_tac x, auto) + apply (simp add: bot_Void_def bot_option_def) + by (simp add: bot_option_def null_option_def) + qed ((simp add: bot_Void_def bot_option_def)+, blast) +qed qed qed qed qed + +definition Boolean :: "('\,Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Boolean \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | Some None \ 0 | _ \ 1))" + +definition Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | _ \ 1))" + +lemma Boolean_defined : "\ Boolean = true" +apply(rule ext, auto simp: Boolean_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +definition String :: "('\,String\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "String \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | Some None \ 0 | _ \ 1))" + +definition String\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,String\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "String\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | _ \ 1))" + +lemma String_defined : "\ String = true" +apply(rule ext, auto simp: String_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma String\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ String\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: String\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +definition Real :: "('\,Real\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Real \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | Some None \ 0 | _ \ 1))" + +definition Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Real\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Bag" +where "Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (\ None \ 0 | _ \ 1))" + +lemma Real_defined : "\ Real = true" +apply(rule ext, auto simp: Real_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +subsection{* Basic Properties of the Bag Type*} + +text{* Every element in a defined bag is valid. *} + +lemma Bag_inv_lemma: "\ \ (\ X) \ \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ bot = 0" +apply(insert Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e [of "X \"], simp) +apply(auto simp: OclValid_def defined_def false_def true_def cp_def + bot_fun_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def + split:split_if_asm) + apply(erule contrapos_pp [of "Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \) = bot"]) + apply(subst Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], rule Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp) + apply(simp add: Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) +apply(erule contrapos_pp [of "Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \) = null"]) +apply(subst Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], rule Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp) +apply(simp add: Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse null_option_def) +by (simp add: bot_option_def) + +lemma Bag_inv_lemma' : + assumes x_def : "\ \ \ X" + and e_mem : "\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ e \ 1" + shows "\ \ \ (\_. e)" +apply(case_tac "e = bot", insert assms, drule Bag_inv_lemma, simp) +by (simp add: foundation18') + +lemma abs_rep_simp' : + assumes S_all_def : "\ \ \ S" + shows "Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ = S \" +proof - + have discr_eq_false_true : "\\. (false \ = true \) = False" by(simp add: false_def true_def) + show ?thesis + apply(insert S_all_def, simp add: OclValid_def defined_def) + apply(rule mp[OF Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_induct[where P = "\S. (if S = \ \ \ S = null \ + then false \ else true \) = true \ \ + Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\\\ = S"]], + rename_tac S') + apply(simp add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse discr_eq_false_true) + apply(case_tac S') apply(simp add: bot_fun_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def)+ + apply(rename_tac S'', case_tac S'') apply(simp add: null_fun_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def)+ + done +qed + +lemma invalid_bag_OclNot_defined [simp,code_unfold]:"\(invalid::('\,'\::null) Bag) = false" by simp +lemma null_bag_OclNot_defined [simp,code_unfold]:"\(null::('\,'\::null) Bag) = false" +by(simp add: defined_def null_fun_def) +lemma invalid_bag_valid [simp,code_unfold]:"\(invalid::('\,'\::null) Bag) = false" +by simp +lemma null_bag_valid [simp,code_unfold]:"\(null::('\,'\::null) Bag) = true" +apply(simp add: valid_def null_fun_def bot_fun_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +apply(subst Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject,simp_all add: null_option_def bot_option_def) +done + +text{* ... which means that we can have a type @{text "('\,('\,('\) Integer) Bag) Bag"} +corresponding exactly to Bag(Bag(Integer)) in OCL notation. Note that the parameter +@{text "'\"} still refers to the object universe; making the OCL semantics entirely parametric +in the object universe makes it possible to study (and prove) its properties +independently from a concrete class diagram. *} + +subsection{* Definition: Strict Equality \label{sec:bag-strict-equality}*} + +text{* After the part of foundational operations on bags, we detail here equality on bags. +Strong equality is inherited from the OCL core, but we have to consider +the case of the strict equality. We decide to overload strict equality in the +same way we do for other value's in OCL:*} + +overloading StrictRefEq \ "StrictRefEq :: [('\,'\::null)Bag,('\,'\::null)Bag] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>B\<^sub>a\<^sub>g : + "(x::('\,'\::null)Bag) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y)\ + else invalid \" +end + +text{* One might object here that for the case of objects, this is an empty definition. +The answer is no, we will restrain later on states and objects such that any object +has its oid stored inside the object (so the ref, under which an object can be referenced +in the store will represented in the object itself). For such well-formed stores that satisfy +this invariant (the WFF-invariant), the referential equality and the +strong equality---and therefore the strict equality on bags in the sense above---coincides.*} + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>B\<^sub>a\<^sub>g : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\,'\::null)Bag) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>B\<^sub>a\<^sub>g) + + + +subsection{* Constants: mtBag *} +definition mtBag::"('\,'\::null) Bag" ("Bag{}") +where "Bag{} \ (\ \. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\_. 0::nat\\ )" + + +lemma mtBag_defined[simp,code_unfold]:"\(Bag{}) = true" +apply(rule ext, auto simp: mtBag_def defined_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_fun_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + +lemma mtBag_valid[simp,code_unfold]:"\(Bag{}) = true" +apply(rule ext,auto simp: mtBag_def valid_def + bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_fun_def) +by(simp_all add: Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + +lemma mtBag_rep_bag: "\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Bag{} \)\\ = (\ _. 0)" + apply(simp add: mtBag_def, subst Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) +by(simp add: bot_option_def)+ + +text_raw{* \isatagafp *} + +lemma [simp,code_unfold]: "const Bag{}" +by(simp add: const_def mtBag_def) + + +text{* Note that the collection types in OCL allow for null to be included; + however, there is the null-collection into which inclusion yields invalid. *} + +text_raw{* \endisatagafp *} + +subsection{* Definition: Including *} + +definition OclIncluding :: "[('\,'\::null) Bag,('\,'\) val] \ ('\,'\) Bag" +where "OclIncluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e(x \)\\ + ((y \):=\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e(x \)\\(y \)+1) + \\ + else invalid \ )" +notation OclIncluding ("_->including\<^sub>B\<^sub>a\<^sub>g'(_')") + +interpretation OclIncluding : profile_bin\<^sub>d_\<^sub>v OclIncluding "\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ + (y := \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ y + 1)\\" +proof - + let ?X = "\x y. \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e(x)\\ ((y):=\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e(x)\\( y )+1)" + show "profile_bin\<^sub>d_\<^sub>v OclIncluding (\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ ?X x y \\)" + apply unfold_locales + apply(auto simp:OclIncluding_def bot_option_def null_option_def + bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + by(subst (asm) Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, simp_all, + metis (mono_tags, lifting) Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_option_def mem_Collect_eq null_option_def, + simp add: bot_option_def null_option_def)+ +qed + +syntax + "_OclFinbag" :: "args => ('\,'a::null) Bag" ("Bag{(_)}") +translations + "Bag{x, xs}" == "CONST OclIncluding (Bag{xs}) x" + "Bag{x}" == "CONST OclIncluding (Bag{}) x " + + +subsection{* Definition: Excluding *} + +definition OclExcluding :: "[('\,'\::null) Bag,('\,'\) val] \ ('\,'\) Bag" +where "OclExcluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ ((y \):=0::nat) \\ + else invalid \ )" +notation OclExcluding ("_->excluding\<^sub>B\<^sub>a\<^sub>g'(_')") + +interpretation OclExcluding: profile_bin\<^sub>d_\<^sub>v OclExcluding + "\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e(x)\\(y:=0::nat)\\" +proof - + show "profile_bin\<^sub>d_\<^sub>v OclExcluding (\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\(y := 0)\\)" + apply unfold_locales + apply(auto simp:OclExcluding_def bot_option_def null_option_def + null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + by(subst (asm) Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, + simp_all add: bot_option_def null_option_def, + metis (mono_tags, lifting) Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_option_def + mem_Collect_eq null_option_def)+ +qed + +subsection{* Definition: Includes *} + +definition OclIncludes :: "[('\,'\::null) Bag,('\,'\) val] \ '\ Boolean" +where "OclIncludes x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\ \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ (y \) > 0 \\ + else \ )" +notation OclIncludes ("_->includes\<^sub>B\<^sub>a\<^sub>g'(_')" (*[66,65]65*)) + +interpretation OclIncludes : profile_bin\<^sub>d_\<^sub>v OclIncludes "\x y. \\ \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ y > 0 \\" +by(unfold_locales, auto simp:OclIncludes_def bot_option_def null_option_def invalid_def) + +subsection{* Definition: Excludes *} + +definition OclExcludes :: "[('\,'\::null) Bag,('\,'\) val] \ '\ Boolean" +where "OclExcludes x y = (not(OclIncludes x y))" +notation OclExcludes ("_->excludes\<^sub>B\<^sub>a\<^sub>g'(_')" (*[66,65]65*)) + +text{* The case of the size definition is somewhat special, we admit +explicitly in Featherweight OCL the possibility of infinite bags. For +the size definition, this requires an extra condition that assures +that the cardinality of the bag is actually a defined integer. *} + +interpretation OclExcludes : profile_bin\<^sub>d_\<^sub>v OclExcludes "\x y. \\ \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ y \ 0 \\" +by(unfold_locales, auto simp:OclExcludes_def OclIncludes_def OclNot_def bot_option_def null_option_def invalid_def) + +subsection{* Definition: Size *} + +definition OclSize :: "('\,'\::null)Bag \ '\ Integer" +where "OclSize x = (\ \. if (\ x) \ = true \ \ finite (Rep_Bag_base x \) + then \\ int (card (Rep_Bag_base x \)) \\ + else \ )" +notation (* standard ascii syntax *) + OclSize ("_->size\<^sub>B\<^sub>a\<^sub>g'(')" (*[66]*)) + +text{* The following definition follows the requirement of the +standard to treat null as neutral element of bags. It is +a well-documented exception from the general strictness +rule and the rule that the distinguished argument self should +be non-null. *} + +(*TODO Locale - Equivalent*) + + +subsection{* Definition: IsEmpty *} + +definition OclIsEmpty :: "('\,'\::null) Bag \ '\ Boolean" +where "OclIsEmpty x = ((\ x and not (\ x)) or ((OclSize x) \ \))" +notation OclIsEmpty ("_->isEmpty\<^sub>B\<^sub>a\<^sub>g'(')" (*[66]*)) + +(*TODO Locale - Equivalent*) + +subsection{* Definition: NotEmpty *} + +definition OclNotEmpty :: "('\,'\::null) Bag \ '\ Boolean" +where "OclNotEmpty x = not(OclIsEmpty x)" +notation OclNotEmpty ("_->notEmpty\<^sub>B\<^sub>a\<^sub>g'(')" (*[66]*)) + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Any *} + +(* Slight breach of naming convention in order to avoid naming conflict on constant.*) +definition OclANY :: "[('\,'\::null) Bag] \ ('\,'\) val" +where "OclANY x = (\ \. if (\ x) \ = true \ + then if (\ x and OclNotEmpty x) \ = true \ + then SOME y. y \ (Rep_Set_base x \) + else null \ + else \ )" +notation OclANY ("_->any\<^sub>B\<^sub>a\<^sub>g'(')") + +(*TODO Locale - Equivalent*) + +(* actually, this definition covers only: X->any\<^sub>B\<^sub>a\<^sub>g(true) of the standard, which foresees +a (totally correct) high-level definition +source->any\<^sub>B\<^sub>a\<^sub>g(iterator | body) = +source->select(iterator | body)->asSequence()->first(). Since we don't have sequences, +we have to go for a direct---restricted---definition. *) + +subsection{* Definition: Forall *} + +text{* The definition of OclForall mimics the one of @{term "OclAnd"}: +OclForall is not a strict operation. *} +definition OclForall :: "[('\,'\::null)Bag,('\,'\)val\('\)Boolean] \ '\ Boolean" +where "OclForall S P = (\ \. if (\ S) \ = true \ + then if (\x\Rep_Set_base S \. P (\_. x) \ = false \) + then false \ + else if (\x\Rep_Set_base S \. P (\_. x) \ = invalid \) + then invalid \ + else if (\x\Rep_Set_base S \. P (\_. x) \ = null \) + then null \ + else true \ + else \)" +syntax + "_OclForallBag" :: "[('\,'\::null) Bag,id,('\)Boolean] \ '\ Boolean" ("(_)->forAll\<^sub>B\<^sub>a\<^sub>g'(_|_')") +translations + "X->forAll\<^sub>B\<^sub>a\<^sub>g(x | P)" == "CONST UML_Bag.OclForall X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Exists *} + +text{* Like OclForall, OclExists is also not strict. *} +definition OclExists :: "[('\,'\::null) Bag,('\,'\)val\('\)Boolean] \ '\ Boolean" +where "OclExists S P = not(UML_Bag.OclForall S (\ X. not (P X)))" + +syntax + "_OclExistBag" :: "[('\,'\::null) Bag,id,('\)Boolean] \ '\ Boolean" ("(_)->exists\<^sub>B\<^sub>a\<^sub>g'(_|_')") +translations + "X->exists\<^sub>B\<^sub>a\<^sub>g(x | P)" == "CONST UML_Bag.OclExists X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Iterate *} + +definition OclIterate :: "[('\,'\::null) Bag,('\,'\::null)val, + ('\,'\)val\('\,'\)val\('\,'\)val] \ ('\,'\)val" +where "OclIterate S A F = (\ \. if (\ S) \ = true \ \ (\ A) \ = true \ \ finite (Rep_Bag_base S \) + then Finite_Set.fold (F o (\a \. a) o fst) A (Rep_Bag_base S \) \ + else \)" +syntax + "_OclIterateBag" :: "[('\,'\::null) Bag, idt, idt, '\, '\] => ('\,'\)val" + ("_ ->iterate\<^sub>B\<^sub>a\<^sub>g'(_;_=_ | _')" (*[71,100,70]50*)) +translations + "X->iterate\<^sub>B\<^sub>a\<^sub>g(a; x = A | P)" == "CONST OclIterate X A (%a. (% x. P))" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Select *} + + +definition OclSelect :: "[('\,'\::null)Bag,('\,'\)val\('\)Boolean] \ ('\,'\)Bag" +where "OclSelect S P = (\\. if (\ S) \ = true \ + then if (\x\Rep_Set_base S \. P(\ _. x) \ = invalid \) + then invalid \ + else Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\x. + let n = \\ Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \) \\ x in + if n = 0 | P (\_. x) \ = false \ then + 0 + else + n\\ + else invalid \)" +syntax + "_OclSelectBag" :: "[('\,'\::null) Bag,id,('\)Boolean] \ '\ Boolean" ("(_)->select\<^sub>B\<^sub>a\<^sub>g'(_|_')") +translations + "X->select\<^sub>B\<^sub>a\<^sub>g(x | P)" == "CONST OclSelect X (% x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Reject *} + +definition OclReject :: "[('\,'\::null)Bag,('\,'\)val\('\)Boolean] \ ('\,'\::null)Bag" +where "OclReject S P = OclSelect S (not o P)" +syntax + "_OclRejectBag" :: "[('\,'\::null) Bag,id,('\)Boolean] \ '\ Boolean" ("(_)->reject\<^sub>B\<^sub>a\<^sub>g'(_|_')") +translations + "X->reject\<^sub>B\<^sub>a\<^sub>g(x | P)" == "CONST OclReject X (% x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: IncludesAll *} + +definition OclIncludesAll :: "[('\,'\::null) Bag,('\,'\) Bag] \ '\ Boolean" +where "OclIncludesAll x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\Rep_Bag_base y \ \ Rep_Bag_base x \ \\ + else \ )" +notation OclIncludesAll ("_->includesAll\<^sub>B\<^sub>a\<^sub>g'(_')" (*[66,65]65*)) + +interpretation OclIncludesAll : profile_bin\<^sub>d_\<^sub>d OclIncludesAll "\x y. \\Rep_Bag_base' y \ Rep_Bag_base' x \\" +by(unfold_locales, auto simp:OclIncludesAll_def bot_option_def null_option_def invalid_def + Rep_Bag_base_def Rep_Bag_base'_def) + +subsection{* Definition: ExcludesAll *} + +definition OclExcludesAll :: "[('\,'\::null) Bag,('\,'\) Bag] \ '\ Boolean" +where "OclExcludesAll x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\Rep_Bag_base y \ \ Rep_Bag_base x \ = {} \\ + else \ )" +notation OclExcludesAll ("_->excludesAll\<^sub>B\<^sub>a\<^sub>g'(_')" (*[66,65]65*)) + +interpretation OclExcludesAll : profile_bin\<^sub>d_\<^sub>d OclExcludesAll "\x y. \\Rep_Bag_base' y \ Rep_Bag_base' x = {} \\" +by(unfold_locales, auto simp:OclExcludesAll_def bot_option_def null_option_def invalid_def + Rep_Bag_base_def Rep_Bag_base'_def) + +subsection{* Definition: Union *} + +definition OclUnion :: "[('\,'\::null) Bag,('\,'\) Bag] \ ('\,'\) Bag" +where "OclUnion x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \ X. \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ X + + \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\ X\\ + else invalid \ )" +notation OclUnion ("_->union\<^sub>B\<^sub>a\<^sub>g'(_')" (*[66,65]65*)) + +interpretation OclUnion : + profile_bin\<^sub>d_\<^sub>d OclUnion "\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \ X. \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ X + + \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ X\\" +proof - + show "profile_bin\<^sub>d_\<^sub>d OclUnion (\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \ X. \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ X + \\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ X\\)" + apply unfold_locales + apply(auto simp:OclUnion_def bot_option_def null_option_def + null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + by(subst (asm) Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, + simp_all add: bot_option_def null_option_def, + metis (mono_tags, lifting) Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_option_def mem_Collect_eq + null_option_def)+ +qed + +subsection{* Definition: Intersection *} + +definition OclIntersection :: "[('\,'\::null) Bag,('\,'\) Bag] \ ('\,'\) Bag" +where "OclIntersection x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\ \ X. min (\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ X) + (\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\ X)\\ + else \ )" +notation OclIntersection("_->intersection\<^sub>B\<^sub>a\<^sub>g'(_')" (*[71,70]70*)) + +interpretation OclIntersection : + profile_bin\<^sub>d_\<^sub>d OclIntersection "\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \ X. min (\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ X) + (\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ X)\\" +proof - + show "profile_bin\<^sub>d_\<^sub>d OclIntersection (\x y. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \ X. min (\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ X) + (\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ X)\\)" + apply unfold_locales + apply(auto simp:OclIntersection_def bot_option_def null_option_def + null_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def invalid_def) + by(subst (asm) Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, + simp_all add: bot_option_def null_option_def, + metis (mono_tags, lifting) Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_option_def mem_Collect_eq min_0R + null_option_def)+ +qed + +subsection{* Definition: Count *} + +definition OclCount :: "[('\,'\::null) Bag,('\,'\) val] \ ('\) Integer" +where "OclCount x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\int(\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ (y \))\\ + else invalid \ )" +notation OclCount ("_->count\<^sub>B\<^sub>a\<^sub>g'(_')" (*[66,65]65*)) + +interpretation OclCount : profile_bin\<^sub>d_\<^sub>d OclCount "\x y. \\int(\\Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ y)\\" +by(unfold_locales, auto simp:OclCount_def bot_option_def null_option_def) + +subsection{* Definition (future operators) *} + +consts (* abstract bag collection operations *) + OclSum :: " ('\,'\::null) Bag \ '\ Integer" + +notation OclSum ("_->sum\<^sub>B\<^sub>a\<^sub>g'(')" (*[66]*)) + +subsection{* Logical Properties *} + +text{* OclIncluding *} + +lemma OclIncluding_valid_args_valid: +"(\ \ \(X->including\<^sub>B\<^sub>a\<^sub>g(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (metis (hide_lams, no_types) OclIncluding.def_valid_then_def OclIncluding.defined_args_valid) + +lemma OclIncluding_valid_args_valid''[simp,code_unfold]: +"\(X->including\<^sub>B\<^sub>a\<^sub>g(x)) = ((\ X) and (\ x))" +by (simp add: OclIncluding.def_valid_then_def) + +text{* etc. etc. *} +text_raw{* \isatagafp *} + +text{* OclExcluding *} + +lemma OclExcluding_valid_args_valid: +"(\ \ \(X->excluding\<^sub>B\<^sub>a\<^sub>g(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (metis OclExcluding.def_valid_then_def OclExcluding.defined_args_valid) + +lemma OclExcluding_valid_args_valid''[simp,code_unfold]: +"\(X->excluding\<^sub>B\<^sub>a\<^sub>g(x)) = ((\ X) and (\ x))" +by (simp add: OclExcluding.def_valid_then_def) + +text{* OclIncludes *} + +lemma OclIncludes_valid_args_valid: +"(\ \ \(X->includes\<^sub>B\<^sub>a\<^sub>g(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (simp add: OclIncludes.def_valid_then_def foundation10') + +lemma OclIncludes_valid_args_valid''[simp,code_unfold]: +"\(X->includes\<^sub>B\<^sub>a\<^sub>g(x)) = ((\ X) and (\ x))" +by (simp add: OclIncludes.def_valid_then_def) + +text{* OclExcludes *} + +lemma OclExcludes_valid_args_valid: +"(\ \ \(X->excludes\<^sub>B\<^sub>a\<^sub>g(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (simp add: OclExcludes.def_valid_then_def foundation10') + +lemma OclExcludes_valid_args_valid''[simp,code_unfold]: +"\(X->excludes\<^sub>B\<^sub>a\<^sub>g(x)) = ((\ X) and (\ x))" +by (simp add: OclExcludes.def_valid_then_def) + +text{* OclSize *} + +lemma OclSize_defined_args_valid: "\ \ \ (X->size\<^sub>B\<^sub>a\<^sub>g()) \ \ \ \ X" +by(auto simp: OclSize_def OclValid_def true_def valid_def false_def StrongEq_def + defined_def invalid_def bot_fun_def null_fun_def + split: bool.split_asm HOL.split_if_asm option.split) + +lemma OclSize_infinite: +assumes non_finite:"\ \ not(\(S->size\<^sub>B\<^sub>a\<^sub>g()))" +shows "(\ \ not(\(S))) \ \ finite (Rep_Bag_base S \)" +apply(insert non_finite, simp) +apply(rule impI) +apply(simp add: OclSize_def OclValid_def defined_def bot_fun_def null_fun_def bot_option_def null_option_def + split: split_if_asm) +done + +lemma "\ \ \ X \ \ finite (Rep_Bag_base X \) \ \ \ \ \ (X->size\<^sub>B\<^sub>a\<^sub>g())" +by(simp add: OclSize_def OclValid_def defined_def bot_fun_def false_def true_def) + +lemma size_defined: + assumes X_finite: "\\. finite (Rep_Bag_base X \)" + shows "\ (X->size\<^sub>B\<^sub>a\<^sub>g()) = \ X" + apply(rule ext, simp add: cp_defined[of "X->size\<^sub>B\<^sub>a\<^sub>g()"] OclSize_def) + apply(simp add: defined_def bot_option_def bot_fun_def null_option_def null_fun_def X_finite) +done + +lemma size_defined': + assumes X_finite: "finite (Rep_Bag_base X \)" + shows "(\ \ \ (X->size\<^sub>B\<^sub>a\<^sub>g())) = (\ \ \ X)" + apply(simp add: cp_defined[of "X->size\<^sub>B\<^sub>a\<^sub>g()"] OclSize_def OclValid_def) + apply(simp add: defined_def bot_option_def bot_fun_def null_option_def null_fun_def X_finite) +done + +text{* OclIsEmpty *} + +lemma OclIsEmpty_defined_args_valid:"\ \ \ (X->isEmpty\<^sub>B\<^sub>a\<^sub>g()) \ \ \ \ X" + apply(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def + bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def + split: split_if_asm) + apply(case_tac "(X->size\<^sub>B\<^sub>a\<^sub>g() \ \) \", simp add: bot_option_def, simp, rename_tac x) + apply(case_tac x, simp add: null_option_def bot_option_def, simp) + apply(simp add: OclSize_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def) +by (metis (hide_lams, no_types) + bot_fun_def OclValid_def defined_def foundation2 invalid_def) + +lemma "\ \ \ (null->isEmpty\<^sub>B\<^sub>a\<^sub>g())" +by(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def + bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def null_is_valid + split: split_if_asm) + +lemma OclIsEmpty_infinite: "\ \ \ X \ \ finite (Rep_Bag_base X \) \ \ \ \ \ (X->isEmpty\<^sub>B\<^sub>a\<^sub>g())" + apply(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def + bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def + split: split_if_asm) + apply(case_tac "(X->size\<^sub>B\<^sub>a\<^sub>g() \ \) \", simp add: bot_option_def, simp, rename_tac x) + apply(case_tac x, simp add: null_option_def bot_option_def, simp) +by(simp add: OclSize_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def bot_fun_def false_def true_def invalid_def) + +text{* OclNotEmpty *} + +lemma OclNotEmpty_defined_args_valid:"\ \ \ (X->notEmpty\<^sub>B\<^sub>a\<^sub>g()) \ \ \ \ X" +by (metis (hide_lams, no_types) OclNotEmpty_def OclNot_defargs OclNot_not foundation6 foundation9 + OclIsEmpty_defined_args_valid) + +lemma "\ \ \ (null->notEmpty\<^sub>B\<^sub>a\<^sub>g())" +by (metis (hide_lams, no_types) OclNotEmpty_def OclAnd_false1 OclAnd_idem OclIsEmpty_def + OclNot3 OclNot4 OclOr_def defined2 defined4 transform1 valid2) + +lemma OclNotEmpty_infinite: "\ \ \ X \ \ finite (Rep_Bag_base X \) \ \ \ \ \ (X->notEmpty\<^sub>B\<^sub>a\<^sub>g())" + apply(simp add: OclNotEmpty_def) + apply(drule OclIsEmpty_infinite, simp) +by (metis OclNot_defargs OclNot_not foundation6 foundation9) + +lemma OclNotEmpty_has_elt : "\ \ \ X \ + \ \ X->notEmpty\<^sub>B\<^sub>a\<^sub>g() \ + \e. e \ (Rep_Bag_base X \)" +proof - + have s_non_empty: "\S. S \ {} \ \x. x \ S" + by blast +show "\ \ \ X \ + \ \ X->notEmpty\<^sub>B\<^sub>a\<^sub>g() \ + ?thesis" + apply(simp add: OclNotEmpty_def OclIsEmpty_def deMorgan1 deMorgan2, drule foundation5) + apply(subst (asm) (2) OclNot_def, + simp add: OclValid_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def + split: split_if_asm) + prefer 2 + apply(simp add: invalid_def bot_option_def true_def) + apply(simp add: OclSize_def valid_def split: split_if_asm, + simp_all add: false_def true_def bot_option_def bot_fun_def OclInt0_def) + apply(drule s_non_empty[of "Rep_Bag_base X \"], erule exE, case_tac x) +by blast +qed + +lemma OclNotEmpty_has_elt' : "\ \ \ X \ + \ \ X->notEmpty\<^sub>B\<^sub>a\<^sub>g() \ + \e. e \ (Rep_Set_base X \)" + apply(drule OclNotEmpty_has_elt, simp) +by(simp add: Rep_Bag_base_def Rep_Set_base_def image_def) + +text{* OclANY *} + +lemma OclANY_defined_args_valid: "\ \ \ (X->any\<^sub>B\<^sub>a\<^sub>g()) \ \ \ \ X" +by(auto simp: OclANY_def OclValid_def true_def valid_def false_def StrongEq_def + defined_def invalid_def bot_fun_def null_fun_def OclAnd_def + split: bool.split_asm HOL.split_if_asm option.split) + +lemma "\ \ \ X \ \ \ X->isEmpty\<^sub>B\<^sub>a\<^sub>g() \ \ \ \ \ (X->any\<^sub>B\<^sub>a\<^sub>g())" + apply(simp add: OclANY_def OclValid_def) + apply(subst cp_defined, subst cp_OclAnd, simp add: OclNotEmpty_def, subst (1 2) cp_OclNot, + simp add: cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_defined[symmetric], + simp add: false_def true_def) +by(drule foundation20[simplified OclValid_def true_def], simp) + +lemma OclANY_valid_args_valid: +"(\ \ \(X->any\<^sub>B\<^sub>a\<^sub>g())) = (\ \ \ X)" +proof - + have A: "(\ \ \(X->any\<^sub>B\<^sub>a\<^sub>g())) \ ((\ \(\ X)))" + by(auto simp: OclANY_def OclValid_def true_def valid_def false_def StrongEq_def + defined_def invalid_def bot_fun_def null_fun_def + split: bool.split_asm HOL.split_if_asm option.split) + have B: "(\ \(\ X)) \ (\ \ \(X->any\<^sub>B\<^sub>a\<^sub>g()))" + apply(auto simp: OclANY_def OclValid_def true_def false_def StrongEq_def + defined_def invalid_def valid_def bot_fun_def null_fun_def + bot_option_def null_option_def null_is_valid + OclAnd_def + split: bool.split_asm HOL.split_if_asm option.split) + apply(frule Bag_inv_lemma[OF foundation16[THEN iffD2], OF conjI], simp) + apply(subgoal_tac "(\ X) \ = true \") + prefer 2 + apply (metis (hide_lams, no_types) OclValid_def foundation16) + apply(simp add: true_def, + drule OclNotEmpty_has_elt'[simplified OclValid_def true_def], simp) + apply(erule exE, + rule someI2[where Q = "\x. x \ \" and P = "\y. y \ (Rep_Set_base X \)", + simplified not_def, THEN mp], simp, auto) + by(simp add: Rep_Set_base_def image_def) + show ?thesis by(auto dest:A intro:B) +qed + +lemma OclANY_valid_args_valid''[simp,code_unfold]: +"\(X->any\<^sub>B\<^sub>a\<^sub>g()) = (\ X)" +by(auto intro!: OclANY_valid_args_valid transform2_rev) + +(* and higher order ones : forall, exists, iterate, select, reject... *) +text_raw{* \endisatagafp *} + +subsection{* Execution Laws with Invalid or Null or Infinite Set as Argument *} + +text{* OclIncluding *} (* properties already generated by the corresponding locale *) + +text{* OclExcluding *} (* properties already generated by the corresponding locale *) + +text{* OclIncludes *} (* properties already generated by the corresponding locale *) + +text{* OclExcludes *} (* properties already generated by the corresponding locale *) + +text{* OclSize *} + +lemma OclSize_invalid[simp,code_unfold]:"(invalid->size\<^sub>B\<^sub>a\<^sub>g()) = invalid" +by(simp add: bot_fun_def OclSize_def invalid_def defined_def valid_def false_def true_def) + +lemma OclSize_null[simp,code_unfold]:"(null->size\<^sub>B\<^sub>a\<^sub>g()) = invalid" +by(rule ext, + simp add: bot_fun_def null_fun_def null_is_valid OclSize_def + invalid_def defined_def valid_def false_def true_def) + +text{* OclIsEmpty *} + +lemma OclIsEmpty_invalid[simp,code_unfold]:"(invalid->isEmpty\<^sub>B\<^sub>a\<^sub>g()) = invalid" +by(simp add: OclIsEmpty_def) + +lemma OclIsEmpty_null[simp,code_unfold]:"(null->isEmpty\<^sub>B\<^sub>a\<^sub>g()) = true" +by(simp add: OclIsEmpty_def) + +text{* OclNotEmpty *} + +lemma OclNotEmpty_invalid[simp,code_unfold]:"(invalid->notEmpty\<^sub>B\<^sub>a\<^sub>g()) = invalid" +by(simp add: OclNotEmpty_def) + +lemma OclNotEmpty_null[simp,code_unfold]:"(null->notEmpty\<^sub>B\<^sub>a\<^sub>g()) = false" +by(simp add: OclNotEmpty_def) + +text{* OclANY *} + +lemma OclANY_invalid[simp,code_unfold]:"(invalid->any\<^sub>B\<^sub>a\<^sub>g()) = invalid" +by(simp add: bot_fun_def OclANY_def invalid_def defined_def valid_def false_def true_def) + +lemma OclANY_null[simp,code_unfold]:"(null->any\<^sub>B\<^sub>a\<^sub>g()) = null" +by(simp add: OclANY_def false_def true_def) + +text{* OclForall *} + +lemma OclForall_invalid[simp,code_unfold]:"invalid->forAll\<^sub>B\<^sub>a\<^sub>g(a| P a) = invalid" +by(simp add: bot_fun_def invalid_def OclForall_def defined_def valid_def false_def true_def) + +lemma OclForall_null[simp,code_unfold]:"null->forAll\<^sub>B\<^sub>a\<^sub>g(a | P a) = invalid" +by(simp add: bot_fun_def invalid_def OclForall_def defined_def valid_def false_def true_def) + +text{* OclExists *} + +lemma OclExists_invalid[simp,code_unfold]:"invalid->exists\<^sub>B\<^sub>a\<^sub>g(a| P a) = invalid" +by(simp add: OclExists_def) + +lemma OclExists_null[simp,code_unfold]:"null->exists\<^sub>B\<^sub>a\<^sub>g(a | P a) = invalid" +by(simp add: OclExists_def) + +text{* OclIterate *} + +lemma OclIterate_invalid[simp,code_unfold]:"invalid->iterate\<^sub>B\<^sub>a\<^sub>g(a; x = A | P a x) = invalid" +by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) + +lemma OclIterate_null[simp,code_unfold]:"null->iterate\<^sub>B\<^sub>a\<^sub>g(a; x = A | P a x) = invalid" +by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) + + +lemma OclIterate_invalid_args[simp,code_unfold]:"S->iterate\<^sub>B\<^sub>a\<^sub>g(a; x = invalid | P a x) = invalid" +by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) + +text{* An open question is this ... *} +lemma (*OclIterate_null_args[simp,code_unfold]:*) "S->iterate\<^sub>B\<^sub>a\<^sub>g(a; x = null | P a x) = invalid" +oops +(* In the definition above, this does not hold in general. + And I believe, this is how it should be ... *) + +lemma OclIterate_infinite: +assumes non_finite: "\ \ not(\(S->size\<^sub>B\<^sub>a\<^sub>g()))" +shows "(OclIterate S A F) \ = invalid \" +apply(insert non_finite [THEN OclSize_infinite]) +apply(subst (asm) foundation9, simp) +by(metis OclIterate_def OclValid_def invalid_def) + +text{* OclSelect *} + +lemma OclSelect_invalid[simp,code_unfold]:"invalid->select\<^sub>B\<^sub>a\<^sub>g(a | P a) = invalid" +by(simp add: bot_fun_def invalid_def OclSelect_def defined_def valid_def false_def true_def) + +lemma OclSelect_null[simp,code_unfold]:"null->select\<^sub>B\<^sub>a\<^sub>g(a | P a) = invalid" +by(simp add: bot_fun_def invalid_def OclSelect_def defined_def valid_def false_def true_def) + +text{* OclReject *} + +lemma OclReject_invalid[simp,code_unfold]:"invalid->reject\<^sub>B\<^sub>a\<^sub>g(a | P a) = invalid" +by(simp add: OclReject_def) + +lemma OclReject_null[simp,code_unfold]:"null->reject\<^sub>B\<^sub>a\<^sub>g(a | P a) = invalid" +by(simp add: OclReject_def) + +text_raw{* \isatagafp *} + +subsubsection{* Context Passing *} + +lemma cp_OclIncludes1: +"(X->includes\<^sub>B\<^sub>a\<^sub>g(x)) \ = (X->includes\<^sub>B\<^sub>a\<^sub>g(\ _. x \)) \" +by(auto simp: OclIncludes_def StrongEq_def invalid_def + cp_defined[symmetric] cp_valid[symmetric]) + +lemma cp_OclSize: "X->size\<^sub>B\<^sub>a\<^sub>g() \ = ((\_. X \)->size\<^sub>B\<^sub>a\<^sub>g()) \" +by(simp add: OclSize_def cp_defined[symmetric] Rep_Bag_base_def) + +lemma cp_OclIsEmpty: "X->isEmpty\<^sub>B\<^sub>a\<^sub>g() \ = ((\_. X \)->isEmpty\<^sub>B\<^sub>a\<^sub>g()) \" + apply(simp only: OclIsEmpty_def) + apply(subst (2) cp_OclOr, + subst cp_OclAnd, + subst cp_OclNot, + subst StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0) +by(simp add: cp_defined[symmetric] cp_valid[symmetric] StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0[symmetric] + cp_OclSize[symmetric] cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) + +lemma cp_OclNotEmpty: "X->notEmpty\<^sub>B\<^sub>a\<^sub>g() \ = ((\_. X \)->notEmpty\<^sub>B\<^sub>a\<^sub>g()) \" + apply(simp only: OclNotEmpty_def) + apply(subst (2) cp_OclNot) +by(simp add: cp_OclNot[symmetric] cp_OclIsEmpty[symmetric]) + +lemma cp_OclANY: "X->any\<^sub>B\<^sub>a\<^sub>g() \ = ((\_. X \)->any\<^sub>B\<^sub>a\<^sub>g()) \" + apply(simp only: OclANY_def) + apply(subst (2) cp_OclAnd) +by(simp only: cp_OclAnd[symmetric] cp_defined[symmetric] cp_valid[symmetric] + cp_OclNotEmpty[symmetric] Rep_Set_base_def) + +lemma cp_OclForall: +"(S->forAll\<^sub>B\<^sub>a\<^sub>g(x | P x)) \ = ((\ _. S \)->forAll\<^sub>B\<^sub>a\<^sub>g(x | P (\ _. x \))) \" +by(auto simp add: OclForall_def cp_defined[symmetric] Rep_Set_base_def) + +(* first-order version !*) +lemma cp_OclForall1 [simp,intro!]: +"cp S \ cp (\X. ((S X)->forAll\<^sub>B\<^sub>a\<^sub>g(x | P x)))" +apply(simp add: cp_def) +apply(erule exE, rule exI, intro allI) +apply(erule_tac x=X in allE) +by(subst cp_OclForall, simp) + +lemma (*cp_OclForall2 [simp,intro!]:*) +"cp (\X St x. P (\\. x) X St) \ cp S \ cp (\X. (S X)->forAll\<^sub>B\<^sub>a\<^sub>g(x|P x X)) " +apply(simp only: cp_def) +oops + +lemma (*cp_OclForall:*) +"cp S \ + (\ x. cp(P x)) \ + cp(\X. ((S X)->forAll\<^sub>B\<^sub>a\<^sub>g(x | P x X)))" +oops + +lemma cp_OclExists: +"(S->exists\<^sub>B\<^sub>a\<^sub>g(x | P x)) \ = ((\ _. S \)->exists\<^sub>B\<^sub>a\<^sub>g(x | P (\ _. x \))) \" +by(simp add: OclExists_def OclNot_def, subst cp_OclForall, simp) + +(* first-order version !*) +lemma cp_OclExists1 [simp,intro!]: +"cp S \ cp (\X. ((S X)->exists\<^sub>B\<^sub>a\<^sub>g(x | P x)))" +apply(simp add: cp_def) +apply(erule exE, rule exI, intro allI) +apply(erule_tac x=X in allE) +by(subst cp_OclExists,simp) + +lemma cp_OclIterate: + "(X->iterate\<^sub>B\<^sub>a\<^sub>g(a; x = A | P a x)) \ = + ((\ _. X \)->iterate\<^sub>B\<^sub>a\<^sub>g(a; x = A | P a x)) \" +by(simp add: OclIterate_def cp_defined[symmetric] Rep_Bag_base_def) + +lemma cp_OclSelect: "(X->select\<^sub>B\<^sub>a\<^sub>g(a | P a)) \ = + ((\ _. X \)->select\<^sub>B\<^sub>a\<^sub>g(a | P a)) \" +by(simp add: OclSelect_def cp_defined[symmetric] Rep_Set_base_def) + +lemma cp_OclReject: "(X->reject\<^sub>B\<^sub>a\<^sub>g(a | P a)) \ = ((\ _. X \)->reject\<^sub>B\<^sub>a\<^sub>g(a | P a)) \" +by(simp add: OclReject_def, subst cp_OclSelect, simp) + +lemmas cp_intro''\<^sub>B\<^sub>a\<^sub>g[intro!,simp,code_unfold] = + cp_OclSize [THEN allI[THEN allI[THEN cpI1], of "OclSize"]] + cp_OclIsEmpty [THEN allI[THEN allI[THEN cpI1], of "OclIsEmpty"]] + cp_OclNotEmpty [THEN allI[THEN allI[THEN cpI1], of "OclNotEmpty"]] + cp_OclANY [THEN allI[THEN allI[THEN cpI1], of "OclANY"]] + +subsubsection{* Const *} + +lemma const_OclIncluding[simp,code_unfold] : + assumes const_x : "const x" + and const_S : "const S" + shows "const (S->including\<^sub>B\<^sub>a\<^sub>g(x))" + proof - + have A:"\\ \'. \ (\ \ \ x) \ (S->including\<^sub>B\<^sub>a\<^sub>g(x) \) = (S->including\<^sub>B\<^sub>a\<^sub>g(x) \')" + apply(simp add: foundation18) + apply(erule const_subst[OF const_x const_invalid],simp_all) + by(rule const_charn[OF const_invalid]) + have B: "\ \ \'. \ (\ \ \ S) \ (S->including\<^sub>B\<^sub>a\<^sub>g(x) \) = (S->including\<^sub>B\<^sub>a\<^sub>g(x) \')" + apply(simp add: foundation16', elim disjE) + apply(erule const_subst[OF const_S const_invalid],simp_all) + apply(rule const_charn[OF const_invalid]) + apply(erule const_subst[OF const_S const_null],simp_all) + by(rule const_charn[OF const_invalid]) + show ?thesis + apply(simp only: const_def,intro allI, rename_tac \ \') + apply(case_tac "\ (\ \ \ x)", simp add: A) + apply(case_tac "\ (\ \ \ S)", simp_all add: B) + apply(frule_tac \'1= \' in const_OclValid2[OF const_x, THEN iffD1]) + apply(frule_tac \'1= \' in const_OclValid1[OF const_S, THEN iffD1]) + apply(simp add: OclIncluding_def OclValid_def) + apply(subst (1 2) const_charn[OF const_x]) + apply(subst (1 2) const_charn[OF const_S]) + by simp +qed +text_raw{* \endisatagafp *} + +subsection{* Test Statements *} + +(*Assert "(\ \ (Bag{\_. \\x\\} \ Bag{\_. \\x\\}))" +Assert "(\ \ (Bag{\_. \x\} \ Bag{\_. \x\}))"*) + +instantiation Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (equal)equal +begin + definition "HOL.equal k l \ (k::('a::equal)Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e) = l" + instance by standard (rule equal_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +end + +lemma equal_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_code [code]: + "HOL.equal k (l::('a::{equal,null})Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e k = Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e l" + by (auto simp add: equal Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Rep_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) + +Assert "\ \ (Bag{} \ Bag{})" + +(* +Assert "\ \ not(Bag{\,\} \ Bag{\})" +Assert "\ \ (Bag{\,\} \ Bag{\,\}" +Assert "\ \ (Bag{\,null} \ Bag{null,\}" +Assert "\ \ (Bag{\,invalid,\} \ invalid)" +Assert "\ \ (Bag{\,\}->including\<^sub>B\<^sub>a\<^sub>g(null) \ Bag{\,\,null})" +*) + +(* > *) + +end diff --git a/src/collection_types/UML_Pair.thy b/src/collection_types/UML_Pair.thy new file mode 100644 index 0000000..0280808 --- /dev/null +++ b/src/collection_types/UML_Pair.thy @@ -0,0 +1,219 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Pair.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + +theory UML_Pair +imports "../UML_PropertyProfiles" +begin + +section{* Collection Type Pairs: Operations \label{sec:collection_pairs} *} + +text{* The OCL standard provides the concept of \emph{Tuples}, \ie{} a family of record-types +with projection functions. In FeatherWeight OCL, only the theory of a special case is +developped, namely the type of Pairs, which is, however, sufficient for all applications +since it can be used to mimick all tuples. In particular, it can be used to express operations +with multiple arguments, roles of n-ary associations, ... *} + +subsection{* Semantic Properties of the Type Constructor *} + +lemma A[simp]:"Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x \ None \ Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x \ null \ (fst \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\) \ bot" +by(insert Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e[of x],auto simp:null_option_def bot_option_def) + +lemma A'[simp]:" x \ bot \ x \ null \ (fst \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\) \ bot" +apply(insert Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e[of x], simp add: bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +apply(auto simp:null_option_def bot_option_def) +apply(erule contrapos_np[of "x = Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e None"]) +apply(subst Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], simp) +apply(subst Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp_all,simp add: bot_option_def) +apply(erule contrapos_np[of "x = Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\"]) +apply(subst Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], simp) +apply(subst Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp_all,simp add: null_option_def bot_option_def) +done + +lemma B[simp]:"Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x \ None \ Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x \ null \ (snd \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\) \ bot" +by(insert Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e[of x],auto simp:null_option_def bot_option_def) + +lemma B'[simp]:"x \ bot \ x \ null \ (snd \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\) \ bot" +apply(insert Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e[of x], simp add: bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +apply(auto simp:null_option_def bot_option_def) +apply(erule contrapos_np[of "x = Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e None"]) +apply(subst Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], simp) +apply(subst Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp_all,simp add: bot_option_def) +apply(erule contrapos_np[of "x = Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\"]) +apply(subst Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], simp) +apply(subst Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp_all,simp add: null_option_def bot_option_def) +done + +subsection{* Fundamental Properties of Strict Equality \label{sec:pair-strict-eq}*} + +text{* After the part of foundational operations on sets, we detail here equality on sets. +Strong equality is inherited from the OCL core, but we have to consider +the case of the strict equality. We decide to overload strict equality in the +same way we do for other value's in OCL:*} + +overloading + StrictRefEq \ "StrictRefEq :: [('\,'\::null,'\::null)Pair,('\,'\::null,'\::null)Pair] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>P\<^sub>a\<^sub>i\<^sub>r : + "((x::('\,'\::null,'\::null)Pair) \ y) \ (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y)\ + else invalid \)" +end + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>P\<^sub>a\<^sub>i\<^sub>r : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\,'\::null,'\::null)Pair) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>P\<^sub>a\<^sub>i\<^sub>r) + +subsection{* Standard Operations Definitions *} + +text{* This part provides a collection of operators for the Pair type. *} + +subsubsection{* Definition: Pair Constructor *} + +definition OclPair::"('\, '\) val \ + ('\, '\) val \ + ('\,'\::null,'\::null) Pair" ("Pair{(_),(_)}") +where "Pair{X,Y} \ (\ \. if (\ X) \ = true \ \ (\ Y) \ = true \ + then Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\(X \, Y \)\\ + else invalid \)" + +interpretation OclPair : profile_bin\<^sub>v_\<^sub>v + OclPair "\ x y. Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\(x, y)\\" + apply(unfold_locales, auto simp: OclPair_def bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + by(auto simp: Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject null_option_def bot_option_def) + + +subsubsection{* Definition: First *} + +definition OclFirst::" ('\,'\::null,'\::null) Pair \ ('\, '\) val" (" _ .First'(')") +where "X .First() \ (\ \. if (\ X) \ = true \ + then fst \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ + else invalid \)" + + +interpretation OclFirst : profile_mono\<^sub>d OclFirst "\x. fst \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x)\\" + by unfold_locales (auto simp: OclFirst_def) + +subsubsection{* Definition: Second *} + +definition OclSecond::" ('\,'\::null,'\::null) Pair \ ('\, '\) val" ("_ .Second'(')") +where "X .Second() \ (\ \. if (\ X) \ = true \ + then snd \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ + else invalid \)" + +interpretation OclSecond : profile_mono\<^sub>d OclSecond "\x. snd \\Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x)\\" + by unfold_locales (auto simp: OclSecond_def) + +subsection{* Logical Properties *} + +lemma 1 : "\ \ \ Y \ \ \ Pair{X,Y} .First() \ X" +apply(case_tac "\(\ \ \ X)") +apply(erule foundation7'[THEN iffD2, THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst2_rev]],simp_all add:foundation18') +apply(auto simp: OclValid_def valid_def defined_def StrongEq_def OclFirst_def OclPair_def + true_def false_def invalid_def bot_fun_def null_fun_def) +apply(auto simp: Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject null_option_def bot_option_def bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +by(simp add: Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) + +lemma 2 : "\ \ \ X \ \ \ Pair{X,Y} .Second() \ Y" +apply(case_tac "\(\ \ \ Y)") +apply(erule foundation7'[THEN iffD2, THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst2_rev]],simp_all add:foundation18') +apply(auto simp: OclValid_def valid_def defined_def StrongEq_def OclSecond_def OclPair_def + true_def false_def invalid_def bot_fun_def null_fun_def) +apply(auto simp: Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject null_option_def bot_option_def bot_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +by(simp add: Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) + +subsection{* Algebraic Execution Properties *} + +lemma proj1_exec [simp, code_unfold] : "Pair{X,Y} .First() = (if (\ Y) then X else invalid endif)" +apply(rule ext, rename_tac "\", simp add: foundation22[symmetric]) +apply(case_tac "\(\ \ \ Y)") +apply(erule foundation7'[THEN iffD2, + THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst2_rev]],simp_all) +apply(subgoal_tac "\ \ \ Y") +apply(erule foundation13[THEN iffD2, THEN StrongEq_L_subst2_rev], simp_all) +by(erule 1) + +lemma proj2_exec [simp, code_unfold] : "Pair{X,Y} .Second() = (if (\ X) then Y else invalid endif)" +apply(rule ext, rename_tac "\", simp add: foundation22[symmetric]) +apply(case_tac "\(\ \ \ X)") +apply(erule foundation7'[THEN iffD2, THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst2_rev]],simp_all) +apply(subgoal_tac "\ \ \ X") +apply(erule foundation13[THEN iffD2, THEN StrongEq_L_subst2_rev], simp_all) +by(erule 2) + +(* < *) + +subsection{* Test Statements*} +(* +Assert "(\ \ (Pair{\_. \\x\\,\_. \\x\\} \ Pair{\_. \\x\\,\_. \\x\\}))" +Assert "(\ \ (Pair{\_. \x\,\_. \x\} \ Pair{\_. \x\,\_. \x\}))" +*) + +instantiation Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (equal,equal)equal +begin + definition "HOL.equal k l \ (k::('a::equal,'b::equal)Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e) = l" + instance by standard (rule equal_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +end + +lemma equal_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_code [code]: + "HOL.equal k (l::('a::{equal,null},'b::{equal,null})Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e k = Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e l" + by (auto simp add: equal Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) + +Assert "\ \ invalid .First() \ invalid " +Assert "\ \ null .First() \ invalid " +Assert "\ \ null .Second() \ invalid .Second() " +Assert "\ \ Pair{invalid, true} \ invalid " +Assert "\ \ \(Pair{null, true}.First())" +Assert "\ \ (Pair{null, true}).First() \ null " +Assert "\ \ (Pair{null, Pair{true,invalid}}).First() \ invalid " + + +(* +Assert "\ (\ \ (Pair{\,\} \ Pair{\,\}))" +*) + +(* > *) + +end diff --git a/src/collection_types/UML_Sequence.thy b/src/collection_types/UML_Sequence.thy new file mode 100644 index 0000000..3f37539 --- /dev/null +++ b/src/collection_types/UML_Sequence.thy @@ -0,0 +1,572 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Sequence.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + + +theory UML_Sequence +imports "../basic_types/UML_Boolean" + "../basic_types/UML_Integer" +begin + +no_notation None ("\") +section{* Collection Type Sequence: Operations *} + +subsection{* Basic Properties of the Sequence Type *} + +text{* Every element in a defined sequence is valid. *} + +lemma Sequence_inv_lemma: "\ \ (\ X) \ \x\set \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. x \ bot" +apply(insert Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e [of "X \"], simp) +apply(auto simp: OclValid_def defined_def false_def true_def cp_def + bot_fun_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def + split:split_if_asm) + apply(erule contrapos_pp [of "Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \) = bot"]) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], rule Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp) + apply(simp add: Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) +apply(erule contrapos_pp [of "Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \) = null"]) +apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], rule Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp) +apply(simp add: Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse null_option_def) +by (simp add: bot_option_def) + +subsection{* Definition: Strict Equality \label{sec:seq-strict-equality}*} + +text{* After the part of foundational operations on sets, we detail here equality on sets. +Strong equality is inherited from the OCL core, but we have to consider +the case of the strict equality. We decide to overload strict equality in the +same way we do for other value's in OCL:*} + +overloading + StrictRefEq \ "StrictRefEq :: [('\,'\::null)Sequence,('\,'\::null)Sequence] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>S\<^sub>e\<^sub>q : + "((x::('\,'\::null)Sequence) \ y) \ (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y)\ + else invalid \)" +end + +text_raw{* \isatagafp *} +text{* One might object here that for the case of objects, this is an empty definition. +The answer is no, we will restrain later on states and objects such that any object +has its oid stored inside the object (so the ref, under which an object can be referenced +in the store will represented in the object itself). For such well-formed stores that satisfy +this invariant (the WFF-invariant), the referential equality and the +strong equality---and therefore the strict equality on sequences in the sense above---coincides.*} +text_raw{* \endisatagafp *} + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>S\<^sub>e\<^sub>q : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\,'\::null)Sequence) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>S\<^sub>e\<^sub>q) + + + +subsection{* Constants: mtSequence *} +definition mtSequence ::"('\,'\::null) Sequence" ("Sequence{}") +where "Sequence{} \ (\ \. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\[]::'\ list\\ )" + + +lemma mtSequence_defined[simp,code_unfold]:"\(Sequence{}) = true" +apply(rule ext, auto simp: mtSequence_def defined_def null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_fun_def) +by(simp_all add: Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + +lemma mtSequence_valid[simp,code_unfold]:"\(Sequence{}) = true" +apply(rule ext,auto simp: mtSequence_def valid_def null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_fun_def) +by(simp_all add: Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + +lemma mtSequence_rep_set: "\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Sequence{} \)\\ = []" + apply(simp add: mtSequence_def, subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) +by(simp add: bot_option_def)+ + +text_raw{* \isatagafp *} + +lemma [simp,code_unfold]: "const Sequence{}" +by(simp add: const_def mtSequence_def) + +text{* Note that the collection types in OCL allow for null to be included; + however, there is the null-collection into which inclusion yields invalid. *} + +text_raw{* \endisatagafp *} + + +subsection{* Definition: Prepend *} +definition OclPrepend :: "[('\,'\::null) Sequence,('\,'\) val] \ ('\,'\) Sequence" +where "OclPrepend x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ (y \)#\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ \\ + else invalid \ )" +notation OclPrepend ("_->prepend\<^sub>S\<^sub>e\<^sub>q'(_')") + +interpretation OclPrepend:profile_bin\<^sub>d_\<^sub>v OclPrepend "\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\y#\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\" +proof - + have A : "\x y. x \ bot \ x \ null \ y \ bot \ + \\y#\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ \ {X. X = bot \ X = null \ (\x\set \\X\\. x \ bot)}" + by(auto intro!:Sequence_inv_lemma[simplified OclValid_def + defined_def false_def true_def null_fun_def bot_fun_def]) + + show "profile_bin\<^sub>d_\<^sub>v OclPrepend (\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\y#\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\)" + apply unfold_locales + apply(auto simp:OclPrepend_def bot_option_def null_option_def null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + apply(erule_tac Q="Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\y#\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + in contrapos_pp) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject [OF A]) + apply(simp_all add: null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + apply(erule_tac Q="Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\y#\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + in contrapos_pp) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF A]) + apply(simp_all add: null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_option_def null_option_def) + done +qed + +syntax + "_OclFinsequence" :: "args => ('\,'a::null) Sequence" ("Sequence{(_)}") +translations + "Sequence{x, xs}" == "CONST OclPrepend (Sequence{xs}) x" + "Sequence{x}" == "CONST OclPrepend (Sequence{}) x " + +subsection{* Definition: Including *} + +definition OclIncluding :: "[('\,'\::null) Sequence,('\,'\) val] \ ('\,'\) Sequence" +where "OclIncluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ @ [y \] \\ + else invalid \ )" +notation OclIncluding ("_->including\<^sub>S\<^sub>e\<^sub>q'(_')") + +interpretation OclIncluding : + profile_bin\<^sub>d_\<^sub>v OclIncluding "\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ @ [y]\\" +proof - + have A : "\x y. x \ bot \ x \ null \ y \ bot \ + \\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ @ [y]\\ \ {X. X = bot \ X = null \ (\x\set \\X\\. x \ bot)}" + by(auto intro!:Sequence_inv_lemma[simplified OclValid_def + defined_def false_def true_def null_fun_def bot_fun_def]) + + show "profile_bin\<^sub>d_\<^sub>v OclIncluding (\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ @ [y]\\)" + apply unfold_locales + apply(auto simp:OclIncluding_def bot_option_def null_option_def null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + apply(erule_tac Q="Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ @ [y]\\ = Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + in contrapos_pp) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject [OF A]) + apply(simp_all add: null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + apply(erule_tac Q="Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ @ [y]\\ = Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + in contrapos_pp) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF A]) + apply(simp_all add: null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def null_option_def) + done +qed + +lemma [simp,code_unfold] : "(Sequence{}->including\<^sub>S\<^sub>e\<^sub>q(a)) = (Sequence{}->prepend\<^sub>S\<^sub>e\<^sub>q(a))" + apply(simp add: OclIncluding_def OclPrepend_def mtSequence_def) + apply(subst (1 2) Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp) +by(metis drop.simps append_Nil) + +lemma [simp,code_unfold] : "((S->prepend\<^sub>S\<^sub>e\<^sub>q(a))->including\<^sub>S\<^sub>e\<^sub>q(b)) = ((S->including\<^sub>S\<^sub>e\<^sub>q(b))->prepend\<^sub>S\<^sub>e\<^sub>q(a))" + proof - + have A: "\S b \. S \ \ \ S \ null \ b \ \ \ + \\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\ @ [b]\\ \ {X. X = bot \ X = null \ (\x\set \\X\\. x \ \)}" + by(auto intro!:Sequence_inv_lemma[simplified OclValid_def + defined_def false_def true_def null_fun_def bot_fun_def]) + have B: "\S a \. S \ \ \ S \ null \ a \ \ \ + \\a # \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\\\ \ {X. X = bot \ X = null \ (\x\set \\X\\. x \ \)}" + by(auto intro!:Sequence_inv_lemma[simplified OclValid_def + defined_def false_def true_def null_fun_def bot_fun_def]) + show ?thesis + apply(simp add: OclIncluding_def OclPrepend_def mtSequence_def, rule ext) + apply(subst (2 5) cp_defined, simp split:) + apply(intro conjI impI) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF B], + (simp add: foundation16[simplified OclValid_def] foundation18'[simplified OclValid_def])+) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF A], + (simp add: foundation16[simplified OclValid_def] foundation18'[simplified OclValid_def])+) + apply(simp add: OclIncluding.def_body) + apply (metis OclValid_def foundation16 invalid_def) + apply (metis (no_types) OclPrepend.def_body' OclValid_def foundation16) + by (metis OclValid_def foundation16 invalid_def)+ +qed + +subsection{* Definition: Excluding *} +definition OclExcluding :: "[('\,'\::null) Sequence,('\,'\) val] \ ('\,'\) Sequence" +where "OclExcluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ filter (\x. x = y \) + \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\\\ + else invalid \ )" +notation OclExcluding ("_->excluding\<^sub>S\<^sub>e\<^sub>q'(_')") + +interpretation OclExcluding:profile_bin\<^sub>d_\<^sub>v OclExcluding + "\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ filter (\x. x = y) \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x)\\\\" +proof - + show "profile_bin\<^sub>d_\<^sub>v OclExcluding (\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\[x\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ . x = y]\\)" + apply unfold_locales + apply(auto simp:OclExcluding_def bot_option_def null_option_def + null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + apply(subst (asm) Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, + simp_all add: null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def null_option_def)+ + done +qed + +subsection{* Definition: Append *} +text{* Identical to OclIncluding. *} +definition OclAppend :: "[('\,'\::null) Sequence,('\,'\) val] \ ('\,'\) Sequence" +where "OclAppend = OclIncluding" +notation OclAppend ("_->append\<^sub>S\<^sub>e\<^sub>q'(_')") + +interpretation OclAppend : + profile_bin\<^sub>d_\<^sub>v OclAppend "\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ @ [y]\\" + apply unfold_locales + by(auto simp: OclAppend_def bin_def bin'_def + OclIncluding.def_scheme OclIncluding.def_body) + +subsection{* Definition: Union *} +definition OclUnion :: "[('\,'\::null) Sequence,('\,'\) Sequence] \ ('\,'\) Sequence" +where "OclUnion x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ @ + \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\\\ + else invalid \ )" +notation OclUnion ("_->union\<^sub>S\<^sub>e\<^sub>q'(_')") + +interpretation OclUnion : + profile_bin\<^sub>d_\<^sub>d OclUnion "\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ @ \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\\\" +proof - + have A : "\x y. x \ \ \ x \ null \ \x\set \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\. x \ \ " + apply(rule Sequence_inv_lemma[of \]) + by(simp add: defined_def OclValid_def bot_fun_def null_fun_def false_def true_def) + show "profile_bin\<^sub>d_\<^sub>d OclUnion (\x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\@\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\\\)" + apply unfold_locales + apply(auto simp:OclUnion_def bot_option_def null_option_def + null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + by(subst (asm) Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, + simp_all add: bot_option_def null_option_def Set.ball_Un A null_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def)+ +qed + +subsection{* Definition: At *} +definition OclAt :: "[('\,'\::null) Sequence,('\) Integer] \ ('\,'\) val" +where "OclAt x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then if 1 \ \\y \\\ \ \\y \\\ \ length\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ + then \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ ! (nat \\y \\\ - 1) + else invalid \ + else invalid \ )" +notation OclAt ("_->at\<^sub>S\<^sub>e\<^sub>q'(_')") +(*TODO Locale - Equivalent*) + + +subsection{* Definition: First *} +definition OclFirst :: "[('\,'\::null) Sequence] \ ('\,'\) val" +where "OclFirst x = (\ \. if (\ x) \ = true \ then + case \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ of [] \ invalid \ + | x # _ \ x + else invalid \ )" +notation OclFirst ("_->first\<^sub>S\<^sub>e\<^sub>q'(_')") +(*TODO Locale - Equivalent*) + + +subsection{* Definition: Last *} +definition OclLast :: "[('\,'\::null) Sequence] \ ('\,'\) val" +where "OclLast x = (\ \. if (\ x) \ = true \ then + if \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ = [] then + invalid \ + else + last \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ + else invalid \ )" +notation OclLast ("_->last\<^sub>S\<^sub>e\<^sub>q'(_')") +(*TODO Locale - Equivalent*) + +subsection{* Definition: Iterate *} + +definition OclIterate :: "[('\,'\::null) Sequence,('\,'\::null)val, + ('\,'\)val\('\,'\)val\('\,'\)val] \ ('\,'\)val" +where "OclIterate S A F = (\ \. if (\ S) \ = true \ \ (\ A) \ = true \ + then (foldr (F) (map (\a \. a) \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\))(A)\ + else \)" +syntax + "_OclIterateSeq" :: "[('\,'\::null) Sequence, idt, idt, '\, '\] => ('\,'\)val" + ("_ ->iterate\<^sub>S\<^sub>e\<^sub>q'(_;_=_ | _')" (*[71,100,70]50*)) +translations + "X->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = A | P)" == "CONST OclIterate X A (%a. (% x. P))" + +(*TODO Locale - Equivalent*) + + + +subsection{* Definition: Forall *} +definition OclForall :: "[('\,'\::null) Sequence,('\,'\)val\('\)Boolean] \ '\ Boolean" +where "OclForall S P = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = true | x and (P b)))" + +syntax + "_OclForallSeq" :: "[('\,'\::null) Sequence,id,('\)Boolean] \ '\ Boolean" ("(_)->forAll\<^sub>S\<^sub>e\<^sub>q'(_|_')") +translations + "X->forAll\<^sub>S\<^sub>e\<^sub>q(x | P)" == "CONST UML_Sequence.OclForall X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Exists *} +definition OclExists :: "[('\,'\::null) Sequence,('\,'\)val\('\)Boolean] \ '\ Boolean" +where "OclExists S P = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = false | x or (P b)))" + +syntax + "_OclExistSeq" :: "[('\,'\::null) Sequence,id,('\)Boolean] \ '\ Boolean" ("(_)->exists\<^sub>S\<^sub>e\<^sub>q'(_|_')") +translations + "X->exists\<^sub>S\<^sub>e\<^sub>q(x | P)" == "CONST OclExists X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Collect *} +definition OclCollect :: "[('\,'\::null)Sequence,('\,'\)val\('\,'\)val]\('\,'\::null)Sequence" +where "OclCollect S P = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = Sequence{} | x->prepend\<^sub>S\<^sub>e\<^sub>q(P b)))" + +syntax + "_OclCollectSeq" :: "[('\,'\::null) Sequence,id,('\)Boolean] \ '\ Boolean" ("(_)->collect\<^sub>S\<^sub>e\<^sub>q'(_|_')") +translations + "X->collect\<^sub>S\<^sub>e\<^sub>q(x | P)" == "CONST OclCollect X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Select *} +definition OclSelect :: "[('\,'\::null)Sequence,('\,'\)val\('\)Boolean]\('\,'\::null)Sequence" +where "OclSelect S P = + (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = Sequence{} | if P b then x->prepend\<^sub>S\<^sub>e\<^sub>q(b) else x endif))" + +syntax + "_OclSelectSeq" :: "[('\,'\::null) Sequence,id,('\)Boolean] \ '\ Boolean" ("(_)->select\<^sub>S\<^sub>e\<^sub>q'(_|_')") +translations + "X->select\<^sub>S\<^sub>e\<^sub>q(x | P)" == "CONST UML_Sequence.OclSelect X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Size *} +definition OclSize :: "[('\,'\::null)Sequence]\('\)Integer" ("(_)->size\<^sub>S\<^sub>e\<^sub>q'(')") +where "OclSize S = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = \ | x +\<^sub>i\<^sub>n\<^sub>t \ ))" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: IsEmpty *} +definition OclIsEmpty :: "('\,'\::null) Sequence \ '\ Boolean" +where "OclIsEmpty x = ((\ x and not (\ x)) or ((OclSize x) \ \))" +notation OclIsEmpty ("_->isEmpty\<^sub>S\<^sub>e\<^sub>q'(')" (*[66]*)) + +(*TODO Locale - Equivalent*) + +subsection{* Definition: NotEmpty *} + +definition OclNotEmpty :: "('\,'\::null) Sequence \ '\ Boolean" +where "OclNotEmpty x = not(OclIsEmpty x)" +notation OclNotEmpty ("_->notEmpty\<^sub>S\<^sub>e\<^sub>q'(')" (*[66]*)) + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Any *} + +definition "OclANY x = (\ \. + if x \ = invalid \ then + \ + else + case drop (drop (Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \))) of [] \ \ + | l \ hd l)" +notation OclANY ("_->any\<^sub>S\<^sub>e\<^sub>q'(')") + +(*TODO Locale - Equivalent*) + +subsection{* Definition (future operators) *} + +consts (* abstract set collection operations *) + OclCount :: "[('\,'\::null) Sequence,('\,'\) Sequence] \ '\ Integer" + (*OclFlatten*) + (*OclInsertAt*) + (*OclSubSequence*) + (*OclIndexOf*) + (*OclReverse*) + OclSum :: " ('\,'\::null) Sequence \ '\ Integer" + +notation OclCount ("_->count\<^sub>S\<^sub>e\<^sub>q'(_')" (*[66,65]65*)) +notation OclSum ("_->sum\<^sub>S\<^sub>e\<^sub>q'(')" (*[66]*)) + +subsection{* Logical Properties *} + +subsection{* Execution Laws with Invalid or Null as Argument *} + +text{* OclIterate *} + +lemma OclIterate_invalid[simp,code_unfold]:"invalid->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = A | P a x) = invalid" +by(simp add: OclIterate_def false_def true_def, simp add: invalid_def) + +lemma OclIterate_null[simp,code_unfold]:"null->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = A | P a x) = invalid" +by(simp add: OclIterate_def false_def true_def, simp add: invalid_def) + +lemma OclIterate_invalid_args[simp,code_unfold]:"S->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = invalid | P a x) = invalid" +by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) + +text_raw{* \isatagafp *} + +subsubsection{* Context Passing *} + +lemma cp_OclIncluding: +"(X->including\<^sub>S\<^sub>e\<^sub>q(x)) \ = ((\ _. X \)->including\<^sub>S\<^sub>e\<^sub>q(\ _. x \)) \" +by(auto simp: OclIncluding_def StrongEq_def invalid_def + cp_defined[symmetric] cp_valid[symmetric]) + +lemma cp_OclIterate: + "(X->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = A | P a x)) \ = + ((\ _. X \)->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = A | P a x)) \" +by(simp add: OclIterate_def cp_defined[symmetric]) + +lemmas cp_intro''\<^sub>S\<^sub>e\<^sub>q[intro!,simp,code_unfold] = + cp_OclIncluding [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "OclIncluding"]] + +subsubsection{* Const *} + +text_raw{* \endisatagafp *} + +subsection{* General Algebraic Execution Rules *} +subsubsection{* Execution Rules on Iterate *} + +lemma OclIterate_empty[simp,code_unfold]:"Sequence{}->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = A | P a x) = A" +apply(simp add: OclIterate_def foundation22[symmetric] foundation13, + rule ext, rename_tac "\") +apply(case_tac "\ \ \ A", simp_all add: foundation18') +apply(simp add: mtSequence_def) +apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) by auto + +text{* In particular, this does hold for A = null. *} + +lemma OclIterate_including[simp,code_unfold]: +assumes strict1 : "\X. P invalid X = invalid" +and P_valid_arg: "\ \. (\ A) \ = (\ (P a A)) \" +and P_cp : "\ x y \. P x y \ = P (\ _. x \) y \" +and P_cp' : "\ x y \. P x y \ = P x (\ _. y \) \" +shows "(S->including\<^sub>S\<^sub>e\<^sub>q(a))->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = A | P b x) = S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = P a A| P b x)" + apply(rule ext) +proof - + have A: "\S b \. S \ \ \ S \ null \ b \ \ \ + \\\\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\ @ [b]\\ \ {X. X = bot \ X = null \ (\x\set \\X\\. x \ \)}" + by(auto intro!:Sequence_inv_lemma[simplified OclValid_def + defined_def false_def true_def null_fun_def bot_fun_def]) + have P: "\l A A' \. A \ = A' \ \ foldr P l A \ = foldr P l A' \" + apply(rule list.induct, simp, simp) + by(subst (1 2) P_cp', simp) + + fix \ + show "OclIterate (S->including\<^sub>S\<^sub>e\<^sub>q(a)) A P \ = OclIterate S (P a A) P \" + apply(subst cp_OclIterate, subst OclIncluding_def, simp split:) + apply(intro conjI impI) + + apply(simp add: OclIterate_def) + apply(intro conjI impI) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF A], + (simp add: foundation16[simplified OclValid_def] foundation18'[simplified OclValid_def])+) + apply(rule P, metis P_cp) + apply (metis P_valid_arg) + apply(simp add: P_valid_arg[symmetric]) + apply (metis (lifting, no_types) OclIncluding.def_body' OclValid_def foundation16) + apply(simp add: OclIterate_def defined_def invalid_def bot_option_def bot_fun_def false_def true_def) + apply(intro impI, simp add: false_def true_def P_valid_arg) + by (metis P_cp P_valid_arg UML_Types.bot_fun_def cp_valid invalid_def strict1 true_def valid1 valid_def) +qed + +lemma OclIterate_prepend[simp,code_unfold]: +assumes strict1 : "\X. P invalid X = invalid" +and strict2 : "\X. P X invalid = invalid" +and P_cp : "\ x y \. P x y \ = P (\ _. x \) y \" +and P_cp' : "\ x y \. P x y \ = P x (\ _. y \) \" +shows "(S->prepend\<^sub>S\<^sub>e\<^sub>q(a))->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = A | P b x) = P a (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = A| P b x))" + apply(rule ext) +proof - + have B: "\S a \. S \ \ \ S \ null \ a \ \ \ + \\a # \\Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\\\ \ {X. X = bot \ X = null \ (\x\set \\X\\. x \ \)}" + by(auto intro!:Sequence_inv_lemma[simplified OclValid_def + defined_def false_def true_def null_fun_def bot_fun_def]) + fix \ + show "OclIterate (S->prepend\<^sub>S\<^sub>e\<^sub>q(a)) A P \ = P a (OclIterate S A P) \" + apply(subst cp_OclIterate, subst OclPrepend_def, simp split:) + apply(intro conjI impI) + + apply(subst P_cp') + apply(simp add: OclIterate_def) + apply(intro conjI impI) + apply(subst Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF B], + (simp add: foundation16[simplified OclValid_def] foundation18'[simplified OclValid_def])+) + apply(simp add: P_cp'[symmetric]) + apply(subst P_cp, simp add: P_cp[symmetric]) + apply (metis (no_types) OclPrepend.def_body' OclValid_def foundation16) + apply (metis P_cp' invalid_def strict2 valid_def) + + apply(subst P_cp', + simp add: OclIterate_def defined_def invalid_def bot_option_def bot_fun_def false_def true_def, + intro conjI impI) + apply (metis P_cp' invalid_def strict2 valid_def) + apply (metis P_cp' invalid_def strict2 valid_def) + apply (metis (no_types) P_cp invalid_def strict1 true_def valid1 valid_def) + apply (metis P_cp' invalid_def strict2 valid_def) + done +qed + + +(* < *) + +subsection{* Test Statements *} +(* +Assert "(\ \ (Sequence{\_. \\x\\} \ Sequence{\_. \\x\\}))" +Assert "(\ \ (Sequence{\_. \x\} \ Sequence{\_. \x\}))" +*) + +instantiation Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (equal)equal +begin + definition "HOL.equal k l \ (k::('a::equal)Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e) = l" + instance by standard (rule equal_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +end + +lemma equal_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_code [code]: + "HOL.equal k (l::('a::{equal,null})Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e k = Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e l" + by (auto simp add: equal Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) + +Assert "\ \ (Sequence{} \ Sequence{})" +Assert "\ \ (Sequence{\,\} \ Sequence{}->prepend\<^sub>S\<^sub>e\<^sub>q(\)->prepend\<^sub>S\<^sub>e\<^sub>q(\))" +Assert "\ \ (Sequence{\,invalid,\} \ invalid)" +Assert "\ \ (Sequence{\,\}->prepend\<^sub>S\<^sub>e\<^sub>q(null) \ Sequence{null,\,\})" +Assert "\ \ (Sequence{\,\}->including\<^sub>S\<^sub>e\<^sub>q(null) \ Sequence{\,\,null})" + +(* +Assert "\ (\ \ (Sequence{\,\,\} \ Sequence{\,\}))" +Assert "\ (\ \ (Sequence{\,\} \ Sequence{\,\}))" +*) + +(* > *) + +end diff --git a/src/collection_types/UML_Set.thy b/src/collection_types/UML_Set.thy new file mode 100644 index 0000000..aa074b5 --- /dev/null +++ b/src/collection_types/UML_Set.thy @@ -0,0 +1,3170 @@ +(***************************************************************************** + * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 + * for the OMG Standard. + * http://www.brucker.ch/projects/hol-testgen/ + * + * UML_Set.thy --- Library definitions. + * This file is part of HOL-TestGen. + * + * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France + * 2013-2015 IRT SystemX, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************) + + +theory UML_Set +imports "../basic_types/UML_Void" + "../basic_types/UML_Boolean" + "../basic_types/UML_Integer" + "../basic_types/UML_String" + "../basic_types/UML_Real" +begin + +no_notation None ("\") +section{* Collection Type Set: Operations \label{formal-set}*} + +subsection{* As a Motivation for the (infinite) Type Construction: Type-Extensions as Sets + \label{sec:type-extensions}*} + +text{* Our notion of typed set goes beyond the usual notion of a finite executable set and +is powerful enough to capture \emph{the extension of a type} in UML and OCL. This means +we can have in Featherweight OCL Sets containing all possible elements of a type, not only +those (finite) ones representable in a state. This holds for base types as well as class types, +although the notion for class-types --- involving object id's not occuring in a state --- +requires some care. + +In a world with @{term invalid} and @{term null}, there are two notions extensions possible: +\begin{enumerate} +\item the set of all \emph{defined} values of a type @{term T} + (for which we will introduce the constant @{term T}) +\item the set of all \emph{valid} values of a type @{term T}, so including @{term null} + (for which we will introduce the constant @{term T\<^sub>n\<^sub>u\<^sub>l\<^sub>l}). +\end{enumerate} +*} + +text{* We define the set extensions for the base type @{term Integer} as follows: *} +definition Integer :: "('\,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Integer \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) ((Some o Some) ` (UNIV::int set)))" + +definition Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (Some ` (UNIV::int option set)))" + +lemma Integer_defined : "\ Integer = true" +apply(rule ext, auto simp: Integer_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +text{* This allows the theorems: + + @{text "\ \ \ x \ \ \ (Integer->includes\<^sub>S\<^sub>e\<^sub>t(x))"} + @{text "\ \ \ x \ \ \ Integer \ (Integer->including\<^sub>S\<^sub>e\<^sub>t(x))"} + +and + + @{text "\ \ \ x \ \ \ (Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l->includes\<^sub>S\<^sub>e\<^sub>t(x))"} + @{text "\ \ \ x \ \ \ Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l->including\<^sub>S\<^sub>e\<^sub>t(x))"} + +which characterize the infiniteness of these sets by a recursive property on these sets. +*} + +text{* In the same spirit, we proceed similarly for the remaining base types: *} + +definition Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) {Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Some None)})" + +definition Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y :: "('\,Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) {})" + +lemma Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def + bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +by((subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, auto simp add: bot_option_def null_option_def bot_Void_def), + (subst (asm) Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, auto simp add: bot_option_def null_option_def))+ + +lemma Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y_defined : "\ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y = true" +apply(rule ext, auto simp: Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def + bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +by((subst (asm) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, auto simp add: bot_option_def null_option_def bot_Void_def))+ + +lemma assumes "\ \ \ (V :: ('\,Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set)" + shows "\ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" +proof - + have A:"\x y. x \ {} \ \y. y\ x" + by (metis all_not_in_conv) +show "?thesis" + apply(case_tac "V \") + proof - fix y show "V \ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y \ + y \ {X. X = \ \ X = null \ (\x\\\X\\. x \ \)} \ + \ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" + apply(insert assms, case_tac y, simp add: bot_option_def, simp add: bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def foundation16) + apply(simp add: bot_option_def null_option_def) + apply(erule disjE, metis OclValid_def defined_def foundation2 null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def true_def) + proof - fix a show "V \ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \a\ \ \x\\a\. x \ \ \ \ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" + apply(case_tac a, simp, insert assms, metis OclValid_def foundation16 null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def true_def) + apply(simp) + proof - fix aa show " V \ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\aa\\ \ \x\aa. x \ \ \ \ \ V \ Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ \ \ V \ Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y" + apply(case_tac "aa = {}", + rule disjI2, + insert assms, + simp add: Void\<^sub>e\<^sub>m\<^sub>p\<^sub>t\<^sub>y_def OclValid_def StrongEq_def true_def, + rule disjI1) + apply(subgoal_tac "aa = {Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\}", simp add: StrongEq_def OclValid_def true_def Void\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def) + apply(drule A, erule exE) + proof - fix y show "V \ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\aa\\ \ + \x\aa. x \ \ \ + \ \ \ V \ + y \ aa \ + aa = {Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\}" + apply(rule equalityI, rule subsetI, simp) + proof - fix x show " V \ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\aa\\ \ + \x\aa. x \ \ \ \ \ \ V \ y \ aa \ x \ aa \ x = Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + apply(case_tac x, simp) + by (metis bot_Void_def bot_option_def null_option_def) + apply_end(simp_all) + + apply_end(erule ballE[where x = y], simp_all) + apply_end(case_tac y, + simp add: bot_option_def null_option_def OclValid_def defined_def split: split_if_asm, + simp add: false_def true_def) + qed (erule disjE, simp add: bot_Void_def, simp) +qed qed qed qed qed + +definition Boolean :: "('\,Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Boolean \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) ((Some o Some) ` (UNIV::bool set)))" + +definition Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (Some ` (UNIV::bool option set)))" + +lemma Boolean_defined : "\ Boolean = true" +apply(rule ext, auto simp: Boolean_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Boolean\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +definition String :: "('\,String\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "String \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) ((Some o Some) ` (UNIV::string set)))" + +definition String\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,String\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "String\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (Some ` (UNIV::string option set)))" + +lemma String_defined : "\ String = true" +apply(rule ext, auto simp: String_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma String\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ String\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: String\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +definition Real :: "('\,Real\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Real \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) ((Some o Some) ` (UNIV::real set)))" + +definition Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l :: "('\,Real\<^sub>b\<^sub>a\<^sub>s\<^sub>e) Set" +where "Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l \ (\ \. (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e o Some o Some) (Some ` (UNIV::real option set)))" + +lemma Real_defined : "\ Real = true" +apply(rule ext, auto simp: Real_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l_defined : "\ Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l = true" +apply(rule ext, auto simp: Real\<^sub>n\<^sub>u\<^sub>l\<^sub>l_def defined_def false_def true_def + bot_fun_def null_fun_def null_option_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +subsection{* Basic Properties of the Set Type*} + +text{* Every element in a defined set is valid. *} + +lemma Set_inv_lemma: "\ \ (\ X) \ \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. x \ bot" +apply(insert Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e [of "X \"], simp) +apply(auto simp: OclValid_def defined_def false_def true_def cp_def + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def + split:split_if_asm) + apply(erule contrapos_pp [of "Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \) = bot"]) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], rule Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp) + apply(simp add: Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) +apply(erule contrapos_pp [of "Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \) = null"]) +apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[symmetric], rule Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp) +apply(simp add: Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse null_option_def) +by (simp add: bot_option_def) + +lemma Set_inv_lemma' : + assumes x_def : "\ \ \ X" + and e_mem : "e \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + shows "\ \ \ (\_. e)" + apply(rule Set_inv_lemma[OF x_def, THEN ballE[where x = e]]) + apply(simp add: foundation18') +by(simp add: e_mem) + +lemma abs_rep_simp' : + assumes S_all_def : "\ \ \ S" + shows "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ = S \" +proof - + have discr_eq_false_true : "\\. (false \ = true \) = False" by(simp add: false_def true_def) + show ?thesis + apply(insert S_all_def, simp add: OclValid_def defined_def) + apply(rule mp[OF Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_induct[where P = "\S. (if S = \ \ \ S = null \ + then false \ else true \) = true \ \ + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\\\ = S"]], + rename_tac S') + apply(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse discr_eq_false_true) + apply(case_tac S') apply(simp add: bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def)+ + apply(rename_tac S'', case_tac S'') apply(simp add: null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def)+ + done +qed + +lemma S_lift' : + assumes S_all_def : "(\ :: '\ st) \ \ S" + shows "\S'. (\a (_::'\ st). a) ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ = (\a (_::'\ st). \a\) ` S'" + apply(rule_tac x = "(\a. \a\) ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\" in exI) + apply(simp only: image_comp) + apply(simp add: comp_def) + apply(rule image_cong, fast) + (* *) + apply(drule Set_inv_lemma'[OF S_all_def]) +by(case_tac x, (simp add: bot_option_def foundation18')+) + +lemma invalid_set_OclNot_defined [simp,code_unfold]:"\(invalid::('\,'\::null) Set) = false" by simp +lemma null_set_OclNot_defined [simp,code_unfold]:"\(null::('\,'\::null) Set) = false" +by(simp add: defined_def null_fun_def) +lemma invalid_set_valid [simp,code_unfold]:"\(invalid::('\,'\::null) Set) = false" +by simp +lemma null_set_valid [simp,code_unfold]:"\(null::('\,'\::null) Set) = true" +apply(simp add: valid_def null_fun_def bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject,simp_all add: null_option_def bot_option_def) +done + +text{* ... which means that we can have a type @{text "('\,('\,('\) Integer) Set) Set"} +corresponding exactly to Set(Set(Integer)) in OCL notation. Note that the parameter +@{text "'\"} still refers to the object universe; making the OCL semantics entirely parametric +in the object universe makes it possible to study (and prove) its properties +independently from a concrete class diagram. *} + +subsection{* Definition: Strict Equality \label{sec:set-strict-equality}*} + +text{* After the part of foundational operations on sets, we detail here equality on sets. +Strong equality is inherited from the OCL core, but we have to consider +the case of the strict equality. We decide to overload strict equality in the +same way we do for other value's in OCL:*} + +overloading + StrictRefEq \ "StrictRefEq :: [('\,'\::null)Set,('\,'\::null)Set] \ ('\)Boolean" +begin + definition StrictRefEq\<^sub>S\<^sub>e\<^sub>t : + "(x::('\,'\::null)Set) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then (x \ y)\ + else invalid \" +end + +text{* One might object here that for the case of objects, this is an empty definition. +The answer is no, we will restrain later on states and objects such that any object +has its oid stored inside the object (so the ref, under which an object can be referenced +in the store will represented in the object itself). For such well-formed stores that satisfy +this invariant (the WFF-invariant), the referential equality and the +strong equality---and therefore the strict equality on sets in the sense above---coincides.*} + +text{* Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}*} +interpretation StrictRefEq\<^sub>S\<^sub>e\<^sub>t : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\,'\::null)Set) \ y" + by unfold_locales (auto simp: StrictRefEq\<^sub>S\<^sub>e\<^sub>t) + + + +subsection{* Constants: mtSet *} +definition mtSet::"('\,'\::null) Set" ("Set{}") +where "Set{} \ (\ \. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\{}::'\ set\\ )" + + +lemma mtSet_defined[simp,code_unfold]:"\(Set{}) = true" +apply(rule ext, auto simp: mtSet_def defined_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_fun_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma mtSet_valid[simp,code_unfold]:"\(Set{}) = true" +apply(rule ext,auto simp: mtSet_def valid_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_fun_def) +by(simp_all add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def) + +lemma mtSet_rep_set: "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Set{} \)\\ = {}" + apply(simp add: mtSet_def, subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) +by(simp add: bot_option_def)+ + +lemma [simp,code_unfold]: "const Set{}" +by(simp add: const_def mtSet_def) + + +text{* Note that the collection types in OCL allow for null to be included; + however, there is the null-collection into which inclusion yields invalid. *} + +subsection{* Definition: Including *} + +definition OclIncluding :: "[('\,'\::null) Set,('\,'\) val] \ ('\,'\) Set" +where "OclIncluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ \ {y \} \\ + else invalid \ )" +notation OclIncluding ("_->including\<^sub>S\<^sub>e\<^sub>t'(_')") + +interpretation OclIncluding : profile_bin\<^sub>d_\<^sub>v OclIncluding "\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ \ {y}\\" +proof - + have A : "None \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: bot_option_def) + have B : "\None\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(simp add: null_option_def bot_option_def) + have C : "\x y. x \ \ \ x \ null \ y \ \ \ + \\insert y \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(auto intro!:Set_inv_lemma[simplified OclValid_def + defined_def false_def true_def null_fun_def bot_fun_def]) + show "profile_bin\<^sub>d_\<^sub>v OclIncluding (\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ \ {y}\\)" + apply unfold_locales + apply(auto simp:OclIncluding_def bot_option_def null_option_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\insert y \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF C A]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\insert y \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF C B]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + done +qed + +syntax + "_OclFinset" :: "args => ('\,'a::null) Set" ("Set{(_)}") +translations + "Set{x, xs}" == "CONST OclIncluding (Set{xs}) x" + "Set{x}" == "CONST OclIncluding (Set{}) x " + + +subsection{* Definition: Excluding *} + +definition OclExcluding :: "[('\,'\::null) Set,('\,'\) val] \ ('\,'\) Set" +where "OclExcluding x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ - {y \} \\ + else \ )" +notation OclExcluding ("_->excluding\<^sub>S\<^sub>e\<^sub>t'(_')") + + +lemma OclExcluding_inv: "(x:: Set('b::{null})) \ \ \ x \ null \ y \ \ \ + \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ - {y}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + proof - fix X :: "'a state \ 'a state \ Set('b)" fix \ + show "x \ \ \ x \ null \ y \ \ \ ?thesis" + when "x = X \" + by(simp add: that Set_inv_lemma[simplified OclValid_def + defined_def null_fun_def bot_fun_def, of X \]) +qed simp_all + +interpretation OclExcluding : profile_bin\<^sub>d_\<^sub>v OclExcluding "\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ - {y}\\" +proof - + have A : "None \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: bot_option_def) + have B : "\None\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(simp add: null_option_def bot_option_def) + show "profile_bin\<^sub>d_\<^sub>v OclExcluding (\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x:: Set('b))\\ - {y}\\)" + apply unfold_locales + apply(auto simp:OclExcluding_def bot_option_def null_option_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def invalid_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ - {y}\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF OclExcluding_inv A]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ - {y}\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF OclExcluding_inv B]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + done +qed + + +subsection{* Definition: Includes *} + +definition OclIncludes :: "[('\,'\::null) Set,('\,'\) val] \ '\ Boolean" +where "OclIncludes x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\(y \) \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ \\ + else \ )" +notation OclIncludes ("_->includes\<^sub>S\<^sub>e\<^sub>t'(_')" (*[66,65]65*)) + +interpretation OclIncludes : profile_bin\<^sub>d_\<^sub>v OclIncludes "\x y. \\y \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\" +by(unfold_locales, auto simp:OclIncludes_def bot_option_def null_option_def invalid_def) + + +subsection{* Definition: Excludes *} + +definition OclExcludes :: "[('\,'\::null) Set,('\,'\) val] \ '\ Boolean" +where "OclExcludes x y = (not(OclIncludes x y))" +notation OclExcludes ("_->excludes\<^sub>S\<^sub>e\<^sub>t'(_')" (*[66,65]65*)) + +text{* The case of the size definition is somewhat special, we admit +explicitly in Featherweight OCL the possibility of infinite sets. For +the size definition, this requires an extra condition that assures +that the cardinality of the set is actually a defined integer. *} + +interpretation OclExcludes : profile_bin\<^sub>d_\<^sub>v OclExcludes "\x y. \\y \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\" +by(unfold_locales, auto simp:OclExcludes_def OclIncludes_def OclNot_def bot_option_def null_option_def invalid_def) + +subsection{* Definition: Size *} + +definition OclSize :: "('\,'\::null)Set \ '\ Integer" +where "OclSize x = (\ \. if (\ x) \ = true \ \ finite(\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\) + then \\ int(card \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\) \\ + else \ )" +notation (* standard ascii syntax *) + OclSize ("_->size\<^sub>S\<^sub>e\<^sub>t'(')" (*[66]*)) + +text{* The following definition follows the requirement of the +standard to treat null as neutral element of sets. It is +a well-documented exception from the general strictness +rule and the rule that the distinguished argument self should +be non-null. *} + +(*TODO Locale - Equivalent*) + + +subsection{* Definition: IsEmpty *} + +definition OclIsEmpty :: "('\,'\::null) Set \ '\ Boolean" +where "OclIsEmpty x = ((\ x and not (\ x)) or ((OclSize x) \ \))" +notation OclIsEmpty ("_->isEmpty\<^sub>S\<^sub>e\<^sub>t'(')" (*[66]*)) + +(*TODO Locale - Equivalent*) + + +subsection{* Definition: NotEmpty *} + +definition OclNotEmpty :: "('\,'\::null) Set \ '\ Boolean" +where "OclNotEmpty x = not(OclIsEmpty x)" +notation OclNotEmpty ("_->notEmpty\<^sub>S\<^sub>e\<^sub>t'(')" (*[66]*)) + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Any *} + +(* Slight breach of naming convention in order to avoid naming conflict on constant.*) +definition OclANY :: "[('\,'\::null) Set] \ ('\,'\) val" +where "OclANY x = (\ \. if (\ x) \ = true \ + then if (\ x and OclNotEmpty x) \ = true \ + then SOME y. y \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ + else null \ + else \ )" +notation OclANY ("_->any\<^sub>S\<^sub>e\<^sub>t'(')") + +(*TODO Locale - Equivalent*) + +(* actually, this definition covers only: X->any\<^sub>S\<^sub>e\<^sub>t(true) of the standard, which foresees +a (totally correct) high-level definition +source->any\<^sub>S\<^sub>e\<^sub>t(iterator | body) = +source->select(iterator | body)->asSequence()->first(). Since we don't have sequences, +we have to go for a direct---restricted---definition. *) + + + +subsection{* Definition: Forall *} + +text{* The definition of OclForall mimics the one of @{term "OclAnd"}: +OclForall is not a strict operation. *} +definition OclForall :: "[('\,'\::null)Set,('\,'\)val\('\)Boolean] \ '\ Boolean" +where "OclForall S P = (\ \. if (\ S) \ = true \ + then if (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P(\ _. x) \ = false \) + then false \ + else if (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P(\ _. x) \ = invalid \) + then invalid \ + else if (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P(\ _. x) \ = null \) + then null \ + else true \ + else \)" +syntax + "_OclForallSet" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->forAll\<^sub>S\<^sub>e\<^sub>t'(_|_')") +translations + "X->forAll\<^sub>S\<^sub>e\<^sub>t(x | P)" == "CONST UML_Set.OclForall X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Exists *} + +text{* Like OclForall, OclExists is also not strict. *} +definition OclExists :: "[('\,'\::null) Set,('\,'\)val\('\)Boolean] \ '\ Boolean" +where "OclExists S P = not(UML_Set.OclForall S (\ X. not (P X)))" + +syntax + "_OclExistSet" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->exists\<^sub>S\<^sub>e\<^sub>t'(_|_')") +translations + "X->exists\<^sub>S\<^sub>e\<^sub>t(x | P)" == "CONST UML_Set.OclExists X (%x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Iterate *} + +definition OclIterate :: "[('\,'\::null) Set,('\,'\::null)val, + ('\,'\)val\('\,'\)val\('\,'\)val] \ ('\,'\)val" +where "OclIterate S A F = (\ \. if (\ S) \ = true \ \ (\ A) \ = true \ \ finite\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ + then (Finite_Set.fold (F) (A) ((\a \. a) ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\))\ + else \)" +syntax + "_OclIterateSet" :: "[('\,'\::null) Set, idt, idt, '\, '\] => ('\,'\)val" + ("_ ->iterate\<^sub>S\<^sub>e\<^sub>t'(_;_=_ | _')" (*[71,100,70]50*)) +translations + "X->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = A | P)" == "CONST OclIterate X A (%a. (% x. P))" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Select *} + +definition OclSelect :: "[('\,'\::null)Set,('\,'\)val\('\)Boolean] \ ('\,'\)Set" +where "OclSelect S P = (\\. if (\ S) \ = true \ + then if (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P(\ _. x) \ = invalid \) + then invalid \ + else Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\{x\\\ Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P (\_. x) \ \ false \}\\ + else invalid \)" +syntax + "_OclSelectSet" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->select\<^sub>S\<^sub>e\<^sub>t'(_|_')") +translations + "X->select\<^sub>S\<^sub>e\<^sub>t(x | P)" == "CONST OclSelect X (% x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: Reject *} + +definition OclReject :: "[('\,'\::null)Set,('\,'\)val\('\)Boolean] \ ('\,'\::null)Set" +where "OclReject S P = OclSelect S (not o P)" +syntax + "_OclRejectSet" :: "[('\,'\::null) Set,id,('\)Boolean] \ '\ Boolean" ("(_)->reject\<^sub>S\<^sub>e\<^sub>t'(_|_')") +translations + "X->reject\<^sub>S\<^sub>e\<^sub>t(x | P)" == "CONST OclReject X (% x. P)" + +(*TODO Locale - Equivalent*) + +subsection{* Definition: IncludesAll *} + +definition OclIncludesAll :: "[('\,'\::null) Set,('\,'\) Set] \ '\ Boolean" +where "OclIncludesAll x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ \\ + else \ )" +notation OclIncludesAll ("_->includesAll\<^sub>S\<^sub>e\<^sub>t'(_')" (*[66,65]65*)) + +interpretation OclIncludesAll : profile_bin\<^sub>d_\<^sub>d OclIncludesAll "\x y. \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\" +by(unfold_locales, auto simp:OclIncludesAll_def bot_option_def null_option_def invalid_def) + +subsection{* Definition: ExcludesAll *} + +definition OclExcludesAll :: "[('\,'\::null) Set,('\,'\) Set] \ '\ Boolean" +where "OclExcludesAll x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ = {} \\ + else \ )" +notation OclExcludesAll ("_->excludesAll\<^sub>S\<^sub>e\<^sub>t'(_')" (*[66,65]65*)) + +interpretation OclExcludesAll : profile_bin\<^sub>d_\<^sub>d OclExcludesAll "\x y. \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\ = {}\\" +by(unfold_locales, auto simp:OclExcludesAll_def bot_option_def null_option_def invalid_def) + +subsection{* Definition: Union *} + +definition OclUnion :: "[('\,'\::null) Set,('\,'\) Set] \ ('\,'\) Set" +where "OclUnion x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ \\ + else \ )" +notation OclUnion ("_->union\<^sub>S\<^sub>e\<^sub>t'(_')" (*[66,65]65*)) + +lemma OclUnion_inv: "(x:: Set('b::{null})) \ \ \ x \ null \ y \ \ \ y \ null \ + \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + proof - fix X Y :: "'a state \ 'a state \ Set('b)" fix \ + show "x \ \ \ x \ null \ y \ \ \ y \ null \ ?thesis" + when "x = X \" "y = Y \" + by(auto simp: that, + insert + Set_inv_lemma[simplified OclValid_def + defined_def null_fun_def bot_fun_def, of Y \] + Set_inv_lemma[simplified OclValid_def + defined_def null_fun_def bot_fun_def, of X \], + auto) +qed simp_all + +interpretation OclUnion : profile_bin\<^sub>d_\<^sub>d OclUnion "\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\" +proof - + have A : "None \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: bot_option_def) + have B : "\None\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(simp add: null_option_def bot_option_def) + show "profile_bin\<^sub>d_\<^sub>d OclUnion (\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\)" + apply unfold_locales + apply(auto simp:OclUnion_def bot_option_def null_option_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def invalid_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF OclUnion_inv A]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF OclUnion_inv B]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + done +qed + +subsection{* Definition: Intersection *} + +definition OclIntersection :: "[('\,'\::null) Set,('\,'\) Set] \ ('\,'\) Set" +where "OclIntersection x y = (\ \. if (\ x) \ = true \ \ (\ y) \ = true \ + then Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\ + \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\\\ + else \ )" +notation OclIntersection("_->intersection\<^sub>S\<^sub>e\<^sub>t'(_')" (*[71,70]70*)) + +lemma OclIntersection_inv: "(x:: Set('b::{null})) \ \ \ x \ null \ y \ \ \ y \ null \ + \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + proof - fix X Y :: "'a state \ 'a state \ Set('b)" fix \ + show "x \ \ \ x \ null \ y \ \ \ y \ null \ ?thesis" + when "x = X \" "y = Y \" + by(auto simp: that, + insert + Set_inv_lemma[simplified OclValid_def + defined_def null_fun_def bot_fun_def, of Y \] + Set_inv_lemma[simplified OclValid_def + defined_def null_fun_def bot_fun_def, of X \], + auto) +qed simp_all + +interpretation OclIntersection : profile_bin\<^sub>d_\<^sub>d OclIntersection "\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\" +proof - + have A : "None \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: bot_option_def) + have B : "\None\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(simp add: null_option_def bot_option_def) + show "profile_bin\<^sub>d_\<^sub>d OclIntersection (\x y. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\)" + apply unfold_locales + apply(auto simp:OclIntersection_def bot_option_def null_option_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def invalid_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF OclIntersection_inv A]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + apply(erule_tac Q="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\\\\ = Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" in contrapos_pp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF OclIntersection_inv B]) + apply(simp_all add: null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def) + done +qed + +subsection{* Definition (future operators) *} + +consts (* abstract set collection operations *) + OclCount :: "[('\,'\::null) Set,('\,'\) Set] \ '\ Integer" + OclSum :: " ('\,'\::null) Set \ '\ Integer" + +notation OclCount ("_->count\<^sub>S\<^sub>e\<^sub>t'(_')" (*[66,65]65*)) +notation OclSum ("_->sum\<^sub>S\<^sub>e\<^sub>t'(')" (*[66]*)) + +subsection{* Logical Properties *} + +text{* OclIncluding *} + +lemma OclIncluding_valid_args_valid: +"(\ \ \(X->including\<^sub>S\<^sub>e\<^sub>t(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (metis (hide_lams, no_types) OclIncluding.def_valid_then_def OclIncluding.defined_args_valid) + +lemma OclIncluding_valid_args_valid''[simp,code_unfold]: +"\(X->including\<^sub>S\<^sub>e\<^sub>t(x)) = ((\ X) and (\ x))" +by (simp add: OclIncluding.def_valid_then_def) + +text{* etc. etc. *} +text_raw{* \isatagafp *} + +text{* OclExcluding *} + +lemma OclExcluding_valid_args_valid: +"(\ \ \(X->excluding\<^sub>S\<^sub>e\<^sub>t(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (metis OclExcluding.def_valid_then_def OclExcluding.defined_args_valid) + +lemma OclExcluding_valid_args_valid''[simp,code_unfold]: +"\(X->excluding\<^sub>S\<^sub>e\<^sub>t(x)) = ((\ X) and (\ x))" +by (simp add: OclExcluding.def_valid_then_def) + +text{* OclIncludes *} + +lemma OclIncludes_valid_args_valid: +"(\ \ \(X->includes\<^sub>S\<^sub>e\<^sub>t(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (simp add: OclIncludes.def_valid_then_def foundation10') + +lemma OclIncludes_valid_args_valid''[simp,code_unfold]: +"\(X->includes\<^sub>S\<^sub>e\<^sub>t(x)) = ((\ X) and (\ x))" +by (simp add: OclIncludes.def_valid_then_def) + +text{* OclExcludes *} + +lemma OclExcludes_valid_args_valid: +"(\ \ \(X->excludes\<^sub>S\<^sub>e\<^sub>t(x))) = ((\ \(\ X)) \ (\ \(\ x)))" +by (simp add: OclExcludes.def_valid_then_def foundation10') + +lemma OclExcludes_valid_args_valid''[simp,code_unfold]: +"\(X->excludes\<^sub>S\<^sub>e\<^sub>t(x)) = ((\ X) and (\ x))" +by (simp add: OclExcludes.def_valid_then_def) + +text{* OclSize *} + +lemma OclSize_defined_args_valid: "\ \ \ (X->size\<^sub>S\<^sub>e\<^sub>t()) \ \ \ \ X" +by(auto simp: OclSize_def OclValid_def true_def valid_def false_def StrongEq_def + defined_def invalid_def bot_fun_def null_fun_def + split: bool.split_asm HOL.split_if_asm option.split) + +lemma OclSize_infinite: +assumes non_finite:"\ \ not(\(S->size\<^sub>S\<^sub>e\<^sub>t()))" +shows "(\ \ not(\(S))) \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\" +apply(insert non_finite, simp) +apply(rule impI) +apply(simp add: OclSize_def OclValid_def defined_def) +apply(case_tac "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\", + simp_all add:null_fun_def null_option_def bot_fun_def bot_option_def) +done + +lemma "\ \ \ X \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ \ \ \ \ (X->size\<^sub>S\<^sub>e\<^sub>t())" +by(simp add: OclSize_def OclValid_def defined_def bot_fun_def false_def true_def) + +lemma size_defined: + assumes X_finite: "\\. finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + shows "\ (X->size\<^sub>S\<^sub>e\<^sub>t()) = \ X" + apply(rule ext, simp add: cp_defined[of "X->size\<^sub>S\<^sub>e\<^sub>t()"] OclSize_def) + apply(simp add: defined_def bot_option_def bot_fun_def null_option_def null_fun_def X_finite) +done + +lemma size_defined': + assumes X_finite: "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + shows "(\ \ \ (X->size\<^sub>S\<^sub>e\<^sub>t())) = (\ \ \ X)" + apply(simp add: cp_defined[of "X->size\<^sub>S\<^sub>e\<^sub>t()"] OclSize_def OclValid_def) + apply(simp add: defined_def bot_option_def bot_fun_def null_option_def null_fun_def X_finite) +done + +text{* OclIsEmpty *} + +lemma OclIsEmpty_defined_args_valid:"\ \ \ (X->isEmpty\<^sub>S\<^sub>e\<^sub>t()) \ \ \ \ X" + apply(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def + bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def + split: split_if_asm) + apply(case_tac "(X->size\<^sub>S\<^sub>e\<^sub>t() \ \) \", simp add: bot_option_def, simp, rename_tac x) + apply(case_tac x, simp add: null_option_def bot_option_def, simp) + apply(simp add: OclSize_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def) +by (metis (hide_lams, no_types) + bot_fun_def OclValid_def defined_def foundation2 invalid_def) + +lemma "\ \ \ (null->isEmpty\<^sub>S\<^sub>e\<^sub>t())" +by(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def + bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def null_is_valid + split: split_if_asm) + +lemma OclIsEmpty_infinite: "\ \ \ X \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ \ \ \ \ (X->isEmpty\<^sub>S\<^sub>e\<^sub>t())" + apply(auto simp: OclIsEmpty_def OclValid_def defined_def valid_def false_def true_def + bot_fun_def null_fun_def OclAnd_def OclOr_def OclNot_def + split: split_if_asm) + apply(case_tac "(X->size\<^sub>S\<^sub>e\<^sub>t() \ \) \", simp add: bot_option_def, simp, rename_tac x) + apply(case_tac x, simp add: null_option_def bot_option_def, simp) +by(simp add: OclSize_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def bot_fun_def false_def true_def invalid_def) + +text{* OclNotEmpty *} + +lemma OclNotEmpty_defined_args_valid:"\ \ \ (X->notEmpty\<^sub>S\<^sub>e\<^sub>t()) \ \ \ \ X" +by (metis (hide_lams, no_types) OclNotEmpty_def OclNot_defargs OclNot_not foundation6 foundation9 + OclIsEmpty_defined_args_valid) + +lemma "\ \ \ (null->notEmpty\<^sub>S\<^sub>e\<^sub>t())" +by (metis (hide_lams, no_types) OclNotEmpty_def OclAnd_false1 OclAnd_idem OclIsEmpty_def + OclNot3 OclNot4 OclOr_def defined2 defined4 transform1 valid2) + +lemma OclNotEmpty_infinite: "\ \ \ X \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ \ \ \ \ (X->notEmpty\<^sub>S\<^sub>e\<^sub>t())" + apply(simp add: OclNotEmpty_def) + apply(drule OclIsEmpty_infinite, simp) +by (metis OclNot_defargs OclNot_not foundation6 foundation9) + +lemma OclNotEmpty_has_elt : "\ \ \ X \ + \ \ X->notEmpty\<^sub>S\<^sub>e\<^sub>t() \ + \e. e \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + apply(simp add: OclNotEmpty_def OclIsEmpty_def deMorgan1 deMorgan2, drule foundation5) + apply(subst (asm) (2) OclNot_def, + simp add: OclValid_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def + split: split_if_asm) + prefer 2 + apply(simp add: invalid_def bot_option_def true_def) + apply(simp add: OclSize_def valid_def split: split_if_asm, + simp_all add: false_def true_def bot_option_def bot_fun_def OclInt0_def) +by (metis equals0I) + +text{* OclANY *} + +lemma OclANY_defined_args_valid: "\ \ \ (X->any\<^sub>S\<^sub>e\<^sub>t()) \ \ \ \ X" +by(auto simp: OclANY_def OclValid_def true_def valid_def false_def StrongEq_def + defined_def invalid_def bot_fun_def null_fun_def OclAnd_def + split: bool.split_asm HOL.split_if_asm option.split) + +lemma "\ \ \ X \ \ \ X->isEmpty\<^sub>S\<^sub>e\<^sub>t() \ \ \ \ \ (X->any\<^sub>S\<^sub>e\<^sub>t())" + apply(simp add: OclANY_def OclValid_def) + apply(subst cp_defined, subst cp_OclAnd, simp add: OclNotEmpty_def, subst (1 2) cp_OclNot, + simp add: cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_defined[symmetric], + simp add: false_def true_def) +by(drule foundation20[simplified OclValid_def true_def], simp) + +lemma OclANY_valid_args_valid: +"(\ \ \(X->any\<^sub>S\<^sub>e\<^sub>t())) = (\ \ \ X)" +proof - + have A: "(\ \ \(X->any\<^sub>S\<^sub>e\<^sub>t())) \ ((\ \(\ X)))" + by(auto simp: OclANY_def OclValid_def true_def valid_def false_def StrongEq_def + defined_def invalid_def bot_fun_def null_fun_def + split: bool.split_asm HOL.split_if_asm option.split) + have B: "(\ \(\ X)) \ (\ \ \(X->any\<^sub>S\<^sub>e\<^sub>t()))" + apply(auto simp: OclANY_def OclValid_def true_def false_def StrongEq_def + defined_def invalid_def valid_def bot_fun_def null_fun_def + bot_option_def null_option_def null_is_valid + OclAnd_def + split: bool.split_asm HOL.split_if_asm option.split) + apply(frule Set_inv_lemma[OF foundation16[THEN iffD2], OF conjI], simp) + apply(subgoal_tac "(\ X) \ = true \") + prefer 2 + apply (metis (hide_lams, no_types) OclValid_def foundation16) + apply(simp add: true_def, + drule OclNotEmpty_has_elt[simplified OclValid_def true_def], simp) + by(erule exE, + insert someI2[where Q = "\x. x \ \" and P = "\y. y \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\"], + simp) + show ?thesis by(auto dest:A intro:B) +qed + +lemma OclANY_valid_args_valid''[simp,code_unfold]: +"\(X->any\<^sub>S\<^sub>e\<^sub>t()) = (\ X)" +by(auto intro!: OclANY_valid_args_valid transform2_rev) + +(* and higher order ones : forall, exists, iterate, select, reject... *) +text_raw{* \endisatagafp *} + +subsection{* Execution Laws with Invalid or Null or Infinite Set as Argument *} + +text{* OclIncluding *} (* properties already generated by the corresponding locale *) + +text{* OclExcluding *} (* properties already generated by the corresponding locale *) + +text{* OclIncludes *} (* properties already generated by the corresponding locale *) + +text{* OclExcludes *} (* properties already generated by the corresponding locale *) + +text{* OclSize *} + +lemma OclSize_invalid[simp,code_unfold]:"(invalid->size\<^sub>S\<^sub>e\<^sub>t()) = invalid" +by(simp add: bot_fun_def OclSize_def invalid_def defined_def valid_def false_def true_def) + +lemma OclSize_null[simp,code_unfold]:"(null->size\<^sub>S\<^sub>e\<^sub>t()) = invalid" +by(rule ext, + simp add: bot_fun_def null_fun_def null_is_valid OclSize_def + invalid_def defined_def valid_def false_def true_def) + +text{* OclIsEmpty *} + +lemma OclIsEmpty_invalid[simp,code_unfold]:"(invalid->isEmpty\<^sub>S\<^sub>e\<^sub>t()) = invalid" +by(simp add: OclIsEmpty_def) + +lemma OclIsEmpty_null[simp,code_unfold]:"(null->isEmpty\<^sub>S\<^sub>e\<^sub>t()) = true" +by(simp add: OclIsEmpty_def) + +text{* OclNotEmpty *} + +lemma OclNotEmpty_invalid[simp,code_unfold]:"(invalid->notEmpty\<^sub>S\<^sub>e\<^sub>t()) = invalid" +by(simp add: OclNotEmpty_def) + +lemma OclNotEmpty_null[simp,code_unfold]:"(null->notEmpty\<^sub>S\<^sub>e\<^sub>t()) = false" +by(simp add: OclNotEmpty_def) + +text{* OclANY *} + +lemma OclANY_invalid[simp,code_unfold]:"(invalid->any\<^sub>S\<^sub>e\<^sub>t()) = invalid" +by(simp add: bot_fun_def OclANY_def invalid_def defined_def valid_def false_def true_def) + +lemma OclANY_null[simp,code_unfold]:"(null->any\<^sub>S\<^sub>e\<^sub>t()) = null" +by(simp add: OclANY_def false_def true_def) + +text{* OclForall *} + +lemma OclForall_invalid[simp,code_unfold]:"invalid->forAll\<^sub>S\<^sub>e\<^sub>t(a| P a) = invalid" +by(simp add: bot_fun_def invalid_def OclForall_def defined_def valid_def false_def true_def) + +lemma OclForall_null[simp,code_unfold]:"null->forAll\<^sub>S\<^sub>e\<^sub>t(a | P a) = invalid" +by(simp add: bot_fun_def invalid_def OclForall_def defined_def valid_def false_def true_def) + +text{* OclExists *} + +lemma OclExists_invalid[simp,code_unfold]:"invalid->exists\<^sub>S\<^sub>e\<^sub>t(a| P a) = invalid" +by(simp add: OclExists_def) + +lemma OclExists_null[simp,code_unfold]:"null->exists\<^sub>S\<^sub>e\<^sub>t(a | P a) = invalid" +by(simp add: OclExists_def) + +text{* OclIterate *} + +lemma OclIterate_invalid[simp,code_unfold]:"invalid->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = A | P a x) = invalid" +by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) + +lemma OclIterate_null[simp,code_unfold]:"null->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = A | P a x) = invalid" +by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) + + +lemma OclIterate_invalid_args[simp,code_unfold]:"S->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = invalid | P a x) = invalid" +by(simp add: bot_fun_def invalid_def OclIterate_def defined_def valid_def false_def true_def) + +text{* An open question is this ... *} +lemma (*OclIterate_null_args[simp,code_unfold]:*) "S->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = null | P a x) = invalid" +oops +(* In the definition above, this does not hold in general. + And I believe, this is how it should be ... *) + +lemma OclIterate_infinite: +assumes non_finite: "\ \ not(\(S->size\<^sub>S\<^sub>e\<^sub>t()))" +shows "(OclIterate S A F) \ = invalid \" +apply(insert non_finite [THEN OclSize_infinite]) +apply(subst (asm) foundation9, simp) +by(metis OclIterate_def OclValid_def invalid_def) + +text{* OclSelect *} + +lemma OclSelect_invalid[simp,code_unfold]:"invalid->select\<^sub>S\<^sub>e\<^sub>t(a | P a) = invalid" +by(simp add: bot_fun_def invalid_def OclSelect_def defined_def valid_def false_def true_def) + +lemma OclSelect_null[simp,code_unfold]:"null->select\<^sub>S\<^sub>e\<^sub>t(a | P a) = invalid" +by(simp add: bot_fun_def invalid_def OclSelect_def defined_def valid_def false_def true_def) + +text{* OclReject *} + +lemma OclReject_invalid[simp,code_unfold]:"invalid->reject\<^sub>S\<^sub>e\<^sub>t(a | P a) = invalid" +by(simp add: OclReject_def) + +lemma OclReject_null[simp,code_unfold]:"null->reject\<^sub>S\<^sub>e\<^sub>t(a | P a) = invalid" +by(simp add: OclReject_def) + +text_raw{* \isatagafp *} + +subsubsection{* Context Passing *} + +lemma cp_OclIncludes1: +"(X->includes\<^sub>S\<^sub>e\<^sub>t(x)) \ = (X->includes\<^sub>S\<^sub>e\<^sub>t(\ _. x \)) \" +by(auto simp: OclIncludes_def StrongEq_def invalid_def + cp_defined[symmetric] cp_valid[symmetric]) + +lemma cp_OclSize: "X->size\<^sub>S\<^sub>e\<^sub>t() \ = ((\_. X \)->size\<^sub>S\<^sub>e\<^sub>t()) \" +by(simp add: OclSize_def cp_defined[symmetric]) + +lemma cp_OclIsEmpty: "X->isEmpty\<^sub>S\<^sub>e\<^sub>t() \ = ((\_. X \)->isEmpty\<^sub>S\<^sub>e\<^sub>t()) \" + apply(simp only: OclIsEmpty_def) + apply(subst (2) cp_OclOr, + subst cp_OclAnd, + subst cp_OclNot, + subst StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0) +by(simp add: cp_defined[symmetric] cp_valid[symmetric] StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0[symmetric] + cp_OclSize[symmetric] cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) + +lemma cp_OclNotEmpty: "X->notEmpty\<^sub>S\<^sub>e\<^sub>t() \ = ((\_. X \)->notEmpty\<^sub>S\<^sub>e\<^sub>t()) \" + apply(simp only: OclNotEmpty_def) + apply(subst (2) cp_OclNot) +by(simp add: cp_OclNot[symmetric] cp_OclIsEmpty[symmetric]) + +lemma cp_OclANY: "X->any\<^sub>S\<^sub>e\<^sub>t() \ = ((\_. X \)->any\<^sub>S\<^sub>e\<^sub>t()) \" + apply(simp only: OclANY_def) + apply(subst (2) cp_OclAnd) +by(simp only: cp_OclAnd[symmetric] cp_defined[symmetric] cp_valid[symmetric] + cp_OclNotEmpty[symmetric]) + +lemma cp_OclForall: +"(S->forAll\<^sub>S\<^sub>e\<^sub>t(x | P x)) \ = ((\ _. S \)->forAll\<^sub>S\<^sub>e\<^sub>t(x | P (\ _. x \))) \" +by(simp add: OclForall_def cp_defined[symmetric]) + +(* first-order version !*) +lemma cp_OclForall1 [simp,intro!]: +"cp S \ cp (\X. ((S X)->forAll\<^sub>S\<^sub>e\<^sub>t(x | P x)))" +apply(simp add: cp_def) +apply(erule exE, rule exI, intro allI) +apply(erule_tac x=X in allE) +by(subst cp_OclForall, simp) + +lemma (*cp_OclForall2 [simp,intro!]:*) +"cp (\X St x. P (\\. x) X St) \ cp S \ cp (\X. (S X)->forAll\<^sub>S\<^sub>e\<^sub>t(x|P x X)) " +apply(simp only: cp_def) +oops + +lemma (*cp_OclForall:*) +"cp S \ + (\ x. cp(P x)) \ + cp(\X. ((S X)->forAll\<^sub>S\<^sub>e\<^sub>t(x | P x X)))" +oops + +lemma cp_OclExists: +"(S->exists\<^sub>S\<^sub>e\<^sub>t(x | P x)) \ = ((\ _. S \)->exists\<^sub>S\<^sub>e\<^sub>t(x | P (\ _. x \))) \" +by(simp add: OclExists_def OclNot_def, subst cp_OclForall, simp) + +(* first-order version !*) +lemma cp_OclExists1 [simp,intro!]: +"cp S \ cp (\X. ((S X)->exists\<^sub>S\<^sub>e\<^sub>t(x | P x)))" +apply(simp add: cp_def) +apply(erule exE, rule exI, intro allI) +apply(erule_tac x=X in allE) +by(subst cp_OclExists,simp) + +lemma cp_OclIterate: + "(X->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = A | P a x)) \ = + ((\ _. X \)->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = A | P a x)) \" +by(simp add: OclIterate_def cp_defined[symmetric]) + +lemma cp_OclSelect: "(X->select\<^sub>S\<^sub>e\<^sub>t(a | P a)) \ = + ((\ _. X \)->select\<^sub>S\<^sub>e\<^sub>t(a | P a)) \" +by(simp add: OclSelect_def cp_defined[symmetric]) + +lemma cp_OclReject: "(X->reject\<^sub>S\<^sub>e\<^sub>t(a | P a)) \ = ((\ _. X \)->reject\<^sub>S\<^sub>e\<^sub>t(a | P a)) \" +by(simp add: OclReject_def, subst cp_OclSelect, simp) + +lemmas cp_intro''\<^sub>S\<^sub>e\<^sub>t[intro!,simp,code_unfold] = + cp_OclSize [THEN allI[THEN allI[THEN cpI1], of "OclSize"]] + cp_OclIsEmpty [THEN allI[THEN allI[THEN cpI1], of "OclIsEmpty"]] + cp_OclNotEmpty [THEN allI[THEN allI[THEN cpI1], of "OclNotEmpty"]] + cp_OclANY [THEN allI[THEN allI[THEN cpI1], of "OclANY"]] + +subsubsection{* Const *} + +lemma const_OclIncluding[simp,code_unfold] : + assumes const_x : "const x" + and const_S : "const S" + shows "const (S->including\<^sub>S\<^sub>e\<^sub>t(x))" + proof - + have A:"\\ \'. \ (\ \ \ x) \ (S->including\<^sub>S\<^sub>e\<^sub>t(x) \) = (S->including\<^sub>S\<^sub>e\<^sub>t(x) \')" + apply(simp add: foundation18) + apply(erule const_subst[OF const_x const_invalid],simp_all) + by(rule const_charn[OF const_invalid]) + have B: "\ \ \'. \ (\ \ \ S) \ (S->including\<^sub>S\<^sub>e\<^sub>t(x) \) = (S->including\<^sub>S\<^sub>e\<^sub>t(x) \')" + apply(simp add: foundation16', elim disjE) + apply(erule const_subst[OF const_S const_invalid],simp_all) + apply(rule const_charn[OF const_invalid]) + apply(erule const_subst[OF const_S const_null],simp_all) + by(rule const_charn[OF const_invalid]) + show ?thesis + apply(simp only: const_def,intro allI, rename_tac \ \') + apply(case_tac "\ (\ \ \ x)", simp add: A) + apply(case_tac "\ (\ \ \ S)", simp_all add: B) + apply(frule_tac \'1= \' in const_OclValid2[OF const_x, THEN iffD1]) + apply(frule_tac \'1= \' in const_OclValid1[OF const_S, THEN iffD1]) + apply(simp add: OclIncluding_def OclValid_def) + apply(subst const_charn[OF const_x]) + apply(subst const_charn[OF const_S]) + by simp +qed +text_raw{* \endisatagafp *} + +subsection{* General Algebraic Execution Rules *} +subsubsection{* Execution Rules on Including *} + +lemma OclIncluding_finite_rep_set : + assumes X_def : "\ \ \ X" + and x_val : "\ \ \ x" + shows "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\ = finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + proof - + have C : "\\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert X_def x_val, frule Set_inv_lemma, simp add: foundation18 invalid_def) + show "?thesis" + by(insert X_def x_val, + auto simp: OclIncluding_def Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF C] + dest: foundation13[THEN iffD2, THEN foundation22[THEN iffD1]]) +qed + +lemma OclIncluding_rep_set: + assumes S_def: "\ \ \ S" + shows "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S->including\<^sub>S\<^sub>e\<^sub>t(\_. \\x\\) \)\\ = insert \\x\\ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\" + apply(simp add: OclIncluding_def S_def[simplified OclValid_def]) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def null_option_def) + apply(insert Set_inv_lemma[OF S_def], metis bot_option_def not_Some_eq) + by(simp) + +lemma OclIncluding_notempty_rep_set: + assumes X_def: "\ \ \ X" + and a_val: "\ \ \ a" + shows "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(a) \)\\ \ {}" + apply(simp add: OclIncluding_def X_def[simplified OclValid_def] a_val[simplified OclValid_def]) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def null_option_def) + apply(insert Set_inv_lemma[OF X_def], metis a_val foundation18') + by(simp) + +lemma OclIncluding_includes0: + assumes "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x)" + shows "X->including\<^sub>S\<^sub>e\<^sub>t(x) \ = X \" +proof - + have includes_def: "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x) \ \ \ \ X" + by (metis bot_fun_def OclIncludes_def OclValid_def defined3 foundation16) + + have includes_val: "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x) \ \ \ \ x" + using foundation5 foundation6 by fastforce + + show ?thesis + apply(insert includes_def[OF assms] includes_val[OF assms] assms, + simp add: OclIncluding_def OclIncludes_def OclValid_def true_def) + apply(drule insert_absorb, simp, subst abs_rep_simp') + by(simp_all add: OclValid_def true_def) +qed + +lemma OclIncluding_includes: + assumes "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x)" + shows "\ \ X->including\<^sub>S\<^sub>e\<^sub>t(x) \ X" +by(simp add: StrongEq_def OclValid_def true_def OclIncluding_includes0[OF assms]) + +lemma OclIncluding_commute0 : + assumes S_def : "\ \ \ S" + and i_val : "\ \ \ i" + and j_val : "\ \ \ j" + shows "\ \ ((S :: ('\, 'a::null) Set)->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(j) \ (S->including\<^sub>S\<^sub>e\<^sub>t(j)->including\<^sub>S\<^sub>e\<^sub>t(i)))" +proof - + have A : "\\insert (i \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert S_def i_val, frule Set_inv_lemma, simp add: foundation18 invalid_def) + have B : "\\insert (j \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert S_def j_val, frule Set_inv_lemma, simp add: foundation18 invalid_def) + + have G1 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (i \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + by(insert A, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G2 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (i \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + by(insert A, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G3 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (j \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + by(insert B, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G4 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (j \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + by(insert B, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + + have * : "(\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (i \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\)) \ = \\True\\" + by(auto simp: OclValid_def false_def defined_def null_fun_def true_def + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def S_def i_val G1 G2) + + have ** : "(\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (j \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\)) \ = \\True\\" + by(auto simp: OclValid_def false_def defined_def null_fun_def true_def + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def S_def i_val G3 G4) + + have *** : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert(j \)\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\insert(i \)\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(S \)\\\\)\\\\ = + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert(i \)\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\insert(j \)\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(S \)\\\\)\\\\" + by(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF A] Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF B] Set.insert_commute) + show ?thesis + apply(simp add: OclIncluding_def S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] + true_def OclValid_def StrongEq_def) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def *) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def ** ***) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def *) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def * ) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def * **) + done +qed + + +lemma OclIncluding_commute[simp,code_unfold]: +"((S :: ('\, 'a::null) Set)->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(j) = (S->including\<^sub>S\<^sub>e\<^sub>t(j)->including\<^sub>S\<^sub>e\<^sub>t(i)))" +proof - + have A: "\ \. \ \ (i \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A': "\ \. \ \ (i \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(j)->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have B:"\ \. \ \ (j \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have B':"\ \. \ \ (j \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(j)->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C: "\ \. \ \ (S \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C': "\ \. \ \ (S \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(j)->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D: "\ \. \ \ (S \ null) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D': "\ \. \ \ (S \ null) \ (S->including\<^sub>S\<^sub>e\<^sub>t(j)->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "\ \ (\ i)") + apply(case_tac "\ \ (\ j)") + apply(case_tac "\ \ (\ S)") + apply(simp only: OclIncluding_commute0[THEN foundation22[THEN iffD1]]) + apply(simp add: foundation16', elim disjE) + apply(simp add: C[OF foundation22[THEN iffD2]] C'[OF foundation22[THEN iffD2]]) + apply(simp add: D[OF foundation22[THEN iffD2]] D'[OF foundation22[THEN iffD2]]) + apply(simp add:foundation18 B[OF foundation22[THEN iffD2]] B'[OF foundation22[THEN iffD2]]) + apply(simp add:foundation18 A[OF foundation22[THEN iffD2]] A'[OF foundation22[THEN iffD2]]) + done +qed + + +subsubsection{* Execution Rules on Excluding *} + +lemma OclExcluding_finite_rep_set : + assumes X_def : "\ \ \ X" + and x_val : "\ \ \ x" + shows "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->excluding\<^sub>S\<^sub>e\<^sub>t(x) \)\\ = finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + proof - + have C : "\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {x \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + apply(insert X_def x_val, frule Set_inv_lemma) + apply(simp add: foundation18 invalid_def) + done + show "?thesis" + by(insert X_def x_val, + auto simp: OclExcluding_def Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF C] + dest: foundation13[THEN iffD2, THEN foundation22[THEN iffD1]]) +qed + +lemma OclExcluding_rep_set: + assumes S_def: "\ \ \ S" + shows "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S->excluding\<^sub>S\<^sub>e\<^sub>t(\_. \\x\\) \)\\ = \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {\\x\\}" + apply(simp add: OclExcluding_def S_def[simplified OclValid_def]) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def null_option_def) + apply(insert Set_inv_lemma[OF S_def], metis Diff_iff bot_option_def not_None_eq) +by(simp) + +lemma OclExcluding_excludes0: + assumes "\ \ X->excludes\<^sub>S\<^sub>e\<^sub>t(x)" + shows "X->excluding\<^sub>S\<^sub>e\<^sub>t(x) \ = X \" +proof - + have excludes_def: "\ \ X->excludes\<^sub>S\<^sub>e\<^sub>t(x) \ \ \ \ X" + by (metis OclExcludes.def_valid_then_def OclExcludes_valid_args_valid'' foundation10' foundation6) + + have excludes_val: "\ \ X->excludes\<^sub>S\<^sub>e\<^sub>t(x) \ \ \ \ x" + by (metis OclExcludes.def_valid_then_def OclExcludes_valid_args_valid'' foundation10' foundation6) + + show ?thesis + apply(insert excludes_def[OF assms] excludes_val[OF assms] assms, + simp add: OclExcluding_def OclExcludes_def OclIncludes_def OclNot_def OclValid_def true_def) + by (metis (hide_lams, no_types) abs_rep_simp' assms excludes_def) +qed + +lemma OclExcluding_excludes: + assumes "\ \ X->excludes\<^sub>S\<^sub>e\<^sub>t(x)" + shows "\ \ X->excluding\<^sub>S\<^sub>e\<^sub>t(x) \ X" +by(simp add: StrongEq_def OclValid_def true_def OclExcluding_excludes0[OF assms]) + +lemma OclExcluding_charn0[simp]: +assumes val_x:"\ \ (\ x)" +shows "\ \ ((Set{}->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ Set{})" +proof - + have A : "\None\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(simp add: null_option_def bot_option_def) + have B : "\\{}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" by(simp add: mtSet_def) + + show ?thesis using val_x + apply(auto simp: OclValid_def OclIncludes_def OclNot_def false_def true_def StrongEq_def + OclExcluding_def mtSet_def defined_def bot_fun_def null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + apply(auto simp: mtSet_def Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse + Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF B A]) + done +qed + +lemma OclExcluding_commute0 : + assumes S_def : "\ \ \ S" + and i_val : "\ \ \ i" + and j_val : "\ \ \ j" + shows "\ \ ((S :: ('\, 'a::null) Set)->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(j) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(j)->excluding\<^sub>S\<^sub>e\<^sub>t(i)))" +proof - + have A : "\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {i \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert S_def i_val, frule Set_inv_lemma, simp add: foundation18 invalid_def) + have B : "\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {j \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert S_def j_val, frule Set_inv_lemma, simp add: foundation18 invalid_def) + + have G1 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {i \}\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + by(insert A, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G2 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {i \}\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + by(insert A, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G3 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {j \}\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + by(insert B, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G4 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {j \}\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + by(insert B, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + + have * : "(\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {i \}\\)) \ = \\True\\" + by(auto simp: OclValid_def false_def defined_def null_fun_def true_def + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def S_def i_val G1 G2) + + have ** : "(\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {j \}\\)) \ = \\True\\" + by(auto simp: OclValid_def false_def defined_def null_fun_def true_def + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def S_def i_val G3 G4) + + have *** : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(S \)\\-{i \}\\)\\-{j \}\\ = + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e(S \)\\-{j \}\\)\\-{i \}\\" + apply(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF A] Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF B]) + by (metis Diff_insert2 insert_commute) + show ?thesis + apply(simp add: OclExcluding_def S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] + true_def OclValid_def StrongEq_def) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def *) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def ** ***) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def *) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def * ) + apply(subst cp_defined, + simp add: S_def[simplified OclValid_def] + i_val[simplified OclValid_def] j_val[simplified OclValid_def] true_def * **) + done +qed + + +lemma OclExcluding_commute[simp,code_unfold]: +"((S :: ('\, 'a::null) Set)->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(j) = (S->excluding\<^sub>S\<^sub>e\<^sub>t(j)->excluding\<^sub>S\<^sub>e\<^sub>t(i)))" +proof - + have A: "\ \. \ \ i \ invalid \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A': "\ \. \ \ i \ invalid \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(j)->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have B:"\ \. \ \ j \ invalid \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have B':"\ \. \ \ j \ invalid \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(j)->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C: "\ \. \ \ S \ invalid \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C': "\ \. \ \ S \ invalid \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(j)->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D: "\ \. \ \ S \ null \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(j)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D': "\ \. \ \ S \ null \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(j)->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "\ \ (\ i)") + apply(case_tac "\ \ (\ j)") + apply(case_tac "\ \ (\ S)") + apply(simp only: OclExcluding_commute0[THEN foundation22[THEN iffD1]]) + apply(simp add: foundation16', elim disjE) + apply(simp add: C[OF foundation22[THEN iffD2]] C'[OF foundation22[THEN iffD2]]) + apply(simp add: D[OF foundation22[THEN iffD2]] D'[OF foundation22[THEN iffD2]]) + apply(simp add:foundation18 B[OF foundation22[THEN iffD2]] B'[OF foundation22[THEN iffD2]]) + apply(simp add:foundation18 A[OF foundation22[THEN iffD2]] A'[OF foundation22[THEN iffD2]]) + done +qed + + +lemma OclExcluding_charn0_exec[simp,code_unfold]: +"(Set{}->excluding\<^sub>S\<^sub>e\<^sub>t(x)) = (if (\ x) then Set{} else invalid endif)" +proof - + have A: "\ \. (Set{}->excluding\<^sub>S\<^sub>e\<^sub>t(invalid)) \ = (if (\ invalid) then Set{} else invalid endif) \" + by simp + have B: "\ \ x. \ \ (\ x) \ + (Set{}->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ = (if (\ x) then Set{} else invalid endif) \" + by(simp add: OclExcluding_charn0[THEN foundation22[THEN iffD1]]) + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "\ \ (\ x)") + apply(simp add: B) + apply(simp add: foundation18) + apply(subst OclExcluding.cp0, simp) + apply(simp add: cp_OclIf[symmetric] OclExcluding.cp0[symmetric] cp_valid[symmetric] A) + done +qed + +lemma OclExcluding_charn1: +assumes def_X:"\ \ (\ X)" +and val_x:"\ \ (\ x)" +and val_y:"\ \ (\ y)" +and neq :"\ \ not(x \ y)" +shows "\ \ ((X->including\<^sub>S\<^sub>e\<^sub>t(x))->excluding\<^sub>S\<^sub>e\<^sub>t(y)) \ ((X->excluding\<^sub>S\<^sub>e\<^sub>t(y))->including\<^sub>S\<^sub>e\<^sub>t(x))" +proof - + have C : "\\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) + have D : "\\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {y \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) + have E : "x \ \ y \" + by(insert neq, + auto simp: OclValid_def bot_fun_def OclIncluding_def OclIncludes_def + false_def true_def defined_def valid_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def StrongEq_def OclNot_def) + + have G1 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + by(insert C, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G2 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + by(insert C, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G : "(\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\)) \ = true \" + by(auto simp: OclValid_def false_def true_def defined_def + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def G1 G2) + + have H1 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {y \}\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + by(insert D, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have H2 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {y \}\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + by(insert D, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have H : "(\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {y \}\\)) \ = true \" + by(auto simp: OclValid_def false_def true_def defined_def + bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def H1 H2) + + have Z : "insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {y \} = insert (x \) (\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {y \})" + by(auto simp: E) + show ?thesis + apply(insert def_X[THEN foundation13[THEN iffD2]] val_x[THEN foundation13[THEN iffD2]] + val_y[THEN foundation13[THEN iffD2]]) + apply(simp add: foundation22 OclIncluding_def OclExcluding_def def_X[THEN foundation16[THEN iffD1]]) + apply(subst cp_defined, simp)+ + apply(simp add: G H Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF C] Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF D] Z) + done +qed + + + +lemma OclExcluding_charn2: +assumes def_X:"\ \ (\ X)" +and val_x:"\ \ (\ x)" +shows "\ \ (((X->including\<^sub>S\<^sub>e\<^sub>t(x))->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x)))" +proof - + have C : "\\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) + have G1 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None" + by(insert C, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + have G2 : "Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \None\" + by(insert C, simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject bot_option_def null_option_def) + show ?thesis + apply(insert def_X[THEN foundation16[THEN iffD1]] + val_x[THEN foundation18[THEN iffD1]]) + apply(auto simp: OclValid_def bot_fun_def OclIncluding_def OclIncludes_def false_def true_def + invalid_def defined_def valid_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + StrongEq_def) + apply(subst OclExcluding.cp0) + apply(auto simp:OclExcluding_def) + apply(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF C]) + apply(simp_all add: false_def true_def defined_def valid_def + null_fun_def bot_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def + split: bool.split_asm HOL.split_if_asm option.split) + apply(auto simp: G1 G2) + done +qed + + + + +theorem OclExcluding_charn3: "((X->including\<^sub>S\<^sub>e\<^sub>t(x))->excluding\<^sub>S\<^sub>e\<^sub>t(x)) = (X->excluding\<^sub>S\<^sub>e\<^sub>t(x))" +proof - + have A1 : "\\. \ \ (X \ invalid) \ (X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A1': "\\. \ \ (X \ invalid) \ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A2 : "\\. \ \ (X \ null) \ (X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A2': "\\. \ \ (X \ null) \ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A3 : "\\. \ \ (x \ invalid) \ (X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A3': "\\. \ \ (x \ invalid) \ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + + show ?thesis + apply(rule ext, rename_tac "\") + apply(case_tac "\ \ (\ x)") + apply(case_tac "\ \ (\ X)") + apply(simp only: OclExcluding_charn2[THEN foundation22[THEN iffD1]]) + apply(simp add: foundation16', elim disjE) + apply(simp add: A1[OF foundation22[THEN iffD2]] A1'[OF foundation22[THEN iffD2]]) + apply(simp add: A2[OF foundation22[THEN iffD2]] A2'[OF foundation22[THEN iffD2]]) + apply(simp add:foundation18 A3[OF foundation22[THEN iffD2]] A3'[OF foundation22[THEN iffD2]]) + done +qed + + +text{* One would like a generic theorem of the form: +\begin{isar}[mathescape] +lemma OclExcluding_charn_exec: + "(X->including$_{Set}$(x::('$\mathfrak{A}$,'a::null)val)->excluding$_{Set}$(y)) = + (if \ X then if x \ y + then X->excluding$_{Set}$(y) + else X->excluding$_{Set}$(y)->including$_{Set}$(x) + endif + else invalid endif)" +\end{isar} +Unfortunately, this does not hold in general, since referential equality is +an overloaded concept and has to be defined for each type individually. +Consequently, it is only valid for concrete type instances for Boolean, +Integer, and Sets thereof... +*} + + +text{* The computational law \emph{OclExcluding-charn-exec} becomes generic since it +uses strict equality which in itself is generic. It is possible to prove +the following generic theorem and instantiate it later (using properties +that link the polymorphic logical strong equality with the concrete instance +of strict quality).*} +lemma OclExcluding_charn_exec: + assumes strict1: "(invalid \ y) = invalid" + and strict2: "(x \ invalid) = invalid" + and StrictRefEq_valid_args_valid: "\ (x::('\,'a::null)val) y \. + (\ \ \ (x \ y)) = ((\ \ (\ x)) \ (\ \ \ y))" + and cp_StrictRefEq: "\ (X::('\,'a::null)val) Y \. (X \ Y) \ = ((\_. X \) \ (\_. Y \)) \" + and StrictRefEq_vs_StrongEq: "\ (x::('\,'a::null)val) y \. + \ \ \ x \ \ \ \ y \ (\ \ ((x \ y) \ (x \ y)))" + shows "(X->including\<^sub>S\<^sub>e\<^sub>t(x::('\,'a::null)val)->excluding\<^sub>S\<^sub>e\<^sub>t(y)) = + (if \ X then if x \ y + then X->excluding\<^sub>S\<^sub>e\<^sub>t(y) + else X->excluding\<^sub>S\<^sub>e\<^sub>t(y)->including\<^sub>S\<^sub>e\<^sub>t(x) + endif + else invalid endif)" +proof - + (* Lifting theorems, largely analogous OclIncludes_execute_generic, + with the same problems wrt. strict equality. *) + have A1: "\\. \ \ (X \ invalid) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + + have B1: "\\. \ \ (X \ null) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + + have A2: "\\. \ \ (X \ invalid) \ X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(y) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + + have B2: "\\. \ \ (X \ null) \ X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(y) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + + note [simp] = cp_StrictRefEq [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "StrictRefEq"]] + + have C: "\\. \ \ (x \ invalid) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(y)) \ = + (if x \ y then X->excluding\<^sub>S\<^sub>e\<^sub>t(y) else X->excluding\<^sub>S\<^sub>e\<^sub>t(y)->including\<^sub>S\<^sub>e\<^sub>t(x) endif) \" + apply(rule foundation22[THEN iffD1]) + apply(erule StrongEq_L_subst2_rev,simp,simp) + by(simp add: strict1) + + have D: "\\. \ \ (y \ invalid) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(y)) \ = + (if x \ y then X->excluding\<^sub>S\<^sub>e\<^sub>t(y) else X->excluding\<^sub>S\<^sub>e\<^sub>t(y)->including\<^sub>S\<^sub>e\<^sub>t(x) endif) \" + apply(rule foundation22[THEN iffD1]) + apply(erule StrongEq_L_subst2_rev,simp,simp) + by (simp add: strict2) + + have E: "\\. \ \ \ x \ \ \ \ y \ + (if x \ y then X->excluding\<^sub>S\<^sub>e\<^sub>t(y) else X->excluding\<^sub>S\<^sub>e\<^sub>t(y)->including\<^sub>S\<^sub>e\<^sub>t(x) endif) \ = + (if x \ y then X->excluding\<^sub>S\<^sub>e\<^sub>t(y) else X->excluding\<^sub>S\<^sub>e\<^sub>t(y)->including\<^sub>S\<^sub>e\<^sub>t(x) endif) \" + apply(subst cp_OclIf) + apply(subst StrictRefEq_vs_StrongEq[THEN foundation22[THEN iffD1]]) + by(simp_all add: cp_OclIf[symmetric]) + + have F: "\\. \ \ \ X \ \ \ \ x \ \ \ (x \ y) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->excluding\<^sub>S\<^sub>e\<^sub>t(y) \) = (X->excluding\<^sub>S\<^sub>e\<^sub>t(y) \)" + apply(drule StrongEq_L_sym) + apply(rule foundation22[THEN iffD1]) + apply(erule StrongEq_L_subst2_rev,simp) + by(simp add: OclExcluding_charn2) + + show ?thesis + apply(rule ext, rename_tac "\") + apply(case_tac "\ (\ \ (\ X))", simp add:defined_split,elim disjE A1 B1 A2 B2) + apply(case_tac "\ (\ \ (\ x))", + simp add:foundation18 foundation22[symmetric], + drule StrongEq_L_sym) + apply(simp add: foundation22 C) + apply(case_tac "\ (\ \ (\ y))", + simp add:foundation18 foundation22[symmetric], + drule StrongEq_L_sym, simp add: foundation22 D, simp) + apply(subst E,simp_all) + apply(case_tac "\ \ not (x \ y)") + apply(simp add: OclExcluding_charn1[simplified foundation22] + OclExcluding_charn2[simplified foundation22]) + apply(simp add: foundation9 F) + done +qed + + +(* Hack to work around OF-Bug *) +schematic_goal OclExcluding_charn_exec\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[simp,code_unfold]: "?X" +by(rule OclExcluding_charn_exec[OF StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.strict1 StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.strict2 + StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.defined_args_valid + StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0 StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.StrictRefEq_vs_StrongEq], simp_all) + +schematic_goal OclExcluding_charn_exec\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[simp,code_unfold]: "?X" +by(rule OclExcluding_charn_exec[OF StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.strict1 StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.strict2 + StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.defined_args_valid + StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.cp0 StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.StrictRefEq_vs_StrongEq], simp_all) + + +schematic_goal OclExcluding_charn_exec\<^sub>S\<^sub>e\<^sub>t[simp,code_unfold]: "?X" +by(rule OclExcluding_charn_exec[OF StrictRefEq\<^sub>S\<^sub>e\<^sub>t.strict1 StrictRefEq\<^sub>S\<^sub>e\<^sub>t.strict2 + StrictRefEq\<^sub>S\<^sub>e\<^sub>t.defined_args_valid + StrictRefEq\<^sub>S\<^sub>e\<^sub>t.cp0 StrictRefEq\<^sub>S\<^sub>e\<^sub>t.StrictRefEq_vs_StrongEq], simp_all) + + +subsubsection{* Execution Rules on Includes *} + +lemma OclIncludes_charn0[simp]: +assumes val_x:"\ \ (\ x)" +shows "\ \ not(Set{}->includes\<^sub>S\<^sub>e\<^sub>t(x))" +using val_x +apply(auto simp: OclValid_def OclIncludes_def OclNot_def false_def true_def) +apply(auto simp: mtSet_def Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) +done + + +lemma OclIncludes_charn0'[simp,code_unfold]: +"Set{}->includes\<^sub>S\<^sub>e\<^sub>t(x) = (if \ x then false else invalid endif)" +proof - + have A: "\ \. (Set{}->includes\<^sub>S\<^sub>e\<^sub>t(invalid)) \ = (if (\ invalid) then false else invalid endif) \" + by simp + have B: "\ \ x. \ \ (\ x) \ (Set{}->includes\<^sub>S\<^sub>e\<^sub>t(x)) \ = (if \ x then false else invalid endif) \" + apply(frule OclIncludes_charn0, simp add: OclValid_def) + apply(rule foundation21[THEN fun_cong, simplified StrongEq_def,simplified, + THEN iffD1, of _ _ "false"]) + by simp + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "\ \ (\ x)") + apply(simp_all add: B foundation18) + apply(subst OclIncludes.cp0, simp add: OclIncludes.cp0[symmetric] A) + done +qed + +lemma OclIncludes_charn1: +assumes def_X:"\ \ (\ X)" +assumes val_x:"\ \ (\ x)" +shows "\ \ (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(x))" +proof - + have C : "\\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) + show ?thesis + apply(subst OclIncludes_def, simp add: foundation10[simplified OclValid_def] OclValid_def + def_X[simplified OclValid_def] val_x[simplified OclValid_def]) + apply(simp add: OclIncluding_def def_X[simplified OclValid_def] val_x[simplified OclValid_def] + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF C] true_def) + done +qed + + + +lemma OclIncludes_charn2: +assumes def_X:"\ \ (\ X)" +and val_x:"\ \ (\ x)" +and val_y:"\ \ (\ y)" +and neq :"\ \ not(x \ y)" +shows "\ \ (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ (X->includes\<^sub>S\<^sub>e\<^sub>t(y))" +proof - + have C : "\\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(insert def_X val_x, frule Set_inv_lemma, simp add: foundation18 invalid_def) + show ?thesis + apply(subst OclIncludes_def, + simp add: def_X[simplified OclValid_def] val_x[simplified OclValid_def] + val_y[simplified OclValid_def] foundation10[simplified OclValid_def] + OclValid_def StrongEq_def) + apply(simp add: OclIncluding_def OclIncludes_def def_X[simplified OclValid_def] + val_x[simplified OclValid_def] val_y[simplified OclValid_def] + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF C] true_def) + by(metis foundation22 foundation6 foundation9 neq) +qed + +text{* Here is again a generic theorem similar as above. *} + +lemma OclIncludes_execute_generic: +assumes strict1: "(invalid \ y) = invalid" +and strict2: "(x \ invalid) = invalid" +and cp_StrictRefEq: "\ (X::('\,'a::null)val) Y \. (X \ Y) \ = ((\_. X \) \ (\_. Y \)) \" +and StrictRefEq_vs_StrongEq: "\ (x::('\,'a::null)val) y \. + \ \ \ x \ \ \ \ y \ (\ \ ((x \ y) \ (x \ y)))" +shows + "(X->including\<^sub>S\<^sub>e\<^sub>t(x::('\,'a::null)val)->includes\<^sub>S\<^sub>e\<^sub>t(y)) = + (if \ X then if x \ y then true else X->includes\<^sub>S\<^sub>e\<^sub>t(y) endif else invalid endif)" +proof - + have A: "\\. \ \ (X \ invalid) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev,simp,simp) + have B: "\\. \ \ (X \ null) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev,simp,simp) + + note [simp] = cp_StrictRefEq [THEN allI[THEN allI[THEN allI[THEN cpI2]], of "StrictRefEq"]] + + have C: "\\. \ \ (x \ invalid) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ = + (if x \ y then true else X->includes\<^sub>S\<^sub>e\<^sub>t(y) endif) \" + apply(rule foundation22[THEN iffD1]) + apply(erule StrongEq_L_subst2_rev,simp,simp) + by (simp add: strict1) + have D:"\\. \ \ (y \ invalid) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ = + (if x \ y then true else X->includes\<^sub>S\<^sub>e\<^sub>t(y) endif) \" + apply(rule foundation22[THEN iffD1]) + apply(erule StrongEq_L_subst2_rev,simp,simp) + by (simp add: strict2) + have E: "\\. \ \ \ x \ \ \ \ y \ + (if x \ y then true else X->includes\<^sub>S\<^sub>e\<^sub>t(y) endif) \ = + (if x \ y then true else X->includes\<^sub>S\<^sub>e\<^sub>t(y) endif) \" + apply(subst cp_OclIf) + apply(subst StrictRefEq_vs_StrongEq[THEN foundation22[THEN iffD1]]) + by(simp_all add: cp_OclIf[symmetric]) + have F: "\\. \ \ (x \ y) \ + (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(y)) \ = (X->including\<^sub>S\<^sub>e\<^sub>t(x)->includes\<^sub>S\<^sub>e\<^sub>t(x)) \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev,simp, simp) + show ?thesis + apply(rule ext, rename_tac "\") + apply(case_tac "\ (\ \ (\ X))", simp add:defined_split,elim disjE A B) + apply(case_tac "\ (\ \ (\ x))", + simp add:foundation18 foundation22[symmetric], + drule StrongEq_L_sym) + apply(simp add: foundation22 C) + apply(case_tac "\ (\ \ (\ y))", + simp add:foundation18 foundation22[symmetric], + drule StrongEq_L_sym, simp add: foundation22 D, simp) + apply(subst E,simp_all) + apply(case_tac "\ \ not(x \ y)") + apply(simp add: OclIncludes_charn2[simplified foundation22]) + apply(simp add: foundation9 F + OclIncludes_charn1[THEN foundation13[THEN iffD2], + THEN foundation22[THEN iffD1]]) + done +qed + + +(* Hack to work around OF-Bug *) +schematic_goal OclIncludes_execute\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[simp,code_unfold]: "?X" +by(rule OclIncludes_execute_generic[OF StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.strict1 StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.strict2 + StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0 + StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.StrictRefEq_vs_StrongEq], simp_all) + + +schematic_goal OclIncludes_execute\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[simp,code_unfold]: "?X" +by(rule OclIncludes_execute_generic[OF StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.strict1 StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.strict2 + StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.cp0 + StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n.StrictRefEq_vs_StrongEq], simp_all) + + +schematic_goal OclIncludes_execute\<^sub>S\<^sub>e\<^sub>t[simp,code_unfold]: "?X" +by(rule OclIncludes_execute_generic[OF StrictRefEq\<^sub>S\<^sub>e\<^sub>t.strict1 StrictRefEq\<^sub>S\<^sub>e\<^sub>t.strict2 + StrictRefEq\<^sub>S\<^sub>e\<^sub>t.cp0 + StrictRefEq\<^sub>S\<^sub>e\<^sub>t.StrictRefEq_vs_StrongEq], simp_all) + +lemma OclIncludes_including_generic : + assumes OclIncludes_execute_generic [simp] : "\X x y. + (X->including\<^sub>S\<^sub>e\<^sub>t(x::('\,'a::null)val)->includes\<^sub>S\<^sub>e\<^sub>t(y)) = + (if \ X then if x \ y then true else X->includes\<^sub>S\<^sub>e\<^sub>t(y) endif else invalid endif)" + and StrictRefEq_strict'' : "\x y. \ ((x::('\,'a::null)val) \ y) = (\(x) and \(y))" + and a_val : "\ \ \ a" + and x_val : "\ \ \ x" + and S_incl : "\ \ (S)->includes\<^sub>S\<^sub>e\<^sub>t((x::('\,'a::null)val))" + shows "\ \ S->including\<^sub>S\<^sub>e\<^sub>t((a::('\,'a::null)val))->includes\<^sub>S\<^sub>e\<^sub>t(x)" +proof - + have discr_eq_bot1_true : "\\. (\ \ = true \) = False" + by (metis bot_fun_def foundation1 foundation18' valid3) + have discr_eq_bot2_true : "\\. (\ = true \) = False" + by (metis bot_fun_def discr_eq_bot1_true) + have discr_neq_invalid_true : "\\. (invalid \ \ true \) = True" + by (metis discr_eq_bot2_true invalid_def) + have discr_eq_invalid_true : "\\. (invalid \ = true \) = False" + by (metis bot_option_def invalid_def option.simps(2) true_def) +show ?thesis + apply(simp) + apply(subgoal_tac "\ \ \ S") + prefer 2 + apply(insert S_incl[simplified OclIncludes_def], simp add: OclValid_def) + apply(metis discr_eq_bot2_true) + apply(simp add: cp_OclIf[of "\ S"] OclValid_def OclIf_def x_val[simplified OclValid_def] + discr_neq_invalid_true discr_eq_invalid_true) + by (metis OclValid_def S_incl StrictRefEq_strict'' a_val foundation10 foundation6 x_val) +qed + +lemmas OclIncludes_including\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r = + OclIncludes_including_generic[OF OclIncludes_execute\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.def_homo] + +subsubsection{* Execution Rules on Excludes *} + +lemma OclExcludes_charn1: +assumes def_X:"\ \ (\ X)" +assumes val_x:"\ \ (\ x)" +shows "\ \ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x)->excludes\<^sub>S\<^sub>e\<^sub>t(x))" +proof - + let ?OclSet = "\S. \\S\\ \ {X. X = \ \ X = null \ (\x\\\X\\. x \ \)}" + have diff_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e : "?OclSet (\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {x \})" + apply(simp, (rule disjI2)+) + by (metis (hide_lams, no_types) Diff_iff Set_inv_lemma def_X) + + show ?thesis + apply(subst OclExcludes_def, simp add: foundation10[simplified OclValid_def] OclValid_def + def_X[simplified OclValid_def] val_x[simplified OclValid_def]) + apply(subst OclIncludes_def, simp add: OclNot_def) + apply(simp add: OclExcluding_def def_X[simplified OclValid_def] val_x[simplified OclValid_def] + Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF diff_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e] true_def) + by(simp add: OclAnd_def def_X[simplified OclValid_def] val_x[simplified OclValid_def] true_def) +qed + +subsubsection{* Execution Rules on Size *} + +lemma [simp,code_unfold]: "Set{} ->size\<^sub>S\<^sub>e\<^sub>t() = \" + apply(rule ext) + apply(simp add: defined_def mtSet_def OclSize_def + bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def + null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, simp_all add: bot_option_def null_option_def) + +by(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse bot_option_def null_option_def OclInt0_def) + +lemma OclSize_including_exec[simp,code_unfold]: + "((X ->including\<^sub>S\<^sub>e\<^sub>t(x)) ->size\<^sub>S\<^sub>e\<^sub>t()) = (if \ X and \ x then + X ->size\<^sub>S\<^sub>e\<^sub>t() +\<^sub>i\<^sub>n\<^sub>t if X ->includes\<^sub>S\<^sub>e\<^sub>t(x) then \ else \ endif + else + invalid + endif)" +proof - + + have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac "P \ = \", simp_all add: true_def) + have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) + + show ?thesis + apply(rule ext, rename_tac \) + proof - + fix \ + have includes_notin: "\ \ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x) \ (\ X) \ = true \ \ (\ x) \ = true \ \ + x \ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + by(simp add: OclIncludes_def OclValid_def true_def) + + have includes_def: "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x) \ \ \ \ X" + by (metis bot_fun_def OclIncludes_def OclValid_def defined3 foundation16) + + have includes_val: "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x) \ \ \ \ x" + using foundation5 foundation6 by fastforce + + have ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e: "\ \ \ X \ \ \ \ x \ + \\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\\\ \ {X. X = \ \ X = null \ (\x\\\X\\. x \ \)}" + apply(simp add: bot_option_def null_option_def) + by (metis (hide_lams, no_types) Set_inv_lemma foundation18' foundation5) + + have m : "\\. (\_. \) = (\_. invalid \)" by(rule ext, simp add:invalid_def) + + show "X->including\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t() \ = (if \ X and \ x + then X->size\<^sub>S\<^sub>e\<^sub>t() +\<^sub>i\<^sub>n\<^sub>t if X->includes\<^sub>S\<^sub>e\<^sub>t(x) then \ else \ endif + else invalid endif) \" + apply(case_tac "\ \ \ X and \ x", simp) + apply(subst OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0) + apply(case_tac "\ \ X->includes\<^sub>S\<^sub>e\<^sub>t(x)", simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0[symmetric]) + apply(case_tac "\ \ ((\ (X->size\<^sub>S\<^sub>e\<^sub>t())) and not (\ (X->size\<^sub>S\<^sub>e\<^sub>t())))", simp) + apply(drule foundation5[where P = "\ X->size\<^sub>S\<^sub>e\<^sub>t()"], erule conjE) + apply(drule OclSize_infinite) + apply(frule includes_def, drule includes_val, simp) + apply(subst OclSize_def, subst OclIncluding_finite_rep_set, assumption+) + apply (metis (hide_lams, no_types) invalid_def) + + apply(subst OclIf_false', + metis (hide_lams, no_types) defined5 defined6 defined_and_I defined_not_I + foundation1 foundation9) + apply(subst cp_OclSize, simp add: OclIncluding_includes0 cp_OclSize[symmetric]) + (* *) + apply(subst OclIf_false', subst foundation9, auto, simp add: OclSize_def) + apply(drule foundation5) + apply(subst (1 2) OclIncluding_finite_rep_set, fast+) + apply(subst (1 2) cp_OclAnd, subst (1 2) OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0, simp) + apply(rule conjI) + apply(simp add: OclIncluding_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e], fast+) + apply(subst (asm) (2 3) OclValid_def, simp add: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r_def OclInt1_def) + apply(rule impI) + apply(drule Finite_Set.card.insert[where x = "x \"]) + apply(rule includes_notin, simp, simp) + apply (metis Suc_eq_plus1 int_1 of_nat_add) + + apply(subst (1 2) m[of \], simp only: OclAdd\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0[symmetric],simp, simp add:invalid_def) + apply(subst OclIncluding_finite_rep_set, fast+, simp add: OclValid_def) + (* *) + apply(subst OclIf_false', metis (hide_lams, no_types) defined6 foundation1 foundation9 + OclExcluding_valid_args_valid'') + by (metis cp_OclSize foundation18' OclIncluding_valid_args_valid'' invalid_def OclSize_invalid) + qed +qed + +subsubsection{* Execution Rules on IsEmpty *} + +lemma [simp,code_unfold]: "Set{}->isEmpty\<^sub>S\<^sub>e\<^sub>t() = true" +by(simp add: OclIsEmpty_def) + +lemma OclIsEmpty_including [simp]: +assumes X_def: "\ \ \ X" + and X_finite: "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + and a_val: "\ \ \ a" +shows "X->including\<^sub>S\<^sub>e\<^sub>t(a)->isEmpty\<^sub>S\<^sub>e\<^sub>t() \ = false \" +proof - + have A1 : "\\ X. X \ = true \ \ X \ = false \ \ (X and not X) \ = false \" + by (metis (no_types) OclAnd_false1 OclAnd_idem OclImplies_def OclNot3 OclNot_not OclOr_false1 + cp_OclAnd cp_OclNot deMorgan1 deMorgan2) + + have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) + + have B : "\X \. \ \ \ X \ X \ \ \ \ \ (X \ \) \ = false \" + apply(simp add: foundation22[symmetric] foundation14 foundation9) + apply(erule StrongEq_L_subst4_rev[THEN iffD2, OF StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.StrictRefEq_vs_StrongEq]) + by(simp_all) + + show ?thesis + apply(simp add: OclIsEmpty_def del: OclSize_including_exec) + apply(subst cp_OclOr, subst A1) + apply (metis OclExcludes.def_homo defined_inject_true) + apply(simp add: cp_OclOr[symmetric] del: OclSize_including_exec) + apply(rule B, + rule foundation20, + metis OclIncluding.def_homo OclIncluding_finite_rep_set X_def X_finite a_val foundation10' size_defined') + apply(simp add: OclSize_def OclIncluding_finite_rep_set[OF X_def a_val] X_finite OclInt0_def) + by (metis OclValid_def X_def a_val foundation10 foundation6 + OclIncluding_notempty_rep_set[OF X_def a_val]) +qed + +subsubsection{* Execution Rules on NotEmpty *} + +lemma [simp,code_unfold]: "Set{}->notEmpty\<^sub>S\<^sub>e\<^sub>t() = false" +by(simp add: OclNotEmpty_def) + +lemma OclNotEmpty_including [simp,code_unfold]: +assumes X_def: "\ \ \ X" + and X_finite: "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + and a_val: "\ \ \ a" +shows "X->including\<^sub>S\<^sub>e\<^sub>t(a)->notEmpty\<^sub>S\<^sub>e\<^sub>t() \ = true \" + apply(simp add: OclNotEmpty_def) + apply(subst cp_OclNot, subst OclIsEmpty_including, simp_all add: assms) +by (metis OclNot4 cp_OclNot) + +subsubsection{* Execution Rules on Any *} + +lemma [simp,code_unfold]: "Set{}->any\<^sub>S\<^sub>e\<^sub>t() = null" +by(rule ext, simp add: OclANY_def, simp add: false_def true_def) + +lemma OclANY_singleton_exec[simp,code_unfold]: + "(Set{}->including\<^sub>S\<^sub>e\<^sub>t(a))->any\<^sub>S\<^sub>e\<^sub>t() = a" + apply(rule ext, rename_tac \, simp add: mtSet_def OclANY_def) + apply(case_tac "\ \ \ a") + apply(simp add: OclValid_def mtSet_defined[simplified mtSet_def] + mtSet_valid[simplified mtSet_def] mtSet_rep_set[simplified mtSet_def]) + apply(subst (1 2) cp_OclAnd, + subst (1 2) OclNotEmpty_including[where X = "Set{}", simplified mtSet_def]) + apply(simp add: mtSet_defined[simplified mtSet_def]) + apply(metis (hide_lams, no_types) finite.emptyI mtSet_def mtSet_rep_set) + apply(simp add: OclValid_def) + apply(simp add: OclIncluding_def) + apply(rule conjI) + apply(subst (1 2) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp add: bot_option_def null_option_def) + apply(simp, metis OclValid_def foundation18') + apply(simp) + apply(simp add: mtSet_defined[simplified mtSet_def]) + (* *) + apply(subgoal_tac "a \ = \") + prefer 2 + apply(simp add: OclValid_def valid_def bot_fun_def split: split_if_asm) + apply(simp) + apply(subst (1 2 3 4) cp_OclAnd, + simp add: mtSet_defined[simplified mtSet_def] valid_def bot_fun_def) +by(simp add: cp_OclAnd[symmetric], rule impI, simp add: false_def true_def) + +subsubsection{* Execution Rules on Forall *} + +lemma OclForall_mtSet_exec[simp,code_unfold] :"((Set{})->forAll\<^sub>S\<^sub>e\<^sub>t(z| P(z))) = true" +apply(simp add: OclForall_def) +apply(subst mtSet_def)+ +apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp_all add: true_def)+ +done + + +text{* The following rule is a main theorem of our approach: From a denotational definition +that assures consistency, but may be --- as in the case of the @{term "X->forAll\<^sub>S\<^sub>e\<^sub>t(x | P x)"} --- +dauntingly complex, we derive operational rules that can serve as a gold-standard for operational +execution, since they may be evaluated in whatever situation and according to whatever strategy. +In the case of @{term "X->forAll\<^sub>S\<^sub>e\<^sub>t(x | P x)"}, the operational rule gives immediately a way to +evaluation in any finite (in terms of conventional OCL: denotable) set, although the rule also +holds for the infinite case: + +@{term "Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l ->forAll\<^sub>S\<^sub>e\<^sub>t(x | (Integer\<^sub>n\<^sub>u\<^sub>l\<^sub>l ->forAll\<^sub>S\<^sub>e\<^sub>t(y | x +\<^sub>i\<^sub>n\<^sub>t y \ y +\<^sub>i\<^sub>n\<^sub>t x)))"} + +or even: + +@{term "Integer ->forAll\<^sub>S\<^sub>e\<^sub>t(x | (Integer ->forAll\<^sub>S\<^sub>e\<^sub>t(y | x +\<^sub>i\<^sub>n\<^sub>t y \ y +\<^sub>i\<^sub>n\<^sub>t x)))"} + +are valid OCL statements in any context $\tau$. +*} + +theorem OclForall_including_exec[simp,code_unfold] : + assumes cp0 : "cp P" + shows "((S->including\<^sub>S\<^sub>e\<^sub>t(x))->forAll\<^sub>S\<^sub>e\<^sub>t(z | P(z))) = (if \ S and \ x + then P x and (S->forAll\<^sub>S\<^sub>e\<^sub>t(z | P(z))) + else invalid + endif)" +proof - + have cp: "\\. P x \ = P (\_. x \) \" by(insert cp0, auto simp: cp_def) + + have cp_eq : "\\ v. (P x \ = v) = (P (\_. x \) \ = v)" by(subst cp, simp) + + have cp_OclNot_eq : "\\ v. (P x \ \ v) = (P (\_. x \) \ \ v)" by(subst cp, simp) + + have insert_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e : "\\. (\ \(\ S)) \ (\ \(\ x)) \ + \\insert (x \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ + {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(frule Set_inv_lemma, simp add: foundation18 invalid_def) + + have forall_including_invert : "\\ f. (f x \ = f (\ _. x \) \) \ + \ \ (\ S and \ x) \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\. f (\_. x) \) = + (f x \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. f (\_. x) \))" + apply(drule foundation5, simp add: OclIncluding_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) + apply(rule insert_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e, fast+) + by(simp add: OclValid_def) + + have exists_including_invert : "\\ f. (f x \ = f (\ _. x \) \) \ + \ \ (\ S and \ x) \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\. f (\_. x) \) = + (f x \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. f (\_. x) \))" + apply(subst arg_cong[where f = "\x. \x", + OF forall_including_invert[where f = "\x \. \ (f x \)"], + simplified]) + by simp_all + + have contradict_Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e: "\\ S f. \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\. f (\_. x) \ \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\. \ (f (\_. x) \)) = False" + by(case_tac "(\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\\. \ (f (\_. x) \)) = True", simp_all) + + have bot_invalid : "\ = invalid" by(rule ext, simp add: invalid_def bot_fun_def) + + have bot_invalid2 : "\\. \ = invalid \" by(simp add: invalid_def) + + have C1 : "\\. P x \ = false \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P (\_. x) \ = false \) \ + \ \ (\ S and \ x) \ + false \ = (P x and OclForall S P) \" + apply(simp add: cp_OclAnd[of "P x"]) + apply(elim disjE, simp) + apply(simp only: cp_OclAnd[symmetric], simp) + apply(subgoal_tac "OclForall S P \ = false \") + apply(simp only: cp_OclAnd[symmetric], simp) + apply(simp add: OclForall_def) + apply(fold OclValid_def, simp add: foundation10') + done + + have C2 : "\\. \ \ (\ S and \ x) \ + P x \ = null \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P (\_. x) \ = null \) \ + P x \ = invalid \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P (\_. x) \ = invalid \) \ + \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\. P (\_. x) \ \ false \ \ + invalid \ = (P x and OclForall S P) \" + apply(subgoal_tac "(\ S)\ = true \") + prefer 2 apply(simp add: foundation10', simp add: OclValid_def) + apply(drule forall_including_invert[of "\ x \. P x \ \ false \", OF cp_OclNot_eq, THEN iffD1]) + apply(assumption) + apply(simp add: cp_OclAnd[of "P x"],elim disjE, simp_all) + apply(simp add: invalid_def null_fun_def null_option_def bot_fun_def bot_option_def) + apply(subgoal_tac "OclForall S P \ = invalid \") + apply(simp only:cp_OclAnd[symmetric],simp,simp add:invalid_def bot_fun_def) + apply(unfold OclForall_def, simp add: invalid_def false_def bot_fun_def,simp) + apply(simp add:cp_OclAnd[symmetric],simp) + apply(erule conjE) + apply(subgoal_tac "(P x \ = invalid \) \ (P x \ = null \) \ (P x \ = true \) \ (P x \ = false \)") + prefer 2 apply(rule bool_split_0) + apply(elim disjE, simp_all) + apply(simp only:cp_OclAnd[symmetric],simp)+ + done + + have A : "\\. \ \ (\ S and \ x) \ + OclForall (S->including\<^sub>S\<^sub>e\<^sub>t(x)) P \ = (P x and OclForall S P) \" + proof - fix \ + assume 0 : "\ \ (\ S and \ x)" + let ?S = "\ocl. P x \ \ ocl \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P (\_. x) \ \ ocl \)" + let ?S' = "\ocl. \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\. P (\_. x) \ \ ocl \" + let ?assms_1 = "?S' null" + let ?assms_2 = "?S' invalid" + let ?assms_3 = "?S' false" + have 4 : "?assms_3 \ ?S false" + apply(subst forall_including_invert[of "\ x \. P x \ \ false \",symmetric]) + by(simp_all add: cp_OclNot_eq 0) + have 5 : "?assms_2 \ ?S invalid" + apply(subst forall_including_invert[of "\ x \. P x \ \ invalid \",symmetric]) + by(simp_all add: cp_OclNot_eq 0) + have 6 : "?assms_1 \ ?S null" + apply(subst forall_including_invert[of "\ x \. P x \ \ null \",symmetric]) + by(simp_all add: cp_OclNot_eq 0) + have 7 : "(\ S) \ = true \" + by(insert 0, simp add: foundation10', simp add: OclValid_def) + show "?thesis \" + apply(subst OclForall_def) + apply(simp add: cp_OclAnd[THEN sym] OclValid_def contradict_Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) + apply(intro conjI impI,fold OclValid_def) + apply(simp_all add: exists_including_invert[where f = "\ x \. P x \ = null \", OF cp_eq]) + apply(simp_all add: exists_including_invert[where f = "\ x \. P x \ = invalid \", OF cp_eq]) + apply(simp_all add: exists_including_invert[where f = "\ x \. P x \ = false \", OF cp_eq]) + proof - + assume 1 : "P x \ = null \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P (\_. x) \ = null \)" + and 2 : ?assms_2 + and 3 : ?assms_3 + show "null \ = (P x and OclForall S P) \" + proof - + note 4 = 4[OF 3] + note 5 = 5[OF 2] + have 6 : "P x \ = null \ \ P x \ = true \" + by(metis 4 5 bool_split_0) + show ?thesis + apply(insert 6, elim disjE) + apply(subst cp_OclAnd) + apply(simp add: OclForall_def 7 4[THEN conjunct2] 5[THEN conjunct2]) + apply(simp_all add:cp_OclAnd[symmetric]) + apply(subst cp_OclAnd, simp_all add:cp_OclAnd[symmetric] OclForall_def) + apply(simp add:4[THEN conjunct2] 5[THEN conjunct2] 0[simplified OclValid_def] 7) + apply(insert 1, elim disjE, auto) + done + qed + next + assume 1 : ?assms_1 + and 2 : "P x \ = invalid \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\. P (\_. x) \ = invalid \)" + and 3 : ?assms_3 + show "invalid \ = (P x and OclForall S P) \" + proof - + note 4 = 4[OF 3] + note 6 = 6[OF 1] + have 5 : "P x \ = invalid \ \ P x \ = true \" + by(metis 4 6 bool_split_0) + show ?thesis + apply(insert 5, elim disjE) + apply(subst cp_OclAnd) + apply(simp add: OclForall_def 4[THEN conjunct2] 6[THEN conjunct2] 7) + apply(simp_all add:cp_OclAnd[symmetric]) + apply(subst cp_OclAnd, simp_all add:cp_OclAnd[symmetric] OclForall_def) + apply(insert 2, elim disjE, simp add: invalid_def true_def bot_option_def) + apply(simp add: 0[simplified OclValid_def] 4[THEN conjunct2] 6[THEN conjunct2] 7) + by(auto) + qed + next + assume 1 : ?assms_1 + and 2 : ?assms_2 + and 3 : ?assms_3 + show "true \ = (P x and OclForall S P) \" + proof - + note 4 = 4[OF 3] + note 5 = 5[OF 2] + note 6 = 6[OF 1] + have 8 : "P x \ = true \" + by(metis 4 5 6 bool_split_0) + show ?thesis + apply(subst cp_OclAnd, simp add: 8 cp_OclAnd[symmetric]) + by(simp add: OclForall_def 4 5 6 7) + qed + qed ( simp add: 0 + | rule C1, simp+ + | rule C2, simp add: 0 )+ + qed + + have B : "\\. \ (\ \ (\ S and \ x)) \ + OclForall (S->including\<^sub>S\<^sub>e\<^sub>t(x)) P \ = invalid \" + apply(rule foundation22[THEN iffD1]) + apply(simp only: foundation10' de_Morgan_conj foundation18'', elim disjE) + apply(simp add: defined_split, elim disjE) + apply(erule StrongEq_L_subst2_rev, simp+)+ + done + + show ?thesis + apply(rule ext, rename_tac \) + apply(simp add: OclIf_def) + apply(simp add: cp_defined[of "\ S and \ x"] cp_defined[THEN sym]) + apply(intro conjI impI) + by(auto intro!: A B simp: OclValid_def) +qed + + + + +subsubsection{* Execution Rules on Exists *} + +lemma OclExists_mtSet_exec[simp,code_unfold] : +"((Set{})->exists\<^sub>S\<^sub>e\<^sub>t(z | P(z))) = false" +by(simp add: OclExists_def) + +lemma OclExists_including_exec[simp,code_unfold] : + assumes cp: "cp P" + shows "((S->including\<^sub>S\<^sub>e\<^sub>t(x))->exists\<^sub>S\<^sub>e\<^sub>t(z | P(z))) = (if \ S and \ x + then P x or (S->exists\<^sub>S\<^sub>e\<^sub>t(z | P(z))) + else invalid + endif)" + by(simp add: OclExists_def OclOr_def cp OclNot_inject) + + +subsubsection{* Execution Rules on Iterate *} + +lemma OclIterate_empty[simp,code_unfold]: "((Set{})->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = A | P a x)) = A" +proof - + have C : "\ \. (\ (\\. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\{}\\)) \ = true \" + by (metis (no_types) defined_def mtSet_def mtSet_defined null_fun_def) + show ?thesis + apply(simp add: OclIterate_def mtSet_def Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse valid_def C) + apply(rule ext, rename_tac \) + apply(case_tac "A \ = \ \", simp_all, simp add:true_def false_def bot_fun_def) + apply(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) + done +qed + +text{* In particular, this does hold for A = null. *} + +lemma OclIterate_including: +assumes S_finite: "\ \ \(S->size\<^sub>S\<^sub>e\<^sub>t())" +and F_valid_arg: "(\ A) \ = (\ (F a A)) \" +and F_commute: "comp_fun_commute F" +and F_cp: "\ x y \. F x y \ = F (\ _. x \) y \" +shows "((S->including\<^sub>S\<^sub>e\<^sub>t(a))->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = A | F a x)) \ = + ((S->excluding\<^sub>S\<^sub>e\<^sub>t(a))->iterate\<^sub>S\<^sub>e\<^sub>t(a; x = F a A | F a x)) \" +proof - + have insert_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e : "\\. (\ \(\ S)) \ (\ \(\ a)) \ + \\insert (a \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(frule Set_inv_lemma, simp add: foundation18 invalid_def) + + have insert_defined : "\\. (\ \(\ S)) \ (\ \(\ a)) \ + (\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\insert (a \) \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\\\)) \ = true \" + apply(subst defined_def) + apply(simp add: bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def) + by(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, + rule insert_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp_all add: null_option_def bot_option_def)+ + + have remove_finite : "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ \ + finite ((\a \. a) ` (\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {a \}))" + by(simp) + + have remove_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e : "\\. (\ \(\ S)) \ (\ \(\ a)) \ + \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {a \}\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)}" + by(frule Set_inv_lemma, simp add: foundation18 invalid_def) + + have remove_defined : "\\. (\ \(\ S)) \ (\ \(\ a)) \ + (\ (\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {a \}\\)) \ = true \" + apply(subst defined_def) + apply(simp add: bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def) + by(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject, + rule remove_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e, simp_all add: null_option_def bot_option_def)+ + + have abs_rep: "\x. \\x\\ \ {X. X = bot \ X = null \ (\x\\\X\\. x \ bot)} \ + \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\x\\)\\ = x" + by(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp_all) + + have inject : "inj (\a \. a)" + by(rule inj_fun, simp) + + show ?thesis + apply(subst (1 2) cp_OclIterate, subst OclIncluding_def, subst OclExcluding_def) + apply(case_tac "\ ((\ S) \ = true \ \ (\ a) \ = true \)", simp add: invalid_def) + + apply(subgoal_tac "OclIterate (\_. \) A F \ = OclIterate (\_. \) (F a A) F \", simp) + apply(rule conjI, blast+) + apply(simp add: OclIterate_def defined_def bot_option_def bot_fun_def false_def true_def) + + apply(simp add: OclIterate_def) + apply((subst abs_rep[OF insert_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e[simplified OclValid_def], of \], simp_all)+, + (subst abs_rep[OF remove_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e[simplified OclValid_def], of \], simp_all)+, + (subst insert_defined, simp_all add: OclValid_def)+, + (subst remove_defined, simp_all add: OclValid_def)+) + + apply(case_tac "\ ((\ A) \ = true \)", (simp add: F_valid_arg)+) + apply(rule impI, + subst Finite_Set.comp_fun_commute.fold_fun_left_comm[symmetric, OF F_commute], + rule remove_finite, simp) + + apply(subst image_set_diff[OF inject], simp) + apply(subgoal_tac "Finite_Set.fold F A (insert (\\'. a \) ((\a \. a) ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\)) \ = + F (\\'. a \) (Finite_Set.fold F A ((\a \. a) ` \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ - {\\'. a \})) \") + apply(subst F_cp, simp) + + by(subst Finite_Set.comp_fun_commute.fold_insert_remove[OF F_commute], simp+) +qed + +subsubsection{* Execution Rules on Select *} + +lemma OclSelect_mtSet_exec[simp,code_unfold]: "OclSelect mtSet P = mtSet" + apply(rule ext, rename_tac \) + apply(simp add: OclSelect_def mtSet_def defined_def false_def true_def + bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def) +by(( subst (1 2 3 4 5) Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse + | subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject), (simp add: null_option_def bot_option_def)+)+ + +definition "OclSelect_body :: _ \ _ \ _ \ ('\, 'a option option) Set + \ (\P x acc. if P x \ false then acc else acc->including\<^sub>S\<^sub>e\<^sub>t(x) endif)" + +theorem OclSelect_including_exec[simp,code_unfold]: + assumes P_cp : "cp P" + shows "OclSelect (X->including\<^sub>S\<^sub>e\<^sub>t(y)) P = OclSelect_body P y (OclSelect (X->excluding\<^sub>S\<^sub>e\<^sub>t(y)) P)" + (is "_ = ?select") +proof - + have P_cp: "\x \. P x \ = P (\_. x \) \" by(insert P_cp, auto simp: cp_def) + + have ex_including : "\f X y \. \ \ \ X \ \ \ \ y \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(y) \)\\. f (P (\_. x)) \) = + (f (P (\_. y \)) \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. f (P (\_. x)) \))" + apply(simp add: OclIncluding_def OclValid_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, (rule disjI2)+) + by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18',simp) + + have al_including : "\f X y \. \ \ \ X \ \ \ \ y \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(y) \)\\. f (P (\_. x)) \) = + (f (P (\_. y \)) \ \ (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. f (P (\_. x)) \))" + apply(simp add: OclIncluding_def OclValid_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, (rule disjI2)+) + by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18', simp) + + have ex_excluding1 : "\f X y \. \ \ \ X \ \ \ \ y \ \ (f (P (\_. y \)) \) \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. f (P (\_. x)) \) = + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->excluding\<^sub>S\<^sub>e\<^sub>t(y) \)\\. f (P (\_. x)) \)" + apply(simp add: OclExcluding_def OclValid_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, (rule disjI2)+) + by (metis (no_types) Diff_iff OclValid_def Set_inv_lemma) auto + + have al_excluding1 : "\f X y \. \ \ \ X \ \ \ \ y \ f (P (\_. y \)) \ \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. f (P (\_. x)) \) = + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->excluding\<^sub>S\<^sub>e\<^sub>t(y) \)\\. f (P (\_. x)) \)" + apply(simp add: OclExcluding_def OclValid_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, (rule disjI2)+) + by (metis (no_types) Diff_iff OclValid_def Set_inv_lemma) auto + + have in_including : "\f X y \. \ \ \ X \ \ \ \ y \ + {x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(y) \)\\. f (P (\_. x) \)} = + (let s = {x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. f (P (\_. x) \)} in + if f (P (\_. y \) \) then insert (y \) s else s)" + apply(simp add: OclIncluding_def OclValid_def) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse, simp, (rule disjI2)+) + apply (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') + by(simp add: Let_def, auto) + + let ?OclSet = "\S. \\S\\ \ {X. X = \ \ X = null \ (\x\\\X\\. x \ \)}" + + have diff_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e : "\\. (\ X) \ = true \ \ ?OclSet (\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ - {y \})" + apply(simp, (rule disjI2)+) + by (metis (mono_tags) Diff_iff OclValid_def Set_inv_lemma) + + have ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e : "\\. (\ X) \ = true \ \ (\ y) \ = true \ \ + ?OclSet (insert (y \) {x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ \ false \})" + apply(simp, (rule disjI2)+) + by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') + + have ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e' : "\\. (\ X) \ = true \ \ (\ y) \ = true \ \ + ?OclSet (insert (y \) {x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. x \ y \ \ P (\_. x) \ \ false \})" + apply(simp, (rule disjI2)+) + by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma foundation18') + + have ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e'' : "\\. (\ X) \ = true \ \ + ?OclSet {x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ \ false \}" + apply(simp, (rule disjI2)+) + by (metis (hide_lams, no_types) OclValid_def Set_inv_lemma) + + have ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e''' : "\\. (\ X) \ = true \ \ + ?OclSet {x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. x \ y \ \ P (\_. x) \ \ false \}" + apply(simp, (rule disjI2)+) + by(metis (hide_lams, no_types) OclValid_def Set_inv_lemma) + + have if_same : "\a b c d \. \ \ \ a \ b \ = d \ \ c \ = d \ \ + (if a then b else c endif) \ = d \" + by(simp add: OclIf_def OclValid_def) + + have invert_including : "\P y \. P \ = \ \ P->including\<^sub>S\<^sub>e\<^sub>t(y) \ = \" + by (metis (hide_lams, no_types) foundation16[THEN iffD1] + foundation18' OclIncluding_valid_args_valid) + + have exclude_defined : "\\. \ \ \ X \ + (\(\_. Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \\{x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. x \ y \ \ P (\_. x) \\false \}\\)) \ = true \" + apply(subst defined_def, + simp add: false_def true_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_fun_def) + by(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e'''[simplified false_def]], + (simp add: OclValid_def bot_option_def null_option_def)+)+ + + have if_eq : "\x A B \. \ \ \ x \ \ \ ((if x \ false then A else B endif) \ + (if x \ false then A else B endif))" + apply(simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclValid_def) + apply(subst (2) StrongEq_def) + by(subst cp_OclIf, simp add: cp_OclIf[symmetric] true_def) + + have OclSelect_body_bot: "\\. \ \ \ X \ \ \ \ y \ P y \ \ \ \ + (\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ = \) \ \ = ?select \" + apply(drule ex_excluding1[where X2 = X and y2 = y and f2 = "\x \. x \ = \"], + (simp add: P_cp[symmetric])+) + apply(subgoal_tac "\ \ (\ \ ?select)", simp add: OclValid_def StrongEq_def true_def bot_fun_def) + apply(simp add: OclSelect_body_def) + apply(subst StrongEq_L_subst3[OF _ if_eq], simp, metis foundation18') + apply(simp add: OclValid_def, subst StrongEq_def, subst true_def, simp) + apply(subgoal_tac "\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->excluding\<^sub>S\<^sub>e\<^sub>t(y) \)\\. P (\_. x) \ = \ \") + prefer 2 apply (metis bot_fun_def ) + apply(subst if_same[where d5 = "\"]) + apply (metis defined7 transform1) + apply(simp add: OclSelect_def bot_option_def bot_fun_def invalid_def) + apply(subst invert_including) + by(simp add: OclSelect_def bot_option_def bot_fun_def invalid_def)+ + + + have d_and_v_inject : "\\ X y. (\ X and \ y) \ \ true \ \ (\ X and \ y) \ = false \" + apply(fold OclValid_def, subst foundation22[symmetric]) + apply(auto simp:foundation10' defined_split) + apply(erule StrongEq_L_subst2_rev,simp,simp) + apply(erule StrongEq_L_subst2_rev,simp,simp) + by(erule foundation7'[THEN iffD2, THEN foundation15[THEN iffD2, + THEN StrongEq_L_subst2_rev]],simp,simp) + + + + + have OclSelect_body_bot': "\\. (\ X and \ y) \ \ true \ \ \ = ?select \" + apply(drule d_and_v_inject) + apply(simp add: OclSelect_def OclSelect_body_def) + apply(subst cp_OclIf, subst OclIncluding.cp0, simp add: false_def true_def) + apply(subst cp_OclIf[symmetric], subst OclIncluding.cp0[symmetric]) + by (metis (lifting, no_types) OclIf_def foundation18 foundation18' invert_including) + + have conj_split2 : "\a b c \. ((a \ false) \ = false \ \ b) \ ((a \ false) \ = true \ \ c) \ + (a \ \ false \ \ b) \ (a \ = false \ \ c)" + by (metis OclValid_def defined7 foundation14 foundation22 foundation9) + + have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) + + have cp_OclSelect_body : "\\. ?select \ = OclSelect_body P y (\_.(OclSelect (X->excluding\<^sub>S\<^sub>e\<^sub>t(y))P)\)\" + apply(simp add: OclSelect_body_def) + by(subst (1 2) cp_OclIf, subst (1 2) OclIncluding.cp0, blast) + + have OclSelect_body_strict1 : "OclSelect_body P y invalid = invalid" + by(rule ext, simp add: OclSelect_body_def OclIf_def) + + have bool_invalid: "\(x::('\)Boolean) y \. \ (\ \ \ x) \ \ \ ((x \ y) \ invalid)" + by(simp add: StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n OclValid_def StrongEq_def true_def) + + have conj_comm : "\p q r. (p \ q \ r) = ((p \ q) \ r)" by blast + + have inv_bot : "\\. invalid \ = \ \" by (metis bot_fun_def invalid_def) + have inv_bot' : "\\. invalid \ = \" by (simp add: invalid_def) + + show ?thesis + apply(rule ext, rename_tac \) + apply(subst OclSelect_def) + apply(case_tac "(\ (X->including\<^sub>S\<^sub>e\<^sub>t(y))) \ = true \", simp) + apply(( subst ex_including | subst in_including), + metis OclValid_def foundation5, + metis OclValid_def foundation5)+ + apply(simp add: Let_def inv_bot) + apply(subst (2 4 7 9) bot_fun_def) + + apply(subst (4) false_def, subst (4) bot_fun_def, simp add: bot_option_def P_cp[symmetric]) + (* *) + apply(case_tac "\ (\ \ (\ P y))") + apply(subgoal_tac "P y \ \ false \") + prefer 2 + apply (metis (hide_lams, no_types) foundation1 foundation18' valid4) + apply(simp) + (* *) + apply(subst conj_comm, rule conjI) + apply(drule_tac y11 = false in bool_invalid) + apply(simp only: OclSelect_body_def, + metis OclIf_def OclValid_def defined_def foundation2 foundation22 + bot_fun_def invalid_def) + (* *) + apply(drule foundation5[simplified OclValid_def], + subst al_including[simplified OclValid_def], + simp, + simp) + apply(simp add: P_cp[symmetric]) + apply (metis bot_fun_def foundation18') + + apply(simp add: foundation18' bot_fun_def OclSelect_body_bot OclSelect_body_bot') + (* *) + apply(subst (1 2) al_including, metis OclValid_def foundation5, metis OclValid_def foundation5) + apply(simp add: P_cp[symmetric], subst (4) false_def, subst (4) bot_option_def, simp) + + apply(simp add: OclSelect_def[simplified inv_bot'] OclSelect_body_def StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n) + apply(subst (1 2 3 4) cp_OclIf, + subst (1 2 3 4) foundation18'[THEN iffD2, simplified OclValid_def], + simp, + simp only: cp_OclIf[symmetric] refl if_True) + apply(subst (1 2) OclIncluding.cp0, rule conj_split2, simp add: cp_OclIf[symmetric]) + apply(subst (1 2 3 4 5 6 7 8) cp_OclIf[symmetric], simp) + apply(( subst ex_excluding1[symmetric] + | subst al_excluding1[symmetric] ), + metis OclValid_def foundation5, + metis OclValid_def foundation5, + simp add: P_cp[symmetric] bot_fun_def)+ + apply(simp add: bot_fun_def) + apply(subst (1 2) invert_including, simp+) + (* *) + apply(rule conjI, blast) + apply(intro impI conjI) + apply(subst OclExcluding_def) + apply(drule foundation5[simplified OclValid_def], simp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF diff_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e], fast) + apply(simp add: OclIncluding_def cp_valid[symmetric]) + apply((erule conjE)+, frule exclude_defined[simplified OclValid_def], simp) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e'''], simp+) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e'], fast+) + (* *) + apply(simp add: OclExcluding_def) + apply(simp add: foundation10[simplified OclValid_def]) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse[OF diff_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e], simp+) + apply(subst Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject[OF ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e'' ins_in_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e'''], simp+) + apply(subgoal_tac "P (\_. y \) \ = false \") + prefer 2 + apply(subst P_cp[symmetric], metis OclValid_def foundation22) + apply(rule equalityI) + apply(rule subsetI, simp, metis) + apply(rule subsetI, simp) + (* *) + apply(drule defined_inject_true) + apply(subgoal_tac "\ (\ \ \ X) \ \ (\ \ \ y)") + prefer 2 + apply (metis OclIncluding.def_homo OclIncluding_valid_args_valid OclIncluding_valid_args_valid'' OclValid_def foundation18 valid1) + apply(subst cp_OclSelect_body, subst cp_OclSelect, subst OclExcluding_def) + apply(simp add: OclValid_def false_def true_def, rule conjI, blast) + apply(simp add: OclSelect_invalid[simplified invalid_def] + OclSelect_body_strict1[simplified invalid_def] + inv_bot') + done +qed + +subsubsection{* Execution Rules on Reject *} + +lemma OclReject_mtSet_exec[simp,code_unfold]: "OclReject mtSet P = mtSet" +by(simp add: OclReject_def) + +lemma OclReject_including_exec[simp,code_unfold]: + assumes P_cp : "cp P" + shows "OclReject (X->including\<^sub>S\<^sub>e\<^sub>t(y)) P = OclSelect_body (not o P) y (OclReject (X->excluding\<^sub>S\<^sub>e\<^sub>t(y)) P)" + apply(simp add: OclReject_def comp_def, rule OclSelect_including_exec) +by (metis assms cp_intro'(5)) + +subsubsection{* Execution Rules Combining Previous Operators *} + +text{* OclIncluding *} + +(* logical level : *) +lemma OclIncluding_idem0 : + assumes "\ \ \ S" + and "\ \ \ i" + shows "\ \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(i) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)))" +by(simp add: OclIncluding_includes OclIncludes_charn1 assms) + +(* Pure algebraic level *) +theorem OclIncluding_idem[simp,code_unfold]: "((S :: ('\,'a::null)Set)->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(i) = (S->including\<^sub>S\<^sub>e\<^sub>t(i)))" +proof - + have A: "\ \. \ \ (i \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A':"\ \. \ \ (i \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C: "\ \. \ \ (S \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C': "\ \. \ \ (S \ invalid) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D: "\ \. \ \ (S \ null) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D': "\ \. \ \ (S \ null) \ (S->including\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "\ \ (\ i)") + apply(case_tac "\ \ (\ S)") + apply(simp only: OclIncluding_idem0[THEN foundation22[THEN iffD1]]) + apply(simp add: foundation16', elim disjE) + apply(simp add: C[OF foundation22[THEN iffD2]] C'[OF foundation22[THEN iffD2]]) + apply(simp add: D[OF foundation22[THEN iffD2]] D'[OF foundation22[THEN iffD2]]) + apply(simp add:foundation18 A[OF foundation22[THEN iffD2]] A'[OF foundation22[THEN iffD2]]) + done +qed + +text{* OclExcluding *} + +(* logical level : *) +lemma OclExcluding_idem0 : + assumes "\ \ \ S" + and "\ \ \ i" + shows "\ \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(i) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)))" +by(simp add: OclExcluding_excludes OclExcludes_charn1 assms) + +(* Pure algebraic level *) +theorem OclExcluding_idem[simp,code_unfold]: "((S->excluding\<^sub>S\<^sub>e\<^sub>t(i))->excluding\<^sub>S\<^sub>e\<^sub>t(i)) = (S->excluding\<^sub>S\<^sub>e\<^sub>t(i))" +proof - + have A: "\ \. \ \ (i \ invalid) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have A':"\ \. \ \ (i \ invalid) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C: "\ \. \ \ (S \ invalid) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have C': "\ \. \ \ (S \ invalid) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D: "\ \. \ \ (S \ null) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + have D': "\ \. \ \ (S \ null) \ (S->excluding\<^sub>S\<^sub>e\<^sub>t(i)) \ = invalid \" + apply(rule foundation22[THEN iffD1]) + by(erule StrongEq_L_subst2_rev, simp,simp) + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "\ \ (\ i)") + apply(case_tac "\ \ (\ S)") + apply(simp only: OclExcluding_idem0[THEN foundation22[THEN iffD1]]) + apply(simp add: foundation16', elim disjE) + apply(simp add: C[OF foundation22[THEN iffD2]] C'[OF foundation22[THEN iffD2]]) + apply(simp add: D[OF foundation22[THEN iffD2]] D'[OF foundation22[THEN iffD2]]) + apply(simp add:foundation18 A[OF foundation22[THEN iffD2]] A'[OF foundation22[THEN iffD2]]) + done +qed + +text{* OclIncludes *} + + +lemma OclIncludes_any[simp,code_unfold]: + "X->includes\<^sub>S\<^sub>e\<^sub>t(X->any\<^sub>S\<^sub>e\<^sub>t()) = (if \ X then + if \ (X->size\<^sub>S\<^sub>e\<^sub>t()) then not(X->isEmpty\<^sub>S\<^sub>e\<^sub>t()) + else X->includes\<^sub>S\<^sub>e\<^sub>t(null) endif + else invalid endif)" +proof - + have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) + + have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac "P \ = \", simp_all add: true_def) + + + + have notempty': "\\ X. \ \ \ X \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ not (X->isEmpty\<^sub>S\<^sub>e\<^sub>t()) \ \ true \ \ + X \ = Set{} \" + apply(case_tac "X \", rename_tac X', simp add: mtSet_def Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) + apply(erule disjE, metis (hide_lams, mono_tags) bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_option_def foundation16) + apply(erule disjE, metis (hide_lams, no_types) bot_option_def + null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def null_option_def foundation16[THEN iffD1]) + apply(case_tac X', simp, metis (hide_lams, no_types) bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def foundation16[THEN iffD1]) + apply(rename_tac X'', case_tac X'', simp) + apply (metis (hide_lams, no_types) foundation16[THEN iffD1] null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + apply(simp add: OclIsEmpty_def OclSize_def) + apply(subst (asm) cp_OclNot, subst (asm) cp_OclOr, subst (asm) StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0, + subst (asm) cp_OclAnd, subst (asm) cp_OclNot) + apply(simp only: OclValid_def foundation20[simplified OclValid_def] + cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) + apply(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse split: split_if_asm) + by(simp add: true_def OclInt0_def OclNot_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r StrongEq_def) + + have B: "\X \. \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ (\ (X->size\<^sub>S\<^sub>e\<^sub>t())) \ = false \" + apply(subst cp_defined) + apply(simp add: OclSize_def) + by (metis bot_fun_def defined_def) + + show ?thesis + apply(rule ext, rename_tac \, simp only: OclIncludes_def OclANY_def) + apply(subst cp_OclIf, subst (2) cp_valid) + apply(case_tac "(\ X) \ = true \", + simp only: foundation20[simplified OclValid_def] cp_OclIf[symmetric], simp, + subst (1 2) cp_OclAnd, simp add: cp_OclAnd[symmetric]) + apply(case_tac "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\") + apply(frule size_defined'[THEN iffD2, simplified OclValid_def], assumption) + apply(subst (1 2 3 4) cp_OclIf, simp) + apply(subst (1 2 3 4) cp_OclIf[symmetric], simp) + apply(case_tac "(X->notEmpty\<^sub>S\<^sub>e\<^sub>t()) \ = true \", simp) + apply(frule OclNotEmpty_has_elt[simplified OclValid_def], simp) + apply(simp add: OclNotEmpty_def cp_OclIf[symmetric]) + apply(subgoal_tac "(SOME y. y \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\) \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\", simp add: true_def) + apply(metis OclValid_def Set_inv_lemma foundation18' null_option_def true_def) + apply(rule someI_ex, simp) + apply(simp add: OclNotEmpty_def cp_valid[symmetric]) + apply(subgoal_tac "\ (null \ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\)", simp) + apply(subst OclIsEmpty_def, simp add: OclSize_def) + apply(subst cp_OclNot, subst cp_OclOr, subst StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0, subst cp_OclAnd, + subst cp_OclNot, simp add: OclValid_def foundation20[simplified OclValid_def] + cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) + apply(frule notempty'[simplified OclValid_def], + (simp add: mtSet_def Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse OclInt0_def false_def)+) + apply(drule notempty'[simplified OclValid_def], simp, simp) + apply (metis (hide_lams, no_types) empty_iff mtSet_rep_set) + (* *) + apply(frule B) + apply(subst (1 2 3 4) cp_OclIf, simp) + apply(subst (1 2 3 4) cp_OclIf[symmetric], simp) + apply(case_tac "(X->notEmpty\<^sub>S\<^sub>e\<^sub>t()) \ = true \", simp) + apply(frule OclNotEmpty_has_elt[simplified OclValid_def], simp) + apply(simp add: OclNotEmpty_def OclIsEmpty_def) + apply(subgoal_tac "X->size\<^sub>S\<^sub>e\<^sub>t() \ = \") + prefer 2 + apply (metis (hide_lams, no_types) OclSize_def) + apply(subst (asm) cp_OclNot, subst (asm) cp_OclOr, subst (asm) StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r.cp0, + subst (asm) cp_OclAnd, subst (asm) cp_OclNot) + apply(simp add: OclValid_def foundation20[simplified OclValid_def] + cp_OclNot[symmetric] cp_OclAnd[symmetric] cp_OclOr[symmetric]) + apply(simp add: OclNot_def StrongEq_def StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r valid_def false_def true_def + bot_option_def bot_fun_def invalid_def) + + apply (metis bot_fun_def null_fun_def null_is_valid valid_def) + by(drule defined_inject_true, + simp add: false_def true_def OclIf_false[simplified false_def] invalid_def) +qed + +text{* OclSize *} + +lemma [simp,code_unfold]: "\ (Set{} ->size\<^sub>S\<^sub>e\<^sub>t()) = true" +by simp + + +lemma [simp,code_unfold]: "\ ((X ->including\<^sub>S\<^sub>e\<^sub>t(x)) ->size\<^sub>S\<^sub>e\<^sub>t()) = (\(X->size\<^sub>S\<^sub>e\<^sub>t()) and \(x))" +proof - + have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) + + have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac "P \ = \", simp_all add: true_def) + + have OclIncluding_finite_rep_set : "\\. (\ X and \ x) \ = true \ \ + finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\ = finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + apply(rule OclIncluding_finite_rep_set) + by(metis OclValid_def foundation5)+ + + have card_including_exec : "\\. (\ (\_. \\int (card \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\)\\)) \ = + (\ (\_. \\int (card \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\)\\)) \" + by(simp add: defined_def bot_fun_def bot_option_def null_fun_def null_option_def) + + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "(\ (X->including\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t())) \ = true \", simp del: OclSize_including_exec) + apply(subst cp_OclAnd, subst cp_defined, simp only: cp_defined[of "X->including\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t()"], + simp add: OclSize_def) + apply(case_tac "((\ X and \ x) \ = true \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->including\<^sub>S\<^sub>e\<^sub>t(x) \)\\)", simp) + apply(erule conjE, + simp add: OclIncluding_finite_rep_set[simplified OclValid_def] card_including_exec + cp_OclAnd[of "\ X" "\ x"] + cp_OclAnd[of "true", THEN sym]) + apply(subgoal_tac "(\ X) \ = true \ \ (\ x) \ = true \", simp) + apply(rule foundation5[of _ "\ X" "\ x", simplified OclValid_def], + simp only: cp_OclAnd[THEN sym]) + apply(simp, simp add: defined_def true_def false_def bot_fun_def bot_option_def) + + apply(drule defined_inject_true[of "X->including\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t()"], + simp del: OclSize_including_exec, + simp only: cp_OclAnd[of "\ (X->size\<^sub>S\<^sub>e\<^sub>t())" "\ x"], + simp add: cp_defined[of "X->including\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t()" ] cp_defined[of "X->size\<^sub>S\<^sub>e\<^sub>t()" ] + del: OclSize_including_exec, + simp add: OclSize_def card_including_exec + del: OclSize_including_exec) + apply(case_tac "(\ X and \ x) \ = true \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\", + simp add: OclIncluding_finite_rep_set[simplified OclValid_def] card_including_exec, + simp only: cp_OclAnd[THEN sym], + simp add: defined_def bot_fun_def) + + apply(split split_if_asm) + apply(simp add: OclIncluding_finite_rep_set[simplified OclValid_def] card_including_exec)+ + apply(simp only: cp_OclAnd[THEN sym], simp, rule impI, erule conjE) + apply(case_tac "(\ x) \ = true \", simp add: cp_OclAnd[of "\ X" "\ x"]) + by(drule valid_inject_true[of "x"], simp add: cp_OclAnd[of _ "\ x"]) +qed + +lemma [simp,code_unfold]: "\ ((X ->excluding\<^sub>S\<^sub>e\<^sub>t(x)) ->size\<^sub>S\<^sub>e\<^sub>t()) = (\(X->size\<^sub>S\<^sub>e\<^sub>t()) and \(x))" +proof - + have defined_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: defined_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac " P \ = \ \ P \ = null", simp_all add: true_def) + + have valid_inject_true : "\\ P. (\ P) \ \ true \ \ (\ P) \ = false \" + apply(simp add: valid_def true_def false_def bot_fun_def bot_option_def + null_fun_def null_option_def) + by (case_tac "P \ = \", simp_all add: true_def) + + have OclExcluding_finite_rep_set : "\\. (\ X and \ x) \ = true \ \ + finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->excluding\<^sub>S\<^sub>e\<^sub>t(x) \)\\ = + finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + apply(rule OclExcluding_finite_rep_set) + by(metis OclValid_def foundation5)+ + + have card_excluding_exec : "\\. (\ (\_. \\int (card \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->excluding\<^sub>S\<^sub>e\<^sub>t(x) \)\\)\\)) \ = + (\ (\_. \\int (card \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\)\\)) \" + by(simp add: defined_def bot_fun_def bot_option_def null_fun_def null_option_def) + + show ?thesis + apply(rule ext, rename_tac \) + apply(case_tac "(\ (X->excluding\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t())) \ = true \", simp) + apply(subst cp_OclAnd, subst cp_defined, simp only: cp_defined[of "X->excluding\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t()"], + simp add: OclSize_def) + apply(case_tac "((\ X and \ x) \ = true \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X->excluding\<^sub>S\<^sub>e\<^sub>t(x) \)\\)", simp) + apply(erule conjE, + simp add: OclExcluding_finite_rep_set[simplified OclValid_def] card_excluding_exec + cp_OclAnd[of "\ X" "\ x"] + cp_OclAnd[of "true", THEN sym]) + apply(subgoal_tac "(\ X) \ = true \ \ (\ x) \ = true \", simp) + apply(rule foundation5[of _ "\ X" "\ x", simplified OclValid_def], + simp only: cp_OclAnd[THEN sym]) + apply(simp, simp add: defined_def true_def false_def bot_fun_def bot_option_def) + + apply(drule defined_inject_true[of "X->excluding\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t()"], + simp, + simp only: cp_OclAnd[of "\ (X->size\<^sub>S\<^sub>e\<^sub>t())" "\ x"], + simp add: cp_defined[of "X->excluding\<^sub>S\<^sub>e\<^sub>t(x)->size\<^sub>S\<^sub>e\<^sub>t()" ] cp_defined[of "X->size\<^sub>S\<^sub>e\<^sub>t()" ], + simp add: OclSize_def card_excluding_exec) + apply(case_tac "(\ X and \ x) \ = true \ \ finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\", + simp add: OclExcluding_finite_rep_set[simplified OclValid_def] card_excluding_exec, + simp only: cp_OclAnd[THEN sym], + simp add: defined_def bot_fun_def) + + apply(split split_if_asm) + apply(simp add: OclExcluding_finite_rep_set[simplified OclValid_def] card_excluding_exec)+ + apply(simp only: cp_OclAnd[THEN sym], simp, rule impI, erule conjE) + apply(case_tac "(\ x) \ = true \", simp add: cp_OclAnd[of "\ X" "\ x"]) + by(drule valid_inject_true[of "x"], simp add: cp_OclAnd[of _ "\ x"]) +qed + +lemma [simp]: + assumes X_finite: "\\. finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\" + shows "\ ((X ->including\<^sub>S\<^sub>e\<^sub>t(x)) ->size\<^sub>S\<^sub>e\<^sub>t()) = (\(X) and \(x))" +by(simp add: size_defined[OF X_finite] del: OclSize_including_exec) + + +text{* OclForall *} + +lemma OclForall_rep_set_false: + assumes "\ \ \ X" + shows "(OclForall X P \ = false \) = (\x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\\. x) \ = false \)" +by(insert assms, simp add: OclForall_def OclValid_def false_def true_def invalid_def + bot_fun_def bot_option_def null_fun_def null_option_def) + +lemma OclForall_rep_set_true: + assumes "\ \ \ X" + shows "(\ \ OclForall X P) = (\x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. \ \ P (\\. x))" +proof - + have destruct_ocl : "\x \. x = true \ \ x = false \ \ x = null \ \ x = \ \" + apply(case_tac x) apply (metis bot_Boolean_def) + apply(rename_tac x', case_tac x') apply (metis null_Boolean_def) + apply(rename_tac x'', case_tac x'') apply (metis (full_types) true_def) + by (metis (full_types) false_def) + + have disjE4 : "\ P1 P2 P3 P4 R. + (P1 \ P2 \ P3 \ P4) \ (P1 \ R) \ (P2 \ R) \ (P3 \ R) \ (P4 \ R) \ R" + by metis + show ?thesis + apply(simp add: OclForall_def OclValid_def true_def false_def invalid_def + bot_fun_def bot_option_def null_fun_def null_option_def split: split_if_asm) + apply(rule conjI, rule impI) apply (metis drop.simps option.distinct(1) invalid_def) + apply(rule impI, rule conjI, rule impI) apply (metis option.distinct(1)) + apply(rule impI, rule conjI, rule impI) apply (metis drop.simps) + apply(intro conjI impI ballI) + proof - fix x show "\x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ \ \None\ \ + \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. \y. P (\_. x) \ = \y\ \ + \x\\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\. P (\_. x) \ \ \\False\\ \ + x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ P (\\. x) \ = \\True\\" + apply(erule_tac x = x in ballE)+ + by(rule disjE4[OF destruct_ocl[of "P (\\. x) \"]], + (simp add: true_def false_def null_fun_def null_option_def bot_fun_def bot_option_def)+) + qed(simp add: assms[simplified OclValid_def true_def])+ +qed + +lemma OclForall_includes : + assumes x_def : "\ \ \ x" + and y_def : "\ \ \ y" + shows "(\ \ OclForall x (OclIncludes y)) = (\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\)" + apply(simp add: OclForall_rep_set_true[OF x_def], + simp add: OclIncludes_def OclValid_def y_def[simplified OclValid_def]) + apply(insert Set_inv_lemma[OF x_def], simp add: valid_def false_def true_def bot_fun_def) +by(rule iffI, simp add: subsetI, simp add: subsetD) + +lemma OclForall_not_includes : + assumes x_def : "\ \ \ x" + and y_def : "\ \ \ y" + shows "(OclForall x (OclIncludes y) \ = false \) = (\ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\)" + apply(simp add: OclForall_rep_set_false[OF x_def], + simp add: OclIncludes_def OclValid_def y_def[simplified OclValid_def]) + apply(insert Set_inv_lemma[OF x_def], simp add: valid_def false_def true_def bot_fun_def) +by(rule iffI, metis set_rev_mp, metis subsetI) + +lemma OclForall_iterate: + assumes S_finite: "finite \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\" + shows "S->forAll\<^sub>S\<^sub>e\<^sub>t(x | P x) \ = (S->iterate\<^sub>S\<^sub>e\<^sub>t(x; acc = true | acc and P x)) \" +proof - + have and_comm : "comp_fun_commute (\x acc. acc and P x)" + apply(simp add: comp_fun_commute_def comp_def) + by (metis OclAnd_assoc OclAnd_commute) + + have ex_insert : "\x F P. (\x\insert x F. P x) = (P x \ (\x\F. P x))" + by (metis insert_iff) + + have destruct_ocl : "\x \. x = true \ \ x = false \ \ x = null \ \ x = \ \" + apply(case_tac x) apply (metis bot_Boolean_def) + apply(rename_tac x', case_tac x') apply (metis null_Boolean_def) + apply(rename_tac x'', case_tac x'') apply (metis (full_types) true_def) + by (metis (full_types) false_def) + + have disjE4 : "\ P1 P2 P3 P4 R. + (P1 \ P2 \ P3 \ P4) \ (P1 \ R) \ (P2 \ R) \ (P3 \ R) \ (P4 \ R) \ R" + by metis + + let ?P_eq = "\x b \. P (\_. x) \ = b \" + let ?P = "\set b \. \x\set. ?P_eq x b \" + let ?if = "\f b c. if f b \ then b \ else c" + let ?forall = "\P. ?if P false (?if P invalid (?if P null (true \)))" + show ?thesis + apply(simp only: OclForall_def OclIterate_def) + apply(case_tac "\ \ \ S", simp only: OclValid_def) + apply(subgoal_tac "let set = \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ in + ?forall (?P set) = + Finite_Set.fold (\x acc. acc and P x) true ((\a \. a) ` set) \", + simp only: Let_def, simp add: S_finite, simp only: Let_def) + apply(case_tac "\\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \)\\ = {}", simp) + apply(rule finite_ne_induct[OF S_finite], simp) + (* *) + apply(simp only: image_insert) + apply(subst comp_fun_commute.fold_insert[OF and_comm], simp) + apply (metis empty_iff image_empty) + apply(simp add: invalid_def) + apply (metis bot_fun_def destruct_ocl null_fun_def) + (* *) + apply(simp only: image_insert) + apply(subst comp_fun_commute.fold_insert[OF and_comm], simp) + apply (metis (mono_tags) imageE) + + (* *) + apply(subst cp_OclAnd) apply(drule sym, drule sym, simp only:, drule sym, simp only:) + apply(simp only: ex_insert) + apply(subgoal_tac "\x. x\F") prefer 2 + apply(metis all_not_in_conv) + proof - fix x F show "(\ S) \ = true \ \ \x. x \ F \ + ?forall (\b \. ?P_eq x b \ \ ?P F b \) = + ((\_. ?forall (?P F)) and (\_. P (\\. x) \)) \" + apply(rule disjE4[OF destruct_ocl[where x1 = "P (\\. x) \"]]) + apply(simp_all add: true_def false_def invalid_def OclAnd_def + null_fun_def null_option_def bot_fun_def bot_option_def) + by (metis (lifting) option.distinct(1))+ + qed(simp add: OclValid_def)+ +qed + +lemma OclForall_cong: + assumes "\x. x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ \ \ P (\\. x) \ \ \ Q (\\. x)" + assumes P: "\ \ OclForall X P" + shows "\ \ OclForall X Q" +proof - + have def_X: "\ \ \ X" + by(insert P, simp add: OclForall_def OclValid_def bot_option_def true_def split: split_if_asm) + show ?thesis + apply(insert P) + apply(subst (asm) OclForall_rep_set_true[OF def_X], subst OclForall_rep_set_true[OF def_X]) + by (simp add: assms) +qed + +lemma OclForall_cong': + assumes "\x. x \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \)\\ \ \ \ P (\\. x) \ \ \ Q (\\. x) \ \ \ R (\\. x)" + assumes P: "\ \ OclForall X P" + assumes Q: "\ \ OclForall X Q" + shows "\ \ OclForall X R" +proof - + have def_X: "\ \ \ X" + by(insert P, simp add: OclForall_def OclValid_def bot_option_def true_def split: split_if_asm) + show ?thesis + apply(insert P Q) + apply(subst (asm) (1 2) OclForall_rep_set_true[OF def_X], subst OclForall_rep_set_true[OF def_X]) + by (simp add: assms) +qed + +text{* Strict Equality *} + +lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_defined : + assumes x_def: "\ \ \ x" + assumes y_def: "\ \ \ y" + shows "((x::('\,'\::null)Set) \ y) \ = + (x->forAll\<^sub>S\<^sub>e\<^sub>t(z| y->includes\<^sub>S\<^sub>e\<^sub>t(z)) and (y->forAll\<^sub>S\<^sub>e\<^sub>t(z| x->includes\<^sub>S\<^sub>e\<^sub>t(z)))) \" +proof - + have rep_set_inj : "\\. (\ x) \ = true \ \ + (\ y) \ = true \ \ + x \ \ y \ \ + \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \)\\ \ \\Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \)\\" + apply(simp add: defined_def) + apply(split split_if_asm, simp add: false_def true_def)+ + apply(simp add: null_fun_def null_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def bot_fun_def bot_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) + + apply(case_tac "x \", rename_tac x') + apply(case_tac x', simp_all, rename_tac x'') + apply(case_tac x'', simp_all) + + apply(case_tac "y \", rename_tac y') + apply(case_tac y', simp_all, rename_tac y'') + apply(case_tac y'', simp_all) + + apply(simp add: Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inverse) + by(blast) + + show ?thesis + apply(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t StrongEq_def + foundation20[OF x_def, simplified OclValid_def] + foundation20[OF y_def, simplified OclValid_def]) + apply(subgoal_tac "\\x \ = y \\\ = true \ \ \\x \ = y \\\ = false \") + prefer 2 + apply(simp add: false_def true_def) + (* *) + apply(erule disjE) + apply(simp add: true_def) + + apply(subgoal_tac "(\ \ OclForall x (OclIncludes y)) \ (\ \ OclForall y (OclIncludes x))") + apply(subst cp_OclAnd, simp add: true_def OclValid_def) + apply(simp add: OclForall_includes[OF x_def y_def] + OclForall_includes[OF y_def x_def]) + + (* *) + apply(simp) + + apply(subgoal_tac "OclForall x (OclIncludes y) \ = false \ \ + OclForall y (OclIncludes x) \ = false \") + apply(subst cp_OclAnd, metis OclAnd_false1 OclAnd_false2 cp_OclAnd) + apply(simp only: OclForall_not_includes[OF x_def y_def, simplified OclValid_def] + OclForall_not_includes[OF y_def x_def, simplified OclValid_def], + simp add: false_def) + by (metis OclValid_def rep_set_inj subset_antisym x_def y_def) +qed + +lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_exec[simp,code_unfold] : +"((x::('\,'\::null)Set) \ y) = + (if \ x then (if \ y + then ((x->forAll\<^sub>S\<^sub>e\<^sub>t(z| y->includes\<^sub>S\<^sub>e\<^sub>t(z)) and (y->forAll\<^sub>S\<^sub>e\<^sub>t(z| x->includes\<^sub>S\<^sub>e\<^sub>t(z))))) + else if \ y + then false (* x'->includes = null *) + else invalid + endif + endif) + else if \ x (* null = ??? *) + then if \ y then not(\ y) else invalid endif + else invalid + endif + endif)" +proof - + have defined_inject_true : "\\ P. (\ (\ \ \ P)) = ((\ P) \ = false \)" + by (metis bot_fun_def OclValid_def defined_def foundation16 null_fun_def) + + have valid_inject_true : "\\ P. (\ (\ \ \ P)) = ((\ P) \ = false \)" + by (metis bot_fun_def OclIf_true' OclIncludes_charn0 OclIncludes_charn0' OclValid_def valid_def + foundation6 foundation9) + show ?thesis + apply(rule ext, rename_tac \) + (* *) + apply(simp add: OclIf_def + defined_inject_true[simplified OclValid_def] + valid_inject_true[simplified OclValid_def], + subst false_def, subst true_def, simp) + apply(subst (1 2) cp_OclNot, simp, simp add: cp_OclNot[symmetric]) + apply(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t_defined[simplified OclValid_def]) + by(simp add: StrictRefEq\<^sub>S\<^sub>e\<^sub>t StrongEq_def false_def true_def valid_def defined_def) +qed + +lemma StrictRefEq\<^sub>S\<^sub>e\<^sub>t_L_subst1 : "cp P \ \ \ \ x \ \ \ \ y \ \ \ \ P x \ \ \ \ P y \ + \ \ (x::('\,'\::null)Set) \ y \ \ \ (P x ::('\,'\::null)Set) \ P y" + apply(simp only: StrictRefEq\<^sub>S\<^sub>e\<^sub>t OclValid_def) + apply(split split_if_asm) + apply(simp add: StrongEq_L_subst1[simplified OclValid_def]) +by (simp add: invalid_def bot_option_def true_def) + +lemma OclIncluding_cong' : +shows "\ \ \ s \ \ \ \ t \ \ \ \ x \ + \ \ ((s::('\,'a::null)Set) \ t) \ \ \ (s->including\<^sub>S\<^sub>e\<^sub>t(x) \ (t->including\<^sub>S\<^sub>e\<^sub>t(x)))" +proof - + have cp: "cp (\s. (s->including\<^sub>S\<^sub>e\<^sub>t(x)))" + apply(simp add: cp_def, subst OclIncluding.cp0) + by (rule_tac x = "(\xab ab. ((\_. xab)->including\<^sub>S\<^sub>e\<^sub>t(\_. x ab)) ab)" in exI, simp) + + show "\ \ \ s \ \ \ \ t \ \ \ \ x \ \ \ (s \ t) \ ?thesis" + apply(rule_tac P = "\s. (s->including\<^sub>S\<^sub>e\<^sub>t(x))" in StrictRefEq\<^sub>S\<^sub>e\<^sub>t_L_subst1) + apply(rule cp) + apply(simp add: foundation20) apply(simp add: foundation20) + apply (simp add: foundation10 foundation6)+ + done +qed + +lemma OclIncluding_cong : "\(s::('\,'a::null)Set) t x y \. \ \ \ t \ \ \ \ y \ + \ \ s \ t \ x = y \ \ \ s->including\<^sub>S\<^sub>e\<^sub>t(x) \ (t->including\<^sub>S\<^sub>e\<^sub>t(y))" + apply(simp only:) + apply(rule OclIncluding_cong', simp_all only:) +by(auto simp: OclValid_def OclIf_def invalid_def bot_option_def OclNot_def split : split_if_asm) + +(* < *) +lemma const_StrictRefEq\<^sub>S\<^sub>e\<^sub>t_empty : "const X \ const (X \ Set{})" + apply(rule StrictRefEq\<^sub>S\<^sub>e\<^sub>t.const, assumption) +by(simp) + +lemma const_StrictRefEq\<^sub>S\<^sub>e\<^sub>t_including : + "const a \ const S \ const X \ const (X \ S->including\<^sub>S\<^sub>e\<^sub>t(a))" + apply(rule StrictRefEq\<^sub>S\<^sub>e\<^sub>t.const, assumption) +by(rule const_OclIncluding) + +subsection{* Test Statements *} + +Assert "(\ \ (Set{\_. \\x\\} \ Set{\_. \\x\\}))" +Assert "(\ \ (Set{\_. \x\} \ Set{\_. \x\}))" + +instantiation Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (equal)equal +begin + definition "HOL.equal k l \ (k::('a::equal)Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) = l" + instance by standard (rule equal_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_def) +end + +lemma equal_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_code [code]: + "HOL.equal k (l::('a::{equal,null})Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \ Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e k = Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e l" + by (auto simp add: equal Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e.Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e_inject) + +Assert "\ \ (Set{} \ Set{})" +Assert "\ \ (Set{\,\} \ Set{}->including\<^sub>S\<^sub>e\<^sub>t(\)->including\<^sub>S\<^sub>e\<^sub>t(\))" +Assert "\ \ (Set{\,invalid,\} \ invalid)" +Assert "\ \ (Set{\,\}->including\<^sub>S\<^sub>e\<^sub>t(null) \ Set{null,\,\})" +Assert "\ \ (Set{\,\}->including\<^sub>S\<^sub>e\<^sub>t(null) \ Set{\,\,null})" + +(* +Assert "\ (\ \ (Set{\,\,\} \ Set{\,\}))" +Assert "\ (\ \ (Set{\,\} \ Set{\,\}))" +*) + +(* > *) + +end diff --git a/src/document/FOCL_Syntax.tex b/src/document/FOCL_Syntax.tex new file mode 100644 index 0000000..3468130 --- /dev/null +++ b/src/document/FOCL_Syntax.tex @@ -0,0 +1,1085 @@ +\isatagannexa +\part{The OCL And Featherweight OCL Syntax} +\endisatagannexa +\isatagafp +\chapter{The OCL And Featherweight OCL Syntax} +\endisatagafp +\newcommand{\simpleArgs}[1]{\_} +\newcommand{\hide}[1]{} +\newcommand{\hideT}[1]{} +\newcommand{\foclcolorbox}[2]{#2} +\newcommand{\isaFS}[1]{\isa{\footnotesize #1}} + +{ +\begin{longtable}[C] +{@{}% +c% +l% +l% +l% >{$}l<{$}% +@{}} + \caption{Comparison of different concrete syntax variants for OCL \label{tab:comp-diff-syntax}}\\ + \toprule +& OCL & Featherweight OCL & Logical Constant \\ + \midrule +\endfirsthead + \toprule +& OCL & Featherweight OCL & Logical Constant \\ + \midrule +\endhead + \midrule \multicolumn{3}{r}{\emph{Continued on next page}} +\endfoot + \bottomrule + \endlastfoot + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.3.1 OclAny + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \multirow{11}{*}{\rotatebox{90}{OclAny}} + &\footnotesize\inlineocl"_ = _" + & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymtriangleq}}} & {{\isaFS{UML{\isacharunderscore}Logic{\isachardot}StrongEq}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ +& \footnotesize\inlineocl"_ <> _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharless}{\isachargreater}}} & {{\color{Gray} \isaFS{notequal}}}% + \\ +&\footnotesize\inlineocl"_ ->oclAsSet( _ )"&&\\ +&\footnotesize\inlineocl"_ .oclIsNew()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}oclIsNew{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclIsNew}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + % +&\footnotesize\inlineocl"not ( _ ->oclIsUndefined() )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymdelta}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}defined}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"not ( _ ->oclIsInvalid() )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymupsilon}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}valid}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\inlineocl"_ ->oclAsType( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsTypeOf( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsKindOf( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsInState( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclType()"&&\\ +&\footnotesize\inlineocl"_ ->oclLocale()"&&\\ + + \cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.3.2 OclVoid + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \multirow{11}{*}{\rotatebox{90}{OclVoid}} + &\footnotesize\inlineocl"_ = _" + & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymtriangleq}}} & {{\isaFS{UML{\isacharunderscore}Logic{\isachardot}StrongEq}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ +& \footnotesize\inlineocl"_ <> _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharless}{\isachargreater}}} & {{\color{Gray} \isaFS{notequal}}}% + \\ +&\footnotesize\inlineocl"_ ->oclAsSet( _ )"&&\\ +&\footnotesize\inlineocl"_ .oclIsNew()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}oclIsNew{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclIsNew}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + % +&\footnotesize\inlineocl"not ( _ ->oclIsUndefined() )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymdelta}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}defined}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"not ( _ ->oclIsInvalid() )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymupsilon}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}valid}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\inlineocl"_ ->oclAsType( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsTypeOf( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsKindOf( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsInState( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclType()"&&\\ +&\footnotesize\inlineocl"_ ->oclLocale()"&&\\ + \cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.3.3 OclInvalid + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \multirow{11}{*}{\rotatebox{90}{OclInvalid}} + &\footnotesize\inlineocl"_ = _" + & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymtriangleq}}} & {{\isaFS{UML{\isacharunderscore}Logic{\isachardot}StrongEq}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ +& \footnotesize\inlineocl"_ <> _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharless}{\isachargreater}}} & {{\color{Gray} \isaFS{notequal}}}% + \\ +&\footnotesize\inlineocl"_ ->oclAsSet( _ )"&&\\ +&\footnotesize\inlineocl"_ .oclIsNew()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}oclIsNew{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclIsNew}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + % +&\footnotesize\inlineocl"not ( _ ->oclIsUndefined() )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymdelta}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}defined}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"not ( _ ->oclIsInvalid() )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymupsilon}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}100}}$} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}valid}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\inlineocl"_ ->oclAsType( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsTypeOf( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsKindOf( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclIsInState( _ )"&&\\ +&\footnotesize\inlineocl"_ ->oclType()"&&\\ +&\footnotesize\inlineocl"_ ->oclLocale()"&&\\ + \cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.3.4 OclMessage + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \multirow{4}{*}{\rotatebox{90}{OclMessage}} +%&\footnotesize\inlineocl"_ ->hasReturned()"&&\\ +%&\footnotesize\inlineocl"_ ->result()"&&\\ +%&\footnotesize\inlineocl"_ ->isSignalSent()"&&\\ +%&\footnotesize\inlineocl"_ ->isOperationCall()"&&\\ +% \cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.5.1 Real + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{7}{*}{\rotatebox{90}{Real}} +&\footnotesize\inlineocl"_ + _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharplus}\isactrlsub r\isactrlsub e\isactrlsub a\isactrlsub l}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclAdd\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\footnotesize\inlineocl"_ - _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}\isactrlsub r\isactrlsub e\isactrlsub a\isactrlsub l}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclMinus\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\footnotesize\inlineocl"_ * _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharasterisk}\isactrlsub r\isactrlsub e\isactrlsub a\isactrlsub l}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclMult\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +& \footnotesize\inlineocl"- _" &&\\ +& \footnotesize\inlineocl"_ / _" &&\\ +& \footnotesize\inlineocl"_ .abs()" &&\\ +& \footnotesize\inlineocl"_ .floor()" &&\\ +& \footnotesize\inlineocl"_ .round()" &&\\ +& \footnotesize\inlineocl"_ .max()" &&\\ +& \footnotesize\inlineocl"_ .min()" &&\\ +% +&\footnotesize\inlineocl"_ < _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharless}\isactrlsub r\isactrlsub e\isactrlsub a\isactrlsub l}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclLess\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +& \footnotesize\inlineocl"_ > _" & &\\ +&\footnotesize\inlineocl"_ <= _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymle}\isactrlsub r\isactrlsub e\isactrlsub a\isactrlsub l}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclLe\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ +& \footnotesize\inlineocl"_ >= _" & &\\ +& \footnotesize\inlineocl"_ .toString()" &&\\ +% +&\footnotesize\textcolor{Gray}{\inlineocl"_ .div(_)"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{div\isactrlsub r\isactrlsub e\isactrlsub a\isactrlsub l}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclDivision\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\footnotesize\textcolor{Gray}{\inlineocl"_ .mod(_)"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{mod\isactrlsub r\isactrlsub e\isactrlsub a\isactrlsub l}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclModulus\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% + + % + +&\footnotesize\textcolor{Gray}{\footnotesize\inlineocl"_ ->oclAsType(Integer)"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}oclAsType\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l{\isacharparenleft}Integer{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsInteger\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\textcolor{Gray}{\footnotesize\inlineocl"_ ->oclAsType(Boolean)"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}oclAsType\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l{\isacharparenleft}Boolean{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsBoolean\isactrlsub R\isactrlsub e\isactrlsub a\isactrlsub l}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +\cmidrule{1-4} +%%%% +%%%% +%%%% +%%%% +\multirow{11}{*}{\rotatebox{90}{Real Literals}} +% +&\footnotesize\inlineocl"0.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymzero}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{0}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"1.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymone}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{1}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"2.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymtwo}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{2}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"3.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymthree}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{3}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"4.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymfour}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{4}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"5.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymfive}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{5}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"6.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymsix}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{6}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"7.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymseven}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{7}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"8.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymeight}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{8}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"9.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymnine}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{9}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"10.0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymone}{\isasymzero}{\isachardot}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclReal{\isadigit{1}}{\isadigit{0}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasympi}}} & {{ \isaFS{UML{\isacharunderscore}Real{\isachardot}OclRealpi}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +\cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.5.2 Integer + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{7}{*}{\rotatebox{90}{Integer}} +&\footnotesize\inlineocl"_ - _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}\isactrlsub i\isactrlsub n\isactrlsub t}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclMinus\isactrlsub I\isactrlsub n\isactrlsub t\isactrlsub e\isactrlsub g\isactrlsub e\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\inlineocl"_ + _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharplus}\isactrlsub i\isactrlsub n\isactrlsub t}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclAdd\isactrlsub I\isactrlsub n\isactrlsub t\isactrlsub e\isactrlsub g\isactrlsub e\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% + &\footnotesize\inlineocl"- _" && \\ +% +&\footnotesize\inlineocl"_ * _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharasterisk}\isactrlsub i\isactrlsub n\isactrlsub t}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclMult\isactrlsub I\isactrlsub n\isactrlsub t\isactrlsub e\isactrlsub g\isactrlsub e\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + &\footnotesize\inlineocl"_ / _" && \\ + &\footnotesize\inlineocl"_ .abs()" && \\ + + % + +&\footnotesize\inlineocl"_ div ( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{div\isactrlsub i\isactrlsub n\isactrlsub t}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclDivision\isactrlsub I\isactrlsub n\isactrlsub t\isactrlsub e\isactrlsub g\isactrlsub e\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\footnotesize\inlineocl"_ mod ( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{mod\isactrlsub i\isactrlsub n\isactrlsub t}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclModulus\isactrlsub I\isactrlsub n\isactrlsub t\isactrlsub e\isactrlsub g\isactrlsub e\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +& \footnotesize\inlineocl"_ .max()" &&\\ +& \footnotesize\inlineocl"_ .min()" &&\\ +& \footnotesize\inlineocl"_ .toString()" &&\\ + + +&\textcolor{Gray}{\footnotesize\inlineocl"_ < _"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharless}\isactrlsub i\isactrlsub n\isactrlsub t}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclLess\isactrlsub I\isactrlsub n\isactrlsub t\isactrlsub e\isactrlsub g\isactrlsub e\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\textcolor{Gray}{\footnotesize\inlineocl"_ <= _"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymle}\isactrlsub i\isactrlsub n\isactrlsub t}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclLe\isactrlsub I\isactrlsub n\isactrlsub t\isactrlsub e\isactrlsub g\isactrlsub e\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ + +&\textcolor{Gray}{\footnotesize\inlineocl"_ ->oclAsType(Real)"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}oclAsType\isactrlsub I\isactrlsub n\isactrlsub t{\isacharparenleft}Real{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsReal\isactrlsub I\isactrlsub n\isactrlsub t}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\textcolor{Gray}{\footnotesize\inlineocl"_ ->oclAsType(Boolean)"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}oclAsType\isactrlsub I\isactrlsub n\isactrlsub t{\isacharparenleft}Boolean{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsBoolean\isactrlsub I\isactrlsub n\isactrlsub t}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +\cmidrule{1-4} +%%%% +%%%% +%%%% +%%%% +\multirow{10}{*}{\rotatebox{90}{Integer Literals}} +&\footnotesize\inlineocl"0" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{0}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"1" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymone}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{1}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"2" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymtwo}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{2}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"3" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymthree}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{3}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"4" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymfour}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{4}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"5" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymfive}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{5}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"6" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymsix}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{6}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"7" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymseven}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{7}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"8" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymeight}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{8}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"9" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymnine}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{9}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"10" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymone}{\isasymzero}}} & {{ \isaFS{UML{\isacharunderscore}Integer{\isachardot}OclInt{\isadigit{1}}{\isadigit{0}}}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +\cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.5.3 String + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{20}{*}{\rotatebox{90}{String and String Literals}} +&\footnotesize\inlineocl"_ + _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharplus}\isactrlsub s\isactrlsub t\isactrlsub r\isactrlsub i\isactrlsub n\isactrlsub g}} & {{ \isaFS{UML{\isacharunderscore}String{\isachardot}OclAdd\isactrlsub S\isactrlsub t\isactrlsub r\isactrlsub i\isactrlsub n\isactrlsub g}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\inlineocl"_ .size()"&&\\ +&\footnotesize\inlineocl"_ .concat( _ )"&&\\ +&\footnotesize\inlineocl"_ .substring( _ , _ )"&&\\ +&\footnotesize\inlineocl"_ .toInteger()"&&\\ +&\footnotesize\inlineocl"_ .toReal()"&&\\ +&\footnotesize\inlineocl"_ .toUpperCase()"&&\\ +&\footnotesize\inlineocl"_ .toLowerCase()"&&\\ +&\footnotesize\inlineocl"_ .indexOf()"&&\\ +&\footnotesize\inlineocl"_ .equalsIgnoreCase( _ )"&&\\ +&\footnotesize\inlineocl"_ .at( _ )"&&\\ +&\footnotesize\inlineocl"_ .characters()"&&\\ +&\footnotesize\inlineocl"_ .toBoolean()"&&\\ +&\footnotesize\inlineocl"_ < _ "&&\\ +&\footnotesize\inlineocl"_ > _ "&&\\ +&\footnotesize\inlineocl"_ <= _ "&&\\ +&\footnotesize\inlineocl"_ >= _ "&&\\ +% +&\footnotesize\inlineocl"a" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasyma}}} & {{ \isaFS{UML{\isacharunderscore}String{\isachardot}OclStringa}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"b" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymb}}} & {{ \isaFS{UML{\isacharunderscore}String{\isachardot}OclStringb}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"c" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymc}}} & {{ \isaFS{UML{\isacharunderscore}String{\isachardot}OclStringc}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + +\cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.5.4 Boolean + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{6}{*}{\rotatebox{90}{Boolean and Core Logic}} +% +& \footnotesize\inlineocl"_ or _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{or}} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}OclOr}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +& \footnotesize\inlineocl"_ xor _"&&\\ +& \footnotesize\inlineocl"_ and _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{and}} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}OclAnd}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\footnotesize\inlineocl"not _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} + \foclcolorbox{Apricot}{\isaFS{not}} & {{ + \isaFS{UML{\isacharunderscore}Logic{\isachardot}OclNot}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ +&\footnotesize\inlineocl"_ implies _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{implies}} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}OclImplies}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\inlineocl"_ .toString()"&&\\ + &\footnotesize\inlineocl"if _ then _ else _ endif" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}50}}$)} \foclcolorbox{Apricot}{\isaFS{if}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}10}}$} \foclcolorbox{Apricot}{\isaFS{then}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}10}}$} \foclcolorbox{Apricot}{\isaFS{else}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}10}}$} \foclcolorbox{Apricot}{\isaFS{endif}} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}OclIf}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +& \footnotesize\inlineocl"_ = _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymdoteq}}} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}StrictRefEq}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +& \footnotesize\inlineocl"_ <> _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isacharless}{\isachargreater}}} & {{\color{Gray} \isaFS{notequal}}}% + \\ +% + % +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}50}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}{\isasymnoteq}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} & {{\color{Gray} \isaFS{OclNonValid}}}% +\\ +% +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}50}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isasymTurnstile}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} & {{ \isaFS{UML{\isacharunderscore}Logic{\isachardot}OclValid}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\textcolor{Gray}{\inlineocl"_ = _"} +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymtriangleq}}} & {{\isaFS{UML{\isacharunderscore}Logic{\isachardot}StrongEq}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% + +\cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.5.5 UnlimitedNatural + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.7.1 Collection + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.7.2 Set + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \multirow{12}{*}{\rotatebox{90}{Set and Iterators on Set}} +&\footnotesize\inlineocl"Set ( _ )" +& \hide{\color{Gray}($\text{\isaFS{type}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Set{\isacharparenleft}}} $\text{\isaFS{type}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Types{\isachardot}Set\isactrlsub b\isactrlsub a\isactrlsub s\isactrlsub e}}\text{\space\color{Black}\isaFS{type}}}% +\\ + +% + +&\footnotesize\inlineocl"Set{}" + & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Set{\isacharbraceleft}{\isacharbraceright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}mtSet}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"Set{ _ }" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Set{\isacharbraceleft}}} $\text{\isaFS{args}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharbraceright}}} & {{\color{Gray} \isaFS{OclFinset}}}% +\\ + &\footnotesize\inlineocl"_ ->union( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}union\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclUnion}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + &\footnotesize\inlineocl"_ = _" + & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{op}} \foclcolorbox{Apricot}{\isaFS{{\isasymtriangleq}}} & {{\isaFS{UML{\isacharunderscore}Logic{\isachardot}StrongEq}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% + \\ +&\footnotesize\inlineocl"_ ->intersection( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}intersection\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclIntersection}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +&\footnotesize\inlineocl"_ - _"&&\\ + +&\footnotesize\inlineocl"_ ->including( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}including\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclIncluding}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +&\footnotesize\inlineocl"_ ->excluding( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}excluding\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclExcluding}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +&\footnotesize\inlineocl"_ ->symmetricDifference( _ )"&&\\ + +&\footnotesize\inlineocl"_ ->count( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}count\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclCount}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +&\footnotesize\inlineocl"_ ->flatten()"&&\\ +&\footnotesize\inlineocl"_ ->selectByKind( _ )"&&\\ +&\footnotesize\inlineocl"_ ->selectByType( _ )"&&\\ + +&\footnotesize\inlineocl"_ ->reject( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}reject\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclRejectSet}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->select( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}select\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclSelectSet}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->iterate( _ ; _ = _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}iterate\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} $\text{\isaFS{idt}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharsemicolon}}} $\text{\isaFS{idt}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharequal}}} $\text{\isaFS{any}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} $\text{\isaFS{any}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclIterateSet}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->exists( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}exists\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclExistSet}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->forAll( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}forAll\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclForallSet}}}% +\\ + + + % +&\footnotesize\inlineocl"_ ->asSequence()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asSequence\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsSeq\isactrlsub S\isactrlsub e\isactrlsub t}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\footnotesize\inlineocl"_ ->asBag()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asBag\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsBag\isactrlsub S\isactrlsub e\isactrlsub t}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ +% +&\footnotesize\inlineocl"_ ->asPair()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asPair\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsPair\isactrlsub S\isactrlsub e\isactrlsub t}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + +&\footnotesize\inlineocl"_ ->sum()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}sum\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclSum}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + + +% + + +% + + +% + +&\footnotesize\inlineocl"_ ->excludesAll( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}excludesAll\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclExcludesAll}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->includesAll( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}includesAll\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclIncludesAll}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + + +% + +&\footnotesize\inlineocl"_ ->any()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}any\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclANY}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->notEmpty()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}notEmpty\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclNotEmpty}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->isEmpty()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}isEmpty\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclIsEmpty}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->size()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}size\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclSize}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->excludes( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}excludes\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclExcludes}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->includes( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}includes\isactrlsub S\isactrlsub e\isactrlsub t{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Set{\isachardot}OclIncludes}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +% + +\cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.7.2 Sequence + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{15}{*}{\rotatebox{90}{Sequence and Iterators on Sequence}} + +&\footnotesize\inlineocl"Sequence ( _ )" +& \hide{\color{Gray}($\text{\isaFS{type}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Sequence{\isacharparenleft}}} $\text{\isaFS{type}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Types{\isachardot}Sequence\isactrlsub b\isactrlsub a\isactrlsub s\isactrlsub e}}\text{\space\color{Black}\isaFS{type}}}% + \\ +&\footnotesize\inlineocl"Sequence{}" + & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Sequence{\isacharbraceleft}{\isacharbraceright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}mtSequence}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"Sequence{ _ }" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Sequence{\isacharbraceleft}}} $\text{\isaFS{args}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharbraceright}}} & {{\color{Gray} \isaFS{OclFinsequence}}}% +\\ + +&\footnotesize\inlineocl"_ ->any()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}any\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclANY}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->notEmpty()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}notEmpty\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclNotEmpty}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->isEmpty()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}isEmpty\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclIsEmpty}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->size()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}size\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclSize}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->select( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}select\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclSelectSeq}}}% +\\ + +% +&\footnotesize\inlineocl"_ ->collect( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}collect\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclCollectSeq}}}% +\\ + +% +&\footnotesize\inlineocl"_ ->exists( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}exists\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclExistSeq}}}% +\\ + +% +&\footnotesize\inlineocl"_ ->forAll( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}forAll\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclForallSeq}}}% +\\ + +% +&\footnotesize\inlineocl"_ ->iterate( _ ; _ : _ = _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}iterate\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} $\text{\isaFS{idt}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharsemicolon}}} $\text{\isaFS{idt}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharequal}}} $\text{\isaFS{any}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} $\text{\isaFS{any}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclIterateSeq}}}% +\\ + +% +&\footnotesize\inlineocl"_ ->last()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}last\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclLast}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->first()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}first\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclFirst}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->at( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}at\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclAt}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"_ ->union( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}union\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclUnion}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->append( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}append\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclAppend}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"_ ->excluding( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}excluding\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclExcluding}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->including( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}including\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclIncluding}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->prepend( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}prepend\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Sequence{\isachardot}OclPrepend}}\hideT{\text{\spae\color{Black}\isaFS{const}}}}% +\\ + + % +&\footnotesize\inlineocl"_ ->asSet()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asSet\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsSet\isactrlsub S\isactrlsub e\isactrlsub q}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + +% +&\footnotesize\inlineocl"_ ->asBag()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asBag\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsBag\isactrlsub S\isactrlsub e\isactrlsub q}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + +% + +&\footnotesize\inlineocl"_ ->asPair()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asPair\isactrlsub S\isactrlsub e\isactrlsub q{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsPair\isactrlsub S\isactrlsub e\isactrlsub q}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + + +% +% + +\cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% 11.7.3 Bag + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{15}{*}{\rotatebox{90}{Bag and Iterators on Bag}} +% + +&\footnotesize\inlineocl"Bag ( _ )" +& \hide{\color{Gray}($\text{\isaFS{type}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Bag{\isacharparenleft}}} $\text{\isaFS{type}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Types{\isachardot}Bag\isactrlsub b\isactrlsub a\isactrlsub s\isactrlsub e}}\text{\space\color{Black}\isaFS{type}}}% +\\ + +% +% +&\footnotesize\inlineocl"Bag{}" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Bag{\isacharbraceleft}{\isacharbraceright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}mtBag}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +&\footnotesize\inlineocl"Bag{ _ }" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Bag{\isacharbraceleft}}} $\text{\isaFS{args}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharbraceright}}} & {{\color{Gray} \isaFS{OclFinbag}}}% +\\ + + +&\footnotesize\inlineocl"_ ->sum()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}sum\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclSum}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->count( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}count\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclCount}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->intersection( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}intersection\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclIntersection}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + +% + +&\footnotesize\inlineocl"_ ->union( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}union\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclUnion}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->excludesAll( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}excludesAll\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclExcludesAll}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->includesAll( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}includesAll\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclIncludesAll}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->reject( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}reject\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclRejectBag}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->select( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}select\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclSelectBag}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->iterate( _ ; _ = _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}iterate\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} $\text{\isaFS{idt}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharsemicolon}}} $\text{\isaFS{idt}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharequal}}} $\text{\isaFS{any}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} $\text{\isaFS{any}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclIterateBag}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->exists( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}exists\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclExistBag}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->forAll( _ | _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}forAll\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \fbox{$\text{\isaFS{id}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbar}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{\color{Gray} \isaFS{OclForallBag}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->any()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}any\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclANY}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->notEmpty()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}notEmpty\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclNotEmpty}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->isEmpty()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}isEmpty\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclIsEmpty}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->size()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}size\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclSize}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->excludes( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}excludes\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclExcludes}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->includes( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}includes\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclIncludes}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->excluding( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}excluding\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclExcluding}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ ->including( _ )" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}including\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Bag{\isachardot}OclIncluding}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + % +&\footnotesize\inlineocl"_ ->asSet()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asSet\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsSet\isactrlsub B\isactrlsub a\isactrlsub g}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + % +&\footnotesize\inlineocl"_ ->asSeq()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asSeq\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsSeq\isactrlsub B\isactrlsub a\isactrlsub g}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + % +&\footnotesize\inlineocl"_ ->asPair()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asPair\isactrlsub B\isactrlsub a\isactrlsub g{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsPair\isactrlsub B\isactrlsub a\isactrlsub g}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +\cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% Pair + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{3}{*}{\rotatebox{90}{Pair}} + +&\footnotesize\inlineocl"" +& \hide{\color{Gray}($\text{\isaFS{type}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Pair{\isacharparenleft}}} $\text{\isaFS{type}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharcomma}}} $\text{\isaFS{type}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Types{\isachardot}Pair\isactrlsub b\isactrlsub a\isactrlsub s\isactrlsub e}}\text{\space\color{Black}\isaFS{type}}}% +\\ + + % +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{Pair{\isacharbraceleft}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharcomma}}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharbraceright}}} & {{ \isaFS{UML{\isacharunderscore}Pair{\isachardot}OclPair}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}Second{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Pair{\isachardot}OclSecond}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}First{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Pair{\isachardot}OclFirst}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +% +&\footnotesize\inlineocl"_ ->asSequence()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asSequence\isactrlsub P\isactrlsub a\isactrlsub i\isactrlsub r{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsSeq\isactrlsub P\isactrlsub a\isactrlsub i\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + +% +&\footnotesize\inlineocl"_ ->asSet()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}asSet\isactrlsub P\isactrlsub a\isactrlsub i\isactrlsub r{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}Library{\isachardot}OclAsSet\isactrlsub P\isactrlsub a\isactrlsub i\isactrlsub r}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + + \cmidrule{1-4} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% Pair + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\multirow{3}{*}{\rotatebox{90}{State Access}} + +&\footnotesize\inlineocl"_ .allInstances()" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}allInstances{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclAllInstances{\isacharunderscore}at{\isacharunderscore}post}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}allInstances{\isacharat}pre{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclAllInstances{\isacharunderscore}at{\isacharunderscore}pre}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + + +% + +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}oclIsDeleted{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclIsDeleted}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}oclIsMaintained{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclIsMaintained}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isachardot}oclIsAbsent{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclIsAbsent}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharminus}{\isachargreater}oclIsModifiedOnly{\isacharparenleft}{\isacharparenright}}} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclIsModifiedOnly}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% + +&\footnotesize\inlineocl"_ @pre _" +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharat}pre}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclSelf{\isacharunderscore}at{\isacharunderscore}pre}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + +% +& +& \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isacharat}post}} \simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} & {{ \isaFS{UML{\isacharunderscore}State{\isachardot}OclSelf{\isacharunderscore}at{\isacharunderscore}post}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +\\ + + + + \cmidrule{1-4} + +%%%% +%%%% +%%%% Other Stuff +%%%% + +% \multirow{7}{*}{\rotatebox{90}{Unsorted}} + +% +% & +% & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymlceil}}}\simpleArgs{$\text{\isaFS{logic}}^{\text{\color{GreenYellow}0}}$} \foclcolorbox{Apricot}{\isaFS{{\isasymrceil}}} & {{ \isaFS{UML{\isacharunderscore}Types{\isachardot}drop}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +% \\ +% % +% & +% & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{I{\isasymlbrakk}}} $\text{\isaFS{any}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isasymrbrakk}}} & {{ \isaFS{UML{\isacharunderscore}Types{\isachardot}Sem}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +% \\ + + +% % +% & +% & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymbottom}}} & {{ \isaFS{UML{\isacharunderscore}Types{\isachardot}bot{\isacharunderscore}class{\isachardot}bot}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +% \\ + +% % + + +% % +% & +% & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymbottom}}} & {{ \isaFS{Option{\isachardot}option{\isachardot}None}}\hideT{\text{\space\color{Black}\isaFS{const}}}}% +% \\ + + + + +% % + + +% % + + +% % + +% % +% % & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} $\text{\isaFS{cartouche{\isacharunderscore}position}}^{\text{\color{GreenYellow}0}}$ & {{\color{Gray} \isaFS{cartouche{\isacharunderscore}oclstring}}}% +% % \\ + +% % +% & +% & \hide{\color{Gray}($\text{\isaFS{logic}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isacharunderscore}{\isacharprime}}} & {{\color{Gray} \isaFS{ocl{\isacharunderscore}denotation}}}% +% \\ + + +% % +% % + +% % +% & +% & \hide{\color{Gray}($\text{\isaFS{type}}^{\text{\color{GreenYellow}1000}}$)} \foclcolorbox{Apricot}{\isaFS{{\isasymlangle}}} $\text{\isaFS{type}}^{\text{\color{GreenYellow}0}}$ \foclcolorbox{Apricot}{\isaFS{{\isasymrangle}\isactrlsub {\isasymbottom}}} & {{ \isaFS{Option{\isachardot}option}}\text{\space\color{Black}\isaFS{type}}}% +% \\ + +% + + + +% + + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% + + + + + + + +\end{longtable} +} + +%%% Local Variables: +%%% fill-column:80 +%%% x-symbol-8bits:nil +%%% mode: latex +%%% TeX-master: "syntax_main" +%%% End: diff --git a/document/conclusion.tex b/src/document/conclusion.tex similarity index 88% rename from document/conclusion.tex rename to src/document/conclusion.tex index 11bd4e8..24d93f3 100644 --- a/document/conclusion.tex +++ b/src/document/conclusion.tex @@ -6,17 +6,23 @@ We provided a typed and type-safe shallow embedding of the core of UML~\cite{omg:uml-infrastructure:2011,omg:uml-superstructure:2011} and OCL~\cite{omg:ocl:2012}. Shallow embedding means that types of OCL -were injectively, \ie, mapped by the embedding one-to-one to types in +were mapped by the embedding one-to-one to types in Isabelle/HOL~\cite{nipkow.ea:isabelle:2002}. We followed the usual methodology to build up the theory uniquely by conservative extensions of all operators in a denotational style and to derive logical and algebraic (execution) rules from them; thus, we can guarantee the logical consistency of the library and instances of the class model -construction, \ie, closed-world object-oriented datatype theories, as +construction. The class models were given a closed-world interpretation +as object-oriented datatype theories, as long as it follows the described methodology.\footnote{Our two - examples of \inlineisar+Employee_DesignModel+ (see - \autoref{ex:employee-design}) sketch how this construction can - be captured by an automated process.} Moreover, all derived + examples of \inlineisar+Employee_AnalysisModel+ and + \inlineisar+Employee_DesignModel+ (see + \autoref{ex:employee-analysis:uml} and + \autoref{ex:employee-analysis:ocl} as well as + \autoref{ex:employee-design:uml} and + \autoref{ex:employee-design:ocl}) sketch how this construction can + be captured by an automated process; its implementation is described + elsewhere.} Moreover, all derived execution rules are by construction type-safe (which would be an issue, if we had chosen to use an object universe construction in Zermelo-Fraenkel set theory as an alternative approach to subtyping.). @@ -81,8 +87,8 @@ inherent messy and a semantically clean compilation of OCL formulae to a two-valued presentation, that is amenable to animators like KodKod~\cite{torlak.ea:kodkod:2007} or SMT-solvers like Z3~\cite{moura.ea:z3:2008} completely impractical. Concretely, if the -expression \inlineocl{not(null)} is defined \inlineocl{invalid} (as is -the case in the present standard~\cite{omg:ocl:2012}), than standard +expression \inlineocl{not(null)} is defined \inlineocl{invalid} (as was +the case in prior versions of the standard~\cite{omg:ocl:2012}), then standard involution does not hold, \ie, \inlineocl{not(not(A))} = \inlineocl{A} does not hold universally. Similarly, if \inlineocl{null and null} is \inlineocl{invalid}, then not even idempotence \inlineocl{X and X} = @@ -93,7 +99,7 @@ respect to this semantical ``information ordering.'' A similar experience with prior paper and pencil arguments was our investigation of the object-oriented data-models, in particular -path-expressions ~\cite{DBLP:conf/models/BruckerLTW13}. The final +path-expressions ~\cite{brucker.ea:path-expressions:2013}. The final presentation is again essentially correct, but the technical details concerning exception handling lead finally to a continuation-passing style of the (in future generated) definitions for accessors, casts @@ -116,22 +122,16 @@ consequences of a four-valued logic (\ie, OCL versions that support, besides the truth values \inlineocl{true} and \inlineocl{false} also the two exception values \inlineocl{invalid} and \inlineocl{null}). -In the following, we outline the necessary steps for turning -Featherweight OCL into a fully fledged tool for OCL, \eg, similar to -\holocl as well as for supporting test case generation similar to -{HOL}-TestGen~\cite{brucker.ea:hol-testgen:2009}. There are +In the following, we outline the following future extensions to use +Featherweight OCL for a concrete fully fledged tool for OCL. There are essentially five extensions necessary: \begin{itemize} -\item extension of the library to support all OCL data types, \eg, - \inlineocl{OrderedSet(T)} or \inlineocl{Sequence(T)}. This - formalization of the OCL standard library can be used for checking - the consistency of the formal semantics (known as ``Annex A'') with - the informal and semi-formal requirements in the normative part of - the OCL standard. \item development of a compiler that compiles a textual or CASE tool representation (\eg, using XMI or the textual syntax of the USE tool~\cite{richters:precise:2002}) of class - models. Such compiler could also generate the necessary casts when + models into an object-oriented data type theory automatically. +\item Full support of OCL standard syntax in a front-end parser; + Such a parser could also generate the necessary casts as well as converting standard OCL to Featherweight OCL as well as providing ``normalizations'' such as converting multiplicities of class attributes to into OCL class invariants. @@ -142,8 +142,9 @@ essentially five extensions necessary: from the default multiplicity \inlineocl{1} of an attributes \inlineocl{x}, we can directly infer that for all valid states \inlineocl{x} is neither \inlineocl{invalid} nor \inlineocl{null}), - such a translation enables an efficient test case generation - approach. + such a translation enables both an integration of fast constraint solvers + such as Z3 as well as test-case generation scenarios as described in + \cite{brucker.ea:ocl-testing:2010}. \item a setup in Featherweight OCL of the Nitpick animator~\cite{blanchette.ea:nitpick:2010}. It remains to be shown that the standard, Kodkod~\cite{torlak.ea:kodkod:2007} based diff --git a/document/figures/AbstractSimpleChair.mp b/src/document/figures/AbstractSimpleChair.mp similarity index 100% rename from document/figures/AbstractSimpleChair.mp rename to src/document/figures/AbstractSimpleChair.mp diff --git a/document/figures/AbstractSimpleChair.pdf b/src/document/figures/AbstractSimpleChair.pdf similarity index 100% rename from document/figures/AbstractSimpleChair.pdf rename to src/document/figures/AbstractSimpleChair.pdf diff --git a/document/figures/jedit.png b/src/document/figures/jedit.png similarity index 100% rename from document/figures/jedit.png rename to src/document/figures/jedit.png diff --git a/document/figures/pdf.png b/src/document/figures/pdf.png similarity index 100% rename from document/figures/pdf.png rename to src/document/figures/pdf.png diff --git a/document/figures/person.png b/src/document/figures/person.png similarity index 100% rename from document/figures/person.png rename to src/document/figures/person.png diff --git a/document/figures/pre-post.pdf b/src/document/figures/pre-post.pdf similarity index 100% rename from document/figures/pre-post.pdf rename to src/document/figures/pre-post.pdf diff --git a/document/hol-ocl-isar.sty b/src/document/hol-ocl-isar.sty similarity index 99% rename from document/hol-ocl-isar.sty rename to src/document/hol-ocl-isar.sty index 2ca1225..fd4a262 100644 --- a/document/hol-ocl-isar.sty +++ b/src/document/hol-ocl-isar.sty @@ -598,6 +598,12 @@ {#2\operatorname{\!.#3}^{(#1)}}% } +\newcommand{\getRole}[3][]{% + \ifthenelse{\equal{#1}{}}% + {#2\operatorname{\!.#3}}% + {#2\operatorname{\!.#3}^{(#1)}}% +} + \newcommand{\setAttrib}[4][]{% \ifthenelse{\equal{#1}{}}% {#2\operatorname{\!.set_{#3}}\ap \mathit{#4}}% diff --git a/src/document/introduction.tex b/src/document/introduction.tex new file mode 100644 index 0000000..9f4ea1e --- /dev/null +++ b/src/document/introduction.tex @@ -0,0 +1,2115 @@ +\section{Introduction} +\isatagafp% +The Unified Modeling Language +(UML)~\cite{omg:uml-infrastructure:2011,omg:uml-superstructure:2011} +is one of the few modeling languages that is widely used in +industry. UML is defined in an open process by the Object Management +Group (OMG), \ie, an industry consortium. While UML is mostly known +as diagrammatic modeling language (\eg, visualizing class models), it +also comprises a textual language, called Object Constraint Language +(OCL)~\cite{omg:ocl:2012}. OCL is a textual annotation language, +originally conceived as a three-valued logic, that turns substantial +parts of UML into a formal language. Unfortunately the semantics of +this specification language, captured in the ``Annex A'' (originally, +based on the work of \citet{richters:precise:2002}) of the OCL +standard leads to different interpretations of corner cases. Many of +these corner cases had been subject to formal analysis since more than +nearly fifteen years (see, +\eg,~\cite{brucker.ea:semantic:2006-b,brucker.ea:proposal:2002,mandel.ea:ocl:1999, + hamie.ea:reflections:1998,cook.ea::amsterdam:2002}). + +At its origins~\cite{richters:precise:2002,omg:ocl:1997}, OCL was +conceived as a strict semantics for undefinedness (\eg, denoted by the +element \inlineocl{invalid}\footnote{In earlier versions of the OCL + standard, this element was called \inlineocl{OclUndefined}.}), with +the exception of the logical connectives of type \inlineocl{Boolean} +that constitute a three-valued propositional logic. At its core, OCL +comprises four layers: +\begin{enumerate} +\item Operators (\eg, \inlineocl{_ and _}, \inlineocl{_ + _}) on + built-in data structures such as \inlineocl{Boolean}, + \inlineocl{Integer}, or typed sets (\inlineocl{Set(_)}. +\item Operators on the user-defined data model (\eg, defined as part + of a UML class model) such as accessors, type casts and tests. +\item Arbitrary, user-defined, side-effect-free methods called \emph{queries}, +\item Specification for invariants on states and contracts for + operations to be specified via pre- and post-conditions. +\end{enumerate} + +Motivated by the need for aligning OCL closer with UML, recent +versions of the OCL standard~\cite{omg:ocl:2006,omg:ocl:2012} added a +second exception element. While the first exception element +\inlineocl{invalid} has a strict semantics, \inlineocl{null} has a non +strict semantic interpretation. Unfortunately, this extension results +in several inconsistencies and contradictions. These problems are +reflected in difficulties to define interpreters, code-generators, +specification animators or theorem provers for OCL in a uniform manner +and resulting incompatibilities of various tools. + +For the OCL community, the semantics of \inlineocl{invalid} and +\inlineocl{null} as well as many related issues resulted in the +challenge to define a consistent version of the OCL standard that is +well aligned with the recent developments of the UML\@. A syntactical +and semantical consistent standard requires a major revision of both +the informal and formal parts of the standard. To discuss the future +directions of the standard, several OCL experts met in November 2013 +in Aachen to discuss possible mid-term improvements of OCL, strategies +of standardization of OCL within the OMG, and a vision for possible +long-term developments of the +language~\cite{brucker.ea:summary-aachen:2013}. During this meeting, a +Request for Proposals (RFP) for OCL 2.5 was finalized and meanwhile +proposed. In particular, this RFP requires that the future OCL 2.5 +standard document shall be generated from a machine-checked +source. This will ensure +\begin{itemize} +\item the absence of syntax errors, +\item the consistency of the formal semantics, +\item a suite of corner-cases relevant for OCL tool implementors. +\end{itemize} + +In this document, we present a formalization using +Isabelle/HOL~\cite{nipkow.ea:isabelle:2002} of a core language of +OCL\@. The semantic theory, based on a ``shallow embedding'', is +called \emph{Featherweight OCL}, since it focuses on a formal +treatment of the key-elements of the language (rather than a full +treatment of all operators and thus, a ``complete'' +implementation). In contrast to full OCL, it comprises just the logic +captured in \verb+Boolean+, the basic data types \verb+Integer+ \verb+Real+ and +\verb+String+, the collection types \verb+Set+, \verb+Sequence+ and \verb+Bag+, +as well as the generic construction principle of class models, which is +instantiated and demonstrated for two examples (an automated support for +this type-safe construction is out of the scope of Featherweight OCL). +This formal semantics +definition is intended to be a proposal for the standardization +process of OCL 2.5, which should ultimately replace parts of the +mandatory part of the standard document~\cite{omg:ocl:2012} as well as +replace completely its informative ``Annex A.'' +\endisatagafp +%% +\isatagannexa +This annex chapter formally defines the semantics of \OCL\@. This +chapter is a, to a large extend automatically generated, summary of a +formal semantics of the core of OCL, called \FOCL\footnote{An updated, + machine-checked version and formally complete version of the + complete formalization is maintained by the Isabelle Archive of + Formal Proofs (AFP), see + \url{http://afp.sourceforge.net/entries/Featherweight_OCL.shtml}}. \FOCL +has a formal semantics in Isabelle/\HOL~\cite{nipkow.ea:isabelle:2002}. +\endisatagannexa + +The semantic definitions are in large parts executable, in some parts +only provable, namely the essence of Set-and Bag-constructions. The first goal +of its construction is \emph{consistency}, \ie, it should be possible +to apply logical rules and/or evaluation rules for \OCL in an +arbitrary manner always yielding the same result. Moreover, except in +pathological cases, this result should be unambiguously defined, \ie, +represent a value. + +To motivate the need for logical consistency and also the magnitude of +the problem, we focus on one particular feature of the language as +example: \inlineocl{Tuples}. Recall that tuples (in other languages +known as \emph{records}) are $n$-ary Cartesian products with named +components, where the component names are used also as projection +functions: the special case % +\inlineocl+Pair{x:First, y:Second}+ stands for the usual binary +pairing operator \inlineocl+Pair{true,null}+ and the two projection +functions \inlineocl+x.First()+ and \inlineocl+x.Second()+. For a +developer of a compiler or proof-tool (based on, say, a connection to +an SMT solver designed to animate \OCL contracts) it would be natural +to add the rules \inlineocl+Pair{X,Y}.First() = X+ and +\inlineocl+Pair{X,Y}.Second() = Y+ to give pairings the usual +semantics. At some place, the \OCL Standard requires the existence of +a constant symbol \inlineocl+invalid+ and requires all operators to be +strict. To implement this, the developer might be tempted to add a +generator for corresponding strictness axioms, producing among +hundreds of other rules +\inlineocl+Pair{invalid,Y}=invalid+,\inlineocl+Pair{X,invalid}=invalid+, +\inlineocl+invalid.First()=invalid+, +\inlineocl+invalid.Second()=invalid+, etc. Unfortunately, this +``natural'' axiomatization of pairing and projection together with +strictness is already inconsistent. One can derive: +\begin{ocl} + Pair{true,invalid}.First() = invalid.First() = invalid +\end{ocl} +and: +\begin{ocl} + Pair{true,invalid}.First() = true +\end{ocl} +which then results in the absurd logical consequence that +\inlineocl+invalid = true+. Obviously, we need to be more careful on +the side-conditions of our rules\footnote{The solution to this little + riddle can be found in \autoref{sec:collection_pairs}.}. And +obviously, only a mechanized check of these definitions, following a +rigorous methodology, can establish strong guarantees for logical +consistency of the \OCL language. + +\isatagafp + This leads us to our second goal of this document: +\endisatagafp +\isatagannexa + This leads us to our second goal of this annex: +\endisatagannexa +it should not only be +usable by logicians, but also by developers of compilers and +proof-tools. For this end, we \emph{derived} from the Isabelle +definitions also \emph{logical rules} allowing formal interactive and +automated proofs on \UML/\OCL specifications, as well as +\emph{execution rules} and \emph{test-cases} revealing corner-cases +resulting from this semantics which give vital information for the +implementor. + +\OCL is an annotation language for \UML models, in particular class +models allowing for specifying data and operations on them. As such, +it is a \emph{typed} object-oriented language. This means that it +is---like Java or C++---based on the concept of a \emph{static type}, +that is the type that the type-checker infers from a \UML class model +and its \OCL annotation, as well as a \emph{dynamic type}, that is the +type at which an object is dynamically created\footnote{As + side-effect free language, \OCL has no object-constructors, but with + \inlineocl+OclIsNew()+, the effect of object creation can be + expressed in a declarative way.}. Types are not only a means for +efficient compilation and a support of separation of concerns in +programming, there are of fundamental importance for our goal of +logical consistency: it is impossible to have sets that contain +themselves, \ie, to state Russels Paradox in \OCL typed set-theory. +Moreover, object-oriented typing means that types there can be in +sub-typing relation; technically speaking, this means that they can be +\emph{cast} via \inlineocl+oclIsTypeOf(T)+ one to the other, and under +particular conditions to be described in detail later, these casts are +semantically \emph{lossless}, \ie, +\begin{equation} + (X.oclAsType(C_j).oclAsType(C_i) = X) +\end{equation} +(where $C_j$ and $C_i$ are class types.) +Furthermore, object-oriented means that operations and object-types can be +grouped to \emph{classes} on which an inheritance relation can be established; +the latter induces a sub-type relation between the corresponding types. + +Here is a feature-list of \FOCL: +\begin{itemize} + \item it specifies key built-in types such as \inlineocl+Boolean+, + \inlineocl+Void+, \inlineocl+Integer+, \inlineocl+Real+ and + \inlineocl+String+ as well as generic types such as + \inlineocl+Pair(T,T')+, \inlineocl+Sequence(T)+ and \inlineocl+Set(T)+. + \item it defines the semantics of the operations of these types in + \emph{denotational form}---see explanation below---, + and thus in an unambiguous (and in Isabelle/\HOL executable or + animatable) way. + \item it develops the \emph{theory} of these definitions, \ie, the collection + of lemmas and theorems that can be proven from these definitions. + \item all types in \FOCL contain the elements \inlineocl{null} and \inlineocl{invalid}; + since this extends to \inlineocl+Boolean+ type, this results + in a four-valued logic. Consequently, \FOCL contains + the derivation of the \emph{logic} of \OCL. + \item collection types may contain + \inlineocl{null} (so \inlineocl|Set{null}| is a defined set) but not + \inlineocl{invalid} (\inlineocl|Set{invalid}| is just + \inlineocl{invalid}). + \item Wrt. to the static types, \FOCL is a strongly typed language in + the Hindley-Milner tradition. + We assume that a pre-process for full \OCL eliminates all implicit + conversions due to subtyping by introducing explicit casts (\eg, + \inlineocl{oclAsType(Class)}).\footnote{The details of such a + pre-processing are described in~\cite{brucker:interactive:2007}.} + \item \FOCL types may be arbitrarily nested. For example, + the expression + \inlineocl|Set{Set{1,2}} = Set{Set{2,1}}| is legal and true. + \item \FOCL types may be higher-order nested. For example, + the expression \inlineocl|\ X. Set{X} = Set{Set{2,1}}| is legal. + Higher-order pattern-matching can be easily extended following + the principles in the \HOL library, which can be applied also to \FOCL types. + \item All objects types are represented in an object universe\footnote{following + the tradition of \HOL-\OCL~\cite{brucker.ea:extensible:2008-b}}. + The universe construction also gives semantics to type casts, dynamic type + tests, as well as functions such as \inlineocl{allInstances()}, + or \inlineocl{oclIsNew()}. The object universe construction is + conceptually described and demonstrated at an example. + \item As part of the \OCL logic, \FOCL develops the theory of + equality in \UML/\OCL. This includes the standard equality, which is a + computable strict equality using the object references for comparison, + and the not necessarily computable logical equality, which expresses + the Leibniz principle that `equals may be replaced by equals' in + \OCL terms. + \item Technically, \FOCL is a \emph{semantic embedding} into a + powerful semantic meta-language and + environment, namely Isabelle/\HOL~\cite{nipkow.ea:isabelle:2002}. + It is a so-called \emph{shallow embedding} in \HOL; this means that types + in \OCL were mapped one-to-one to types in Isabelle/\HOL. + Ill-typed \OCL specifications can therefore not be represented in + \FOCL and a type in \FOCL contains exactly + the values that are possible in \OCL\@. +% \item It supports equational reasoning and congruence reasoning, but +% this requires a differentiation of the different equalities like +% strict equality, strong equality, meta-equality (HOL). Strict +% equality and strong equality require a subcalculus, ``cp'' (a +% detailed discussion of the different equalities as well as the +% subcalculus ``cp''---for three-valued \OCL 2.0---is given +% in~\cite{brucker.ea:semantics:2009}), which is nasty but can be +% hidden from the user inside tools. +\end{itemize} + +\paragraph*{Context.} This document stands in a more than fifteen years +tradition of giving a formal semantics to the core of \UML and its +annotation language \OCL, starting from \citet{richters:precise:2002} +and~\cite{hamie.ea:reflections:1998,mandel.ea:ocl:1999,cook.ea::amsterdam:2002}, +leading to a number of formal, machine-checked versions, most notably +\HOL-\OCL~\cite{brucker.ea:semantic:2006-b,brucker:interactive:2007,brucker.ea:hol-ocl-book:2006,brucker.ea:extensible:2008-b} +and more recent approaches~\cite{brucker.ea:path-expressions:2013}. All +of them have in common the attempt to reconcile the conflicting +demands of an industrially used specification language and its various +stakeholders, the needs of OMG standardization process and the desire +for sufficient logical precision for tool-implementors, in particular +from the Formal Methods research community. To discuss the future +directions of the standard, several \OCL experts met in November 2013 +in Aachen to discuss possible mid-term improvements of \OCL, +strategies of standardization of \OCL within the OMG, and a vision for +possible long-term developments of the +language~\cite{brucker.ea:summary-aachen:2013}. The participants +agreed that future proposals for a formal semantics should be +machine-check, to ensure the absence of syntax errors, the consistency +of the formal semantics, as well as provide a a suite of corner-cases +relevant for \OCL tool implementors. + +\paragraph*{Organization of this document.} +This document is organized as follows. After a brief background section +introducing a running example and basic knowledge on Isabelle/\HOL and its formal +notations, we present the formal semantics of \FOCL introducing: +\begin{enumerate} +\item A conceptual description of the formal semantics, highlighting the essentials + and avoiding the definitions in detail. +\item A detailed formal description. This covers: +\begin{enumerate} +\item \OCL Types and their presentation in Isabelle/\HOL, +\item \OCL Terms, \ie, the semantics of library operators, + together with definitions, lemmas, and test cases for the implementor, +\item \UML/\OCL Constructs, \ie, a core of \UML class models plus user-defined + constructions on them such as class-invariants and operation contracts. +\end{enumerate} +\item Since the latter, \ie, the construction of \UML class models, has to be done on the meta-level +(so not \emph{inside} \HOL, rather on the level of a pre-compiler), we will describe this process +with two larger examples, namely formalizations of our running example. +\end{enumerate} + + +%A.1 Object Models +%In this sub clause, the notion of an object model is formally defined. +%An object model provides the context for \OCL expressions and constraints. +%A precise understanding of object models is required before a formal +%definition of \OCL expressions can be given. Sub clause A.1.1 proceeds with a +%formal definition of the syntax of object models. The semantics of object +%models is defined in sub clause A.1.2. This sub clause also defines the +%notion of system states as snapshots of a running system. + +\section{Background} +\isatagafp +\subsection{A Running Example for \UML/\OCL} +\label{sec:guidedtour} +The Unified Modeling Language +(\UML)~\cite{omg:uml-infrastructure:2011,omg:uml-superstructure:2011} +comprises a variety of model types for describing static (\eg, class +models, object models) and dynamic (\eg, state-machines, activity +graphs) system properties. +\begin{figure*} + \centering\scalebox{1}{\includegraphics{figures/AbstractSimpleChair}}% + \caption{A simple \UML class model representing a conference + system for organizing conference sessions: persons can + participate, in different roles, in a session. \label{fig:uml}} +\end{figure*} +One of the more prominent model types of the \UML is the +\emph{class model} (visualized as \emph{class diagram}) for modeling +the underlying data model of a system in an object-oriented manner. As +a running example, we model a part of a conference management +system. Such a system usually supports the conference organizing +process, \eg, creating a conference Website, reviewing submissions, +registering attendees, organizing the different sessions and tracks, +and indexing and producing the resulting proceedings. In this example, +we constrain ourselves to the process of organizing conference +sessions; \autoref{fig:uml} shows the class model. We model the +hierarchy of roles of our system as a hierarchy of classes (\eg, +\inlineocl{Hearer}, \inlineocl{Speaker}, or \inlineocl{Chair}) using +an \emph{inheritance} relation (also called \emph{generalization}). In +particular, \emph{inheritance} establishes a \emph{subtyping} +relationship, \ie, every \inlineocl{Speaker} (\emph{subclass}) is also +a \inlineocl{Hearer} (\emph{superclass}). + +A class does not only describe a set of \emph{instances} (called +\emph{objects}), \ie, record-like data consisting of \emph{attributes} +such as \inlineocl{name} of class \inlineocl{Session}, but also +\emph{operations} defined over them. For example, for the class +\inlineocl{Session}, representing a conference session, we model an +operation \inlineocl{findRole(p:Person):Role} that should return the +role of a \inlineocl{Person} in the context of a specific session; +later, we will describe the behavior of this operation in more detail +using \UML\@. In the following, the term object describes a +(run-time) instance of a class or one of its subclasses. + +Relations between classes (called \emph{associations} in \UML) +can be represented in a class diagram by connecting lines, \eg, +\inlineocl{Participant} and \inlineocl{Session} or \inlineocl{Person} +and \inlineocl{Role}. Associations may be labeled by a particular +constraint called \emph{multiplicity}, \eg, \inlineocl+0..*+ or +\inlineocl+0..1+, which means that in a relation between participants +and sessions, each \inlineocl{Participant} object is associated to at +most one \inlineocl{Session} object, while each \inlineocl{Session} +object may be associated to arbitrarily many \inlineocl{Participant} +objects. Furthermore, associations may be labeled by projection +functions like \inlineocl{person} and \inlineocl{role}; these implicit +function definitions allow for \OCL-expressions like +\inlineocl+self.person+, where \inlineocl+self+ is a variable of the +class \inlineocl{Role}. The expression \inlineocl+self.person+ denotes +persons being related to the specific object \inlineocl{self} of +type role. A particular feature of the \UML are \emph{association + classes} (\inlineocl{Participant} in our example) which represent a +concrete tuple of the relation within a system state as an object; +\ie, associations classes allow also for defining attributes and +operations for such tuples. In a class diagram, association classes +are represented by a dotted line connecting the class with the +association. Associations classes can take part in other associations. +Moreover, \UML supports also $n$-ary associations (not shown in +our example). + +We refine this data model using the Object Constraint Language (\OCL) +for specifying additional invariants, preconditions and postconditions +of operations. For example, we specify that objects of the class +\inlineocl{Person} are uniquely determined by the value of the +\inlineocl{name} attribute and that the attribute \inlineocl{name} is +not equal to the empty string (denoted by \inlineocl{''}): +\begin{ocl} +context Person + inv: name <> '' and + Person::allInstances()->isUnique(p:Person | p.name) +\end{ocl} +Moreover, we specify that every session has exactly one chair by the +following invariant (called \inlineocl{onlyOneChair}) of the class +\inlineocl{Session}: +\begin{ocl} +context Session + inv onlyOneChair: self.participants->one( p:Participant | + p.role.oclIsTypeOf(Chair)) +\end{ocl} +where \inlineocl{p.role.oclIsTypeOf(Chair)} evaluates to true, if +\inlineocl{p.role} is of \emph{dynamic type} +\inlineocl{Chair}. Besides the usual \emph{static types} (\ie, the +types inferred by a static type inference), objects in \UML and other +object-oriented languages have a second \emph{dynamic} type concept. +This is a consequence of a family of \emph{casting functions} (written +$\typeCast{o}{C}$ for an object $o$ into another class type $C$) that +allows for converting the static type of objects along the class +hierarchy. The dynamic type of an object can be understood as its +``initial static type'' and is unchanged by casts. We complete our +example by describing the behavior of the operation +\inlineocl{findRole} as follows: +\begin{ocl} +context Session::findRole(person:Person):Role + pre: self.participates.person->includes(person) + post: result=self.participants->one(p:Participant | + p.person = person ).role + and self.participants = self.participants@pre + and self.name = self.name@pre +\end{ocl} +where in post-conditions, the operator \inlineocl{@pre} allows for +accessing the previous state. Note that: +\begin{ocl} + pre: self.participates.person->includes(person) +\end{ocl} +is actually a syntactic abbreviation for a contraint referring to +the previous state: +\begin{ocl} + self.participates@pre.person@pre->includes(person). +\end{ocl} +Note, further, that conventions for full-\OCL permit the suppression +of the \inlineocl$self$-parameter, following similar syntactic conventions +in other object-oriented languages such as Java: +\begin{ocl} +context Session::findRole(person:Person):Role + pre: participates.person->includes(person) + post: result=participants->one(p:Participant | + p.person = person ).role + and participants = participants@pre + and name = name@pre +\end{ocl} + + +In \UML, classes can contain attributes of the type of the +defining class. Thus, \UML can represent (mutually) recursive +datatypes. Moreover, \OCL introduces also recursively specified +operations. + +A key idea of defining the semantics of \UML and extensions like +SecureUML~\cite{brucker.ea:transformation:2006} is to translate the +diagrammatic \UML features into a combination of more elementary +features of \UML and \OCL +expressions~\cite{gogolla.ea:expressing:2001}. For example, +associations (\ie, relations on objects) can be implemented in +specifications at the design level by aggregations, \ie, collection-valued +class attributes together with \OCL constraints expressing the +multiplicity. Thus, having a semantics for a subset of \UML and \OCL is +tantamount for the foundation of the entire method. +\endisatagafp + + + +\subsection{Formal Foundation} + +\subsubsection{A Gentle Introduction to Isabelle} +Isabelle~\cite{nipkow.ea:isabelle:2002} is a \emph{generic} theorem +prover. New object logics can be introduced by specifying their syntax +and natural deduction inference rules. Among other logics, Isabelle +supports first-order logic, Zermelo-Fraenkel set theory and the +instance for Church's higher-order logic (HOL). + +The core language of Isabelle is a typed $\lambda$-calculus providing +a uniform term language $T$ in which all logical entities where +represented:\footnote{In the Isabelle implementation, there are + actually two further variants which were irrelevant for this + presentation and are therefore omitted.} +\begin{gather*} + T~~ ::=~~ C~~ |~~ V ~~|~~ \lambda~V.~~ T ~~|~~ T~T +\end{gather*} +where: +\begin{itemize} +\item $C$ is the set of \emph{constant symbols} + like "$\operatorname{fst}$" or "$\operatorname{snd}$" as operators on pairs. Note that + Isabelle's syntax engine supports mixfix-notation for terms: + "$(\_ \Longrightarrow \_)~A~B$" or "$(\_ + \_)~A~B$" + can be parsed and printed as + "$A \Longrightarrow B$" or "$A + B$", respectively. +\item $V$ is the set of \emph{variable symbols} like "$x$", "$y$", "$z$", \ldots + Variables standing in the scope of a $\lambda$-operator were called + \emph{bound} variables, all others are \emph{free} variables. +\item "$\lambda~V.~~T$" is called $\lambda$-abstraction. For example, consider the + identity function $\lambda~x. x$. + A $\lambda$-abstraction forms a scope for the variable $V$. +\item $T~T'$ is called an \emph{application}. +\end{itemize} +These concepts are not at all Isabelle specific and can be found in many modern programming +languages ranging from Haskell over Python to Java. + +Terms where associated to \emph{types} by a set of \emph{type + inference rules}\footnote{Similar to +\url{https://en.wikipedia.org/w/index.php?title=Hindley\%E2\%80\%93Milner_type_system&oldid=668548458}}; only +terms for which a type can be inferred---\ie, for \emph{typed + terms}---were considered as legal input to the Isabelle +system. The type-terms $\tau$ for $\lambda$-terms are defined +as:\footnote{Again, the Isabelle implementation is actually slightly + different; our presentation is an abstraction in order to improve + readability.} +\begin{gather} +\tau~~ ::=~~ TV~~ |~~ TV :: \Xi~~ |~~ \tau~\Rightarrow~\tau~~ |~~ (\tau, \ldots, \tau)TC +\end{gather} +\begin{itemize} +\item $TV$ is the set of \emph{type variables} like $'\alpha$, + $'\beta$, \ldots + The syntactic categories $V$ and $TV$ are disjoint; thus, + $'x$ is a perfectly possible type variable. +\item $\Xi$ is a set of \emph{type-classes} like \emph{ord}, + \emph{order}, \emph{linorder}, \ldots + This feature + in the Isabelle type system is inspired by Haskell type classes.\footnote{See \url{https://en.wikipedia.org/w/index.php?title=Type_class&oldid=672053941}.} + A \emph{type class constraint} such as "$\alpha::\operatorname{order}$" expresses that + the type variable $'\alpha$ may range over any type that has the algebraic + structure of a partial ordering (as it is configured in the Isabelle/\HOL library). +\item The type $'\alpha \Rightarrow '\beta$ denotes the total function space from + $'\alpha$ to $'\beta$. +\item $TC$ is a set of \emph{type constructors} like "$('\alpha)\operatorname{list}$" or + "$('\alpha)\operatorname{tree}$". Again, Isabelle's syntax engine supports mixfix-notation + for type terms: cartesian products $'\alpha \times '\beta $ or type sums + $'\alpha + '\beta $ are notations for $('\alpha,'\beta)(\_ \backslash<\operatorname{times}> \_)$ or + $('\alpha,'\beta)(\_ + \_)$, respectively. Also null-ary type-constructors like + $()\operatorname{bool}$,$()\operatorname{nat}$ and $()\operatorname{int}$ are possible; + note that the parentheses of null-ary type constructors are usually omitted. +\end{itemize} + +Isabelle accepts also the notation $t :: \tau$ as type assertion in +the term-language; $t :: \tau$ means "t is required to have type +$\tau$". Note that typed terms \emph{can} contain free variables; +terms like $x + y = y + x$ reflecting common mathematical notation +(and the convention that free variables are implicitly universally +quantified) are possible and common in Isabelle +theories.\footnote{Here, we assume that $\_ + \_$ and $\_ = \_$ are + declared constant symbols having type + $\operatorname{int} \Rightarrow \operatorname{int} \Rightarrow + \operatorname{int}$ + and $'\alpha \Rightarrow '\alpha \Rightarrow \operatorname{bool}$, + respectively.}. + + +An environment providing $\Xi$, $TC$ as well as a map from constant +symbols $C$ to types (built over these $\Xi$ and $TC$) is called a +\emph{global context}; it provides a kind of signature, \ie, a +mechanism to construct the syntactic material of a logical theory. + +The most basic (built-in) global context of Isabelle provides just a +language to construct logical rules. More concretely, it provides a +constant declaration for the (built-in) \emph{meta-level implication} +$\_ \Implies \_$ allowing to form constructs like +$A_1 \Implies \cdots \Implies A_n \Implies A_{n+1}$, which are viewed +as a \emph{rule} of the form ``from assumptions $A_1$ to $A_n$, infer +conclusion $A_{n+1}$'' and which is written in Isabelle syntax as +\begin{gather} + \semantics{A_1 ; \ldots; A_n}\Implies A_{n+1} + \qquad + \text{or, in mathematical notation,} + \quad + \begin{prooftree} + A_1 \qquad \cdots \qquad A_n + \justifies + A_{n+1} + \ptmi{.} + \end{prooftree} +\end{gather} +Moreover, the built-in meta-level quantification $\operatorname{Forall} (\lambda~x.~E~x)$ +(pretty-printed and parsed as $\Forall x\spot E~x$) captures +the usual side-constraints ``$x$ must not occur free in the +assumptions'' for quantifier rules; meta-quantified variables can be +considered as ``fresh'' free variables. Meta-level quantification +leads to a generalization of Horn-clauses of the form: +\begin{gather} +\Forall x_1, \ldots, x_m\spot \semantics{A_1 ; \ldots; A_n}\Implies +A_{n+1}\mi{.} +\end{gather} + +Isabelle supports forward- and backward reasoning on rules. For +backward-reasoning, a \emph{proof-state} can be initialized in a given +global context and further transformed into others. For example, a proof of $\phi$, using +the Isar~\cite{wenzel:isabelleisar:2002} language, will look as +follows in Isabelle: +\begin{gather} + \begin{array}{l} + \Lemma{label} \phi\\ + \quad\apply{case\_tac}\\ + \quad\apply{simp\_all}\\ + \done + \end{array} +\end{gather} +This proof script instructs Isabelle to prove $\phi$ by case +distinction followed by a simplification of the resulting proof state. +Such a proof state is an implicitly conjoint sequence of generalized +Horn-clauses (called \emph{subgoals}) $\phi_1$, \ldots,$\phi_n$ and a +\emph{goal} $\phi$. Proof states were usually denoted by: +\begin{gather} +\begin{array}{rl} +\pglabel{label}:& \phi \\ + 1.& \phi_1 \\ + &\vdots \\ + n.& \phi_n\\ +\end{array} +\end{gather} +Subgoals and goals may be extracted from the proof state into theorems +of the form $\semantics{\phi_1 ; \ldots; \phi_n}\Implies \phi$ at any +time; +% ; this mechanism helps to generate test theorems. +% Further, Isabelle supports meta-variables (written $\meta{x}, \meta{y}, +% \ldots$), which can be seen as ``holes in a term'' that can still be +% substituted. Meta-variables are instantiated by Isabelle's built-in +% higher-order unification. + +By extensions of global contexts with axioms and proofs of theorems, +\emph{theories} can be constructed step by step. Beyond the basic +mechanisms to extend a global context by a type-constructor-, type-class- +constant-definition or an axiom, Isabelle offers a number of +\emph{commands} that allow for more complex extensions of theories in +a logically safe way (avoiding the use of axioms directly). + +\subsubsection{Higher-order Logic (HOL)} +\emph{Higher-order logic} +(HOL)~\cite{church:types:1940,andrews:introduction:2002} is a +classical logic based on a simple type system. Isabelle/\HOL is +a theory extension of the basic Isabelle core-language with +operators and the 7 axioms of HOL; together with large libraries +this constitutes an implementation of HOL. +Isabelle/\HOL provides the usual +logical connectives like $\_ \land \_$, $\_ \implies\_$, $\lnot \_ $ +as well as the object-logical quantifiers $\forall x\spot P\ap x$ and +$\exists x\spot P\ap x$; in contrast to first-order logic, quantifiers +may range over arbitrary types, including total functions +$f\ofType\alpha \Rightarrow \beta$. HOL is centered around +extensional equality $\_ = \_ \ofType \alpha \Rightarrow \alpha +\Rightarrow \text{bool}$. Extensional equality means that two functions $f$ and $g$ +are equal if and only if they are point-wise equal; this is captured by the rule: +$(\Forall~x\spot f~x = g~x) \Longrightarrow f = g$. +HOL is more expressive than first-order +logic, since, among many other things, induction schemes can be expressed inside the +logic. For example, the standard induction rule on natural numbers in HOL: +\begin{gather*} + P~0 \Longrightarrow (\Forall~x\spot P~x \Longrightarrow P~(x+1)) \Longrightarrow P~x +\end{gather*} +is just an ordinary rule in Isabelle which is in fact a proven theorem +in the theory of natural numbers. This example exemplifies an important +design principle of Isabelle: theorems and rules are technically the +same, paving the way to \emph{derived rules} and automated +decision procedures based on them. This has the consequence that +that these procedures are consequently sound by construction +with respect to their logical aspects (they may be incomplete +or failing, though). + +On the other hand, Isabelle/\HOL can also be viewed as a functional programming language +like SML or Haskell. Isabelle/\HOL definitions can usually be +read just as another functional \textbf{programming} language; +if not interested in proofs and the possibilities of a +\textbf{specification} language providing +powerful logical quantifiers or equivalent free variables, +the reader can just ignore these aspects in theories. + +%Isabelle/HOL is a logical embedding of HOL into Isabelle. The +%(original) simple-type system underlying HOL has been extended by +%Hindley-Milner style polymorphism with type-classes similar to +%Haskell. +%While Isabelle/HOL is usually seen as proof assistant, we +%use it as symbolic computation environment. Implementations on top of +%Isabelle/HOL can re-use existing powerful deduction mechanisms such as +%higher-order resolution, tableaux-based reasoners, rewriting +%procedures, Presburger arithmetic, and via various integration +%mechanisms, also external provers such as +%Vampire~\cite{riazanov.ea:vampire:1999} and the SMT-solver +%Z3~\cite{moura.ea:z3:2008}. + +Isabelle/\HOL offers support for a particular methodology to extend +given theories in a logically safe way: A theory-extension is +\emph{conservative} if the extended theory is consistent provided that +the original theory was consistent. Conservative extensions can be +\emph{constant definitions}, \emph{type definitions}, \emph{datatype + definitions}, \emph{primitive recursive definitions} and +\emph{well founded recursive definitions}. + +For instance, the library includes the type constructor $\up{\tau} := +\isasymbottom ~ | ~ \lift{\_} : \alpha$ that assigns to each type +$\tau$ a type $\up{\tau}$ \emph{disjointly extended} by the +exceptional element $\isasymbottom$. The function $\drop{\_} : +\up{\alpha} \to \alpha$ is the inverse of $\lift{\_}$ (unspecified for +$\isasymbottom$). Partial functions $\alpha \isasymrightharpoonup +\beta$ are defined as functions $\alpha \isasymRightarrow \up{\beta}$ +supporting the usual concepts of domain ($\dom\;\_$) and range +($\ran\;\_$). + +As another example of a conservative extension, typed sets were built +in the Isabelle libraries conservatively on top of the kernel of HOL +as functions to $\HolBoolean$; consequently, the constant definitions +for membership is as follows:\footnote{To increase readability, we use + a slightly simplified presentation.} +\begin{gather} + \begin{array}{lrll} + \types& \alpha \HolSet &= \alpha \Rightarrow \HolBoolean\\[.5ex] + \isardef &\operatorname{Collect}&\ofType (\alpha \Rightarrow + \HolBoolean) \Rightarrow \HolSet{\alpha} &\qquad\text{--- set comprehension}\\ + \where &\operatorname{Collect}\ap S &\equiv S\\[.5ex] + \isardef &\operatorname{member} &\ofType \alpha \Rightarrow + \alpha \Rightarrow \HolBoolean &\qquad\text{--- + membership test}\\ + \where &\operatorname{member}\ap s\ap S &\equiv S s\\ + \end{array} +\end{gather} +Isabelle's syntax engine is instructed to accept the notation +$\{x \mid P\}$ for $\operatorname{Collect}\ap\lambda x\spot P$ and the +notation $s \in S$ for $\operatorname{member}\ap s\ap S$. As can be +inferred from the example, constant definitions are axioms that +introduce a fresh constant symbol by some non-recursive expressions not +containing free variables; this type of axiom is logically safe since it works +like an abbreviation. The syntactic side conditions of this axiom are +mechanically checked. It is straightforward to express the +usual operations on sets like $\_ \cup \_, +\_\cap\_\ofType\HolSet{\alpha} \Rightarrow \HolSet{\alpha} \Rightarrow +\HolSet{\alpha}$ as conservative extensions, too, while the rules of +typed set theory were derived by proofs from these definitions. + +Similarly, a logical compiler is invoked for the following statements +introducing the types option and list: +\begin{gather} + \begin{array}{lrll} + \datatype & \HolOption &= \HolNone \mid \HolSome{\alpha}\\[.5ex] + \datatype & \HolList{\alpha} &= \operatorname{Nil} \mid + \operatorname{Cons}\ap a\ap l + \end{array} +\end{gather} +Here, $[]$ or $a\#l$ are an alternative syntax for $\operatorname{Nil}$ +or $\operatorname{Cons}\ap a ~l$; moreover, $[a, b, c]$ is defined as +alternative syntax for $a\#b\#c\#[]$. These (recursive) statements +were internally represented in by internal type and constant +definitions. Besides the \emph{constructors} $\HolNone$, $\HolSome$, +$[]$ and $\operatorname{Cons}$, there is the match operation +\begin{gather} +\HolCase\ap x\ap\HolOf~\HolNone \isasymRightarrow F\ap \mid +\HolSome{a} \isasymRightarrow G\ap a +\end{gather} +respectively +\begin{gather} +\HolCase\ap x\ap\HolOf~[] \isasymRightarrow F\ap \mid \operatorname{Cons}\ap a\ap +r \isasymRightarrow G\ap a\ap r\mi{.} +\end{gather} +From the internal definitions (not shown here) several properties were +automatically derived. We show only the case for lists: +\begin{gather}\label{eq:datatype-rules} + \begin{array}{ll} + (\HolCase\ap[]\ap\HolOf\ap[] \Rightarrow F \ap | \ap (a\#r) \Rightarrow + G\ap a\ap r) = F &\\ + (\HolCase \ap b\#t \ap \HolOf \ap [] \Rightarrow F \ap | \ap + (a\#r) \Rightarrow G\ap a\ap r) = G~b~t &\\ % + \mbox{}[] \neq a\#t &\text{-- distinctness} \\ + \semantics{a = [] \implies P ; \exists~x~t\spot a = x\#t \implies P } \Longrightarrow P &\text{-- exhaust} \\ + \semantics{P~[] ; \forall~at\spot P~t \implies P (a\#t) } \Longrightarrow P~x &\text{-- induct} + \end{array} +\end{gather} +Finally, there is a compiler for primitive and well founded recursive +function definitions. For example, we may define the +$\operatorname{sort}$ operation on linearly ordered lists by: +\begin{gather}\label{eq:sortdef} + \begin{array}{lll} + \fun + &\enspace\operatorname{ins} & \ofType + [\alpha\ofType\mathrm{linorder}, \HolList{\alpha}] + \Rightarrow + \HolList{\alpha}\\ + \where + &\enspace \operatorname{ins}\ap x \ap [\;] &= [x]\\ + &\enspace \operatorname{ins}\ap x \ap (y\#\mathit{ys})&= + \HolIf x < y + \HolThen x\# y \# ys + \HolElse y\#(\operatorname{ins} \ap x \ap ys) + \end{array}\\ + \begin{array}{lll} + \fun + &\enspace\operatorname{sort} & \ofType + \HolList{(\alpha\ofType\mathrm{linorder})} + \Rightarrow + \HolList{\alpha}\\ + \where + &\enspace \operatorname{sort}\ap [\;] &= [\;]\\ + &\enspace \operatorname{sort} (x\#\mathit{xs})&= + \operatorname{ins}\ap x\ap (\operatorname{sort}\ap xs) + \end{array} +\end{gather} +The internal (non-recursive) constant definition for these operations +is quite involved; however, the logical compiler will finally derive +all the equations in the statements above from this definition and +make them available for automated simplification. + +Thus, Isabelle/\HOL also provides a large collection of theories like +sets, lists, orderings, and various arithmetic theories +which only contain rules derived from conservative definitions. +This library constitutes a comfortable basis for defining the OCL +library and language constructs. + +In particular, Isabelle manages a set of \emph{executable types and + operators}, \ie, types and operators for which a compilation to +SML, OCaml or Haskell is possible. Setups for arithmetic types +such as $\text{int}$ have been done; moreover any datatype and any +recursive function were included in this executable set (providing +that they only consist of executable operators). This forms the +basis that many OCL terms can be executed directly. +Using the value command, it is possible to compile many OCL ground expressions +(no free variables) to code and to execute them; for example +\inlineisar$value "3 + 7"$ just answers with \inlineisar$10$ in Isabelle's +output window. This is even true for many expressions containing types which +in themselves are not executable. For example, the Set type, which is +defined in Featherweight OCL as the type of potentially infinite sets, +is consequently not in itself executable; however, due to special setups +of the code-generator, expressions like \inlineisar$value "Set{1,2}"$ are, +because the underlying constructors in this expression allow for automatically +establishing that this set is finite and reducible to constructs that \emph{are} +in this special case executable. + + +% Similarly, Isabelle +%manages a large set of (higher-order) rewrite rules into which +%recursive function definitions were included. Provided that this +%rule set represents a terminating and confluent rewrite system, the +%Isabelle simplifier provides also a highly potent decision procedure +%for many fragments of theories underlying the constraints to be +% processed when constructing test theorems. + +\subsection{How this Annex A was Generated from Isabelle/HOL Theories} +\begin{figure*}[tb] + \mbox{}\hfill + \subfloat% + [The Isabelle jEdit environment. ]% + {\label{fig:jedit} \includegraphics[height=6.2cm]{jedit}}% + \hfill% + \hfill% + \subfloat[The generated formal document.]% + {\label{fig:pdf} \includegraphics[height=6.2cm]{pdf}} + \hfill\mbox{} + \caption{Generating documents with guaranteed syntactical and + semantical consistency.} + \label{fig:gener-docum-where} +\end{figure*} +Isabelle, as a framework for building formal +tools~\cite{wenzel.ea:building:2007}, provides the means for +generating \emph{formal documents}. With formal documents (such as +the one you are currently reading) we refer to documents that are +machine-generated and ensure certain formal guarantees. In particular, +all formal content (\eg, definitions, formulae, types) are checked for +consistency during the document generation. + +For writing documents, Isabelle supports the embedding of informal +texts using a \LaTeX-based markup language within the theory files. To +ensure the consistency, Isabelle supports to use, within these +informal texts, \emph{antiquotations} that refer to the formal parts +and that are checked while generating the actual document as +PDF\@. For example, in an informal text, the antiquotation +\inlineisar|@{$\text{thm}$ "not_not"}| will instruct Isabelle to +lock-up the (formally proven) theorem of name \inlineisar"ocl_not_not" +and to replace the antiquotation with the actual theorem, \ie, +\inlineocl{not (not x) $=$ x}. + +\autoref{fig:gener-docum-where} +illustrates this approach: \autoref{fig:jedit} shows the jEdit-based +development environment of Isabelle with an excerpt of one of the core +theories of \FOCL\@. \autoref{fig:pdf} shows the generated +PDF document where all antiquotations are replaced. Moreover, +the document generation tools allows for defining syntactic sugar as +well as skipping technical details of the formalization. + +\isatagannexa +Thus, applying the \FOCL approach to writing an updated +Annex A that provides a formal semantics of the most fundamental +concepts of \OCL ensures +\begin{enumerate} +\item that all formal context is syntactically correct and well-typed, + and +\item all formal definitions and the derived logical rules are + semantically consistent. +\end{enumerate} +% Overall, this would contribute to one of the main goals of the \OCL 2.5 +% RFP, as discussed at the \OCL meeting in +% Aachen~\cite{brucker.ea:summary-aachen:2013}. +\endisatagannexa +\isatagafp +Featherweight OCL is a formalization of the core of OCL +aiming at formally investigating the relationship between the +various concepts. At present, it does not attempt to define the complete +OCL library. Instead, it concentrates on the core concepts of +OCL as well as the types \inlineocl{Boolean}, +\inlineocl{Integer}, and typed sets (\inlineocl|Set(T)|). Following +the tradition of +HOL-OCL~\cite{brucker.ea:hol-ocl:2008,brucker.ea:hol-ocl-book:2006}, +Featherweight OCL is based on the following principles: +\begin{enumerate} +\item It is an embedding into a powerful semantic meta-language and + environment, namely + Isabelle/HOL~\cite{nipkow.ea:isabelle:2002}. +\item It is a \emph{shallow embedding} in HOL; types + in OCL were injectively mapped to types in Featherweight + OCL\@. Ill-typed OCL specifications cannot be represented in + Featherweight OCL and a type in Featherweight OCL contains exactly + the values that are possible in OCL\@. Thus, sets may contain + \inlineocl{null} (\inlineocl|Set{null}| is a defined set) but not + \inlineocl{invalid} (\inlineocl|Set{invalid}| is just + \inlineocl{invalid}). +\item Any Featherweight OCL type contains at least + \inlineocl{invalid} and \inlineocl{null} (the type \inlineocl{Void} + contains only these instances). The logic is consequently + four-valued, and there is a \inlineocl{null}-element in the type + \inlineocl{Set(A)}. +\item It is a strongly typed language in the Hindley-Milner tradition. + We assume that a pre-process eliminates all implicit conversions due + to sub-typing by introducing explicit casts (\eg, + \inlineocl{oclAsType()}). The details of such a pre-processing are + described in~\cite{brucker:interactive:2007}. Casts are semantic + functions, typically injections, that may convert data between the + different Featherweight OCL types. +\item All objects are represented in an object universe in the HOL-OCL + tradition~\cite{brucker.ea:extensible:2008-b}. The universe + construction also gives semantics to type casts, dynamic type + tests, as well as functions such as \inlineocl{oclAllInstances()}, + or \inlineocl{oclIsNew()}. +\item Featherweight OCL types may be arbitrarily nested. For example, + the expression + \inlineocl|Set{Set{1,2}} = Set{Set{2,1}}| is legal and true. +\item For demonstration purposes, the set type in Featherweight OCL + may be infinite, allowing infinite quantification and a constant + that contains the set of all Integers. Arithmetic laws like + commutativity may therefore be expressed in OCL itself. The + iterator is only defined on finite sets. +\item It supports equational reasoning and congruence reasoning, but + this requires a differentiation of the different equalities like + strict equality, strong equality, meta-equality (HOL). Strict + equality and strong equality require a sub-calculus, ``cp'' (a + detailed discussion of the different equalities as well as the + sub-calculus ``cp''---for three-valued OCL 2.0---is given + in~\cite{brucker.ea:semantics:2009}), which is nasty but can be + hidden from the user inside tools. +\end{enumerate} +Overall, this would contribute to one of the main goals of the \OCL 2.5 +RFP, as discussed at the \OCL meeting in +Aachen~\cite{brucker.ea:summary-aachen:2013}. +\endisatagafp + + +\section{The Essence of UML-OCL Semantics} +\subsection{The Theory Organization} +The semantic theory is organized in a quite conventional manner in +three layers. The first layer, called the \emph{denotational + semantics} comprises a set of definitions of the operators of the +language. Presented as \emph{definitional axioms} inside +Isabelle/\HOL, this part assures the logically consistency of the +overall construction. The denotational definitions of types, constants +and operations, and \OCL contracts represent the ``gold standard'' of the +semantics. The second layer, called \emph{logical layer}, +is derived from the former and centered around the notion of validity +of an \OCL formula $P$. For a state-transition from pre-state $\sigma$ +to post-state $\sigma'$, a validity statement is written $(\sigma, +\sigma') \isasymMathOclValid P$. Its major purpose is to logically establish facts +(lemmas and theorems) about the denotational definitions. +The third layer, called \emph{algebraic layer}, +also derived from the former layers, tries to establish algebraic laws +of the form $P = P'$; such laws are amenable to equational reasoning +and also help for automated reasoning and code-generation. For an +implementor of an \OCL compiler, these consequences are of most interest. + +For space reasons, we will restrict ourselves in this document to a few +operators and make a traversal through all three layers to give a +high-level description of our formalization. Especially, the details +of the semantic construction for sets and the handling of objects and +object universes were excluded from a presentation here. + +\subsection{Denotational Semantics of Types} +The syntactic material for type expressions, called $\text{TYPES}(C)$, is +inductively defined as follows: +\begin{itemize} +\item $C \subseteq \text{TYPES}(C)$ +\item $\text{Boolean}$, $\text{Integer}$, $\text{Real}$, $\text{Void}$, \ldots + are elements of $\text{TYPES}(C)$ +\item $\text{Set}(X)$, $\text{Bag}(X)$, $\text{Sequence}(X)$, and + $\text{Pair}(X,Y)$ (as example for a Tuple-type) + are in $\text{TYPES}(C)$ (if $X, Y \in \text{TYPES}(C)$). +\end{itemize} + +Types were directly represented in \FOCL by types in \HOL; consequently, +any \FOCL type must provide elements for a bottom element (also denoted $\bot$) +and a null element; this is enforced in Isabelle by a type-class $\TCnull$ that +contains two distinguishable elements $\HolBot$ and $\HolNull$ +(see \autoref{sec:focl-types} for the details of the construction). + +Moreover, the representation mapping from \OCL types to \FOCL is +one-to-one (\ie, injective), and the corresponding \FOCL types were +constructed to represent \emph{exactly} the elements (``no junk, no confusion + elements'') of their \OCL counterparts. The corresponding \FOCL types were +constructed in two stages: First, a \emph{base type} is constructed whose +carrier set contains exactly the elements of the \OCL type. Secondly, this +base type is lifted to a \emph{valuation} type that we use for type-checking +\FOCL constants, operations, and expressions. The valuation type takes into account +that some \UML-\OCL functions of its \OCL type (namely: accessors in path-expressions) +depend on a pre- and a post-state. + +For most base types like $\text{Boolean}_{\text{base}}$ or +$\text{Integer}_{\text{base}}$, it suffices to double-lift a \HOL library type: +\begin{equation} +\typesynonym \qquad \text{Boolean}_{\text{base}} \defeq \up{{\up{bool}}} +\end{equation} +As a consequence of this definition of the type, we have the elements +$\isasymbottom, \lift{\isasymbottom}, \lift{\lift{\HolTrue}}, +\lift{\lift{\HolFalse}}$ in the carrier-set of $\text{Boolean}_{\text{base}}$. +We can therefore use the element$\isasymbottom$ to define the generic type +class element $\bot$ and $\lift{\bot}$ for the generic type class $\HolNull$. +For collection types and object types this definition +is more evolved (see \autoref{sec:focl-types}). + +For object base types, we assume a typed universe $\isaAA$ of objects to be +discussed later, for the moment we will refer it by its polymorphic variable. + +With respect the valuation types for \OCL expression in general and Boolean +expressions in particular, they depend on the pair $(\sigma, \sigma')$ of +pre-and post-state. Thus, we define valuation types by the synonym: +\begin{equation} +\typesynonym \qquad \V{\isaAA}{\alpha} \defeq \state{\isaAA} \times + \state{\isaAA} \to \alpha \ofType \TCnull \mi{.} +\end{equation} +The valuation type for boolean,integer, etc. \OCL terms is therefore defined as: +\begin{gather*} +\typesynonym \qquad \text{Boolean}_{\isaAA} \defeq \V{\isaAA}{\text{Boolean}_{\text{base}}} \\ +\typesynonym \qquad \text{Integer}_{\isaAA} \defeq \V{\isaAA}{\text{Integer}_{\text{base}}} \\ +\ldots +\end{gather*} +the other cases are analogous. In the subsequent subsections, we will drop the +index $\isaAA$ since it is constant in all formulas and expressions except for +operations related to the object universe construction in \autoref{sec:universe} + +The rules of the logical layer (there are no algebraic rules related to the +semantics of types), and more details can be found in \autoref{sec:focl-types}. + +\subsection{Denotational Semantics of Constants and Operations} +We use the notation $I\semantics{E}\tau$ for the semantic interpretation +function as commonly used in mathematical textbooks and the variable $\tau$ +standing for pairs of pre- and post state $(\sigma, \sigma')$. Note that we will +also use $\tau$ to denote the \emph{type} of a state-pair; since both syntactic +categories are independent, we can do so without arising confusion. \OCL +provides for all \OCL types the constants \mocl{invalid} for the exceptional +computation result and \mocl{null} for the non-existing value. Thus we define: +\begin{gather*} +\begin{alignedat}{3} +I\semantics{\mocl{invalid}\ofType V(\alpha)} \tau &\equiv \HolBot & +\qquad I\semantics{\mocl{null}\ofType V(\alpha)} \tau &\equiv \HolNull\\ +\end{alignedat} +\end{gather*} +For the concrete \mocl{Boolean}-type, we define similarly the boolean constants +$\mocl{true}$ and $\mocl{false}$ as well as the fundamental tests for definedness +and validity (generically defined for all types): +\begin{gather*} +\begin{alignedat}{3} +I\semantics{\mocl{true}\ofType\mocl{Boolean}} \tau &= \lift{\lift{\HolTrue}} & +\qquad I\semantics{\mocl{false}} \tau &= \lift{\lift{\HolFalse}}\\ +\end{alignedat}\\ +I\semantics{X\mocl{.oclIsUndefined()}} \tau = + (\HolIf I\semantics{X}\tau \in \{\HolBot, \HolNull\} \HolThen I\semantics{\mocl{true}}\tau \HolElse I\semantics{\mocl{false}}\tau)\\ + I\semantics{X\mocl{.oclIsInvalid()}} \tau = + (\HolIf I\semantics{X}\tau = \HolBot \HolThen I\semantics{\mocl{true}}\tau \HolElse I\semantics{\mocl{false}}\tau) +\end{gather*} + +For reasons of conciseness, we will write $\delta~X$ for +$\mocl{not}(X\mocl{.oclIsUndefined())}$ and $\upsilon~X$ for +$\mocl{not}(X\mocl{.oclIsInvalid())}$ throughout this document. + +Due to the used style of semantic representation (a shallow embedding) $I$ is +in fact superfluous and defined semantically as the identity $\lambda x.~x$; +instead of: +\begin{gather*} +I\semantics{\mocl{true}\ofType\mocl{Boolean}} \tau = \lift{\lift{\HolTrue}} +\shortintertext{we can therefore write:} +\mocl{true}\ofType\mocl{Boolean} = \lambda \tau. \lift{\lift{\HolTrue}} +\end{gather*} +In Isabelle theories, this particular presentation of definitions +paves the way for an automatic check that the underlying equation +has the form of an \emph{axiomatic definition} and is therefore logically safe. + +\isatagannexa +Since all operators of the assertion language depend on the context +$\tau$ = $(\sigma, \sigma')$ and result in values that can be $\isasymbottom$, +all expressions can be viewed as \emph{evaluations} from $(\sigma, \sigma')$ to +a type $\alpha$ which must posses a $\bottom$ and a $\text{null}$-element. Given +that such constraints can be expressed in Isabelle/HOL via \emph{type classes} +(written: $\alpha::\kappa$), all types for OCL-expressions are of a form captured +by +\begin{equation*} + \V{}{\alpha} \defeq \state{} \times \state{} \to \alpha::\{bot,null\} \mi{,} + \end{equation*} +where $\state{}$ stands for the system state and $\state{} \times +\state{}$ describes the pair of pre-state and post-state and +$\_\defeq\_$ denotes the type abbreviation. + +Previous versions of the OCL semantics~\cite[Annex A]{omg:ocl:2003} used different +interpretation functions for invariants and pre-conditions; we achieve +their semantic effect by a syntactic transformation $\__\text{pre}$ +which replaces, for example, all accessor functions +$\getAttrib{\_}{a}$ by their counterparts +$\getAttrib{\_}{a\isasymOclATpre}$ (see \autoref{sec:invlogic}). For example, +$(\getAttrib{\self}{a} > 5)_\text{pre}$ is just +$(\getAttrib{\self}{a\isasymOclATpre} > 5)$. This way, also invariants +and pre-conditions can be interpreted by the same interpretation +function and have the same type of an evaluation $\V{}{\alpha}$. +\endisatagannexa + +On this basis, one can define the core logical operators $\mocl{not}$ +and $\mocl{and}$ as follows: +\begin{gather*} + \begin{array}{ll} + I\semantics{\mocl{not}\; X} \tau + &= (\HolCase I\semantics{X} \tau \HolOf\\ + &\quad\begin{array}{ll} + ~ \bottom &\Rightarrow \bottom \\ + | \lfloor \bottom \rfloor &\Rightarrow \lfloor \bottom \rfloor \\ + | \lfloor \lfloor x \rfloor \rfloor &\Rightarrow \lfloor \lfloor \lnot x \rfloor \rfloor ) + \end{array} + \end{array} +\end{gather*} +\begin{gather*} + \begin{array}{ll} + I\semantics{X\;\mocl{and}\; Y} \tau + &= (\HolCase I\semantics{X} \tau \HolOf\\ + &\quad\begin{array}{ll} + ~ \bottom &\Rightarrow + (\HolCase I\semantics{Y} \tau \HolOf\\ + &\quad\begin{array}{ll} + ~ \bottom &\Rightarrow \bottom \\ + | \lfloor \bottom \rfloor &\Rightarrow \bottom \\ + | \lfloor \lfloor \HolTrue \rfloor \rfloor + &\Rightarrow \bottom\\ + | \lfloor \lfloor \HolFalse \rfloor \rfloor + &\Rightarrow \lfloor \lfloor \HolFalse \rfloor \rfloor )\\ + \end{array} + \\ + | \lfloor \bottom \rfloor &\Rightarrow + (\HolCase I\semantics{Y} \tau \HolOf\\ + &\quad\begin{array}{ll} + ~ \bottom &\Rightarrow + \bottom \\ + | \lfloor \bottom \rfloor &\Rightarrow \lfloor + \bottom \rfloor \\ + | \lfloor \lfloor \HolTrue \rfloor \rfloor + &\Rightarrow \lfloor \bottom\rfloor\\ + | \lfloor \lfloor \HolFalse \rfloor \rfloor + &\Rightarrow \lfloor \lfloor \HolFalse \rfloor \rfloor )\\ + \end{array} + \\ + | \lfloor \lfloor \HolTrue \rfloor \rfloor &\Rightarrow + (\HolCase I\semantics{Y} \tau \HolOf\\ + &\quad\begin{array}{ll} + ~ \bottom &\Rightarrow + \bottom \\ + | \lfloor \bottom \rfloor &\Rightarrow \lfloor + \bottom \rfloor \\ + | \lfloor \lfloor y \rfloor \rfloor + &\Rightarrow \lfloor \lfloor y \rfloor \rfloor )\\ + \end{array} + \\ + | \lfloor \lfloor \HolFalse \rfloor \rfloor + &\Rightarrow \lfloor \lfloor \HolFalse \rfloor + \rfloor )\\ + \end{array}\\ +\end{array} +\end{gather*} +These non-strict operations were used to define the other logical connectives in +the usual classical way: $X\; \mocl{or}\; Y \equiv (\mocl{not}\; X)\; +\mocl{and}\; (\mocl{not}\; Y)$ or +$X\;\mocl{implies}\;Y \equiv (\mocl{not}\; X)\;\mocl{or}\; Y$. + +The default semantics for an \OCL library operator is strict +semantics; this means that the result of an operation $f$ is +\inlineisar+invalid+ if one of its arguments is \mocl+invalid+ or \mocl+null+. +The definition of the addition for integers as default variant reads as follows: +\begin{gather*} + \begin{array}{rl} + I\semantics{x \;\mocl{+}\; y}\tau = &\HolIf I\semantics{\delta ~ x}\tau =I\semantics{\mocl{true}}\tau + \land I\semantics{\delta ~ y}\tau =I\semantics{\mocl{true}}\tau \\ + &\HolThen \lfloor \lfloor \lceil \lceil I\semantics{x}\tau \rceil \rceil + \lceil \lceil I\semantics{y}\tau \rceil \rceil \rfloor \rfloor\\ + &\HolElse \bottom + \end{array} +\end{gather*} +where the operator ``\mocl{+}'' on the left-hand +side of the equation denotes the \OCL addition of type +$\mocl{Integer} \Rightarrow \mocl{Integer} \Rightarrow \mocl{Integer}$ while +the ``$+$'' on the right-hand side of the equation of type +$[\HolInteger,\HolInteger]\Rightarrow \HolInteger$ denotes the integer-addition +from the HOL library. + +\subsection{Logical Layer} +The topmost goal of the logic for OCL is to define the \emph{validity statement}: +\begin{equation*} + (\sigma, \sigma') \isasymMathOclValid P\mi{,} +\end{equation*} +where $\sigma$ is the pre-state and $\sigma'$ the post-state of the +underlying system and $P$ is a formula, \ie, and \OCL expression of type \mocl{Boolean}. +Informally, a formula $P$ is valid if and only if its evaluation in +$(\sigma, \sigma')$ (\ie, $\tau$ for short) yields true. Formally this means: +\begin{equation*} +\tau \isasymMathOclValid P \equiv \bigl(I\semantics{P} \tau = \lift{\lift{\HolTrue }} \bigr)\mi{.} +\end{equation*} +On this basis, classical, two-valued inference rules can be established for +reasoning over the logical connectives, the different notions of equality, +definedness and validity. Generally speaking, rules over logical validity can +relate bits and pieces in various \OCL terms and allow---via strong +logical equality discussed below---the replacement +of semantically equivalent sub-expressions. The core inference rules are: +\begin{gather*} +\begin{array}{lccr} + \tau \isasymMathOclValid \mocl{true} &\quad + \lnot(\tau \isasymMathOclValid \mocl{false})&\quad + \lnot(\tau \isasymMathOclValid \mocl{invalid})&\quad + \lnot(\tau \isasymMathOclValid \mocl{null}) +\end{array}\\ + \tau \isasymMathOclValid \mocl{not}\; P \Longrightarrow \lnot (\tau \isasymMathOclValid P)\\ +\begin{array}{lcr} + \tau \isasymMathOclValid P \;\mocl{and}\; Q \Longrightarrow \tau \isasymMathOclValid P&\qquad& + \tau \isasymMathOclValid P \;\mocl{and}\; Q \Longrightarrow \tau \isasymMathOclValid Q \\ + \tau \isasymMathOclValid P \Longrightarrow \tau \isasymMathOclValid P \;\mocl{or}\; Q &\qquad& + \tau \isasymMathOclValid Q \tau \Longrightarrow \isasymMathOclValid P \;\mocl{or}\; Q \\ +\end{array}\\ + \tau \isasymMathOclValid P \Longrightarrow + (\mocl{if}\; P \;\mocl{then}\; B_1 \;\mocl{else}\; B_2 \;\mocl{endif})\tau = B_1\ap \tau\\ + \tau \isasymMathOclValid \mocl{not}\; P \Longrightarrow + (\mocl{if}\; P \;\mocl{then}\; B_1 \;\mocl{else}\; B_2 \;\mocl{endif})\tau = B_2\ap \tau\\ +\begin{array}[lcr]{lcr} + \tau \isasymMathOclValid P \Longrightarrow \tau \isasymMathOclValid \delta \ap P &\qquad& + \tau \isasymMathOclValid \delta \ap X \Longrightarrow \tau \isasymMathOclValid \upsilon \ap X +\end{array} +\end{gather*} + +By the latter two properties it can be inferred that any valid +property $P$ (so for example: a valid invariant) is defined, which +allows to infer for terms composed by strict operations that their +arguments and finally the variables occurring in it are valid or +defined. + +The mandatory part of the \OCL standard refers to an equality +(written \mocl{x = y} or \mocl{x <> y} for its negation), which is +intended to be a strict operation (thus: \mocl{invalid = y} evaluates + to \mocl{invalid}) and which uses the references of objects in a state +when comparing objects, similarly to C++ or Java. In order to avoid +confusions, we will use the following notations for equality: +\begin{enumerate} +\item The symbol $\_ = \_$ remains to be reserved to the \HOL equality, + \ie, the equality of our semantic meta-language, +\item The symbol $\_ \isasymMathOclStrongEq \_$ will be used for + the \emph{strong logical equality}, which follows the general + logical principle that ``equals can be replaced by equals,''\footnote{Strong logical equality is also referred as ``Leibniz''-equality.} + and is at the heart of the \OCL logic, +\item The symbol $\_ \isasymMathOclStrictEq \_$ is used for the + strict referential equality, \ie, the equality the mandatory part + of the \OCL standard refers to by the \mocl{_ = _}- symbol. +\end{enumerate} + +The strong logical equality is a polymorphic +concept which is defined using polymorphism for all \OCL types by: +\begin{gather*} + I\semantics{X \triangleq Y} \tau \equiv + \lift {\lift{I\semantics{X} \tau = I\semantics{Y} \tau }} +\shortintertext{It enjoys nearly the laws of a congruence:} +\tau \isasymMathOclValid (x \triangleq x)\\ +\tau \isasymMathOclValid (x \triangleq y) \Longrightarrow \tau \isasymMathOclValid (y \triangleq x)\\ +\tau \isasymMathOclValid (x \triangleq y) \Longrightarrow \tau \isasymMathOclValid (y \triangleq z) \Longrightarrow \tau \isasymMathOclValid (x \triangleq z)\\ +\HolOclCp P \Longrightarrow \tau \isasymMathOclValid (x \triangleq y) \Longrightarrow \tau \isasymMathOclValid (P\ap x) \Longrightarrow \tau \isasymMathOclValid (P\ap y) +\end{gather*} +where the predicate $\HolOclCp$ stands for \emph{context-passing}, a +property that is true for all pure \OCL expressions (but not +arbitrary mixtures of \OCL and HOL) in \FOCL\@. The +necessary side-calculus for establishing $\HolOclCp$ can be fully +automated; the reader interested in the details is referred to +\autoref{sec:equality}. + +The strong logical equality of \FOCL give rise to a number +of further rules and derived properties, that clarify the role of strong +logical equality and the Boolean constants in \OCL specifications: +\begin{gather*} +\tau \isasymMathOclValid \delta \ap x \lor \tau \isasymMathOclValid x \triangleq \mocl{invalid} \lor \tau \isasymMathOclValid x \triangleq \mocl{null} \mi{,}\\ +(\tau \isasymMathOclValid A \triangleq \mocl{invalid}) = (\tau \isasymMathOclValid \mocl{not} (\upsilon A))\\ +% (* foundation15 *) +\begin{multlined} + (\tau \isasymMathOclValid A \triangleq \mocl{true}) = (\tau \isasymMathOclValid A) \qquad + (\tau \isasymMathOclValid A \triangleq \mocl{false}) = (\tau \isasymMathOclValid \mocl{not} A) \\ + (\tau \isasymMathOclValid \mocl{not} (\delta x)) = (\lnot \tau \isasymMathOclValid \delta x) \qquad + (\tau \isasymMathOclValid \mocl{not} (\upsilon x)) = (\lnot \tau \isasymMathOclValid \upsilon x) % (* UML_Logic.foundation7':*) +\end{multlined} +\end{gather*} +% (not A \ not B) = (A \ B) (*foundation21*) + +The logical layer of the \FOCL rules gives also a means +to convert an \OCL formula living in its four-valued world into a +representation that is classically two-valued and can be processed by +standard SMT solvers such as CVC3~\cite{barrett.ea:cvc3:2007} or +Z3~\cite{moura.ea:z3:2008}. $\delta$-closure rules for all logical +connectives have the following format, \eg: +\begin{gather*} +\tau \isasymMathOclValid \delta \ap x \Longrightarrow (\tau \isasymMathOclValid \ap\mocl{not}\ap x) = (\lnot (\tau \isasymMathOclValid x))\\ +\tau \isasymMathOclValid \delta \ap x \Longrightarrow \tau \isasymMathOclValid \delta \ap y \Longrightarrow (\tau \isasymMathOclValid x \ap\mocl{and}\ap y) = ( \tau \isasymMathOclValid x \land \tau \isasymMathOclValid y)\\ +\begin{multlined} +\tau \isasymMathOclValid \delta \ap x \Longrightarrow \tau \isasymMathOclValid \delta \ap y \\ +\Longrightarrow (\tau \isasymMathOclValid (x \ap\mocl{implies}\ap y)) = ( (\tau \isasymMathOclValid x) \longrightarrow (\tau \isasymMathOclValid y)) +\end{multlined} +\end{gather*} +Together with the already mentioned general case-distinction +\begin{gather*} +\tau \isasymMathOclValid \delta \ap x \lor \tau \isasymMathOclValid x \triangleq \mocl{invalid} \lor \tau \isasymMathOclValid x \triangleq \mocl{null} +\end{gather*} +which is possible for any \OCL type, a case distinction on the +variables in a formula can be performed; due to strictness rules, +formulae containing somewhere a variable $x$ that is known to be +$\mocl{invalid}$ or $\mocl{null}$ reduce usually quickly to +contradictions. For example, we can infer from an invariant $\tau +\isasymMathOclValid x \isasymMathOclStrictEq y \;\mocl{-}\; \mocl{3}$ +that we have +$\tau \isasymMathOclValid x \isasymMathOclStrictEq y \;\mocl{-}\; \mocl{3} \land \tau \isasymMathOclValid +\delta \ap x \land \tau \isasymMathOclValid \delta \ap y$. +We call the latter formula the $\delta$-closure of the former. Now, we can +convert a formula like +$\tau \isasymMathOclValid x \;\mocl{>}\; \mocl{0} \ap\mocl{or}\ap \mocl{3} \;\mocl{*}\; y \;\mocl{>}\; +x \;\mocl{*}\; x$ into the equivalent formula +$\tau \isasymMathOclValid x \;\mocl{>}\; \mocl{0} \lor \tau +\isasymMathOclValid \mocl{3} \;\mocl{*}\; y \;\mocl{>}\; x \;\mocl{*}\; x$ and +thus internalize the \OCL-logic into a classical (and more tool-conform) logic. +This works---for the price of a potential, but due to the usually ``rich'' +$\delta$-closures of invariants rare---exponential blow-up of the +formula for all \OCL formulas. + +\subsection{Algebraic Layer} +Based on the logical layer, we build a system with simpler rules which +are amenable to automated reasoning. We restrict ourselves to pure +equations on \OCL expressions. + +Our denotational definitions on \inlineocl+not+ and \inlineocl+and+ +can be re-formulated in the following ground equations: +\begin{gather*} + \begin{aligned} + \upsilon\; \mocl{invalid} &= \mocl{false}&\qquad + \upsilon\; \mocl{null} &= \mocl{true}\\ + \upsilon\; \mocl{true} &= \mocl{true}&\qquad + \upsilon\; \mocl{false} &= \mocl{true}\\ +\end{aligned}\\[.04\baselineskip] +\begin{aligned} + % + \delta\; \mocl{invalid} &= \mocl{false}&\qquad + \delta\; \mocl{null} &= \mocl{false}\\ + \delta\; \mocl{true} &= \mocl{true}&\qquad + \delta\; \mocl{false} &= \mocl{true}\\ +\end{aligned}\\[.04\baselineskip] +\begin{aligned} + % + \mocl{not}\; \mocl{invalid} &= \mocl{invalid}&\qquad + \mocl{not}\; \mocl{null} &= \mocl{null}\\ + \mocl{not}\; \mocl{true} &= \mocl{false}&\qquad + \mocl{not}\; \mocl{false} &= \mocl{true}\\ +\end{aligned}\\[.04\baselineskip] +\begin{aligned} + % + (\mocl{null} \;\mocl{and}\; \mocl{true}) &= \mocl{null}&\qquad + (\mocl{null} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ + (\mocl{null} \;\mocl{and}\; \mocl{null}) &= \mocl{null}&\qquad + (\mocl{null} \;\mocl{and}\; \mocl{invalid}) &= \mocl{invalid}\\ +\end{aligned}\\[.04\baselineskip] +\begin{aligned} + % + (\mocl{false} \;\mocl{and}\; \mocl{true}) &= \mocl{false}&\qquad + (\mocl{false} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ + (\mocl{false} \;\mocl{and}\; \mocl{null}) &= \mocl{false}&\qquad + (\mocl{false} \;\mocl{and}\; \mocl{invalid}) &= \mocl{false}\\ +\end{aligned}\\[.04\baselineskip] +\begin{aligned} + % + (\mocl{true} \;\mocl{and}\; \mocl{true}) &= \mocl{true}&\qquad + (\mocl{true} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ + (\mocl{true} \;\mocl{and}\; \mocl{null}) &= \mocl{null}&\qquad + (\mocl{true} \;\mocl{and}\; \mocl{invalid}) &= \mocl{invalid} +\end{aligned}\\[.04\baselineskip] +\begin{aligned} + (\mocl{invalid} \;\mocl{and}\; \mocl{true}) &= \mocl{invalid} &\qquad + (\mocl{invalid} \;\mocl{and}\; \mocl{false}) &= \mocl{false}\\ + (\mocl{invalid} \;\mocl{and}\; \mocl{null}) &= \mocl{invalid} &\qquad + (\mocl{invalid} \;\mocl{and}\; \mocl{invalid}) &= \mocl{invalid}\\ +\end{aligned} +\shortintertext{On this core, the structure of a conventional lattice arises:} + \begin{aligned} + X \;\mocl{and}\; X &= X &\qquad X \;\mocl{and}\; Y &= Y \;\mocl{and}\; X + \end{aligned}\\ + \begin{aligned} + \mocl{false} \;\mocl{and}\; X &= \mocl{false} &\qquad + X \;\mocl{and}\; \mocl{false} &= \mocl{false} \\ + \mocl{true} \;\mocl{and}\; X &= X &\qquad + X \;\mocl{and}\; \mocl{true} &= X + \end{aligned}\\ + \begin{aligned} + X \;\mocl{and}\; (Y \;\mocl{and}\; Z) &= X \;\mocl{and}\; Y \;\mocl{and}\; Z + \end{aligned} +\end{gather*} +as well as the dual equalities for \inlineocl|_ or _| and the De Morgan +rules. This wealth of algebraic properties makes the understanding of +the logic easier as well as automated analysis possible: for example, it allows +for computing a DNF of invariant systems (by term-rewriting techniques) +which are a prerequisite for $\delta$-closures. + +The above equations explain the behavior for the most-important +non-strict operations. The clarification of the exceptional behaviors +is of key-importance for a semantic definition of the standard and the +major deviation point from +\HOLOCL~\cite{brucker.ea:hol-ocl:2008,brucker.ea:hol-ocl-book:2006} +to \FOCL as presented here. Expressed in algebraic equations, +``strictness-principles'' boil down to: +\begin{gather*} + \begin{aligned} + \mocl{invalid} \;\mocl{+}\; X &= \mocl{invalid} &\qquad + X \;\mocl{+}\; \mocl{invalid} &= \mocl{invalid}\\ + \mocl{invalid->including(}X\mocl{)} &= \mocl{invalid} &\qquad + \mocl{null->including(}X\mocl{)} &= \mocl{invalid}\\ + X \isasymMathOclStrictEq \mocl{invalid} &= \mocl{invalid}&\qquad + \mocl{invalid} \isasymMathOclStrictEq X &= \mocl{invalid} \\ + \end{aligned}\\ + \mocl{S->including(invalid)}=\mocl{invalid} \\ + X \isasymMathOclStrictEq X = (\mocl{if}\; \upsilon\; x\; \mocl{then true} + \mocl{else invalid endif}) \\ + \begin{aligned} + \mocl{1} \;\mocl{/}\; \mocl{0} &= \mocl{invalid} \quad &\quad + \mocl{1} \;\mocl{/}\; \mocl{null} &= \mocl{invalid} \\ + \mocl{invalid->isEmpty()}&=\mocl{invalid} \quad &\quad \mocl{null->isEmpty()}&=\mocl{null}\\ + \end{aligned}\\ +\end{gather*} + +Algebraic rules are also the key for execution and compilation +of \FOCL expressions. We derived, \eg: +\begin{gather*} +\delta\; \mocl{Set\{\}} = \mocl{true}\\ +\delta\; (X\mocl{->including(}x\mocl{)}) = \delta \ap X \;\mocl{and}\; + \upsilon \ap x\\ +\begin{aligned} +\mocl{Set\{\}->includes(}x\mocl{)} = (\mocl{if}\; \upsilon\; x\; &\mocl{then false}\\ +&\mocl{else invalid endif}) +\end{aligned}\\ +\begin{multlined} + {(X\mocl{->including(}x\mocl{)->includes(}y\mocl{)})=}\\ + \mbox{\hspace{3.2cm}}\qquad{\begin{aligned} + (&\mocl{if}\; \delta\; X\\ + &\mocl{then}\; +\begin{array}[t]{l} +\mocl{if}\; x \doteq y\\ +\mocl{then}\ap \mocl{true} \\ +\mocl{else}\ap X\mocl{->includes(}y\mocl{)}\\ +\mocl{endif} + \end{array}\\ +&\mocl{else invalid} \\ + &\mocl{endif}) + \end{aligned}} +\end{multlined} +\end{gather*} +As \inlineocl+Set{1,2}+ is only syntactic sugar for +\begin{ocl} + Set{}->including(1)->including(2) +\end{ocl} +an expression like \inlineocl+Set{1,2}->includes(null)+ becomes +decidable in \FOCL by applying these algebraic laws (which can give + rise to efficient compilations). The reader interested in the list of +``test-statements'' like: +\begin{isar}[mathescape] +value "\ \ ($\mathtt{Set\{Set\{2,null\}\}}$ \ $\;\mathtt{Set\{Set\{null,2\}\}}$)" +\end{isar} +make consult \autoref{formal-set}; these test-statements + have been machine-checked and proven consistent with the denotational and logic + semantics of \FOCL. +% It fairly readable information for \OCL tool manufactures and users. + + +\subsection{Object-oriented Datatype Theories} +In the following, we will refine the concepts of a user-defined +data-model implied by a \emph{class-model} (\emph{visualized} by a class-\emph{diagram}) +as well as the notion of $\state{}$ used in the +previous section to much more detail. \UML class models represent in a compact +and visual manner quite complex, object-oriented data-types with a surprisingly rich +theory. In this section, this theory is made explicit +and corner cases were pointed out. + +A \UML class model underlying a +given \OCL invariant or operation contract +produces several implicit operations which +become accessible via appropriate \OCL syntax. +A class model is a four-tuple $(C, \_ < \_, Attrib, Assoc)$ where: +\begin{enumerate} +\item $C$ is a set of class names (written as $\{C_1, \ldots, C_n\}$). To each class + name a type of data in \OCL is associated. Moreover, class names declare two projector + functions to the set of all objects in a state: + $C_i$\inlineocl{.allInstances()} and + $C_i$\inlineocl{.allInstances}$\isasymOclATpre$\inlineocl{()}, +\item $\_ < \_$ is an inheritance relation on classes, +\item $Attrib(C_i)$ is a collection of + attributes associated to classes $C_i$. It declares two families of accessors; for each attribute $a \in Attrib(C_i) $ in a + class definition $C_i$ (denoted + $\getAttrib{X}{\text{$a$}} :: C_i \rightarrow A $ and + $\getAttrib{X}{\text{$a$}\isasymOclATpre}:: C_i \rightarrow A $ for + $A\in TYPES(C)$), +\item $Assoc(C_i,C_j)$ is a collection of associations\footnote{Given the fact that there is at present no consensus on the + semantics of n-ary associations, \FOCL{} restricts itself to binary associations. }. + An association $(n, rn_{from}, rn_{to})\in Assoc(C_i,C_j)$ between to classes + $C_i$ and $C_j$ is a triple consisting of a (unique) association name $n$, + and the role-names $rn_{to}$ and $rn_{from}$. To each role-name belong two + families of accessors denoted + $\getRole{X}{\text{$a$}} :: C_i \rightarrow A$ and + $\getRole{X}{\text{$a$}\isasymOclATpre}:: C_i \rightarrow A$ for + $A\in TYPES(C)$), +\item for each pair $C_i < C_j$ ($C_i, C_j < C$), there is a + cast operation of type $C_j \rightarrow C_i$ that can change the static type + of an object of type $C_i$: + $\getAttrib{obj::C_i}{\mocl{oclAsType(}\text{$C_j$}\mocl{)}}$, +\item for each class $C_i\in C$, there are two dynamic type tests + ($\getAttrib{X}{\mocl{oclIsTypeOf(}\text{$C_i$}\mocl{)}}$ and + $\getAttrib{X}{\mocl{oclIsKindOf(}\text{$C_i$}\mocl{)}}$ ), +\item and last but not least, for each class name $C_i\in C$ there is an + instance of the overloaded referential equality (written $\_ + \isasymMathOclStrictEq \_$). +\end{enumerate} + + +Assuming a strong static type discipline in the sense of +Hindley-Milner types, \FOCL has no ``syntactic +subtyping.'' In contrast, sub-typing can be expressed +\emph{semantically} in \FOCL by adding suitable type-casts which do +have a formal semantics. Thus, sub-typing becomes an issue of the front-end +that can make implicit type-coercions explicit. Our perspective shifts the +emphasis on the semantic properties of casting, and the necessary universe of +object representations (induced by a class model) that allows to establish +them. + +As a pre-requisite of a denotational semantics for these operations induced +by a class-model, we need an \emph{object-universe} in which these operations can +be defined in a denotational manner and from which the necessary properties +for constructors, accessors, tests and casts +can be derived. A concrete universe constructed from a class model will be +used to instantiate the implicit type parameter $\isaAA$ of all \OCL operations +discussed so far. + +\subsubsection{A Denotational Space for Class-Models: Object Universes} + +It is natural to construct system states by a set of partial functions +$f$ that map object identifiers $\oid$ to some representations of +objects: +\begin{gather} + \typedef \qquad \mathfrak{A}~\state{} \defeq \{\sigma :: + \oid \isasymrightharpoonup \alpha \ap|\ap \inv_\sigma(\sigma) \} +\end{gather} +where $\inv_\sigma$ is a to be discussed invariant on states. + +The key point is that we need a common type $\mathfrak{A}$ for the set of all +possible \emph{object representations}. Object representations model +``a piece of typed memory,'' \ie, a kind of record comprising +administration information and the information for all attributes of +an object; here, the primitive types as well as collections over them +are stored directly in the object representations, class types and +collections over them are represented by $\oid$'s (respectively lifted +collections over them). + +In a shallow embedding which must represent +\UML types one-to-one by HOL types, there are two fundamentally +different ways to construct such a set of object representations, +which we call an \emph{object universe} $\mathfrak{A}$: +\begin{enumerate} +\item an object universe can be constructed from a given class model, + leading to \emph{closed world semantics}, and +\item an object universe can be constructed for a given class model + \emph{and all its extensions by new classes added into the leaves of + the class hierarchy}, leading to an \emph{open world semantics}. +\end{enumerate} +For the sake of simplicity, the present semantics chose the first option for + \FOCL, while HOL-\OCL~\cite{brucker.ea:extensible:2008-b} +used an involved construction allowing the latter. + +A na\"ive attempt to construct $\mathfrak{A}$ would look like this: +the class type $C_i$ induced by a class will be the type of such an +object representation: $C_i \defeq (\oid \times A_{i_1} \times \cdots +\times A_{i_k} )$ where the types $A_{i_1}$, \ldots, $A_{i_k}$ are the +attribute types (including inherited attributes) with class types +substituted by $\oid$. The function $\HolOclOidOf$ projects the first +component, the $\oid$, out of an object representation. Then the +object universe will be constructed by the type definition: +\begin{gather} +\mathfrak{A} := C_1 + \cdots + C_n\mi{.} +\end{gather} +It is possible to define constructors, accessors, and the referential +equality on this object universe. However, the treatment of type casts +and type tests cannot be faithful with common object-oriented +semantics, be it in \UML or Java: casting up along the class hierarchy +can only be implemented by loosing information, such that casting up +and casting down will \emph{not} give the required identity, whenever $C_k < C_i$ and $X$ is valid: +\begin{gather} + X.\mocl{oclIsTypeOf(}C_k\mocl{)} ~ ~ \mocl{implies} ~ ~ X\mocl{.oclAsType(}C_i\mocl{)}\mocl{.oclAsType(}C_k\mocl{)} \isasymMathOclStrictEq + X +\end{gather} + +To overcome this limitation, we introduce an auxiliary type +$C_{i\text{ext}}$ for \emph{class type extension}; together, they were +inductively defined for a given class diagram: + +Let $C_i$ be a class with a possibly empty set of subclasses +$\{C_{j_{1}}, \ldots, C_{j_{m}}\}$. +\begin{itemize} +\item Then the \emph{class type extension} $C_{i\text{ext}}$ + associated to $C_i$ is + $A_{i_{1}} \times \cdots \times A_{i_{n}} \times \up{(C_{j_{1}\text{ext}} + \cdots + C_{j_{m}\text{ext}})}$ + where $A_{i_{k}}$ ranges over the local + attribute types of $C_i$ and $C_{j_{l}\text{ext}}$ + ranges over all class type extensions of the subclass $C_{j}$ of $C_i$. +\item Then the \emph{class type} for $C_i$ is + $oid \times A_{i_{1}} \times \cdots \times A_{i_{n}} \times \up{(C_{j_{1}\text{ext}} + \cdots + C_{j_{m}\text{ext}})}$ + where $A_{i_{k}}$ ranges over the inherited \emph{and} local + attribute types of $C_i$ and $C_{j_{l}\text{ext}}$ + ranges over all class type extensions of the subclass $C_{j}$ of $C_i$. +\end{itemize} + +\isatagafp +Example instances of this scheme---outlining a compiler---can be found +in \autoref{ex:employee-analysis:uml} and \autoref{ex:employee-design:uml}. +\endisatagafp +\isatagannexa +Example instances of this scheme---outlining a compiler---can be found +in \autoref{ex:employee-analysis:uml}. +\endisatagannexa + +This construction can \emph{not} be done in HOL itself since it +involves quantifications and iterations over the ``set of class-types''; +rather, it is a meta-level construction. Technically, this means that +we need a compiler to be done in SML on the syntactic +``meta-model''-level of a class model. + +With respect to our semantic construction here, +which above all means is intended to be type-safe, this has the following consequences: +\begin{itemize} +\item there is a generic theory of states, which must be formulated independently + from a concrete object universe, +\item there is a principle of translation (captured by the inductive scheme for + class type extensions and class types above) that converts a given class model + into an concrete object universe, +\item there are fixed principles that allow to derive the semantic theory of any + concrete object universe, called the \emph{object-oriented datatype theory.} +\end{itemize} +\isatagafp +We will work out concrete examples for the construction of the +object-universes in \autoref{ex:employee-analysis:uml} and \autoref{ex:employee-design:uml} and the +derivation of the respective datatype theories. While an +automatization is clearly possible and desirable for concrete +applications of \FOCL, we consider this out of the scope +of this document which has a focus on the semantic construction and its +presentation. +\endisatagafp +\isatagannexa +We will work out concrete examples for the construction of the +object-universes in \autoref{ex:employee-analysis:uml} and the +derivation of the respective datatype theories. While an +automatization is clearly possible and desirable for concrete +applications of \FOCL, we consider this out of the scope +of this annex which has a focus on the semantic construction and its +presentation. +\endisatagannexa + + +\subsubsection{Denotational Semantics of Accessors on Objects and Associations} +Our choice to use a shallow embedding of \OCL in HOL and, thus having +an injective mapping from \OCL types to HOL types, results in +type-safety of \FOCL\@. Arguments and results of accessors +are based on type-safe object representations and \emph{not} $\oid$'s. +This implies the following scheme for an accessor: +\begin{itemize} +\item The \emph{evaluation and extraction} phase. If the argument + evaluation results in an object representation, the $\oid$ is + extracted, if not, exceptional cases like \inlineocl{invalid} are + reported. +\item The \emph{de-referentiation} phase. The $\oid$ is interpreted in + the pre- or post-state, %(depending on the suffix of accessor), + the resulting object is cast to the expected format. The + exceptional case of non-existence in this state must be treated. +\item The \emph{selection} phase. The corresponding attribute is + extracted from the object representation. +\item The \emph{re-construction} phase. The resulting value has to be + embedded in the adequate HOL type. If an attribute has the type of + an object (not value), it is represented by an optional (set of) + $\oid$, which must be converted via de-referentiation in one of the + states to produce an object representation again. The + exceptional case of non-existence in this state must be treated. +\end{itemize} + +The first phase directly translates into the following formalization: +\begin{multline} + \shoveleft{\isardef}\quad\\ + \begin{array}{rllr} + \operatorname{eval\_extract} X\ap f = (\lambda \tau\spot \HolCase + X\ap + \tau \HolOf & \bottom &\Rightarrow + \mocl{invalid}\ap\tau&\text{exception}\\ + |& \lift{\bottom} &\Rightarrow + \mocl{invalid}\ap\tau&\text{deref. null}\\ + |& \lift{\lift{\mathit{obj}}} &\Rightarrow f\ap (\operatorname{oid\_of} \ap \mathit{obj})\ap\tau)& + \end{array} +\end{multline} + +For each class $C$, we introduce the de-referentiation phase of this +form: +\begin{multline} + \isardef \ap + \operatorname{deref\_oid}_C \ap \mathit{fst\_snd}\ap f\ap \mathit{oid} = + (\lambda \tau\spot \HolCase\ap (\operatorname{heap}\ap + (\mathit{fst\_snd}\ap \tau))\ap \mathit{oid}\ap + \HolOf\\ + \begin{array}{ll} + \phantom{|}\ap \lift{\operatorname{in}_C obj} &\Rightarrow f\ap + \mathit{obj} \ap \tau\\ + |\ap \_ &\Rightarrow \mocl{invalid}\ap \tau) + \end{array} + \end{multline} + +The operation yields undefined if the $\oid$ is uninterpretable in the +state or referencing an object representation not conforming to the +expected type. + +We turn to the selection phase: for each class $C$ in the class model +with at least one attribute, +and each attribute $a$ in this class, +we introduce the selection phase of this form: +\begin{gather} + \begin{array}{rlcll} + \isardef \ap + \operatorname{select}_a \ap f = (\lambda & + \operatorname{mk}_C \ap oid & \cdots \bottom \cdots & C_{X\text{ext}} & \Rightarrow \mocl{null}\\ + |& \operatorname{mk}_C \ap oid & \cdots \lift{a} \cdots & C_{X\text{ext}} + &\Rightarrow f\ap (\lambda \ap x \ap \_\spot + \lift{\lift{x}})\ap a) + \end{array} +\end{gather} + +This works for definitions of basic values as well as for object +references in which the $a$ is of type $\oid$. To increase +readability, we introduce the functions: +\begin{gather} +\begin{array}{llrlr} +\qquad\qquad&\isardef\enspace&\operatorname{in\_pre\_state} &= \operatorname{fst} & \qquad \text{first component}\\ +\qquad\qquad&\isardef\enspace&\operatorname{in\_post\_state} &= \operatorname{snd} & \qquad \text{second component} \\ +\qquad\qquad&\isardef\enspace&\operatorname{reconst\_basetype} &= \operatorname{id} & \qquad \text{identity function} +\end{array} +\end{gather} + + +Let \_\inlineocl{.getBase} be an accessor of class $C$ yielding a +value of base-type $A_{base}$. Then its definition is of the form: +\begin{gather} +\begin{array}{lll} +\isardef&\_\mocl{.getBase} &\ofType \ap C \Rightarrow A_{base}\\ +\where\enspace&X\mocl{.getBase} &= \operatorname{eval\_extract}\ap X\ap + (\operatorname{deref\_oid}_C\ap \operatorname{in\_post\_state}\ap\\ + & &\quad (\operatorname{select}_\text{getBase}\ap \operatorname{reconst\_basetype})) +\end{array} +\end{gather} + +Let \_\inlineocl{.getObject} be an accessor of class $C$ yielding a +value of object-type $A_{object}$. Then its definition is of the form: +\begin{gather} +\begin{array}{lll} +\isardef&\_\mocl{.getObject} &\ofType \ap C \Rightarrow A_{object}\\ +\where\enspace&X\mocl{.getObject} &= \operatorname{eval\_extract}\ap X\ap + (\operatorname{deref\_oid}_C\ap \operatorname{in\_post\_state}\ap\\ + & &\quad (\operatorname{select}_\text{getObject}\ap + (\operatorname{deref\_oid}_C\ap\operatorname{in\_post\_state}))) +\end{array} +\end{gather} +The variant for an accessor yielding a collection is omitted here; its +construction follows by the application of the principles of the +former two. The respective variants +$\getAttrib{\_}{\text{$a$}\isasymOclATpre}$ were produced when +\inlineisar+in_post_state+ is replaced by +$\operatorname{in\_pre\_state}$. + +\isatagafp +Examples for the construction of accessors via associations can be found in +\autoref{sec:eam-accessors}, the construction of accessors via attributes in +\autoref{sec:edm-accessors}. The construction of casts and type tests \inlineocl{->oclIsTypeOf()} and +\inlineocl{->oclIsKindOf()} is similarly. +\endisatagafp +\isatagannexa +Examples for the construction of accessors via associations can be found in +\autoref{sec:eam-accessors}. The construction of casts and type tests \inlineocl{->oclIsTypeOf()} and +\inlineocl{->oclIsKindOf()} is similarly. +\endisatagannexa + +In the following, we discuss the role of multiplicities on the types of the +accessors. +Depending on the specified multiplicity, the evaluation of an attribute can +yield just a value (multiplicity \inlineocl{0..1} or \inlineocl{1}) +or a collection type like Set or Sequence of values (otherwise). +A multiplicity defines a lower bound as well as a possibly infinite upper +bound on the cardinality of the attribute's values. + + +\paragraph{Single-Valued Attributes}\label{sec:single-valued-properties} +If the upper bound specified by the attribute's multiplicity is one, +then an evaluation of the attribute yields a single value. +Thus, the evaluation result is \emph{not} a collection. If the lower bound specified by the +multiplicity is zero, the evaluation is not required to yield a non-null value. In this case an +evaluation of the attribute can return $\isasymOclNull$ to indicate an +absence of value. + +To facilitate accessing attributes with multiplicity \inlineocl{0..1}, the \OCL +standard states that single values can be used as sets by calling collection +operations on them. This implicit conversion of a value to a +\inlineocl{Set} is not defined by the standard. We argue that the resulting set +cannot be constructed the same way as when evaluating a \inlineocl{Set} +literal. Otherwise, $\isasymOclNull$ would be mapped to the singleton set +containing $\isasymOclNull$, but the standard demands that +the resulting set is empty in this case. The conversion should instead +be defined as follows: +\begin{ocl} +context OclAny::asSet():T + post: if self = null then result = Set{} + else result = Set{self} endif +\end{ocl} +% Changed self.isTypeOf(\OCLVoid) to self = null to make it easier for the superficial reader + +\paragraph{Collection-Valued Attributes}\label{sec:collection-valued-properties} +If the upper bound specified by the attribute's multiplicity is larger than one, +then an evaluation of the attribute yields a collection of values. This raises +the question whether $\isasymOclNull$ can belong to this collection. The \OCL +standard states that $\isasymOclNull$ can be owned by collections. However, if +an attribute can evaluate to a collection containing $\isasymOclNull$, it is not +clear how multiplicity constraints should be interpreted for this attribute. The +question arises whether the $\isasymOclNull$ element should be counted or not +when determining the cardinality of the collection. Recall that $\isasymOclNull$ +denotes the absence of value in the case of a cardinality upper bound of one, so +we would assume that $\isasymOclNull$ is not counted. On the other hand, the +operation \inlineocl{size} defined for collections in \OCL does count +$\isasymOclNull$. + +We propose to resolve this dilemma by regarding multiplicities as optional. This +point of view complies with the \UML standard, that does not require lower and +upper bounds to be defined for multiplicities.\footnote{We are however aware + that a well-formedness rule of the \UML standard does define a default bound + of one in case a lower or upper bound is not specified.} In case a +multiplicity is specified for an attribute, \ie, a lower and an upper bound +are provided, we require for any collection the attribute evaluates to +a collection not containing $\isasymOclNull$. This allows for a straightforward +interpretation of +the multiplicity constraint. If bounds are not provided for an attribute, we +consider the attribute values to not be restricted in any way. Because in +particular the cardinality of the attribute's values is not bounded, the result +of an evaluation of the attribute is of collection type. As the range of values +that the attribute can assume is not restricted, the attribute can evaluate to a +collection containing $\isasymOclNull$. The attribute can also evaluate to +$\isasymOclInvalid$. Allowing multiplicities to be optional in this way gives +the modeler the freedom to define attributes that can assume the full ranges of +values provided by their types. However, we do not permit the omission of +multiplicities for association ends, since the values of association ends are +not only restricted by multiplicities, but also by other constraints enforcing +the semantics of associations. Hence, the values of association ends cannot be +completely unrestricted. + +\paragraph{The Precise Meaning of Multiplicity Constraints} +We are now ready to define the meaning of multiplicity constraints by giving +equivalent invariants written in \OCL\@. Let \inlineocl{a} be an attribute of a +class \inlineocl{C} with a multiplicity specifying a lower bound $m$ and an +upper bound $n$. Then we can define the multiplicity constraint on the values of +attribute \inlineocl{a} to be equivalent to the following invariants written in +\OCL: +\begin{ocl} +context C inv lowerBound: a->size() >= m + inv upperBound: a->size() <= n + inv notNull: not a->includes(null) +\end{ocl} +If the upper bound $n$ is infinite, the second invariant is omitted. For the +definition of these invariants we are making use of the conversion of single +values to sets described in \autoref{sec:single-valued-properties}. If $n +\leq 1$, the attribute \inlineocl{a} evaluates to a single value, which is then +converted to a \inlineocl{Set} on which the \inlineocl{size} operation is +called. + +If a value of the attribute \inlineocl{a} includes a reference to a non-existent +object, the attribute call evaluates to $\isasymOclInvalid$. As a result, the +entire expressions evaluate to $\isasymOclInvalid$, and the invariants are not +satisfied. Thus, references to non-existent objects are ruled out by these +invariants. We believe that this result is appropriate, since we argue that the +presence of such references in a system state is usually not intended and likely +to be the result of an error. If the modeler wishes to allow references to +non-existent objects, she can make use of the possibility described above to +omit the multiplicity. + +\subsubsection{Logic Properties of Class-Models}\label{sec:logicprop-datamodel} +In this section, we assume to be $C_z,C_i,C_j \in C$ and $C_i < C_j$. +Let $C_z$ be a smallest element with respect to the class hierarchy $\_ < \_$. +The operations induced from a class-model have the following properties: +\begin{gather*} + \tau \isasymMathOclValid X \mocl{.oclAsType(}C_i\mocl{)} \isasymMathOclStrongEq X \\ + \tau \isasymMathOclValid \mocl{invalid .oclAsType(}C_i\mocl{)} \isasymMathOclStrongEq \mocl{invalid} \\ + \tau \isasymMathOclValid \mocl{null .oclAsType(}C_i\mocl{)} \isasymMathOclStrongEq \mocl{null} \\ + \tau \isasymMathOclValid \mocl{((}X::C_i) \mocl{.oclAsType(C_j) .oclAsType(}C_i\mocl{)} \isasymMathOclStrongEq X\mocl{)} \\ + \tau \isasymMathOclValid X \mocl{.oclAsType(}C_j\mocl{) .oclAsType(}C_i) \isasymMathOclStrongEq X \\ + \tau \isasymMathOclValid \mocl{(}X::OclAny\mocl{) .oclAsType(}OclAny\mocl{)} \isasymMathOclStrongEq X \\ + \tau \isasymMathOclValid \upsilon (X :: C_i) \Longrightarrow %\qquad \qquad \qquad \qquad \\ + \tau \isasymMathOclValid (X \mocl{.oclIsTypeOf(}C_i\mocl{) implies (}X \mocl{.oclAsType(}C_j\mocl{).oclAsType(}C_i\mocl{))} \isasymMathOclStrictEq X) \\ + \tau \isasymMathOclValid \upsilon (X :: C_i) \Longrightarrow %\qquad \qquad \qquad \qquad \\ + \tau \isasymMathOclValid X \mocl{.oclIsTypeOf(}C_i\mocl{) implies (}X \mocl{.oclAsType(}C_j\mocl{) .oclAsType(}C_i\mocl{))} \isasymMathOclStrictEq X \\ + \tau \isasymMathOclValid \delta X \Longrightarrow \tau \isasymMathOclValid X \mocl{.oclAsType(}C_j\mocl{) .oclAsType(}C_i\mocl{)} \isasymMathOclStrongEq X \\ + \tau \isasymMathOclValid \upsilon X \Longrightarrow \tau \isasymMathOclValid X \mocl{.oclIsTypeOf(}C_i\mocl{) implies} X \mocl{.oclAsType(}C_j\mocl{) .oclAsType(}C_i\mocl{)} \isasymMathOclStrictEq X \\ + \tau \isasymMathOclValid X \mocl{.oclIsTypeOf(}C_j\mocl{)} \Longrightarrow \tau \isasymMathOclValid \delta X \Longrightarrow \tau \isasymMathOclValid \mocl{not} (\upsilon X \mocl{.oclAsType(}C_i\mocl{))} \\ + \tau \isasymMathOclValid \mocl{invalid} \mocl{.oclIsTypeOf(}C_i\mocl{)} \isasymMathOclStrongEq \mocl{invalid} \\ + \tau \isasymMathOclValid \mocl{null .oclIsTypeOf(}C_i\mocl{)} \isasymMathOclStrongEq \mocl{true} \\ + \tau \isasymMathOclValid Person \mocl{.allInstances()->forAll(}X\mocl{|}X \mocl{.oclIsTypeOf(}C_z\mocl{))} \\ + \tau \isasymMathOclValid Person \mocl{.allInstances@pre()->forAll(}X\mocl{|}X \mocl{.oclIsTypeOf(}C_z\mocl{))} \\ + \tau \isasymMathOclValid Person \mocl{.allInstances()->forAll(}X\mocl{|}X \mocl{.oclIsKindOf(}C_i\mocl{))} \\ + \tau \isasymMathOclValid Person \mocl{.allInstances@pre()->forAll(}X\mocl{|}X \mocl{.oclIsKindOf(}C_i\mocl{))} \\ + \tau \isasymMathOclValid (X::C_i)\mocl{.oclIsTypeOf(}C_j\mocl{)} \Longrightarrow \tau \isasymMathOclValid \mocl{(}X::C_i\mocl{).oclIsKindOf(}C_i\mocl{)} \\ +(\tau \isasymMathOclValid (X::C_j) \isasymMathOclStrictEq X) = (\tau \isasymMathOclValid \mocl{if } \upsilon X \mocl{then true else invalid endif}) \\ + \tau \isasymMathOclValid (X::C_j) \isasymMathOclStrictEq Y \Longrightarrow \tau \isasymMathOclValid Y \isasymMathOclStrictEq X \\ + \tau \isasymMathOclValid (X::C_j) \isasymMathOclStrictEq Y \Longrightarrow \tau \isasymMathOclValid Y \isasymMathOclStrictEq Z \Longrightarrow \tau \isasymMathOclValid X \isasymMathOclStrictEq Z +\end{gather*} + +\subsubsection{Algebraic Properties of the Class-Models}\label{sec:algprop-datamodel} +In this section, we assume to be $C_i,C_j \in C$ and $C_i < C_j$. +The operations induced from a class-model have the following properties: +\begin{gather*} +\begin{array}{ll} + \mocl{invalid} \mocl{.oclIsTypeOf(}C_i\mocl{)} = \mocl{invalid} \qquad + \mocl{null} \mocl{.oclIsTypeOf(}C_i\mocl{)} = \mocl{true} \\ + \mocl{invalid} \mocl{.oclIsKindOf(}C_i\mocl{)} = \mocl{invalid} \qquad + \mocl{null} \mocl{.oclIsKindOf(}C_i\mocl{)} = \mocl{true} \\ + (X::C_i) \mocl{.oclAsType(}C_i\mocl{)} = X \qquad + \mocl{invalid} \mocl{.oclAsType(}C_i\mocl{)} = \mocl{invalid} \\ + \mocl{null} \mocl{.oclAsType(}C_i\mocl{)} = \mocl{null} \qquad + (X::C_i) \mocl{.oclAsType(}C_j\mocl{).oclAsType(}C_i\mocl{)} = X +\end{array} \\ + (X::C_i) \isasymMathOclStrictEq X = \mocl{if } \upsilon ~ X \mocl{ then true els invalid endif} \\ +\end{gather*} +With respect to attributes $\getAttrib{\_}{\text{a}}$ or $\getAttrib{\_}{\text{a}\isasymOclATpre}$ +and role-ends $\getAttrib{\_}{\text{r}}$ or $\getAttrib{\_}{\text{r}\isasymOclATpre}$ we have +\begin{gather*} + \getAttrib{\mocl{invalid}}{\text{a}} = \mocl{invalid} \qquad + \getAttrib{\mocl{null}}{\text{a}} = \mocl{invalid} \\ + \getAttrib{\mocl{invalid}}{\text{a}\isasymOclATpre} = \mocl{invalid} \qquad + \getAttrib{\mocl{null}}{\text{a}\isasymOclATpre} = \mocl{invalid} \\ + \getRole{\mocl{invalid}}{\text{r}} = \mocl{invalid} \qquad + \getRole{\mocl{null}}{\text{r}} = \mocl{invalid} \\ + \getRole{\mocl{invalid}}{\text{r}\isasymOclATpre} = \mocl{invalid} \qquad + \getRole{\mocl{null}}{\text{r}\isasymOclATpre} = \mocl{invalid} +\end{gather*} + +\subsubsection{Other Operations on States}\label{sec:otherStateOperations} +Defining $\_\isasymOclAllInstances$ +is straight-forward; the only difference is the property +$T\isasymOclAllInstances\isasymOclExcludes(\isasymOclNull)$ which is a +consequence of the fact that $\Null{}$'s are values and do not ``live'' in the +state. \OCL semantics admits states with ``dangling references,''; it is +the semantics of accessors or roles which maps these references to \mocl{invalid}, +which makes it possible to rule out these situations in invariants. + +%it is +%possible to define a counterpart to \inlineocl+_.oclIsNew()+ called +%\inlineocl+_.oclIsDeleted()+ which asks if an object id (represented by an object +%representation) is contained in the pre-state, but not the post-state. + +\OCL does not guarantee that an operation only modifies the path-expressions +mentioned in the postcondition, \ie, it allows arbitrary relations from +pre-states to post-states. This framing problem is well-known (one of the +suggested solutions is~\cite{kosiuczenko:specification:2006}). We define +\begin{ocl} + (S:Set(OclAny))->oclIsModifiedOnly():Boolean +\end{ocl} +where \inlineocl|S| is a set of object representations, encoding +a set of $\oid$'s. The semantics of this operator is defined such that +for any object whose $\oid$ is \emph{not }represented in \inlineocl|S| +and that is defined in pre and post state, the corresponding object representation will not change +in the state transition. A simplified presentation is as follows: +\begin{gather*} +I\semantics{X\isasymMathOclIsModifiedOnly} (\sigma, \sigma') \equiv + \begin{cases} + \isasymbottom & \text{if $X' = \bottom \lor \text{null}\in X'$} \\ + \lift{\isasymforall i \isasymin M\spot + \sigma~i = \sigma'~i} & \text{otherwise}\mi{.} + \end{cases} +\end{gather*} +where $X' = I\semantics{X} (\sigma, \sigma')$ and $M= +(\dom~\sigma\cap\dom~\sigma') - \{ \HolOclOidOf x |~x \in\drop{X'}\}$. Thus, if +we require in a postcondition \inlineocl|Set{}->oclIsModifiedOnly()| and exclude via +\inlineocl+_.oclIsNew()+ and \inlineocl+_.oclIsDeleted()+ the existence of new +or deleted objects, the operation is a query in the sense of the \OCL standard, \ie, +the \inlineocl|isQuery| property is true. So, whenever we have $ \tau +\isasymMathOclValid X\isasymOclExcluding(s.a)\isasymMathOclIsModifiedOnly$ and $ \tau +\isasymMathOclValid X\mocl{->forAll(}x\mocl{|not}(x \doteq s.a) \mocl{)}$, we can infer that $\tau +\isasymMathOclValid s.a \triangleq s.a\isasymOclATpre$. + + +\subsection{Data Invariants} +\label{sec:invlogic} +Since the present \OCL semantics uses one interpretation function\footnote{This has been handled +differently in previous versions of the Annex A.}, we express the effect of \OCL terms +occurring in preconditions and invariants by a syntactic transformation $\__\text{pre}$ which +replaces: +\begin{itemize} +\item all accessor functions $\getAttrib{\_}{a}$ from the class model $a \in Attrib(C)$ by their +counterparts $\getAttrib{\_}{i\isasymOclATpre}$. For example, $(\getAttrib{\self}{salary} > +500)_\text{pre}$ is transformed to $(\getAttrib{\self}{salary\isasymOclATpre} > 500)$. +\item all role accessor functions $\getRole{\_}{rn_{from}}$ or $\getRole{\_}{rn_{to}}$ + within the class model (\ie, $(id, rn_{from}, rn_{to}) \in Assoc(C_i, C_j)$) + were replaced by their counterparts $\getRole{\_}{rn\isasymOclATpre}$. + For example, $(\getAttrib{\self}{boss} = null)_\text{pre}$ is transformed to + $\getAttrib{\self}{boss\isasymOclATpre} = null$. +\item The operation $\_\isasymOclAllInstances$ is also substituted by its +$\isasymOclATpre$ counterpart. +\end{itemize} +Thus, we formulate the semantics of the invariant specification as follows: +\begin{gather}\label{eq:inv} +\begin{aligned} +& I\semantics{\mathtt{context}~c:C_i~\mathtt{inv}~n: \phi(c)} \tau \equiv \\ +&\qquad \tau \isasymMathOclValid (C_i\isasymOclAllInstances\isasymOclForAll(x +\text{|} \phi(x)))~\land \\ +&\qquad \tau \isasymMathOclValid (C_i\isasymOclAllInstances\isasymOclForAll(x +\text{|} \phi(x)))_\text{pre} +\end{aligned} +\end{gather} +Recall that expressions containing $\isasymOclATpre$ constructs in +invariants or preconditions are syntactically forbidden; thus, mixed forms cannot arise. + +\subsection{Operation Contracts} +Since operations have strict semantics in \OCL, we have to distinguish for a specification of an +operation $\mathit{op}$ with the arguments $a_1$, \ldots, $a_n$ the +two cases where all arguments are valid and additionally, $\self$ is non-null (\ie, it must be defined), or not. +In former case, a method call can be replaced by a $\mathit{result}$ +that satisfies the contract, in the latter case the result is +\mocl{invalid}. This is reflected by the following definition of the contract semantics: +\begin{gather}\label{eq:contract} +\begin{aligned} + I\semantics{& \mathtt{context}~C~:: \mathit{op}(a_1, \ldots, a_n) : T \\ + & \qquad\mathtt{pre}~ \phi(\self, a_1, \ldots, a_n) \\ + & \qquad\mathtt{post}~\psi(\self, a_1, \ldots, a_n, \mathit{result})} \equiv \\ + & \qquad \quad \lambda s, x_1, \ldots, x_n, \tau. \\ + & \qquad\qquad \text{if} ~ ~ \tau +\isasymMathOclValid \isasymMathOclIsDefined s \land \tau \isasymMathOclValid +\isasymupsilon~x_1 \land \ldots \land \tau \isasymMathOclValid +\isasymupsilon~ x_n \\ + & \qquad\qquad \text{then} ~ \text{SOME}~ \mathit{result}. ~ ~ ~ ~\tau \isasymMathOclValid \phi(s, x_1, \ldots, x_n)_\text{pre} \\ + & \qquad\qquad\qquad\qquad\qquad\qquad ~ ~ \land \tau \isasymMathOclValid \psi(s, x_1, \ldots, x_n, \mathit{result}))\\ + &\qquad\qquad \text{else} ~ \isasymMathOclUndefined +\end{aligned} +\end{gather} +where $\text{SOME}~ x. ~P(x)$ is the Hilbert-Choice Operator that +chooses an arbitrary element satisfying $P$; if such an element does not exist, it chooses +an arbitrary one\footnote{In \HOL, the Hilbert-Choice operator is a first-class element of +the logical language.}. Thus, using the Hilbert-Choice Operator, a contract can be associated +to a function definition: +\begin{gather}\label{eq:contractdef} + f_{op} \equiv I\semantics{ \mathtt{context}~C~:: \mathit{op}(a_1, \ldots, a_n) : T \ldots } +\end{gather} +provided that neither $\phi$ nor $\psi$ contain recursive method calls of $\mathit{op}$. +In the case of a query operation (\ie, $\tau$ must have the form: $(\sigma,\sigma)$, which +means that query operations do not change the state; c.f. \mocl{oclIsModifiedOnly()} in +\autoref{sec:otherStateOperations}), this constraint can be relaxed: the above +equation is then stated as \emph{axiom}. Note however, that the consistency of the overall +theory is for recursive query contracts left to the user (it can be shown, for example, by a proof +of termination, \ie, by showing that all recursive calls were applied to argument vectors that are +smaller wrt. a well-founded ordering). Under this condition, an $f_{op}$ resulting from recursive +query operations can be used safely inside pre- and post-conditions of other contracts. + +For the general case of a user-defined contract, the following rule can be established +that reduces the proof of a property $E$ over a method call $f_{op}$ to a proof +of $E(res)$ (where $res$ must be one of the values that satisfy the post-condition $\psi$): +\begin{gather} + \begin{prooftree} + \[ \big[ \tau \isasymMathOclValid \psi~self~a_1\ldots a_n~res \big]_{res} + \leadsto + \tau \isasymMathOclValid E(res) + \] + \justifies + \tau \isasymMathOclValid E(f_{op}~self~a_1 \ldots a_n) + \end{prooftree} +\end{gather} +under the conditions: +\begin{itemize} +\item $E$ must be an \OCL term and +\item $\self$ must be defined, and the arguments valid in $\tau$: \\ + $\tau \isasymMathOclValid \isasymMathOclIsDefined~\self \land \tau \isasymMathOclValid \isasymupsilon~a_1 \land \ldots \land \tau \isasymMathOclValid \isasymupsilon~ a_n$ +\item the post-condition must be satisfiable (``the operation must be implementable''): + $\exists res.~ \tau \isasymMathOclValid \psi ~\self ~a_1 \ldots a_n~res $. +\end{itemize} +For the special case of a (recursive) query method, this rule can be specialized to the following +executable ``unfolding principle'': +\begin{gather} + \begin{prooftree} + \tau \isasymMathOclValid \phi~self~a_1\ldots a_n + \justifies + (\tau \isasymMathOclValid E(f_{op}~self~a_1\ldots a_n)) = e + (\tau \isasymMathOclValid E (BODY~self~a_1 + \cdots a_n)) + \end{prooftree} +\end{gather} +where +\begin{itemize} +\item $E$ must be an \OCL term. +\item $\self$ must be defined, and the arguments valid in $\tau$: \\ + $\tau \isasymMathOclValid \isasymMathOclIsDefined~\self \land \tau \isasymMathOclValid \isasymupsilon~a_1 \land \ldots \land \tau \isasymMathOclValid \isasymupsilon~ a_n$ +\item the postcondition $\psi~self~a_1~\ldots~a_n~result$ must be decomposable + into: \\ + $\psi'~self~a_1~\ldots a_n$ and $result \isasymMathOclStrongEq BODY~self~a_1~\ldots~a_n$. +\end{itemize} +Currently, \FOCL neither supports overloading nor overriding for +user-defined operations: the \FOCL compiler needs to be extended to +generate pre-conditions that constrain the classes on which an +overridden function can be called as well as the dispatch order. This +construction, overall, is similar to the virtual function table that, +e.g., is generated by C++ compilers. Moreover, to avoid logical +contradictions (inconsistencies) between different instances of an +overridden operation, the user has to prove Liskov's principle for +these situations: pre-conditions of the superclass must imply +pre-conditions of the subclass, and post-conditions of a subclass must +imply post-conditions of the superclass. + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "root" +%%% End: + +% LocalWords: \UML \OCL implementors RFP OMG provers invariants +% LocalWords: wellfounded Denotational equalities diff --git a/document/lstisar.sty b/src/document/lstisar.sty similarity index 100% rename from document/lstisar.sty rename to src/document/lstisar.sty diff --git a/src/document/omg.sty b/src/document/omg.sty new file mode 100644 index 0000000..087d360 --- /dev/null +++ b/src/document/omg.sty @@ -0,0 +1,28 @@ +% $Id: omg.sty 3 2014-10-11 14:53:59Z brucker $ +% Contact: adbrucker@0x5f.org +\usepackage{fixltx2e} +\usepackage[T1]{fontenc} +\KOMAoptions{paper=8.28in:11in,fontsize=10pt,twoside=semi,headings=openany} +\areaset{6.7in}{8in} +\usepackage{mathptmx} % rm & math +\usepackage[scaled=0.90]{helvet} % ss +\usepackage{courier} % tt +\usepackage[fleqn]{amsmath} +\usepackage{mathastext} +\normalfont +\usepackage[document]{ragged2e} +% \usepackage[pdfpagelabels, pageanchor=false, bookmarksnumbered, plainpages=false]{hyperref} +\setcounter{secnumdepth}{4} +\newcommand{\oclHeadingOne}[1]{\chapter{#1}}% +\newcommand{\oclHeadingTwo}[1]{\section{#1}}% +\newcommand{\oclHeadingThree}[1]{\subsection{#1}}% +\newcommand{\oclHeadingFour}[1]{\subsubsection{#1}}% +\newcommand{\oclHeadingZero}[1]{\subsubsection*{#1}}% +\newcommand{\oclEmph}[1]{\emph{#1}} +% +\newenvironment{oclDefinition}{\csname gather*\endcsname}{\csname endgather*\endcsname} + +\addtokomafont{caption}{\sffamily\bfseries} +\addtokomafont{captionlabel}{\sffamily\bfseries} +\renewcommand*{\captionformat}{\ --\ \ } +\setcapwidth[l]{\textwidth} \ No newline at end of file diff --git a/document/prooftree.sty b/src/document/prooftree.sty similarity index 100% rename from document/prooftree.sty rename to src/document/prooftree.sty diff --git a/document/root.bib b/src/document/root.bib similarity index 94% rename from document/root.bib rename to src/document/root.bib index b29d8d9..1d6fde6 100644 --- a/document/root.bib +++ b/src/document/root.bib @@ -1332,18 +1332,52 @@ } -@inproceedings{DBLP:conf/models/BruckerLTW13, - author = {Achim D. Brucker and - Delphine Longuet and - Fr{\'e}d{\'e}ric Tuong and - Burkhart Wolff}, - title = {On the Semantics of Object-Oriented Data Structures and - Path Expressions}, - booktitle = {OCL@MoDELS}, - year = {2013}, - pages = {23-32}, - ee = {http://ceur-ws.org/Vol-1092/brucker.pdf}, - bibsource = {DBLP, http://dblp.uni-trier.de} +@InProceedings{ brucker.ea:path-expressions:2013, + author = {Achim D. Brucker and Delphine Longuet and Fr{\'e}d{\'e}ric + Tuong and Burkhart Wolff}, + title = {On the Semantics of Object-oriented Data Structures and + Path Expressions}, + year = 2013, + booktitle = {Proceedings of the \acs{models} 2013 \acs{ocl} Workshop (\acs{ocl} 2013)}, + location = {Miami, \acs{usa}}, + editor = {Jordi Cabot and Martin Gogolla and Istv{\'a}n R{\'a}th and + Edward D. Willink}, + publisher = {\acs{ceur-ws}.org}, + series = {\acs{ceur} Workshop Proceedings}, + volume = 1092, + ee = {http://ceur-ws.org/Vol-1092}, + pages = {23--32}, + abstract = { \\acs{uml}/\\acs{ocl} is perceived as the de-facto standard for + specifying object-oriented models in general and data + models in particular. Since recently, all data types of + \\acs{uml}/\\acs{ocl} comprise two different exception elements: + \inlineocl{invalid} (``bottom'' in semantics terminology) + and \inlineocl{null} (for ``non-existing element''). This + has far-reaching consequences on both the logical and + algebraic properties of \\acs{ocl} expressions as well as the + path expressions over object-oriented data structures, \ie, + class models. + + In this paper, we present a formal semantics for + object-oriented data models in which all data types and, + thus, all class attributes and path expressions, support + \inlineocl{invalid} and \inlineocl{null}. Based on this + formal semantics, we present a set of \\acs{ocl} test cases that + can be used for evaluating the support of \inlineocl{null} + and \inlineocl{invalid} in \\acs{ocl} tools.}, + classification= {workshop}, + categories = {holocl}, + areas = {formal methods, software}, + keywords = {Object-oriented Data Structures, Path Expressions, + Featherweight \acs{ocl}, Null, Invalid, Formal Semantics}, + public = {yes}, + pdf = {http://www.brucker.ch/bibliography/download/2013/brucker.ea-path-expressions-2013.pdf}, + note = {An extended version of this paper is available as \acs{lri} + Technical Report 1565.}, + filelabel = {Extended Version}, + file = {http://www.brucker.ch/bibliography/download/2013/brucker.ea-path-expressions-2013-b.pdf}, + url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-path-expressions-2013} + } @@ -1382,3 +1416,32 @@ acknowledgement={brucker, 2007-04-23} } +@InProceedings{ haftmann.ea:constructive:2006, + author = {Florian Haftmann and Makarius Wenzel}, + title = {Constructive Type Classes in Isabelle}, + booktitle = {Types for Proofs and Programs, International Workshop, + {TYPES} 2006, Nottingham, UK, April 18-21, 2006, Revised + Selected Papers}, + year = 2006, + pages = {160--174}, + crossref = {altenkirch.ea:types:2007}, + url = {http://dx.doi.org/10.1007/978-3-540-74464-1_11}, + doi = {10.1007/978-3-540-74464-1_11}, + timestamp = {Thu, 04 Sep 2014 22:14:34 +0200}, + biburl = {http://dblp.uni-trier.de/rec/bib/conf/types/HaftmannW06} +} + +@Proceedings{ altenkirch.ea:types:2007, + editor = {Thorsten Altenkirch and Conor McBride}, + title = {Types for Proofs and Programs, International Workshop, + {TYPES} 2006, Nottingham, UK, April 18-21, 2006, Revised + Selected Papers}, + series = {Lecture Notes in Computer Science}, + year = 2007, + volume = 4502, + publisher = {Springer}, + isbn = {978-3-540-74463-4}, + timestamp = {Thu, 04 Sep 2014 22:14:34 +0200}, + biburl = {http://dblp.uni-trier.de/rec/bib/conf/types/2006} +} + diff --git a/src/document/root.tex b/src/document/root.tex new file mode 100644 index 0000000..d9ac898 --- /dev/null +++ b/src/document/root.tex @@ -0,0 +1,283 @@ +\documentclass[fontsize=10pt,DIV12,paper=a4,open=right,twoside,abstract=true]{scrreprt} +\usepackage{fixltx2e} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage{lmodern} +\usepackage{textcomp} +\usepackage[english]{babel} +\usepackage{isabelle} +\isatagannexa + \usepackage{omg} + \usepackage{draftwatermark} + \SetWatermarkAngle{55} + \SetWatermarkLightness{.9} + \SetWatermarkFontSize{3cm} + \SetWatermarkScale{1.4} + \SetWatermarkText{\textbf{\textsf{Draft Proposal}}} +\endisatagannexa +\usepackage[nocolortable, noaclist,isasymonly,nocolor]{hol-ocl-isar} +\renewcommand{\lfloor}{\isasymHolOclLiftLeft} +\renewcommand{\rfloor}{\isasymHolOclLiftRight} +\renewcommand{\lceil}{\isasymHolOclDropLeft} +\renewcommand{\rceil}{\isasymHolOclDropRight} +\renewcommand{\oclkeywordstyle}{\bfseries} +\renewcommand{\javakeywordstyle}{\bfseries} +\renewcommand{\smlkeywordstyle}{\bfseries} +\renewcommand{\holoclthykeywordstyle}{} + +\usepackage{lstisar} +\usepackage{railsetup} +\usepackage[]{mathtools} +\usepackage{% + multirow, + paralist, + booktabs, % " " " + threeparttable, + longtable, % Mehrseitige Tabellen +} + + + +\usepackage{graphicx} +\usepackage[numbers, sort&compress, sectionbib]{natbib} +\usepackage{chapterbib} +\usepackage[caption=false]{subfig} +\usepackage{tabu} +\usepackage{prooftree} +%\usepackage[draft]{fixme} +\usepackage[pdfpagelabels, pageanchor=false, bookmarksnumbered, plainpages=false]{hyperref} +\graphicspath{{data/},{figures/}} +\makeatletter +\renewcommand*\l@section{\bprot@dottedtocline{1}{1.5em}{2.8em}} +\renewcommand*\l@subsection{\bprot@dottedtocline{2}{3.8em}{3.7em}} +\renewcommand*\l@subsubsection{\bprot@dottedtocline{3}{7.0em}{5em}} +\renewcommand*\l@paragraph{\bprot@dottedtocline{4}{10em}{6.2em}} +%\renewcommand*\l@paragraph{\bprot@dottedtocline{4}{10em}{5.5em}} +\renewcommand*\l@subparagraph{\bprot@dottedtocline{5}{12em}{7.7em}} +%\renewcommand*\l@subparagraph{\bprot@dottedtocline{5}{12em}{6.5em}} +\makeatother +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Overall the (rightfully issued) warning by Koma Script that \rm +%%% etc. should not be used (they are deprecated since more than a +%%% decade) + \DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} + \DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} + \DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} + \DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} + \DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\setcounter{tocdepth}{3} % printed TOC not too detailed +\hypersetup{bookmarksdepth=3} % more detailed digital TOC (aka bookmarks) +\sloppy +\allowdisplaybreaks[4] +\raggedbottom + +\newcommand{\HOL}{HOL\xspace} +\newcommand{\OCL}{OCL\xspace} +\newcommand{\UML}{UML\xspace} +\newcommand{\HOLOCL}{HOL-OCL\xspace} +\newcommand{\FOCL}{Featherweight OCL\xspace} +\renewcommand{\HolTrue}{\mathrm{true}} +\renewcommand{\HolFalse}{\mathrm{false}} +\newcommand{\ptmi}[1]{\using{\mi{#1}}} +\newcommand{\Lemma}[1]{{\color{BrickRed}% + \mathbf{\operatorname{lemma}}}~\text{#1:}\quad} +\newcommand{\done}{{\color{OliveGreen}\operatorname{done}}} +\newcommand{\apply}[1]{{\holoclthykeywordstyle% + \operatorname{apply}}(\text{#1})} +\newcommand{\fun} {{\holoclthykeywordstyle\operatorname{fun}}} +\newcommand{\isardef} {{\holoclthykeywordstyle\operatorname{definition}}} +\newcommand{\where} {{\holoclthykeywordstyle\operatorname{where}}} +\newcommand{\datatype} {{\holoclthykeywordstyle\operatorname{datatype}}} +\newcommand{\types} {{\holoclthykeywordstyle\operatorname{types}}} +\newcommand{\pglabel}[1]{\text{#1}} +\renewcommand{\isasymOclUndefined}{\ensuremath{\mathtt{invalid}}} +\newcommand{\isasymOclNull}{\ensuremath{\mathtt{null}}} +\newcommand{\isasymOclInvalid}{\isasymOclUndefined} +\DeclareMathOperator{\inv}{inv} +\newcommand{\Null}[1]{{\ensuremath{\mathtt{null}_\text{{#1}}}}} +\newcommand{\testgen}{HOL-TestGen\xspace} +\newcommand{\HolOption}{\mathrm{option}} +\newcommand{\ran}{\mathrm{ran}} +\newcommand{\dom}{\mathrm{dom}} +\newcommand{\typedef}{\mathrm{typedef}} +\newcommand{\typesynonym}{\mathrm{type\_synonym}} +\newcommand{\mi}[1]{\,\text{#1}} +\newcommand{\state}[1]{\ifthenelse{\equal{}{#1}}% + {\operatorname{state}}% + {\operatorname{\mathit{state}}(#1)}% +} +\newcommand{\mocl}[1]{\text{\inlineocl|#1|}} +\DeclareMathOperator{\TCnull}{null} +\DeclareMathOperator{\HolNull}{null} +\DeclareMathOperator{\HolBot}{bot} +\newcommand{\isaAA}{\mathfrak{A}} + +% urls in roman style, theory text in math-similar italics +\urlstyle{rm} +\isabellestyle{it} +\newcommand{\ie}{i.\,e.\xspace} +\newcommand{\eg}{e.\,g.\xspace} + +\newenvironment{isamarkuplazy_text}{\par \isacommand{lazy{\isacharunderscore}text}\isamarkupfalse\isacharverbatimopen\isastyletext\begin{isapar}}{\end{isapar}\isacharverbatimclose} +\renewcommand{\isasymguillemotleft}{\isatext{\textquotedblleft}} +\renewcommand{\isasymguillemotright}{\isatext{\textquotedblright}} +\begin{document} +\renewcommand{\subsubsectionautorefname}{Section} +\renewcommand{\subsectionautorefname}{Section} +\renewcommand{\sectionautorefname}{Section} +\renewcommand{\chapterautorefname}{Chapter} +\newcommand{\subtableautorefname}{\tableautorefname} +\newcommand{\subfigureautorefname}{\figureautorefname} +\isatagannexa +\renewcommand\thepart{\Alph{part}} +\renewcommand\partname{Annex} +\endisatagannexa + +\newenvironment{matharray}[1]{\[\begin{array}{#1}}{\end{array}\]} % from 'iman.sty' +\newcommand{\indexdef}[3]% +{\ifthenelse{\equal{}{#1}}{\index{#3 (#2)|bold}}{\index{#3 (#1\ #2)|bold}}} % from 'isar.sty' + + + +\isatagafp + \title{Featherweight OCL} + \subtitle{A Proposal for a Machine-Checked Formal Semantics for OCL 2.5 %\\ + %\includegraphics[scale=.5]{figures/logo_focl} + } +\endisatagafp +\isatagannexa + \title{A Formal Machine-Checked Semantics for OCL 2.5} + \subtitle{A Proposal for the "Annex A" of the OCL Standard} +\endisatagannexa +\author{% + \href{http://www.brucker.ch/}{Achim D. Brucker}\footnotemark[1] + \and + \href{https://www.lri.fr/~tuong/}{Fr\'ed\'eric Tuong}\footnotemark[2]~\footnotemark[3] + \and + \href{https://www.lri.fr/~wolff/}{Burkhart Wolff}\footnotemark[2]~\footnotemark[3]} +\publishers{% + \footnotemark[1]~SAP SE\\ + Vincenz-Priessnitz-Str. 1, 76131 Karlsruhe, + Germany \texorpdfstring{\\}{} \href{mailto:"Achim D. Brucker" + }{achim.brucker@sap.com}\\[2em] + % + \footnotemark[2]~LRI, Univ. Paris-Sud, CNRS, CentraleSup\'elec, Universit\'e Paris-Saclay \\ + b\^at. 650 Ada Lovelace, 91405 Orsay, France \texorpdfstring{\\}{} + \href{mailto:"Frederic Tuong" + }{frederic.tuong@lri.fr} \hspace{4.5em} + \href{mailto:"Burkhart Wolff" + }{burkhart.wolff@lri.fr} \\[2em] + % + \footnotemark[3]~IRT SystemX\\ + 8 av.~de la Vauve, 91120 Palaiseau, France \texorpdfstring{\\}{} + \href{mailto:"Frederic Tuong" + }{frederic.tuong@irt-systemx.fr} \quad + \href{mailto:"Burkhart Wolff" + }{burkhart.wolff@irt-systemx.fr} +} + + +\maketitle +\isatagannexa +\cleardoublepage +\endisatagannexa + +\isatagafp + \begin{abstract} + The Unified Modeling Language (UML) is one of the few modeling + languages that is widely used in industry. While UML is mostly known + as diagrammatic modeling language (\eg, visualizing class models), + it is complemented by a textual language, called Object Constraint + Language (OCL). OCL is a textual annotation language, originally based on a + three-valued logic, that turns UML into a formal language. + Unfortunately the semantics of this specification language, captured + in the ``Annex A'' of the OCL standard, leads to different + interpretations of corner cases. Many of these corner cases had + been subject to formal analysis since more than ten years. + + The situation complicated with the arrival of version 2.3 of the OCL + standard. OCL was aligned with the latest version of UML: this led to the + extension of the three-valued logic by a second exception element, called + \inlineocl{null}. While the first exception element + \inlineocl{invalid} has a strict semantics, \inlineocl{null} has a + non strict interpretation. The combination of these semantic features lead + to remarkable confusion for implementors of OCL compilers and + interpreters. + + In this paper, we provide a formalization of the core of OCL in + HOL\@. It provides denotational definitions, a logical calculus and + operational rules that allow for the execution of OCL expressions by + a mixture of term rewriting and code compilation. Moreover, we describe + a coding-scheme for UML class models that were annotated by + code-invariants and code contracts. An implementation of this coding-scheme + has been undertaken: it consists of a kind of compiler that takes a UML class + model and translates it into a family of definitions and derived + theorems over them capturing the properties of constructors and selectors, + tests and casts resulting from the class model. However, this compiler + is \emph{not} included in this document. + + Our formalization reveals several inconsistencies and contradictions + in the current version of the OCL standard. They reflect a challenge + to define and implement OCL tools in a uniform manner. Overall, this + document is intended to provide the basis for a machine-checked text + ``Annex A'' of the OCL standard targeting at tool implementors. + \end{abstract} + \tableofcontents +\endisatagafp + +\part{Formal Semantics of OCL} +\input{introduction} +%\clearpage +\isatagafp +\input{session} +\endisatagafp +\isatagannexa +\input{UML_Types.tex} +\input{UML_Logic.tex} +\input{UML_PropertyProfiles.tex} +\input{UML_Boolean.tex} +\input{UML_Void.tex} +\input{UML_Integer.tex} +\input{UML_Real.tex} +\input{UML_String.tex} +\input{UML_Pair.tex} +\input{UML_Bag.tex} +\input{UML_Set.tex} +\input{UML_Sequence.tex} +\input{UML_Library.tex} +\input{UML_State.tex} +\input{UML_Contracts.tex} +%\input{UML_Tools.tex} +%\input{UML_Main.tex} +% \input{Design_UML.tex} +% \input{Design_OCL.tex} +\input{Analysis_UML.tex} +\input{Analysis_OCL.tex} +\part{Bibliography} +\endisatagannexa +\isatagafp +\input{conclusion} %no conclusion for standard document +\endisatagafp +\bibliographystyle{abbrvnat} +\bibliography{root} + +\isatagafp +\appendix +\part{Appendix} +\endisatagafp +\input{FOCL_Syntax} + +\isatagannexa + \part{Table of Contents} + \clearpage {\small \tableofcontents } +\endisatagannexa +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: + +% LocalWords: implementors denotational OCL UML