001/* 002 * Copyright (c) 2003-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.sms.actors; 031 032import java.util.Iterator; 033import java.util.Vector; 034 035import org.kepler.sms.SMSServices; 036import org.kepler.sms.SemanticType; 037 038import ptolemy.actor.IOPort; 039import ptolemy.actor.TypedIOPort; 040import ptolemy.kernel.util.NamedObj; 041 042/** 043 * SIMPLE MERGE ALGORITHM: 044 * 045 * ComputeMerge() 1. Let Matches = {} 2. Let Conflicts = {} 3. foreach A in 046 * MergeActors 4. foreach output port P of A involved in merge 5. 047 * ComputeMatches(A, P, Matches, Conflicts) 6. ComputeMappings(Matches) 7. 048 * ComputeTargetSemTypes(matches); 049 * 050 * ComputeMatches(A, P, Matches, Conflicts) 1. Let Actors = MergeActors - {A} 2. 051 * foreach A' in Actors and !HasConflict(P, A', Conflicts) 3. foreach output 052 * port P' of A' involved in merge 4. if( semType(P) subtypeof semType(P') ) 5. 053 * if( HasMatch(P', A, Matches) ) 6. AddConflict(P, A', Matches, Conflicts) 7. 054 * else 8. AddMatch(P, P', Matches) ... here we can add a condition for 055 * conversion functions ... 056 * 057 * ComputeMappings(Matches) 1. Let MergeSets = PartitionMatches(Matches) 2. 058 * foreach S in MergeSets 3. Let P' = CreateNewOutputPort() 4. foreach P in S 5. 059 * AddMapping(P, P') 6. foreach A in MergeActors 7. foreach otuput port P of A 060 * involved in merge 8. if( !InMatch(P, Matches) ) 9. Let P' = 061 * CreateNewOutputPort() 10. AddMapping(P, P') 062 */ 063 064public class SimpleComputeMergeAlgorithm { 065 066 /** 067 * 068 */ 069 public SimpleComputeMergeAlgorithm(MergeActor mergeActor) { 070 _mergeActor = mergeActor; 071 } 072 073 /** 074 * 075 */ 076 public void computeMerge() { 077 Vector matches = new Vector(); 078 Vector conflicts = new Vector(); 079 Iterator actors = _mergeActor.getActors().iterator(); 080 while (actors.hasNext()) { 081 NamedObj a = (NamedObj) actors.next(); 082 Iterator ports = _mergeActor.getActorPorts(a).iterator(); 083 while (ports.hasNext()) { 084 IOPort p = (IOPort) ports.next(); 085 _computeMatches(a, p, matches, conflicts); 086 } 087 } 088 089 System.out.print("COMPUTE MATCHES: "); 090 _printMatches(matches); 091 092 _computeMappings(matches); 093 _computeTargetSemTypes(matches); 094 } 095 096 /** 097 * 098 */ 099 private void _computeMatches(NamedObj a, IOPort p, Vector matches, 100 Vector conflicts) { 101 Vector actors = new Vector(); 102 Iterator iter = _mergeActor.getActors().iterator(); 103 while (iter.hasNext()) { 104 NamedObj actor = (NamedObj) iter.next(); 105 if (!actor.equals(a)) 106 actors.add(actor); 107 } 108 iter = actors.iterator(); 109 while (iter.hasNext()) { 110 NamedObj ap = (NamedObj) iter.next(); 111 if (!_hasConflict(p, ap, conflicts)) { 112 Iterator ports = _mergeActor.getActorPorts(ap).iterator(); 113 while (ports.hasNext()) { 114 IOPort pp = (IOPort) ports.next(); 115 Vector<SemanticType> p_semtypes = SMSServices.getPortSemanticTypes(p); 116 Vector<SemanticType> pp_semtypes = SMSServices.getPortSemanticTypes(pp); 117 if (SMSServices.compatible(p_semtypes, pp_semtypes)) { 118 System.out.println(p.getContainer().getName() + "." 119 + p.getName() + " is compatible with " 120 + pp.getContainer().getName() + "." 121 + pp.getName()); 122 if (_hasMatch(pp, a, matches)) 123 _addConflict(p, ap, matches, conflicts); 124 else 125 _addMatch(p, pp, matches); 126 } 127 // else if(SMSServices.compatible(pp_semtypes, p_semtypes)) 128 // { 129 // System.out.println(pp.getContainer().getName() + "." + 130 // pp.getName() + 131 // " is compatible with " + 132 // p.getContainer().getName() + "." + p.getName()); 133 // if(_hasMatch(pp, a, matches)) 134 // _addConflict(p, ap, matches, conflicts); 135 // else 136 // _addMatch(pp, p, matches); 137 // } 138 } 139 } 140 } 141 } 142 143 /** 144 * 145 */ 146 private void _computeMappings(Vector matches) { 147 Vector mergeSets = _partitionMatches(matches); 148 Iterator iter = mergeSets.iterator(); 149 while (iter.hasNext()) { 150 Vector s = (Vector) iter.next(); 151 System.out.println("ADDING PARTITION"); 152 TypedIOPort pp = _createNewOutputPort(); 153 Iterator ports = s.iterator(); 154 while (ports.hasNext()) { 155 IOPort p = (IOPort) ports.next(); 156 System.out.println("... ADDING PORT: " 157 + p.getContainer().getName() + "." + p.getName()); 158 _addMapping(p, pp); 159 } 160 } 161 iter = _mergeActor.getActors().iterator(); 162 while (iter.hasNext()) { 163 NamedObj a = (NamedObj) iter.next(); 164 Iterator ports = _mergeActor.getActorPorts(a).iterator(); 165 while (ports.hasNext()) { 166 IOPort p = (IOPort) ports.next(); 167 // System.out.println("CHECKING a = " + a.getName() + 168 // " and p = " + p.getName()); 169 if (!_inMatch(p, matches)) { 170 TypedIOPort pp = _createNewOutputPort(); 171 _addMapping(p, pp); 172 } 173 } 174 } 175 } 176 177 /** 178 * 179 */ 180 private void _addMapping(IOPort p, IOPort pp) { 181 String name = _mergeActor.uniqueName("_merge"); 182 String actor = p.getContainer().getName(); 183 String port = p.getName(); 184 String target = pp.getName(); 185 try { 186 SimpleMergeMapping m = new SimpleMergeMapping(_mergeActor, name, 187 actor, port, target); 188 } catch (Exception e) { 189 e.printStackTrace(); 190 } 191 } 192 193 /** 194 * 195 */ 196 private boolean _inMatch(IOPort p, Vector matches) { 197 Iterator iter = matches.iterator(); 198 while (iter.hasNext()) { 199 IOPort[] match = (IOPort[]) iter.next(); 200 if (p.equals(match[0]) || p.equals(match[1])) 201 return true; 202 } 203 return false; 204 } 205 206 /** 207 * 208 */ 209 private TypedIOPort _createNewOutputPort() { 210 TypedIOPort p = null; 211 try { 212 p = new TypedIOPort(_mergeActor, _mergeActor.uniqueName("target"), 213 false, true); 214 } catch (Exception e) { 215 e.printStackTrace(); 216 } 217 return p; 218 } 219 220 /** 221 * 222 */ 223 private Vector _partitionMatches(Vector matches) { 224 Vector matches_copy = new Vector(); 225 Iterator iter = matches.iterator(); 226 while (iter.hasNext()) 227 matches_copy.add(iter.next()); 228 Vector partitions = new Vector(); 229 _partitionMatches(matches_copy, partitions); 230 return partitions; 231 } 232 233 /** 234 * 235 */ 236 private void _partitionMatches(Vector matches, Vector partitions) { 237 if (matches.isEmpty()) 238 return; 239 IOPort[] match = (IOPort[]) matches.elementAt(0); 240 boolean found = false; 241 Iterator iter = partitions.iterator(); 242 while (!found && iter.hasNext()) { 243 Vector partition = (Vector) iter.next(); 244 if (partition.contains(match[0]) || partition.contains(match[1])) { 245 // add both to be sure 246 if (!partition.contains(match[0])) 247 partition.add(match[0]); 248 if (!partition.contains(match[1])) 249 partition.add(match[1]); 250 found = true; 251 } 252 } 253 matches.remove(match); 254 if (!found) { 255 Vector partition = new Vector(); 256 partition.add(match[0]); 257 partition.add(match[1]); 258 partitions.add(partition); 259 } 260 _partitionMatches(matches, partitions); 261 } 262 263 /** 264 * 265 */ 266 private void _computeTargetSemTypes(Vector matches) { 267 268 } 269 270 /** 271 * 272 */ 273 private boolean _hasConflict(IOPort p, NamedObj ap, Vector conflicts) { 274 Iterator iter = conflicts.iterator(); 275 while (iter.hasNext()) { 276 Object[] conflict = (Object[]) iter.next(); 277 if (p.equals(conflict[0]) && ap.equals(conflict[1])) 278 return true; 279 } 280 return false; 281 } 282 283 /** 284 * 285 */ 286 private boolean _hasMatch(IOPort pp, NamedObj a, Vector matches) { 287 Iterator iter = matches.iterator(); 288 while (iter.hasNext()) { 289 IOPort[] match = (IOPort[]) iter.next(); 290 if (pp.equals(match[0]) && a.equals(match[1])) 291 return true; 292 } 293 return false; 294 } 295 296 /** 297 * 298 */ 299 private void _addConflict(IOPort p, NamedObj ap, Vector matches, 300 Vector conflicts) { 301 Object[] conflict = { p, ap }; 302 if (!conflicts.contains(conflict)) 303 conflicts.add(conflict); 304 // remove all <p,pp> or <pp,p> matches 305 Iterator iter = matches.iterator(); 306 while (iter.hasNext()) { 307 IOPort[] match = (IOPort[]) iter.next(); 308 if (p.equals(match[0])) { 309 Iterator ports = _mergeActor.getActorPorts(ap).iterator(); 310 while (ports.hasNext()) { 311 IOPort pp = (IOPort) ports.next(); 312 if (pp.equals(match[1])) 313 matches.remove(match); 314 } 315 } 316 if (p.equals(match[1])) { 317 Iterator ports = _mergeActor.getActorPorts(ap).iterator(); 318 while (ports.hasNext()) { 319 IOPort pp = (IOPort) ports.next(); 320 if (pp.equals(match[0])) 321 matches.remove(match); 322 } 323 } 324 } 325 } 326 327 /** 328 * 329 */ 330 private void _addMatch(IOPort p, IOPort pp, Vector matches) { 331 IOPort[] match = { p, pp }; 332 Iterator iter = matches.iterator(); 333 while (iter.hasNext()) { 334 IOPort[] m = (IOPort[]) iter.next(); 335 if (m[0].equals(p) && m[1].equals(pp)) 336 return; 337 } 338 matches.add(match); 339 } 340 341 /** 342 * Helper function for printing out a set of matches 343 */ 344 private void _printMatches(Vector matches) { 345 Iterator iter = matches.iterator(); 346 System.out.print("{"); 347 while (iter.hasNext()) { 348 IOPort[] match = (IOPort[]) iter.next(); 349 System.out.print("<" + match[0].getName() + ", " 350 + match[1].getName() + ">"); 351 if (iter.hasNext()) 352 System.out.print(", "); 353 } 354 System.out.println("}"); 355 } 356 357 // ////////////////////////////////////////////////////////////////////////// 358 // PRIVATE MEMBERS 359 360 private MergeActor _mergeActor; 361 362}// SimpleComputeMergeAlgorithm