Ver código fonte

added a getAttrNames() function for model transformations, fixed workflow

Simon Van Mierlo 8 anos atrás
pai
commit
ac3c263e70

+ 3 - 3
exported_to_sccdxml/run_train.py

@@ -133,9 +133,9 @@ class SimulationGUI(Tk):
             self.light_change_events.append((self.counter + random.random() * 500 + 300, item, turn_green))
         
         if self.train is not None:
-            self.train.speed += self.train.acceleration / 2
-            self.label_speed.config(text="Speed: %.2f" % self.train.speed)
-            self.travelled_x += float(self.train.speed) / 20
+            self.train.velocity += self.train.acceleration / 2
+            self.label_speed.config(text="Speed: %.2f" % self.train.velocity)
+            self.travelled_x += float(self.train.velocity) / 20
             delta_x = -int(self.travelled_x - self.travelled_x_int)
             self.travelled_x_int = int(self.travelled_x)
             # Move rails

+ 290 - 273
mt/ptcal/dapi.py

@@ -23,296 +23,313 @@ from pytcore.core.himesis import HConstants as HC
 from utils import Utilities as utils
 
 '''
-	implements the DesignerAPI functions used in pattern/attribute constraints 
-	and actions
-
-	NOTE: the current username is required (and remembered) to enable file I/O
-  			within his own directory... the current backend aswid is required (and
-			remembered) to enable httpreqs to backend from rule code
-
-	NOTE: cloned from mmmk.js constraint/action/accessor DesignerAPI... same
-  			comments and thoughts apply... noteworthy differences are 
-				. instead of atompm ids, API functions now take __pLabels as node
-			  	  identifiers
-				. 'sys_*()' functions enable system calls and file i/o
-				. 'session_*()' functions provide a clean and efficient way to 
-				  remember information across rules
-				. the 'isConnectionType()' function '''
-class DesignerAPI :	
-	def __init__(self,username,aswid,mtwid) :
-		self._username = username
-		self._aswid		= aswid
-		self._mtwid		= mtwid
-		
-	def _aswPrintReq(self,msg):
-		utils.httpReq(	'PUT', 
-						'127.0.0.1:8124', 
-						'/GET/console?wid='+self._aswid, 
-						{'text':msg})
-	
-	def _printToDevCon(self,msg):
-		self._aswPrintReq(msg)
-
-
-	'''
-		configure this instance of DesignerAPI
-
-		1. set the Himesis graph that will be used to satisfy getAttr/setAttr/...
-			function calls... this graph represents a (partially) matched LHS, NAC
-			or RHS 
-		2. set the type of the calling function... legal values are 
-				patternCondition
-				patternAction
-				attrCondition
-				attrAction
-		3. set the pattern-label -> graph-index mapping 
-		4. set reference to exception holder
-		5. set the __pLabel of the owner of the calling function, if any
-		6. set the attribute that owns the calling function, if any 
-		7. set reference to journal (to write changes to), if any 
-		8. extend the pattern-label -> graph-index map w/ $atompmId -> graph-index
-			mappings... this enables access to all graph nodes (not just matched 
-			ones, that are incidently the only ones w/ associated __pLabels) 
-		
-		TBI: self._pl2gi should be given a name that reflects step 8. and errors
-			  pertaining to missing/incorrect pLabel parameters should be updated 
-			  to account for fact that specified pLabels may not be pLabels (i.e.,
-			  they could be of the form '$atompmId:*' '''
-	def configure(self,graph,type,pl2gi,ex,pLabel=None,attr=None,journal=None) :
-		self._graph 	= graph
-		self._type	 	= type
-		self._pl2gi		= pl2gi
-		self._ex			= ex
-		self._pLabel 	= pLabel
-		self._attr	   = attr
-		self._journal 	= journal
-
-		matched = self._pl2gi.values()
-		for v in self._graph.vs :
-			if v.index not in matched :
-				self._pl2gi['$atompmId:'+str(v['$atompmId'])] = v.index
-			
-			
-	'''
-		wrapper around raise()... to be properly reported to the client, 
-		exceptions can not simply be raised... this would just cause them to be
-	  	captured by their ExecutionContext who might return a generic error (not
-		the one it caught)... instead, we store exceptions, if any, in self._ex 
-		for the caller to do with them what he wants... '''
-	def __raise(self,msg) :
-		self._ex['$err'] = msg
-		raise RuntimeError(msg)
-
-
-
-	# ***************************** API functions ***************************** #
-	def _getAttr(self,attr=None,pLabel=None) :
-		if pLabel == None :
-			if self._type.startswith('pattern') :
-				self.__raise(\
-					'getAttr() requires a __pLabel in pattern conditions/actions')
-			pLabel = self._pLabel
-		elif not self._type.startswith('pattern') :
-			self.__raise(\
-				'getAttr() only accepts a __pLabel in pattern conditions/actions')
-		elif pLabel not in self._pl2gi :
-			self.__raise(\
-				'invalid getAttr() __pLabel :: '+str(pLabel)+' (either no node '+\
-				'with that __pLabel exists, or none is matched yet)')
-		if attr == None :
-			if not self._type.startswith('attr') :
-				self.__raise(\
-					'getAttr() can only be called without parameters'+\
-					'in attribute conditions/actions')
-			attr = self._attr
-
-		n = self._graph.vs[self._pl2gi[pLabel]]
-		if attr not in n.attribute_names() :
-			self.__raise('invalid getAttr() attribute :: '+str(attr))
-		return copy.deepcopy(n[attr])
-	
-
-
-	def _hasAttr(self,attr=None,pLabel=None) :
-		if pLabel == None :
-			if self._type.startswith('pattern') :
-				self.__raise(\
-					'hasAttr() requires a __pLabel in pattern conditions/actions')
-			pLabel = self._pLabel
-		elif not self._type.startswith('pattern') :
-			self.__raise(\
-				'hasAttr() only accepts a __pLabel in pattern conditions/actions')
-		elif pLabel not in self._pl2gi :
-			self.__raise(\
-				'invalid hasAttr() __pLabel :: '+str(pLabel)+' (either no node '+\
-				'with that __pLabel exists, or none is matched yet)')
-		if attr == None :
-			self.__raise(\
-				'hasAttr() can not be called without an attribute parameter')
-
-		n = self._graph.vs[self._pl2gi[pLabel]]
-		return attr in n.attribute_names()
-
-
-
-	def _setAttr(self,attr,val,pLabel) :
-		if self._type != 'patternAction' :
-			self.__raise('setAttr() can only be used within RHS actions')
-		elif pLabel == None :
-			self.__raise('setAttr() requires a valid __pLabel')
-		elif pLabel not in self._pl2gi :
-			self.__raise(\
-				'invalid setAttr() __pLabel :: '+str(pLabel)+' (either no node '+\
-				'with that __pLabel exists, or none is matched yet)')
-
-		n = self._graph.vs[self._pl2gi[pLabel]]
-		if attr not in n.attribute_names() :
-			self.__raise('invalid setAttr() attribute :: '+attr)
-		oldVal = n[attr]
-		if oldVal != val :
-			n[attr] = val
-			self._journal.append(
-								{'op':'CHATTR',
-			  					 'guid':n[HC.GUID],
-								 'attr':attr,
-								 'old_val':oldVal,
-								 'new_val':val})
-			n[HC.MT_DIRTY] = True
-
-
-
-	def _getAllNodes(self,fulltypes=None) :
-		if not self._type.startswith('pattern') :
-			self.__raise(\
-				'getAllNodes() can only be used in pattern conditions/actions')
-		elif fulltypes != None and fulltypes.__class__ != [].__class__ :
-			self.__raise('invalid getAllNodes() fulltypes array :: '+fulltypes)
-
-		pLabels = []
-		for pLabel in self._pl2gi :
-			n = self._graph.vs[self._pl2gi[pLabel]]
-			if fulltypes == None or n[HC.FULLTYPE] in fulltypes :
-				pLabels.append(pLabel)
-		return pLabels
-
-
-
-	def _getNeighbors(self,dir,type,pLabel) :
-		if not self._type.startswith('pattern') :
-			self.__raise(\
-				'getNeighbors() can only be used in pattern conditions/actions')
-		elif pLabel == None :
-			self.__raise('getNeighbors() requires a valid __pLabel')
-		elif pLabel not in self._pl2gi :
-			self.__raise(\
-				'invalid getNeighbors() __pLabel :: '+str(pLabel)+' (no node '+\
-				'with that __pLabel exists)')
-
-		pLabels = set()
-		if len(self._graph.es) > 0 :
-			gi2pl = dict((v, k) for (k, v) in self._pl2gi.items())
-			idx   = self._pl2gi[pLabel]
-			for e in self._graph.get_edgelist() :
-				if e[0] == idx and \
-					(dir == '>' or dir == '*' or dir == "out") and \
-					(type == '*' or self._graph.vs[e[1]][HC.FULLTYPE] == type) :
-					pLabels.add(gi2pl[e[1]])
-				elif e[1] == idx and \
-					  (dir == '<' or dir == '*' or dir == "in") and \
-					  (type == '*' or self._graph.vs[e[0]][HC.FULLTYPE] == type) :
-					pLabels.add(gi2pl[e[0]])
-		return list(pLabels)
-
-
-
-	def _isConnectionType(self,pLabel) :
-		if not self._type.startswith('pattern') :
-			self.__raise(\
-				'isConnectionType() can only be used in pattern conditions/actions')
-		elif pLabel == None :
-			self.__raise('isConnectionType() requires a valid __pLabel')
-		elif pLabel not in self._pl2gi :
-			self.__raise(\
-				'invalid isConnectionType() __pLabel :: '+str(pLabel)+' (no node '+\
-				'with that __pLabel exists)')
-
-		return self._graph.vs[self._pl2gi[pLabel]][HC.CONNECTOR_TYPE]
-
-
-
-
-	def _session_get(self,key) :
-		if key in self._graph.session :
-			return self._graph.session[key]
+    implements the DesignerAPI functions used in pattern/attribute constraints 
+    and actions
+
+    NOTE: the current username is required (and remembered) to enable file I/O
+              within his own directory... the current backend aswid is required (and
+            remembered) to enable httpreqs to backend from rule code
+
+    NOTE: cloned from mmmk.js constraint/action/accessor DesignerAPI... same
+              comments and thoughts apply... noteworthy differences are 
+                . instead of atompm ids, API functions now take __pLabels as node
+                    identifiers
+                . 'sys_*()' functions enable system calls and file i/o
+                . 'session_*()' functions provide a clean and efficient way to 
+                  remember information across rules
+                . the 'isConnectionType()' function '''
+class DesignerAPI :    
+    def __init__(self,username,aswid,mtwid) :
+        self._username = username
+        self._aswid        = aswid
+        self._mtwid        = mtwid
+        
+    def _aswPrintReq(self,msg):
+        utils.httpReq(    'PUT', 
+                        '127.0.0.1:8124', 
+                        '/GET/console?wid='+self._aswid, 
+                        {'text':msg})
+    
+    def _printToDevCon(self,msg):
+        self._aswPrintReq(msg)
+
+
+    '''
+        configure this instance of DesignerAPI
+
+        1. set the Himesis graph that will be used to satisfy getAttr/setAttr/...
+            function calls... this graph represents a (partially) matched LHS, NAC
+            or RHS 
+        2. set the type of the calling function... legal values are 
+                patternCondition
+                patternAction
+                attrCondition
+                attrAction
+        3. set the pattern-label -> graph-index mapping 
+        4. set reference to exception holder
+        5. set the __pLabel of the owner of the calling function, if any
+        6. set the attribute that owns the calling function, if any 
+        7. set reference to journal (to write changes to), if any 
+        8. extend the pattern-label -> graph-index map w/ $atompmId -> graph-index
+            mappings... this enables access to all graph nodes (not just matched 
+            ones, that are incidently the only ones w/ associated __pLabels) 
+        
+        TBI: self._pl2gi should be given a name that reflects step 8. and errors
+              pertaining to missing/incorrect pLabel parameters should be updated 
+              to account for fact that specified pLabels may not be pLabels (i.e.,
+              they could be of the form '$atompmId:*' '''
+    def configure(self,graph,type,pl2gi,ex,pLabel=None,attr=None,journal=None) :
+        self._graph     = graph
+        self._type         = type
+        self._pl2gi        = pl2gi
+        self._ex            = ex
+        self._pLabel     = pLabel
+        self._attr       = attr
+        self._journal     = journal
+
+        matched = self._pl2gi.values()
+        for v in self._graph.vs :
+            if v.index not in matched :
+                self._pl2gi['$atompmId:'+str(v['$atompmId'])] = v.index
+            
+            
+    '''
+        wrapper around raise()... to be properly reported to the client, 
+        exceptions can not simply be raised... this would just cause them to be
+          captured by their ExecutionContext who might return a generic error (not
+        the one it caught)... instead, we store exceptions, if any, in self._ex 
+        for the caller to do with them what he wants... '''
+    def __raise(self,msg) :
+        self._ex['$err'] = msg
+        raise RuntimeError(msg)
+
+
+
+    # ***************************** API functions ***************************** #
+    def _getAttr(self,attr=None,pLabel=None) :
+        if pLabel == None :
+            if self._type.startswith('pattern') :
+                self.__raise(\
+                    'getAttr() requires a __pLabel in pattern conditions/actions')
+            pLabel = self._pLabel
+        elif not self._type.startswith('pattern') :
+            self.__raise(\
+                'getAttr() only accepts a __pLabel in pattern conditions/actions')
+        elif pLabel not in self._pl2gi :
+            self.__raise(\
+                'invalid getAttr() __pLabel :: '+str(pLabel)+' (either no node '+\
+                'with that __pLabel exists, or none is matched yet)')
+        if attr == None :
+            if not self._type.startswith('attr') :
+                self.__raise(\
+                    'getAttr() can only be called without parameters'+\
+                    'in attribute conditions/actions')
+            attr = self._attr
+
+        n = self._graph.vs[self._pl2gi[pLabel]]
+        if attr not in n.attribute_names() :
+            self.__raise('invalid getAttr() attribute :: '+str(attr))
+        return copy.deepcopy(n[attr])
+    
+    
+    def _getAttrNames(self,pLabel=None):
+        if pLabel == None :
+            if self._type.startswith('pattern') :
+                self.__raise(\
+                    'getAttrNames() requires a __pLabel in pattern conditions/actions')
+            pLabel = self._pLabel        
+        elif not self._type.startswith('pattern') :
+            self.__raise(\
+                'getAttrNames() only accepts a __pLabel in pattern conditions/actions')
+        elif pLabel not in self._pl2gi :
+            self.__raise(\
+                'invalid getAttr() __pLabel :: '+str(pLabel)+' (either no node '+\
+                'with that __pLabel exists, or none is matched yet)')
+
+        n = self._graph.vs[self._pl2gi[pLabel]]
+        return n.attribute_names()
+
+
+    def _hasAttr(self,attr=None,pLabel=None) :
+        if pLabel == None :
+            if self._type.startswith('pattern') :
+                self.__raise(\
+                    'hasAttr() requires a __pLabel in pattern conditions/actions')
+            pLabel = self._pLabel
+        elif not self._type.startswith('pattern') :
+            self.__raise(\
+                'hasAttr() only accepts a __pLabel in pattern conditions/actions')
+        elif pLabel not in self._pl2gi :
+            self.__raise(\
+                'invalid hasAttr() __pLabel :: '+str(pLabel)+' (either no node '+\
+                'with that __pLabel exists, or none is matched yet)')
+        if attr == None :
+            self.__raise(\
+                'hasAttr() can not be called without an attribute parameter')
+
+        n = self._graph.vs[self._pl2gi[pLabel]]
+        return attr in n.attribute_names()
+
+
+
+    def _setAttr(self,attr,val,pLabel) :
+        if self._type != 'patternAction' :
+            self.__raise('setAttr() can only be used within RHS actions')
+        elif pLabel == None :
+            self.__raise('setAttr() requires a valid __pLabel')
+        elif pLabel not in self._pl2gi :
+            self.__raise(\
+                'invalid setAttr() __pLabel :: '+str(pLabel)+' (either no node '+\
+                'with that __pLabel exists, or none is matched yet)')
+
+        n = self._graph.vs[self._pl2gi[pLabel]]
+        if attr not in n.attribute_names() :
+            self.__raise('invalid setAttr() attribute :: '+attr)
+        oldVal = n[attr]
+        if oldVal != val :
+            n[attr] = val
+            self._journal.append(
+                                {'op':'CHATTR',
+                                   'guid':n[HC.GUID],
+                                 'attr':attr,
+                                 'old_val':oldVal,
+                                 'new_val':val})
+            n[HC.MT_DIRTY] = True
+
+
+
+    def _getAllNodes(self,fulltypes=None) :
+        if not self._type.startswith('pattern') :
+            self.__raise(\
+                'getAllNodes() can only be used in pattern conditions/actions')
+        elif fulltypes != None and fulltypes.__class__ != [].__class__ :
+            self.__raise('invalid getAllNodes() fulltypes array :: '+fulltypes)
+
+        pLabels = []
+        for pLabel in self._pl2gi :
+            n = self._graph.vs[self._pl2gi[pLabel]]
+            if fulltypes == None or n[HC.FULLTYPE] in fulltypes :
+                pLabels.append(pLabel)
+        return pLabels
+
+
+
+    def _getNeighbors(self,dir,type,pLabel) :
+        if not self._type.startswith('pattern') :
+            self.__raise(\
+                'getNeighbors() can only be used in pattern conditions/actions')
+        elif pLabel == None :
+            self.__raise('getNeighbors() requires a valid __pLabel')
+        elif pLabel not in self._pl2gi :
+            self.__raise(\
+                'invalid getNeighbors() __pLabel :: '+str(pLabel)+' (no node '+\
+                'with that __pLabel exists)')
+
+        pLabels = set()
+        if len(self._graph.es) > 0 :
+            gi2pl = dict((v, k) for (k, v) in self._pl2gi.items())
+            idx   = self._pl2gi[pLabel]
+            for e in self._graph.get_edgelist() :
+                if e[0] == idx and \
+                    (dir == '>' or dir == '*' or dir == "out") and \
+                    (type == '*' or self._graph.vs[e[1]][HC.FULLTYPE] == type) :
+                    pLabels.add(gi2pl[e[1]])
+                elif e[1] == idx and \
+                      (dir == '<' or dir == '*' or dir == "in") and \
+                      (type == '*' or self._graph.vs[e[0]][HC.FULLTYPE] == type) :
+                    pLabels.add(gi2pl[e[0]])
+        return list(pLabels)
+
+
+
+    def _isConnectionType(self,pLabel) :
+        if not self._type.startswith('pattern') :
+            self.__raise(\
+                'isConnectionType() can only be used in pattern conditions/actions')
+        elif pLabel == None :
+            self.__raise('isConnectionType() requires a valid __pLabel')
+        elif pLabel not in self._pl2gi :
+            self.__raise(\
+                'invalid isConnectionType() __pLabel :: '+str(pLabel)+' (no node '+\
+                'with that __pLabel exists)')
+
+        return self._graph.vs[self._pl2gi[pLabel]][HC.CONNECTOR_TYPE]
+
+
+
+
+    def _session_get(self,key) :
+        if key in self._graph.session :
+            return self._graph.session[key]
 
 
 
-	def _session_put(self,key,val) :
-		if not self._type.endswith('Action') :
-			self.__raise(\
-				'session_put() can only be used in attribute and pattern actions')
+    def _session_put(self,key,val) :
+        if not self._type.endswith('Action') :
+            self.__raise(\
+                'session_put() can only be used in attribute and pattern actions')
 
-		self._graph.session[key] = val
-		return val
-
-
-	def _pauseTransformation(self):
-		self._httpReq("PUT", '127.0.0.1:8125', '/execmode?wid='+self._mtwid, {'mode':'pause'})
-		
-	def _stopTransformation(self):
-		self._httpReq("PUT", '127.0.0.1:8125', '/execmode?wid='+self._mtwid, {'mode':'stop'})
-		
-	def _resumeTransformation(self):
-		self._httpReq("PUT", '127.0.0.1:8125', '/execmode?wid='+self._mtwid, {'mode':'play'})
+        self._graph.session[key] = val
+        return val
+
+
+    def _pauseTransformation(self):
+        self._httpReq("PUT", '127.0.0.1:8125', '/execmode?wid='+self._mtwid, {'mode':'pause'})
+        
+    def _stopTransformation(self):
+        self._httpReq("PUT", '127.0.0.1:8125', '/execmode?wid='+self._mtwid, {'mode':'stop'})
+        
+    def _resumeTransformation(self):
+        self._httpReq("PUT", '127.0.0.1:8125', '/execmode?wid='+self._mtwid, {'mode':'play'})
 
-	def _httpReq(self,method,host,uri,data) :
-		if host == None :
-			return utils.httpReq(
-						method,
-						'127.0.0.1:8124',
-						uri+'?wid='+self._aswid,
-						data)
-		else : 
-			return utils.httpReq(method,host,uri,data)
+    def _httpReq(self,method,host,uri,data) :
+        if host == None :
+            return utils.httpReq(
+                        method,
+                        '127.0.0.1:8124',
+                        uri+'?wid='+self._aswid,
+                        data)
+        else : 
+            return utils.httpReq(method,host,uri,data)
 
-		
+        
 
-	def _print(self,str) :
-		print(str)
+    def _print(self,str) :
+        print(str)
 
 
 
-	def _sys_call(self,args) :
-		try :
-			return subprocess.call(args)
-		except OSError as ex : 
-			self.__raise('system call crashed on :: '+ex.strerror)
+    def _sys_call(self,args) :
+        try :
+            return subprocess.call(args)
+        except OSError as ex : 
+            self.__raise('system call crashed on :: '+ex.strerror)
 
 
 
-	def _sys_mkdir(self,path) :
-		try :
-			return os.makedirs('./users/'+self._username+'/'+path)
-		except OSError as ex : 
-			if ex.errno != 17 :
-				#ignore directory already exists error
-				self.__raise('directory creation failed :: '+ex.strerror)
+    def _sys_mkdir(self,path) :
+        try :
+            return os.makedirs('./users/'+self._username+'/'+path)
+        except OSError as ex : 
+            if ex.errno != 17 :
+                #ignore directory already exists error
+                self.__raise('directory creation failed :: '+ex.strerror)
 
 
 
-	def _sys_readf(self,path) :
-		f = open('./users/'+self._username+'/'+path,'r')
-		contents = f.read()
-		f.close()
-		return contents
+    def _sys_readf(self,path) :
+        f = open('./users/'+self._username+'/'+path,'r')
+        contents = f.read()
+        f.close()
+        return contents
 
 
 
-	def _sys_writef(self,path,content,append=True) :
-		if append :
-			f = open('./users/'+self._username+'/'+path,'a')
-		else :
-			f = open('./users/'+self._username+'/'+path,'w')
-		f.write(content)
-		f.close()
+    def _sys_writef(self,path,content,append=True) :
+        if append :
+            f = open('./users/'+self._username+'/'+path,'a')
+        else :
+            f = open('./users/'+self._username+'/'+path,'w')
+        f.write(content)
+        f.close()
 

+ 1 - 0
mt/ptcal/dcal.py

@@ -125,6 +125,7 @@ class PythonExecutionContext :
 		self._context = \
 			{'getAttr' 				: dAPI._getAttr,
 			 'hasAttr'				: dAPI._hasAttr,
+			 'getAttrNames'		    : dAPI._getAttrNames,
 		 	 'setAttr' 				: dAPI._setAttr,
 			 'getAllNodes' 			: dAPI._getAllNodes,
 			 'getNeighbors' 		: dAPI._getNeighbors,

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
users/(default)/Formalisms/Workflows/simulate/R_LoadRTParams.model