Giter Club home page Giter Club logo

dgraph's Introduction

DGraph

An implementation of directed graph with powerful graph matching functionality.

Anything could change in the next releases.

This library is experimental and NOT production-ready by any means.

In this library, a graph has two main components: Node and DEdge. Node[N] contains id:Int and a value of type N .DEdge[E] has from:Int and to:Int and value of type E.

Using:

 resolvers += Resolver.sonatypeRepo("snapshots")

 libraryDependencies += "com.github.omidb" %%% "dgraph" % "0.1.0-SNAPSHOT"

##Create Graph

There are two main ways you can create a graph:

Using Nodes and Edges

val nodes = Map(0 -> Node("n0", 0), 1 -> Node("n1", 1), 2 -> Node("n2", 2))
val edges = TreeMap((0,1) -> DEdge("e0",0,1), (1,0) -> DEdge("e1",1,0), (1,2) -> DEdge("e2",1,2))
val g:Dgraph[String,String] = DGraph.from(nodes,edges)

###Using a recursive representation Using QNodeLike and HalfEdgeLike you can represent different recursive graphs, but it will get converted to Dgraph. Following all are QNodeLike : QNode is a simple node QNodeMarker is a node with a mark for future references QNodeRef is a references to a marker node Following are all HalfEdgeLike : HalfEdge is an edge to a node EmprtHalfEdge is an empty node and edge

Here is an example:

val g:Dgraph[String,String] = DGraph.from(QNode("n0", HalfEdge("e0", QNode("n1", EmptyHalfEdge))))

For all these we provide a DSL to make things easier:

import DGraphDSL._
val g = DGraph.from[String,String](
  Nd("n0",
   --("e0")->Nd("n1"),
   --("e1")->Nd("n2"),
   --("e2")->Nd("n3"))
)

val g2 = DGraph.from[String,String](
  Nd("n0",
   --("e0")->NdMark("n1","mrk1"),
   --("e1")->Nd("n2"),
   --("e2")->Nd("n3",
              --("e3")->(Ref("mrk1"))))
)

##Graph Pattern This library provides algorithms for graph matching. A pattern for matching on graphs is a graph of DGraph[NodeMatchLike[N],EdgeMatchLike[E]] which both NodeMatchLike[N] and EdgeMatchLike[E] contains an eval function of T=> Boolean The following are all NodeMatchLike[N]:

NodeMatchAND[N] all the output edge-nodes should be true <&() NodeMatchANDCons[N] all the output edge-nodes should be true (order is important) <&() NodeMatchOR[N] one of the output edge-nodes is enough to be true <|()

We can use our DSL to define the pattern graph:

val q = query[String,String](
        <&(_ == "n0",
            -?>(_ == "e0", <&(_ == "n1"))
        )
      )

-?> is a simple EdgeMatch ... ##Graph Operations: let's assume we have a graph:

import DGraphDSL._
      val g = DGraph.from[String,String](
        Nd("n0",
         --("e0")->NdMark("n1","mrk1"),
         --("e1")->Nd("n2"),
         --("e2")->Nd("n3",
                    --("e3")->(Ref("mrk1"))))
      )

and a pattern:

val q = query[String,String](
        <&(_ == "n0",
            -?>(_ == "e0", <&(_ == "n1"))
        )
      )

We can perform many operations on it like Scala collections:

 g.containsNode("n0") //check if it contains a node
 g.containsEdge("e0") //check if it contains an edge
   
 g.contains(q) //check if it contains a subgraph that matches the q query
 
 g.mapByNodes(_.toInt) //convert the graph by mapping nodes
 g.mapByEdges(e => e.toInt + 1) //convert the graph by mapping edges
 g.map(_.toInt, _.toInt + 1) //convert the graph by two different map functions


 g.filterNodes(_.startWith("n0")) //filtering nodes
 g.filterEdges(_.startWith("e0")) //filtering edges
 g.filter(q) // return List[DGraph[String,String]] of sub-graphs that match the query

All the functions above use GraphMatch.mtch(g, q) that returns all possible matches between graph g and query q.

If you want to extract some information from graph and convert it to a record (case class) you can do the following:

Let's say you have the following graph and you want to extract some specific items from it.

 import DGraphDSL._

      case class SimpleExtract(n0:String, n3:String, e3:String)

      val g = DGraph.from[String,String](
        Nd("n0",
          --("e0")->Nd("n1"),
          --("e1")->Nd("n2"),
          --("e2")->Nd("n3",
            --("e3")->Nd("n4")))
      )

We can use queryAndExtract that will give us two graphs: A query graph and an Extractor graph

      val res = queryAndExtract[String, String, SimpleExtract](
        <-&(n => n == "n0", (n, p) => p.copy(n0 = n),
          --?>(_ == "e2", (e,p) => p,
            <-&(_ == "n3", (n, p) => p.copy(n3 = n),
              --?>(_ == "e3", (e,p) => p.copy(e3 = e), <-&(_ == "n4",(n,p) => p))))
        ),
        g, SimpleExtract("", "", "")
      )


      
      println(res.head._2)
      assert(res.head._2 == SimpleExtract("n0", "n3", "e3"))

As you can see, it will extract the information and updates the SimpleExtract("", "", "").

dgraph's People

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

mrmechko

dgraph's Issues

Weird type issue

res53: dgraph.DGraph[dgraph.NodeMatchAND[String],dgraph.EdgeMatch[String]] = DGraph(Map(0 -> Node(NodeMatchAND(<function1>),0), 1 -> Node(NodeMatchAND(<function1>),1), 2 -> Node(NodeMatchAND(<function1>),2)),Map((0,1) -> DEdge(EdgeMatch(<function1>),0,1), (0,2) -> DEdge(EdgeMatch(<function1>),0,2)),Map(2 -> Vector(0), 1 -> Vector(0), 0 -> Vector()),Map(2 -> Vector(), 1 -> Vector(), 0 -> Vector(1, 2)))

res54: dgraph.DGraph[String,String] = DGraph(Map(0 -> Node(a,0), 1 -> Node(b,1), 2 -> Node(c,2)),Map((0,1) -> DEdge(1,0,1), (0,2) -> DEdge(2,0,2)),Map(2 -> Vector(0), 1 -> Vector(0), 0 -> Vector()),Map(2 -> Vector(), 1 -> Vector(), 0 -> Vector(1, 2)))

scala> res54.filter(res43)
<console>:32: error: type mismatch;
 found   : dgraph.DGraph[dgraph.NodeMatchAND[String],dgraph.EdgeMatch[String]]
 required: dgraph.DGraph[dgraph.NodeMatchLike[String],dgraph.EdgeMatchLike[String]]
Note: dgraph.NodeMatchAND[String] <: dgraph.NodeMatchLike[String], but class DGraph is invariant in type N.
You may wish to define N as +N instead. (SLS 4.5)
Note: dgraph.EdgeMatch[String] <: dgraph.EdgeMatchLike[String], but class DGraph is invariant in type E.
You may wish to define E as +E instead. (SLS 4.5)

Trying to map a graph into a pattern is causing some problems because NodeMatchAND[N] can't be automatically cast to NodeMatchLike[N] and similarly with edges.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.