2017-08-15 14:55:28 +00:00
|
|
|
package pov
|
|
|
|
|
|
|
|
const testVersion = 2
|
|
|
|
|
|
|
|
type Graph struct {
|
|
|
|
leaves []Node
|
|
|
|
}
|
|
|
|
|
|
|
|
func New() *Graph {
|
|
|
|
g := new(Graph)
|
|
|
|
return g
|
|
|
|
}
|
|
|
|
|
2017-08-15 22:06:46 +00:00
|
|
|
// GetNode returns the node from the graph with label lbl
|
2017-08-15 14:55:28 +00:00
|
|
|
func (g *Graph) GetNode(lbl string) *Node {
|
|
|
|
for i := range g.leaves {
|
|
|
|
if n := g.leaves[i].GetNode(lbl); n != nil {
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-08-15 22:06:46 +00:00
|
|
|
// AddNode adds a top level leaf with label lbl
|
2017-08-15 14:55:28 +00:00
|
|
|
func (g *Graph) AddNode(lbl string) {
|
|
|
|
g.leaves = append(g.leaves, Node{label: lbl})
|
|
|
|
}
|
|
|
|
|
2017-08-15 22:06:46 +00:00
|
|
|
// addRealNode adds the node n to the top level
|
2017-08-15 14:55:28 +00:00
|
|
|
func (g *Graph) addRealNode(n *Node) {
|
2017-08-15 22:06:46 +00:00
|
|
|
g.leaves = append(g.leaves, *n)
|
2017-08-15 14:55:28 +00:00
|
|
|
}
|
|
|
|
|
2017-08-15 22:06:46 +00:00
|
|
|
// AddArc creates a new node after to named from
|
2017-08-15 14:55:28 +00:00
|
|
|
func (g *Graph) AddArc(from, to string) {
|
|
|
|
if n := g.GetNode(to); n != nil {
|
|
|
|
n.AddNode(from)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-15 22:06:46 +00:00
|
|
|
// ArcList returns a list of all arcs
|
2017-08-15 14:55:28 +00:00
|
|
|
func (g *Graph) ArcList() []string {
|
|
|
|
var ret []string
|
|
|
|
for i := range g.leaves {
|
|
|
|
ret = append(ret, g.leaves[i].ArcList()...)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2017-08-15 22:06:46 +00:00
|
|
|
// ChangeRoot changes the graph from starting at oldRoot going to newRoot
|
2017-08-15 14:55:28 +00:00
|
|
|
func (g *Graph) ChangeRoot(oldRoot, newRoot string) *Graph {
|
|
|
|
// First of all, find the newRoot node
|
|
|
|
ret := New()
|
|
|
|
// The new graph will start with newRoot and have newRoot's leaves
|
2017-08-15 22:06:46 +00:00
|
|
|
var rt *Node
|
|
|
|
if rt = g.GetNode(newRoot); rt == nil {
|
2017-08-15 14:55:28 +00:00
|
|
|
return ret
|
|
|
|
}
|
|
|
|
// It'll have one more leaf, it's parent node
|
2017-08-15 22:06:46 +00:00
|
|
|
//rt.addRealNode(g.GetNode(oldRoot))
|
|
|
|
ret.addRealNode(rt)
|
|
|
|
return ret
|
2017-08-15 14:55:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Graph) getPath(from, to string) []string {
|
|
|
|
var ret []string
|
|
|
|
// Get the 'from' node
|
|
|
|
frNode := g.GetNode(from)
|
|
|
|
if frNode == nil {
|
|
|
|
// Couldn't find the starting node
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
// Just in case we got the same value for both
|
|
|
|
if from == to {
|
|
|
|
return []string{from}
|
|
|
|
}
|
|
|
|
// Found it
|
|
|
|
return frNode.getPath(to)
|
|
|
|
}
|
|
|
|
|
|
|
|
type Node struct {
|
|
|
|
label string
|
|
|
|
leaves []Node
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *Node) AddNode(lbl string) {
|
|
|
|
n.leaves = append(n.leaves, Node{label: lbl})
|
|
|
|
}
|
|
|
|
|
2017-08-15 22:06:46 +00:00
|
|
|
func (n *Node) addRealNode(nd *Node) {
|
|
|
|
n.leaves = append(n.leaves, *nd)
|
|
|
|
}
|
|
|
|
|
2017-08-15 14:55:28 +00:00
|
|
|
func (n *Node) GetNode(lbl string) *Node {
|
|
|
|
if n.label == lbl {
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
for i := range n.leaves {
|
|
|
|
if r := n.leaves[i].GetNode(lbl); r != nil {
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *Node) ArcList() []string {
|
|
|
|
var ret []string
|
|
|
|
for i := range n.leaves {
|
|
|
|
ret = append(ret, n.leaves[i].label+" -> "+n.label)
|
|
|
|
ret = append(ret, n.leaves[i].ArcList()...)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *Node) getPath(to string) []string {
|
|
|
|
ret := []string{n.label}
|
|
|
|
if n.label == to {
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
var i int
|
|
|
|
var found bool
|
|
|
|
for i = range n.leaves {
|
|
|
|
if n.leaves[i].GetNode(to) != nil {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
// We didn't find a path... :(
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
// n.leaves[i] should be the right leaf now
|
|
|
|
return append(ret, n.leaves[i].getPath(to)...)
|
|
|
|
}
|