예제 #1
0
    def out(self, model, heads, tails):
        #output head and tail outside for merging
        if self.head != None:
            self.next_path()

        #generate place for every input
        #skip if explicit place at the begining or end
        for e in self.final_heads:
            if util.is_explicit_place(model, e) == False:
                place_begin = t.TreePlace()
                place_begin.name = util.gen_place_label(model)
                place_begin.children += [e]
                model.elements += [place_begin]
                heads += [place_begin]

        for e in self.final_tails:
            if util.is_explicit_place(model, e) == False:
                place_end = t.TreePlace()
                place_end.name = util.gen_place_label(model)
                e.children += [place_end]
                model.elements += [place_end]
                tails += [place_end]

        if len(heads) < 2:
            raise Exception(
                'Expected parallel block to have at least two paths')
예제 #2
0
    def out(self, model, heads, tails):
        #output head and tail outside for merging
        if self.head != None:
            self.next_path()

        place_begin = t.TreePlace()
        model.elements += [place_begin]
        heads += [place_begin]

        place_begin.name = util.gen_place_label(model)

        #NOTE: Implementation propetrty. If the segment in confusion has chain with multiple children
        #   at the time of processing the block the central place is attached to the children.
        #   This functionality allows for implementation of gated confusion.
        #To achieve regular confusion block use fragment within the selectgion list
        # Might need improvement in next versions
        #place on second child if more than one exist in path

        for i in range(len(self.final_heads)):
            fh = self.final_heads[i]
            e = self.final_tails[i]

            if util.is_explicit_place(model, e) == False:
                tails += [e]
                place_begin.children += [e]

            if util.is_explicit_place(model, fh) == False and fh != e:
                heads += [fh]

        if len(place_begin.children) < 2:
            raise Exception(
                'Expected confusion block to have at least two paths')
예제 #3
0
def apply_markings(model):

    for m in model.meta.markings:
        place = util.match_strictly(model, m.input, m.output, t.TreePlace)

        if len(place) == 0:
            #attempt to find one to one transition
            #many to many without place are invalid
            if (len(m.input) == 1) and (len(m.output) == 1):
                place = util.find_transition_one_to_one(
                    model, m.input[0], m.output[0])
                if len(place) == 1:
                    p = t.TreePlace()
                    p.name = util.gen_place_label(model)
                    p.marking = True
                    model.elements += [p]

                    s = place[0][0]
                    d = place[0][1]

                    s.children.remove(d)
                    s.children += [p]
                    p.children += [d]

                elif len(place) == 0:
                    raise Exception('Could not locate marking [%s]->[%s]' %
                                    (m.input, m.output))
                elif len(place) > 1:
                    raise Exception(
                        'Multiple candidates marking inconclusive [%s]->[%s]' %
                        (m.input, m.output))

            else:
                raise Exception('Invalid marking without place [%s]->[%s]' %
                                (m.input, m.output))
        elif len(place) > 1:
            raise Exception(
                'Multiple candidates marking inconclusive [%s]->[%s]' %
                (m.input, m.output))
        else:
            place[0].marking = True
