How can I define a generic custom hyperedge

51 views
Skip to first unread message

Jose Emilio Labra Gayo

unread,
Apr 27, 2013, 9:12:41 AM4/27/13
to scala...@googlegroups.com
I would like to define graphs with a custom hyperedge made from three nodes. 

Following the "flight" example from the user-manual I was able to define a custom edge with triples of Int values. 

However, I am having problems to define a more generic edge made from triples of the form (A,A,A).

The following code works: 

class Triple[N](nodes: Product,
                val triple: (Int,Int,Int)) 
extends DiHyperEdge[N](nodes)
    with    EdgeCopy[Triple]
    with    EdgeIn[N,Triple] {

  override def copy[NN](newNodes: Product) =
    new Triple[NN](newNodes, triple)
    
  def subj : Int = { triple._1 }
  def pred : Int = { triple._2 }
  def obj  : Int = { triple._3 }
}
object Triple{
  def apply(subj: Int, pred: Int, obj : Int) =
     new Triple[Int](NodeProduct(subj, pred,obj), (subj,pred,obj))
  def unapply(e: Triple[Int]) = Some(e)
}

The following code does not work. 

class Triple[N,A](nodes: Product,
                val triple: (A,A,A)) 
extends DiHyperEdge[N](nodes)
    with    EdgeCopy[Triple[A]]
    with    EdgeIn[N,Triple[A]] {

  override def copy[NN](newNodes: Product) =
    new Triple[NN](newNodes, triple)
    
  def subj : A = { triple._1 }
  def pred : A = { triple._2 }
  def obj  : A = { triple._3 }
}

Best regards, Jose Labra


Peter Empen

unread,
Apr 27, 2013, 10:27:21 AM4/27/13
to scala...@googlegroups.com
Jose,

this is the case because both EdgeCopy's single type parameter as well as EdgeIn's second type parameter expect a type with exactly one type parameter what your Triple[N,A] doesn't satisfies.

One way to overcome this situation is to use Scala type lambdas. Among others, they serve to propagate a subset of the type parameters. But type lambdas are a rarely used language feature.

Onother simple workaroud is to define the A type parameter in an outer class like

class Outer[A] {

  class Triple[N](nodes: Product,
                  val triple: Tuple3[A,A,A])
  extends DiHyperEdge[N](nodes)
      with    EdgeCopy[Triple]
      with    EdgeIn[N,Triple] {

    override def copy[NN](newNodes: Product) =
      new Triple[NN](newNodes, triple)
   
    def subj : A = { triple._1 }
    def pred : A = { triple._2 }
    def obj  : A = { triple._3 }
  }
}

I personally would prefer the latter unless not practicable for you.

Please note that release 1.7 wil include true directed hyper edge support meaning we'll have to pass two sets of nodes to each direceted hyperedge. Currently, the library just assumes that the first supplied node is the source.
 
Hope this helps,

Peter

Jose Emilio Labra Gayo

unread,
Apr 27, 2013, 11:22:04 AM4/27/13
to scala...@googlegroups.com
Thanks for your answer.

I was trying to use your solution but I am not sure how to do it. I
would like to define a graph nodes of type A and hypergraphs of type
Triple[A], i.e. (A,A,A)

I think it should be something like this...

val g = Graph[A,Triple[A]]

but it doesn't seem to work...

Best regards, Jose Labra

Peter Empen

unread,
Apr 27, 2013, 12:41:05 PM4/27/13
to scala...@googlegroups.com
It seems I've misunderstood your example. You don't need two different type parameters in case you just want to ensure that the edges are all Triples. Possibly you just need:

class Triple[N](nodes: (N,N,N))
    extends DiHyperEdge[N](nodes)
    with    EdgeCopy[Triple]
    with    EdgeIn[N,Triple] {

  override def copy[NN](newNodes: Product) =
    new Triple[NN](newNodes.asInstanceOf[(NN,NN,NN)])
 
  def subj : N = { nodes._1 }
  def pred : N = { nodes._2 }
  def obj  : N = { nodes._3 }
}

val g = Graph[Int, Triple]()


Here, asInstanceOf is safe.

Jose Emilio Labra Gayo

unread,
Apr 27, 2013, 2:13:47 PM4/27/13
to scala...@googlegroups.com
Yes, that's what I wanted. I was trying it and it works now.

Thanks a lot!! :) 

empen...@gmail.com

unread,
May 1, 2023, 11:01:03 AM5/1/23
to scala-graph
This is now much easier with version 2.
Reply all
Reply to author
Forward
0 new messages