aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation
diff options
context:
space:
mode:
authorLibravatar OszkarSemerath <oszka@SEMERATH-LAPTOP>2017-07-12 15:40:33 +0200
committerLibravatar OszkarSemerath <oszka@SEMERATH-LAPTOP>2017-07-12 15:40:33 +0200
commitb4927437a3487ecc61c48d1351d18b7a38c5b154 (patch)
tree3f1e6c25c50a71efb0de6131b0d94c5163759dcc /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation
parentRearranged the solver configuration into different subsections (diff)
downloadVIATRA-Generator-b4927437a3487ecc61c48d1351d18b7a38c5b154.tar.gz
VIATRA-Generator-b4927437a3487ecc61c48d1351d18b7a38c5b154.tar.zst
VIATRA-Generator-b4927437a3487ecc61c48d1351d18b7a38c5b154.zip
Graphviz based visualisation for the concretizations of partial models.
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend239
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/Test.xtend24
2 files changed, 263 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend
new file mode 100644
index 00000000..a4baeadb
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend
@@ -0,0 +1,239 @@
1package hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz
2
3import guru.nidi.graphviz.attribute.Arrow
4import guru.nidi.graphviz.attribute.Color
5import guru.nidi.graphviz.attribute.Shape
6import guru.nidi.graphviz.attribute.Style
7import guru.nidi.graphviz.engine.Format
8import guru.nidi.graphviz.engine.Graphviz
9import guru.nidi.graphviz.model.Graph
10import guru.nidi.graphviz.model.Label
11import guru.nidi.graphviz.model.Node
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
13import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
14import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
15import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser
20import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
21import java.io.File
22import java.util.HashMap
23import java.util.HashSet
24import java.util.LinkedList
25import java.util.Random
26import java.util.Set
27
28import static guru.nidi.graphviz.model.Factory.*
29import static guru.nidi.graphviz.attribute.Records.*;
30
31import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
32import guru.nidi.graphviz.engine.Engine
33import guru.nidi.graphviz.attribute.Records
34import guru.nidi.graphviz.attribute.Attributes
35import java.util.List
36
37class GraphvizVisualisation implements PartialInterpretationVisualiser {
38
39 val TypeColoringStyle typeColoringStyle = TypeColoringStyle::AVERAGE;
40 val smallFontSize=9
41 val keywords = #{"class","reference","literal","enum"}
42
43 override visualiseConcretization(PartialInterpretation partialInterpretation) {
44 visualisePartialInterpretation(partialInterpretation,true)
45 }
46
47 override visualisePartialSolution(PartialInterpretation partialInterpretation) {
48 visualisePartialInterpretation(partialInterpretation,false)
49 }
50
51 def private visualisePartialInterpretation(PartialInterpretation partialInterpretation, boolean concretizationOnly) {
52 val problem = partialInterpretation.problem
53
54 // Elements of the partial solutions
55 val oldElements = problem.elements
56 val newElements = partialInterpretation.newElements
57 //val prototypeElements = #[partialInterpretation.openWorldElementPrototype]
58 val allElements = problem.elements + partialInterpretation.newElements
59
60 // Indexing types
61 val mustTypes = new HashMap<DefinedElement,Set<Type>>
62 val mayTypes = new HashMap<DefinedElement,Set<Type>>
63 for(element : allElements) {
64 mustTypes.put(element,new HashSet)
65 mayTypes.put(element,new HashSet)
66 }
67 for(typeDefinition: problem.types.filter(TypeDefinition)) {
68 for(element : typeDefinition.elements) {
69 mustTypes.get(element)+=typeDefinition
70 }
71 }
72 for(partialTypeInterpretations: partialInterpretation.partialtypeinterpratation) {
73 for(element : partialTypeInterpretations.elements) {
74 mustTypes.get(element)+=partialTypeInterpretations.interpretationOf
75 }
76 }
77
78 // Indexing references
79
80 // Drawing the nodes
81 val elements2Node = new HashMap
82 val elements2ID = new HashMap
83 for(oldElemenetIndex : 0..<oldElements.size) {
84 val oldElement = oldElements.get(oldElemenetIndex)
85 val id = '''o «oldElemenetIndex»'''
86 val image = drawElement(oldElement,id,true,oldElement.lookup(mustTypes),emptySet)
87 elements2ID.put(oldElement, id)
88 elements2Node.put(oldElement, image)
89 }
90 for(newElementIndex: 0..<newElements.size) {
91 val newElement = newElements.get(newElementIndex)
92 val id = '''n «newElementIndex»'''
93 val image = drawElement(newElement,id,false,newElement.lookup(mustTypes),emptySet)
94 elements2ID.put(newElement,id)
95 elements2Node.put(newElement,image)
96 }
97 // Prototype elements
98
99 // Drawing the edges
100 val edges = new HashMap
101 for(element : elements2Node.values) {
102 edges.put(element,new LinkedList)
103 }
104 for(relationInterpretation : partialInterpretation.partialrelationinterpretation) {
105 val type = relationInterpretation.interpretationOf
106 val isContainment = problem.containmentHierarchies.exists[it.containmentRelations.contains(type)]
107 for(link : relationInterpretation.relationlinks.filter(BinaryElementRelationLink)) {
108 val sourceNode = link.param1.lookup(elements2Node)
109 val targetNode = link.param2.lookup(elements2Node)
110
111 val edge = drawEdge(link,type,targetNode,isContainment)
112 sourceNode.lookup(edges).add(edge)
113 }
114 }
115
116 val graph = graph("PartialInterpretation").directed.with(
117 edges.entrySet.map[entry | entry.key.link(entry.value)]
118 )
119
120 return new GraphvisVisualisation(graph)
121 }
122
123 def protected drawElement(DefinedElement element, String ID, boolean old, Set<Type> mustTypes, Set<Type> mayTypes) {
124 var tableStyle = ''' CELLSPACING="0" BORDER="2" CELLBORDER="0" CELLPADDING="1" STYLE="ROUNDED"'''
125 if(typeColoringStyle==TypeColoringStyle::AVERAGE) {
126 tableStyle += ''' BGCOLOR="#«typePredicateColor(mustTypes).toBackgroundColorString»"'''
127 }
128 val mainLabel = if(element.name !== null) {
129 val parts = element.name.split("\\s+")
130 textWithSubSup(parts.getOrNull(0),parts.getOrNull(1),parts.getOrNull(2),null)
131 } else {
132 val parts = ID.split("\\s+")
133 textWithSubSup(parts.get(0),parts.get(1),parts.getOrNull(2),null)
134 }
135 val label = Label.html(
136 '''<TABLE«tableStyle»>'''+
137 '''<TR><TD COLSPAN="2" BORDER="2" SIDES="B">«mainLabel»</TD></TR>'''+
138 '''«FOR mustTypeName : mustTypes.map[it.name].sort»«typePredicateDescription(mustTypeName,true)»«ENDFOR»'''+
139 '''«FOR mayTypeName : mayTypes.map[it.name].sort»«typePredicateDescription(mayTypeName,false)»«ENDFOR»'''+
140 '''</TABLE>''')
141
142 val node = node(ID).with(label).with(
143 Shape.NONE,
144 Attributes.attr("margin","0")
145 )
146 return node
147 }
148
149 protected def drawEdge(BinaryElementRelationLink link, Relation relation, Node to, boolean isContainemnt) {
150 val nameSegments = relation.name.split("\\s+")
151 var l = to(to).with(Label.html(textWithSubSup(nameSegments.getOrNull(0),nameSegments.getOrNull(1),nameSegments.getOrNull(2),null)))
152 if(isContainemnt) {
153 l = l.with(Style.BOLD)
154 }
155 return l
156 }
157
158 private def <T> getOrNull(List<T> list, int index) {
159 if(list.size>index) return list.get(index)
160 else return null
161 }
162
163 def private textWithSubSup(String text, String sub, String sup, String after) {
164 val actualText = text
165 val actualSub = if(sub===null) {" "} else {sub.checkAndHighlightKeyword}
166 val actualSup = if(sup==null) {" "} else {sup.checkAndHighlightKeyword}
167 val actualAfter = if(after === null) {""} else {
168 '''<TD ROWSPAN="2" ALIGN="LEFT">«after»</TD>'''
169 }
170 return
171 '''<FONT FACE="helvetica"><Table CELLSPACING="0" BORDER="0" CELLBORDER="0" CELLPADDING="0">'''+
172 '''<TR><TD ROWSPAN="2" ALIGN="RIGHT">«actualText»</TD><TD ALIGN="LEFT" VALIGN="BOTTOM"><FONT POINT-SIZE="«smallFontSize»">«actualSup»</FONT></TD>«actualAfter»</TR>'''+
173 '''<TR><TD ALIGN="LEFT" VALIGN="TOP"><FONT POINT-SIZE="«smallFontSize»">«actualSub»</FONT></TD></TR>'''+
174 '''</Table></FONT>'''
175 }
176 def checkAndHighlightKeyword(String word) {
177 if(keywords.contains(word)) {
178 return '''<B>«word»</B>'''
179 } else {
180 word
181 }
182 }
183 def typePredicateDescription(String typeName, boolean must)
184 {
185 val value = if(must){'''1'''} else{'''½'''}
186 val backgroundColor = if(this.typeColoringStyle == TypeColoringStyle.FLAG) {
187 ''' BGCOLOR="#«typeName.typePredicateColor.toBackgroundColorString»"'''
188 } else {
189 ""
190 }
191 val typeNameSegments = typeName.split("\\s+")
192 return '''<TR><TD«backgroundColor»>«textWithSubSup(typeNameSegments.getOrNull(0),typeNameSegments.getOrNull(1),typeNameSegments.getOrNull(2),null)»</TD><TD«backgroundColor»> = «value» </TD></TR>'''
193 }
194 def toBackgroundColorString(List<Integer> backgroundColor) {
195 '''«Integer.toHexString(backgroundColor.get(0))»«Integer.toHexString(backgroundColor.get(1))»«Integer.toHexString(backgroundColor.get(2))»'''
196 }
197 protected def typePredicateColor(Set<Type> types) { types.averageColor }
198 protected def typePredicateColor(String name) {
199 val Random random = new Random(name.hashCode+1)
200 val rangePicker = [|random.nextInt(128)+128]
201 return #[rangePicker.apply(), rangePicker.apply(), rangePicker.apply()]
202 }
203 private def averageColor(Set<Type> types) {
204 if(types.empty) {
205 return #[256,256,256]
206 } else {
207 val typeColors = types.filter[!it.isIsAbstract].map[typePredicateColor(it.name)]
208 return #[
209 typeColors.map[get(0)].average,
210 typeColors.map[get(1)].average,
211 typeColors.map[get(2)].average
212 ]
213 }
214 }
215 private def average(Iterable<Integer> doubles) { return doubles.reduce[p1, p2|p1+p2]/doubles.size }
216
217
218
219
220}
221
222enum TypeColoringStyle {
223 FLAG, AVERAGE
224}
225
226class GraphvisVisualisation implements PartialInterpretationVisualisation {
227 val private Graph graph
228
229 public new(Graph graph) {
230 this.graph = graph
231 }
232
233 override writeToFile(ReasonerWorkspace workspace, String name) {
234 val path = '''«workspace.workspaceURI.toFileString»/«name».png'''
235 Graphviz.fromGraph(graph)//.engine(Engine::NEATO)
236 .render(Format.PNG).toFile(new File(path));
237 }
238
239}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/Test.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/Test.xtend
new file mode 100644
index 00000000..75187c26
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/Test.xtend
@@ -0,0 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
5import hu.bme.mit.inf.dslreasoner.workspace.FileSystemWorkspace
6import org.eclipse.emf.ecore.resource.Resource
7import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
8
9class Test {
10 def static void main(String[] args) {
11 val workspace = new FileSystemWorkspace("input/","")
12
13 PartialinterpretationPackage.eINSTANCE.eClass
14 Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("*",new XMIResourceFactoryImpl)
15
16 val model = workspace.readModel(PartialInterpretation,"solution1.partialinterpretation")
17 println("loaded")
18 val translator = new GraphvizVisualisation
19 val visualisation = translator.visualiseConcretization(model)
20 println("visualised")
21 visualisation.writeToFile(workspace,"output")
22 println("saved")
23 }
24} \ No newline at end of file