graph: implement SubGraph and Equal

This commit is contained in:
Brian Picciano 2018-08-18 13:51:38 -04:00
parent 91c0629377
commit c1bdb46623
2 changed files with 93 additions and 13 deletions

View File

@ -204,3 +204,32 @@ func (g Graph) Traverse(start Value, next func(v Value, in, out []Edge) (Value,
} }
} }
} }
func (g Graph) edgesShared(g2 Graph) bool {
for id := range g2.m {
if _, ok := g.m[id]; !ok {
return false
}
}
return true
}
// SubGraph returns true if the given Graph shares all of its Edges with this
// Graph.
func (g Graph) SubGraph(g2 Graph) bool {
// as a quick check before iterating through the edges, if g has fewer edges
// than g2 then g2 can't possibly be a sub-graph of it
if len(g.m) < len(g2.m) {
return false
}
return g.edgesShared(g2)
}
// Equal returns true if the given Graph and this Graph have exactly the same
// Edges.
func (g Graph) Equal(g2 Graph) bool {
if len(g.m) != len(g2.m) {
return false
}
return g.edgesShared(g2)
}

View File

@ -1,6 +1,7 @@
package graph package graph
import ( import (
"fmt"
. "testing" . "testing"
"time" "time"
@ -9,7 +10,12 @@ import (
"github.com/mediocregopher/mediocre-go-lib/mtest/mchk" "github.com/mediocregopher/mediocre-go-lib/mtest/mchk"
) )
func strV(s string) Value {
return Value{ID: s, V: s}
}
func TestGraph(t *T) { func TestGraph(t *T) {
t.Parallel()
type state struct { type state struct {
Graph Graph
@ -21,10 +27,6 @@ func TestGraph(t *T) {
del Edge del Edge
} }
strV := func(s string) Value {
return Value{ID: s, V: s}
}
chk := mchk.Checker{ chk := mchk.Checker{
Init: func() mchk.State { Init: func() mchk.State {
return state{ return state{
@ -118,15 +120,64 @@ func TestGraph(t *T) {
return s, nil return s, nil
}, },
MaxLength: 10, }
}
if err := chk.RunFor(5 * time.Second); err != nil {
err := chk.RunCase( t.Fatal(err)
params{add: Edge{Tail: strV("4"), Val: strV("d"), Head: strV("4")}}, }
params{del: Edge{Tail: strV("4"), Val: strV("d"), Head: strV("4")}}, }
)
if err != nil { func TestSubGraphAndEqual(t *T) {
t.Fatal(err) t.Parallel()
type state struct {
g1, g2 Graph
expEqual, expSubGraph bool
}
type params struct {
e Edge
add1, add2 bool
}
chk := mchk.Checker{
Init: func() mchk.State {
return state{expEqual: true, expSubGraph: true}
},
Next: func(ss mchk.State) mchk.Action {
i := mrand.Intn(10)
p := params{
e: Edge{
Tail: strV(mrand.Hex(1)),
Val: strV(mrand.Hex(8)),
Head: strV(mrand.Hex(1)),
},
add1: i != 0,
add2: i != 1,
}
return mchk.Action{Params: p}
},
Apply: func(ss mchk.State, a mchk.Action) (mchk.State, error) {
s, p := ss.(state), a.Params.(params)
if p.add1 {
s.g1 = s.g1.AddEdge(p.e)
}
if p.add2 {
s.g2 = s.g2.AddEdge(p.e)
}
s.expSubGraph = s.expSubGraph && p.add1
s.expEqual = s.expEqual && p.add1 && p.add2
if s.g1.SubGraph(s.g2) != s.expSubGraph {
return nil, fmt.Errorf("SubGraph expected to return %v", s.expSubGraph)
}
if s.g1.Equal(s.g2) != s.expEqual {
return nil, fmt.Errorf("Equal expected to return %v", s.expEqual)
}
return s, nil
},
MaxLength: 100,
} }
if err := chk.RunFor(5 * time.Second); err != nil { if err := chk.RunFor(5 * time.Second); err != nil {