diff --git a/graph/graph.go b/graph/graph.go index a8c1589..22fd20b 100644 --- a/graph/graph.go +++ b/graph/graph.go @@ -16,23 +16,57 @@ type Value interface { // OpenEdge is an un-realized Edge which can't be used for anything except // constructing graphs. It has no meaning on its own. type OpenEdge[V Value] struct { - fromV vertex[V] + val *V + tup []OpenEdge[V] + edgeVal V } func (oe OpenEdge[V]) equal(oe2 OpenEdge[V]) bool { - return oe.edgeVal.Equal(oe2.edgeVal) && oe.fromV.equal(oe2.fromV) + if !oe.edgeVal.Equal(oe2.edgeVal) { + return false + } + + if oe.val != nil { + return oe2.val != nil && (*oe.val).Equal(*oe2.val) + } + + if len(oe.tup) != len(oe2.tup) { + return false + } + + for i := range oe.tup { + if !oe.tup[i].equal(oe2.tup[i]) { + return false + } + } + + return true } func (oe OpenEdge[V]) String() string { vertexType := "tup" - if oe.fromV.val != nil { + var fromStr string + + if oe.val != nil { + vertexType = "val" + fromStr = (*oe.val).String() + + } else { + + strs := make([]string, len(oe.tup)) + + for i := range oe.tup { + strs[i] = oe.tup[i].String() + } + + fromStr = fmt.Sprintf("[%s]", strings.Join(strs, ", ")) } - return fmt.Sprintf("%s(%s, %s)", vertexType, oe.fromV.String(), oe.edgeVal.String()) + return fmt.Sprintf("%s(%s, %s)", vertexType, fromStr, oe.edgeVal.String()) } // WithEdgeValue returns a copy of the OpenEdge with the given Value replacing @@ -52,29 +86,29 @@ func (oe OpenEdge[V]) EdgeValue() V { // FromValue returns the Value from which the OpenEdge was created via ValueOut, // or false if it wasn't created via ValueOut. func (oe OpenEdge[V]) FromValue() (V, bool) { - if oe.fromV.val == nil { + if oe.val == nil { var zero V return zero, false } - return *oe.fromV.val, true + return *oe.val, true } // FromTuple returns the tuple of OpenEdges from which the OpenEdge was created // via TupleOut, or false if it wasn't created via TupleOut. func (oe OpenEdge[V]) FromTuple() ([]OpenEdge[V], bool) { - if oe.fromV.val != nil { + if oe.val != nil { return nil, false } - return oe.fromV.tup, true + return oe.tup, true } // ValueOut creates a OpenEdge which, when used to construct a Graph, represents // an edge (with edgeVal attached to it) coming from the ValueVertex containing // val. func ValueOut[V Value](val, edgeVal V) OpenEdge[V] { - return OpenEdge[V]{fromV: vertex[V]{val: &val}, edgeVal: edgeVal} + return OpenEdge[V]{val: &val, edgeVal: edgeVal} } // TupleOut creates an OpenEdge which, when used to construct a Graph, @@ -102,51 +136,11 @@ func TupleOut[V Value](ins []OpenEdge[V], edgeVal V) OpenEdge[V] { } return OpenEdge[V]{ - fromV: vertex[V]{tup: ins}, + tup: ins, edgeVal: edgeVal, } } - -type vertex[V Value] struct { - val *V - tup []OpenEdge[V] -} - -func (v vertex[V]) equal(v2 vertex[V]) bool { - - if v.val != nil { - return v2.val != nil && (*v.val).Equal(*v2.val) - } - - if len(v.tup) != len(v2.tup) { - return false - } - - for i := range v.tup { - if !v.tup[i].equal(v2.tup[i]) { - return false - } - } - - return true -} - -func (v vertex[V]) String() string { - - if v.val != nil { - return (*v.val).String() - } - - strs := make([]string, len(v.tup)) - - for i := range v.tup { - strs[i] = v.tup[i].String() - } - - return fmt.Sprintf("[%s]", strings.Join(strs, ", ")) -} - type graphValueIn[V Value] struct { val V edges []OpenEdge[V]