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,22 +20,22 @@ 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,
val emptyTransition = {effect=NONE,
guard=NONE,
source="",
target="",
trans_id="",
trigger=NONE}))
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="",
val emptyEffect = {proc_id="",
language="",
body="",
expression=""}

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,116 +50,21 @@ 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
fun get_state_by_id (id:StateVertex_Id, SLp: StateVertex list ref) =
hd (List.filter (fn x => id_of_state x = id) (!SLp))
(*returns the list of subvertices *)
(* StateVertex -> StateVertex list *)
fun get_subvertex_list(State_CompositeState{subvertex,...}) = subvertex
| get_subvertex_list(S:StateVertex) = []
fun FinalState (SL:StateVertex list) = hd (List.filter isFinal SL)
(*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) = []
(* 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
(***************************************)
@ -217,26 +111,11 @@ 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"
@ -244,21 +123,24 @@ fun name_of_classif(C as Class c) = Rep.short_name_of C
(*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)
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 get_subvertex_list(top_state_of(hd SM))
else subvertices_of (#top (hd SM))
end
val SL1 = soc(C)
fun dive([]) = []
fun dive [] = []
| dive ((State_CompositeState{name=n,
subvertex=a,
incoming=b,
isConcurrent=c,
outgoing=d,
state_id=f})::t) = a@[(State_CompositeState{name=n,
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,
@ -266,38 +148,28 @@ fun states_of_classif(C:Classifier) = let fun soc(x) = let val SM:StateMachine l
state_id=f})]@dive(t)
| dive (h::t) = h::dive(t)
in
dive(SL1)
dive (soc C)
end
(* Classifier -> Transition list *)
fun transitions_of_classif(C:Classifier) = let val AG:ActivityGraph list = ActGraph_of_classif(C)
fun transitions_of_classif (C:Classifier) =
let val AG:ActivityGraph list = activity_graphs_of C
in
if AG = [] then []
else transitions_of_SM(hd AG)
else #transition (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 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)
fun get_names_of_trans (C:Classifier) =
let val ids = map #trans_id (List.concat (map #transition (activity_graphs_of C)))
in
concat_names "" ids
String.concatWith "," ids
end
@ -305,30 +177,23 @@ fun get_names_of_trans(C:Classifier) = let val SM = ActGraph_of_classif C
(*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)
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
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
@ -341,76 +206,31 @@ fun get_other_States(C:StateVertex list) = List.filter (fn x => (not (isPseudo x
(* 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)
(* 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
foreach(funList,[],!TransL)
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
fun next_state_id (TransID: Transition_Id, TransList: Transition list) =
#target (get_trans_by_id (TransID, ref TransList))
(* 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: *)
(* 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 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)
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
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 *)
@ -428,49 +248,42 @@ fun ident_of_guard(G:Guard) = let val sop = string_of_path(path_of_operation(G)
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 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)
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
(* 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 *)
(* 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)
| 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 = get_subvertex_list(S)
of true => let val subvertices = subvertices_of(S)
(*val outList = get_next_transitions(S,TransList)*)
val NextInit = get_initial(subvertices)
in
T_mk{trans_id=tid,
{trans_id=tid,
source=src,
target=id_of_state(NextInit),
guard=gd,
@ -481,8 +294,6 @@ fun correct_TransList([],_) = []
| false => head::correct_TransList(tail,StateList)
end
(* ''a * ''a list -> bool *)
fun ListMember(a,L) = List.exists (fn X => X=a) L
(* ''a * ''a list -> ''a list *)
@ -492,17 +303,16 @@ 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
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
@ -517,12 +327,10 @@ fun triggered_OUT_Trans(State_CompositeState{outgoing,...}, TL) = let val Trans
*)
(* 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)
| 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)
@ -531,24 +339,26 @@ fun correctCompositeTransitions([],RES,_) = RES
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),
fun handleUntriggered ([]:Transition list,_) = []
| handleUntriggered (h::t,T_id) = {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,
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_of_trans(T),
guard = guard_of_trans(T),
trigger = trigger_of_trans(T),
effect = effect_of_trans(T)}
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)
| 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))
@ -563,18 +373,16 @@ fun correctCompositeTransitions([],RES,_) = RES
| 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}
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
@ -588,15 +396,17 @@ fun updateStates([],_) = []
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)
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_of_trans(T))]
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 *)
@ -604,28 +414,30 @@ fun CollectTGE(T, TL, SL) = let val S = get_state_by_id(target_of_trans(T), SL)
(* 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)
| 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)
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
| 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)
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,
@ -644,12 +456,13 @@ fun calculate_SM_Trans([],_,_,_) = []
end
(* Classifier -> SM_Trans list *)
fun SM_Trans_of_classif(C:Classifier) = let val SL = states_of_classif(C)
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))))
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),
@ -675,7 +488,8 @@ fun SM_Trans_of_classif(C:Classifier) = let val SL = states_of_classif(C)
(* 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
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
@ -683,7 +497,8 @@ fun sort_SM_TransL_withGAtEnd(L,G) = let fun filterG({guards,...}:SM_Trans) = Li
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 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))
@ -691,9 +506,10 @@ fun next_SM_Trans_4EV(S, TLp,E) = let fun filterS({source,...}:SM_Trans) = (sour
(* 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)))
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
@ -701,15 +517,7 @@ fun is_TopState(S as State_CompositeState{...},C:Classifier) = let val top = top
| 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,46 +1,19 @@
(** convenience functions for handling strings. *)
structure StringHandling =
struct
open library
(** returns the capitalized string. *)
fun toUpper(S:string) = String.implode (List.map Char.toUpper (String.explode S))
(** returns the string in all caps. *)
fun toUpper (s:string) = String.map Char.toUpper 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
(** returns the uncapitalized string. *)
fun uncapitalize (s:string) = 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
(** returns the capitalized string. *)
fun capitalize (s:string) = let val sl = String.explode s
in
String.implode ((Char.toUpper (hd sl))::(tl sl))
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,6 +96,7 @@ fun replaceSafely _ _ "" = ""
(** removes leading, trainling, and multiple consecutive whitespace chars. *)
(* FIXME: movev to StringHandling? *)
fun cleanLine s = String.concatWith " " (String.tokens Char.isSpace s)
@ -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
@ -621,6 +622,11 @@ fun parents_of C cl = case parent_name_of C of
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
val classname = (rev o tl o rev) fq_name

