diff options
Diffstat (limited to 'Solvers/VIATRA-Solver')
6 files changed, 55 insertions, 33 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ScopePropagator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ScopePropagator.xtend index 38633c07..df38337e 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ScopePropagator.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ScopePropagator.xtend | |||
@@ -63,9 +63,12 @@ class ScopePropagator { | |||
63 | def public propagateAdditionToType(PartialTypeInterpratation t) { | 63 | def public propagateAdditionToType(PartialTypeInterpratation t) { |
64 | // println('''Adding to «(t as PartialComplexTypeInterpretation).interpretationOf.name»''') | 64 | // println('''Adding to «(t as PartialComplexTypeInterpretation).interpretationOf.name»''') |
65 | val targetScope = type2Scope.get(t) | 65 | val targetScope = type2Scope.get(t) |
66 | targetScope.removeOne | 66 | if(targetScope!==null) { |
67 | val sups = superScopes.get(targetScope) | 67 | targetScope.removeOne |
68 | sups.forEach[removeOne] | 68 | val sups = superScopes.get(targetScope) |
69 | sups.forEach[removeOne] | ||
70 | } | ||
71 | |||
69 | if(this.partialInterpretation.minNewElements > 0) { | 72 | if(this.partialInterpretation.minNewElements > 0) { |
70 | this.partialInterpretation.minNewElements = this.partialInterpretation.minNewElements-1 | 73 | this.partialInterpretation.minNewElements = this.partialInterpretation.minNewElements-1 |
71 | } | 74 | } |
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend index 608ab994..5ca78e97 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend | |||
@@ -143,7 +143,13 @@ class PConstraintTransformer { | |||
143 | return referPattern(pcall.referredQuery,params,modality,true,true) | 143 | return referPattern(pcall.referredQuery,params,modality,true,true) |
144 | } | 144 | } |
145 | dispatch def transformConstraint(ExportedParameter e, Modality modality, List<VariableMapping> variableMapping) { | 145 | dispatch def transformConstraint(ExportedParameter e, Modality modality, List<VariableMapping> variableMapping) { |
146 | return '''// «e.parameterName» is exported''' | 146 | val v1 = '''var_«e.parameterName»''' |
147 | val v2 = e.parameterVariable.canonizeName | ||
148 | if(v1.compareTo(v2) == 0) { | ||
149 | return '''// «v1» exported''' | ||
150 | } else { | ||
151 | return '''«v1» == «v2»;''' | ||
152 | } | ||
147 | } | 153 | } |
148 | dispatch def transformConstraint(ConstantValue c, Modality modality, List<VariableMapping> variableMapping) { | 154 | dispatch def transformConstraint(ConstantValue c, Modality modality, List<VariableMapping> variableMapping) { |
149 | val target = c.supplierKey | 155 | val target = c.supplierKey |
@@ -189,24 +195,29 @@ class PConstraintTransformer { | |||
189 | def hasValue(PVariable v, String target, Modality m, List<VariableMapping> variableMapping) { | 195 | def hasValue(PVariable v, String target, Modality m, List<VariableMapping> variableMapping) { |
190 | val typeReference = variableMapping.filter[it.sourcePVariable === v].head.targetLogicVariable.range as PrimitiveTypeReference | 196 | val typeReference = variableMapping.filter[it.sourcePVariable === v].head.targetLogicVariable.range as PrimitiveTypeReference |
191 | if(m.isMay) { | 197 | if(m.isMay) { |
192 | '''PrimitiveElement.valueSet(«v.canonizeName»,«v.valueSetted»); «hasValueExpression(typeReference,v,v.valueVariable)» check(!«v.valueSetted»||«v.valueVariable»==«target»));''' | 198 | '''PrimitiveElement.valueSet(«v.canonizeName»,«v.valueSetted»); «hasValueExpressionByRef(typeReference,v,v.valueVariable)» check(!«v.valueSetted»||«v.valueVariable»==«target»));''' |
193 | } else { // Must or current | 199 | } else { // Must or current |
194 | '''PrimitiveElement.valueSet(«v.canonizeName»,true);«hasValueExpression(typeReference,v,target)»''' | 200 | '''PrimitiveElement.valueSet(«v.canonizeName»,true);«hasValueExpressionByRef(typeReference,v,target)»''' |
195 | } | 201 | } |
196 | } | 202 | } |
197 | 203 | ||
198 | private def hasValueExpression(List<VariableMapping> variableMapping, PVariable v, String target) { | 204 | private def hasValueExpression(List<VariableMapping> variableMapping, PVariable v, String target) { |
199 | hasValueExpression( | 205 | val mapping = variableMapping.filter[ |
200 | variableMapping.filter[it.sourcePVariable === v].head.targetLogicVariable.range, | 206 | val v2 = (it.sourcePVariable as PVariable) |
207 | v2 === v | ||
208 | ].head | ||
209 | val range = mapping.targetLogicVariable.range | ||
210 | hasValueExpressionByRef( | ||
211 | range, | ||
201 | v, | 212 | v, |
202 | target | 213 | target |
203 | ) | 214 | ) |
204 | } | 215 | } |
205 | private def dispatch hasValueExpression(BoolTypeReference typeReference, PVariable v, String target) '''BooleanElement.value(«v.canonizeName»,«target»);''' | 216 | private def dispatch hasValueExpressionByRef(BoolTypeReference typeReference, PVariable v, String target) '''BooleanElement.value(«v.canonizeName»,«target»);''' |
206 | private def dispatch hasValueExpression(IntTypeReference typeReference, PVariable v, String target) '''IntegerElement.value(«v.canonizeName»,«target»);''' | 217 | private def dispatch hasValueExpressionByRef(IntTypeReference typeReference, PVariable v, String target) '''IntegerElement.value(«v.canonizeName»,«target»);''' |
207 | private def dispatch hasValueExpression(RealTypeReference typeReference, PVariable v, String target) '''RealElement.value(«v.canonizeName»,«target»);''' | 218 | private def dispatch hasValueExpressionByRef(RealTypeReference typeReference, PVariable v, String target) '''RealElement.value(«v.canonizeName»,«target»);''' |
208 | private def dispatch hasValueExpression(StringTypeReference typeReference, PVariable v, String target) '''StringElement.value(«v.canonizeName»,«target»);''' | 219 | private def dispatch hasValueExpressionByRef(StringTypeReference typeReference, PVariable v, String target) '''StringElement.value(«v.canonizeName»,«target»);''' |
209 | private def dispatch hasValueExpression(TypeReference typeReference, PVariable v, String target) { | 220 | private def dispatch hasValueExpressionByRef(TypeReference typeReference, PVariable v, String target) { |
210 | throw new UnsupportedOperationException('''Unsupported primitive type reference: «typeReference.class»''') | 221 | throw new UnsupportedOperationException('''Unsupported primitive type reference: «typeReference.class»''') |
211 | } | 222 | } |
212 | 223 | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend index bd6e3e6e..37950834 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend | |||
@@ -10,6 +10,7 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.Binary | |||
10 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery | 10 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery |
11 | 11 | ||
12 | import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* | 12 | import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* |
13 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PDisjunction | ||
13 | 14 | ||
14 | class RelationDefinitionIndexer { | 15 | class RelationDefinitionIndexer { |
15 | public val PatternGenerator base; | 16 | public val PatternGenerator base; |
@@ -23,7 +24,8 @@ class RelationDefinitionIndexer { | |||
23 | def generateRelationDefinitions( | 24 | def generateRelationDefinitions( |
24 | LogicProblem problem, | 25 | LogicProblem problem, |
25 | Iterable<RelationDefinition> relations, | 26 | Iterable<RelationDefinition> relations, |
26 | Map<String,PQuery> fqn2PQuery) { | 27 | Map<String,PQuery> fqn2PQuery) |
28 | { | ||
27 | val relation2PQuery = relations.toInvertedMap[ | 29 | val relation2PQuery = relations.toInvertedMap[ |
28 | annotations.filter(TransfomedViatraQuery).head.patternFullyQualifiedName.lookup(fqn2PQuery) | 30 | annotations.filter(TransfomedViatraQuery).head.patternFullyQualifiedName.lookup(fqn2PQuery) |
29 | ] | 31 | ] |
@@ -67,11 +69,12 @@ class RelationDefinitionIndexer { | |||
67 | 69 | ||
68 | private def transformPattern(RelationDefinition relation, PQuery p, Modality modality) { | 70 | private def transformPattern(RelationDefinition relation, PQuery p, Modality modality) { |
69 | try { | 71 | try { |
72 | val bodies = (relation.annotations.filter(TransfomedViatraQuery).head.optimizedDisjunction as PDisjunction).bodies | ||
70 | return ''' | 73 | return ''' |
71 | private pattern «relationDefinitionName(relation,modality)»( | 74 | private pattern «relationDefinitionName(relation,modality)»( |
72 | problem:LogicProblem, interpretation:PartialInterpretation, | 75 | problem:LogicProblem, interpretation:PartialInterpretation, |
73 | «FOR param : p.parameters SEPARATOR ', '»var_«param.name»«ENDFOR») | 76 | «FOR param : p.parameters SEPARATOR ', '»var_«param.name»«ENDFOR») |
74 | «FOR body : p.disjunctBodies.bodies SEPARATOR "or"»{ | 77 | «FOR body : bodies SEPARATOR "or"»{ |
75 | find interpretation(problem,interpretation); | 78 | find interpretation(problem,interpretation); |
76 | «FOR constraint : body.constraints» | 79 | «FOR constraint : body.constraints» |
77 | «this.constraintTransformer.transformConstraint(constraint,modality,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)» | 80 | «this.constraintTransformer.transformConstraint(constraint,modality,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)» |
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend index 013da873..b4cb9ec7 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend | |||
@@ -90,7 +90,7 @@ class RefinementRuleProvider { | |||
90 | if(containmentRelation !== null) { | 90 | if(containmentRelation !== null) { |
91 | if(inverseRelation!== null) { | 91 | if(inverseRelation!== null) { |
92 | ruleBuilder.action[match | | 92 | ruleBuilder.action[match | |
93 | //println(name) | 93 | println(name) |
94 | val startTime = System.nanoTime | 94 | val startTime = System.nanoTime |
95 | //val problem = match.get(0) as LogicProblem | 95 | //val problem = match.get(0) as LogicProblem |
96 | val interpretation = match.get(1) as PartialInterpretation | 96 | val interpretation = match.get(1) as PartialInterpretation |
@@ -115,7 +115,7 @@ class RefinementRuleProvider { | |||
115 | ] | 115 | ] |
116 | } else { | 116 | } else { |
117 | ruleBuilder.action[match | | 117 | ruleBuilder.action[match | |
118 | //println(name) | 118 | println(name) |
119 | val startTime = System.nanoTime | 119 | val startTime = System.nanoTime |
120 | //val problem = match.get(0) as LogicProblem | 120 | //val problem = match.get(0) as LogicProblem |
121 | val interpretation = match.get(1) as PartialInterpretation | 121 | val interpretation = match.get(1) as PartialInterpretation |
@@ -139,6 +139,7 @@ class RefinementRuleProvider { | |||
139 | } | 139 | } |
140 | } else { | 140 | } else { |
141 | ruleBuilder.action[match | | 141 | ruleBuilder.action[match | |
142 | println(name) | ||
142 | val startTime = System.nanoTime | 143 | val startTime = System.nanoTime |
143 | //val problem = match.get(0) as LogicProblem | 144 | //val problem = match.get(0) as LogicProblem |
144 | val interpretation = match.get(1) as PartialInterpretation | 145 | val interpretation = match.get(1) as PartialInterpretation |
@@ -210,7 +211,7 @@ class RefinementRuleProvider { | |||
210 | ) | 211 | ) |
211 | } | 212 | } |
212 | } | 213 | } |
213 | } else if(relation.parameters instanceof PrimitiveTypeReference) { | 214 | } else if(relation.parameters.get(1) instanceof PrimitiveTypeReference) { |
214 | val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) | 215 | val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) |
215 | for(var times=0; times<number; times++) { | 216 | for(var times=0; times<number; times++) { |
216 | recursiveObjectCreation.get(sourceTypeInterpretation.interpretationOf) += | 217 | recursiveObjectCreation.get(sourceTypeInterpretation.interpretationOf) += |
@@ -230,10 +231,13 @@ class RefinementRuleProvider { | |||
230 | // Doing the recursion | 231 | // Doing the recursion |
231 | var objectCreations = new LinkedList(recursiveObjectCreation.values.flatten.toList) | 232 | var objectCreations = new LinkedList(recursiveObjectCreation.values.flatten.toList) |
232 | for(objectCreation : objectCreations) { | 233 | for(objectCreation : objectCreations) { |
233 | val newlyCreatedType = (objectCreation.typeInterpretation as PartialComplexTypeInterpretation).interpretationOf | 234 | val newInterpretation = objectCreation.typeInterpretation |
234 | if(recursiveObjectCreation.containsKey(newlyCreatedType)) { | 235 | if(newInterpretation instanceof PartialComplexTypeInterpretation) { |
235 | val actionsWhenTypeCreated = recursiveObjectCreation.get(newlyCreatedType) | 236 | val newlyCreatedType = newInterpretation.interpretationOf |
236 | objectCreation.recursiveConstructors+=actionsWhenTypeCreated | 237 | if(recursiveObjectCreation.containsKey(newlyCreatedType)) { |
238 | val actionsWhenTypeCreated = recursiveObjectCreation.get(newlyCreatedType) | ||
239 | objectCreation.recursiveConstructors+=actionsWhenTypeCreated | ||
240 | } | ||
237 | } | 241 | } |
238 | } | 242 | } |
239 | 243 | ||
@@ -246,7 +250,7 @@ class RefinementRuleProvider { | |||
246 | } else { | 250 | } else { |
247 | reachable = reachable.map[it.recursiveConstructors].flatten.toList | 251 | reachable = reachable.map[it.recursiveConstructors].flatten.toList |
248 | } | 252 | } |
249 | } while(reachable.empty) | 253 | } while(!reachable.empty) |
250 | } | 254 | } |
251 | 255 | ||
252 | return recursiveObjectCreation | 256 | return recursiveObjectCreation |
@@ -413,14 +417,14 @@ class RefinementRuleProvider { | |||
413 | val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] | 417 | val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] |
414 | inverseRelationInterpretation.relationlinks+=newLink2 | 418 | inverseRelationInterpretation.relationlinks+=newLink2 |
415 | 419 | ||
420 | // Scope propagation | ||
421 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
422 | |||
416 | // Do recursive object creation | 423 | // Do recursive object creation |
417 | for(newConstructor : recursiceObjectCreations) { | 424 | for(newConstructor : recursiceObjectCreations) { |
418 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | 425 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) |
419 | } | 426 | } |
420 | 427 | ||
421 | // Scope propagation | ||
422 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
423 | |||
424 | return newElement | 428 | return newElement |
425 | } | 429 | } |
426 | 430 | ||
@@ -451,14 +455,14 @@ class RefinementRuleProvider { | |||
451 | val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] | 455 | val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] |
452 | relationInterpretation.relationlinks+=newLink | 456 | relationInterpretation.relationlinks+=newLink |
453 | 457 | ||
458 | // Scope propagation | ||
459 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
460 | |||
454 | // Do recursive object creation | 461 | // Do recursive object creation |
455 | for(newConstructor : recursiceObjectCreations) { | 462 | for(newConstructor : recursiceObjectCreations) { |
456 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | 463 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) |
457 | } | 464 | } |
458 | 465 | ||
459 | // Scope propagation | ||
460 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
461 | |||
462 | return newElement | 466 | return newElement |
463 | } | 467 | } |
464 | 468 | ||
@@ -484,14 +488,14 @@ class RefinementRuleProvider { | |||
484 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | 488 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] |
485 | } | 489 | } |
486 | 490 | ||
491 | // Scope propagation | ||
492 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
493 | |||
487 | // Do recursive object creation | 494 | // Do recursive object creation |
488 | for(newConstructor : recursiceObjectCreations) { | 495 | for(newConstructor : recursiceObjectCreations) { |
489 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | 496 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) |
490 | } | 497 | } |
491 | 498 | ||
492 | // Scope propagation | ||
493 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
494 | |||
495 | return newElement | 499 | return newElement |
496 | } | 500 | } |
497 | 501 | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend index bdc48b8d..1e623823 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend | |||
@@ -77,6 +77,7 @@ class ViatraReasoner extends LogicReasoner{ | |||
77 | scopePropagator, | 77 | scopePropagator, |
78 | viatraConfig.documentationLevel | 78 | viatraConfig.documentationLevel |
79 | ) | 79 | ) |
80 | println("parsed") | ||
80 | 81 | ||
81 | dse.addObjective(new ModelGenerationCompositeObjective( | 82 | dse.addObjective(new ModelGenerationCompositeObjective( |
82 | new ScopeObjective, | 83 | new ScopeObjective, |
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 index 78326207..05a4e6c2 100644 --- 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 | |||
@@ -155,7 +155,7 @@ class GraphvizVisualiser implements PartialInterpretationVisualiser { | |||
155 | textWithSubSup(parts.getOrNull(0),parts.getOrNull(1),parts.getOrNull(2),null) | 155 | textWithSubSup(parts.getOrNull(0),parts.getOrNull(1),parts.getOrNull(2),null) |
156 | } else { | 156 | } else { |
157 | val parts = ID.split("\\s+") | 157 | val parts = ID.split("\\s+") |
158 | textWithSubSup(parts.get(0),parts.get(1),parts.getOrNull(2),null) | 158 | textWithSubSup(parts.getOrNull(0),parts.getOrNull(1),parts.getOrNull(2),null) |
159 | } | 159 | } |
160 | val label = Label.html( | 160 | val label = Label.html( |
161 | '''<TABLE«tableStyle»>'''+ | 161 | '''<TABLE«tableStyle»>'''+ |