Theory UML_Library

(*****************************************************************************
 * 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 OclAsBooleanInt  :: "('𝔄) Integer ⇒ ('𝔄) Boolean" (‹(_)->oclAsTypeInt'(Boolean')›)
where     "OclAsBooleanInt X = (λτ. if (δ X) τ = true τ 
                              then ⌊⌊⌈⌈X τ⌉⌉ ≠ 0⌋⌋
                              else invalid τ)"

interpretation OclAsBooleanInt : profile_monod OclAsBooleanInt "λx. ⌊⌊⌈⌈x⌉⌉ ≠ 0⌋⌋"
                                by unfold_locales (auto simp: OclAsBooleanInt_def bot_option_def)

definition OclAsBooleanReal  :: "('𝔄) Real ⇒ ('𝔄) Boolean" (‹(_)->oclAsTypeReal'(Boolean')›)
where     "OclAsBooleanReal X = (λτ. if (δ X) τ = true τ 
                              then ⌊⌊⌈⌈X τ⌉⌉ ≠ 0⌋⌋
                              else invalid τ)"

interpretation OclAsBooleanReal : profile_monod OclAsBooleanReal "λx. ⌊⌊⌈⌈x⌉⌉ ≠ 0⌋⌋"
                                 by unfold_locales (auto simp: OclAsBooleanReal_def bot_option_def)

subsection‹Definition: asInteger›

definition OclAsIntegerReal  :: "('𝔄) Real ⇒ ('𝔄) Integer" (‹(_)->oclAsTypeReal'(Integer')›)
where     "OclAsIntegerReal X = (λτ. if (δ X) τ = true τ 
                              then ⌊⌊floor ⌈⌈X τ⌉⌉⌋⌋
                              else invalid τ)"

interpretation OclAsIntegerReal : profile_monod OclAsIntegerReal "λx. ⌊⌊floor ⌈⌈x⌉⌉⌋⌋"
                                 by unfold_locales (auto simp: OclAsIntegerReal_def bot_option_def)

subsection‹Definition: asReal›

definition OclAsRealInt  :: "('𝔄) Integer ⇒ ('𝔄) Real" (‹(_)->oclAsTypeInt'(Real')›)
where     "OclAsRealInt X = (λτ. if (δ X) τ = true τ 
                              then ⌊⌊real_of_int ⌈⌈X τ⌉⌉⌋⌋
                              else invalid τ)"

interpretation OclAsRealInt : profile_monod OclAsRealInt "λx. ⌊⌊real_of_int ⌈⌈x⌉⌉⌋⌋"
                             by unfold_locales (auto simp: OclAsRealInt_def bot_option_def)

lemma Integer_subtype_of_Real: 
  assumes "τ ⊨ δ X"
  shows   "τ ⊨ X ->oclAsTypeInt(Real) ->oclAsTypeReal(Integer) ≜ X"
  apply(insert assms,  simp add: OclAsIntegerReal_def OclAsRealInt_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 OclAsPairSeq   :: "[('𝔄,'α::null)Sequence]⇒('𝔄,'α::null,'α::null) Pair" (‹(_)->asPairSeq'(')›)
where     "OclAsPairSeq S = (if S->sizeSeq() ≐ 𝟮
                            then Pair{S->atSeq(𝟬),S->atSeq(𝟭)}
                            else invalid
                            endif)"

definition OclAsPairSet   :: "[('𝔄,'α::null)Set]⇒('𝔄,'α::null,'α::null) Pair" (‹(_)->asPairSet'(')›)
where     "OclAsPairSet S = (if S->sizeSet() ≐ 𝟮
                            then let v = S->anySet() in
                                 Pair{v,S->excludingSet(v)->anySet()}
                            else invalid
                            endif)"

definition OclAsPairBag   :: "[('𝔄,'α::null)Bag]⇒('𝔄,'α::null,'α::null) Pair" (‹(_)->asPairBag'(')›)
where     "OclAsPairBag S = (if S->sizeBag() ≐ 𝟮
                            then let v = S->anyBag() in
                                 Pair{v,S->excludingBag(v)->anyBag()}
                            else invalid
                            endif)"

subsection‹Definition: asSet›

