mesh.sml 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. (* Mesh = Zusammenhangskomponente eines einfachen Graphen *)
  2. signature MESH =
  3. sig
  4. structure Key : ORD_KEY
  5. structure Set : ORD_SET
  6. structure PairSet : ORD_SET
  7. structure Map : ORD_MAP
  8. type mesh = { nodes : Set.set,
  9. edges : PairSet.set }
  10. type meshes = mesh Map.map
  11. type graph = { meshes : meshes,
  12. node2meshindex : Key.ord_key Map.map }
  13. val empty_graph : graph
  14. val add_link : graph -> int * int -> graph
  15. val links2graph : (int * int) list -> graph
  16. end
  17. structure Mesh : MESH =
  18. struct
  19. functor PairKeyFn ( Key : ORD_KEY ) : ORD_KEY =
  20. struct
  21. type ord_key = Key.ord_key * Key.ord_key
  22. fun compare (i as (i1, i2), j as (j1, j2)) =
  23. let val (ia, ib) = if Key.compare (i1, i2) = GREATER
  24. then (i2, i1) else i
  25. val (ja, jb) = if Key.compare (i1, i2) = GREATER
  26. then (j2, j1) else j
  27. in case Key.compare (ia, ja)
  28. of EQUAL => Key.compare (ib, jb)
  29. | unequal => unequal
  30. end
  31. end
  32. (* XXX Unterschiedliche key Typen (statt beide = int)
  33. fuer die Maps node2meshindex und meshes
  34. damit der type checker Verwechslungen erkennen kann *)
  35. structure Key =
  36. struct
  37. type ord_key = Int.int
  38. val compare = Int.compare
  39. val minkey = 0
  40. fun nextkey k = k + 1
  41. end
  42. structure PairKey = PairKeyFn (Key)
  43. structure Set = SplaySetFn (Key)
  44. structure PairSet = SplaySetFn (PairKey)
  45. structure Map = SplayMapFn (Key)
  46. type mesh = { nodes : Set.set,
  47. edges : PairSet.set }
  48. type meshes = mesh Map.map
  49. type graph = { meshes : meshes,
  50. node2meshindex : Key.ord_key Map.map }
  51. val empty_graph = { meshes = Map.empty,
  52. node2meshindex = Map.empty }
  53. fun n2im (g : graph) n =
  54. case Map.find (#node2meshindex g, n)
  55. of NONE => NONE
  56. | SOME mi =>
  57. SOME (mi, valOf (Map.find (#meshes g, mi)))
  58. handle Option =>
  59. raise Fail ("n2im: n = " ^ (Int.toString n) ^
  60. ", mi = " ^ (Int.toString mi))
  61. fun maxkey map = Map.foldli (fn (k, _, i) =>
  62. if Key.compare (k, i) = GREATER
  63. then k else i)
  64. Key.minkey
  65. map
  66. fun add_link' (g : graph as { meshes, node2meshindex })
  67. (e as (n1, n2)) =
  68. case (n2im g n1, n2im g n2)
  69. of (NONE, NONE) =>
  70. let val m = { nodes = Set.add (Set.singleton n1, n2),
  71. edges = PairSet.singleton e }
  72. val mi = Key.nextkey (maxkey meshes)
  73. in { meshes = Map.insert (meshes, mi, m),
  74. node2meshindex = Map.insert
  75. (Map.insert (node2meshindex,
  76. n1, mi),
  77. n2, mi) }
  78. end
  79. | (SOME (m1i, { nodes, edges }), NONE) =>
  80. let val m1' = { nodes = Set.add (nodes, n2),
  81. edges = PairSet.add (edges, e) }
  82. in { meshes = Map.insert (meshes, m1i, m1'),
  83. node2meshindex = Map.insert (node2meshindex, n2, m1i) }
  84. end
  85. | (NONE, SOME (m2i, { nodes, edges })) =>
  86. let val m2' = { nodes = Set.add (nodes, n1),
  87. edges = PairSet.add (edges, e) }
  88. in { meshes = Map.insert (meshes, m2i, m2'),
  89. node2meshindex = Map.insert (node2meshindex, n1, m2i) }
  90. end
  91. | (SOME (m1i, { nodes = nodes1, edges = edges1 }),
  92. SOME (m2i, { nodes = nodes2, edges = edges2 })) =>
  93. case Key.compare (m1i, m2i)
  94. of EQUAL =>
  95. let val m1' = { nodes = nodes1,
  96. edges = PairSet.add (edges1, e) }
  97. in { meshes = Map.insert (meshes, m1i, m1'),
  98. node2meshindex = node2meshindex }
  99. end
  100. | unequal =>
  101. let val (mai, mbi) = if unequal = GREATER
  102. then (m2i, m1i) else (m1i, m2i)
  103. val nodesb = if unequal = GREATER
  104. then nodes1 else nodes2
  105. val ma = { nodes = Set.union (nodes1, nodes2),
  106. edges = PairSet.add
  107. (PairSet.union (edges1, edges2),
  108. e) }
  109. in { meshes = #1 (Map.remove (Map.insert (meshes, mai, ma),
  110. mbi)),
  111. node2meshindex = foldl (fn (n, map) =>
  112. Map.insert (map, n, mai))
  113. node2meshindex
  114. (Set.listItems nodesb) }
  115. end
  116. fun add_link g (e as (n1, n2)) =
  117. let val (na, nb) = if Key.compare (n1, n2) = GREATER
  118. then (n2, n1) else e
  119. in add_link' g (na, nb)
  120. end
  121. fun links2graph links = foldl (fn (e, g) => add_link g e)
  122. empty_graph
  123. links
  124. end