UML::Element的代数规范

学了这么久的maude,也没什么感觉,帖段代码吧。

(omod UML2-KERNEL-ELEMENT is
pr UML2-BASE .

sorts OwnedCommentRC OwnedElementRC .
subsorts OwnedCommentRC < OwnedElementRC < RoleCode .


--- subsorts OwnerRC < RoleCode . 
--- 因为模型元素的一般访问次序为树型访问,
--- 所以去掉OwnerRC角色码,以减少重复,
--- 另一个问题是当ownedElement从其容器元素中移到
--- 新的容器元素,则其owner需清除,这为模型转换带
--- 来复杂性,而没有owner成员属性时,当从容器中
--- 移走一个元素N,只要将容器.ownedElements(N.Oid)去掉
--- 即可将N重新绑定到新的容器。


op oe : -> OwnedElementRC [ctor] .
op oc : -> OwnedCommentRC [ctor] .


--- ownedComment: Comment[*] The Comments owned by this element. Subsets Element::ownedElement.
--- /ownedElement: Element[*] The Elements owned by this element. This is a derived union.
--- /owner: Element [0..1] The Element that owns this element. This is a derived union.


class Element | ownedElementCNt : List(ConnNode) .  *** 使用列表以支持子类的有序关联端约束

op isOwnedElement : Object Oid    -> Bool .
op getOwnedElement : Object Oid   -> ConnNode .     ***ownedElementCNt中以Oid为索引
op getOwnedElements : Object -> Set(Oid) .
op apdOwnedElement : Object Oid   -> Object .
op rmvOwnedElement : Object Oid   -> Object .

op isOwnedComment : Object Oid    -> Bool .
op getOwnedComment : Object Oid   -> ConnNode .
op getOwnedComments : Object -> Set(Oid) .
op apdOwnedComment : Object Oid   -> Object .
op rmvOwnedComment : Object Oid   -> Object .


vars O O1 O2 : Oid .
vars L L1 : List(ConnNode) .
vars R : RoleCode .

eq isOwnedElement(< O : Element | ownedElementCNt : L >, O1) = isInCN(L, O1) .

eq getOwnedElement(< O : Element | ownedElementCNt : L >, O1) = getCN(L, O1) .

eq getOwnedElements(< O : Element | ownedElementCNt : L >) = getOids(L) .

eq apdOwnedElement(< O : Element | ownedElementCNt : L >, O1) =
   < O : Element | ownedElementCNt : apdCN(L, O1, oe) > .         ***保证只有一个O。

eq rmvOwnedElement(< O : Element | ownedElementCNt : L >, O1) =
   < O : Element | ownedElementCNt : rmvCN(L, O1) > .
----------------------------------------------------------------------------
ceq isOwnedComment(< O : Element | ownedElementCNt : L >, O1) =
  true if rc(getCN(L, O1)) :: OwnedCommentRC .
eq isOwnedComment(< O : Element | >, O1) = false [owise] .

ceq getOwnedComment(< O : Element | ownedElementCNt : L ; (O1, R) ; L1 >, O1) =
   (O1, R) if R :: OwnedCommentRC .
eq getOwnedComment(< O : Element | ownedElementCNt : L >, O1) =
   (nil, nil) [owise] .

eq getOwnedComments(< O : Element | ownedElementCNt : (O1, R) ; L >) =
  if R :: OwnedCommentRC then O1 getOwnedComments(< O : Element | ownedElementCNt : L >)
  else getOwnedComments(< O : Element | ownedElementCNt : L >)
  fi .
eq  getOwnedComments(< O : Element | ownedElementCNt : none >) = mt .

eq apdOwnedComment(< O : Element | ownedElementCNt : L >, O1) =
   < O : Element | ownedElementCNt : apdCN(L, O1, oc) > .           *** 保证只有一个O。

***因为apdXXX保证最多只有一个O,故只需移走一个。
ceq rmvOwnedElement(< O : Element | ownedElementCNt : L ; (O1, R) ; L1 >, O1) =
   < O : Element | ownedElementCNt : L ; L1 > if R :: OwnedCommentRC .   
eq rmvOwnedElement(< O : Element | >, O1) = < O : Element | > [owise] .

endom)