definition OclAsSetSeq   :: "[('𝔄,'α::null)Sequence]⇒('𝔄,'α)Set" (‹(_)->asSetSeq'(')›)
where     "OclAsSetSeq S = (S->iterateSeq(b; x = Set{} | x ->includingSet(b)))"

definition OclAsSetPair   :: "[('𝔄,'α::null,'α::null) Pair]⇒('𝔄,'α)Set" (‹(_)->asSetPair'(')›)
where     "OclAsSetPair S = Set{S .First(), S .Second()}"

definition OclAsSetBag   :: "('𝔄,'α::null) Bag⇒('𝔄,'α)Set" (‹(_)->asSetBag'(')›)
where     "OclAsSetBag S =  (λ τ. if (δ S) τ = true τ 
                                 then Abs_Setbase⌊⌊ Rep_Set_base S τ ⌋⌋ 
                                 else if (υ S) τ = true τ then null τ 
                                                          else invalid τ)"

subsection‹Definition: asSequence›

definition OclAsSeqSet   :: "[('𝔄,'α::null)Set]⇒('𝔄,'α)Sequence" (‹(_)->asSequenceSet'(')›)
where     "OclAsSeqSet S = (S->iterateSet(b; x = Sequence{} | x ->includingSeq(b)))"

definition OclAsSeqBag   :: "[('𝔄,'α::null)Bag]⇒('𝔄,'α)Sequence" (‹(_)->asSequenceBag'(')›)
where     "OclAsSeqBag S = (S->iterateBag(b; x = Sequence{} | x ->includingSeq(b)))"

definition OclAsSeqPair   :: "[('𝔄,'α::null,'α::null) Pair]⇒('𝔄,'α)Sequence" (‹(_)->asSequencePair'(')›)
where     "OclAsSeqPair S = Sequence{S .First(), S .Second()}"

subsection‹Definition: asBag›

definition OclAsBagSeq   :: "[('𝔄,'α::null)Sequence]⇒('𝔄,'α)Bag" (‹(_)->asBagSeq'(')›)
where     "OclAsBagSeq S = (λτ. Abs_Bagbase ⌊⌊λs. if list_ex ((=) s) ⌈⌈Rep_Sequencebase (S τ)⌉⌉ then 1 else 0⌋⌋)"

definition OclAsBagSet   :: "[('𝔄,'α::null)Set]⇒('𝔄,'α)Bag" (‹(_)->asBagSet'(')›)
where     "OclAsBagSet S = (λτ. Abs_Bagbase ⌊⌊λs. if s ∈ ⌈⌈Rep_Setbase (S τ)⌉⌉ then 1 else 0⌋⌋)"

lemma assumes "τ ⊨ δ (S ->sizeSet())" (* S is finite *)
      shows "OclAsBagSet S = (S->iterateSet(b; x = Bag{} | x ->includingBag(b)))"
oops

definition OclAsBagPair   :: "[('𝔄,'α::null,'α::null) Pair]⇒('𝔄,'α)Bag" (‹(_)->asBagPair'(')›)
where     "OclAsBagPair S = Bag{S .First(), S .Second()}"

text_raw‹\isatagafp›
subsection‹Collection Types›
lemmas cp_intro'' [intro!,simp,code_unfold] =
       cp_intro'
     (*  cp_intro''Pair *)
       cp_intro''Set
       cp_intro''Seq
text_raw‹\endisatagafp›

subsection‹Test Statements›

lemma syntax_test: "Set{𝟮,𝟭} = (Set{}->includingSet(𝟭)->includingSet(𝟮))"
by (rule refl)

text‹Here is an example of a nested collection.›
lemma semantic_test2:
assumes H:"(Set{𝟮} ≐ null) = (false::('𝔄)Boolean)"
shows   "(τ::('𝔄)st) ⊨ (Set{Set{𝟮},null}->includesSet(null))"
by(simp add: OclIncludes_executeSet H)



lemma short_cut'[simp,code_unfold]: "(𝟴 ≐ 𝟲) = false"
 apply(rule ext)
 apply(simp add: StrictRefEqInteger StrongEq_def OclInt8_def OclInt6_def
                 true_def false_def invalid_def bot_option_def)
done

