case class U(name: String) {
override def toString = s"${getClass.getSimpleName}($name: ${System.identityHashCode(this)})"
override def equals(a: Any) = System.identityHashCode(this) == System.identityHashCode(a)
}
case class V(name: String, u: U) {
override def toString = s"${getClass.getSimpleName}($name: ${System.identityHashCode(this)}, $u)"
override def equals(a: Any) = System.identityHashCode(this) == System.identityHashCode(a)
}
case class T(u: U, v1: V, v2: V){
override def toString = s"${getClass.getSimpleName}(${System.identityHashCode(this)}, $u, $v1, $v2)"
}
val v = V("v1", U("u2"))
val graph = T(U("u1"), v, v)
T
/ |\
U1 | \
| /
V
|
U2
If I rewrite this graph with this strategy, which makes singletons in a tree:
def singletonStrategy[S](implicit tag: ClassTag[S]): Strategy = {
var s: Option[S] = None
strategy[Any] {
case tag(v) =>
s match {
case Some(singleton) =>
Some(singleton)
case None =>
s = Some(v.asInstanceOf[S])
Some(v)
}
case other => Some(other)
}
}
Then rewrite(everywhere(singletonStrategy[U]))(graph) do its job and replace every instance of `U` with the first instance found.
Unfortunately it will also duplicate the shared node `v`:
T
/ |\
U1 | \
| \
V1 V2
| |
U1 U1
My question is: is there a way to rewrite a graph so that shared nodes are preserved?
I tried to look at previous messages on this mailing-list and there is supposedly a solution which I previously used for this:
but I cannot recall what it was. Do you think it is even possible to do what I want?
Thanks,
Eric.