View File

@ -309,13 +309,13 @@ 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,
{ 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 ,
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),
@ -324,11 +324,11 @@ fun transform_transition t (XMI.mk_Transition 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),
{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),
{top = transform_state t (#top st),
transition = map (transform_transition t) (#transitions st) }
(** transform a XMI.Classifier classifier into a Rep.Classifier *)

View File

@ -30,13 +30,7 @@ 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 Procedure
type Guard = Rep_OclTerm.OclTerm
type Parameter = string * Rep_OclType.OclType
@ -46,19 +40,12 @@ datatype Event = SignalEvent of 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 =
State_CompositeState
of {name : string,
@ -104,11 +91,29 @@ datatype StateVertex =
outgoing : Transition_Id list,
incoming : Transition_Id list}
(* | StubState *)
and StateMachine = SM_mk of {top : StateVertex,
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
@ -118,14 +123,13 @@ struct
type StateVertex_Id = string
type Transition_Id = string
datatype Procedure = Proc_mk of {proc_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 Event = SignalEvent of Parameter list
@ -134,7 +138,7 @@ datatype Event = SignalEvent of Parameter list
(* | ChangeEvent of Parameter list *)
datatype Transition = T_mk of {trans_id : Transition_Id,
type Transition = {trans_id : Transition_Id,
source : StateVertex_Id,
target : StateVertex_Id,
guard : Guard option,
@ -143,7 +147,6 @@ datatype Transition = T_mk of {trans_id : Transition_Id,
(* 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,
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