Import of current (Isabelle 2016) release of Featherweight OCL.
This commit is contained in:
parent
ed232e8aa3
commit
02c1e24f17
3171
OCL_lib.thy
3171
OCL_lib.thy
File diff suppressed because it is too large
Load Diff
57
OCL_main.thy
57
OCL_main.thy
|
@ -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
68
ROOT
|
@ -1,24 +1,68 @@
|
|||
(*****************************************************************************
|
||||
* Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5
|
||||
* for the OMG Standard.
|
||||
* http://www.brucker.ch/projects/hol-testgen/
|
||||
*
|
||||
* This file is part of HOL-TestGen.
|
||||
*
|
||||
* Copyright (c) 2013-2015 Université Paris-Saclay, Univ. Paris-Sud, France
|
||||
* 2013-2015 IRT SystemX, France
|
||||
* 2013-2015 Achim D. Brucker, Germany
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************)
|
||||
|
||||
chapter AFP
|
||||
|
||||
session Featherweight_OCL (AFP) = HOL +
|
||||
session Featherweight_OCL (AFP) in "src" = HOL +
|
||||
description {* Featherweight-OCL *}
|
||||
options [document_variants = "document:outline=/proof,/ML"]
|
||||
options [document_variants = "annex-a=annexa,-theory,-afp,-proof,-ML:document=afp,-annexa:outline=-annexa,afp,/proof,/ML",
|
||||
show_question_marks = false]
|
||||
theories
|
||||
"OCL_main"
|
||||
"examples/Employee_AnalysisModel_OCLPart"
|
||||
"examples/Employee_DesignModel_OCLPart"
|
||||
"UML_Main"
|
||||
"../examples/Employee_Model/Analysis/Analysis_OCL"
|
||||
"../examples/Employee_Model/Design/Design_OCL"
|
||||
document_files
|
||||
"conclusion.tex"
|
||||
"formalization.tex"
|
||||
"hol-ocl-isar.sty"
|
||||
"introduction.tex"
|
||||
"lstisar.sty"
|
||||
"prooftree.sty"
|
||||
"root.bib"
|
||||
"root.tex"
|
||||
"figures/AbstractSimpleChair.pdf"
|
||||
"figures/jedit.png"
|
||||
"figures/pdf.png"
|
||||
"figures/person.png"
|
||||
"figures/pre-post.pdf"
|
||||
"hol-ocl-isar.sty"
|
||||
"introduction.tex"
|
||||
"lstisar.sty"
|
||||
"omg.sty"
|
||||
"prooftree.sty"
|
||||
"root.bib"
|
||||
"root.tex"
|
||||
"FOCL_Syntax.tex"
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
|
@ -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
|
|
@ -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
|
@ -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
|
|
@ -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
|
@ -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
|
||||
|
||||
(* > *)
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
|
@ -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
File diff suppressed because it is too large
Load Diff
|
@ -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
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -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
|
@ -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}
|
|
@ -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}
|
||||
}
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue