mainFeatures.py

#Graph representation module
from Himesis.Graph                   import Graph
from Himesis.Node                    import Node

#Primitive types
from Himesis.Int                     import Int
from Himesis.String                  import String
from Himesis.Float                   import Float
from Himesis.Bool                    import Bool

#To import/export to XML
from Himesis.GraphUtils.AGLLoader    import AGLLoader
from Himesis.GraphUtils.AGLGenerator import AGLGenerator

#To match graphs
from Himesis.GraphUtils.Match        import Match

import os

#In linux , to pretty print this file to .ps
#aliased to enscript  -G2rjE --color -o !*.ps !*; gv !*.ps
# to html: enscript -Whtml -Epython --color mainFeatures.py -o mainFeatures.html

#Instantiating a graph g = Graph(ID="", label="", parent=None)
#all arguments are facultative.

root = Graph(ID="Root", label="PrimitiveElementsGraph")

print "Root ID: ", root.getName()
print "Root label: ", root.getLabel()
print "Root parent: ", root.getParent()

#All elements have the same interface
# Node(ID="", label="", parent=None)
# Int(ID="", label="", parent=None, value=None)

# e.g.
i1 = Int(ID="i1", label="Int", value=55)

print "Int i1 ID: ", i1.getName()
print "Int i1 label: ", i1.getLabel()
print "Int i1 parent: ", i1.getParent()
print "Int i1 value: ", i1.getValue()

#setting value, simply:
i1.setValue(456)

#Adding elements to a graph:
# graph[path] = element
# A path is a string of the form ID1.ID2.ID3 navigating down
# the hierarchy of graphs. The final ID (ID3 in our example)
# it the actual name of the added element. The added element
# will be renamed..
          
root["i3"] = i1 #this will rename i1 to i3
root["i2"] = Int(label="Int", value=102)

#getting elements by name

print "Int i3 (previously i1) ", root["i3"]
print "Int i2", root["i2"]

#each element has a unique, global id, which is a path from the root
print "i3 unique ID: ", root["i3"].getGlobalId()

#getting elements by label
#getElements(labels=[listofwantedlabels])

print "Elements with label Int: \n", root.getElements(labels=["Int"])

#adding elements with other labels
root["f1"] = Float(label="Float", value=4.56)
root["f2"] = Float(label="Float", value=55.6)

print "Elements with label Int and Float: \n", root.getElements(labels=["Int", "Float"])

#cloning a graph. simply g.clone()

internalGraph = root.clone()

#comparing the graphs (structural equality, IDs are ignored in the process)
#(labels are used to compare elements)
print "Graphs should be equals: ", internalGraph.equals(root)

#adding the graph to root..
root["internalGraph"]=internalGraph

#Graphs aren't equal anymore
print "Graphs should not be equals: ", root["internalGraph"].equals(root)

#adding a string to root
root["s1"] = String(label="String", value=99.9)

#iterating over the elements of the first level:
print "Iterating over the first level"
for elem in root: #or root.iterate()
  print elem.getGlobalId()

print "Iterating over all elements (default traversal is Depth First)"
for elem in root.iterateAll():
  print elem.getGlobalId()

print "Iterating over all elements (Breath First)"
for elem in root.iterateAll(traversal="BreathFirst"):
  print elem.getGlobalId()

#connecting stuff
root.connect("i3", "i2")
root.connect("i3", "f1")
root.connect("f1", "s1")

#accross level, using the path syntax..
root.connect("i3", "internalGraph.f2")
 
#iterating over connections..
print "iterating over i3 out connections"
for outC in root["i3"].outC():
  print outC.getGlobalId()

print "iterating over s1 in connections"
for inC in root["s1"].inC():
  print inC.getGlobalId()

# to get a list of connections
outList = root["i3"].getOutC()
inList  = root["i3"].getInC()

# to get the degree..
print "i3 out degree: ", root["i3"].getOutDegree()
print "i3 in degree: ", root["i3"].getInDegree()

#disconnecting..
root.disconnect("i3", "internalGraph.f2")

#creating a graph to match..
#the matching algorithm will, by default, match nodes with corresponding labels.
#note that it *will* match through hierarchies..

#In order to match, first create a match objects, which implements the
#matching algorithms:

# m = Match(subgraph, host)
# This object will try to match subgraph in host and returns, for now,
# a list of lists [match1, match2, ...] of tuples
# [ [(subgraph.element, host.element), ..], ...]
  
#For now, two functions are provided, subgraphIso and subgraphHomo,
#for inductive and non-inductive matches. Those two functions run the same
#algorithm solving a constraint satisfaction problem with different rules to prune the search tree.
#and a different check to verify if the current extension is legal
#Ullman's test is used while solving subgraph isomorphism.

subgraph = Graph(ID="subgraph", label="PrimitiveElementsGraph")
subgraph["oneInt"] = Int(label="Int", value=444)
subgraph["twoInt"] = Int(label="Int", value=444)
subgraph.connect("oneInt", "twoInt")

#creating the match object..
m = Match(subgraph, root)
print "Finding one match: \n", m.subgraphIso()

print "connecting elements deeper in the hierarchy.."
root["internalGraph"].connect("i2", "i3")

print "Finding two matches: \n", m.subgraphIso()

#Graph can also be exported to a simple xml (agl, for a graph language).
#One file will be generated for each graph in the exported graph, connections
#are stored in the lowest common parent. Generating xml is quite simple.

#Create a generator object, implementing the algorithm:
#it takes a graph and a directory as an argument
#you can also specify indendation size (default is two space)
#if you want unzipped agl, you must also specify it (it generates zipped stuff by default)
print "generating files in the current directory"
gen = AGLGenerator(root, directory="", indentSize="  ", unzip=True)
gen.genCode()

#Similarly, to load, create a loader specifying the search path
loader = AGLLoader(directory="")

#then, you can load the graphs *independently* !
loadedRoot = loader.load("Root")

print "Comparing loaded graphs: "
print loadedRoot.equals(root)

#Unique ID should be specified
loadedInternal = loader.load("Root.internalGraph")

print "Comparing loaded internal graphs:"
print loadedInternal.equals(root.remove("internalGraph"))




Generated by GNU enscript 1.6.1.