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
|
chapter AFP
|
||||||
|
|
||||||
session Featherweight_OCL (AFP) = HOL +
|
session Featherweight_OCL (AFP) in "src" = HOL +
|
||||||
description {* Featherweight-OCL *}
|
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
|
theories
|
||||||
"OCL_main"
|
"UML_Main"
|
||||||
"examples/Employee_AnalysisModel_OCLPart"
|
"../examples/Employee_Model/Analysis/Analysis_OCL"
|
||||||
"examples/Employee_DesignModel_OCLPart"
|
"../examples/Employee_Model/Design/Design_OCL"
|
||||||
document_files
|
document_files
|
||||||
"conclusion.tex"
|
"conclusion.tex"
|
||||||
"formalization.tex"
|
|
||||||
"hol-ocl-isar.sty"
|
|
||||||
"introduction.tex"
|
|
||||||
"lstisar.sty"
|
|
||||||
"prooftree.sty"
|
|
||||||
"root.bib"
|
|
||||||
"root.tex"
|
|
||||||
"figures/AbstractSimpleChair.pdf"
|
"figures/AbstractSimpleChair.pdf"
|
||||||
"figures/jedit.png"
|
"figures/jedit.png"
|
||||||
"figures/pdf.png"
|
"figures/pdf.png"
|
||||||
"figures/person.png"
|
"figures/person.png"
|
||||||
"figures/pre-post.pdf"
|
"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.
|
* for the OMG Standard.
|
||||||
* http://www.brucker.ch/projects/hol-testgen/
|
* http://www.brucker.ch/projects/hol-testgen/
|
||||||
*
|
*
|
||||||
* OCL_tools.thy ---
|
* UML_Main.thy ---
|
||||||
* This file is part of HOL-TestGen.
|
* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -39,8 +40,7 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
******************************************************************************)
|
******************************************************************************)
|
||||||
|
|
||||||
theory OCL_tools
|
theory UML_Main
|
||||||
imports OCL_core
|
imports UML_Contracts UML_Tools
|
||||||
begin
|
begin
|
||||||
|
|
||||||
end
|
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
|
We provided a typed and type-safe shallow embedding of the core of
|
||||||
UML~\cite{omg:uml-infrastructure:2011,omg:uml-superstructure:2011} and
|
UML~\cite{omg:uml-infrastructure:2011,omg:uml-superstructure:2011} and
|
||||||
OCL~\cite{omg:ocl:2012}. Shallow embedding means that types of OCL
|
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
|
Isabelle/HOL~\cite{nipkow.ea:isabelle:2002}. We followed the usual
|
||||||
methodology to build up the theory uniquely by conservative extensions
|
methodology to build up the theory uniquely by conservative extensions
|
||||||
of all operators in a denotational style and to derive logical and
|
of all operators in a denotational style and to derive logical and
|
||||||
algebraic (execution) rules from them; thus, we can guarantee the
|
algebraic (execution) rules from them; thus, we can guarantee the
|
||||||
logical consistency of the library and instances of the class model
|
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
|
long as it follows the described methodology.\footnote{Our two
|
||||||
examples of \inlineisar+Employee_DesignModel+ (see
|
examples of \inlineisar+Employee_AnalysisModel+ and
|
||||||
\autoref{ex:employee-design}) sketch how this construction can
|
\inlineisar+Employee_DesignModel+ (see
|
||||||
be captured by an automated process.} Moreover, all derived
|
\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
|
execution rules are by construction type-safe (which would be an
|
||||||
issue, if we had chosen to use an object universe construction in
|
issue, if we had chosen to use an object universe construction in
|
||||||
Zermelo-Fraenkel set theory as an alternative approach to subtyping.).
|
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
|
a two-valued presentation, that is amenable to animators like
|
||||||
KodKod~\cite{torlak.ea:kodkod:2007} or SMT-solvers like
|
KodKod~\cite{torlak.ea:kodkod:2007} or SMT-solvers like
|
||||||
Z3~\cite{moura.ea:z3:2008} completely impractical. Concretely, if the
|
Z3~\cite{moura.ea:z3:2008} completely impractical. Concretely, if the
|
||||||
expression \inlineocl{not(null)} is defined \inlineocl{invalid} (as is
|
expression \inlineocl{not(null)} is defined \inlineocl{invalid} (as was
|
||||||
the case in the present standard~\cite{omg:ocl:2012}), than standard
|
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}
|
involution does not hold, \ie, \inlineocl{not(not(A))} = \inlineocl{A}
|
||||||
does not hold universally. Similarly, if \inlineocl{null and null} is
|
does not hold universally. Similarly, if \inlineocl{null and null} is
|
||||||
\inlineocl{invalid}, then not even idempotence \inlineocl{X and X} =
|
\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
|
A similar experience with prior paper and pencil arguments was our
|
||||||
investigation of the object-oriented data-models, in particular
|
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
|
presentation is again essentially correct, but the technical details
|
||||||
concerning exception handling lead finally to a continuation-passing
|
concerning exception handling lead finally to a continuation-passing
|
||||||
style of the (in future generated) definitions for accessors, casts
|
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
|
besides the truth values \inlineocl{true} and \inlineocl{false} also
|
||||||
the two exception values \inlineocl{invalid} and \inlineocl{null}).
|
the two exception values \inlineocl{invalid} and \inlineocl{null}).
|
||||||
|
|
||||||
In the following, we outline the necessary steps for turning
|
In the following, we outline the following future extensions to use
|
||||||
Featherweight OCL into a fully fledged tool for OCL, \eg, similar to
|
Featherweight OCL for a concrete fully fledged tool for OCL. There are
|
||||||
\holocl as well as for supporting test case generation similar to
|
|
||||||
{HOL}-TestGen~\cite{brucker.ea:hol-testgen:2009}. There are
|
|
||||||
essentially five extensions necessary:
|
essentially five extensions necessary:
|
||||||
\begin{itemize}
|
\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
|
\item development of a compiler that compiles a textual or CASE
|
||||||
tool representation (\eg, using XMI or the textual syntax of
|
tool representation (\eg, using XMI or the textual syntax of
|
||||||
the USE tool~\cite{richters:precise:2002}) of class
|
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
|
converting standard OCL to Featherweight OCL as well as providing
|
||||||
``normalizations'' such as converting multiplicities of class
|
``normalizations'' such as converting multiplicities of class
|
||||||
attributes to into OCL class invariants.
|
attributes to into OCL class invariants.
|
||||||
|
@ -142,8 +142,9 @@ essentially five extensions necessary:
|
||||||
from the default multiplicity \inlineocl{1} of an attributes
|
from the default multiplicity \inlineocl{1} of an attributes
|
||||||
\inlineocl{x}, we can directly infer that for all valid states
|
\inlineocl{x}, we can directly infer that for all valid states
|
||||||
\inlineocl{x} is neither \inlineocl{invalid} nor \inlineocl{null}),
|
\inlineocl{x} is neither \inlineocl{invalid} nor \inlineocl{null}),
|
||||||
such a translation enables an efficient test case generation
|
such a translation enables both an integration of fast constraint solvers
|
||||||
approach.
|
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
|
\item a setup in Featherweight OCL of the Nitpick
|
||||||
animator~\cite{blanchette.ea:nitpick:2010}. It remains to be shown
|
animator~\cite{blanchette.ea:nitpick:2010}. It remains to be shown
|
||||||
that the standard, Kodkod~\cite{torlak.ea:kodkod:2007} based
|
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)}}%
|
{#2\operatorname{\!.#3}^{(#1)}}%
|
||||||
}
|
}
|
||||||
|
|
||||||
|
\newcommand{\getRole}[3][]{%
|
||||||
|
\ifthenelse{\equal{#1}{}}%
|
||||||
|
{#2\operatorname{\!.#3}}%
|
||||||
|
{#2\operatorname{\!.#3}^{(#1)}}%
|
||||||
|
}
|
||||||
|
|
||||||
\newcommand{\setAttrib}[4][]{%
|
\newcommand{\setAttrib}[4][]{%
|
||||||
\ifthenelse{\equal{#1}{}}%
|
\ifthenelse{\equal{#1}{}}%
|
||||||
{#2\operatorname{\!.set_{#3}}\ap \mathit{#4}}%
|
{#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,
|
@InProceedings{ brucker.ea:path-expressions:2013,
|
||||||
author = {Achim D. Brucker and
|
author = {Achim D. Brucker and Delphine Longuet and Fr{\'e}d{\'e}ric
|
||||||
Delphine Longuet and
|
Tuong and Burkhart Wolff},
|
||||||
Fr{\'e}d{\'e}ric Tuong and
|
title = {On the Semantics of Object-oriented Data Structures and
|
||||||
Burkhart Wolff},
|
Path Expressions},
|
||||||
title = {On the Semantics of Object-Oriented Data Structures and
|
year = 2013,
|
||||||
Path Expressions},
|
booktitle = {Proceedings of the \acs{models} 2013 \acs{ocl} Workshop (\acs{ocl} 2013)},
|
||||||
booktitle = {OCL@MoDELS},
|
location = {Miami, \acs{usa}},
|
||||||
year = {2013},
|
editor = {Jordi Cabot and Martin Gogolla and Istv{\'a}n R{\'a}th and
|
||||||
pages = {23-32},
|
Edward D. Willink},
|
||||||
ee = {http://ceur-ws.org/Vol-1092/brucker.pdf},
|
publisher = {\acs{ceur-ws}.org},
|
||||||
bibsource = {DBLP, http://dblp.uni-trier.de}
|
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}
|
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