(***************************************************************************** * Featherweight-OCL --- A Formal Semantics for UML-OCL Version OCL 2.5 * for the OMG Standard. * http://www.brucker.ch/projects/hol-testgen/ * * UML_Real.thy --- Library definitions. * This file is part of HOL-TestGen. * * Copyright (c) 2012-2015 Université Paris-Saclay, Univ. Paris-Sud, France * 2013-2015 IRT SystemX, France * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************) theory UML_Real imports "../UML_PropertyProfiles" begin section\Basic Type Real: Operations\ subsection\Fundamental Predicates on Reals: Strict Equality \label{sec:real-strict-eq}\ text\The last basic operation belonging to the fundamental infrastructure of a value-type in OCL is the weak equality, which is defined similar to the @{typ "('\)Boolean"}-case as strict extension of the strong equality:\ overloading StrictRefEq \ "StrictRefEq :: [('\)Real,('\)Real] \ ('\)Boolean" begin definition StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l [code_unfold] : "(x::('\)Real) \ y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then (x \ y) \ else invalid \" end text\Property proof in terms of @{term "profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v"}\ interpretation StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>S\<^sub>t\<^sub>r\<^sub>o\<^sub>n\<^sub>g\<^sub>E\<^sub>q_\<^sub>v_\<^sub>v "\ x y. (x::('\)Real) \ y" by unfold_locales (auto simp: StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l) subsection\Basic Real Constants\ text\Although the remaining part of this library reasons about reals abstractly, we provide here as example some convenient shortcuts.\ definition OclReal0 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\0::real\\)" definition OclReal1 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\1::real\\)" definition OclReal2 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\2::real\\)" text\Etc.\ text_raw\\isatagafp\ definition OclReal3 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\3::real\\)" definition OclReal4 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\4::real\\)" definition OclReal5 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\5::real\\)" definition OclReal6 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\6::real\\)" definition OclReal7 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\7::real\\)" definition OclReal8 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\8::real\\)" definition OclReal9 ::"('\)Real" ("\.\") where "\.\ = (\ _ . \\9::real\\)" definition OclReal10 ::"('\)Real" ("\\.\") where "\\.\ = (\ _ . \\10::real\\)" definition OclRealpi ::"('\)Real" ("\") where "\ = (\ _ . \\pi\\)" subsection\Validity and Definedness Properties\ lemma "\(null::('\)Real) = false" by simp lemma "\(null::('\)Real) = true" by simp lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" by(simp add:defined_def true_def bot_fun_def bot_option_def null_fun_def null_option_def) lemma [simp,code_unfold]: "\ (\_. \\n\\) = true" by(simp add:valid_def true_def bot_fun_def bot_option_def) (* ecclectic proofs to make examples executable *) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal0_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal0_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal1_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal1_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal2_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal2_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal6_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal6_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal8_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal8_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal9_def) lemma [simp,code_unfold]: "\ \.\ = true" by(simp add:OclReal9_def) text_raw\\endisatagafp\ subsection\Arithmetical Operations\ subsubsection\Definition\ text\Here is a common case of a built-in operation on built-in types. Note that the arguments must be both defined (non-null, non-bot).\ text\Note that we can not follow the lexis of the OCL Standard for Isabelle technical reasons; these operators are heavily overloaded in the HOL library that a further overloading would lead to heavy technical buzz in this document. \ definition OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "+\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 40) where "x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then \\\\x \\\ + \\y \\\\\ else invalid \ " interpretation OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "(+\<^sub>r\<^sub>e\<^sub>a\<^sub>l)" "\ x y. \\\\x\\ + \\y\\\\" by unfold_locales (auto simp:OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) definition OclMinus\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "-\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 41) where "x -\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then \\\\x \\\ - \\y \\\\\ else invalid \ " interpretation OclMinus\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "(-\<^sub>r\<^sub>e\<^sub>a\<^sub>l)" "\ x y. \\\\x\\ - \\y\\\\" by unfold_locales (auto simp:OclMinus\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) definition OclMult\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "*\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45) where "x *\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then \\\\x \\\ * \\y \\\\\ else invalid \" interpretation OclMult\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "OclMult\<^sub>R\<^sub>e\<^sub>a\<^sub>l" "\ x y. \\\\x\\ * \\y\\\\" by unfold_locales (auto simp:OclMult\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) text\Here is the special case of division, which is defined as invalid for division by zero.\ definition OclDivision\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "div\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45) where "x div\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then if y \ \ OclReal0 \ then \\\\x \\\ / \\y \\\\\ else invalid \ else invalid \ " (* TODO: special locale setup.*) definition "mod_float a b = a - real_of_int (floor (a / b)) * b" definition OclModulus\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Real" (infix "mod\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 45) where "x mod\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then if y \ \ OclReal0 \ then \\mod_float \\x \\\ \\y \\\\\ else invalid \ else invalid \ " (* TODO: special locale setup.*) definition OclLess\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Boolean" (infix "<\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 35) where "x <\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then \\\\x \\\ < \\y \\\\\ else invalid \ " interpretation OclLess\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "(<\<^sub>r\<^sub>e\<^sub>a\<^sub>l)" "\ x y. \\\\x\\ < \\y\\\\" by unfold_locales (auto simp:OclLess\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) definition OclLe\<^sub>R\<^sub>e\<^sub>a\<^sub>l ::"('\)Real \ ('\)Real \ ('\)Boolean" (infix "\\<^sub>r\<^sub>e\<^sub>a\<^sub>l" 35) where "x \\<^sub>r\<^sub>e\<^sub>a\<^sub>l y \ \ \. if (\ x) \ = true \ \ (\ y) \ = true \ then \\\\x \\\ \ \\y \\\\\ else invalid \ " interpretation OclLe\<^sub>R\<^sub>e\<^sub>a\<^sub>l : profile_bin\<^sub>d_\<^sub>d "(\\<^sub>r\<^sub>e\<^sub>a\<^sub>l)" "\ x y. \\\\x\\ \ \\y\\\\" by unfold_locales (auto simp:OclLe\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def bot_option_def null_option_def) subsubsection\Basic Properties\ lemma OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_commute: "(X +\<^sub>r\<^sub>e\<^sub>a\<^sub>l Y) = (Y +\<^sub>r\<^sub>e\<^sub>a\<^sub>l X)" by(rule ext,auto simp:true_def false_def OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def invalid_def split: option.split option.split_asm bool.split bool.split_asm) subsubsection\Execution with Invalid or Null or Zero as Argument\ lemma OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_zero1[simp,code_unfold] : "(x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) = (if \ x and not (\ x) then invalid else x endif)" proof (rule ext, rename_tac \, case_tac "(\ x and not (\ x)) \ = true \") fix \ show "(\ x and not (\ x)) \ = true \ \ (x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) \ = (if \ x and not (\ x) then invalid else x endif) \" apply(subst OclIf_true', simp add: OclValid_def) by (metis OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def OclNot_defargs OclValid_def foundation5 foundation9) next fix \ have A: "\\. (\ \ not (\ x and not (\ x))) = (x \ = invalid \ \ \ \ \ x)" by (metis OclNot_not OclOr_def defined5 defined6 defined_not_I foundation11 foundation18' foundation6 foundation7 foundation9 invalid_def) have B: "\ \ \ x \ \\\\x \\\\\ = x \" apply(cases "x \", metis bot_option_def foundation16) apply(rename_tac x', case_tac x', metis bot_option_def foundation16 null_option_def) by(simp) show "(x +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) \ = (if \ x and not (\ x) then invalid else x endif) \" when "\ \ not (\ x and not (\ x))" apply(insert that, subst OclIf_false', simp, simp add: A, auto simp: OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_def OclReal0_def) (* *) apply(simp add: foundation16'[simplified OclValid_def]) apply(simp add: B) by(simp add: OclValid_def) qed(metis OclValid_def defined5 defined6 defined_and_I defined_not_I foundation9) lemma OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_zero2[simp,code_unfold] : "(\.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l x) = (if \ x and not (\ x) then invalid else x endif)" by(subst OclAdd\<^sub>R\<^sub>e\<^sub>a\<^sub>l_commute, simp) (* TODO Basic proproperties for multiplication, division, modulus. *) subsection\Test Statements\ text\Here follows a list of code-examples, that explain the meanings of the above definitions by compilation to code and execution to @{term "True"}.\ Assert "\ \ ( \.\ \\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\ )" Assert "\ \ (( \.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\ ) \\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\ )" Assert "\ |\ (( \.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l ( \.\ +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\ )) <\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\ )" Assert "\ \ not (\ (null +\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\)) " Assert "\ \ (((\.\ *\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \\.\) \\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\) " Assert "\ \ not (\ (\.\ div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\)) " Assert "\ \ not (\ (\.\ div\<^sub>r\<^sub>e\<^sub>a\<^sub>l \.\)) " lemma real_non_null [simp]: "((\_. \\n\\) \ (null::('\)Real)) = false" by(rule ext,auto simp: StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l valid_def bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) lemma null_non_real [simp]: "((null::('\)Real) \ (\_. \\n\\)) = false" by(rule ext,auto simp: StrictRefEq\<^sub>R\<^sub>e\<^sub>a\<^sub>l valid_def bot_fun_def bot_option_def null_fun_def null_option_def StrongEq_def) lemma OclReal0_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal0_def) lemma null_non_OclReal0 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal0_def) lemma OclReal1_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal1_def) lemma null_non_OclReal1 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal1_def) lemma OclReal2_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal2_def) lemma null_non_OclReal2 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal2_def) lemma OclReal6_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal6_def) lemma null_non_OclReal6 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal6_def) lemma OclReal8_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal8_def) lemma null_non_OclReal8 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal8_def) lemma OclReal9_non_null [simp,code_unfold]: "(\.\ \ null) = false" by(simp add: OclReal9_def) lemma null_non_OclReal9 [simp,code_unfold]: "(null \ \.\) = false" by(simp add: OclReal9_def) text\Here follows a list of code-examples, that explain the meanings of the above definitions by compilation to code and execution to @{term "True"}.\ text\Elementary computations on Real\ Assert "\ \ \.\ <> \.\" Assert "\ \ \.\ <> \.\" Assert "\ \ \.\ \ \.\" Assert "\ \ \ \.\" Assert "\ \ \ \.\" Assert "\ \ \ (null::('\)Real)" Assert "\ \ (invalid \ invalid)" Assert "\ \ (null \ null)" Assert "\ \ (\.\ \ \.\)" Assert "\ |\ (\.\ \ \\.\)" Assert "\ |\ (invalid \ \\.\)" Assert "\ |\ (null \ \\.\)" Assert "\ |\ (invalid \ (invalid::('\)Real))" (* Without typeconstraint not executable.*) Assert "\ |\ \ (invalid \ (invalid::('\)Real))" (* Without typeconstraint not executable.*) Assert "\ |\ (invalid <> (invalid::('\)Real))" (* Without typeconstraint not executable.*) Assert "\ |\ \ (invalid <> (invalid::('\)Real))" (* Without typeconstraint not executable.*) Assert "\ \ (null \ (null::('\)Real) )" (* Without typeconstraint not executable.*) Assert "\ \ (null \ (null::('\)Real) )" (* Without typeconstraint not executable.*) Assert "\ \ (\.\ \ \.\)" Assert "\ |\ (\.\ <> \.\)" Assert "\ |\ (\.\ \ \\.\)" Assert "\ \ (\.\ <> \\.\)" Assert "\ |\ (\.\ <\<^sub>r\<^sub>e\<^sub>a\<^sub>l null)" Assert "\ |\ (\ (\.\ <\<^sub>r\<^sub>e\<^sub>a\<^sub>l null))" end