diff --git a/gg/gg.go b/gg/gg.go index 0a6ccd8..2ba705d 100644 --- a/gg/gg.go +++ b/gg/gg.go @@ -8,8 +8,6 @@ import ( "hash" ) -// TODO rename half-edge to open-edge - // Identifier is implemented by any value which can return a unique string for // itself via an Identify method type Identifier interface { @@ -53,9 +51,9 @@ type Vertex struct { //////////////////////////////////////////////////////////////////////////////// -// HalfEdge is an un-realized Edge which can't be used for anything except +// OpenEdge is an un-realized Edge which can't be used for anything except // constructing graphs. It has no meaning on its own. -type HalfEdge struct { +type OpenEdge struct { // fromV will be the source vertex as-if the vertex (and any sub-vertices of // it) doesn't already exist in the graph. If it or it's sub-vertices does // already that will need to be taken into account when persisting into the @@ -65,19 +63,19 @@ type HalfEdge struct { } // Identify implements the Identifier interface -func (he HalfEdge) Identify(h hash.Hash) { - fmt.Fprintln(h, "halfEdge") - he.fromV.Identify(h) - he.val.Identify(h) +func (oe OpenEdge) Identify(h hash.Hash) { + fmt.Fprintln(h, "openEdge") + oe.fromV.Identify(h) + oe.val.Identify(h) } // vertex is a representation of a vertex in the graph. Each Graph contains a // set of all the Value vertex instances it knows about. Each of these contains -// all the input HalfEdges which are known for it. So you can think of these -// "top-level" Value vertex instances as root nodes in a tree, and each HalfEdge +// all the input OpenEdges which are known for it. So you can think of these +// "top-level" Value vertex instances as root nodes in a tree, and each OpenEdge // as a branch. // -// If a HalfEdge contains a fromV which is a Value that vertex won't have its in +// If a OpenEdge contains a fromV which is a Value that vertex won't have its in // slice populated no matter what. If fromV is a Junction it will be populated, // with any sub-Value's not being populated and so-on recursively // @@ -86,7 +84,7 @@ func (he HalfEdge) Identify(h hash.Hash) { type vertex struct { VertexType val Identifier - in []HalfEdge + in []OpenEdge } // A Value vertex is unique by the value it contains @@ -108,25 +106,25 @@ func (v vertex) Identify(h hash.Hash) { func (v vertex) cp() vertex { cp := v - cp.in = make([]HalfEdge, len(v.in)) + cp.in = make([]OpenEdge, len(v.in)) copy(cp.in, v.in) return cp } -func (v vertex) hasHalfEdge(he HalfEdge) bool { - heID := identify(he) +func (v vertex) hasOpenEdge(oe OpenEdge) bool { + oeID := identify(oe) for _, in := range v.in { - if identify(in) == heID { + if identify(in) == oeID { return true } } return false } -func (v vertex) cpAndDelHalfEdge(he HalfEdge) (vertex, bool) { - heID := identify(he) +func (v vertex) cpAndDelOpenEdge(oe OpenEdge) (vertex, bool) { + oeID := identify(oe) for i, in := range v.in { - if identify(in) == heID { + if identify(in) == oeID { v = v.cp() v.in = append(v.in[:i], v.in[i+1:]...) return v, true @@ -162,15 +160,15 @@ func (g *Graph) cp() *Graph { //////////////////////////////////////////////////////////////////////////////// // Graph creation -// ValueOut creates a HalfEdge which, when used to construct a Graph, represents +// ValueOut creates a OpenEdge which, when used to construct a Graph, represents // an edge (with edgeVal attached to it) leaving the Value Vertex containing // val. // // When constructing Graphs Value vertices are de-duplicated on their value. So -// multiple ValueOut HalfEdges constructed with the same val will be leaving the +// multiple ValueOut OpenEdges constructed with the same val will be leaving the // same Vertex instance in the constructed Graph. -func ValueOut(val, edgeVal Identifier) HalfEdge { - return HalfEdge{ +func ValueOut(val, edgeVal Identifier) OpenEdge { + return OpenEdge{ fromV: vertex{ VertexType: Value, val: val, @@ -179,15 +177,15 @@ func ValueOut(val, edgeVal Identifier) HalfEdge { } } -// JunctionOut creates a HalfEdge which, when used to construct a Graph, +// JunctionOut creates a OpenEdge which, when used to construct a Graph, // represents an edge (with edgeVal attached to it) leaving the Junction Vertex // comprised of the given ordered-set of input edges. // // When constructing Graphs Junction vertices are de-duplicated on their input -// edges. So multiple Junction HalfEdges constructed with the same set of input +// edges. So multiple Junction OpenEdges constructed with the same set of input // edges will be leaving the same Junction instance in the constructed Graph. -func JunctionOut(in []HalfEdge, edgeVal Identifier) HalfEdge { - return HalfEdge{ +func JunctionOut(in []OpenEdge, edgeVal Identifier) OpenEdge { + return OpenEdge{ fromV: vertex{ VertexType: Junction, in: in, @@ -196,11 +194,11 @@ func JunctionOut(in []HalfEdge, edgeVal Identifier) HalfEdge { } } -// AddValueIn takes a HalfEdge and connects it to the Value Vertex containing +// AddValueIn takes a OpenEdge and connects it to the Value Vertex containing // val, returning the new Graph which reflects that connection. Any Vertices -// referenced within the HalfEdge which do not yet exist in the Graph will also +// referenced within toe OpenEdge which do not yet exist in the Graph will also // be created in this step. -func (g *Graph) AddValueIn(he HalfEdge, val Identifier) *Graph { +func (g *Graph) AddValueIn(oe OpenEdge, val Identifier) *Graph { to := vertex{ VertexType: Value, val: val, @@ -214,12 +212,12 @@ func (g *Graph) AddValueIn(he HalfEdge, val Identifier) *Graph { } // if the incoming edge already exists in to then there's nothing to do - if to.hasHalfEdge(he) { + if to.hasOpenEdge(oe) { return g } to = to.cp() - to.in = append(to.in, he) + to.in = append(to.in, oe) g = g.cp() // starting with to (which we always overwrite) go through vM and @@ -246,12 +244,12 @@ func (g *Graph) AddValueIn(he HalfEdge, val Identifier) *Graph { return g } -// DelValueIn takes a HalfEdge and disconnects it from the Value Vertex +// DelValueIn takes a OpenEdge and disconnects it from the Value Vertex // containing val, returning the new Graph which reflects the disconnection. If // the Value Vertex doesn't exist within the graph, or it doesn't have the given -// HalfEdge, no changes are made. Any vertices referenced by the HalfEdge for +// OpenEdge, no changes are made. Any vertices referenced by toe OpenEdge for // which that edge is their only outgoing edge will be removed from the Graph. -func (g *Graph) DelValueIn(he HalfEdge, val Identifier) *Graph { +func (g *Graph) DelValueIn(oe OpenEdge, val Identifier) *Graph { to := vertex{ VertexType: Value, val: val, @@ -266,7 +264,7 @@ func (g *Graph) DelValueIn(he HalfEdge, val Identifier) *Graph { // get new copy of to without the half-edge, or return if the half-edge // wasn't even in to - to, ok = to.cpAndDelHalfEdge(he) + to, ok = to.cpAndDelOpenEdge(oe) if !ok { return g } @@ -309,19 +307,19 @@ func (g *Graph) DelValueIn(he HalfEdge, val Identifier) *Graph { delete(g.vM, toID) } - // rmOrphaned descends down the given HalfEdge and removes any Value + // rmOrphaned descends down the given OpenEdge and removes any Value // Vertices referenced in it which are now orphaned - var rmOrphaned func(HalfEdge) - rmOrphaned = func(he HalfEdge) { - if he.fromV.VertexType == Value && isOrphaned(he.fromV) { - delete(g.vM, identify(he.fromV)) - } else if he.fromV.VertexType == Junction { - for _, juncHe := range he.fromV.in { + var rmOrphaned func(OpenEdge) + rmOrphaned = func(oe OpenEdge) { + if oe.fromV.VertexType == Value && isOrphaned(oe.fromV) { + delete(g.vM, identify(oe.fromV)) + } else if oe.fromV.VertexType == Junction { + for _, juncHe := range oe.fromV.in { rmOrphaned(juncHe) } } } - rmOrphaned(he) + rmOrphaned(oe) return g } @@ -337,7 +335,7 @@ func (g *Graph) Union(g2 *Graph) *Graph { v = v2 } else { for _, v2e := range v2.in { - if !v.hasHalfEdge(v2e) { + if !v.hasOpenEdge(v2e) { v.in = append(v.in, v2e) } } @@ -432,7 +430,7 @@ func Equal(g1, g2 *Graph) bool { return false } for _, in := range v1.in { - if !v2.hasHalfEdge(in) { + if !v2.hasOpenEdge(in) { return false } } diff --git a/gg/gg_test.go b/gg/gg_test.go index 9f8a51d..8ca7012 100644 --- a/gg/gg_test.go +++ b/gg/gg_test.go @@ -156,7 +156,7 @@ func TestGraph(t *T) { func() *Graph { e0 := ValueOut(id("v0"), id("e0")) e1 := ValueOut(id("v1"), id("e1")) - ej0 := JunctionOut([]HalfEdge{e0, e1}, id("ej0")) + ej0 := JunctionOut([]OpenEdge{e0, e1}, id("ej0")) return Null.AddValueIn(ej0, id("v2")) }, value("v0"), value("v1"), @@ -171,11 +171,11 @@ func TestGraph(t *T) { func() *Graph { e00 := ValueOut(id("v0"), id("e00")) e10 := ValueOut(id("v1"), id("e10")) - ej0 := JunctionOut([]HalfEdge{e00, e10}, id("ej0")) + ej0 := JunctionOut([]OpenEdge{e00, e10}, id("ej0")) e01 := ValueOut(id("v0"), id("e01")) e11 := ValueOut(id("v1"), id("e11")) - ej1 := JunctionOut([]HalfEdge{e01, e11}, id("ej1")) - ej2 := JunctionOut([]HalfEdge{ej0, ej1}, id("ej2")) + ej1 := JunctionOut([]OpenEdge{e01, e11}, id("ej1")) + ej2 := JunctionOut([]OpenEdge{ej0, ej1}, id("ej2")) return Null.AddValueIn(ej2, id("v2")) }, value("v0"), value("v1"), @@ -196,7 +196,7 @@ func TestGraph(t *T) { func() *Graph { e0 := ValueOut(id("v0"), id("e0")) e1 := ValueOut(id("v1"), id("e1")) - ej0 := JunctionOut([]HalfEdge{e0, e1}, id("ej0")) + ej0 := JunctionOut([]OpenEdge{e0, e1}, id("ej0")) g0 := Null.AddValueIn(ej0, id("v2")) e20 := ValueOut(id("v2"), id("e20")) g1 := g0.AddValueIn(e20, id("v0")) @@ -275,27 +275,27 @@ func TestGraphDelValueIn(t *T) { } { // removing only edge - he := ValueOut(id("v0"), id("e0")) - g0 := Null.AddValueIn(he, id("v1")) - g1 := g0.DelValueIn(he, id("v1")) + oe := ValueOut(id("v0"), id("e0")) + g0 := Null.AddValueIn(oe, id("v1")) + g1 := g0.DelValueIn(oe, id("v1")) assert.True(t, Equal(Null, g1)) } { // removing only edge (junction) - he := JunctionOut([]HalfEdge{ + oe := JunctionOut([]OpenEdge{ ValueOut(id("v0"), id("e0")), ValueOut(id("v1"), id("e1")), }, id("ej0")) - g0 := Null.AddValueIn(he, id("v2")) - g1 := g0.DelValueIn(he, id("v2")) + g0 := Null.AddValueIn(oe, id("v2")) + g1 := g0.DelValueIn(oe, id("v2")) assert.True(t, Equal(Null, g1)) } { // removing one of two edges - he := ValueOut(id("v1"), id("e0")) + oe := ValueOut(id("v1"), id("e0")) g0 := Null.AddValueIn(ValueOut(id("v0"), id("e0")), id("v2")) - g1 := g0.AddValueIn(he, id("v2")) - g2 := g1.DelValueIn(he, id("v2")) + g1 := g0.AddValueIn(oe, id("v2")) + g2 := g1.DelValueIn(oe, id("v2")) assert.True(t, Equal(g0, g2)) assert.NotNil(t, g2.Value(id("v0"))) assert.Nil(t, g2.Value(id("v1"))) @@ -306,11 +306,11 @@ func TestGraphDelValueIn(t *T) { e0 := ValueOut(id("v0"), id("e0")) e1 := ValueOut(id("v1"), id("e1")) e2 := ValueOut(id("v2"), id("e2")) - heA := JunctionOut([]HalfEdge{e0, e1}, id("heA")) - heB := JunctionOut([]HalfEdge{e1, e2}, id("heB")) - g0a := Null.AddValueIn(heA, id("v3")) - g0b := Null.AddValueIn(heB, id("v3")) - g1 := g0a.Union(g0b).DelValueIn(heA, id("v3")) + oeA := JunctionOut([]OpenEdge{e0, e1}, id("oeA")) + oeB := JunctionOut([]OpenEdge{e1, e2}, id("oeB")) + g0a := Null.AddValueIn(oeA, id("v3")) + g0b := Null.AddValueIn(oeB, id("v3")) + g1 := g0a.Union(g0b).DelValueIn(oeA, id("v3")) assert.True(t, Equal(g1, g0b)) assert.Nil(t, g1.Value(id("v0"))) assert.NotNil(t, g1.Value(id("v1"))) @@ -329,7 +329,7 @@ func TestGraphDelValueIn(t *T) { } { // removing to's only edge, sub-nodes have edge to each other - ej := JunctionOut([]HalfEdge{ + ej := JunctionOut([]OpenEdge{ ValueOut(id("v0"), id("ej0")), ValueOut(id("v1"), id("ej0")), }, id("ej")) @@ -370,11 +370,11 @@ func TestGraphUnion(t *T) { } { // Two disparate graphs with junctions - ga := Null.AddValueIn(JunctionOut([]HalfEdge{ + ga := Null.AddValueIn(JunctionOut([]OpenEdge{ ValueOut(id("va0"), id("ea0")), ValueOut(id("va1"), id("ea1")), }, id("eaj")), id("va2")) - gb := Null.AddValueIn(JunctionOut([]HalfEdge{ + gb := Null.AddValueIn(JunctionOut([]OpenEdge{ ValueOut(id("vb0"), id("eb0")), ValueOut(id("vb1"), id("eb1")), }, id("ebj")), id("vb2")) @@ -413,11 +413,11 @@ func TestGraphUnion(t *T) { } { // two partially overlapping graphs with junctions - g0 := Null.AddValueIn(JunctionOut([]HalfEdge{ + g0 := Null.AddValueIn(JunctionOut([]OpenEdge{ ValueOut(id("v0"), id("e0")), ValueOut(id("v1"), id("e1")), }, id("ej0")), id("v2")) - g1 := Null.AddValueIn(JunctionOut([]HalfEdge{ + g1 := Null.AddValueIn(JunctionOut([]OpenEdge{ ValueOut(id("v0"), id("e0")), ValueOut(id("v1"), id("e1")), }, id("ej1")), id("v2")) @@ -444,7 +444,7 @@ func TestGraphUnion(t *T) { } { // Two equal graphs with junctions - g0 := Null.AddValueIn(JunctionOut([]HalfEdge{ + g0 := Null.AddValueIn(JunctionOut([]OpenEdge{ ValueOut(id("v0"), id("e0")), ValueOut(id("v1"), id("e1")), }, id("ej0")), id("v2")) @@ -500,8 +500,8 @@ func TestGraphEqual(t *T) { { // junction basic test e0 := ValueOut(id("v0"), id("e0")) e1 := ValueOut(id("v1"), id("e1")) - ga := Null.AddValueIn(JunctionOut([]HalfEdge{e0, e1}, id("ej")), id("v2")) - gb := Null.AddValueIn(JunctionOut([]HalfEdge{e1, e0}, id("ej")), id("v2")) + ga := Null.AddValueIn(JunctionOut([]OpenEdge{e0, e1}, id("ej")), id("v2")) + gb := Null.AddValueIn(JunctionOut([]OpenEdge{e1, e0}, id("ej")), id("v2")) assertEqual(ga, ga) assertNotEqual(ga, gb) }