예제 #4
0
def apply_loop_places(model):
    #extract all loop fragments
    loop_fragment_begin_array = []

    for p in model.elements:
        if type(p) is t.TreeLoopFragmentBegin:
            loop_fragment_begin_array += [p]

    #remove all loop fragments from the main array
    for p in loop_fragment_begin_array:
        model.elements.remove(p)
        model.elements.remove(p.ref_end)

    #For all begin loop places, if there exist child place remove it and assign all its children to loop place
    for p in loop_fragment_begin_array:
        for c in p.children:
            if type(c) is t.TreePlace:
                p.children += c.children
                p.children.remove(c)
                model.elements.remove(c)

    #For all end loop places, if there exist a parent place remove it and assign its parents to the loop place
    for p in loop_fragment_begin_array:
        p_parents = util.get_parents(model, p.ref_end)

        for c in p_parents:
            if type(c) is t.TreePlace:
                for cp in util.get_parents(model, c):
                    cp.children.remove(c)
                    cp.children += [p.ref_end]

                model.elements.remove(c)

    #start processing loop places
    for meta_lp in model.meta.loop_place:
        #throw exception of still false at the end of nested loop
        applied = False

        for lpb in loop_fragment_begin_array:
            #check if possible duplicate was already satisfied
            duplicate = False
            for dupl in lpb.satisfied:
                if util.loop_place_equiv(dupl, meta_lp) == True:
                    duplicate = True

            if duplicate == False:
                #Obtain candidate transitions lists
                end_array = lpb.children
                begin_array = util.get_parents(model, lpb.ref_end)

                #check if current loop place contains required transitions
                end_match = util.have_all(end_array, meta_lp.output)
                begin_match = util.have_all(begin_array, meta_lp.input)

                if begin_match == True and end_match == True:
                    #Create loop place
                    lp = t.TreePlace()
                    lp.name = util.gen_place_label(model)

                    #inherit parents of the loop begin place(if any)
                    for p in util.get_parents(model, lpb):
                        p.children += [lp]

                    #assign postset
                    for e in end_array:
                        if e.name in meta_lp.output:
                            lp.children += [e]

                    #assign preset
                    for b in begin_array:
                        if b.name in meta_lp.input:
                            b.children += [lp]

                    #insert into main array
                    model.elements += [lp]

                    #assign loop place to satisfied list
                    lpb.satisfied += [meta_lp]
                    applied = True
                    break

        #exception of not applied!!!
        if applied == False:
            raise Exception('Missing place for [%s]->[%s]' %
                            (meta_lp.input, meta_lp.output))

    #remove any references to loop places
    for e in model.elements:
        for lpb in loop_fragment_begin_array:
            if lpb in e.children:
                e.children.remove(lpb)

            if lpb.ref_end in e.children:
                e.children.remove(lpb.ref_end)
