diff --git a/shared/python/metrics.py b/shared/python/metrics.py index 332bfd9f..97245f46 100755 --- a/shared/python/metrics.py +++ b/shared/python/metrics.py @@ -134,20 +134,21 @@ def getADigraph(g): return adg def getLevels(g): - calls = getCallGraph(g) - calls = getClosure(calls) + return calculateLevels(getClosure(getCallGraph(g))) + +# +def calculateLevels(calls): unassigned = calls.keys() levels = [] while len(unassigned)>0: - nt = unassigned[0] + nt = unassigned[0] + unassigned = unassigned[1:] levels.append([]) levels[-1].append(nt) - unassigned = unassigned[1:] for n in calls[nt]: - if nt in calls[n]: + if (nt in calls[n]) and (n not in levels[-1]) and (n in unassigned): levels[-1].append(n) - if n in unassigned: - unassigned.remove(n) + unassigned.remove(n) return levels def getCallGraph(g): @@ -166,11 +167,13 @@ def getCallGraph(g): return calls def getClosure(cg): - calls = cg.copy() + # simple copy doesn't work because of the inner arrays + #calls = cg.copy() + calls = {} + for x in cg.keys(): + calls[x]=cg[x][:] for n in calls.keys(): for x in calls[n]: - if x not in calls.keys(): - calls[x] = [] for y in calls[x]: if y not in calls[n]: calls[n].append(y) @@ -180,6 +183,18 @@ def getClosure(cg): #print '--------------------' return calls +# +def makeOneStep(cg): + calls = cg.copy() + for n in cg.keys(): + for x in cg[n]: + calls[n] = union(calls[n],cg[x]) + calls[n].sort() + #for n in calls.keys(): + # print n,'▻*',calls[n] + #print '--------------------' + return calls + # DEP - cardinality of the largest grammatical level def DEP(g): return max(map(len,getLevels(g))) @@ -221,16 +236,25 @@ def HEI(g): # TIMP - tree impurity def TIMP(g): - cg = getClosure(getCallGraph(g)) + return impurityOfCallGraph(getClosure(getCallGraph(g))) + +# TIMP - tree impurity of the immediate successor graph +def TIMPI(g): + return impurityOfCallGraph(getCallGraph(g)) + +def impurityOfCallGraph(cg): n = len(cg) e = sum(map(len,cg.values())) - # Power and Malloy made two mistakes: - # (1) the number of edges in a complete directed graph is n(n-1), not n(n-1)/2, as in a complete undirected graph! - # (2) we don't have to substract another 1 from the number of nonterminals to account for a start symbol - # To compute TIMP exactly as they intended to, run this: - # return (100*2*(e-n+1)/(0.0+(n-1)*(n-2))) - # To run our fixed version, uncomment this: - return (100*(e-n+1)/(0.0+n*(n-1))) + if n<2: + return 100 + else: + # Power and Malloy made two mistakes: + # (1) the number of edges in a complete directed graph is n(n-1), not n(n-1)/2, as in a complete undirected graph! + # (2) we don't have to substract another 1 from the number of nonterminals to account for a start symbol + # To compute TIMP exactly as they intended to, run this: + # return (100*2*(e-n+1)/(0.0+(n-1)*(n-2))) + # To run our fixed version, uncomment this: + return (100*(e-n+1)/(0.0+n*(n-1))) ###################################################################### ########## Complexity metrics ########## @@ -291,6 +315,9 @@ def rhssize(node): def AVS(g): return sum(map(rhssize,g.prods))/(0.0+VAR(g)) +def AVSp(g): + return sum(map(rhssize,g.prods))/(0.0+PROD(g)) + # HAL - Halstead effort def opr(node): # number of occurrences of operators @@ -418,3 +445,50 @@ def HADIF(g): def HAEFF(g): hal = HADIF(g)*HAVOL(g) return hal + +# HALEV - Halstead level +def HALEV(g): + mu1 = hal_mu1(g) + mu2 = hal_mu2(g) + eta1 = hal_eta1(g) + eta2 = hal_eta2(g) + hal = (2.0*mu2)/(mu1*eta2) + return hal + +# HATIM - Halstead time +def HATIM(g): + return HAEFF(g)/18.0 + +###################################################################### +# Experiments +def shortestPath(a,b,cg): + return shortestPathAllPars(a,b,cg,getClosure(cg),[]) + +def shortestPathAllPars(a,b,cg,ccg,visited): + visited.append(a) + if a == b: + #print '∆:',a,'is',b + return 0 + if b in cg[a]: + #print '∆:',a,'is next to',b + return 1 + if b not in ccg[a]: + #print '∆:',a,'is inaccessible from',b + return 1000000 + if not cg[a]: + #print '∆:',a,'is inaccessible from',b + return 1000000 + #print '∆:',a,'-->?' + goto = filter(lambda x:x not in visited,cg[a]) + if not goto: + #print '∆:',a,'is inaccessible from',b + return 1000000 + return 1 + min(map(lambda x:shortestPathAllPars(x,b,cg,ccg,visited),goto)) + +def nameLevel(level,roots,g): + return '/'.join(union([],map(lambda x:nameLevel1Root(level,x,getCallGraph(g)),roots)))+'('+str(len(level))+')' + +def nameLevel1Root(level,root,cg): + deltas = map(lambda x:shortestPath(root,x,cg),level) + #d = min(deltas): + return '|'.join(map(lambda i:level[i],filter(lambda i:deltas[i]==min(deltas),range(0,len(level))))) diff --git a/topics/investigation/structural/tests/antlr.bgf.baseline b/topics/investigation/structural/tests/antlr.bgf.baseline index 3a5419dc..ef3087b9 100644 --- a/topics/investigation/structural/tests/antlr.bgf.baseline +++ b/topics/investigation/structural/tests/antlr.bgf.baseline @@ -1,4 +1,4 @@ -6 +5 7 63.6 1 diff --git a/topics/investigation/structural/tests/dcg.bgf.baseline b/topics/investigation/structural/tests/dcg.bgf.baseline index 4a4e4161..7b3fa80f 100644 --- a/topics/investigation/structural/tests/dcg.bgf.baseline +++ b/topics/investigation/structural/tests/dcg.bgf.baseline @@ -1,4 +1,4 @@ -3 +2 7 87.5 1 diff --git a/topics/investigation/structural/tests/ecore.bgf.baseline b/topics/investigation/structural/tests/ecore.bgf.baseline index 9905bda5..44689025 100644 --- a/topics/investigation/structural/tests/ecore.bgf.baseline +++ b/topics/investigation/structural/tests/ecore.bgf.baseline @@ -1,4 +1,4 @@ -9 +8 5 41.7 1 diff --git a/topics/investigation/structural/tests/ecore2.bgf.baseline b/topics/investigation/structural/tests/ecore2.bgf.baseline index 1c6a9bd6..f7914c5f 100644 --- a/topics/investigation/structural/tests/ecore2.bgf.baseline +++ b/topics/investigation/structural/tests/ecore2.bgf.baseline @@ -1,4 +1,4 @@ -5 +4 6 66.7 1 diff --git a/topics/investigation/structural/tests/impl1.bgf.baseline b/topics/investigation/structural/tests/impl1.bgf.baseline index fe98c589..b4d74c60 100644 --- a/topics/investigation/structural/tests/impl1.bgf.baseline +++ b/topics/investigation/structural/tests/impl1.bgf.baseline @@ -1,7 +1,7 @@ -34 +33 83 58.5 20 -20 +4 22 37.7 diff --git a/topics/investigation/structural/tests/impl2.bgf.baseline b/topics/investigation/structural/tests/impl2.bgf.baseline index ad85fb2b..f5eb20c1 100644 --- a/topics/investigation/structural/tests/impl2.bgf.baseline +++ b/topics/investigation/structural/tests/impl2.bgf.baseline @@ -1,4 +1,4 @@ -52 +51 41 45.1 1 diff --git a/topics/investigation/structural/tests/impl3.bgf.baseline b/topics/investigation/structural/tests/impl3.bgf.baseline index edf91f49..cd4aeff4 100644 --- a/topics/investigation/structural/tests/impl3.bgf.baseline +++ b/topics/investigation/structural/tests/impl3.bgf.baseline @@ -1,4 +1,4 @@ -91 +90 35 27.8 2 diff --git a/topics/investigation/structural/tests/jaxb.bgf.baseline b/topics/investigation/structural/tests/jaxb.bgf.baseline index d904fb2b..b117644c 100644 --- a/topics/investigation/structural/tests/jaxb.bgf.baseline +++ b/topics/investigation/structural/tests/jaxb.bgf.baseline @@ -1,4 +1,4 @@ -4 +3 9 81.8 1 diff --git a/topics/investigation/structural/tests/om.bgf.baseline b/topics/investigation/structural/tests/om.bgf.baseline index eff90d80..4a8faa32 100644 --- a/topics/investigation/structural/tests/om.bgf.baseline +++ b/topics/investigation/structural/tests/om.bgf.baseline @@ -1,4 +1,4 @@ -4 +3 8 80.0 1 diff --git a/topics/investigation/structural/tests/read1.bgf.baseline b/topics/investigation/structural/tests/read1.bgf.baseline index bc34b5d0..42b61091 100644 --- a/topics/investigation/structural/tests/read1.bgf.baseline +++ b/topics/investigation/structural/tests/read1.bgf.baseline @@ -1,7 +1,7 @@ -34 +33 97 61.8 26 -26 +4 22 31.9 diff --git a/topics/investigation/structural/tests/read2.bgf.baseline b/topics/investigation/structural/tests/read2.bgf.baseline index 33182319..175fa812 100644 --- a/topics/investigation/structural/tests/read2.bgf.baseline +++ b/topics/investigation/structural/tests/read2.bgf.baseline @@ -1,7 +1,7 @@ -94 +93 68 42.0 21 -21 +2 13 56.8 diff --git a/topics/investigation/structural/tests/read3.bgf.baseline b/topics/investigation/structural/tests/read3.bgf.baseline index 5e4a7a3f..b3057969 100644 --- a/topics/investigation/structural/tests/read3.bgf.baseline +++ b/topics/investigation/structural/tests/read3.bgf.baseline @@ -1,7 +1,7 @@ -124 +123 75 35.5 19 -19 +3 14 58.7 diff --git a/topics/investigation/structural/tests/sdf.bgf.baseline b/topics/investigation/structural/tests/sdf.bgf.baseline index e099cc90..21ec4664 100644 --- a/topics/investigation/structural/tests/sdf.bgf.baseline +++ b/topics/investigation/structural/tests/sdf.bgf.baseline @@ -1,7 +1,7 @@ -2 +1 7 100.0 1 -1 +0 3 21.4 diff --git a/topics/investigation/structural/tests/txl.bgf.baseline b/topics/investigation/structural/tests/txl.bgf.baseline index e099cc90..21ec4664 100644 --- a/topics/investigation/structural/tests/txl.bgf.baseline +++ b/topics/investigation/structural/tests/txl.bgf.baseline @@ -1,7 +1,7 @@ -2 +1 7 100.0 1 -1 +0 3 21.4 diff --git a/topics/investigation/structural/tests/xml.bgf.baseline b/topics/investigation/structural/tests/xml.bgf.baseline index f7067cba..fb88f1f9 100644 --- a/topics/investigation/structural/tests/xml.bgf.baseline +++ b/topics/investigation/structural/tests/xml.bgf.baseline @@ -1,4 +1,4 @@ -5 +4 7 70.0 1 diff --git a/topics/investigation/structural/tests/xsd.bgf.baseline b/topics/investigation/structural/tests/xsd.bgf.baseline index f7067cba..fb88f1f9 100644 --- a/topics/investigation/structural/tests/xsd.bgf.baseline +++ b/topics/investigation/structural/tests/xsd.bgf.baseline @@ -1,4 +1,4 @@ -5 +4 7 70.0 1