lemma short_cut''[simp,code_unfold]: "(𝟮 ≐ 𝟭) = false"
 apply(rule ext)
 apply(simp add: StrictRefEqInteger StrongEq_def OclInt2_def OclInt1_def
                 true_def false_def invalid_def bot_option_def)
done
lemma short_cut'''[simp,code_unfold]: "(𝟭 ≐ 𝟮) = false"
 apply(rule ext)
 apply(simp add: StrictRefEqInteger StrongEq_def OclInt2_def OclInt1_def
                 true_def false_def invalid_def bot_option_def)
done

Assert   "τ ⊨ (𝟬 <int 𝟮) and (𝟬 <int 𝟭) "


text‹Elementary computations on Sets.›

declare OclSelect_body_def [simp]

Assert "¬ (τ ⊨ υ(invalid::('𝔄,'α::null) Set))"
Assert    "τ ⊨ υ(null::('𝔄,'α::null) Set)"
Assert "¬ (τ ⊨ δ(null::('𝔄,'α::null) Set))"
Assert    "τ ⊨ υ(Set{})"
Assert    "τ ⊨ υ(Set{Set{𝟮},null})"
Assert    "τ ⊨ δ(Set{Set{𝟮},null})"
Assert    "τ ⊨ (Set{𝟮,𝟭}->includesSet(𝟭))"
Assert "¬ (τ ⊨ (Set{𝟮}->includesSet(𝟭)))"
Assert "¬ (τ ⊨ (Set{𝟮,𝟭}->includesSet(null)))"
Assert    "τ ⊨ (Set{𝟮,null}->includesSet(null))"
Assert    "τ ⊨ (Set{null,𝟮}->includesSet(null))"

Assert    "τ ⊨ ((Set{})->forAllSet(z | 𝟬 <int z))"

Assert    "τ ⊨ ((Set{𝟮,𝟭})->forAllSet(z | 𝟬 <int z))"
Assert "¬ (τ ⊨ ((Set{𝟮,𝟭})->existsSet(z | z <int 𝟬 )))"
Assert "¬ (τ ⊨ (δ(Set{𝟮,null})->forAllSet(z | 𝟬 <int z)))"
Assert "¬ (τ ⊨ ((Set{𝟮,null})->forAllSet(z | 𝟬 <int z)))"
Assert    "τ ⊨ ((Set{𝟮,null})->existsSet(z | 𝟬 <int z))"


Assert "¬ (τ ⊨ (Set{null::'a Boolean} ≐ Set{}))"
Assert "¬ (τ ⊨ (Set{null::'a Integer} ≐ Set{}))"

Assert "¬ (τ ⊨ (Set{true} ≐ Set{false}))"
Assert "¬ (τ ⊨ (Set{true,true} ≐ Set{false}))"
lemma "¬ (τ ⊨ (Set{𝟮} ≐ Set{𝟭}))"
  by simp
lemma "τ ⊨ (Set{𝟮,null,𝟮} ≐ Set{null,𝟮})"
  by simp
lemma "τ ⊨ (Set{𝟭,null,𝟮} <> Set{null,𝟮})"
  by simp
lemma "τ ⊨ (Set{Set{𝟮,null}} ≐ Set{Set{null,𝟮}})"
  by simp
lemma "τ ⊨ (Set{Set{𝟮,null}} <> Set{Set{null,𝟮},null})"
  by simp
lemma "τ ⊨ (Set{null}->selectSet(x | not x) ≐ Set{null})"
  by simp
lemma "τ ⊨ (Set{null}->rejectSet(x | not x) ≐ Set{null})"
  by simp

lemma     "const (Set{Set{𝟮,null}, invalid})" by(simp add: const_ss)


text‹Elementary computations on Sequences.›

Assert "¬ (τ ⊨ υ(invalid::('𝔄,'α::null) Sequence))"
Assert    "τ ⊨ υ(null::('𝔄,'α::null) Sequence)"
Assert "¬ (τ ⊨ δ(null::('𝔄,'α::null) Sequence))"
Assert    "τ ⊨ υ(Sequence{})"

lemma     "const (Sequence{Sequence{𝟮,null}, invalid})" by(simp add: const_ss)

end