예제 #5
0
def parse_segment(model, head, tail, src):
    #process series of tokens in a segment

    i = 0
    last = len(src)

    #Default segment
    seg = SegmentSequential()

    while (i < last):
        #iterate through every token

        elem = src[i]
        token = syntax.decode_token(elem)

        if token == syntax.Token.SQR_BR_R or token == syntax.Token.PAR_R:
            #unexpected closing bracket without opening bracket
            raise Exception(
                'Unexpected closing bracket %s without opening bracket' % elem)
        elif token == syntax.Token.LOOP:
            #loop token detected

            #extract internal sorurce
            block_src = util.extract_block_subarray(i, src)
            tree_fragment = t.TreeFragment()
            tree_fragment.src = block_src[1]
            model.elements += [tree_fragment]

            #create loop fragment
            loop_fragment_end = t.TreeLoopFragmentEnd()
            loop_fragment_begin = t.TreeLoopFragmentBegin()
            loop_fragment_begin.children += [tree_fragment]
            loop_fragment_begin.ref_end = loop_fragment_end
            tree_fragment.children += [loop_fragment_end]
            model.elements += [loop_fragment_begin, loop_fragment_end]

            if seg.head:
                #something is already in segment
                #uncommon potentially modeling initialization
                #followed by infinite loop
                seg.tail.children += [loop_fragment_begin]
                seg.tail = loop_fragment_end
            else:
                seg.head = loop_fragment_begin
                seg.tail = loop_fragment_end

            i = block_src[0]

        elif token == syntax.Token.SQR_BR_L or token == syntax.Token.PAR_L:
            #opening bracket detected
            #extract source fragment until matching closing bracket
            #and place as source fragment

            block_src = util.extract_block_subarray(i, src)

            tree_fragment = t.TreeFragment()
            tree_fragment.src = block_src[1]
            model.elements += [tree_fragment]

            if seg.head:
                seg.tail.children += [tree_fragment]
                seg.tail = tree_fragment
            else:
                seg.head = tree_fragment
                seg.tail = tree_fragment

            i = block_src[0]

        elif token == syntax.Token.CONFUSION or token == syntax.Token.CONFUSION_ARB:
            #confusion token encountered

            if type(seg) is not SegmentSequential and type(
                    seg) is not SegmentConfusion:
                raise Exception('Unexpected current segment type %s' %
                                type(seg))

            #transform existing sequential path to confusion block
            #and start new path for further tokens
            if type(seg) is SegmentSequential:
                tmp = SegmentConfusion()
                tmp.transfer(seg)
                seg = tmp
            seg.next_path()

            i = i + 1
        elif token == syntax.Token.SEQ or token == syntax.Token.ACT:
            # sequential (;) or (->)
            #add place to the path

            place = t.TreePlace()
            place.name = util.gen_place_label(model)
            model.elements += [place]

            if seg.head:
                seg.tail.children += [place]
                seg.tail = place
            else:
                seg.head = place
                seg.tail = place

            i = i + 1
        elif token == syntax.Token.EPL:
            # (=>) token
            #do nothing

            i = i + 1
        elif token == syntax.Token.PARALLEL:
            #parallel token

            if type(seg) is not SegmentSequential and type(
                    seg) is not SegmentParallel:
                raise Exception('Unexpected current segment type %s' %
                                type(seg))

            #transform existing sequential path to parallel block (if applicable)
            #and start new path for further tokens
            if type(seg) is SegmentSequential:
                tmp = SegmentParallel()
                tmp.transfer(seg)
                seg = tmp
            seg.next_path()

            i = i + 1

        elif token == syntax.Token.SEP:
            #Create a source fragment without any parent child connections
            #Absorb the remainder of tokens for the new fragment
            i = i + 1

            block_src = []

            while (i < last):
                block_src += [src[i]]
                i = i + 1

            tree_fragment = t.TreeFragment()
            tree_fragment.src = block_src
            model.elements += [tree_fragment]

        elif token == syntax.Token.UNKNOWN:
            #other type of token

            #WARNING: this version does not do the sanity check!!!
            if util.is_explicit_place(model, elem):
                #1 test for explicit place token
                #if place then either detached or no tail
                #no tail if sequential not empty or parallel
                #OBSOLETE: assuming correct syntax meaning no a+; P0; b+ but parallel allowed

                #find if there is already an explicit place present
                place = util.get_place(model, elem)
                if place == None:
                    #if no create one
                    place = t.TreePlace()
                    place.name = elem
                    model.elements += [place]

                #look one before and one after element if there is -> operator
                #if present then attach a place without modifying regular flow

                #NOTE: Limitation, only transition allowed after and before -> operator
                #otherwise thrown an exception
                pre_arrow_present = False
                post_arrow_present = False
                inflow_present = False

                if i > 0:
                    prev = src[i - 1]
                    prev_token = syntax.decode_token(prev)
                    if prev_token == syntax.Token.EPL:
                        pre_arrow_present = True

                if i < (last - 1):
                    nxt = src[i + 1]
                    nxt_token = syntax.decode_token(nxt)
                    if nxt_token == syntax.Token.EPL:
                        post_arrow_present = True

                if pre_arrow_present == True:
                    #add created place as a child of preceding transition

                    if type(seg.tail) is not t.TreeTransition:
                        raise Exception(
                            'Syntax error, preceding element must be a transition'
                        )

                    seg.tail.children += [place]

                if post_arrow_present == True:
                    #get element past the arrow, verify that is is a transition and add both
                    # the explicit place and the transition
                    nxt = src[i + 2]

                    if util.is_transition(model, nxt) == False:
                        raise Exception(
                            'Syntax error, following element must be a transition'
                        )

                    #process transition
                    tran = t.TreeTransition()
                    tran.name = nxt
                    model.elements += [tran]

                    if seg.head:
                        seg.tail.children += [tran]
                        seg.tail = tran
                    else:
                        seg.head = tran
                        seg.tail = tran

                    place.children += [tran]
                elif pre_arrow_present == False:
                    inflow_present = True

                    if seg.head:
                        seg.tail.children += [place]
                        seg.tail = place
                    else:
                        seg.head = place
                        seg.tail = place

                if pre_arrow_present == True or inflow_present == True:
                    i = i + 1
                else:
                    #must be post
                    i = i + 3

            elif util.is_transition(model, elem):
                #2 test for transition
                tran = t.TreeTransition()
                tran.name = elem
                model.elements += [tran]

                if seg.head:
                    seg.tail.children += [tran]
                    seg.tail = tran
                else:
                    seg.head = tran
                    seg.tail = tran

                i = i + 1
            elif util.is_fragment(model, elem):
                #3 test for source fragment
                frag = t.TreeFragment()
                frag.label = elem
                model.elements += [frag]

                if seg.head:
                    seg.tail.children += [frag]
                    seg.tail = frag
                else:
                    seg.head = frag
                    seg.tail = frag

                i = i + 1
            else:
                raise Exception('Unknown token %s' % elem)
        else:
            raise Exception('DEBUG POINT 0')

    #Obtain final heads and tails
    seg.out(model, head, tail)

    return SegmentParseStatus.DEFAULT