def handleContext(ctxt): global dom dom = ctxt cdecls = ctxt.getElementsByTagName("CONSTANTDECLARATION") defs = dict() j = 0 for i in cdecls: uStr = HSalXMLPP.getNameTag(i, "IDENTIFIER") uTypeXML = HSalXMLPP.getArg(i, 3) if (uTypeXML.localName != 'TYPENAME') | (HSalXMLPP.valueOf(uTypeXML) != 'REAL'): continue fuXML = HSalXMLPP.getArg(i, 4) if fuXML == None: # No value; e.g., the case x: REAL; continue # get all NAMEEXPR in fuXML; replace by f(nameexpr) fuXML = replaceNameexprsNumerals(defs, fuXML) # Now evaluate the expression and check if it is a constant. # print(polyrep.expr2poly(varValueInXML)) fuPolyrep = polyrep.expr2poly(fuXML) if polyrep.isConstant(fuPolyrep): value = polyrep.getConstant(fuPolyrep) defs[uStr] = format(value, '.4f') # ASHISH: CHECK LATER print((uStr + ' = ' + format(value, '.4f'))) # ASHISH: CHECK LATER else: j = j + 1 # print(fuXML.toxml()) # print(fuPolyrep) # print("ERROR: Preprocessor can't eliminate constant decls") # return ctxt # print("Found " + str(j) + "constant decls that are not constants") # get all NAMEEXPR in the document; see if their textvalue == above; replace ctxt = replaceNameexprsNumerals(defs, ctxt) return ctxt
def HSalPPSimpleDefn(node): lhsVar = HSalXMLPP.HSalPPExpr(HSalXMLPP.getArg(node,1)) rhsexpr = node.getElementsByTagName("RHSEXPRESSION") if not(rhsexpr.length == 0): try: rhsVal = float(HSalXMLPP.HSalPPExprs(rhsexpr[0].childNodes)) return (lhsVar, rhsVal) except: print("init expr rhs is not a number") else: print("init expr not of the form lhs = rhs") return
def main(): global dom filename = sys.argv[1] if not (os.path.isfile(filename)): print("File does not exist. Quitting.") return 1 basename, ext = os.path.splitext(filename) if ext == '.hxml': xmlfilename = filename elif ext == '.hsal': xmlfilename = basename + ".hxml" subprocess.call( ["hybridsal2xml/hybridsal2xml", "-o", xmlfilename, filename]) if not (os.path.isfile(xmlfilename)): print("hybridsal2xml failed to create XML file. Quitting.") return 1 else: print("Unknown file extension; Expecting .hsal or .hxml; Quitting") return 1 dom = xml.dom.minidom.parse(xmlfilename) newctxt = handleContext(dom) moveIfExists(xmlfilename) with open(xmlfilename, "w") as fp: print(newctxt.toxml(), file=fp) print(("Created file %s containing the preprocessed model (XML)" % xmlfilename)) filename = basename + ".hsal.preprocessed" moveIfExists(filename) with open(filename, "w") as fp: HSalXMLPP.HSalPPContext(newctxt, fp) print(("Created file %s containing the preprocessed model (HSal)" % filename)) return 0
def main(): global dom filename = sys.argv[1] if not(os.path.isfile(filename)): print("File does not exist. Quitting.") return 1 basename,ext = os.path.splitext(filename) if ext == '.hxml': xmlfilename = filename elif ext == '.hsal': xmlfilename = basename + ".hxml" subprocess.call(["hybridsal2xml/hybridsal2xml", "-o", xmlfilename, filename]) if not(os.path.isfile(xmlfilename)): print("hybridsal2xml failed to create XML file. Quitting.") return 1 else: print("Unknown file extension; Expecting .hsal; Quitting") return 1 dom = xml.dom.minidom.parse(xmlfilename) setDom(dom) absTransitions = calcAbs() relAbsToXml(absTransitions) newCtxt = dom xmlFile = basename+".xml" with open(xmlFile, "w") as fp: print(newCtxt.toxml(), file=fp) absSalFile = basename+".sal" print("Abstraction saved as a SAL file::" + absSalFile) with open(absSalFile, "w") as fp: HSalXMLPP.HSalPPContext(newCtxt, fp)
def HSalPPDecls(nodes): k = 0 l=[] for j in nodes: if (j.localName == "VARDECL"): l.append(HSalXMLPP.getName(j)) return l
def handleGuardedCommand(gc): guard = gc.getElementsByTagName("GUARD")[0] assigns = gc.getElementsByTagName("ASSIGNMENTS")[0] defs = assigns.getElementsByTagName("SIMPLEDEFINITION") flow = HSalRelAbsCons.getFlow(defs) [varlist, A, b] = HSalRelAbsCons.flow2Ab(flow) # print "A" # print A # print "b" # print b guard = HSalXMLPP.getArg(guard, 1) return (guard, varlist, A, b)
def xml_fmla_2_dnf_fmla(fmla): assert fmla != None and ( isinstance(fmla, list) or fmla.nodeType == fmla.ELEMENT_NODE), 'Error: expecting ELEMENT node' if isinstance(fmla, list): polyllL = [xml_fmla_2_dnf_fmla(i) for i in fmla] ans = DNF.true() for i in polyllL: ans = applyBOp('AND', ans, i) return ans elif fmla.localName == 'NAMEEXPR': bcst = HSalXMLPP.valueOf(fmla).strip() assert bcst in ['TRUE', 'FALSE'], 'Error: Boolean constant is not TRUE/FALSE?' return DNF.false() if bcst == "FALSE" else DNF.true() elif fmla.localName == 'APPLICATION': if fmla.getAttribute('INFIX') == 'YES': op = HSalXMLPP.valueOf(HSalXMLPP.getArg(fmla, 1)).strip() if op in ['AND', 'OR']: fmla1 = xml_fmla_2_dnf_fmla(HSalXMLPP.appArg(fmla, 1)) fmla2 = xml_fmla_2_dnf_fmla(HSalXMLPP.appArg(fmla, 2)) return applyBOp(op, fmla1, fmla2) elif op in ['<', '<=', '>', '>=', '=']: fmla1 = polyrep.expr2poly(HSalXMLPP.appArg(fmla, 1), ignoreNext=True) fmla2 = polyrep.expr2poly(HSalXMLPP.appArg(fmla, 2), ignoreNext=True) return applyArithOp(op, fmla1, fmla2) else: assert False, 'Error: Unknown op {0} in formula'.format(op) else: op = HSalXMLPP.valueOf(HSalXMLPP.getArg(fmla, 1)).strip() assert op in ['NOT' ], 'Error: Unhandled bool connective {0}'.format(op) fmla1 = xml_fmla_2_dnf_fmla(HSalXMLPP.appArg(fmla, 1)) fmla1.neg() return fmla1 else: assert False, 'Error: Unknown tag {0} in formula'.format( fmla.localName)
def replaceNameexprsNumerals(ufu, xmlnode): """Replace all nameexprs in xmlnode by their numeral value from ufu""" if xmlnode.localName == 'NAMEEXPR': nameexprs = [xmlnode] else: nameexprs = xmlnode.getElementsByTagName("NAMEEXPR") # print("Found so many NAMEEXPRSs to possibly replace") # print(len(nameexprs)) for j in nameexprs: v = HSalXMLPP.valueOf(j) if v in ufu: fv = ufu[v] fvXML = createNodeTag("NUMERAL", fv) # replace j by fvXML jParent = j.parentNode jParent.replaceChild(fvXML, j) if j == xmlnode: xmlnode = fvXML return xmlnode
def expr2poly(node, ignoreNext=False): # print(node.localName) if (node == None) or not (node.nodeType == node.ELEMENT_NODE): return list() if node.localName == "NAMEEXPR": return nameExpr2poly(node) elif node.localName == "APPLICATION": return app2poly(node) elif node.localName == "NUMERAL": return numeral2poly(node) elif node.localName == "NEXTOPERATOR": if ignoreNext: return expr2poly(HSalXMLPP.getArg(node, 1), ignoreNext) else: return nextOperator2poly(node) elif node.localName == "SETPREDEXPRESSION": return setPredExpr2poly(node) else: print((node.toxml())) print('Type of expr unknown? Missing code') return None
def simpledef2fmlalist(node): "node is XML node for SIMPLEDEFINITION, return list of formula XML-nodes" lhs = HSalXMLPP.getArg(node, 1) rhs = HSalXMLPP.getArg(node, 2) assert lhs.tagName == 'NAMEEXPR', 'ERROR: Unidentified tagName {0} for LHS in simpledefinition'.format( lhs.tagName) if rhs.tagName == 'RHSEXPRESSION': rhsVal = HSalXMLPP.getArg(rhs, 1) return [createNodeInfixApp('=', lhs, rhsVal)] elif rhs.tagName == 'RHSSELECTION': rhsVal = HSalXMLPP.getArg(rhs, 1) assert rhsVal.tagName == 'SETPREDEXPRESSION', 'ERROR: Unidentified tagName {0}'.format( rhsVal.tagName) dummyvar = HSalXMLPP.getNameTag(rhsVal, 'IDENTIFIER').strip() lhsvar = HSalXMLPP.valueOf(lhs).strip() rhsfmla = HSalXMLPP.getArg(rhsVal, 3) # replace dummyvar by lhsvar in rhsfmla allnames = rhsfmla.getElementsByTagName('NAMEEXPR') for i in allnames: if HSalXMLPP.valueOf(i).strip() == dummyvar: i.firstChild.data = lhsvar return [rhsfmla] else: assert False, 'ERROR: Unreachable code'
def prop2modpropExpr(ctxt, prop): "create and output the shared data-structure" # first, find the assertiondecl for prop in ctxt # get list of all assertiondeclarations in ctxt modulemodels = None adecls = ctxt.getElementsByTagName("ASSERTIONDECLARATION") assert len( adecls) > 0, 'ERROR: Property {0} not found in input HSal file'.format( prop) for i in adecls: propName = HSalXMLPP.getNameTag(i, 'IDENTIFIER') if propName == prop: modulemodels = HSalXMLPP.getArg(i, 3) break assert modulemodels != None, 'ERROR: Property {0} not found in input HSal file'.format( prop) # second, extract modulename and property expression modulename = None try: modulename = HSalXMLPP.getNameTag(modulemodels, 'MODULENAME') except IndexError: print('ERROR: Expecting MODULENAME inside property {0}'.format(prop)) sys.exit(1) propExpr = HSalXMLPP.getArg(modulemodels, 2) assert propExpr != None, 'ERROR: Failed to find property expression' # Now, I have modulename and propExpr # Next, find module modulename from the list of ALL basemodules... moddecl = None moddecls = ctxt.getElementsByTagName("MODULEDECLARATION") for i in moddecls: tmp = HSalXMLPP.getArg(i, 1) assert tmp != None, 'ERROR: Module declaration has no NAME ??' identifier = HSalXMLPP.valueOf(tmp).strip() if identifier == modulename: moddecl = i break assert moddecl != None, 'ERROR: Module {0}, referenced in property {1}, not found'.format( modulename, prop) # Now, I have moddecl and propExpr basemod = HSalXMLPP.getArg(moddecl, 3) assert basemod != None, 'ERROR: Module {0} is not a base module'.format( modulename) # Now I have basemod and propExpr; check if propExpr is G( inv ) assert propExpr.tagName == 'APPLICATION', 'ERROR: Property must be of the form G(inv)' functionName = HSalXMLPP.valueOf(HSalXMLPP.getArg(propExpr, 1)).strip() assert functionName == 'G', 'ERROR: Property must be of the form G(inv)' invExpr = HSalXMLPP.getArg(HSalXMLPP.getArg(propExpr, 2), 1) return (basemod, invExpr)
def interpretSALXML(): global dom ###################### AUX functions ################## def getModeData(gc, varTypeDict): "Return a new guarded command that is a rel abs of input GC" #Separate the type var lists initVarDict = varTypeDict['inits'] #Assumes each guard-transition represent a mode guard = gc.getElementsByTagName("GUARD")[0] clonedGuard = guard.cloneNode(True) assigns = gc.getElementsByTagName("ASSIGNMENTS")[0] defs = assigns.getElementsByTagName("SIMPLEDEFINITION") #Assuming that all the flows have been recieved in one call flow = getFlow(defs) [varlist,A,b] = flow2Ab(flow, varTypeDict) #Check if all plant variables are initialised if len(varlist) != len(initVarDict): print("error:no. of plant variables dont match the no. of initial values\n") exit(0) matA = scipy.mat(A) matBT = scipy.mat(b) matB = matBT.getT() return (clonedGuard,varlist,matA,matB) ####################################################### ctxt = dom ctxtName = HSalXMLPP.getName(ctxt) global globalPD globalPD['context'] = ctxtName print("\n############################################") print("Context: %s" % ctxtName) ctxtBody = (ctxt.getElementsByTagName("CONTEXTBODY")[0]) modules = ctxtBody.getElementsByTagName("MODULEDECLARATION") if len(modules) > 1: print("FATAL: more than 1 module:(%d) found\n" %len(modules)) exit(0) # for module in modules: module = modules[0] moduleName = HSalXMLPP.getName(module) globalPD['module'] = moduleName print("Module: %s" % moduleName) print("############################################\n") moduleChildNodes = module.childNodes for node in moduleChildNodes: if node.localName == 'BASEMODULE': varTypeDict = HSalPPBaseModule(node) gc = ctxtBody.getElementsByTagName("GUARDEDCOMMAND") if len(gc) > 1: print("each transition will be interpreted as a HA mode\n") elif len(gc) < 1: print("error:less than one transition\n") else: i = 0 modeDataList = [] #each gc represents a mode for mode in gc: #What exactly does it check? only the first assignment??!! if isCont(mode): #return (varlist,matA,matB,t) modeDataList.append(getModeData(mode, varTypeDict)) else: print("error: no flow found in a mode\n") exit(0) plantName = moduleName t = getT(plantName) return (modeDataList,varTypeDict,t)