(omod UML2-KERNEL-ELEMENT-WF is
inc UML2-KERNEL-ELEMENT .

*** public methods, please don't override
msgs check : Oid -> Msg .                      --- !!! required global variable g-m1CK(true, none) !!!
op   groupCkNotOwnThis : Set(Oid) Oid -> Object [ctor object] .
msgs ckNotOwnSelf-r : Oid Bool -> Msg .

*** output method for subclass to do themself check
msgs Element->check-r : Oid Bool -> Msg .

*** private methods
op   ckNotOwnSelf : Oid Set(Oid) -> Configuration [ctor] .
op   ckOwnedElements : Set(Oid) -> Configuration [ctor] .


vars N S : Oid .  *** N : current Node, S : Src
vars B : Bool .
vars R : RoleCode .
vars LT : List(Lmr(String | Oid | Bool)) .
vars L L1 : List(ConnNode) .
vars NS : Set(Oid) .


--- check global error state(only here) and avoid reEnter
crl [Element::check] : check(N) < N : Element | >
g-m1CK(LT, true) => < N : Element | > g-m1CK(("checking...", N, true) ; LT, true)
ckNotOwnSelf(N, getOwnedElements(< N : Element | >))
if not hasChecked(LT, "checking...", N) .


--- crl [Element::check.reEnter] : check(N) < N : Element | >
--- g-m1CK(B, L) => < N : Element | > g-m1CK(B, L)
--- if not B or hasChecked("Element::check.b", N, L) .   *** eat check(N) if reEnter


rl [Element::groupCkNotOwnThis.OK] : groupCkNotOwnThis(mt, S)
=> ckNotOwnSelf-r(S, true) .


crl [Element::groupCkNotOwnThis.Fail] : groupCkNotOwnThis(N NS, S)
< N : Element | > => < N : Element | > ckNotOwnSelf-r(S, false)
if isOwnedElement(< N : Element | >, S) .


crl [Element::groupCkNotOwnThis.Cont] : groupCkNotOwnThis(N NS, S)
< N : Element | > => < N : Element | >
groupCkNotOwnThis(NS getOwnedElements(< N : Element | >), S)
if not isOwnedElement(< N : Element | >, S) .


--- ckNotOwnSelf-r
*** finished and OK+(bootstrap owned elements' checking)
rl [Element::ckNotOwnSelf-r.OK+] : ckNotOwnSelf-r(N, true)
< N : Element | > g-m1CK(LT, true) => 
< N : Element | > g-m1CK(("Element::ckNotOwnSelf", N, true) ; LT, true)
Element->check-r(N, true) ckOwnedElements(getOwnedElements(< N : Element | >)) .


rl [Element::ckNotOwnSelf-r.OK-] : ckNotOwnSelf-r(N, true)
< N : Element | > g-m1CK(LT, false) => < N : Element | >
g-m1CK(("Element::ckNotOwnSelf", N, true) ; LT, false) . *** finished and OK-


rl [Element::ckNotOwnSelf.Fail] : ckNotOwnSelf-r(N, false)
< N : Element | > g-m1CK(LT, B) =>
< N : Element | > g-m1CK(("Element::ckNotOwnSelf", N, false) ; LT, false) .
                                                                 *** finished and FAIL
*** private methods

eq ckNotOwnSelf(N, N NS ) = ckNotOwnSelf-r(N, false) .
eq ckNotOwnSelf(N, mt) = ckNotOwnSelf-r(N, true) .
eq ckNotOwnSelf(N, NS) = groupCkNotOwnThis(NS, N) [owise] .

eq ckOwnedElements(mt) = none .
eq ckOwnedElements(N NS) = check(N) ckOwnedElements(NS) .

endom)

posted on 2005-03-02 01:34  阿飞外传  阅读(985)  评论(0编辑  收藏  举报

导航