Import of current (Isabelle 2016) release of Featherweight OCL.

This commit is contained in:
Achim D. Brucker 2016-08-10 11:22:14 +01:00
parent ed232e8aa3
commit 02c1e24f17
45 changed files with 13515 additions and 6456 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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

68
ROOT
View File

@ -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"

View File

@ -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:

File diff suppressed because it is too large Load Diff

View File

@ -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>}{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>}{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

View File

@ -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 \<Rightarrow> Boolean"
where A : "(\<tau> \<Turnstile> (\<delta> self)) \<longrightarrow>
(\<tau> \<Turnstile> inv_Person(self)) =
((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
( \<tau> \<Turnstile> (self .boss <> null) \<and> (\<tau> \<Turnstile> ((self .salary) `\<le> (self .boss .salary))) \<and>
(\<tau> \<Turnstile> (inv_Person(self .boss))))) "
axiomatization inv_Person_at_pre :: "Person \<Rightarrow> Boolean"
where B : "(\<tau> \<Turnstile> (\<delta> self)) \<longrightarrow>
(\<tau> \<Turnstile> inv_Person_at_pre(self)) =
((\<tau> \<Turnstile> (self .boss@pre \<doteq> null)) \<or>
( \<tau> \<Turnstile> (self .boss@pre <> null) \<and>
(\<tau> \<Turnstile> (self .boss@pre .salary@pre `\<le> self .salary@pre)) \<and>
(\<tau> \<Turnstile> (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 \<Rightarrow> (\<AA>)st \<Rightarrow> bool" where
"(\<tau> \<Turnstile> (\<delta> self)) \<Longrightarrow> ((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
(\<tau> \<Turnstile> (self .boss <> null) \<and> (\<tau> \<Turnstile> (self .boss .salary `\<le> self .salary)) \<and>
( (inv(self .boss))\<tau> )))
\<Longrightarrow> ( inv self \<tau>)"
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 \<Rightarrow> Set_Integer" ("(1(_).contents'('))" 50)
axiomatization where dot_contents_def:
"(\<tau> \<Turnstile> ((self).contents() \<triangleq> result)) =
(if (\<delta> self) \<tau> = true \<tau>
then ((\<tau> \<Turnstile> true) \<and>
(\<tau> \<Turnstile> (result \<triangleq> if (self .boss \<doteq> null)
then (Set{self .salary})
else (self .boss .contents()->including(self .salary))
endif)))
else \<tau> \<Turnstile> result \<triangleq> invalid)"
consts dot_contents_AT_pre :: "Person \<Rightarrow> Set_Integer" ("(1(_).contents@pre'('))" 50)
axiomatization where dot_contents_AT_pre_def:
"(\<tau> \<Turnstile> (self).contents@pre() \<triangleq> result) =
(if (\<delta> self) \<tau> = true \<tau>
then \<tau> \<Turnstile> true \<and> (* pre *)
\<tau> \<Turnstile> (result \<triangleq> if (self).boss@pre \<doteq> null (* post *)
then Set{(self).salary@pre}
else (self).boss@pre .contents@pre()->including(self .salary@pre)
endif)
else \<tau> \<Turnstile> result \<triangleq> 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 \<Rightarrow> Integer \<Rightarrow> Void" ("(1(_).insert'(_'))" 50)
axiomatization where dot_insert_def:
"(\<tau> \<Turnstile> ((self).insert(x) \<triangleq> result)) =
(if (\<delta> self) \<tau> = true \<tau> \<and> (\<upsilon> x) \<tau> = true \<tau>
then \<tau> \<Turnstile> true \<and>
\<tau> \<Turnstile> ((self).contents() \<triangleq> (self).contents@pre()->including(x))
else \<tau> \<Turnstile> ((self).insert(x) \<triangleq> invalid))"
end

View File

@ -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 \<Rightarrow> Boolean"
where A : "(\<tau> \<Turnstile> (\<delta> self)) \<longrightarrow>
(\<tau> \<Turnstile> inv_Person(self)) =
((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
( \<tau> \<Turnstile> (self .boss <> null) \<and> (\<tau> \<Turnstile> ((self .salary) `\<le> (self .boss .salary))) \<and>
(\<tau> \<Turnstile> (inv_Person(self .boss))))) "
axiomatization inv_Person_at_pre :: "Person \<Rightarrow> Boolean"
where B : "(\<tau> \<Turnstile> (\<delta> self)) \<longrightarrow>
(\<tau> \<Turnstile> inv_Person_at_pre(self)) =
((\<tau> \<Turnstile> (self .boss@pre \<doteq> null)) \<or>
( \<tau> \<Turnstile> (self .boss@pre <> null) \<and>
(\<tau> \<Turnstile> (self .boss@pre .salary@pre `\<le> self .salary@pre)) \<and>
(\<tau> \<Turnstile> (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 \<Rightarrow> (\<AA>)st \<Rightarrow> bool" where
"(\<tau> \<Turnstile> (\<delta> self)) \<Longrightarrow> ((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
(\<tau> \<Turnstile> (self .boss <> null) \<and> (\<tau> \<Turnstile> (self .boss .salary `\<le> self .salary)) \<and>
( (inv(self .boss))\<tau> )))
\<Longrightarrow> ( inv self \<tau>)"
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 \<Rightarrow> Set_Integer" ("(1(_).contents'('))" 50)
axiomatization where dot_contents_def:
"(\<tau> \<Turnstile> ((self).contents() \<triangleq> result)) =
(if (\<delta> self) \<tau> = true \<tau>
then ((\<tau> \<Turnstile> true) \<and>
(\<tau> \<Turnstile> (result \<triangleq> if (self .boss \<doteq> null)
then (Set{self .salary})
else (self .boss .contents()->including(self .salary))
endif)))
else \<tau> \<Turnstile> result \<triangleq> invalid)"
consts dot_contents_AT_pre :: "Person \<Rightarrow> Set_Integer" ("(1(_).contents@pre'('))" 50)
axiomatization where dot_contents_AT_pre_def:
"(\<tau> \<Turnstile> (self).contents@pre() \<triangleq> result) =
(if (\<delta> self) \<tau> = true \<tau>
then \<tau> \<Turnstile> true \<and> (* pre *)
\<tau> \<Turnstile> (result \<triangleq> if (self).boss@pre \<doteq> null (* post *)
then Set{(self).salary@pre}
else (self).boss@pre .contents@pre()->including(self .salary@pre)
endif)
else \<tau> \<Turnstile> result \<triangleq> 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 \<Rightarrow> Integer \<Rightarrow> Void" ("(1(_).insert'(_'))" 50)
axiomatization where dot_insert_def:
"(\<tau> \<Turnstile> ((self).insert(x) \<triangleq> result)) =
(if (\<delta> self) \<tau> = true \<tau> \<and> (\<upsilon> x) \<tau> = true \<tau>
then \<tau> \<Turnstile> true \<and>
\<tau> \<Turnstile> ((self).contents() \<triangleq> (self).contents@pre()->including(x))
else \<tau> \<Turnstile> ((self).insert(x) \<triangleq> invalid))"
end

View File

@ -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 \<le> ((self .boss) .salary))
\end{ocl}
*}
definition Person_label\<^sub>i\<^sub>n\<^sub>v :: "Person \<Rightarrow> Boolean"
where "Person_label\<^sub>i\<^sub>n\<^sub>v (self) \<equiv>
(self .boss <> null implies (self .salary \<le>\<^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 \<Rightarrow> Boolean"
where "Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e (self) \<equiv>
(self .boss@pre <> null implies (self .salary@pre \<le>\<^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 \<equiv> (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 "\<tau> \<Turnstile> \<delta> (X .boss) \<Longrightarrow> \<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X .boss) \<and>
\<tau> \<Turnstile> 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 : "\<tau> \<Turnstile> Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v
\<Longrightarrow> \<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X) (* X represented object in state *)
\<Longrightarrow> \<exists> REC. \<tau> \<Turnstile> REC(X) \<triangleq> (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 \<Rightarrow> 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:
"(\<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> (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) \<triangleq> (self .boss <> null implies
(self .salary \<le>\<^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 \<Rightarrow> 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:
"(\<tau> \<Turnstile> Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> (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) \<triangleq> (self .boss@pre <> null implies
(self .salary@pre \<le>\<^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 :
"(\<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> 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) = ((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
( \<tau> \<Turnstile> (self .boss <> null) \<and>
\<tau> \<Turnstile> ((self .salary) \<le>\<^sub>i\<^sub>n\<^sub>t (self .boss .salary)) \<and>
\<tau> \<Turnstile> (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 :
"(\<tau> \<Turnstile> Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> 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)) = ((\<tau> \<Turnstile> (self .boss@pre \<doteq> null)) \<or>
(\<tau> \<Turnstile> (self .boss@pre <> null) \<and>
(\<tau> \<Turnstile> (self .boss@pre .salary@pre \<le>\<^sub>i\<^sub>n\<^sub>t self .salary@pre)) \<and>
(\<tau> \<Turnstile> (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 \<Rightarrow> (\<AA>)st \<Rightarrow> bool" where
"(\<tau> \<Turnstile> (\<delta> self)) \<Longrightarrow> ((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
(\<tau> \<Turnstile> (self .boss <> null) \<and> (\<tau> \<Turnstile> (self .boss .salary \<le>\<^sub>i\<^sub>n\<^sub>t self .salary)) \<and>
( (inv(self .boss))\<tau> )))
\<Longrightarrow> ( inv self \<tau>)"
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 \<Rightarrow> Set_Integer" ("(1(_).contents'('))" 50)
where contents_def:
"(self .contents()) = (\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if \<tau> \<Turnstile> (\<delta> self)
then ((\<tau> \<Turnstile> true) \<and>
(\<tau> \<Turnstile> res \<triangleq> if (self .boss \<doteq> null)
then (Set{self .salary})
else (self .boss .contents()
->including\<^sub>S\<^sub>e\<^sub>t(self .salary))
endif))
else \<tau> \<Turnstile> res \<triangleq> invalid)"
and cp0_contents:"(X .contents()) \<tau> = ((\<lambda>_. X \<tau>) .contents()) \<tau>"
interpretation contents : contract0 "contents" "\<lambda> self. true"
"\<lambda> self res. res \<triangleq> if (self .boss \<doteq> null)
then (Set{self .salary})
else (self .boss .contents()
->including\<^sub>S\<^sub>e\<^sub>t(self .salary))
endif"
proof (unfold_locales)
show "\<And>self \<tau>. true \<tau> = true \<tau>" by auto
next
show "\<And>self. \<forall>\<sigma> \<sigma>' \<sigma>''. ((\<sigma>, \<sigma>') \<Turnstile> true) = ((\<sigma>, \<sigma>'') \<Turnstile> true)" by auto
next
show "\<And>self. self .contents() \<equiv>
\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if \<tau> \<Turnstile> (\<delta> self)
then ((\<tau> \<Turnstile> true) \<and>
(\<tau> \<Turnstile> res \<triangleq> if (self .boss \<doteq> null)
then (Set{self .salary})
else (self .boss .contents()
->including\<^sub>S\<^sub>e\<^sub>t(self .salary))
endif))
else \<tau> \<Turnstile> res \<triangleq> invalid"
by(auto simp: contents_def )
next
have A:"\<And>self \<tau>. ((\<lambda>_. self \<tau>) .boss \<doteq> null) \<tau> = (\<lambda>_. (self .boss \<doteq> null) \<tau>) \<tau>"
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\<B>\<O>\<S>\<S>)
have B:"\<And>self \<tau>. (\<lambda>_. Set{(\<lambda>_. self \<tau>) .salary} \<tau>) = (\<lambda>_. Set{self .salary} \<tau>)"
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\<S>\<A>\<L>\<A>\<R>\<Y>) by simp
have C:"\<And>self \<tau>. ((\<lambda>_. self \<tau>).boss .contents()->including\<^sub>S\<^sub>e\<^sub>t((\<lambda>_. self \<tau>).salary) \<tau>) =
(self .boss .contents() ->including\<^sub>S\<^sub>e\<^sub>t(self .salary) \<tau>)"
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\<S>\<A>\<L>\<A>\<R>\<Y>)
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\<B>\<O>\<S>\<S>) by simp
show "\<And>self res \<tau>.
(res \<triangleq> if (self .boss) \<doteq> null then Set{self .salary}
else self .boss .contents()->including\<^sub>S\<^sub>e\<^sub>t(self .salary) endif) \<tau> =
((\<lambda>_. res \<tau>) \<triangleq> if (\<lambda>_. self \<tau>) .boss \<doteq> null then Set{(\<lambda>_. self \<tau>) .salary}
else(\<lambda>_. self \<tau>) .boss .contents()->including\<^sub>S\<^sub>e\<^sub>t((\<lambda>_. self \<tau>) .salary) endif) \<tau>"
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 "\<tau> \<Turnstile> \<delta> self"
shows "(\<tau> \<Turnstile> E (self .contents())) =
(\<tau> \<Turnstile> E (if self .boss \<doteq> null
then Set{self .salary}
else self .boss .contents()->including\<^sub>S\<^sub>e\<^sub>t(self .salary) endif))"
by(rule contents.unfold2[of _ _ _ "\<lambda> 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 \<Rightarrow> Set_Integer" ("(1(_).contents@pre'('))" 50)
axiomatization where contentsATpre_def:
" (self).contents@pre() = (\<lambda> \<tau>.
SOME res. let res = \<lambda> _. res in
if \<tau> \<Turnstile> (\<delta> self)
then ((\<tau> \<Turnstile> true) \<and> (* pre *)
(\<tau> \<Turnstile> (res \<triangleq> if (self).boss@pre \<doteq> 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 \<tau> \<Turnstile> res \<triangleq> invalid)"
and cp0_contents_at_pre:"(X .contents@pre()) \<tau> = ((\<lambda>_. X \<tau>) .contents@pre()) \<tau>"
interpretation contentsATpre : contract0 "contentsATpre" "\<lambda> self. true"
"\<lambda> self res. res \<triangleq> if (self .boss@pre \<doteq> 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 "\<And>self \<tau>. true \<tau> = true \<tau>" by auto
next
show "\<And>self. \<forall>\<sigma> \<sigma>' \<sigma>''. ((\<sigma>, \<sigma>') \<Turnstile> true) = ((\<sigma>, \<sigma>'') \<Turnstile> true)" by auto
next
show "\<And>self. self .contents@pre() \<equiv>
\<lambda>\<tau>. SOME res. let res = \<lambda> _. res in
if \<tau> \<Turnstile> \<delta> self
then \<tau> \<Turnstile> true \<and>
\<tau> \<Turnstile> res \<triangleq> (if self .boss@pre \<doteq> null then Set{self .salary@pre}
else self .boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre)
endif)
else \<tau> \<Turnstile> res \<triangleq> invalid"
by(auto simp: contentsATpre_def)
next
have A:"\<And>self \<tau>. ((\<lambda>_. self \<tau>) .boss@pre \<doteq> null) \<tau> = (\<lambda>_. (self .boss@pre \<doteq> null) \<tau>) \<tau>"
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\<B>\<O>\<S>\<S>_at_pre)
have B:"\<And>self \<tau>. (\<lambda>_. Set{(\<lambda>_. self \<tau>) .salary@pre} \<tau>) = (\<lambda>_. Set{self .salary@pre} \<tau>)"
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\<S>\<A>\<L>\<A>\<R>\<Y>_at_pre) by simp
have C:"\<And>self \<tau>. ((\<lambda>_. self \<tau>).boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t((\<lambda>_. self \<tau>).salary@pre) \<tau>) =
(self .boss@pre .contents@pre() ->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre) \<tau>)"
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\<S>\<A>\<L>\<A>\<R>\<Y>_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\<B>\<O>\<S>\<S>_at_pre) by simp
show "\<And>self res \<tau>.
(res \<triangleq> if (self .boss@pre) \<doteq> null then Set{self .salary@pre}
else self .boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(self .salary@pre) endif) \<tau> =
((\<lambda>_. res \<tau>) \<triangleq> if (\<lambda>_. self \<tau>) .boss@pre \<doteq> null then Set{(\<lambda>_. self \<tau>) .salary@pre}
else(\<lambda>_. self \<tau>) .boss@pre .contents@pre()->including\<^sub>S\<^sub>e\<^sub>t((\<lambda>_. self \<tau>) .salary@pre) endif) \<tau>"
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 "\<tau> \<Turnstile> \<delta> self"
shows "(\<tau> \<Turnstile> E (self .contents@pre())) =
(\<tau> \<Turnstile> E (if self .boss@pre \<doteq> 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 _ _ _ "\<lambda> 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 \<Rightarrow>Integer \<Rightarrow> Void" ("(1(_).insert'(_'))" 50)
where "self .insert(x) \<equiv>
(\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if (\<tau> \<Turnstile> (\<delta> self)) \<and> (\<tau> \<Turnstile> \<upsilon> x)
then (\<tau> \<Turnstile> true \<and>
(\<tau> \<Turnstile> ((self).contents() \<triangleq> (self).contents@pre()->including\<^sub>S\<^sub>e\<^sub>t(x))))
else \<tau> \<Turnstile> res \<triangleq> invalid)"
text{* The semantic consequences of this definition were computed inside this locale interpretation:*}
interpretation insert : contract1 "insert" "\<lambda> self x. true"
"\<lambda> self x res. ((self .contents()) \<triangleq>
(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

View File

@ -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 \<le> ((self .boss) .salary))
\end{ocl}
*}
definition Person_label\<^sub>i\<^sub>n\<^sub>v :: "Person \<Rightarrow> Boolean"
where "Person_label\<^sub>i\<^sub>n\<^sub>v (self) \<equiv>
(self .boss <> null implies (self .salary \<le>\<^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 \<Rightarrow> Boolean"
where "Person_label\<^sub>i\<^sub>n\<^sub>v\<^sub>A\<^sub>T\<^sub>p\<^sub>r\<^sub>e (self) \<equiv>
(self .boss@pre <> null implies (self .salary@pre \<le>\<^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 \<equiv> (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 "\<tau> \<Turnstile> \<delta> (X .boss) \<Longrightarrow> \<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X .boss) \<and>
\<tau> \<Turnstile> 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 : "\<tau> \<Turnstile> Person_label\<^sub>g\<^sub>l\<^sub>o\<^sub>b\<^sub>a\<^sub>l\<^sub>i\<^sub>n\<^sub>v
\<Longrightarrow> \<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(X) (* X represented object in state *)
\<Longrightarrow> \<exists> REC. \<tau> \<Turnstile> REC(X) \<triangleq> (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 \<Rightarrow> 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:
"(\<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> (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) \<triangleq> (self .boss <> null implies
(self .salary \<le>\<^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 \<Rightarrow> 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:
"(\<tau> \<Turnstile> Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> (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) \<triangleq> (self .boss@pre <> null implies
(self .salary@pre \<le>\<^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 :
"(\<tau> \<Turnstile> Person .allInstances()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> 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) = ((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
( \<tau> \<Turnstile> (self .boss <> null) \<and>
\<tau> \<Turnstile> ((self .salary) \<le>\<^sub>i\<^sub>n\<^sub>t (self .boss .salary)) \<and>
\<tau> \<Turnstile> (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 :
"(\<tau> \<Turnstile> Person .allInstances@pre()->includes\<^sub>S\<^sub>e\<^sub>t(self)) \<Longrightarrow>
(\<tau> \<Turnstile> 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)) = ((\<tau> \<Turnstile> (self .boss@pre \<doteq> null)) \<or>
(\<tau> \<Turnstile> (self .boss@pre <> null) \<and>
(\<tau> \<Turnstile> (self .boss@pre .salary@pre \<le>\<^sub>i\<^sub>n\<^sub>t self .salary@pre)) \<and>
(\<tau> \<Turnstile> (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 \<Rightarrow> (\<AA>)st \<Rightarrow> bool" where
"(\<tau> \<Turnstile> (\<delta> self)) \<Longrightarrow> ((\<tau> \<Turnstile> (self .boss \<doteq> null)) \<or>
(\<tau> \<Turnstile> (self .boss <> null) \<and> (\<tau> \<Turnstile> (self .boss .salary \<le>\<^sub>i\<^sub>n\<^sub>t self .salary)) \<and>
( (inv(self .boss))\<tau> )))
\<Longrightarrow> ( inv self \<tau>)"
section{* OCL Part: The Contract of a Recursive Query *}
text{* This part is analogous to the Analysis Model and skipped here. *}
end

76
readme.txt Normal file
View File

@ -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
(* < *)
<<skipped isar text, not shown in doc >>
(* > *)
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.

413
src/UML_Contracts.thy Normal file
View File

@ -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_\<upsilon>
fixes f_lam
fixes f :: "('\<AA>,'\<alpha>0::null)val \<Rightarrow>
'b \<Rightarrow>
('\<AA>,'res::null)val"
fixes PRE
fixes POST
assumes def_scheme': "f self x \<equiv> (\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if (\<tau> \<Turnstile> (\<delta> self)) \<and> f_\<upsilon> x \<tau>
then (\<tau> \<Turnstile> PRE self x) \<and>
(\<tau> \<Turnstile> POST self x res)
else \<tau> \<Turnstile> res \<triangleq> invalid)"
assumes all_post': "\<forall> \<sigma> \<sigma>' \<sigma>''. ((\<sigma>,\<sigma>') \<Turnstile> PRE self x) = ((\<sigma>,\<sigma>'') \<Turnstile> 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 \<tau> = PRE (\<lambda> _. self \<tau>) (f_lam x \<tau>) \<tau> "
(* this interface is preferable than :
assumes "cp self' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp (\<lambda>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) \<tau> = POST (\<lambda> _. self \<tau>) (f_lam x \<tau>) (\<lambda> _. res \<tau>) \<tau>"
assumes f_\<upsilon>_val: "\<And>a1. f_\<upsilon> (f_lam a1 \<tau>) \<tau> = f_\<upsilon> a1 \<tau>"
begin
lemma strict0 [simp]: "f invalid X = invalid"
by(rule ext, rename_tac "\<tau>", simp add: def_scheme' StrongEq_def OclValid_def false_def true_def)
lemma nullstrict0[simp]: "f null X = invalid"
by(rule ext, rename_tac "\<tau>", simp add: def_scheme' StrongEq_def OclValid_def false_def true_def)
lemma cp0 : "f self a1 \<tau> = f (\<lambda> _. self \<tau>) (f_lam a1 \<tau>) \<tau>"
proof -
have A: "(\<tau> \<Turnstile> \<delta> (\<lambda>_. self \<tau>)) = (\<tau> \<Turnstile> \<delta> self)" by(simp add: OclValid_def cp_defined[symmetric])
have B: "f_\<upsilon> (f_lam a1 \<tau>) \<tau> = f_\<upsilon> a1 \<tau>" by (rule f_\<upsilon>_val)
have D: "(\<tau> \<Turnstile> PRE (\<lambda>_. self \<tau>) (f_lam a1 \<tau>)) = ( \<tau> \<Turnstile> 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: "(\<tau> \<Turnstile> \<delta> self) \<and> f_\<upsilon> a1 \<tau>"
and pre_satisfied: "\<tau> \<Turnstile> PRE self a1"
and post_satisfiable: " \<exists>res. (\<tau> \<Turnstile> POST self a1 (\<lambda> _. res))"
and sat_for_sols_post: "(\<And>res. \<tau> \<Turnstile> POST self a1 (\<lambda> _. res) \<Longrightarrow> \<tau> \<Turnstile> E (\<lambda> _. res))"
shows "\<tau> \<Turnstile> E(f self a1)"
proof -
have cp0: "\<And> X \<tau>. E X \<tau> = E (\<lambda>_. X \<tau>) \<tau>" 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: "(\<tau> \<Turnstile> \<delta> self) \<and> (f_\<upsilon> a1 \<tau>)"
and pre_satisfied: "\<tau> \<Turnstile> PRE self a1"
and postsplit_satisfied: "\<tau> \<Turnstile> POST' self a1" (* split constraint holds on post-state *)
and post_decomposable : "\<And> res. (POST self a1 res) =
((POST' self a1) and (res \<triangleq> (BODY self a1)))"
shows "(\<tau> \<Turnstile> E(f self a1)) = (\<tau> \<Turnstile> E(BODY self a1))"
proof -
have cp0: "\<And> X \<tau>. E X \<tau> = E (\<lambda>_. X \<tau>) \<tau>" 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 :: "('\<AA>,'\<alpha>0::null)val \<Rightarrow>
('\<AA>,'res::null)val"
fixes PRE
fixes POST
assumes def_scheme: "f self \<equiv> (\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if (\<tau> \<Turnstile> (\<delta> self))
then (\<tau> \<Turnstile> PRE self) \<and>
(\<tau> \<Turnstile> POST self res)
else \<tau> \<Turnstile> res \<triangleq> invalid)"
assumes all_post: "\<forall> \<sigma> \<sigma>' \<sigma>''. ((\<sigma>,\<sigma>') \<Turnstile> PRE self) = ((\<sigma>,\<sigma>'') \<Turnstile> 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) \<tau> = PRE (\<lambda> _. self \<tau>) \<tau> "
(* this interface is preferable than :
assumes "cp self' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp (\<lambda>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) \<tau> = POST (\<lambda> _. self \<tau>) (\<lambda> _. res \<tau>) \<tau>"
sublocale contract0 < contract_scheme "\<lambda>_ _. True" "\<lambda>x _. x" "\<lambda>x _. f x" "\<lambda>x _. PRE x" "\<lambda>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' \<Longrightarrow> cp (\<lambda>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' \<Longrightarrow> cp res' \<Longrightarrow> cp (\<lambda>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' \<Longrightarrow> cp res' \<Longrightarrow> cp (\<lambda>X. f (self' X) )"
by(rule_tac f=f in cpI1, auto intro:cp0)
lemmas unfold = unfold'[simplified]
lemma unfold2 :
assumes "cp E"
and "(\<tau> \<Turnstile> \<delta> self)"
and "\<tau> \<Turnstile> PRE self"
and "\<tau> \<Turnstile> POST' self" (* split constraint holds on post-state *)
and "\<And> res. (POST self res) =
((POST' self) and (res \<triangleq> (BODY self)))"
shows "(\<tau> \<Turnstile> E(f self)) = (\<tau> \<Turnstile> E(BODY self))"
apply(rule unfold2'[simplified])
by((rule assms)+)
end
locale contract1 =
fixes f :: "('\<AA>,'\<alpha>0::null)val \<Rightarrow>
('\<AA>,'\<alpha>1::null)val \<Rightarrow>
('\<AA>,'res::null)val"
fixes PRE
fixes POST
assumes def_scheme: "f self a1 \<equiv>
(\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if (\<tau> \<Turnstile> (\<delta> self)) \<and> (\<tau> \<Turnstile> \<upsilon> a1)
then (\<tau> \<Turnstile> PRE self a1) \<and>
(\<tau> \<Turnstile> POST self a1 res)
else \<tau> \<Turnstile> res \<triangleq> invalid) "
assumes all_post: "\<forall> \<sigma> \<sigma>' \<sigma>''. ((\<sigma>,\<sigma>') \<Turnstile> PRE self a1) = ((\<sigma>,\<sigma>'') \<Turnstile> 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) \<tau> = PRE (\<lambda> _. self \<tau>) (\<lambda> _. a1 \<tau>) \<tau> "
(* this interface is preferable than :
assumes "cp self' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp (\<lambda>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) \<tau> = POST (\<lambda> _. self \<tau>)(\<lambda> _. a1 \<tau>) (\<lambda> _. res \<tau>) \<tau>"
sublocale contract1 < contract_scheme "\<lambda>a1 \<tau>. (\<tau> \<Turnstile> \<upsilon> a1)" "\<lambda>a1 \<tau>. (\<lambda> _. a1 \<tau>)"
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 "\<tau>", simp add: def_scheme StrongEq_def OclValid_def false_def true_def)
lemma defined_mono : "\<tau> \<Turnstile>\<upsilon>(f Y Z) \<Longrightarrow> (\<tau> \<Turnstile>\<delta> Y) \<and> (\<tau> \<Turnstile>\<upsilon> 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' \<Longrightarrow> cp a1' \<Longrightarrow> cp (\<lambda>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' \<Longrightarrow> cp a1' \<Longrightarrow> cp res'
\<Longrightarrow> cp (\<lambda>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' \<Longrightarrow> cp a1' \<Longrightarrow> cp res' \<Longrightarrow> cp (\<lambda>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 :: "('\<AA>,'\<alpha>0::null)val \<Rightarrow>
('\<AA>,'\<alpha>1::null)val \<Rightarrow> ('\<AA>,'\<alpha>2::null)val \<Rightarrow>
('\<AA>,'res::null)val"
fixes PRE
fixes POST
assumes def_scheme: "f self a1 a2 \<equiv>
(\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if (\<tau> \<Turnstile> (\<delta> self)) \<and> (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2)
then (\<tau> \<Turnstile> PRE self a1 a2) \<and>
(\<tau> \<Turnstile> POST self a1 a2 res)
else \<tau> \<Turnstile> res \<triangleq> invalid) "
assumes all_post: "\<forall> \<sigma> \<sigma>' \<sigma>''. ((\<sigma>,\<sigma>') \<Turnstile> PRE self a1 a2) = ((\<sigma>,\<sigma>'') \<Turnstile> 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) \<tau> = PRE (\<lambda> _. self \<tau>) (\<lambda> _. a1 \<tau>) (\<lambda> _. a2 \<tau>) \<tau> "
(* this interface is preferable than :
assumes "cp self' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp (\<lambda>X. PRE (self' X) (a1' X) (a2' X) )"
which is too polymorphic. *)
assumes cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T:"\<And>res. POST (self) (a1) (a2) (res) \<tau> =
POST (\<lambda> _. self \<tau>)(\<lambda> _. a1 \<tau>)(\<lambda> _. a2 \<tau>) (\<lambda> _. res \<tau>) \<tau>"
sublocale contract2 < contract_scheme "\<lambda>(a1,a2) \<tau>. (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2)"
"\<lambda>(a1,a2) \<tau>. (\<lambda> _.a1 \<tau>, \<lambda> _.a2 \<tau>)"
"(\<lambda>x (a,b). f x a b)"
"(\<lambda>x (a,b). PRE x a b)"
"(\<lambda>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 "\<tau>", 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 "\<tau>", simp add: def_scheme StrongEq_def OclValid_def false_def true_def)
lemma defined_mono : "\<tau> \<Turnstile>\<upsilon>(f X Y Z) \<Longrightarrow> (\<tau> \<Turnstile>\<delta> X) \<and> (\<tau> \<Turnstile>\<upsilon> Y) \<and> (\<tau> \<Turnstile>\<upsilon> 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' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp (\<lambda>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' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp res'
\<Longrightarrow> cp (\<lambda>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 \<tau> = f (\<lambda> _. self \<tau>) (\<lambda> _. a1 \<tau>) (\<lambda> _. a2 \<tau>) \<tau>"
by (rule cp0[of _ "(a1,a2)", simplified])
lemma cp [simp]: "cp self' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp res'
\<Longrightarrow> cp (\<lambda>X. f (self' X) (a1' X) (a2' X))"
by(rule_tac f=f in cpI3, auto intro:cp0')
theorem unfold :
assumes "cp E"
and "(\<tau> \<Turnstile> \<delta> self) \<and> (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2)"
and "\<tau> \<Turnstile> PRE self a1 a2"
and " \<exists>res. (\<tau> \<Turnstile> POST self a1 a2 (\<lambda> _. res))"
and "(\<And>res. \<tau> \<Turnstile> POST self a1 a2 (\<lambda> _. res) \<Longrightarrow> \<tau> \<Turnstile> E (\<lambda> _. res))"
shows "\<tau> \<Turnstile> E(f self a1 a2)"
apply(rule unfold'[of _ _ _ "(a1, a2)", simplified])
by((rule assms)+)
lemma unfold2 :
assumes "cp E"
and "(\<tau> \<Turnstile> \<delta> self) \<and> (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2)"
and "\<tau> \<Turnstile> PRE self a1 a2"
and "\<tau> \<Turnstile> POST' self a1 a2" (* split constraint holds on post-state *)
and "\<And> res. (POST self a1 a2 res) =
((POST' self a1 a2) and (res \<triangleq> (BODY self a1 a2)))"
shows "(\<tau> \<Turnstile> E(f self a1 a2)) = (\<tau> \<Turnstile> E(BODY self a1 a2))"
apply(rule unfold2'[of _ _ _ "(a1, a2)", simplified])
by((rule assms)+)
end
locale contract3 =
fixes f :: "('\<AA>,'\<alpha>0::null)val \<Rightarrow>
('\<AA>,'\<alpha>1::null)val \<Rightarrow>
('\<AA>,'\<alpha>2::null)val \<Rightarrow>
('\<AA>,'\<alpha>3::null)val \<Rightarrow>
('\<AA>,'res::null)val"
fixes PRE
fixes POST
assumes def_scheme: "f self a1 a2 a3 \<equiv>
(\<lambda> \<tau>. SOME res. let res = \<lambda> _. res in
if (\<tau> \<Turnstile> (\<delta> self)) \<and> (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2) \<and> (\<tau> \<Turnstile> \<upsilon> a3)
then (\<tau> \<Turnstile> PRE self a1 a2 a3) \<and>
(\<tau> \<Turnstile> POST self a1 a2 a3 res)
else \<tau> \<Turnstile> res \<triangleq> invalid) "
assumes all_post: "\<forall> \<sigma> \<sigma>' \<sigma>''. ((\<sigma>,\<sigma>') \<Turnstile> PRE self a1 a2 a3) = ((\<sigma>,\<sigma>'') \<Turnstile> 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) \<tau> = PRE (\<lambda> _. self \<tau>) (\<lambda> _. a1 \<tau>) (\<lambda> _. a2 \<tau>) (\<lambda> _. a3 \<tau>) \<tau> "
(* this interface is preferable than :
assumes "cp self' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp a3' \<Longrightarrow> cp (\<lambda>X. PRE (self' X) (a1' X) (a2' X) (a3' X) )"
which is too polymorphic. *)
assumes cp\<^sub>P\<^sub>O\<^sub>S\<^sub>T:"\<And>res. POST (self) (a1) (a2) (a3) (res) \<tau> =
POST (\<lambda> _. self \<tau>)(\<lambda> _. a1 \<tau>)(\<lambda> _. a2 \<tau>)(\<lambda> _. a3 \<tau>) (\<lambda> _. res \<tau>) \<tau>"
sublocale contract3 < contract_scheme "\<lambda>(a1,a2,a3) \<tau>. (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2)\<and> (\<tau> \<Turnstile> \<upsilon> a3)"
"\<lambda>(a1,a2,a3) \<tau>. (\<lambda> _.a1 \<tau>, \<lambda> _.a2 \<tau>, \<lambda> _.a3 \<tau>)"
"(\<lambda>x (a,b,c). f x a b c)"
"(\<lambda>x (a,b,c). PRE x a b c)"
"(\<lambda>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 "\<tau>", 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 "\<tau>", 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 "\<tau>", 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 "\<tau>", simp add: def_scheme StrongEq_def OclValid_def false_def true_def)
lemma defined_mono : "\<tau> \<Turnstile>\<upsilon>(f W X Y Z) \<Longrightarrow> (\<tau> \<Turnstile>\<delta> W) \<and> (\<tau> \<Turnstile>\<upsilon> X) \<and> (\<tau> \<Turnstile>\<upsilon> Y) \<and> (\<tau> \<Turnstile>\<upsilon> 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' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2'\<Longrightarrow> cp a3'
\<Longrightarrow> cp (\<lambda>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' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp a3' \<Longrightarrow> cp res'
\<Longrightarrow> cp (\<lambda>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 \<tau> = f (\<lambda> _. self \<tau>) (\<lambda> _. a1 \<tau>) (\<lambda> _. a2 \<tau>) (\<lambda> _. a3 \<tau>) \<tau>"
by (rule cp0[of _ "(a1,a2,a3)", simplified])
lemma cp [simp]: "cp self' \<Longrightarrow> cp a1' \<Longrightarrow> cp a2' \<Longrightarrow> cp a3' \<Longrightarrow> cp res'
\<Longrightarrow> cp (\<lambda>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 "(\<tau> \<Turnstile> \<delta> self) \<and> (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2) \<and> (\<tau> \<Turnstile> \<upsilon> a3)"
and "\<tau> \<Turnstile> PRE self a1 a2 a3"
and " \<exists>res. (\<tau> \<Turnstile> POST self a1 a2 a3 (\<lambda> _. res))"
and "(\<And>res. \<tau> \<Turnstile> POST self a1 a2 a3 (\<lambda> _. res) \<Longrightarrow> \<tau> \<Turnstile> E (\<lambda> _. res))"
shows "\<tau> \<Turnstile> E(f self a1 a2 a3)"
apply(rule unfold'[of _ _ _ "(a1, a2, a3)", simplified])
by((rule assms)+)
lemma unfold2 :
assumes "cp E"
and "(\<tau> \<Turnstile> \<delta> self) \<and> (\<tau> \<Turnstile> \<upsilon> a1) \<and> (\<tau> \<Turnstile> \<upsilon> a2) \<and> (\<tau> \<Turnstile> \<upsilon> a3)"
and "\<tau> \<Turnstile> PRE self a1 a2 a3"
and "\<tau> \<Turnstile> POST' self a1 a2 a3" (* split constraint holds on post-state *)
and "\<And> res. (POST self a1 a2 a3 res) =
((POST' self a1 a2 a3) and (res \<triangleq> (BODY self a1 a2 a3)))"
shows "(\<tau> \<Turnstile> E(f self a1 a2 a3)) = (\<tau> \<Turnstile> E(BODY self a1 a2 a3))"
apply(rule unfold2'[of _ _ _ "(a1, a2, a3)", simplified])
by((rule assms)+)
end
end

260
src/UML_Library.thy Normal file
View File

@ -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 :: "('\<AA>) Integer \<Rightarrow> ('\<AA>) Boolean" ("(_)->oclAsType\<^sub>I\<^sub>n\<^sub>t'(Boolean')")
where "OclAsBoolean\<^sub>I\<^sub>n\<^sub>t X = (\<lambda>\<tau>. if (\<delta> X) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>X \<tau>\<rceil>\<rceil> \<noteq> 0\<rfloor>\<rfloor>
else invalid \<tau>)"
interpretation OclAsBoolean\<^sub>I\<^sub>n\<^sub>t : profile_mono\<^sub>d OclAsBoolean\<^sub>I\<^sub>n\<^sub>t "\<lambda>x. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> \<noteq> 0\<rfloor>\<rfloor>"
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 :: "('\<AA>) Real \<Rightarrow> ('\<AA>) Boolean" ("(_)->oclAsType\<^sub>R\<^sub>e\<^sub>a\<^sub>l'(Boolean')")
where "OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l X = (\<lambda>\<tau>. if (\<delta> X) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>X \<tau>\<rceil>\<rceil> \<noteq> 0\<rfloor>\<rfloor>
else invalid \<tau>)"
interpretation OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_mono\<^sub>d OclAsBoolean\<^sub>R\<^sub>e\<^sub>a\<^sub>l "\<lambda>x. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> \<noteq> 0\<rfloor>\<rfloor>"
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 :: "('\<AA>) Real \<Rightarrow> ('\<AA>) Integer" ("(_)->oclAsType\<^sub>R\<^sub>e\<^sub>a\<^sub>l'(Integer')")
where "OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l X = (\<lambda>\<tau>. if (\<delta> X) \<tau> = true \<tau>
then \<lfloor>\<lfloor>floor \<lceil>\<lceil>X \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau>)"
interpretation OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_mono\<^sub>d OclAsInteger\<^sub>R\<^sub>e\<^sub>a\<^sub>l "\<lambda>x. \<lfloor>\<lfloor>floor \<lceil>\<lceil>x\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 :: "('\<AA>) Integer \<Rightarrow> ('\<AA>) Real" ("(_)->oclAsType\<^sub>I\<^sub>n\<^sub>t'(Real')")
where "OclAsReal\<^sub>I\<^sub>n\<^sub>t X = (\<lambda>\<tau>. if (\<delta> X) \<tau> = true \<tau>
then \<lfloor>\<lfloor>real_of_int \<lceil>\<lceil>X \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau>)"
interpretation OclAsReal\<^sub>I\<^sub>n\<^sub>t : profile_mono\<^sub>d OclAsReal\<^sub>I\<^sub>n\<^sub>t "\<lambda>x. \<lfloor>\<lfloor>real_of_int \<lceil>\<lceil>x\<rceil>\<rceil>\<rfloor>\<rfloor>"
by unfold_locales (auto simp: OclAsReal\<^sub>I\<^sub>n\<^sub>t_def bot_option_def)
lemma Integer_subtype_of_Real:
assumes "\<tau> \<Turnstile> \<delta> X"
shows "\<tau> \<Turnstile> X ->oclAsType\<^sub>I\<^sub>n\<^sub>t(Real) ->oclAsType\<^sub>R\<^sub>e\<^sub>a\<^sub>l(Integer) \<triangleq> 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 :: "[('\<AA>,'\<alpha>::null)Sequence]\<Rightarrow>('\<AA>,'\<alpha>::null,'\<alpha>::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() \<doteq> \<two>
then Pair{S->at\<^sub>S\<^sub>e\<^sub>q(\<zero>),S->at\<^sub>S\<^sub>e\<^sub>q(\<one>)}
else invalid
endif)"
definition OclAsPair\<^sub>S\<^sub>e\<^sub>t :: "[('\<AA>,'\<alpha>::null)Set]\<Rightarrow>('\<AA>,'\<alpha>::null,'\<alpha>::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() \<doteq> \<two>
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 :: "[('\<AA>,'\<alpha>::null)Bag]\<Rightarrow>('\<AA>,'\<alpha>::null,'\<alpha>::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() \<doteq> \<two>
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 :: "[('\<AA>,'\<alpha>::null)Sequence]\<Rightarrow>('\<AA>,'\<alpha>)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 :: "[('\<AA>,'\<alpha>::null,'\<alpha>::null) Pair]\<Rightarrow>('\<AA>,'\<alpha>)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 :: "('\<AA>,'\<alpha>::null) Bag\<Rightarrow>('\<AA>,'\<alpha>)Set" ("(_)->asSet\<^sub>B\<^sub>a\<^sub>g'(')")
where "OclAsSet\<^sub>B\<^sub>a\<^sub>g S = (\<lambda> \<tau>. if (\<delta> S) \<tau> = true \<tau>
then Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e\<lfloor>\<lfloor> Rep_Set_base S \<tau> \<rfloor>\<rfloor>
else if (\<upsilon> S) \<tau> = true \<tau> then null \<tau>
else invalid \<tau>)"
subsection{* Definition: asSequence *}
definition OclAsSeq\<^sub>S\<^sub>e\<^sub>t :: "[('\<AA>,'\<alpha>::null)Set]\<Rightarrow>('\<AA>,'\<alpha>)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 :: "[('\<AA>,'\<alpha>::null)Bag]\<Rightarrow>('\<AA>,'\<alpha>)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 :: "[('\<AA>,'\<alpha>::null,'\<alpha>::null) Pair]\<Rightarrow>('\<AA>,'\<alpha>)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 :: "[('\<AA>,'\<alpha>::null)Sequence]\<Rightarrow>('\<AA>,'\<alpha>)Bag" ("(_)->asBag\<^sub>S\<^sub>e\<^sub>q'(')")
where "OclAsBag\<^sub>S\<^sub>e\<^sub>q S = (\<lambda>\<tau>. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>\<lambda>s. if list_ex (op = s) \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \<tau>)\<rceil>\<rceil> then 1 else 0\<rfloor>\<rfloor>)"
definition OclAsBag\<^sub>S\<^sub>e\<^sub>t :: "[('\<AA>,'\<alpha>::null)Set]\<Rightarrow>('\<AA>,'\<alpha>)Bag" ("(_)->asBag\<^sub>S\<^sub>e\<^sub>t'(')")
where "OclAsBag\<^sub>S\<^sub>e\<^sub>t S = (\<lambda>\<tau>. Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>\<lambda>s. if s \<in> \<lceil>\<lceil>Rep_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \<tau>)\<rceil>\<rceil> then 1 else 0\<rfloor>\<rfloor>)"
lemma assumes "\<tau> \<Turnstile> \<delta> (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 :: "[('\<AA>,'\<alpha>::null,'\<alpha>::null) Pair]\<Rightarrow>('\<AA>,'\<alpha>)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{\<two>,\<one>} = (Set{}->including\<^sub>S\<^sub>e\<^sub>t(\<one>)->including\<^sub>S\<^sub>e\<^sub>t(\<two>))"
by (rule refl)
text{* Here is an example of a nested collection. *}
lemma semantic_test2:
assumes H:"(Set{\<two>} \<doteq> null) = (false::('\<AA>)Boolean)"
shows "(\<tau>::('\<AA>)st) \<Turnstile> (Set{Set{\<two>},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]: "(\<eight> \<doteq> \<six>) = 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]: "(\<two> \<doteq> \<one>) = 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]: "(\<one> \<doteq> \<two>) = 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 "\<tau> \<Turnstile> (\<zero> <\<^sub>i\<^sub>n\<^sub>t \<two>) and (\<zero> <\<^sub>i\<^sub>n\<^sub>t \<one>) "
text{* Elementary computations on Sets.*}
declare OclSelect_body_def [simp]
Assert "\<not> (\<tau> \<Turnstile> \<upsilon>(invalid::('\<AA>,'\<alpha>::null) Set))"
Assert "\<tau> \<Turnstile> \<upsilon>(null::('\<AA>,'\<alpha>::null) Set)"
Assert "\<not> (\<tau> \<Turnstile> \<delta>(null::('\<AA>,'\<alpha>::null) Set))"
Assert "\<tau> \<Turnstile> \<upsilon>(Set{})"
Assert "\<tau> \<Turnstile> \<upsilon>(Set{Set{\<two>},null})"
Assert "\<tau> \<Turnstile> \<delta>(Set{Set{\<two>},null})"
Assert "\<tau> \<Turnstile> (Set{\<two>,\<one>}->includes\<^sub>S\<^sub>e\<^sub>t(\<one>))"
Assert "\<not> (\<tau> \<Turnstile> (Set{\<two>}->includes\<^sub>S\<^sub>e\<^sub>t(\<one>)))"
Assert "\<not> (\<tau> \<Turnstile> (Set{\<two>,\<one>}->includes\<^sub>S\<^sub>e\<^sub>t(null)))"
Assert "\<tau> \<Turnstile> (Set{\<two>,null}->includes\<^sub>S\<^sub>e\<^sub>t(null))"
Assert "\<tau> \<Turnstile> (Set{null,\<two>}->includes\<^sub>S\<^sub>e\<^sub>t(null))"
Assert "\<tau> \<Turnstile> ((Set{})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \<zero> <\<^sub>i\<^sub>n\<^sub>t z))"
Assert "\<tau> \<Turnstile> ((Set{\<two>,\<one>})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \<zero> <\<^sub>i\<^sub>n\<^sub>t z))"
Assert "\<not> (\<tau> \<Turnstile> ((Set{\<two>,\<one>})->exists\<^sub>S\<^sub>e\<^sub>t(z | z <\<^sub>i\<^sub>n\<^sub>t \<zero> )))"
Assert "\<not> (\<tau> \<Turnstile> (\<delta>(Set{\<two>,null})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \<zero> <\<^sub>i\<^sub>n\<^sub>t z)))"
Assert "\<not> (\<tau> \<Turnstile> ((Set{\<two>,null})->forAll\<^sub>S\<^sub>e\<^sub>t(z | \<zero> <\<^sub>i\<^sub>n\<^sub>t z)))"
Assert "\<tau> \<Turnstile> ((Set{\<two>,null})->exists\<^sub>S\<^sub>e\<^sub>t(z | \<zero> <\<^sub>i\<^sub>n\<^sub>t z))"
Assert "\<not> (\<tau> \<Turnstile> (Set{null::'a Boolean} \<doteq> Set{}))"
Assert "\<not> (\<tau> \<Turnstile> (Set{null::'a Integer} \<doteq> Set{}))"
Assert "\<not> (\<tau> \<Turnstile> (Set{true} \<doteq> Set{false}))"
Assert "\<not> (\<tau> \<Turnstile> (Set{true,true} \<doteq> Set{false}))"
Assert "\<not> (\<tau> \<Turnstile> (Set{\<two>} \<doteq> Set{\<one>}))"
Assert "\<tau> \<Turnstile> (Set{\<two>,null,\<two>} \<doteq> Set{null,\<two>})"
Assert "\<tau> \<Turnstile> (Set{\<one>,null,\<two>} <> Set{null,\<two>})"
Assert "\<tau> \<Turnstile> (Set{Set{\<two>,null}} \<doteq> Set{Set{null,\<two>}})"
Assert "\<tau> \<Turnstile> (Set{Set{\<two>,null}} <> Set{Set{null,\<two>},null})"
Assert "\<tau> \<Turnstile> (Set{null}->select\<^sub>S\<^sub>e\<^sub>t(x | not x) \<doteq> Set{null})"
Assert "\<tau> \<Turnstile> (Set{null}->reject\<^sub>S\<^sub>e\<^sub>t(x | not x) \<doteq> Set{null})"
lemma "const (Set{Set{\<two>,null}, invalid})" by(simp add: const_ss)
text{* Elementary computations on Sequences.*}
Assert "\<not> (\<tau> \<Turnstile> \<upsilon>(invalid::('\<AA>,'\<alpha>::null) Sequence))"
Assert "\<tau> \<Turnstile> \<upsilon>(null::('\<AA>,'\<alpha>::null) Sequence)"
Assert "\<not> (\<tau> \<Turnstile> \<delta>(null::('\<AA>,'\<alpha>::null) Sequence))"
Assert "\<tau> \<Turnstile> \<upsilon>(Sequence{})"
lemma "const (Sequence{Sequence{\<two>,null}, invalid})" by(simp add: const_ss)
end

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 :: "('\<AA>,'\<alpha>::null)val \<Rightarrow> ('\<AA>,'\<beta>::null)val"
fixes g
assumes def_scheme: "(f x) \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> then g (x \<tau>) else invalid \<tau>"
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 \<tau> = f (\<lambda> _. X \<tau>) \<tau>"
by(simp add: def_scheme cp_defined[symmetric])
lemma cp[simp,code_unfold] : " cp P \<Longrightarrow> cp (\<lambda>X. f (P X) )"
by(rule cpI1[of "f"], intro allI, rule cp0, simp_all)
end
locale profile_mono_schemeV =
fixes f :: "('\<AA>,'\<alpha>::null)val \<Rightarrow> ('\<AA>,'\<beta>::null)val"
fixes g
assumes def_scheme: "(f x) \<equiv> \<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> then g (x \<tau>) else invalid \<tau>"
begin
lemma strict[simp,code_unfold]: " f invalid = invalid"
by(rule ext, simp add: def_scheme true_def false_def)
lemma cp0 : "f X \<tau> = f (\<lambda> _. X \<tau>) \<tau>"
by(simp add: def_scheme cp_valid[symmetric])
lemma cp[simp,code_unfold] : " cp P \<Longrightarrow> cp (\<lambda>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 "\<And> x. x \<noteq> bot \<Longrightarrow> x \<noteq> null \<Longrightarrow> g x \<noteq> bot"
begin
lemma const[simp,code_unfold] :
assumes C1 :"const X"
shows "const(f X)"
proof -
have const_g : "const (\<lambda>\<tau>. g (X \<tau>))" 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: "\<And> x. x \<noteq> bot \<Longrightarrow> x \<noteq> null \<Longrightarrow> g x \<noteq> bot \<and> g x \<noteq> 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]: "\<delta>(f x) = (\<delta> x)"
apply(rule ext, rename_tac "\<tau>",subst foundation22[symmetric])
apply(case_tac "\<not>(\<tau> \<Turnstile> \<delta> 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 ="\<delta> 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: "\<upsilon>(f x) = (\<delta>(f x))"
apply(rule ext, rename_tac "\<tau>",subst foundation22[symmetric])
apply(case_tac "\<not>(\<tau> \<Turnstile> \<delta> 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:: "('\<AA>,'a::null)val \<Rightarrow> '\<AA> Boolean"
assumes d_strict[simp,code_unfold]: "d invalid = false"
assumes d_cp0: "d X \<tau> = d (\<lambda> _. X \<tau>) \<tau>"
assumes d_const[simp,code_unfold]: "const X \<Longrightarrow> const (d X)"
subsection{* Property Profiles for Binary Operators *}
definition "bin' f g d\<^sub>x d\<^sub>y X Y =
(f X Y = (\<lambda> \<tau>. if (d\<^sub>x X) \<tau> = true \<tau> \<and> (d\<^sub>y Y) \<tau> = true \<tau>
then g X Y \<tau>
else invalid \<tau> ))"
definition "bin f g = bin' f (\<lambda>X Y \<tau>. g (X \<tau>) (Y \<tau>))"
lemmas [simp,code_unfold] = bin'_def bin_def
locale profile_bin_scheme =
fixes d\<^sub>x:: "('\<AA>,'a::null)val \<Rightarrow> '\<AA> Boolean"
fixes d\<^sub>y:: "('\<AA>,'b::null)val \<Rightarrow> '\<AA> Boolean"
fixes f::"('\<AA>,'a::null)val \<Rightarrow> ('\<AA>,'b::null)val \<Rightarrow> ('\<AA>,'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) \<Longrightarrow>
cp (\<lambda>x. f x Y) \<Longrightarrow>
f X invalid = invalid \<Longrightarrow>
f invalid Y = invalid \<Longrightarrow>
(\<not> (\<tau> \<Turnstile> d\<^sub>x X) \<or> \<not> (\<tau> \<Turnstile> d\<^sub>y Y)) \<Longrightarrow>
\<tau> \<Turnstile> (\<delta> f X Y \<triangleq> (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: "\<tau> \<Turnstile> d\<^sub>x X \<Longrightarrow> \<tau> \<Turnstile> d\<^sub>y Y \<Longrightarrow> \<tau> \<Turnstile> \<delta> 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 \<tau> = f (\<lambda> _. X \<tau>) (\<lambda> _. Y \<tau>) \<tau>"
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 \<Longrightarrow> cp Q \<Longrightarrow> cp (\<lambda>X. f (P X) (Q X))"
by(rule cpI2[of "f"], intro allI, rule cp0, simp_all)
lemma def_homo[simp,code_unfold]: "\<delta>(f x y) = (d\<^sub>x x and d\<^sub>y y)"
apply(rule ext, rename_tac "\<tau>",subst foundation22[symmetric])
apply(case_tac "\<not>(\<tau> \<Turnstile> d\<^sub>x x)", simp)
apply(case_tac "\<not>(\<tau> \<Turnstile> 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: "\<upsilon>(f x y) = (\<delta>(f x y))" (* [simp,code_unfold] ? *)
apply(rule ext, rename_tac "\<tau>")
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: "(\<tau> \<Turnstile> \<delta> (f x y)) = ((\<tau> \<Turnstile> d\<^sub>x x) \<and> (\<tau> \<Turnstile> 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 (\<lambda>\<tau>. g (X \<tau>) (Y \<tau>))"
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:: "('\<AA>,'b::null)val \<Rightarrow> '\<AA> Boolean"
fixes f::"('\<AA>,'a::null)val \<Rightarrow> ('\<AA>,'b::null)val \<Rightarrow> ('\<AA>,'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) \<Longrightarrow>
f X invalid = invalid \<Longrightarrow>
\<not> \<tau> \<Turnstile> d\<^sub>y Y \<Longrightarrow>
\<tau> \<Turnstile> \<delta> f X Y \<triangleq> (\<delta> X and d\<^sub>y Y)"
assumes def_scheme'[simplified]: "bin f g defined d\<^sub>y X Y"
assumes def_body': "\<And> x y \<tau>. x\<noteq>bot \<Longrightarrow> x\<noteq>null \<Longrightarrow> (d\<^sub>y y) \<tau> = true \<tau> \<Longrightarrow> g x (y \<tau>) \<noteq> bot \<and> g x (y \<tau>) \<noteq> 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::"('\<AA>,'a::null)val \<Rightarrow> ('\<AA>,'b::null)val \<Rightarrow> ('\<AA>,'c::null)val"
fixes g
assumes def_scheme[simplified]: "bin f g defined defined X Y"
assumes def_body: "\<And> x y. x\<noteq>bot \<Longrightarrow> x\<noteq>null \<Longrightarrow> y\<noteq>bot \<Longrightarrow> y\<noteq>null \<Longrightarrow>
g x y \<noteq> bot \<and> g x y \<noteq> 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::"('\<AA>,'a::null)val \<Rightarrow> ('\<AA>,'b::null)val \<Rightarrow> ('\<AA>,'c::null)val"
fixes g
assumes def_scheme[simplified]: "bin f g defined valid X Y"
assumes def_body: "\<And> x y. x\<noteq>bot \<Longrightarrow> x\<noteq>null \<Longrightarrow> y\<noteq>bot \<Longrightarrow> g x y \<noteq> bot \<and> g x y \<noteq> 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 :: "('\<AA>,'\<alpha>::null)val \<Rightarrow> ('\<AA>,'\<alpha>::null)val \<Rightarrow> ('\<AA>) 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 "\<lambda>x y. \<lfloor>\<lfloor>x = y\<rfloor>\<rfloor>"
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: "\<tau> \<Turnstile> f x y \<Longrightarrow> (\<tau> \<Turnstile> \<upsilon> x) \<and> (\<tau> \<Turnstile> \<upsilon> 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' : "\<delta> (f x y) = (\<upsilon> x and \<upsilon> 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 (\<upsilon> x) then true else invalid endif)"
by(rule ext, simp add: def_scheme OclIf_def)
lemma sym : "\<tau> \<Turnstile> (f x y) \<Longrightarrow> \<tau> \<Turnstile> (f y x)"
apply(case_tac "\<tau> \<Turnstile> \<upsilon> 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 \<tau>, auto simp: def_scheme StrongEq_sym)
lemma trans : "\<tau> \<Turnstile> (f x y) \<Longrightarrow> \<tau> \<Turnstile> (f y z) \<Longrightarrow> \<tau> \<Turnstile> (f x z)"
apply(case_tac "\<tau> \<Turnstile> \<upsilon> x")
apply(case_tac "\<tau> \<Turnstile> \<upsilon> y")
apply(auto simp: def_scheme OclValid_def)
by(fold OclValid_def, auto elim: StrongEq_L_trans)
lemma StrictRefEq_vs_StrongEq: "\<tau> \<Turnstile>(\<upsilon> x) \<Longrightarrow> \<tau> \<Turnstile>(\<upsilon> y) \<Longrightarrow> (\<tau> \<Turnstile> ((f x y) \<triangleq> (x \<triangleq> y)))"
apply(simp add: def_scheme OclValid_def)
apply(subst cp_StrongEq[of _ "(x \<triangleq> y)"])
by simp
end
locale profile_bin\<^sub>v_\<^sub>v =
fixes f :: "('\<AA>,'\<alpha>::null)val \<Rightarrow> ('\<AA>,'\<beta>::null)val \<Rightarrow> ('\<AA>,'\<gamma>::null)val"
fixes g
assumes def_scheme[simplified]: "bin f g valid valid X Y"
assumes def_body: "\<And> x y. x\<noteq>bot \<Longrightarrow> y\<noteq>bot \<Longrightarrow> g x y \<noteq> bot \<and> g x y \<noteq> 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

File diff suppressed because it is too large Load Diff

137
src/UML_Tools.thy Normal file
View File

@ -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 : "\<tau> \<Turnstile> A \<Longrightarrow> \<tau> \<Turnstile> (A and B \<triangleq> B)"
apply(tactic "ocl_subst_asm_tac @{context} 1")
apply(simp)
done
lemma test2 : "\<tau> \<Turnstile> A \<Longrightarrow> \<tau> \<Turnstile> (A and B \<triangleq> B)"
by(ocl_subst_asm, simp)
lemma test3 : "\<tau> \<Turnstile> A \<Longrightarrow> \<tau> \<Turnstile> (A and A)"
by(ocl_subst_asm, simp)
lemma test4 : "\<tau> \<Turnstile> not A \<Longrightarrow> \<tau> \<Turnstile> (A and B \<triangleq> false)"
by(ocl_subst_asm, simp)
lemma test5 : "\<tau> \<Turnstile> (A \<triangleq> null) \<Longrightarrow> \<tau> \<Turnstile> (B \<triangleq> null) \<Longrightarrow> \<not> (\<tau> \<Turnstile> (A and B))"
by(ocl_subst_asm,ocl_subst_asm,simp)
lemma test6 : "\<tau> \<Turnstile> not A \<Longrightarrow> \<not> (\<tau> \<Turnstile> (A and B))"
by(ocl_subst_asm, simp)
lemma test7 : "\<not> (\<tau> \<Turnstile> (\<upsilon> A)) \<Longrightarrow> \<tau> \<Turnstile> (not B) \<Longrightarrow> \<not> (\<tau> \<Turnstile> (A and B))"
by(ocl_subst_asm,ocl_subst_asm,simp)
(* a proof that shows that not everything is humpty dumpty ... *)
lemma X: "\<not> (\<tau> \<Turnstile> (invalid and B))"
apply(insert foundation8[of "\<tau>" "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': "\<not> (\<tau> \<Turnstile> (invalid and B))"
by(simp add:foundation10')
lemma Y: "\<not> (\<tau> \<Turnstile> (null and B))"
by(simp add: foundation10')
lemma Z: "\<not> (\<tau> \<Turnstile> (false and B))"
by(simp add: foundation10')
lemma Z': "(\<tau> \<Turnstile> (true and B)) = (\<tau> \<Turnstile> B)"
by(simp)
end
(* > *)

653
src/UML_Types.thy Normal file
View File

@ -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 ("\<lceil>_\<rceil>") (* For Real Numbers only ... Otherwise has unfortunate side-effects on syntax. *)
no_notation floor ("\<lfloor>_\<rfloor>") (* For Real Numbers only ... Otherwise has unfortunate side-effects on syntax. *)
type_notation option ("\<langle>_\<rangle>\<^sub>\<bottom>") (* NOTE: "_\<^sub>\<bottom>" also works *)
notation Some ("\<lfloor>(_)\<rfloor>")
notation None ("\<bottom>")
text{* These commands introduce an alternative, more compact notation for the type constructor
@{typ "'\<alpha> option"}, namely @{typ "\<langle>'\<alpha>\<rangle>\<^sub>\<bottom>"}. Furthermore, the constructors @{term "Some X"} and
@{term "None"} of the type @{typ "'\<alpha> option"}, namely @{term "\<lfloor>X\<rfloor>"} and @{term "\<bottom>"}. *}
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 :: "'\<alpha> option \<Rightarrow> '\<alpha>" ("\<lceil>(_)\<rceil>")
where drop_lift[simp]: "\<lceil>\<lfloor>v\<rfloor>\<rceil> = 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 \<Rightarrow> 'a" ("I\<lbrakk>_\<rbrakk>")
where "I\<lbrakk>x\<rbrakk> \<equiv> 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{\<two>},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 "\<lfloor> \<bottom> \<rfloor>"} on
@{text "'a option option"}) to a @{text null} element, which may
have an arbitrary semantic structure, and an undefinedness element @{text "\<bottom>"}
to an abstract undefinedness element @{text "bot"} (also written
@{text "\<bottom>"} 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 : "\<exists> x. x \<noteq> bot"
class null = bot +
fixes null :: "'a"
assumes null_is_valid : "null \<noteq> 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) \<equiv> (None::'a option)"
instance proof show "\<exists>x::'a option. x \<noteq> 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) \<equiv> \<lfloor> bot \<rfloor>"
instance proof show "(null::'a::bot option) \<noteq> bot"
by( simp add : null_option_def bot_option_def)
qed
end
instantiation "fun" :: (type,bot) bot
begin
definition bot_fun_def: "bot \<equiv> (\<lambda> x. bot)"
instance proof show "\<exists>(x::'a \<Rightarrow> 'b). x \<noteq> bot"
apply(rule_tac x="\<lambda> _. (SOME y. y \<noteq> 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 \<Rightarrow> 'b::null) \<equiv> (\<lambda> x. null)"
instance proof
show "(null::'a \<Rightarrow> 'b::null) \<noteq> 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 "'\<AA>"}.*}
record ('\<AA>)state =
heap :: "oid \<rightharpoonup> '\<AA> "
assocs :: "oid \<rightharpoonup> ((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 ('\<AA>)st = "'\<AA> state \<times> '\<AA> 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 \<Rightarrow> oid"
text{* Thus, if needed, we can constrain the object universe to objects by adding
the following type class constraint:*}
typ "'\<AA> :: 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 "'\<AA>"}) to an arbitrary null-type (\ie, containing
at least a destinguished @{text "null"} and @{text "invalid"} element). *}
type_synonym ('\<AA>,'\<alpha>) val = "'\<AA> st \<Rightarrow> '\<alpha>::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 :: "('\<AA>,'\<alpha>::bot) val"
where "invalid \<equiv> \<lambda> \<tau>. bot"
text{* This conservative Isabelle definition of the polymorphic constant
@{const invalid} is equivalent with the textbook definition: *}
lemma textbook_invalid: "I\<lbrakk>invalid\<rbrakk>\<tau> = bot"
by(simp add: invalid_def Sem_def)
text {* Note that the definition :
{\small
\begin{isar}[mathescape]
definition null :: "('$\mathfrak{A}$,'\<alpha>::null) val"
where "null \<equiv> \<lambda> \<tau>. 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\<lbrakk>null::('\<AA>,'\<alpha>::null) val\<rbrakk> \<tau> = (null::('\<alpha>::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 ('\<AA>)Boolean = "('\<AA>,Boolean\<^sub>b\<^sub>a\<^sub>s\<^sub>e) val"
text{* Because of the previous class definitions, Isabelle type-inference establishes that
@{typ "('\<AA>)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 ('\<AA>)Integer = "('\<AA>,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 ('\<AA>)String = "('\<AA>,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 ('\<AA>)Real = "('\<AA>,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 \<or> X = null }" by(rule_tac x="bot" in exI, simp)
type_synonym ('\<AA>)Void = "('\<AA>,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 "'\<alpha> Set"} just by
@{text "('\<AA>, ('\<alpha> option option) set) val"}. This would allow sets to contain
junk elements such as @{text "{\<bottom>}"} 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 "('\<alpha>, '\<beta>) 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) ('\<alpha>, '\<beta>) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e = "{X::('\<alpha>::null \<times> '\<beta>::null) option option.
X = bot \<or> X = null \<or> (fst\<lceil>\<lceil>X\<rceil>\<rceil> \<noteq> bot \<and> snd\<lceil>\<lceil>X\<rceil>\<rceil> \<noteq> bot)}"
by (rule_tac x="bot" in exI, simp)
text{* We ``carve'' out from the concrete type @{typ "('\<alpha>::null \<times> '\<beta>::null) option option"}
the new fully abstract type, which will not contain representations like @{term "\<lfloor>\<lfloor>(\<bottom>,a)\<rfloor>\<rfloor>"}
or @{term "\<lfloor>\<lfloor>(b,\<bottom>)\<rfloor>\<rfloor>"}. 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) \<equiv> Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e None"
instance proof show "\<exists>x::('a,'b) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \<noteq> bot"
apply(rule_tac x="Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>" 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) \<equiv> Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor> None \<rfloor>"
instance proof show "(null::('a::null,'b::null) Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \<noteq> 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 ('\<AA>,'\<alpha>,'\<beta>) Pair = "('\<AA>, ('\<alpha>,'\<beta>) 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 "'\<alpha> 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) '\<alpha> Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e ="{X::('\<alpha>::null) set option option. X = bot \<or> X = null \<or> (\<forall>x\<in>\<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> 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) \<equiv> Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e None"
instance proof show "\<exists>x::'a Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \<noteq> bot"
apply(rule_tac x="Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>" 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) \<equiv> Abs_Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor> None \<rfloor>"
instance proof show "(null::('a::null) Set\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \<noteq> 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 ('\<AA>,'\<alpha>) Set = "('\<AA>, '\<alpha> 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 "'\<alpha> 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) '\<alpha> Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e ="{X::('\<alpha>::null \<Rightarrow> nat) option option. X = bot \<or> X = null \<or> \<lceil>\<lceil>X\<rceil>\<rceil> 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) \<equiv> Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e None"
instance proof show "\<exists>x::'a Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \<noteq> bot"
apply(rule_tac x="Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>" 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) \<equiv> Abs_Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor> None \<rfloor>"
instance proof show "(null::('a::null) Bag\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \<noteq> 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 ('\<AA>,'\<alpha>) Bag = "('\<AA>, '\<alpha> 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 "'\<alpha> 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) '\<alpha> Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e ="{X::('\<alpha>::null) list option option.
X = bot \<or> X = null \<or> (\<forall>x\<in>set \<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> 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) \<equiv> Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e None"
instance proof show "\<exists>x::'a Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \<noteq> bot"
apply(rule_tac x="Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>" 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) \<equiv> Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor> None \<rfloor>"
instance proof show "(null::('a::null) Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \<noteq> 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 ('\<AA>,'\<alpha>) Sequence = "('\<AA>, '\<alpha> 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 "('\<AA>)Boolean"} \\
\inlineocl|Boolean -> Boolean| & @{typ "('\<AA>)Boolean \<Rightarrow> ('\<AA>)Boolean"} \\
\inlineocl|(Integer,Integer) -> Boolean| & @{typ "('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Boolean"} \\
\inlineocl|Set(Integer)| & @{typ "('\<AA>,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e)Set"} \\
\inlineocl|Set(Integer)-> Real| & @{typ "('\<AA>,Integer\<^sub>b\<^sub>a\<^sub>s\<^sub>e)Set \<Rightarrow> ('\<AA>)Real"} \\
\inlineocl|Set(Pair(Integer,Boolean))| & @{typ "('\<AA>,(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(<T>)| & @{typ "('\<AA>,'\<alpha>::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

View File

@ -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 "('\<AA>)Boolean"}, it is just
the strict extension of the logical
equality:
*}
overloading StrictRefEq \<equiv> "StrictRefEq :: [('\<AA>)Boolean,('\<AA>)Boolean] \<Rightarrow> ('\<AA>)Boolean"
begin
definition StrictRefEq\<^sub>B\<^sub>o\<^sub>o\<^sub>l\<^sub>e\<^sub>a\<^sub>n[code_unfold] :
"(x::('\<AA>)Boolean) \<doteq> y \<equiv> \<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then (x \<triangleq> y)\<tau>
else invalid \<tau>"
end
text{* which implies elementary properties like: *}
lemma [simp,code_unfold] : "(true \<doteq> 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 \<doteq> 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 \<doteq> 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 \<doteq> 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 \<doteq> 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 \<doteq> 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 "\<lambda> x y. (x::('\<AA>)Boolean) \<doteq> 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 \<doteq> false) = invalid" by(simp)
lemma "(invalid \<doteq> true) = invalid" by(simp)
lemma "(false \<doteq> invalid) = invalid" by(simp)
lemma "(true \<doteq> invalid) = invalid" by(simp)
lemma "((invalid::('\<AA>)Boolean) \<doteq> 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 "\<tau> \<Turnstile> \<upsilon>(true)"
Assert "\<tau> \<Turnstile> \<delta>(false)"
Assert "\<tau> |\<noteq> \<delta>(null)"
Assert "\<tau> |\<noteq> \<delta>(invalid)"
Assert "\<tau> \<Turnstile> \<upsilon>((null::('\<AA>)Boolean))"
Assert "\<tau> |\<noteq> \<upsilon>(invalid)"
Assert "\<tau> \<Turnstile> (true and true)"
Assert "\<tau> \<Turnstile> (true and true \<triangleq> true)"
Assert "\<tau> \<Turnstile> ((null or null) \<triangleq> null)"
Assert "\<tau> \<Turnstile> ((null or null) \<doteq> null)"
Assert "\<tau> \<Turnstile> ((true \<triangleq> false) \<triangleq> false)"
Assert "\<tau> \<Turnstile> ((invalid \<triangleq> false) \<triangleq> false)"
Assert "\<tau> \<Turnstile> ((invalid \<doteq> false) \<triangleq> invalid)"
Assert "\<tau> \<Turnstile> (true <> false)"
Assert "\<tau> \<Turnstile> (false <> true)"
end

View File

@ -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 "('\<AA>)Boolean"}-case as strict extension of the strong equality:*}
overloading StrictRefEq \<equiv> "StrictRefEq :: [('\<AA>)Integer,('\<AA>)Integer] \<Rightarrow> ('\<AA>)Boolean"
begin
definition StrictRefEq\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r[code_unfold] :
"(x::('\<AA>)Integer) \<doteq> y \<equiv> \<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then (x \<triangleq> y) \<tau>
else invalid \<tau>"
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 "\<lambda> x y. (x::('\<AA>)Integer) \<doteq> 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 ::"('\<AA>)Integer" ("\<zero>") where "\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>0::int\<rfloor>\<rfloor>)"
definition OclInt1 ::"('\<AA>)Integer" ("\<one>") where "\<one> = (\<lambda> _ . \<lfloor>\<lfloor>1::int\<rfloor>\<rfloor>)"
definition OclInt2 ::"('\<AA>)Integer" ("\<two>") where "\<two> = (\<lambda> _ . \<lfloor>\<lfloor>2::int\<rfloor>\<rfloor>)"
text{* Etc. *}
text_raw{* \isatagafp *}
definition OclInt3 ::"('\<AA>)Integer" ("\<three>") where "\<three> = (\<lambda> _ . \<lfloor>\<lfloor>3::int\<rfloor>\<rfloor>)"
definition OclInt4 ::"('\<AA>)Integer" ("\<four>") where "\<four> = (\<lambda> _ . \<lfloor>\<lfloor>4::int\<rfloor>\<rfloor>)"
definition OclInt5 ::"('\<AA>)Integer" ("\<five>") where "\<five> = (\<lambda> _ . \<lfloor>\<lfloor>5::int\<rfloor>\<rfloor>)"
definition OclInt6 ::"('\<AA>)Integer" ("\<six>") where "\<six> = (\<lambda> _ . \<lfloor>\<lfloor>6::int\<rfloor>\<rfloor>)"
definition OclInt7 ::"('\<AA>)Integer" ("\<seven>") where "\<seven> = (\<lambda> _ . \<lfloor>\<lfloor>7::int\<rfloor>\<rfloor>)"
definition OclInt8 ::"('\<AA>)Integer" ("\<eight>") where "\<eight> = (\<lambda> _ . \<lfloor>\<lfloor>8::int\<rfloor>\<rfloor>)"
definition OclInt9 ::"('\<AA>)Integer" ("\<nine>") where "\<nine> = (\<lambda> _ . \<lfloor>\<lfloor>9::int\<rfloor>\<rfloor>)"
definition OclInt10 ::"('\<AA>)Integer" ("\<one>\<zero>")where "\<one>\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>10::int\<rfloor>\<rfloor>)"
subsection{* Validity and Definedness Properties *}
lemma "\<delta>(null::('\<AA>)Integer) = false" by simp
lemma "\<upsilon>(null::('\<AA>)Integer) = true" by simp
lemma [simp,code_unfold]: "\<delta> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) = true"
by(simp add:defined_def true_def
bot_fun_def bot_option_def null_fun_def null_option_def)
lemma [simp,code_unfold]: "\<upsilon> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) = true"
by(simp add:valid_def true_def
bot_fun_def bot_option_def)
(* ecclectic proofs to make examples executable *)
lemma [simp,code_unfold]: "\<delta> \<zero> = true" by(simp add:OclInt0_def)
lemma [simp,code_unfold]: "\<upsilon> \<zero> = true" by(simp add:OclInt0_def)
lemma [simp,code_unfold]: "\<delta> \<one> = true" by(simp add:OclInt1_def)
lemma [simp,code_unfold]: "\<upsilon> \<one> = true" by(simp add:OclInt1_def)
lemma [simp,code_unfold]: "\<delta> \<two> = true" by(simp add:OclInt2_def)
lemma [simp,code_unfold]: "\<upsilon> \<two> = true" by(simp add:OclInt2_def)
lemma [simp,code_unfold]: "\<delta> \<six> = true" by(simp add:OclInt6_def)
lemma [simp,code_unfold]: "\<upsilon> \<six> = true" by(simp add:OclInt6_def)
lemma [simp,code_unfold]: "\<delta> \<eight> = true" by(simp add:OclInt8_def)
lemma [simp,code_unfold]: "\<upsilon> \<eight> = true" by(simp add:OclInt8_def)
lemma [simp,code_unfold]: "\<delta> \<nine> = true" by(simp add:OclInt9_def)
lemma [simp,code_unfold]: "\<upsilon> \<nine> = 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 ::"('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer" (infix "+\<^sub>i\<^sub>n\<^sub>t" 40)
where "x +\<^sub>i\<^sub>n\<^sub>t y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> + \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> + \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer" (infix "-\<^sub>i\<^sub>n\<^sub>t" 41)
where "x -\<^sub>i\<^sub>n\<^sub>t y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> - \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> - \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer" (infix "*\<^sub>i\<^sub>n\<^sub>t" 45)
where "x *\<^sub>i\<^sub>n\<^sub>t y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> * \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau>"
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> * \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer" (infix "div\<^sub>i\<^sub>n\<^sub>t" 45)
where "x div\<^sub>i\<^sub>n\<^sub>t y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then if y \<tau> \<noteq> OclInt0 \<tau> then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> div \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor> else invalid \<tau>
else invalid \<tau> "
(* TODO: special locale setup.*)
definition OclModulus\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer" (infix "mod\<^sub>i\<^sub>n\<^sub>t" 45)
where "x mod\<^sub>i\<^sub>n\<^sub>t y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then if y \<tau> \<noteq> OclInt0 \<tau> then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> mod \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor> else invalid \<tau>
else invalid \<tau> "
(* TODO: special locale setup.*)
definition OclLess\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r ::"('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Boolean" (infix "<\<^sub>i\<^sub>n\<^sub>t" 35)
where "x <\<^sub>i\<^sub>n\<^sub>t y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> < \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> < \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Integer \<Rightarrow> ('\<AA>)Integer \<Rightarrow> ('\<AA>)Boolean" (infix "\<le>\<^sub>i\<^sub>n\<^sub>t" 35)
where "x \<le>\<^sub>i\<^sub>n\<^sub>t y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> \<le> \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
interpretation OclLe\<^sub>I\<^sub>n\<^sub>t\<^sub>e\<^sub>g\<^sub>e\<^sub>r : profile_bin\<^sub>d_\<^sub>d "op \<le>\<^sub>i\<^sub>n\<^sub>t" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> \<le> \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 \<zero>) = (if \<upsilon> x and not (\<delta> x) then invalid else x endif)"
proof (rule ext, rename_tac \<tau>, case_tac "(\<upsilon> x and not (\<delta> x)) \<tau> = true \<tau>")
fix \<tau> show "(\<upsilon> x and not (\<delta> x)) \<tau> = true \<tau> \<Longrightarrow>
(x +\<^sub>i\<^sub>n\<^sub>t \<zero>) \<tau> = (if \<upsilon> x and not (\<delta> x) then invalid else x endif) \<tau>"
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 \<tau>
have A: "\<And>\<tau>. (\<tau> \<Turnstile> not (\<upsilon> x and not (\<delta> x))) = (x \<tau> = invalid \<tau> \<or> \<tau> \<Turnstile> \<delta> x)"
by (metis OclNot_not OclOr_def defined5 defined6 defined_not_I foundation11 foundation18'
foundation6 foundation7 foundation9 invalid_def)
have B: "\<tau> \<Turnstile> \<delta> x \<Longrightarrow> \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor> = x \<tau>"
apply(cases "x \<tau>", 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 \<zero>) \<tau> = (if \<upsilon> x and not (\<delta> x) then invalid else x endif) \<tau>"
when "\<tau> \<Turnstile> not (\<upsilon> x and not (\<delta> 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] :
"(\<zero> +\<^sub>i\<^sub>n\<^sub>t x) = (if \<upsilon> x and not (\<delta> 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 "\<tau> \<Turnstile> ( \<nine> \<le>\<^sub>i\<^sub>n\<^sub>t \<one>\<zero> )"
Assert "\<tau> \<Turnstile> (( \<four> +\<^sub>i\<^sub>n\<^sub>t \<four> ) \<le>\<^sub>i\<^sub>n\<^sub>t \<one>\<zero> )"
Assert "\<tau> |\<noteq> (( \<four> +\<^sub>i\<^sub>n\<^sub>t ( \<four> +\<^sub>i\<^sub>n\<^sub>t \<four> )) <\<^sub>i\<^sub>n\<^sub>t \<one>\<zero> )"
Assert "\<tau> \<Turnstile> not (\<upsilon> (null +\<^sub>i\<^sub>n\<^sub>t \<one>)) "
Assert "\<tau> \<Turnstile> (((\<nine> *\<^sub>i\<^sub>n\<^sub>t \<four>) div\<^sub>i\<^sub>n\<^sub>t \<one>\<zero>) \<le>\<^sub>i\<^sub>n\<^sub>t \<four>) "
Assert "\<tau> \<Turnstile> not (\<delta> (\<one> div\<^sub>i\<^sub>n\<^sub>t \<zero>)) "
Assert "\<tau> \<Turnstile> not (\<upsilon> (\<one> div\<^sub>i\<^sub>n\<^sub>t \<zero>)) "
lemma integer_non_null [simp]: "((\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) \<doteq> (null::('\<AA>)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::('\<AA>)Integer) \<doteq> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>)) = 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]: "(\<zero> \<doteq> null) = false" by(simp add: OclInt0_def)
lemma null_non_OclInt0 [simp,code_unfold]: "(null \<doteq> \<zero>) = false" by(simp add: OclInt0_def)
lemma OclInt1_non_null [simp,code_unfold]: "(\<one> \<doteq> null) = false" by(simp add: OclInt1_def)
lemma null_non_OclInt1 [simp,code_unfold]: "(null \<doteq> \<one>) = false" by(simp add: OclInt1_def)
lemma OclInt2_non_null [simp,code_unfold]: "(\<two> \<doteq> null) = false" by(simp add: OclInt2_def)
lemma null_non_OclInt2 [simp,code_unfold]: "(null \<doteq> \<two>) = false" by(simp add: OclInt2_def)
lemma OclInt6_non_null [simp,code_unfold]: "(\<six> \<doteq> null) = false" by(simp add: OclInt6_def)
lemma null_non_OclInt6 [simp,code_unfold]: "(null \<doteq> \<six>) = false" by(simp add: OclInt6_def)
lemma OclInt8_non_null [simp,code_unfold]: "(\<eight> \<doteq> null) = false" by(simp add: OclInt8_def)
lemma null_non_OclInt8 [simp,code_unfold]: "(null \<doteq> \<eight>) = false" by(simp add: OclInt8_def)
lemma OclInt9_non_null [simp,code_unfold]: "(\<nine> \<doteq> null) = false" by(simp add: OclInt9_def)
lemma null_non_OclInt9 [simp,code_unfold]: "(null \<doteq> \<nine>) = 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 "\<tau> \<Turnstile> ((\<zero> <\<^sub>i\<^sub>n\<^sub>t \<two>) and (\<zero> <\<^sub>i\<^sub>n\<^sub>t \<one>))"
Assert "\<tau> \<Turnstile> \<one> <> \<two>"
Assert "\<tau> \<Turnstile> \<two> <> \<one>"
Assert "\<tau> \<Turnstile> \<two> \<doteq> \<two>"
Assert "\<tau> \<Turnstile> \<upsilon> \<four>"
Assert "\<tau> \<Turnstile> \<delta> \<four>"
Assert "\<tau> \<Turnstile> \<upsilon> (null::('\<AA>)Integer)"
Assert "\<tau> \<Turnstile> (invalid \<triangleq> invalid)"
Assert "\<tau> \<Turnstile> (null \<triangleq> null)"
Assert "\<tau> \<Turnstile> (\<four> \<triangleq> \<four>)"
Assert "\<tau> |\<noteq> (\<nine> \<triangleq> \<one>\<zero>)"
Assert "\<tau> |\<noteq> (invalid \<triangleq> \<one>\<zero>)"
Assert "\<tau> |\<noteq> (null \<triangleq> \<one>\<zero>)"
Assert "\<tau> |\<noteq> (invalid \<doteq> (invalid::('\<AA>)Integer))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> \<upsilon> (invalid \<doteq> (invalid::('\<AA>)Integer))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> (invalid <> (invalid::('\<AA>)Integer))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> \<upsilon> (invalid <> (invalid::('\<AA>)Integer))" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (null \<doteq> (null::('\<AA>)Integer) )" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (null \<doteq> (null::('\<AA>)Integer) )" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (\<four> \<doteq> \<four>)"
Assert "\<tau> |\<noteq> (\<four> <> \<four>)"
Assert "\<tau> |\<noteq> (\<four> \<doteq> \<one>\<zero>)"
Assert "\<tau> \<Turnstile> (\<four> <> \<one>\<zero>)"
Assert "\<tau> |\<noteq> (\<zero> <\<^sub>i\<^sub>n\<^sub>t null)"
Assert "\<tau> |\<noteq> (\<delta> (\<zero> <\<^sub>i\<^sub>n\<^sub>t null))"
end

View File

@ -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 "('\<AA>)Boolean"}-case as strict extension of the strong equality:*}
overloading StrictRefEq \<equiv> "StrictRefEq :: [('\<AA>)Real,('\<AA>)Real] \<Rightarrow> ('\<AA>)Boolean"
begin
definition StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l [code_unfold] :
"(x::('\<AA>)Real) \<doteq> y \<equiv> \<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then (x \<triangleq> y) \<tau>
else invalid \<tau>"
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 "\<lambda> x y. (x::('\<AA>)Real) \<doteq> 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 ::"('\<AA>)Real" ("\<zero>.\<zero>") where "\<zero>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>0::real\<rfloor>\<rfloor>)"
definition OclReal1 ::"('\<AA>)Real" ("\<one>.\<zero>") where "\<one>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>1::real\<rfloor>\<rfloor>)"
definition OclReal2 ::"('\<AA>)Real" ("\<two>.\<zero>") where "\<two>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>2::real\<rfloor>\<rfloor>)"
text{* Etc. *}
text_raw{* \isatagafp *}
definition OclReal3 ::"('\<AA>)Real" ("\<three>.\<zero>") where "\<three>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>3::real\<rfloor>\<rfloor>)"
definition OclReal4 ::"('\<AA>)Real" ("\<four>.\<zero>") where "\<four>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>4::real\<rfloor>\<rfloor>)"
definition OclReal5 ::"('\<AA>)Real" ("\<five>.\<zero>") where "\<five>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>5::real\<rfloor>\<rfloor>)"
definition OclReal6 ::"('\<AA>)Real" ("\<six>.\<zero>") where "\<six>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>6::real\<rfloor>\<rfloor>)"
definition OclReal7 ::"('\<AA>)Real" ("\<seven>.\<zero>") where "\<seven>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>7::real\<rfloor>\<rfloor>)"
definition OclReal8 ::"('\<AA>)Real" ("\<eight>.\<zero>") where "\<eight>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>8::real\<rfloor>\<rfloor>)"
definition OclReal9 ::"('\<AA>)Real" ("\<nine>.\<zero>") where "\<nine>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>9::real\<rfloor>\<rfloor>)"
definition OclReal10 ::"('\<AA>)Real" ("\<one>\<zero>.\<zero>") where "\<one>\<zero>.\<zero> = (\<lambda> _ . \<lfloor>\<lfloor>10::real\<rfloor>\<rfloor>)"
definition OclRealpi ::"('\<AA>)Real" ("\<pi>") where "\<pi> = (\<lambda> _ . \<lfloor>\<lfloor>pi\<rfloor>\<rfloor>)"
subsection{* Validity and Definedness Properties *}
lemma "\<delta>(null::('\<AA>)Real) = false" by simp
lemma "\<upsilon>(null::('\<AA>)Real) = true" by simp
lemma [simp,code_unfold]: "\<delta> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) = true"
by(simp add:defined_def true_def
bot_fun_def bot_option_def null_fun_def null_option_def)
lemma [simp,code_unfold]: "\<upsilon> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) = true"
by(simp add:valid_def true_def
bot_fun_def bot_option_def)
(* ecclectic proofs to make examples executable *)
lemma [simp,code_unfold]: "\<delta> \<zero>.\<zero> = true" by(simp add:OclReal0_def)
lemma [simp,code_unfold]: "\<upsilon> \<zero>.\<zero> = true" by(simp add:OclReal0_def)
lemma [simp,code_unfold]: "\<delta> \<one>.\<zero> = true" by(simp add:OclReal1_def)
lemma [simp,code_unfold]: "\<upsilon> \<one>.\<zero> = true" by(simp add:OclReal1_def)
lemma [simp,code_unfold]: "\<delta> \<two>.\<zero> = true" by(simp add:OclReal2_def)
lemma [simp,code_unfold]: "\<upsilon> \<two>.\<zero> = true" by(simp add:OclReal2_def)
lemma [simp,code_unfold]: "\<delta> \<six>.\<zero> = true" by(simp add:OclReal6_def)
lemma [simp,code_unfold]: "\<upsilon> \<six>.\<zero> = true" by(simp add:OclReal6_def)
lemma [simp,code_unfold]: "\<delta> \<eight>.\<zero> = true" by(simp add:OclReal8_def)
lemma [simp,code_unfold]: "\<upsilon> \<eight>.\<zero> = true" by(simp add:OclReal8_def)
lemma [simp,code_unfold]: "\<delta> \<nine>.\<zero> = true" by(simp add:OclReal9_def)
lemma [simp,code_unfold]: "\<upsilon> \<nine>.\<zero> = 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 ::"('\<AA>)Real \<Rightarrow> ('\<AA>)Real \<Rightarrow> ('\<AA>)Real" (infix "+\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 40)
where "x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> + \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> + \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Real \<Rightarrow> ('\<AA>)Real \<Rightarrow> ('\<AA>)Real" (infix "-\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 41)
where "x -\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> - \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> - \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Real \<Rightarrow> ('\<AA>)Real \<Rightarrow> ('\<AA>)Real" (infix "*\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45)
where "x *\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> * \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau>"
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> * \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Real \<Rightarrow> ('\<AA>)Real \<Rightarrow> ('\<AA>)Real" (infix "div\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45)
where "x div\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then if y \<tau> \<noteq> OclReal0 \<tau> then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> / \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor> else invalid \<tau>
else invalid \<tau> "
(* 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 ::"('\<AA>)Real \<Rightarrow> ('\<AA>)Real \<Rightarrow> ('\<AA>)Real" (infix "mod\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45)
where "x mod\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then if y \<tau> \<noteq> OclReal0 \<tau> then \<lfloor>\<lfloor>mod_float \<lceil>\<lceil>x \<tau>\<rceil>\<rceil> \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor> else invalid \<tau>
else invalid \<tau> "
(* TODO: special locale setup.*)
definition OclLess\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\<AA>)Real \<Rightarrow> ('\<AA>)Real \<Rightarrow> ('\<AA>)Boolean" (infix "<\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 35)
where "x <\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> < \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
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" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> < \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 ::"('\<AA>)Real \<Rightarrow> ('\<AA>)Real \<Rightarrow> ('\<AA>)Boolean" (infix "\<le>\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 35)
where "x \<le>\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil> \<le> \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> "
interpretation OclLe\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "op \<le>\<^sub>r\<^sub>e\<^sub>a\<^sub>l" "\<lambda> x y. \<lfloor>\<lfloor>\<lceil>\<lceil>x\<rceil>\<rceil> \<le> \<lceil>\<lceil>y\<rceil>\<rceil>\<rfloor>\<rfloor>"
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 \<zero>.\<zero>) = (if \<upsilon> x and not (\<delta> x) then invalid else x endif)"
proof (rule ext, rename_tac \<tau>, case_tac "(\<upsilon> x and not (\<delta> x)) \<tau> = true \<tau>")
fix \<tau> show "(\<upsilon> x and not (\<delta> x)) \<tau> = true \<tau> \<Longrightarrow>
(x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<zero>.\<zero>) \<tau> = (if \<upsilon> x and not (\<delta> x) then invalid else x endif) \<tau>"
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 \<tau>
have A: "\<And>\<tau>. (\<tau> \<Turnstile> not (\<upsilon> x and not (\<delta> x))) = (x \<tau> = invalid \<tau> \<or> \<tau> \<Turnstile> \<delta> x)"
by (metis OclNot_not OclOr_def defined5 defined6 defined_not_I foundation11 foundation18'
foundation6 foundation7 foundation9 invalid_def)
have B: "\<tau> \<Turnstile> \<delta> x \<Longrightarrow> \<lfloor>\<lfloor>\<lceil>\<lceil>x \<tau>\<rceil>\<rceil>\<rfloor>\<rfloor> = x \<tau>"
apply(cases "x \<tau>", 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 \<zero>.\<zero>) \<tau> = (if \<upsilon> x and not (\<delta> x) then invalid else x endif) \<tau>"
when "\<tau> \<Turnstile> not (\<upsilon> x and not (\<delta> 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] :
"(\<zero>.\<zero> +\<^sub>r\<^sub>e\<^sub>a\<^sub>l x) = (if \<upsilon> x and not (\<delta> 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 "\<tau> \<Turnstile> ( \<nine>.\<zero> \<le>\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<one>\<zero>.\<zero> )"
Assert "\<tau> \<Turnstile> (( \<four>.\<zero> +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<four>.\<zero> ) \<le>\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<one>\<zero>.\<zero> )"
Assert "\<tau> |\<noteq> (( \<four>.\<zero> +\<^sub>r\<^sub>e\<^sub>a\<^sub>l ( \<four>.\<zero> +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<four>.\<zero> )) <\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<one>\<zero>.\<zero> )"
Assert "\<tau> \<Turnstile> not (\<upsilon> (null +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<one>.\<zero>)) "
Assert "\<tau> \<Turnstile> (((\<nine>.\<zero> *\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<four>.\<zero>) div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<one>\<zero>.\<zero>) \<le>\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<four>.\<zero>) "
Assert "\<tau> \<Turnstile> not (\<delta> (\<one>.\<zero> div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<zero>.\<zero>)) "
Assert "\<tau> \<Turnstile> not (\<upsilon> (\<one>.\<zero> div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \<zero>.\<zero>)) "
lemma real_non_null [simp]: "((\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) \<doteq> (null::('\<AA>)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::('\<AA>)Real) \<doteq> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>)) = 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]: "(\<zero>.\<zero> \<doteq> null) = false" by(simp add: OclReal0_def)
lemma null_non_OclReal0 [simp,code_unfold]: "(null \<doteq> \<zero>.\<zero>) = false" by(simp add: OclReal0_def)
lemma OclReal1_non_null [simp,code_unfold]: "(\<one>.\<zero> \<doteq> null) = false" by(simp add: OclReal1_def)
lemma null_non_OclReal1 [simp,code_unfold]: "(null \<doteq> \<one>.\<zero>) = false" by(simp add: OclReal1_def)
lemma OclReal2_non_null [simp,code_unfold]: "(\<two>.\<zero> \<doteq> null) = false" by(simp add: OclReal2_def)
lemma null_non_OclReal2 [simp,code_unfold]: "(null \<doteq> \<two>.\<zero>) = false" by(simp add: OclReal2_def)
lemma OclReal6_non_null [simp,code_unfold]: "(\<six>.\<zero> \<doteq> null) = false" by(simp add: OclReal6_def)
lemma null_non_OclReal6 [simp,code_unfold]: "(null \<doteq> \<six>.\<zero>) = false" by(simp add: OclReal6_def)
lemma OclReal8_non_null [simp,code_unfold]: "(\<eight>.\<zero> \<doteq> null) = false" by(simp add: OclReal8_def)
lemma null_non_OclReal8 [simp,code_unfold]: "(null \<doteq> \<eight>.\<zero>) = false" by(simp add: OclReal8_def)
lemma OclReal9_non_null [simp,code_unfold]: "(\<nine>.\<zero> \<doteq> null) = false" by(simp add: OclReal9_def)
lemma null_non_OclReal9 [simp,code_unfold]: "(null \<doteq> \<nine>.\<zero>) = 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 "\<tau> \<Turnstile> \<one>.\<zero> <> \<two>.\<zero>"
Assert "\<tau> \<Turnstile> \<two>.\<zero> <> \<one>.\<zero>"
Assert "\<tau> \<Turnstile> \<two>.\<zero> \<doteq> \<two>.\<zero>"
Assert "\<tau> \<Turnstile> \<upsilon> \<four>.\<zero>"
Assert "\<tau> \<Turnstile> \<delta> \<four>.\<zero>"
Assert "\<tau> \<Turnstile> \<upsilon> (null::('\<AA>)Real)"
Assert "\<tau> \<Turnstile> (invalid \<triangleq> invalid)"
Assert "\<tau> \<Turnstile> (null \<triangleq> null)"
Assert "\<tau> \<Turnstile> (\<four>.\<zero> \<triangleq> \<four>.\<zero>)"
Assert "\<tau> |\<noteq> (\<nine>.\<zero> \<triangleq> \<one>\<zero>.\<zero>)"
Assert "\<tau> |\<noteq> (invalid \<triangleq> \<one>\<zero>.\<zero>)"
Assert "\<tau> |\<noteq> (null \<triangleq> \<one>\<zero>.\<zero>)"
Assert "\<tau> |\<noteq> (invalid \<doteq> (invalid::('\<AA>)Real))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> \<upsilon> (invalid \<doteq> (invalid::('\<AA>)Real))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> (invalid <> (invalid::('\<AA>)Real))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> \<upsilon> (invalid <> (invalid::('\<AA>)Real))" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (null \<doteq> (null::('\<AA>)Real) )" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (null \<doteq> (null::('\<AA>)Real) )" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (\<four>.\<zero> \<doteq> \<four>.\<zero>)"
Assert "\<tau> |\<noteq> (\<four>.\<zero> <> \<four>.\<zero>)"
Assert "\<tau> |\<noteq> (\<four>.\<zero> \<doteq> \<one>\<zero>.\<zero>)"
Assert "\<tau> \<Turnstile> (\<four>.\<zero> <> \<one>\<zero>.\<zero>)"
Assert "\<tau> |\<noteq> (\<zero>.\<zero> <\<^sub>r\<^sub>e\<^sub>a\<^sub>l null)"
Assert "\<tau> |\<noteq> (\<delta> (\<zero>.\<zero> <\<^sub>r\<^sub>e\<^sub>a\<^sub>l null))"
end

View File

@ -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 "('\<AA>)Boolean"}-case as strict extension of the strong equality:*}
overloading StrictRefEq \<equiv> "StrictRefEq :: [('\<AA>)String,('\<AA>)String] \<Rightarrow> ('\<AA>)Boolean"
begin
definition StrictRefEq\<^sub>S\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g[code_unfold] :
"(x::('\<AA>)String) \<doteq> y \<equiv> \<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then (x \<triangleq> y) \<tau>
else invalid \<tau>"
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 "\<lambda> x y. (x::('\<AA>)String) \<doteq> 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 ::"('\<AA>)String" ("\<a>") where "\<a> = (\<lambda> _ . \<lfloor>\<lfloor>''a''\<rfloor>\<rfloor>)"
definition OclStringb ::"('\<AA>)String" ("\<b>") where "\<b> = (\<lambda> _ . \<lfloor>\<lfloor>''b''\<rfloor>\<rfloor>)"
definition OclStringc ::"('\<AA>)String" ("\<c>") where "\<c> = (\<lambda> _ . \<lfloor>\<lfloor>''c''\<rfloor>\<rfloor>)"
text{* Etc.*}
text_raw{* \isatagafp *}
subsection{* Validity and Definedness Properties *}
lemma "\<delta>(null::('\<AA>)String) = false" by simp
lemma "\<upsilon>(null::('\<AA>)String) = true" by simp
lemma [simp,code_unfold]: "\<delta> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) = true"
by(simp add:defined_def true_def
bot_fun_def bot_option_def null_fun_def null_option_def)
lemma [simp,code_unfold]: "\<upsilon> (\<lambda>_. \<lfloor>\<lfloor>n\<rfloor>\<rfloor>) = true"
by(simp add:valid_def true_def
bot_fun_def bot_option_def)
(* ecclectic proofs to make examples executable *)
lemma [simp,code_unfold]: "\<delta> \<a> = true" by(simp add:OclStringa_def)
lemma [simp,code_unfold]: "\<upsilon> \<a> = 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 ::"('\<AA>)String \<Rightarrow> ('\<AA>)String \<Rightarrow> ('\<AA>)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 \<equiv> \<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then \<lfloor>\<lfloor>concat [\<lceil>\<lceil>x \<tau>\<rceil>\<rceil>, \<lceil>\<lceil>y \<tau>\<rceil>\<rceil>]\<rfloor>\<rfloor>
else invalid \<tau> "
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" "\<lambda> x y. \<lfloor>\<lfloor>concat [\<lceil>\<lceil>x\<rceil>\<rceil>, \<lceil>\<lceil>y\<rceil>\<rceil>]\<rfloor>\<rfloor>"
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: "\<exists>X Y. (X +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g Y) \<noteq> (Y +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g X)"
apply(rule_tac x = "\<lambda>_. \<lfloor>\<lfloor>''b''\<rfloor>\<rfloor>" in exI)
apply(rule_tac x = "\<lambda>_. \<lfloor>\<lfloor>''a''\<rfloor>\<rfloor>" 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 "\<tau> \<Turnstile> ( \<nine> \<le>\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \<one>\<zero> )"
Assert "\<tau> \<Turnstile> (( \<four> +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \<four> ) \<le>\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \<one>\<zero> )"
Assert "\<tau> |\<noteq> (( \<four> +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g ( \<four> +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \<four> )) <\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \<one>\<zero> )"
Assert "\<tau> \<Turnstile> not (\<upsilon> (null +\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g \<one>)) "
*)
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 "\<tau> \<Turnstile> \<a> <> \<b>"
Assert "\<tau> \<Turnstile> \<b> <> \<a>"
Assert "\<tau> \<Turnstile> \<b> \<doteq> \<b>"
Assert "\<tau> \<Turnstile> \<upsilon> \<a>"
Assert "\<tau> \<Turnstile> \<delta> \<a>"
Assert "\<tau> \<Turnstile> \<upsilon> (null::('\<AA>)String)"
Assert "\<tau> \<Turnstile> (invalid \<triangleq> invalid)"
Assert "\<tau> \<Turnstile> (null \<triangleq> null)"
Assert "\<tau> \<Turnstile> (\<a> \<triangleq> \<a>)"
Assert "\<tau> |\<noteq> (\<a> \<triangleq> \<b>)"
Assert "\<tau> |\<noteq> (invalid \<triangleq> \<b>)"
Assert "\<tau> |\<noteq> (null \<triangleq> \<b>)"
Assert "\<tau> |\<noteq> (invalid \<doteq> (invalid::('\<AA>)String))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> \<upsilon> (invalid \<doteq> (invalid::('\<AA>)String))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> (invalid <> (invalid::('\<AA>)String))" (* Without typeconstraint not executable.*)
Assert "\<tau> |\<noteq> \<upsilon> (invalid <> (invalid::('\<AA>)String))" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (null \<doteq> (null::('\<AA>)String) )" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (null \<doteq> (null::('\<AA>)String) )" (* Without typeconstraint not executable.*)
Assert "\<tau> \<Turnstile> (\<b> \<doteq> \<b>)"
Assert "\<tau> |\<noteq> (\<b> <> \<b>)"
Assert "\<tau> |\<noteq> (\<b> \<doteq> \<c>)"
Assert "\<tau> \<Turnstile> (\<b> <> \<c>)"
(*Assert "\<tau> |\<noteq> (\<zero> <\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g null)"
Assert "\<tau> |\<noteq> (\<delta> (\<zero> <\<^sub>s\<^sub>t\<^sub>r\<^sub>i\<^sub>n\<^sub>g null))"
*)
end

View File

@ -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) \<equiv> Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e None"
instance proof show "\<exists>x:: Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e. x \<noteq> bot"
apply(rule_tac x="Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>" 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) \<equiv> Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor> None \<rfloor>"
instance proof show "(null:: Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e) \<noteq> 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 "('\<AA>)Void"}-case as strict extension of the strong equality:*}
overloading StrictRefEq \<equiv> "StrictRefEq :: [('\<AA>)Void,('\<AA>)Void] \<Rightarrow> ('\<AA>)Boolean"
begin
definition StrictRefEq\<^sub>V\<^sub>o\<^sub>i\<^sub>d[code_unfold] :
"(x::('\<AA>)Void) \<doteq> y \<equiv> \<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then (x \<triangleq> y) \<tau>
else invalid \<tau>"
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 "\<lambda> x y. (x::('\<AA>)Void) \<doteq> 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 "\<delta>(null::('\<AA>)Void) = false" by simp
lemma "\<upsilon>(null::('\<AA>)Void) = true" by simp
lemma [simp,code_unfold]: "\<delta> (\<lambda>_. 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]: "\<upsilon> (\<lambda>_. 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]: "\<delta> (\<lambda>_. Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>) = 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]: "\<upsilon> (\<lambda>_. Abs_Void\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>) = 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 "\<tau> \<Turnstile> ((null::('\<AA>)Void) \<doteq> null)"
end

File diff suppressed because it is too large Load Diff

View File

@ -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 \<noteq> None \<Longrightarrow> Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x \<noteq> null \<Longrightarrow> (fst \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>) \<noteq> 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 \<noteq> bot \<Longrightarrow> x \<noteq> null \<Longrightarrow> (fst \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>) \<noteq> 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 \<lfloor>None\<rfloor>"])
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 \<noteq> None \<Longrightarrow> Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x \<noteq> null \<Longrightarrow> (snd \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>) \<noteq> 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 \<noteq> bot \<Longrightarrow> x \<noteq> null \<Longrightarrow> (snd \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>) \<noteq> 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 \<lfloor>None\<rfloor>"])
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 \<equiv> "StrictRefEq :: [('\<AA>,'\<alpha>::null,'\<beta>::null)Pair,('\<AA>,'\<alpha>::null,'\<beta>::null)Pair] \<Rightarrow> ('\<AA>)Boolean"
begin
definition StrictRefEq\<^sub>P\<^sub>a\<^sub>i\<^sub>r :
"((x::('\<AA>,'\<alpha>::null,'\<beta>::null)Pair) \<doteq> y) \<equiv> (\<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then (x \<triangleq> y)\<tau>
else invalid \<tau>)"
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 "\<lambda> x y. (x::('\<AA>,'\<alpha>::null,'\<beta>::null)Pair) \<doteq> 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::"('\<AA>, '\<alpha>) val \<Rightarrow>
('\<AA>, '\<beta>) val \<Rightarrow>
('\<AA>,'\<alpha>::null,'\<beta>::null) Pair" ("Pair{(_),(_)}")
where "Pair{X,Y} \<equiv> (\<lambda> \<tau>. if (\<upsilon> X) \<tau> = true \<tau> \<and> (\<upsilon> Y) \<tau> = true \<tau>
then Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>(X \<tau>, Y \<tau>)\<rfloor>\<rfloor>
else invalid \<tau>)"
interpretation OclPair : profile_bin\<^sub>v_\<^sub>v
OclPair "\<lambda> x y. Abs_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>(x, y)\<rfloor>\<rfloor>"
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::" ('\<AA>,'\<alpha>::null,'\<beta>::null) Pair \<Rightarrow> ('\<AA>, '\<alpha>) val" (" _ .First'(')")
where "X .First() \<equiv> (\<lambda> \<tau>. if (\<delta> X) \<tau> = true \<tau>
then fst \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \<tau>)\<rceil>\<rceil>
else invalid \<tau>)"
interpretation OclFirst : profile_mono\<^sub>d OclFirst "\<lambda>x. fst \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x)\<rceil>\<rceil>"
by unfold_locales (auto simp: OclFirst_def)
subsubsection{* Definition: Second *}
definition OclSecond::" ('\<AA>,'\<alpha>::null,'\<beta>::null) Pair \<Rightarrow> ('\<AA>, '\<beta>) val" ("_ .Second'(')")
where "X .Second() \<equiv> (\<lambda> \<tau>. if (\<delta> X) \<tau> = true \<tau>
then snd \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \<tau>)\<rceil>\<rceil>
else invalid \<tau>)"
interpretation OclSecond : profile_mono\<^sub>d OclSecond "\<lambda>x. snd \<lceil>\<lceil>Rep_Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x)\<rceil>\<rceil>"
by unfold_locales (auto simp: OclSecond_def)
subsection{* Logical Properties *}
lemma 1 : "\<tau> \<Turnstile> \<upsilon> Y \<Longrightarrow> \<tau> \<Turnstile> Pair{X,Y} .First() \<triangleq> X"
apply(case_tac "\<not>(\<tau> \<Turnstile> \<upsilon> 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 : "\<tau> \<Turnstile> \<upsilon> X \<Longrightarrow> \<tau> \<Turnstile> Pair{X,Y} .Second() \<triangleq> Y"
apply(case_tac "\<not>(\<tau> \<Turnstile> \<upsilon> 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 (\<upsilon> Y) then X else invalid endif)"
apply(rule ext, rename_tac "\<tau>", simp add: foundation22[symmetric])
apply(case_tac "\<not>(\<tau> \<Turnstile> \<upsilon> Y)")
apply(erule foundation7'[THEN iffD2,
THEN foundation15[THEN iffD2,
THEN StrongEq_L_subst2_rev]],simp_all)
apply(subgoal_tac "\<tau> \<Turnstile> \<upsilon> 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 (\<upsilon> X) then Y else invalid endif)"
apply(rule ext, rename_tac "\<tau>", simp add: foundation22[symmetric])
apply(case_tac "\<not>(\<tau> \<Turnstile> \<upsilon> X)")
apply(erule foundation7'[THEN iffD2, THEN foundation15[THEN iffD2,
THEN StrongEq_L_subst2_rev]],simp_all)
apply(subgoal_tac "\<tau> \<Turnstile> \<upsilon> X")
apply(erule foundation13[THEN iffD2, THEN StrongEq_L_subst2_rev], simp_all)
by(erule 2)
(* < *)
subsection{* Test Statements*}
(*
Assert "(\<tau> \<Turnstile> (Pair{\<lambda>_. \<lfloor>\<lfloor>x\<rfloor>\<rfloor>,\<lambda>_. \<lfloor>\<lfloor>x\<rfloor>\<rfloor>} \<doteq> Pair{\<lambda>_. \<lfloor>\<lfloor>x\<rfloor>\<rfloor>,\<lambda>_. \<lfloor>\<lfloor>x\<rfloor>\<rfloor>}))"
Assert "(\<tau> \<Turnstile> (Pair{\<lambda>_. \<lfloor>x\<rfloor>,\<lambda>_. \<lfloor>x\<rfloor>} \<doteq> Pair{\<lambda>_. \<lfloor>x\<rfloor>,\<lambda>_. \<lfloor>x\<rfloor>}))"
*)
instantiation Pair\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (equal,equal)equal
begin
definition "HOL.equal k l \<longleftrightarrow> (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) \<longleftrightarrow> 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 "\<tau> \<Turnstile> invalid .First() \<triangleq> invalid "
Assert "\<tau> \<Turnstile> null .First() \<triangleq> invalid "
Assert "\<tau> \<Turnstile> null .Second() \<triangleq> invalid .Second() "
Assert "\<tau> \<Turnstile> Pair{invalid, true} \<triangleq> invalid "
Assert "\<tau> \<Turnstile> \<upsilon>(Pair{null, true}.First())"
Assert "\<tau> \<Turnstile> (Pair{null, true}).First() \<triangleq> null "
Assert "\<tau> \<Turnstile> (Pair{null, Pair{true,invalid}}).First() \<triangleq> invalid "
(*
Assert "\<not> (\<tau> \<Turnstile> (Pair{\<one>,\<two>} \<doteq> Pair{\<two>,\<one>}))"
*)
(* > *)
end

View File

@ -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 ("\<bottom>")
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: "\<tau> \<Turnstile> (\<delta> X) \<Longrightarrow> \<forall>x\<in>set \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (X \<tau>)\<rceil>\<rceil>. x \<noteq> bot"
apply(insert Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e [of "X \<tau>"], 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 \<tau>) = 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 \<tau>) = 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 \<equiv> "StrictRefEq :: [('\<AA>,'\<alpha>::null)Sequence,('\<AA>,'\<alpha>::null)Sequence] \<Rightarrow> ('\<AA>)Boolean"
begin
definition StrictRefEq\<^sub>S\<^sub>e\<^sub>q :
"((x::('\<AA>,'\<alpha>::null)Sequence) \<doteq> y) \<equiv> (\<lambda> \<tau>. if (\<upsilon> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then (x \<triangleq> y)\<tau>
else invalid \<tau>)"
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 "\<lambda> x y. (x::('\<AA>,'\<alpha>::null)Sequence) \<doteq> y"
by unfold_locales (auto simp: StrictRefEq\<^sub>S\<^sub>e\<^sub>q)
subsection{* Constants: mtSequence *}
definition mtSequence ::"('\<AA>,'\<alpha>::null) Sequence" ("Sequence{}")
where "Sequence{} \<equiv> (\<lambda> \<tau>. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>[]::'\<alpha> list\<rfloor>\<rfloor> )"
lemma mtSequence_defined[simp,code_unfold]:"\<delta>(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]:"\<upsilon>(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: "\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (Sequence{} \<tau>)\<rceil>\<rceil> = []"
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 :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>) val] \<Rightarrow> ('\<AA>,'\<alpha>) Sequence"
where "OclPrepend x y = (\<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor> (y \<tau>)#\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil> \<rfloor>\<rfloor>
else invalid \<tau> )"
notation OclPrepend ("_->prepend\<^sub>S\<^sub>e\<^sub>q'(_')")
interpretation OclPrepend:profile_bin\<^sub>d_\<^sub>v OclPrepend "\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\<lfloor>\<lfloor>y#\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>\<rfloor>\<rfloor>"
proof -
have A : "\<And>x y. x \<noteq> bot \<Longrightarrow> x \<noteq> null \<Longrightarrow> y \<noteq> bot \<Longrightarrow>
\<lfloor>\<lfloor>y#\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>\<rfloor>\<rfloor> \<in> {X. X = bot \<or> X = null \<or> (\<forall>x\<in>set \<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> 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 (\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>y#\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>\<rfloor>\<rfloor>)"
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 \<lfloor>\<lfloor>y#\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>\<rfloor>\<rfloor> = 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\<lfloor>\<lfloor>y#\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>\<rfloor>\<rfloor> = Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>"
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 => ('\<AA>,'a::null) Sequence" ("Sequence{(_)}")
translations
"Sequence{x, xs}" == "CONST OclPrepend (Sequence{xs}) x"
"Sequence{x}" == "CONST OclPrepend (Sequence{}) x "
subsection{* Definition: Including *}
definition OclIncluding :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>) val] \<Rightarrow> ('\<AA>,'\<alpha>) Sequence"
where "OclIncluding x y = (\<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor> \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil> @ [y \<tau>] \<rfloor>\<rfloor>
else invalid \<tau> )"
notation OclIncluding ("_->including\<^sub>S\<^sub>e\<^sub>q'(_')")
interpretation OclIncluding :
profile_bin\<^sub>d_\<^sub>v OclIncluding "\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> @ [y]\<rfloor>\<rfloor>"
proof -
have A : "\<And>x y. x \<noteq> bot \<Longrightarrow> x \<noteq> null \<Longrightarrow> y \<noteq> bot \<Longrightarrow>
\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> @ [y]\<rfloor>\<rfloor> \<in> {X. X = bot \<or> X = null \<or> (\<forall>x\<in>set \<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> 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 (\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> @ [y]\<rfloor>\<rfloor>)"
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 \<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> @ [y]\<rfloor>\<rfloor> = 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\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> @ [y]\<rfloor>\<rfloor> = Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>None\<rfloor>"
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: "\<And>S b \<tau>. S \<noteq> \<bottom> \<Longrightarrow> S \<noteq> null \<Longrightarrow> b \<noteq> \<bottom> \<Longrightarrow>
\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\<rceil>\<rceil> @ [b]\<rfloor>\<rfloor> \<in> {X. X = bot \<or> X = null \<or> (\<forall>x\<in>set \<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> \<bottom>)}"
by(auto intro!:Sequence_inv_lemma[simplified OclValid_def
defined_def false_def true_def null_fun_def bot_fun_def])
have B: "\<And>S a \<tau>. S \<noteq> \<bottom> \<Longrightarrow> S \<noteq> null \<Longrightarrow> a \<noteq> \<bottom> \<Longrightarrow>
\<lfloor>\<lfloor>a # \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\<rceil>\<rceil>\<rfloor>\<rfloor> \<in> {X. X = bot \<or> X = null \<or> (\<forall>x\<in>set \<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> \<bottom>)}"
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 :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>) val] \<Rightarrow> ('\<AA>,'\<alpha>) Sequence"
where "OclExcluding x y = (\<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<upsilon> y) \<tau> = true \<tau>
then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor> filter (\<lambda>x. x = y \<tau>)
\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> )"
notation OclExcluding ("_->excluding\<^sub>S\<^sub>e\<^sub>q'(_')")
interpretation OclExcluding:profile_bin\<^sub>d_\<^sub>v OclExcluding
"\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor> filter (\<lambda>x. x = y) \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x)\<rceil>\<rceil>\<rfloor>\<rfloor>"
proof -
show "profile_bin\<^sub>d_\<^sub>v OclExcluding (\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor>[x\<leftarrow>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> . x = y]\<rfloor>\<rfloor>)"
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 :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>) val] \<Rightarrow> ('\<AA>,'\<alpha>) Sequence"
where "OclAppend = OclIncluding"
notation OclAppend ("_->append\<^sub>S\<^sub>e\<^sub>q'(_')")
interpretation OclAppend :
profile_bin\<^sub>d_\<^sub>v OclAppend "\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> @ [y]\<rfloor>\<rfloor>"
apply unfold_locales
by(auto simp: OclAppend_def bin_def bin'_def
OclIncluding.def_scheme OclIncluding.def_body)
subsection{* Definition: Union *}
definition OclUnion :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>) Sequence] \<Rightarrow> ('\<AA>,'\<alpha>) Sequence"
where "OclUnion x y = (\<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e \<lfloor>\<lfloor> \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil> @
\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (y \<tau>)\<rceil>\<rceil>\<rfloor>\<rfloor>
else invalid \<tau> )"
notation OclUnion ("_->union\<^sub>S\<^sub>e\<^sub>q'(_')")
interpretation OclUnion :
profile_bin\<^sub>d_\<^sub>d OclUnion "\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil> @ \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\<rceil>\<rceil>\<rfloor>\<rfloor>"
proof -
have A : "\<And>x y. x \<noteq> \<bottom> \<Longrightarrow> x \<noteq> null \<Longrightarrow> \<forall>x\<in>set \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>. x \<noteq> \<bottom> "
apply(rule Sequence_inv_lemma[of \<tau>])
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 (\<lambda>x y. Abs_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e x\<rceil>\<rceil>@\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e y\<rceil>\<rceil>\<rfloor>\<rfloor>)"
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 :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>) Integer] \<Rightarrow> ('\<AA>,'\<alpha>) val"
where "OclAt x y = (\<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> \<and> (\<delta> y) \<tau> = true \<tau>
then if 1 \<le> \<lceil>\<lceil>y \<tau>\<rceil>\<rceil> \<and> \<lceil>\<lceil>y \<tau>\<rceil>\<rceil> \<le> length\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil>
then \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil> ! (nat \<lceil>\<lceil>y \<tau>\<rceil>\<rceil> - 1)
else invalid \<tau>
else invalid \<tau> )"
notation OclAt ("_->at\<^sub>S\<^sub>e\<^sub>q'(_')")
(*TODO Locale - Equivalent*)
subsection{* Definition: First *}
definition OclFirst :: "[('\<AA>,'\<alpha>::null) Sequence] \<Rightarrow> ('\<AA>,'\<alpha>) val"
where "OclFirst x = (\<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> then
case \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil> of [] \<Rightarrow> invalid \<tau>
| x # _ \<Rightarrow> x
else invalid \<tau> )"
notation OclFirst ("_->first\<^sub>S\<^sub>e\<^sub>q'(_')")
(*TODO Locale - Equivalent*)
subsection{* Definition: Last *}
definition OclLast :: "[('\<AA>,'\<alpha>::null) Sequence] \<Rightarrow> ('\<AA>,'\<alpha>) val"
where "OclLast x = (\<lambda> \<tau>. if (\<delta> x) \<tau> = true \<tau> then
if \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil> = [] then
invalid \<tau>
else
last \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>)\<rceil>\<rceil>
else invalid \<tau> )"
notation OclLast ("_->last\<^sub>S\<^sub>e\<^sub>q'(_')")
(*TODO Locale - Equivalent*)
subsection{* Definition: Iterate *}
definition OclIterate :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<beta>::null)val,
('\<AA>,'\<alpha>)val\<Rightarrow>('\<AA>,'\<beta>)val\<Rightarrow>('\<AA>,'\<beta>)val] \<Rightarrow> ('\<AA>,'\<beta>)val"
where "OclIterate S A F = (\<lambda> \<tau>. if (\<delta> S) \<tau> = true \<tau> \<and> (\<upsilon> A) \<tau> = true \<tau>
then (foldr (F) (map (\<lambda>a \<tau>. a) \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (S \<tau>)\<rceil>\<rceil>))(A)\<tau>
else \<bottom>)"
syntax
"_OclIterateSeq" :: "[('\<AA>,'\<alpha>::null) Sequence, idt, idt, '\<alpha>, '\<beta>] => ('\<AA>,'\<gamma>)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 :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>)val\<Rightarrow>('\<AA>)Boolean] \<Rightarrow> '\<AA> Boolean"
where "OclForall S P = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = true | x and (P b)))"
syntax
"_OclForallSeq" :: "[('\<AA>,'\<alpha>::null) Sequence,id,('\<AA>)Boolean] \<Rightarrow> '\<AA> 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 :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>)val\<Rightarrow>('\<AA>)Boolean] \<Rightarrow> '\<AA> Boolean"
where "OclExists S P = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = false | x or (P b)))"
syntax
"_OclExistSeq" :: "[('\<AA>,'\<alpha>::null) Sequence,id,('\<AA>)Boolean] \<Rightarrow> '\<AA> 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 :: "[('\<AA>,'\<alpha>::null)Sequence,('\<AA>,'\<alpha>)val\<Rightarrow>('\<AA>,'\<beta>)val]\<Rightarrow>('\<AA>,'\<beta>::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" :: "[('\<AA>,'\<alpha>::null) Sequence,id,('\<AA>)Boolean] \<Rightarrow> '\<AA> 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 :: "[('\<AA>,'\<alpha>::null)Sequence,('\<AA>,'\<alpha>)val\<Rightarrow>('\<AA>)Boolean]\<Rightarrow>('\<AA>,'\<alpha>::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" :: "[('\<AA>,'\<alpha>::null) Sequence,id,('\<AA>)Boolean] \<Rightarrow> '\<AA> 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 :: "[('\<AA>,'\<alpha>::null)Sequence]\<Rightarrow>('\<AA>)Integer" ("(_)->size\<^sub>S\<^sub>e\<^sub>q'(')")
where "OclSize S = (S->iterate\<^sub>S\<^sub>e\<^sub>q(b; x = \<zero> | x +\<^sub>i\<^sub>n\<^sub>t \<one> ))"
(*TODO Locale - Equivalent*)
subsection{* Definition: IsEmpty *}
definition OclIsEmpty :: "('\<AA>,'\<alpha>::null) Sequence \<Rightarrow> '\<AA> Boolean"
where "OclIsEmpty x = ((\<upsilon> x and not (\<delta> x)) or ((OclSize x) \<doteq> \<zero>))"
notation OclIsEmpty ("_->isEmpty\<^sub>S\<^sub>e\<^sub>q'(')" (*[66]*))
(*TODO Locale - Equivalent*)
subsection{* Definition: NotEmpty *}
definition OclNotEmpty :: "('\<AA>,'\<alpha>::null) Sequence \<Rightarrow> '\<AA> 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 = (\<lambda> \<tau>.
if x \<tau> = invalid \<tau> then
\<bottom>
else
case drop (drop (Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e (x \<tau>))) of [] \<Rightarrow> \<bottom>
| l \<Rightarrow> hd l)"
notation OclANY ("_->any\<^sub>S\<^sub>e\<^sub>q'(')")
(*TODO Locale - Equivalent*)
subsection{* Definition (future operators) *}
consts (* abstract set collection operations *)
OclCount :: "[('\<AA>,'\<alpha>::null) Sequence,('\<AA>,'\<alpha>) Sequence] \<Rightarrow> '\<AA> Integer"
(*OclFlatten*)
(*OclInsertAt*)
(*OclSubSequence*)
(*OclIndexOf*)
(*OclReverse*)
OclSum :: " ('\<AA>,'\<alpha>::null) Sequence \<Rightarrow> '\<AA> 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)) \<tau> = ((\<lambda> _. X \<tau>)->including\<^sub>S\<^sub>e\<^sub>q(\<lambda> _. x \<tau>)) \<tau>"
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)) \<tau> =
((\<lambda> _. X \<tau>)->iterate\<^sub>S\<^sub>e\<^sub>q(a; x = A | P a x)) \<tau>"
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 "\<tau>")
apply(case_tac "\<tau> \<Turnstile> \<upsilon> 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 : "\<And>X. P invalid X = invalid"
and P_valid_arg: "\<And> \<tau>. (\<upsilon> A) \<tau> = (\<upsilon> (P a A)) \<tau>"
and P_cp : "\<And> x y \<tau>. P x y \<tau> = P (\<lambda> _. x \<tau>) y \<tau>"
and P_cp' : "\<And> x y \<tau>. P x y \<tau> = P x (\<lambda> _. y \<tau>) \<tau>"
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: "\<And>S b \<tau>. S \<noteq> \<bottom> \<Longrightarrow> S \<noteq> null \<Longrightarrow> b \<noteq> \<bottom> \<Longrightarrow>
\<lfloor>\<lfloor>\<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\<rceil>\<rceil> @ [b]\<rfloor>\<rfloor> \<in> {X. X = bot \<or> X = null \<or> (\<forall>x\<in>set \<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> \<bottom>)}"
by(auto intro!:Sequence_inv_lemma[simplified OclValid_def
defined_def false_def true_def null_fun_def bot_fun_def])
have P: "\<And>l A A' \<tau>. A \<tau> = A' \<tau> \<Longrightarrow> foldr P l A \<tau> = foldr P l A' \<tau>"
apply(rule list.induct, simp, simp)
by(subst (1 2) P_cp', simp)
fix \<tau>
show "OclIterate (S->including\<^sub>S\<^sub>e\<^sub>q(a)) A P \<tau> = OclIterate S (P a A) P \<tau>"
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 : "\<And>X. P invalid X = invalid"
and strict2 : "\<And>X. P X invalid = invalid"
and P_cp : "\<And> x y \<tau>. P x y \<tau> = P (\<lambda> _. x \<tau>) y \<tau>"
and P_cp' : "\<And> x y \<tau>. P x y \<tau> = P x (\<lambda> _. y \<tau>) \<tau>"
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: "\<And>S a \<tau>. S \<noteq> \<bottom> \<Longrightarrow> S \<noteq> null \<Longrightarrow> a \<noteq> \<bottom> \<Longrightarrow>
\<lfloor>\<lfloor>a # \<lceil>\<lceil>Rep_Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e S\<rceil>\<rceil>\<rfloor>\<rfloor> \<in> {X. X = bot \<or> X = null \<or> (\<forall>x\<in>set \<lceil>\<lceil>X\<rceil>\<rceil>. x \<noteq> \<bottom>)}"
by(auto intro!:Sequence_inv_lemma[simplified OclValid_def
defined_def false_def true_def null_fun_def bot_fun_def])
fix \<tau>
show "OclIterate (S->prepend\<^sub>S\<^sub>e\<^sub>q(a)) A P \<tau> = P a (OclIterate S A P) \<tau>"
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 "(\<tau> \<Turnstile> (Sequence{\<lambda>_. \<lfloor>\<lfloor>x\<rfloor>\<rfloor>} \<doteq> Sequence{\<lambda>_. \<lfloor>\<lfloor>x\<rfloor>\<rfloor>}))"
Assert "(\<tau> \<Turnstile> (Sequence{\<lambda>_. \<lfloor>x\<rfloor>} \<doteq> Sequence{\<lambda>_. \<lfloor>x\<rfloor>}))"
*)
instantiation Sequence\<^sub>b\<^sub>a\<^sub>s\<^sub>e :: (equal)equal
begin
definition "HOL.equal k l \<longleftrightarrow> (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) \<longleftrightarrow> 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 "\<tau> \<Turnstile> (Sequence{} \<doteq> Sequence{})"
Assert "\<tau> \<Turnstile> (Sequence{\<one>,\<two>} \<triangleq> Sequence{}->prepend\<^sub>S\<^sub>e\<^sub>q(\<two>)->prepend\<^sub>S\<^sub>e\<^sub>q(\<one>))"
Assert "\<tau> \<Turnstile> (Sequence{\<one>,invalid,\<two>} \<triangleq> invalid)"
Assert "\<tau> \<Turnstile> (Sequence{\<one>,\<two>}->prepend\<^sub>S\<^sub>e\<^sub>q(null) \<triangleq> Sequence{null,\<one>,\<two>})"
Assert "\<tau> \<Turnstile> (Sequence{\<one>,\<two>}->including\<^sub>S\<^sub>e\<^sub>q(null) \<triangleq> Sequence{\<one>,\<two>,null})"
(*
Assert "\<not> (\<tau> \<Turnstile> (Sequence{\<one>,\<one>,\<two>} \<doteq> Sequence{\<one>,\<two>}))"
Assert "\<not> (\<tau> \<Turnstile> (Sequence{\<one>,\<two>} \<doteq> Sequence{\<two>,\<one>}))"
*)
(* > *)
end

File diff suppressed because it is too large Load Diff

1085
src/document/FOCL_Syntax.tex Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -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}}%

File diff suppressed because it is too large Load Diff

28
src/document/omg.sty Normal file
View File

@ -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}

View File

@ -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}
}

283
src/document/root.tex Normal file
View File

@ -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>}{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>}{frederic.tuong@lri.fr} \hspace{4.5em}
\href{mailto:"Burkhart Wolff"
<burkhart.wolff@lri.fr>}{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>}{frederic.tuong@irt-systemx.fr} \quad
\href{mailto:"Burkhart Wolff"
<burkhart.wolff@irt-systemx.fr>}{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