some cleanup, mostly state machines

git-svn-id: https://projects.brucker.ch/su4sml/svn/infsec-import/trunk/src/su4sml@6086 3260e6d1-4efc-4170-b0a7-36055960796d
This commit is contained in:
Jürgen Doser 2007-02-08 17:02:09 +00:00
parent 743110b62f
commit 08d3897b87
11 changed files with 594 additions and 659 deletions

View File

@ -12,6 +12,7 @@ struct
open Rep
open Rep_OclType
open Rep_OclTerm
(* open Rep_SecureUML_ComponentUML.Security*)
open ComponentUML
open XMI_DataTypes
@ -19,23 +20,23 @@ open XMI_DataTypes
val emptyEvent = CallEvent(["","","EMPTY"],[])
val emptyGuard = OperationCall(Variable("",DummyT),DummyT,["EMPTY"],[],DummyT):Guard
val emptyState = (State_SimpleState({ state_id="",
val emptyState = (Rep_StateMachine.State_SimpleState({ state_id="",
outgoing=[],
incoming=[],
name=""}))
val emptyTransition = (T_mk({effect=NONE,
guard=NONE,
source="",
target="",
trans_id="",
trigger=NONE}))
val emptyTransition = {effect=NONE,
guard=NONE,
source="",
target="",
trans_id="",
trigger=NONE}
val lastGuard = OperationCall(Variable("self",DummyT),DummyT,["else"],[],Boolean):Guard
val alwaysTrigger = CallEvent(["auto","auto","auto"],[])
val alwaysGuard = OperationCall(Variable("self",DummyT), DummyT, ["alwaysG"],[],Boolean):Guard
val emptyEffect = Proc_mk{proc_id="",
language="",
body="",
expression=""}
val emptyEffect = {proc_id="",
language="",
body="",
expression=""}
end

View File

@ -74,9 +74,9 @@ fun super2Native "ClassifierScope" = "static"
* overrides some lookup entries of the base cartridge
*)
fun lookup (env : environment) "attribute_name_small_letter"
= StringHandling.startWithSmallLetter (SuperCart.lookup (unpack env) "attribute_name")
= StringHandling.uncapitalize (SuperCart.lookup (unpack env) "attribute_name")
| lookup (env : environment) "attribute_name_capital"
= StringHandling.startWithCapital (SuperCart.lookup (unpack env) "attribute_name")
= StringHandling.capitalize (SuperCart.lookup (unpack env) "attribute_name")
| lookup (env : environment) (s as "attribute_type") = super2Native (SuperCart.lookup (unpack env) s )
| lookup (env : environment) (s as "attribute_visibility")= super2Native (SuperCart.lookup (unpack env) s)
| lookup (env : environment) (s as "attribute_scope") = super2Native (SuperCart.lookup (unpack env) s)

View File

@ -97,7 +97,7 @@ fun lookup (env : environment) "state_name" = toUpper(name_of_state(#curState en
| lookup (env : environment) "guard_ident" = ident_of_guard(#1(#curGuard env))
| lookup (env : environment) "event_name" = toUpper(name_of_event(#curEvent env))
| lookup (env : environment) "cur_event_id" = toUpper(name_of_event(#curEvent env))
| lookup (env : environment) "effect_ident" = ident_of_effect(#curEffect env)
| lookup (env : environment) "effect_ident" = #proc_id (#curEffect env)
| lookup (env : environment) "trigger_name" = name_of_event(#curEvent env)
| lookup (env : environment) "real_init" = id_of_state(realInit(Option.valOf(SuperCart.curClassifier (unpack env))))
| lookup (env : environment) s = SuperCart.lookup (unpack env) s
@ -107,7 +107,7 @@ fun evalCondition (env : environment) "hasAG" = hasAG(Option.valOf(SuperCart.cur
| evalCondition (env : environment) "isTrigger" = let val Transitions = transitions_of_classif(Option.valOf(SuperCart.curClassifier (unpack env)))
val oper = Option.valOf(SuperCart.curOperation (unpack env))
in
acts_as_trigger(oper,Transitions)
acts_as_trigger oper Transitions
end
| evalCondition (env : environment) "isLastGuard" = (#2(#curGuard env)) = 0
| evalCondition (env : environment) "isLastTrans" = (#2(#curTransition env)) = 0
@ -215,7 +215,7 @@ fun foreach_guard(env: environment) = let val GL = guards_of_SM_Trans(#1(#curTra
List.map env_from_GL (transform(GL,(LEN-1)))
end
fun all_guards(env: environment) = let val AGL = createDistinct(List.concat (List.map guards_of_SM_Trans (#allTransitions env)))
fun all_guards(env: environment) = let val AGL = makeDistinct(List.concat (List.map guards_of_SM_Trans (#allTransitions env)))
fun env_from_GL G = {
curState = #curState env,
allTransitions = #allTransitions env,

View File

@ -71,9 +71,9 @@ fun super2Native "ClassifierScope" = "static"
* overrides some lookup entries of the base cartridge
*)
fun lookup (env : environment) "attribute_name_small_letter"
= StringHandling.startWithSmallLetter (SuperCart.lookup (unpack env) "attribute_name")
= StringHandling.uncapitalize (SuperCart.lookup (unpack env) "attribute_name")
| lookup (env : environment) "attribute_name_capital"
= StringHandling.startWithCapital (SuperCart.lookup (unpack env) "attribute_name")
= StringHandling.capitalize (SuperCart.lookup (unpack env) "attribute_name")
| lookup (env : environment) (s as "attribute_type") = super2Native (SuperCart.lookup (unpack env) s )
| lookup (env : environment) (s as "attribute_visibility")= super2Native (SuperCart.lookup (unpack env) s)
| lookup (env : environment) (s as "attribute_scope") = super2Native (SuperCart.lookup (unpack env) s)

View File

@ -24,13 +24,6 @@
(* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
(*****************************************************************************************)
(*use "../../me/sources/types.sml";
use "../../me/sources/helperFunctions.sml";
use "../../me/sources/stringHandling.sml";
use "SM_helper.sml";
*)
structure StateMachine =
struct
@ -41,16 +34,12 @@ open Rep_OclTerm
open Rep_StateMachine
open SM_Helper
open StateMachineTypes
open ListEq
(********************************************)
(* Generic types handling functions: *)
(* --------------------------------- *)
(********************************************)
(*simulate SET behaviour*)
(* ''a list -> ''a list *)
fun createDistinct([]) = []
| createDistinct(h::t) = createDistinct((List.filter (fn x => not (x=h)) t))@[h]
(*return the initial state*)
exception MalformedStateMachine
@ -61,117 +50,22 @@ exception MalformedStateMachine
(* ------------------------- *)
(************************************)
fun is_StartState(PseudoState{kind,...}) = (kind=XMI.initial)
| is_StartState(_) = false
(* StateVertex -> StateVertex_Id *)
fun id_of_state(State_SimpleState{state_id,...}) = state_id
| id_of_state(State_CompositeState{state_id,...}) = state_id
| id_of_state(SimpleState_ActionState{state_id,...}) = state_id
| id_of_state(SimpleState_ObjectflowState{state_id,...}) = state_id
| id_of_state(State_FinalState{state_id,...}) = state_id
| id_of_state(PseudoState{state_id,...}) = state_id
| id_of_state(SyncState{state_id,...}) = state_id
fun name_of_state(State_SimpleState{name,...}) = name
| name_of_state(State_CompositeState{name,...}) = name
| name_of_state(SimpleState_ActionState{name,...}) = name
| name_of_state(State_FinalState{...}) = "Final"
| name_of_state(S as PseudoState{kind,...}) = case kind
of XMI.initial => "INIT"^id_of_state(S)
| XMI.junction => "ERROR"
| _ => "WRONG"
(* StateVertex_Id * StateVertex list ref -> StateVertex *)
fun get_state_by_id(id:StateVertex_Id, SLp: StateVertex list ref) = let fun hasID i S = (id_of_state(S) = i)
val filterf = hasID id
in
hd (List.filter filterf (!SLp))
end
(*returns the list of subvertices *)
(* StateVertex -> StateVertex list *)
fun get_subvertex_list(State_CompositeState{subvertex,...}) = subvertex
| get_subvertex_list(S:StateVertex) = []
(*return list of outgoing states' transition ids*)
(* StateVertex -> Transition_Id list *)
fun get_next_transitions_ID(State_SimpleState{outgoing,...}) = outgoing
| get_next_transitions_ID(State_CompositeState{outgoing,...}) = outgoing
| get_next_transitions_ID(SimpleState_ActionState{outgoing,...}) = outgoing
| get_next_transitions_ID(SimpleState_ObjectflowState{outgoing,...}) = outgoing
| get_next_transitions_ID(State_FinalState{...}) = []
| get_next_transitions_ID(PseudoState{outgoing,...}) = outgoing
| get_next_transitions_ID(SyncState{outgoing,...}) = outgoing
(* StateVertex -> Transition_Id list *)
fun get_prev_transitions_T(State_SimpleState{incoming,...}) = incoming
| get_prev_transitions_T(State_CompositeState{incoming,...}) = incoming
| get_prev_transitions_T(SimpleState_ActionState{incoming,...}) = incoming
| get_prev_transitions_T(SimpleState_ObjectflowState{incoming,...}) = incoming
| get_prev_transitions_T(State_FinalState{...}) = []
| get_prev_transitions_T(PseudoState{incoming,...}) = incoming
| get_prev_transitions_T(SyncState{incoming,...}) = incoming
(* StateVertex -> bool *)
fun isPseudo(PseudoState{kind,...}) = not(kind=XMI.initial)
| isPseudo(_) = false
fun isInit(PseudoState{kind,...}) = kind=XMI.initial
| isInit(_) = false
(* StateVertex -> bool *)
(* fun Final(State_FinalState x) = true *)
(* | Final(_) = false *)
fun isFinal(State_FinalState{...}) = true
| isFinal(_) = false
fun FinalState(SL:StateVertex list) = hd (List.filter (fn (State_FinalState x) => true
| (_) => false) SL)
(* get list of subvertices *)
(* StateVertex -> StateVertex list *)
fun subvertices_of_state(State_CompositeState{subvertex,...}) = subvertex
| subvertices_of_state(S:StateVertex) = []
fun get_state_by_id (id:StateVertex_Id, SLp: StateVertex list ref) =
hd (List.filter (fn x => id_of_state x = id) (!SLp))
fun FinalState (SL:StateVertex list) = hd (List.filter isFinal SL)
(* StateVertex * SM_Trans list ref -> SM_Trans list *)
fun get_next_SM_Trans(S, TLp) = let fun filterF({source,...}:SM_Trans) = (source = id_of_state(S))
in
List.filter filterF (!TLp)
end
fun get_next_SM_Trans (s:StateVertex) TLp =
List.filter (fn (x:SM_Trans) => #source x = id_of_state s) (!TLp)
(* StateVertex * SM_Trans list ref * 'a -> Event list *)
fun events_of_state(S:StateVertex, TLp, SLp) = let val TransitionOutList = get_next_SM_Trans(S,TLp)
fun TRIGGERS({triggers,...}:SM_Trans) = triggers
fun collectEvts([]) = []
| collectEvts(h::t) = TRIGGERS(h)::collectEvts(t)
in
createDistinct(List.concat (collectEvts(TransitionOutList)))
end
(*****************************************)
(* Transition handling functions: *)
(* ------------------------------ *)
(*****************************************)
(* Transition -> Transition_Id *)
fun id_of_trans(T_mk{trans_id,...}) = trans_id
(* Transition -> StateVertex_Id *)
fun source_of_trans(T_mk{source,...}) = source
(* Transition -> StateVertex_Id *)
fun target_of_trans(T_mk{target,...}) = target
(* Transition -> Guard option *)
fun guard_of_trans(T_mk{guard,...}) = guard
fun effect_of_trans(T_mk{effect,...}) = effect
(* Transition -> Event option *)
fun trigger_of_trans(T_mk{trigger,...}) = trigger
fun events_of_state (S:StateVertex, TLp, SLp) =
(makeDistinct o List.concat o map #triggers o get_next_SM_Trans S) TLp
(***************************************)
(* SM_Trans handling functions: *)
@ -179,23 +73,23 @@ fun trigger_of_trans(T_mk{trigger,...}) = trigger
(***************************************)
(* SM_Trans -> StateVertex_Id *)
fun target_of_SM_Trans({target,...}:SM_Trans) = target
fun target_of_SM_Trans ({target,...}:SM_Trans) = target
(* SM_Trans -> Guard list *)
fun guards_of_SM_Trans({guards,...}:SM_Trans) = guards
fun guards_of_SM_Trans ({guards,...}:SM_Trans) = guards
(* SM_Trans -> Event list *)
fun triggers_of_SM_Trans({triggers,...}:SM_Trans) = triggers
fun triggers_of_SM_Trans ({triggers,...}:SM_Trans) = triggers
(* Transition_Id * StateVertex_Id * StateVertex_Id * Guard list * Event list * Action list -> SM_Trans *)
fun mk_SM_T(tid, s, t, ga, ta, ea) = {trans_id = tid,
source = s,
target = t,
guards = ga,
triggers = ta,
effects = ea}:SM_Trans
fun mk_SM_T (tid, s, t, ga, ta, ea) = {trans_id = tid,
source = s,
target = t,
guards = ga,
triggers = ta,
effects = ea}:SM_Trans
(************************************)
(* Event handling functions: *)
(* ------------------------- *)
@ -217,273 +111,190 @@ fun path_of_event(CallEvent([a,b,c],_)) = c
(* ------------------------------ *)
(*****************************************)
(*returns the activity graphs (list) of the given Classifier --> this is a list of StateMachines*)
(* Classifier -> ActivityGraph list *)
fun ActGraph_of_classif(Class{activity_graphs,...}) = activity_graphs
| ActGraph_of_classif(_) = []
(*get the list of transitions *)
(* ActivityGraph -> Transition list *)
fun transitions_of_SM(SM_mk{transition,...}:ActivityGraph) = transition
(*return top state of a state machine*)
(* StateMachine -> StateVertex *)
fun top_state_of(SM_mk{top,...}) = top
(*get all defined activity graphs in a list of Classifiers --> ActivityGraph list*)
(* Classifier list -> ActivityGraph list *)
fun ActGraph_of_classif_from_list(C:Classifier list) = let fun isFull l = (fn x => (List.length x > 0)) l
in
List.concat (List.filter isFull (List.map ActGraph_of_classif C))
end
fun ActGraph_of_classif_from_list (C:Classifier list) =
List.concat (map activity_graphs_of C)
fun name_of_classif(C as Class c) = Rep.short_name_of C
| name_of_classif(Primitive p) = "PRIMITIVE"
| name_of_classif(_) = "XXX"
fun name_of_classif (C as Class c) = Rep.short_name_of C
| name_of_classif (Primitive p) = "PRIMITIVE"
| name_of_classif (_) = "XXX"
(*return list of subertices ot the given Classifier (Class, Primitive,...)*)
(* Classifier -> StateVertex list *)
fun states_of_classif(C:Classifier) = let fun soc(x) = let val SM:StateMachine list = ActGraph_of_classif(x)
in
if SM=[] then []
(*FIXME: SM can have more than one AG defined... (remove "hd")
SM can be another type than CompositeState...*)
else get_subvertex_list(top_state_of(hd SM))
end
val SL1 = soc(C)
fun dive([]) = []
| dive((State_CompositeState{name=n,
subvertex=a,
incoming=b,
isConcurrent=c,
outgoing=d,
state_id=f})::t) = a@[(State_CompositeState{name=n,
subvertex=a,
incoming=b,
isConcurrent=c,
outgoing=d,
state_id=f})]@dive(t)
| dive(h::t) = h::dive(t)
in
dive(SL1)
end
fun states_of_classif (C:Classifier) =
let fun soc x =
let val SM:StateMachine list = activity_graphs_of x
in
if SM=[] then []
(*FIXME: SM can have more than one AG defined... (remove "hd")
SM can be another type than CompositeState...*)
else subvertices_of (#top (hd SM))
end
fun dive [] = []
| dive ((State_CompositeState{name=n,
subvertex=a,
incoming=b,
isConcurrent=c,
outgoing=d,
state_id=f})::t) =
(* FIXME: don't we have to recurse here into a? *)
a@[(State_CompositeState{name=n,
subvertex=a,
incoming=b,
isConcurrent=c,
outgoing=d,
state_id=f})]@dive(t)
| dive (h::t) = h::dive(t)
in
dive (soc C)
end
(* Classifier -> Transition list *)
fun transitions_of_classif(C:Classifier) = let val AG:ActivityGraph list = ActGraph_of_classif(C)
in
if AG = [] then []
else transitions_of_SM(hd AG)
end
fun events_of_classif(C:Classifier) = let val TL = transitions_of_classif(C)
val TrigL = List.map trigger_of_trans TL
in
createDistinct (List.map Option.valOf (List.filter Option.isSome TrigL))
end
fun transitions_of_classif (C:Classifier) =
let val AG:ActivityGraph list = activity_graphs_of C
in
if AG = [] then []
else #transition (hd AG)
end
fun events_of_classif (C:Classifier) =
makeDistinct (List.mapPartial #trigger (transitions_of_classif C))
(*returns a string with every transition_id separated by a "," *)
(* Classifier -> string *)
fun get_names_of_trans(C:Classifier) = let val SM = ActGraph_of_classif C
val transitions_LL = List.map transitions_of_SM SM
fun concat_names s [] = s
| concat_names s (h::t) = concat_names (s^","^h) t
val ids = List.map id_of_trans (List.concat transitions_LL)
in
concat_names "" ids
end
fun get_names_of_trans (C:Classifier) =
let val ids = map #trans_id (List.concat (map #transition (activity_graphs_of C)))
in
String.concatWith "," ids
end
(*processes the list of given {Simple,Pseudo,...} states and creates a "sane" representation. *)
(* Transition_Id * Transition list ref -> Transition *)
fun get_trans_by_id(id:Transition_Id, TLp: Transition list ref) = let fun hasID i T = (id_of_trans(T) = i)
val filterf = hasID id
val TL = !TLp
in
hd (List.filter filterf TL)
end
fun get_trans_by_id (id:Transition_Id, TLp: Transition list ref) =
hd (List.filter (fn x => #trans_id x = id) (!TLp))
(*returns list of state having given kind. NOTE: this only applies for PseudoStates*)
(* PseudoStateVars * StateVertex list -> StateVertex list *)
fun get_state_by_kind(KIND:PseudoStateVars, SVL: StateVertex list) = let fun hasKind k (PseudoState{kind,...}) = (k = kind)
| hasKind k _ = false
val filterF = hasKind KIND
in
List.filter filterF SVL
end
fun get_state_by_kind (KIND:PseudoStateVars, SVL: StateVertex list) =
let fun hasKind k (PseudoState{kind,...}) = (k = kind)
| hasKind k _ = false
in
List.filter (hasKind KIND) SVL
end
(* StateVertex list -> StateVertex *)
fun get_initial(SVL: StateVertex list) = let val IL = get_state_by_kind(XMI.initial,SVL)
val count = List.length IL
in
if (count > 1) orelse (count = 0) then raise MalformedStateMachine
else hd IL
end
fun get_initial (SVL: StateVertex list) = case List.find isInit SVL
of SOME x => x
| _ => raise MalformedStateMachine
(* StateVertex list -> StateVertex list *)
fun get_PseudoStates(C:StateVertex list) = List.filter isPseudo C
fun get_PseudoStates (C:StateVertex list) = List.filter isPseudo C
(* StateVertex list -> StateVertex list *)
fun get_other_States(C:StateVertex list) = List.filter (fn x => (not (isPseudo x))) C
fun get_other_States (C:StateVertex list) = List.filter (fn x => (not (isPseudo x))) C
(* returns the list of state ids that are targets of the items in the transition list "outgoing" *)
(* StateVertex * Transition list ref -> Transition list *)
fun get_next_transitions(S:StateVertex, TransL: Transition list ref) = let fun filterf x y = get_trans_by_id(x, ref y)
val OUT_T = get_next_transitions_ID(S)
val funList = List.map filterf OUT_T
fun foreach([],R,T) = R
| foreach(h::t,R,T) = foreach(t,(h T)::R, T)
in
foreach(funList,[],!TransL)
end
(* FIXME: there must be some simpler way... *)
fun get_next_transitions (s:StateVertex, TransL: Transition list ref) =
let fun filterf x y = get_trans_by_id (x, ref y)
val funList = List.map filterf (outgoing_of s)
in
foldl (fn (f,x) => f (!TransL) :: x ) [] funList
end
(* Transition_Id * Transition list -> StateVertex_Id *)
fun next_state_id(TransID: Transition_Id, TransList: Transition list) = let val TRANS = get_trans_by_id(TransID, ref TransList)
in
target_of_trans(TRANS)
end
(* Transition * Transition list * StateVertex list -> GEPath *)
(* fun GE(T, TL, SL) = let val S = get_state_by_id(target_of_trans(T),ref SL) *)
(* val TRIGGER = trigger_of_trans(T) *)
(* val GUARD = guard_of_trans(T) *)
(* val NEXTL = get_next_transitions(S,ref TL) *)
(* in *)
(* if Pseudo(S) then GEBranch(GUARD,TRIGGER,List.map (fn X => GE(X,TL,SL)) NEXTL) *)
(* else GELeaf(GUARD,TRIGGER,target_of_trans(T)) *)
(* end *)
(* fun traverseGE(GELeaf(one,two,three)) = [([one],[two],three)] *)
(* | traverseGE(GEBranch(one,two,LIST)) = let val DEEPER = List.map traverseGE LIST *)
(* val PRUNED = List.concat DEEPER *)
(* fun ADD(L1,L2,S) = (one::L1,two::L2,S) *)
(* val REALLY = List.map ADD PRUNED *)
(* in *)
(* REALLY *)
(* end *)
(*or, without the GEPath datastructure: *)
fun next_state_id (TransID: Transition_Id, TransList: Transition list) =
#target (get_trans_by_id (TransID, ref TransList))
(* operation * Transition list -> bool *)
fun acts_as_trigger(O:operation,T: Transition list) = let fun collect_triggers(TL) = let val triggerList = List.map (fn T_mk{trigger,...} => trigger) TL
val triggerList_pure = List.filter Option.isSome triggerList
val EventList = List.map Option.valOf triggerList_pure
fun getPath(CallEvent(path,parameters)) = path
| getPath(_) = []: Path
fun extractPath(E:Event) = List.nth(getPath(E),2)
in
List.map extractPath EventList
end
val TriggerID_list = collect_triggers(T)
in
List.exists (fn x => x = name_of_op(O)) TriggerID_list
end
fun acts_as_trigger (O:operation) (T:Transition list) =
let val EventList = List.mapPartial #trigger T
fun getPath (CallEvent(path,parameters)) = path
| getPath (_) = []: Path
fun extractPath (E:Event) = List.nth (getPath E, 2)
in
List.exists (fn x => x = name_of_op O) (map extractPath EventList)
end
(* operation list * Transition list -> operation list *)
fun get_triggers(O: operation list, T: Transition list) = let fun filterf([],Ls,Lr) = Lr
| filterf(h::t, Ls, Lr) = if acts_as_trigger(h,Ls) then filterf(t,Ls,h::Lr)
else filterf(t,Ls,Lr)
in
filterf(O,T,[])
end
(* Classifier -> string list *)
fun get_event_list(C:Classifier) = let val EL = events_of_classif(C)
in
List.map name_of_event EL
end
(* returns the path (string list) of the operation call *)
(* OclTerm -> Path *)
fun path_of_operation(OperationCall(_,_,P,L,_)) = P
| path_of_operation(_) = []
fun path_of_operation (OperationCall(_,_,P,L,_)) = P
| path_of_operation (_) = []
(* Guard -> Path *)
fun path_of_guard(G:Guard) = path_of_operation(G)
fun path_of_guard (G:Guard) = path_of_operation(G)
(* Guard -> string *)
fun ident_of_guard(G:Guard) = let val sop = string_of_path(path_of_operation(G))
in
case sop
of "else" => "elseG"
| _ => sop
end
fun ident_of_guard (G:Guard) = let val sop = string_of_path(path_of_operation(G))
in
case sop
of "else" => "elseG"
| _ => sop
end
(*
(* (Guard option list * Event option list * 'a) list -> (string list * string list * 'a) list *)
fun processPL(L) = let fun processOptionL(LIST) = List.map (fn X => Option.valOf(X)) (List.filter Option.isSome LIST)
fun processOCList(LIST) = List.concat (List.map path_of_guard LIST)
fun processEVList(LIST) = List.map name_of_event LIST
fun transform(a,b,c) = (processOCList(processOptionL(a)),processEVList(processOptionL(b)),c)
in
List.map transform L
end
fun processPL L =
let fun processOptionL (LIST) = List.mapPartial (fn x => x) LIST
fun processOCList (LIST) = List.concat (List.map path_of_guard LIST)
fun processEVList (LIST) = List.map name_of_event LIST
fun transform (a,b,c) = (processOCList (processOptionL a),
processEVList (processOptionL b),
c)
in
List.map transform L
end
*)
(*Classifier -> bool *)
fun hasAG(C:Classifier) = let val AG = ActGraph_of_classif(C)
in
not (AG = [])
end
fun hasAG (C:Classifier) = not ((activity_graphs_of C) = [])
(* OclTerm -> bool *)
fun is_else_Guard(G as OperationCall(Variable(_,_),_,[a,b,c],_,_)) = a = "else"
| is_else_Guard(_) = false
fun is_else_Guard (G as OperationCall(Variable(_,_),_,[a,b,c],_,_)) = a = "else"
| is_else_Guard (_) = false
(* StateVertex -> bool *)
fun isComposite(State_CompositeState{...}) = true
| isComposite(_) = false
(*re-route all transitions pointing to a Composite State.
Afther this there does _NOT_ exist a transition from any
state to a Composite State anymore *)
Afther this there does _NOT_ exist a transition from any
state to a Composite State anymore *)
(* Transition list * StateVertex list ref -> Transition list *)
fun correct_TransList([],_) = []
| correct_TransList((head as T_mk{trans_id=tid,
source=src,
target=tgt,
guard=gd,
trigger=tr,
effect=eff})::tail,StateList) = let val S = get_state_by_id(target_of_trans(head),StateList)
in
case isComposite(S)
of true => let val subvertices = get_subvertex_list(S)
(*val outList = get_next_transitions(S,TransList)*)
val NextInit = get_initial(subvertices)
in
T_mk{trans_id=tid,
source=src,
target=id_of_state(NextInit),
guard=gd,
trigger=tr,
effect=eff}::correct_TransList(tail,StateList)
end
| false => head::correct_TransList(tail,StateList)
end
(* ''a * ''a list -> bool *)
fun ListMember(a,L) = List.exists (fn X => X=a) L
| correct_TransList((head as {trans_id=tid, source=src, target=tgt, guard=gd,
trigger=tr, effect=eff})::tail,StateList) =
let val S = get_state_by_id(#target(head),StateList)
in
case isComposite(S)
of true => let val subvertices = subvertices_of(S)
(*val outList = get_next_transitions(S,TransList)*)
val NextInit = get_initial(subvertices)
in
{trans_id=tid,
source=src,
target=id_of_state(NextInit),
guard=gd,
trigger=tr,
effect=eff}::correct_TransList(tail,StateList)
end
| false => head::correct_TransList(tail,StateList)
end
(* ''a * ''a list -> ''a list *)
fun removeFromList(a,[]) = []
@ -492,224 +303,221 @@ fun removeFromList(a,[]) = []
(*assumption: elements are unique --> set-like *)
(* ''a list * ''a list -> ''a list *)
(* FIXME: find out the intendes semantics and move to ListEq *)
fun ListDifference([],L2) = L2
| ListDifference(L1,[]) = L1
| ListDifference(h::t,L) = if ListMember(h,L) then ListDifference(t,removeFromList(h,L))
| ListDifference(h::t,L) = if ListEq.includes L h then ListDifference(t,removeFromList(h,L))
else h::ListDifference(t,removeFromList(h,L))
(* Transition -> bool *)
fun isTriggered(T_mk{trigger=SOME(x),...}) = true
| isTriggered(_) = false
(* return the transitions of this composite state having a trigger defined *)
(* StateVertex * Transition list ref -> Transition list *)
fun triggered_OUT_Trans(State_CompositeState{outgoing,...}, TL) = let val Trans = List.map (fn X => get_trans_by_id(X,TL)) outgoing
in
List.filter isTriggered Trans
end
fun triggered_OUT_Trans(State_CompositeState{outgoing,...}, TL) =
let val Trans = List.map (fn X => get_trans_by_id(X,TL)) outgoing
in
List.filter isTriggered Trans
end
| triggered_OUT_Trans(_) = []
(* here we have to handle two cases:
1) the super state's (composite state) transitions without a trigger
2) the SS' transitions with a trigger
In the case of 1) we only have to re-route these transitions such that they have as origin the inner finalState
To tackle 2) we have to create for each inner state an additional transition to the the targets of those transitions.
Of course the Events/Guards/Effects have to be preserved...
*)
1) the super state's (composite state) transitions without a trigger
2) the SS' transitions with a trigger
In the case of 1) we only have to re-route these transitions such that they have as origin the inner finalState
To tackle 2) we have to create for each inner state an additional transition to the the targets of those transitions.
Of course the Events/Guards/Effects have to be preserved...
*)
(* StateVertex list * Transition list * Transition list ref -> Transition list *)
fun correctCompositeTransitions([],RES,_) = RES
| correctCompositeTransitions((SCS as State_CompositeState{name,
state_id,
outgoing,
incoming,
subvertex,
isConcurrent})::tail,newTrans,allTrans) = let val SV = get_subvertex_list(SCS)
val subverticesID = List.map id_of_state SV
val subvertex_count = List.length(SV)
val triggered = triggered_OUT_Trans(SCS,allTrans)
val outlist = get_next_transitions(SCS,allTrans)
val untriggered = ListDifference(triggered,outlist)
val Final = FinalState(SV)
fun createIncList 0 = []
| createIncList n = (createIncList (n-1))@[n]
fun handleUntriggered([],_) = []
| handleUntriggered(h::t,T_id) = T_mk{trans_id = "newUT_"^Int.toString(T_id),
source = id_of_state(Final),
target = target_of_trans(h),
guard = guard_of_trans(h),
trigger = trigger_of_trans(h),
effect = effect_of_trans(h)}::handleUntriggered(t,(T_id+1))
fun createTrans T_id T S = T_mk{trans_id = T_id,
source = S,
target = target_of_trans(T),
guard = guard_of_trans(T),
trigger = trigger_of_trans(T),
effect = effect_of_trans(T)}
fun applyList([],_) = []
| applyList(h::t,fList) = (List.map (fn X => X(h)) fList)@applyList(t,fList)
fun handleTriggered([],_) = []
| handleTriggered(h::t,T_id) = let val idList = List.map (fn X => Int.toString(T_id)^"_"^Int.toString(X)) (createIncList subvertex_count)
val funList = (List.map (fn X => X(h)) (List.map createTrans idList))
in
applyList(subverticesID,funList)@handleTriggered(t,(T_id+1))
end
val newTriggered = handleTriggered(triggered,0)
val newUTriggered = handleUntriggered(untriggered,0)
in
correctCompositeTransitions(tail,
newTrans@newTriggered@newUTriggered,
allTrans)
end
| correctCompositeTransitions((SCS as State_CompositeState{name,state_id,outgoing,incoming,
subvertex,isConcurrent})::tail,
newTrans, allTrans) =
let val SV = subvertices_of(SCS)
val subverticesID = List.map id_of_state SV
val subvertex_count = List.length(SV)
val triggered = triggered_OUT_Trans(SCS,allTrans)
val outlist = get_next_transitions(SCS,allTrans)
val untriggered = ListDifference(triggered,outlist)
val Final = FinalState(SV)
fun createIncList 0 = []
| createIncList n = (createIncList (n-1))@[n]
fun handleUntriggered ([]:Transition list,_) = []
| handleUntriggered (h::t,T_id) = {trans_id = "newUT_"^Int.toString(T_id),
source = id_of_state(Final),
target = #target(h),
guard = #guard(h),
trigger = #trigger(h),
effect = #effect(h)}::handleUntriggered(t,(T_id+1))
fun createTrans T_id (T:Transition) S = {trans_id = T_id,
source = S,
target = #target(T),
guard = #guard(T),
trigger = #trigger(T),
effect = #effect(T)}
fun applyList([],_) = []
| applyList(h::t,fList) = (List.map (fn X => X(h)) fList)@applyList(t,fList)
fun handleTriggered([],_) = []
| handleTriggered(h::t,T_id) =
let val idList = List.map (fn X => Int.toString(T_id)^"_"^Int.toString(X))
(createIncList subvertex_count)
val funList = (List.map (fn X => X(h)) (List.map createTrans idList))
in
applyList(subverticesID,funList)@handleTriggered(t,(T_id+1))
end
val newTriggered = handleTriggered(triggered,0)
val newUTriggered = handleUntriggered(untriggered,0)
in
correctCompositeTransitions(tail,
newTrans@newTriggered@newUTriggered,
allTrans)
end
| correctCompositeTransitions(h::t,nt,at) = correctCompositeTransitions(t,nt,at)
(* StateVertex list * Transition list -> StateVertex list *)
fun updateStates([],_) = []
| updateStates(h::t,Transitions) = let val affectedOutTransitions = List.filter (fn X => source_of_trans(X) = id_of_state(h)) Transitions (* transitions that source from h *)
val affectedInTransitions = List.filter (fn X => target_of_trans(X) = id_of_state(h)) Transitions
val newOut = createDistinct((List.map id_of_trans affectedOutTransitions)@get_next_transitions_ID(h))
val newIn = createDistinct((List.map id_of_trans affectedInTransitions)@get_prev_transitions_T(h))
fun updateState(State_CompositeState{name=n,state_id=sid,outgoing=ol,incoming=il,subvertex=sv,isConcurrent=c}) = State_CompositeState{name=n,state_id=sid,outgoing=ol@newOut,incoming=il@newIn,subvertex=sv,isConcurrent=c}
| updateState(State_SimpleState{name=n,state_id=sid,outgoing=ol,incoming=il}) = State_SimpleState{name=n,state_id=sid,outgoing=ol@newOut,incoming=il@newIn}
| updateState(SimpleState_ActionState{name=n,state_id=sid,outgoing=ol,incoming=il,isDynamic=d}) = SimpleState_ActionState{name=n,state_id=sid,outgoing=ol@newOut,incoming=il@newIn,isDynamic=d}
| updateState(SimpleState_ObjectflowState{state_id=sid,outgoing=ol,incoming=il,isSynch=s,parameter=p,types=t}) = SimpleState_ObjectflowState{state_id=sid,outgoing=ol,incoming=il,isSynch=s,parameter=p,types=t}
| updateState(State_FinalState{state_id=sid,incoming=il}) = State_FinalState{state_id=sid,incoming=il@newIn}
| updateState(PseudoState{state_id=sid,kind=k,outgoing=ol,incoming=il}) = PseudoState{state_id=sid,kind=k,outgoing=ol@newOut,incoming=il@newIn}
| updateState(SyncState{state_id=sid,outgoing=ol,incoming=il}) = SyncState{state_id=sid,outgoing=ol@newOut,incoming=il@newIn}
in
updateState(h)::updateStates(t,Transitions)
end
fun updateStates([],_:Transition list) = []
| updateStates(h::t,Transitions) =
let val affectedOutTransitions = List.filter (fn X => #source X = id_of_state h)
Transitions (* transitions that source from h *)
val affectedInTransitions = List.filter (fn X => #target(X) = id_of_state(h))
Transitions
val newOut = makeDistinct((List.map #trans_id affectedOutTransitions)@outgoing_of(h))
val newIn = makeDistinct((List.map #trans_id affectedInTransitions)@incoming_of(h))
fun updateState s = add_incoming (add_outgoing s newOut) newIn
in
updateState(h)::updateStates(t,Transitions)
end
(*
T: Transition
TL: Transition list ref (all)
SL: (State * parent) list ref (all)
TL: Transition list ref (all)
SL: (State * parent) list ref (all)
for every transition T we calculate the propper transition list to every target state.
I.e. we "divide out" the CompositeStates and the PseudoStates.
*)
fun CollectTGE(T, TL, SL) = let val S = get_state_by_id(target_of_trans(T), SL)
val TRIGGER = trigger_of_trans(T)
val GUARD = guard_of_trans(T)
val EFFECT = effect_of_trans(T)
val NEXTL = get_next_transitions(S,TL)
fun ADD(L1,L2,L3,S) = (GUARD::L1,TRIGGER::L2,EFFECT::L3,S)
in
if isPseudo(S) orelse isInit(S) then List.map ADD (List.concat (List.map (fn X => CollectTGE(X,TL,SL)) NEXTL))
else [([GUARD],[TRIGGER],[EFFECT],target_of_trans(T))]
end
for every transition T we calculate the propper transition list to every target state.
I.e. we "divide out" the CompositeStates and the PseudoStates.
*)
fun CollectTGE(T, TL, SL) =
let val S = get_state_by_id(#target(T), SL)
val TRIGGER = #trigger(T)
val GUARD = #guard(T)
val EFFECT = #effect(T)
val NEXTL = get_next_transitions(S,TL)
fun ADD(L1,L2,L3,S) = (GUARD::L1,TRIGGER::L2,EFFECT::L3,S)
in
if isPseudo(S) orelse isInit(S)
then List.map ADD (List.concat (List.map (fn X => CollectTGE(X,TL,SL)) NEXTL))
else [([GUARD],[TRIGGER],[EFFECT],#target(T))]
end
(* add transitions of to the out-states of the 'parent' states inside a composite state *)
(* NOTE: has to be called with a list of states that does NOT contain pseudo states!!*)
(* StateVertex list * Transition list * Transition list * StateVertex list -> SM_Trans list list *)
fun calculate_SM_Trans([],_,_,_) = []
| calculate_SM_Trans((SCS as State_CompositeState{name,state_id,outgoing,incoming,subvertex,isConcurrent})::t,
Parent_OutList,
TransList,
StateList) = let val outlist = get_next_transitions(SCS, ref TransList)
in
calculate_SM_Trans(subvertex,
Parent_OutList@outlist,
TransList,
StateList)@calculate_SM_Trans(t,
Parent_OutList,
TransList,
StateList)
end
| calculate_SM_Trans(h::t,
Parent_OutList:Transition list,
TransList:Transition list,
StateList:StateVertex list) = let val outlist = get_next_transitions(h,ref TransList):Transition list
val TL = List.concat (List.map (fn X => CollectTGE(X,ref TransList,ref StateList)) outlist)
val UTriggeredParentT = List.concat (List.map (fn X => CollectTGE(X,ref TransList, ref StateList)) (List.filter (fn X => not(isTriggered(X))) Parent_OutList))
val TriggeredParentT = List.concat (List.map (fn X => CollectTGE(X,ref TransList, ref StateList)) (List.filter isTriggered Parent_OutList))
val ParentT = List.concat (List.map (fn X => CollectTGE(X,ref TransList, ref StateList)) Parent_OutList)
fun getValOfOptionList(LIST) = List.map (fn X =>Option.valOf(X)) (List.filter Option.isSome LIST)
fun Path2SM_Trans Source (Guards,Events,Effects,Target) = { trans_id = "nothing",
source = Source,
target = Target,
guards = Guards,
triggers = Events,
effects = Effects
}:SM_Trans
val PList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) TL
val TriggeredPPList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) TriggeredParentT
val PPList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) ParentT
val UTriggeredPPList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) UTriggeredParentT
val SM_TransL = if isFinal(h) then (List.map (Path2SM_Trans (id_of_state(h))) (PList@PPList))
else List.map (Path2SM_Trans (id_of_state(h))) (PList@TriggeredPPList)
in
SM_TransL::calculate_SM_Trans(t,Parent_OutList,TransList,StateList)
end
| calculate_SM_Trans((SCS as State_CompositeState{name,state_id,outgoing,incoming,
subvertex,isConcurrent})::t,
Parent_OutList, TransList, StateList) =
let val outlist = get_next_transitions(SCS, ref TransList)
in
calculate_SM_Trans(subvertex,
Parent_OutList@outlist,
TransList,
StateList)@calculate_SM_Trans(t, Parent_OutList, TransList, StateList)
end
| calculate_SM_Trans(h::t, Parent_OutList:Transition list, TransList:Transition list,
StateList:StateVertex list) =
let val outlist = get_next_transitions(h,ref TransList):Transition list
val TL = List.concat (List.map (fn X => CollectTGE(X,ref TransList,ref StateList)) outlist)
val UTriggeredParentT =
List.concat (List.map (fn X => CollectTGE(X,ref TransList, ref StateList))
(List.filter (fn X => not(isTriggered(X))) Parent_OutList))
val TriggeredParentT =
List.concat (List.map (fn X => CollectTGE(X,ref TransList, ref StateList))
(List.filter isTriggered Parent_OutList))
val ParentT = List.concat (List.map (fn X => CollectTGE(X,ref TransList, ref StateList))
Parent_OutList)
fun getValOfOptionList(LIST) = List.map (fn X =>Option.valOf(X))
(List.filter Option.isSome LIST)
fun Path2SM_Trans Source (Guards,Events,Effects,Target) = { trans_id = "nothing",
source = Source,
target = Target,
guards = Guards,
triggers = Events,
effects = Effects
}:SM_Trans
val PList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) TL
val TriggeredPPList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) TriggeredParentT
val PPList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) ParentT
val UTriggeredPPList = List.map (fn (a,b,c,d) => (getValOfOptionList(a),getValOfOptionList(b),getValOfOptionList(c),d)) UTriggeredParentT
val SM_TransL = if isFinal(h) then (List.map (Path2SM_Trans (id_of_state(h))) (PList@PPList))
else List.map (Path2SM_Trans (id_of_state(h))) (PList@TriggeredPPList)
in
SM_TransL::calculate_SM_Trans(t,Parent_OutList,TransList,StateList)
end
(* Classifier -> SM_Trans list *)
fun SM_Trans_of_classif(C:Classifier) = let val SL = states_of_classif(C)
val TL = correct_TransList(transitions_of_classif(C),ref SL)
val TL = TL@correctCompositeTransitions(SL,[],ref TL)
val SL = updateStates(SL,TL)
val NPS = List.filter (fn X => (not (isPseudo(X)))) SL
val rawTransList = createDistinct(List.concat(calculate_SM_Trans(NPS,[],TL,states_of_classif(C))))
fun addAutoTriggers([]) = []
| addAutoTriggers(h::t) = case triggers_of_SM_Trans(h)
of [] => mk_SM_T((#trans_id h),
(#source h),
(#target h),
(#guards h),
[alwaysTrigger],
(#effects h))::addAutoTriggers(t)
| _ => h::addAutoTriggers(t)
fun addAutoGuards([]) = []
| addAutoGuards(h::t) = case guards_of_SM_Trans(h)
of [] => mk_SM_T((#trans_id h),
(#source h),
(#target h),
[alwaysGuard],
(#triggers h),
(#effects h))::addAutoGuards(t)
| _ => h::addAutoGuards(t)
in
addAutoGuards(addAutoTriggers(rawTransList))
end
fun SM_Trans_of_classif (C:Classifier) =
let val SL = states_of_classif(C)
val TL = correct_TransList(transitions_of_classif(C),ref SL)
val TL = TL@correctCompositeTransitions(SL,[],ref TL)
val SL = updateStates(SL,TL)
val NPS = List.filter (fn X => (not (isPseudo(X)))) SL
val rawTransList = makeDistinct (List.concat(calculate_SM_Trans(NPS,[],TL,states_of_classif(C))))
fun addAutoTriggers([]) = []
| addAutoTriggers(h::t) = case triggers_of_SM_Trans(h)
of [] => mk_SM_T((#trans_id h),
(#source h),
(#target h),
(#guards h),
[alwaysTrigger],
(#effects h))::addAutoTriggers(t)
| _ => h::addAutoTriggers(t)
fun addAutoGuards([]) = []
| addAutoGuards(h::t) = case guards_of_SM_Trans(h)
of [] => mk_SM_T((#trans_id h),
(#source h),
(#target h),
[alwaysGuard],
(#triggers h),
(#effects h))::addAutoGuards(t)
| _ => h::addAutoGuards(t)
in
addAutoGuards(addAutoTriggers(rawTransList))
end
(* SM_Trans list * Guard -> SM_Trans list *)
(* Sorts the list L in such a way, that all SM_Transitions with guard G are at the end *)
fun sort_SM_TransL_withGAtEnd(L,G) = let fun filterG({guards,...}:SM_Trans) = List.exists (fn X => X=G) guards
val GL = List.filter filterG L
val nGL = List.filter (fn X => not(filterG(X))) L
in
nGL@GL
end
fun sort_SM_TransL_withGAtEnd(L,G) =
let fun filterG({guards,...}:SM_Trans) = List.exists (fn X => X=G) guards
val GL = List.filter filterG L
val nGL = List.filter (fn X => not(filterG(X))) L
in
nGL@GL
end
(*FIXME - we have to discard the trigger-array and use a single trigger instead *)
fun next_SM_Trans_4EV(S, TLp,E) = let fun filterS({source,...}:SM_Trans) = (source=id_of_state(S))
fun filterE({triggers,...}:SM_Trans) = List.exists (fn X => X=E) triggers
in
List.filter filterE (List.filter filterS (!TLp))
end
fun next_SM_Trans_4EV(S, TLp,E) =
let fun filterS({source,...}:SM_Trans) = (source=id_of_state(S))
fun filterE({triggers,...}:SM_Trans) = List.exists (fn X => X=E) triggers
in
List.filter filterE (List.filter filterS (!TLp))
end
(* effects_of_SM_Trans = fn : SM_Trans -> Action list *)
fun effects_of_SM_Trans({effects,...}: SM_Trans) = effects
fun ident_of_effect(Proc_mk{proc_id,...}) = proc_id
(* fun ident_of_effect ({proc_id,...}:Procedure) = proc_id*)
fun is_TopState(S as State_CompositeState{...},C:Classifier) = let val top = top_state_of(hd (ActGraph_of_classif(C)))
val dbt = print(id_of_state(top))
in
S = top
end
fun is_TopState(S as State_CompositeState{...},C:Classifier) =
let val top = #top (hd (activity_graphs_of C))
val dbt = print(id_of_state(top))
in
S = top
end
| is_TopState(_,_) = false
fun realInit(C:Classifier) = let val TopState = top_state_of(hd(ActGraph_of_classif(C)))
val subvertices = get_subvertex_list(TopState)
val InitL = List.filter is_StartState subvertices
in
case InitL
of [] => raise MalformedStateMachine
| [x] => x
| _ => raise MalformedStateMachine
end
(* Codegen.generate (Rep_SecureUML_ComponentUML.readXMI "examples/Chessboard_composite.xmi") "c#_sm_VIZ"; *)
fun realInit (c:Classifier) = (get_initial o subvertices_of o #top o hd o activity_graphs_of) c
end

View File

@ -1,49 +1,22 @@
(** convenience functions for handling strings. *)
structure StringHandling =
struct
open library
(** returns the string in all caps. *)
fun toUpper (s:string) = String.map Char.toUpper s
(** returns the uncapitalized string. *)
fun uncapitalize (s:string) = let val sl = String.explode s
in
String.implode ((Char.toLower (hd sl))::(tl sl))
end
(** returns the capitalized string. *)
fun toUpper(S:string) = String.implode (List.map Char.toUpper (String.explode S))
(*reassemble given string list by concatenating every time the string character to each element and return the whole as a string *)
(* string list * string -> string *)
fun reassemble(S: string list,c : string) = String.concat (List.map (fn x => x^c) S)
fun concatBefore(S: string list, c: string) = String.concat (List.map (fn x =>c^x) S)
(* Pair list * string -> string *)
fun replace_vars_in_String(L:(string*string) list,Str) =
let val LINES = String.tokens (fn x => x = #"\n") Str
fun isVariable(S) = (List.length (List.filter (fn x => x = #"$") (String.explode S))) = 2 (*string->bool*)
fun isEqual(s1:string,s2:string) = (s1<=s2) andalso (s1>=s2)(*string*string -> bool*)
fun filterOut(VarName) = List.filter (fn X => isEqual(fst(X),VarName)) L(*string -> Pair list*)
fun VarIt(x) = String.tokens (fn x => x = #"$") x
fun process([],R) = R
| process(h::t,R) = let val Filtered = filterOut(h)
in
if (List.length Filtered) > 0 then process(t,R@[snd(hd Filtered)])
else process(t,R@[h])
end
fun replace(Str) = let val TABBED = String.tokens (fn x => x = #"\t") Str
val VARRED = List.map VarIt TABBED
val P = List.map (fn X => process(X,[])) VARRED
in
String.concatWith "\t" (List.map (fn X => (String.concatWith "" X)) P)
end
in
String.concatWith "\n" (List.map replace LINES)
end
fun startWithSmallLetter s = let val sl = String.explode s
in
String.implode ((Char.toLower (hd sl))::(tl sl))
end
fun startWithCapital s = let val sl = String.explode s
in
String.implode ((Char.toUpper (hd sl))::(tl sl))
end
fun capitalize (s:string) = let val sl = String.explode s
in
String.implode ((Char.toUpper (hd sl))::(tl sl))
end
end

View File

@ -80,6 +80,7 @@ datatype TemplateTree = RootNode of TemplateTree list
(**
* replaceSafely (s,v,x) replaces every v that occurs unescaped in s with x.
* if v occurs escaped with "\" in s, then the "\" is removed from s.
* FIXME: move to stringhandling?
*)
fun replaceSafely _ _ "" = ""
| replaceSafely v x s =
@ -95,7 +96,8 @@ fun replaceSafely _ _ "" = ""
(** removes leading, trainling, and multiple consecutive whitespace chars. *)
fun cleanLine s = String.concatWith " " (String.tokens Char.isSpace s)
(* FIXME: movev to StringHandling? *)
fun cleanLine s = String.concatWith " " (String.tokens Char.isSpace s)
(* debugging function
@ -149,10 +151,7 @@ fun getContent l = let val sl = tokenize l
else String.concat (tl (fieldSplit #" " (String.concat (tl sl))))
end
(**
* cleans line, replaces nl and tabs
* so that no space char is left out
*)
(** cleans line, replaces nl and tabs so that no space char is left out. *)
fun preprocess s = replaceSafely "@tab" "\t" (replaceSafely "@nl" "\n" (cleanLine s))

View File

@ -9,6 +9,9 @@ sig
(** checks whether the lists are disjunct, i.e., do not overlap. *)
val disjunct: ''a list -> ''a list -> bool
(** removes duplicate elements. *)
val makeDistinct: ''a list -> ''a list
end
@ -25,4 +28,8 @@ fun overlaps xs ys = includes (map (includes xs) ys) true
(** checks whether the lists are disjunct, i.e., do not overlap. *)
fun disjunct xs ys = not (overlaps xs ys)
(** removes duplicate elements. *)
fun makeDistinct [] = []
| makeDistinct (h::t) = h::makeDistinct (List.filter (fn x => not (x=h)) t)
end

View File

@ -122,6 +122,7 @@ val operations_of : Classifier -> operation list
val invariant_of : Classifier -> (string option * Rep_OclTerm.OclTerm) list
val stereotypes_of : Classifier -> string list
val string_of_path : string list -> string
val activity_graphs_of: Classifier -> Rep_ActivityGraph.ActivityGraph list
val arguments_of_op : operation -> (string * Rep_OclType.OclType) list
val precondition_of_op : operation -> (string option * Rep_OclTerm.OclTerm) list
@ -620,6 +621,11 @@ fun parents_of C cl = case parent_name_of C of
| class => (if( class = (name_of OclAnyC) )
then [(name_of OclAnyC)]
else [class]@(parents_of (class_of class cl) cl))
(* returns the activity graphs (list) of the given Classifier --> this is a list of StateMachines*)
(* Classifier -> ActivityGraph list *)
fun activity_graphs_of (Class{activity_graphs,...}) = activity_graphs
| activity_graphs_of _ = []
fun operation_of cl fq_name =
let

View File

@ -309,27 +309,27 @@ fun transform_event t (XMI.CallEvent ev) =
Rep.SignalEvent (map (transform_parameter t) (#parameter ev))
fun transform_proc t (XMI.mk_Procedure proc) =
Rep.Proc_mk { proc_id = #xmiid proc,
language = #language proc,
body = #body proc,
expression = #expression proc }
fun transform_transition t (XMI.mk_Transition trans)
= Rep.T_mk { trans_id = #xmiid trans ,
source = #source trans,
target = #target trans,
guard = Option.map (transform_guard t) (#guard trans),
trigger = Option.map ((transform_event t) o (find_event t))
(#trigger trans),
effect = Option.map (transform_proc t) (#effect trans)}
{ proc_id = #xmiid proc,
language = #language proc,
body = #body proc,
expression = #expression proc }
fun transform_transition t (XMI.mk_Transition trans) =
{ trans_id = #xmiid trans ,
source = #source trans,
target = #target trans,
guard = Option.map (transform_guard t) (#guard trans),
trigger = Option.map ((transform_event t) o (find_event t))
(#trigger trans),
effect = Option.map (transform_proc t) (#effect trans)}
fun transform_activitygraph t (XMI.mk_ActivityGraph act) =
Rep_StateMachine.SM_mk {top = transform_state t (#top act),
transition = map (transform_transition t) (#transitions act) }
{top = transform_state t (#top act),
transition = map (transform_transition t) (#transitions act) }
fun transform_statemachine t (XMI.mk_StateMachine st) =
Rep_StateMachine.SM_mk {top = transform_state t (#top st),
transition = map (transform_transition t) (#transitions st) }
{top = transform_state t (#top st),
transition = map (transform_transition t) (#transitions st) }
(** transform a XMI.Classifier classifier into a Rep.Classifier *)
fun transform_classifier t (XMI.Class {xmiid,name,isActive,visibility,isLeaf,

View File

@ -29,37 +29,24 @@ sig
type StateVertex_Id
type Transition_Id
datatype Procedure = Proc_mk of {proc_id : string,
language : string,
body : string,
expression : string }
(* perhaps this type has to be changes according to what we can expect *)
(* from CASE tools *)
type Guard = Rep_OclTerm.OclTerm
type Procedure
type Guard = Rep_OclTerm.OclTerm
type Parameter = string * Rep_OclType.OclType
datatype Event = SignalEvent of Parameter list
| CallEvent of Rep_OclType.Path * Parameter list
| CallEvent of Rep_OclType.Path * Parameter list
(* | TimeEvent of Parameter list *)
(* | ChangeEvent of Parameter list *)
datatype Transition = T_mk of {trans_id: Transition_Id,
source : StateVertex_Id,
target : StateVertex_Id,
guard : Guard option,
trigger : Event option,
effect : Procedure option
(* mmm : StateVertexId option *)
}
type Transition
type PseudoStateVars = XMI_StateMachines.PseudoStateVars
datatype StateVertex =
datatype StateVertex =
State_CompositeState
of {name : string,
state_id : StateVertex_Id,
@ -67,11 +54,11 @@ datatype StateVertex =
incoming : Transition_Id list,
subvertex : StateVertex list,
isConcurrent : bool
(* submachine : StateMachine *
{isDynamic : bool
(* + dynamicArguments
+ dynamicMultiplicity *)} option *)}
(* variant for Subactivity State *)
(* submachine : StateMachine *
{isDynamic : bool
(* + dynamicArguments
+ dynamicMultiplicity *)} option *)}
(* variant for Subactivity State *)
| State_SimpleState
of {name : string,
state_id : StateVertex_Id,
@ -104,12 +91,30 @@ datatype StateVertex =
outgoing : Transition_Id list,
incoming : Transition_Id list}
(* | StubState *)
and StateMachine = SM_mk of {top : StateVertex,
transition : Transition list}
withtype StateMachine = {top : StateVertex,
transition : Transition list}
val isInit : StateVertex -> bool
val isPseudo : StateVertex -> bool
val isFinal : StateVertex -> bool
val isComposite : StateVertex -> bool
val isTriggered : Transition -> bool
val id_of_state : StateVertex -> string
val name_of_state : StateVertex -> string
val subvertices_of : StateVertex -> StateVertex list
val outgoing_of : StateVertex -> Transition_Id list
val incoming_of : StateVertex -> Transition_Id list
val pseudo_state_kind_of : StateVertex -> PseudoStateVars
val add_outgoing : StateVertex -> Transition_Id list -> StateVertex
val add_incoming : StateVertex -> Transition_Id list -> StateVertex
end
structure Rep_StateMachine : REP_STATE_MACHINE =
@ -117,33 +122,31 @@ struct
type StateVertex_Id = string
type Transition_Id = string
type Procedure = {proc_id : string,
language : string,
body : string,
expression : string }
type Guard = Rep_OclTerm.OclTerm
type Parameter = string * Rep_OclType.OclType
datatype Procedure = Proc_mk of {proc_id : string,
language : string,
body : string,
expression : string }
type Guard = Rep_OclTerm.OclTerm
type Parameter = string * Rep_OclType.OclType
datatype Event = SignalEvent of Parameter list
| CallEvent of Rep_OclType.Path * Parameter list
(* | TimeEvent of Parameter list *)
(* | ChangeEvent of Parameter list *)
| CallEvent of Rep_OclType.Path * Parameter list
(* | TimeEvent of Parameter list *)
(* | ChangeEvent of Parameter list *)
datatype Transition = T_mk of {trans_id : Transition_Id,
source : StateVertex_Id,
target : StateVertex_Id,
guard : Guard option,
trigger : Event option,
effect : Procedure option
(* mmm : StateVertexId option *)
}
type Transition = {trans_id : Transition_Id,
source : StateVertex_Id,
target : StateVertex_Id,
guard : Guard option,
trigger : Event option,
effect : Procedure option
(* mmm : StateVertexId option *)
}
type PseudoStateVars = XMI_StateMachines.PseudoStateVars
datatype StateVertex =
@ -191,8 +194,146 @@ datatype StateVertex =
outgoing : Transition_Id list,
incoming : Transition_Id list}
(* | StubState *)
and StateMachine = SM_mk of {top : StateVertex,
transition : Transition list}
withtype StateMachine = {top : StateVertex,
transition : Transition list}
(* StateVertex -> StateVertex_Id *)
fun id_of_state (State_SimpleState{state_id,...}) = state_id
| id_of_state (State_CompositeState{state_id,...}) = state_id
| id_of_state (SimpleState_ActionState{state_id,...}) = state_id
| id_of_state (SimpleState_ObjectflowState{state_id,...}) = state_id
| id_of_state (State_FinalState{state_id,...}) = state_id
| id_of_state (PseudoState{state_id,...}) = state_id
| id_of_state (SyncState{state_id,...}) = state_id
fun name_of_state (State_SimpleState{name,...}) = name
| name_of_state (State_CompositeState{name,...}) = name
| name_of_state (SimpleState_ActionState{name,...}) = name
| name_of_state (State_FinalState{...}) = "Final"
| name_of_state (S as PseudoState{kind,...}) = case kind
of XMI.initial => "INIT"^id_of_state(S)
| XMI.junction => "ERROR"
| _ => "WRONG"
(** returns the list of subvertices. *)
fun subvertices_of (State_CompositeState{subvertex,...}) = subvertex
| subvertices_of _ = []
fun pseudo_state_kind_of (PseudoState{kind,...}) = kind
(* cough. *)
fun isPseudo (PseudoState{kind,...}) = not(kind=XMI.initial)
| isPseudo _ = false
fun isInit (PseudoState{kind,...}) = kind=XMI.initial
| isInit _ = false
fun isFinal (State_FinalState{...}) = true
| isFinal _ = false
fun isComposite (State_CompositeState{...}) = true
| isComposite _ = false
fun outgoing_of (State_SimpleState{outgoing,...}) = outgoing
| outgoing_of (State_CompositeState{outgoing,...}) = outgoing
| outgoing_of (SimpleState_ActionState{outgoing,...}) = outgoing
| outgoing_of (SimpleState_ObjectflowState{outgoing,...}) = outgoing
| outgoing_of (State_FinalState{...}) = []
| outgoing_of (PseudoState{outgoing,...}) = outgoing
| outgoing_of (SyncState{outgoing,...}) = outgoing
fun incoming_of (State_SimpleState{incoming,...}) = incoming
| incoming_of (State_CompositeState{incoming,...}) = incoming
| incoming_of (SimpleState_ActionState{incoming,...}) = incoming
| incoming_of (SimpleState_ObjectflowState{incoming,...}) = incoming
| incoming_of (State_FinalState{incoming,...}) = incoming
| incoming_of (PseudoState{incoming,...}) = incoming
| incoming_of (SyncState{incoming,...}) = incoming
fun isTriggered (t:Transition) = Option.isSome (#trigger t)
fun add_outgoing (State_CompositeState {name,state_id,outgoing,incoming,
subvertex,isConcurrent}) newOut =
State_CompositeState{name=name,
state_id=state_id,
outgoing=outgoing@newOut,
incoming=incoming,
subvertex=subvertex,
isConcurrent=isConcurrent}
| add_outgoing (State_SimpleState{name=n,state_id=sid,outgoing=ol,incoming=il}) newOut =
State_SimpleState{ name=n,
state_id=sid,
outgoing=ol@newOut,
incoming=il}
| add_outgoing (SimpleState_ActionState{name=n,state_id=sid,outgoing=ol,
incoming=il,isDynamic=d}) newOut =
SimpleState_ActionState{ name=n,
state_id=sid,
outgoing=ol@newOut,
incoming=il,
isDynamic=d}
| add_outgoing (SimpleState_ObjectflowState{state_id=sid,outgoing=ol,incoming=il,
isSynch=s,parameter=p,types=t}) newOut =
SimpleState_ObjectflowState{ state_id=sid,
outgoing=ol@newOut,
incoming=il,
isSynch=s,
parameter=p,
types=t}
| add_outgoing (s as State_FinalState{state_id=sid,incoming=il}) newOut = s
| add_outgoing (PseudoState{state_id=sid,kind=k,outgoing=ol,incoming=il}) newOut =
PseudoState{ state_id=sid,
kind=k,
outgoing=ol@newOut,
incoming=il}
| add_outgoing (SyncState{state_id=sid,outgoing=ol,incoming=il}) newOut =
SyncState {state_id=sid,
outgoing=ol@newOut,
incoming=il}
fun add_incoming (State_CompositeState{name=n,state_id=sid,outgoing=ol,
incoming=il,subvertex=sv,isConcurrent=c}) newIn =
State_CompositeState{ name=n,
state_id=sid,
outgoing=ol,
incoming=il@newIn,
subvertex=sv,
isConcurrent=c}
| add_incoming (State_SimpleState{name=n,state_id=sid,outgoing=ol,incoming=il}) newIn =
State_SimpleState{name=n,
state_id=sid,
outgoing=ol,
incoming=il@newIn}
| add_incoming (SimpleState_ActionState{name=n,state_id=sid,outgoing=ol,
incoming=il,isDynamic=d}) newIn =
SimpleState_ActionState{name=n,
state_id=sid,
outgoing=ol,
incoming=il@newIn,
isDynamic=d}
| add_incoming (SimpleState_ObjectflowState{state_id=sid,outgoing=ol,incoming=il,
isSynch=s,parameter=p,types=t}) newIn =
SimpleState_ObjectflowState{state_id=sid,
outgoing=ol,
incoming=il, (* FIXME? *)
isSynch=s,
parameter=p,
types=t}
| add_incoming (State_FinalState{state_id=sid,incoming=il}) newIn =
State_FinalState{ state_id=sid,
incoming=il@newIn}
| add_incoming (PseudoState{ state_id=sid,kind=k,outgoing=ol,incoming=il}) newIn =
PseudoState{ state_id=sid,
kind=k,
outgoing=ol,
incoming=il@newIn}
| add_incoming (SyncState{state_id=sid,outgoing=ol,incoming=il}) newIn =
SyncState{ state_id=sid,
outgoing=ol,
incoming=il@newIn}
end