su4sml/su4sml/src/wfcpog/rep_holocl.sml

319 lines
13 KiB
Standard ML

(*****************************************************************************
* HOL-OCL --- an interactive theorem-prover for for UML/OCL
* http://www.brucker.ch/projects/hol-ocl/
*
* holocl_namespace.sml ---
* This file is part of HOL-OCL.
*
* Copyright (c) 2005-2007 ETH Zurich, Switzerland
* 2008-2009 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.
******************************************************************************)
(* $Id: holocl_namespace.sml 7513 2008-03-27 06:27:50Z brucker $ *)
signature REP_HOLOCL_NAMESPACE =
sig
datatype Level = univ (* universe toolbox *)
| operation
| holocl (* HOL-OCL toplevel *)
| l0 (* Level 0 *)
| l1 (* Level 1 *)
| l2 (* Level 2 *)
(* useful stuff; move to su4sml? *)
val rm_whitespace : string -> string
val listin : ''a -> ''a list -> bool
val ext_name_of : Rep_OclType.Path -> string list
val post_1_of : Rep_OclType.Path -> Rep_OclType.Path
val pre_1_of : Rep_OclType.Path -> Rep_OclType.Path
val local_name_of : Rep_OclType.Path -> string
val hc_path : Level -> Rep_OclType.Path -> Rep_OclType.Path
val get_class_of : Rep_OclType.Path -> Rep_OclType.Path
val mk_class_of : Rep_OclType.Path -> Rep_OclType.Path
val mk_def_of : Rep_OclType.Path -> Rep_OclType.Path
val is_hc_pathstr : Level-> string -> bool
val class2get_parent : Rep_OclType.Path -> string -> Rep_OclType.Path
val parent2class_of : Rep_OclType.Path -> string -> Rep_OclType.Path
val is_univ_class_of : Rep_OclType.Path -> Rep_OclType.Path
val is_class_of : Rep_OclType.Path -> Rep_OclType.Path
val key_name_of : Rep_OclType.Path -> string list
val base_type_name_of : Rep_OclType.Path -> Rep_OclType.Path
val type_name_of : Rep_OclType.Path -> Rep_OclType.Path
val attr_of : Rep_OclType.Path -> string -> Rep_OclType.Path
val is_classType_of : Rep_OclType.Path -> Rep_OclType.Path
val attr_pre_of : Rep_OclType.Path -> string -> Rep_OclType.Path
val type_charset_name_of : Rep_OclType.Path -> Rep_OclType.Path
val invariant_1_of : Rep_OclType.Path -> Rep_OclType.Path
val invariant_2_of : Rep_OclType.Path -> Rep_OclType.Path
val strong_sve_2_of :Rep_OclType.Path -> Rep_OclType.Path
val strict_sve_2_of :Rep_OclType.Path -> Rep_OclType.Path
val name_of_inv : Rep_Core.Classifier -> Rep_OclType.Path
val name_of_pre : Rep_Core.Classifier -> Rep_Core.operation -> Rep_OclType.Path
val name_of_post : Rep_Core.Classifier -> Rep_Core.operation -> Rep_OclType.Path
end
structure Rep_HolOcl_Namespace:REP_HOLOCL_NAMESPACE =
struct
datatype Level = univ (* universe toolbox *)
| operation
| holocl (* HOL-OCL toplevel *)
| l0 (* Level 0 *)
| l1 (* Level 1 *)
| l2 (* Level 2 *)
fun listin _ [] = false
| listin e (x::xs) = if e=x then true else listin e xs
(*separate s [x1, x2, ..., xn] ===> [x1, s, x2, s, ..., s, xn]*)
fun separate s (x :: (xs as _ :: _)) = x :: s :: separate s xs
| separate _ xs = xs;
fun space_implode a bs = SML90.implode (separate a bs);
fun rm_whitespace s = space_implode "_" (String.tokens (fn c => c = (#" ")
orelse c = (#":")) s)
fun local_name_of path = case path of
[] => ""
| p => (hd o rev) p
fun hc_path level p = if ((String.isSubstring "OclAny" (local_name_of p))
andalso not (String.isSubstring "_2_OclAny" (local_name_of p))
andalso not (String.isSubstring "OclAny_2" (local_name_of p)))
(* hack *)
then
case level of
univ => p
| operation => p
| holocl => p
| l0 => ("UML_OCL"::["level0"])@p
| l1 => ("UML_OCL"::["level1"])@p
| l2 => p
else
case level of
univ => ("UML_OCL"::["univ"])@p (* universe toolbox *)
| operation => ("UML_OCL"::["ops"])@p
| holocl => "UML_OCL"::p (* HOL-OCL toplevel *)
| l0 => ("UML_OCL"::["level0"])@p
| l1 => ("UML_OCL"::["level1"])@p
| l2 => p
fun class2get_parent path superclass = rev (((hd (rev path))^"_2_"^superclass)::(tl (rev path)))
fun parent2class_of path superclass = rev ((superclass^"_2_"^(hd (rev path)))::(tl (rev path)))
fun mk_def_of path = rev (((hd (rev path))^"_def")::(tl (rev path)))
fun type_charset_name_of path = rev (((hd (rev path))^"_type")::(tl (rev path)))
fun attr_of path attr= path @[attr]
fun attr_pre_of path attr = path@[attr^"_pre"]
fun invariant_1_of path = path@["invariant1"]
fun invariant_2_of path = path@["inv"]
fun strong_sve_2_of path = path@["strong_sve"]
fun strict_sve_2_of path = path@["strict_sve"]
fun rm_whitespace s = space_implode "_" (String.tokens (fn c => c = (#" ")
orelse c = (#":")) s)
fun op_tab_of path = path@["op_tab"]
fun pre_1_of path = path@["pre1"]
fun post_1_of path = path@["post1"]
fun get_class_of path = rev (("get_"^(hd (rev path)))::(tl (rev path))) (* mkC *)
fun mk_class_of path = rev (("mk_"^(hd (rev path)))::(tl (rev path))) (* mkC *)
fun key_name_of path = if (path = (Rep_Core.name_of Rep_Core.OclAnyC)) (* hack *)
then ["OCL_OclAny_type","OclAny_key"]
else rev (((hd (rev path))^"_key")::(tl (rev path))) (* keyC *)
fun is_hc_pathstr level pstr = if ((String.isSubstring "OclAny" pstr)
andalso not (String.isSubstring "_2_OclAny" pstr)
andalso not (String.isSubstring "OclAny_2" pstr))
(* hack *)
then
case level of
univ => false
| operation => false
| holocl => false
| l0 => String.isSubstring "UML_OCL.level0." pstr
| l1 => String.isSubstring "UML_OCL.level1." pstr
| l2 => false
else
case level of
univ => String.isSubstring "UML_OCL.univ." pstr
| operation => String.isSubstring "UML_OCL.ops" pstr
| holocl => String.isSubstring "UML_OCL." pstr
| l0 => String.isSubstring "UML_OCL.level0." pstr
| l1 => String.isSubstring "UML_OCL.level1." pstr
| l2 => not (String.isSubstring "UML_OCL." pstr)
fun base_type_name_of path = if (path = (Rep_Core.name_of Rep_Core.OclAnyC)) (* hack *)
then ["OCL_OclAny_type","OclAny_key"] (* ??? *)
else rev (((hd (rev path))^"_base_type")::(tl (rev path)))
fun type_name_of path = if (path = (Rep_Core.name_of Rep_Core.OclAnyC)) (* hack *)
then ["OCL_OclAny_type","OclAny_key"]
else rev (((hd (rev path))^"_type")::(tl (rev path))) (* typeC *)
fun is_class_of path = rev (("is_"^(hd (rev path)))::(tl (rev path))) (* mkC *)
fun is_classType_of path = rev (("isType_"^(hd (rev path)))::(tl (rev path))) (* mkC *)
fun is_univ_class_of path = rev (("is_"^(hd (rev path))^"_univ")::(tl (rev path))) (* mkC *)
fun ext_name_of path = if (path = (Rep_Core.name_of Rep_Core.OclAnyC)) (* hack *)
then ["OCL_OclAny_type","OclAny_ext"]
else rev (((hd (rev path))^"_ext")::(tl (rev path))) (* extC *)
fun name_of_inv C = let
fun invariant_1_of path = path@["model","inv"]
in
hc_path l2 (invariant_1_of ((Rep_Core.name_of C)))
end
fun name_of_pre C Op = hc_path l2 (pre_1_of ((Rep_Core.name_of C)@[Rep_Core.mangled_name_of_op Op]))
fun name_of_post C Op = hc_path l2 (post_1_of ((Rep_Core.name_of C)@[Rep_Core.mangled_name_of_op Op]))
end
signature REP_HOLOCL_HELPER =
sig
val holocl_and : Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm
val holocl_and_all : Rep_OclTerm.OclTerm list -> Rep_OclTerm.OclTerm
val holocl_or : Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm
val holocl_or_all : Rep_OclTerm.OclTerm list -> Rep_OclTerm.OclTerm
val holocl_implies : Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm
val holocl_not : Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm
val holocl_xor : Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm -> Rep_OclTerm.OclTerm
val holocl_localValid_state : Rep_OclTerm.OclTerm -> string -> Rep_OclTerm.OclTerm
val holocl_localValid_transition : Rep_OclTerm.OclTerm -> string -> string -> Rep_OclTerm.OclTerm
val get_holocl_operation : string -> Rep_Core.operation -> Rep_Core.Classifier -> Rep_Core.transform_model -> Rep_OclTerm.OclTerm
val get_holocl_abstraction_relation: Rep_Core.Classifier -> Rep_Core.Classifier -> Rep_Core.transform_model -> Rep_OclTerm.OclTerm
end
structure Rep_HolOcl_Helper:REP_HOLOCL_HELPER =
struct
open Rep_Core
open Rep_OclType
open Rep_OclTerm
open WFCPOG_Library
exception HolOcl_Helper_InvalidArguments of string
fun type_of_t term = Rep_OclHelper.type_of term
fun ocl_opcall (source:OclTerm) f args t = OperationCall (source, type_of_t source, f,
map (fn x => (x,type_of_t x)) args,
t)
fun holocl_and a b = ocl_opcall a ["holOclLib","Boolean","and"] [b] Boolean
fun holocl_and_all [] = raise (HolOcl_Helper_InvalidArguments ("holocl.holocl_and_all: empty argument list"))
| holocl_and_all [a:OclTerm] = a
| holocl_and_all (h::t) = holocl_and h (holocl_and_all t)
fun holocl_or a b = ocl_opcall a ["holOclLib","Boolean","or"] [b] Boolean
fun holocl_or_all [] = raise (HolOcl_Helper_InvalidArguments ("holocl.holocl_or_all: empty argument list"))
| holocl_or_all [a:OclTerm] = a
| holocl_or_all (h::t) = holocl_or h (holocl_or_all t)
fun holocl_implies a b = ocl_opcall a ["holOclLib","Boolean","implies"] [b] Boolean
fun holocl_xor a b = ocl_opcall a ["holOclLib","Boolean","xor"] [b] Boolean
fun holocl_not a = ocl_opcall a ["holOclLib","Boolean","not"] [] Boolean
fun holocl_localValid_state term var_name =
OperationCall(term,Boolean,["holOclLib","Boolean","OclLocalValid"],[(Literal(var_name,OclState),DummyT)],Boolean)
fun holocl_localValid_transition term var_name1 var_name2 =
let
val sigma = Literal(var_name1,OclState)
val sigma_s = Literal(var_name2,OclState)
val tuple_term = Tuple [(var_name1,sigma,OclState),(var_name2,sigma_s,OclState)]
in
OperationCall(term,Boolean,["holOclLib","Boolean","OclLocalValid"],[(tuple_term,OclState)],Boolean)
end
fun get_holocl_operation abs_or_conc oper class model =
let
val _ = Logger.info ("WFCPOG_Refine_Constraint.get_holocl_operation\n")
val hol_name = string_of_path ((name_of class)@[name_of_op oper])
val styp = type_of class
val src = Variable((abs_or_conc^"_"^(name_of_op oper)),styp)
val predicate = Predicate(src,Boolean,[hol_name],args2varargs
(map (fn (n,t) => (abs_or_conc^"_"^n,t)) (arguments_of_op oper)))
val _ = Logger.info ("WFCPOG_Refine_Constraint.get_holocl_operation\n")
in
predicate
end
fun get_holocl_abstraction_relation abs_class conc_class model =
let
val _ = Logger.info ("WFCPOG_Refine_Constraint.get_holocl_abstraction_relation\n")
val predicate_name = "R_"^(string_of_path (package_of abs_class))^"_"^(string_of_path (package_of conc_class))^"_"^(List.last (name_of abs_class))
val abs_typ = type_of abs_class
val conc_typ = type_of conc_class
val abs_state = Variable("tau_concrete",OclState)
val conc_state = Variable("tau_abstract",OclState)
val abs_term = Variable(string_of_path (name_of abs_class),abs_typ)
val conc_term = Variable(string_of_path (name_of conc_class),conc_typ)
val predicate = Predicate(abs_state,OclState,[predicate_name],[(conc_state,OclState),(abs_term,abs_typ),(conc_term,conc_typ)])
val _ = Logger.info ("WFCPOG_Refine_Constraint.get_holocl_abstraction_relation\n")
in
predicate
end
end