diff --git a/gg/decoder.go b/gg/decoder.go index bdf574d..11635e7 100644 --- a/gg/decoder.go +++ b/gg/decoder.go @@ -9,6 +9,12 @@ import ( "github.com/mediocregopher/ginger/graph" ) +// Type aliases for convenience +type ( + Graph = graph.Graph[Value, Value] + OpenEdge = graph.OpenEdge[Value, Value] +) + // Punctuations which are used in the gg file format. const ( punctTerm = ";" @@ -90,7 +96,7 @@ func (d *decoder) parseSingleValue( func (d *decoder) parseOpenEdge( toks []LexerToken, ) ( - *graph.OpenEdge[Value], []LexerToken, error, + *OpenEdge, []LexerToken, error, ) { if isPunct(toks[0], punctOpenTuple) { @@ -137,7 +143,7 @@ func (d *decoder) parseOpenEdge( return nil, nil, err } - oe = graph.TupleOut[Value]([]*graph.OpenEdge[Value]{oe}, val) + oe = graph.TupleOut[Value]([]*OpenEdge{oe}, val) return oe, toks, nil } @@ -145,12 +151,12 @@ func (d *decoder) parseOpenEdge( func (d *decoder) parseTuple( toks []LexerToken, ) ( - *graph.OpenEdge[Value], []LexerToken, error, + *OpenEdge, []LexerToken, error, ) { openTok, toks := toks[0], toks[1:] - var edges []*graph.OpenEdge[Value] + var edges []*OpenEdge for { @@ -163,7 +169,7 @@ func (d *decoder) parseTuple( } var ( - oe *graph.OpenEdge[Value] + oe *OpenEdge err error ) @@ -203,7 +209,7 @@ func (d *decoder) parseGraphValue( openTok, toks = toks[0], toks[1:] } - g := new(graph.Graph[Value]) + g := new(Graph) for { @@ -254,7 +260,7 @@ func (d *decoder) parseGraphValue( return val, toks, termed, nil } -func (d *decoder) parseValIn(into *graph.Graph[Value], toks []LexerToken) (*graph.Graph[Value], []LexerToken, error) { +func (d *decoder) parseValIn(into *Graph, toks []LexerToken) (*Graph, []LexerToken, error) { if len(toks) == 0 { return into, nil, nil @@ -285,7 +291,7 @@ func (d *decoder) parseValIn(into *graph.Graph[Value], toks []LexerToken) (*grap return into.AddValueIn(oe, dstVal), toks, nil } -func (d *decoder) decode(lexer Lexer) (*graph.Graph[Value], error) { +func (d *decoder) decode(lexer Lexer) (*Graph, error) { var toks []LexerToken @@ -316,7 +322,7 @@ func (d *decoder) decode(lexer Lexer) (*graph.Graph[Value], error) { // construct a Graph according to the rules of the gg file format. DecodeLexer // will only return an error if there is a non-EOF file returned from the Lexer, // or the tokens read cannot be used to construct a valid Graph. -func DecodeLexer(lexer Lexer) (*graph.Graph[Value], error) { +func DecodeLexer(lexer Lexer) (*Graph, error) { decoder := &decoder{} return decoder.decode(lexer) } diff --git a/gg/decoder_test.go b/gg/decoder_test.go index a73a2ff..dcccb6b 100644 --- a/gg/decoder_test.go +++ b/gg/decoder_test.go @@ -11,7 +11,7 @@ import ( func TestDecoder(t *testing.T) { - zeroGraph := new(graph.Graph[Value]) + zeroGraph := new(Graph) i := func(i int64) Value { return Value{Number: &i} @@ -21,19 +21,17 @@ func TestDecoder(t *testing.T) { return Value{Name: &n} } - vOut := func(val, edgeVal Value) *graph.OpenEdge[Value] { + vOut := func(val, edgeVal Value) *OpenEdge { return graph.ValueOut(val, edgeVal) } - tOut := func(ins []*graph.OpenEdge[Value], edgeVal Value) *graph.OpenEdge[Value] { + tOut := func(ins []*OpenEdge, edgeVal Value) *OpenEdge { return graph.TupleOut(ins, edgeVal) } - type openEdge = *graph.OpenEdge[Value] - tests := []struct { in string - exp *graph.Graph[Value] + exp *Graph }{ { in: "", @@ -51,7 +49,7 @@ func TestDecoder(t *testing.T) { in: "out = a < b < 1;", exp: zeroGraph.AddValueIn( tOut( - []openEdge{vOut(i(1), n("b"))}, + []*OpenEdge{vOut(i(1), n("b"))}, n("a"), ), n("out"), @@ -61,12 +59,12 @@ func TestDecoder(t *testing.T) { in: "out = a < b < (1; c < 2; d < e < 3;);", exp: zeroGraph.AddValueIn( tOut( - []openEdge{tOut( - []openEdge{ + []*OpenEdge{tOut( + []*OpenEdge{ vOut(i(1), ZeroValue), vOut(i(2), n("c")), tOut( - []openEdge{vOut(i(3), n("e"))}, + []*OpenEdge{vOut(i(3), n("e"))}, n("d"), ), }, @@ -81,11 +79,11 @@ func TestDecoder(t *testing.T) { in: "out = a < b < (1; c < (d < 2; 3;); );", exp: zeroGraph.AddValueIn( tOut( - []openEdge{tOut( - []openEdge{ + []*OpenEdge{tOut( + []*OpenEdge{ vOut(i(1), ZeroValue), tOut( - []openEdge{ + []*OpenEdge{ vOut(i(2), n("d")), vOut(i(3), ZeroValue), }, @@ -107,7 +105,7 @@ func TestDecoder(t *testing.T) { AddValueIn(vOut(i(1), ZeroValue), n("a")). AddValueIn( tOut( - []openEdge{ + []*OpenEdge{ vOut(i(2), n("d")), }, n("c"), @@ -124,7 +122,7 @@ func TestDecoder(t *testing.T) { in: "out = a < { b = 1; } < 2;", exp: zeroGraph.AddValueIn( tOut( - []openEdge{ + []*OpenEdge{ vOut( i(2), Value{Graph: zeroGraph. diff --git a/gg/gg.go b/gg/gg.go index 5b1c35a..eb21cf1 100644 --- a/gg/gg.go +++ b/gg/gg.go @@ -16,7 +16,7 @@ type Value struct { // Only one of these fields may be set Name *string Number *int64 - Graph *graph.Graph[Value] + Graph *Graph // TODO coming soon! // String *string diff --git a/graph/graph.go b/graph/graph.go index 34c95f6..57c57bf 100644 --- a/graph/graph.go +++ b/graph/graph.go @@ -15,16 +15,18 @@ type Value interface { String() string } -// 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 { +// OpenEdge consists of the edge value (E) and source vertex value (V) of an +// edge in a Graph. When passed into the AddValueIn method a full edge is +// created. An OpenEdge can also be sourced from a tuple vertex, whose value is +// an ordered set of OpenEdges of this same type. +type OpenEdge[E, V Value] struct { val *V - tup []*OpenEdge[V] + tup []*OpenEdge[E, V] - edgeVal V + edgeVal E } -func (oe *OpenEdge[V]) equal(oe2 *OpenEdge[V]) bool { +func (oe *OpenEdge[E, V]) equal(oe2 *OpenEdge[E, V]) bool { if !oe.edgeVal.Equal(oe2.edgeVal) { return false } @@ -46,7 +48,7 @@ func (oe *OpenEdge[V]) equal(oe2 *OpenEdge[V]) bool { return true } -func (oe *OpenEdge[V]) String() string { +func (oe *OpenEdge[E, V]) String() string { vertexType := "tup" @@ -75,20 +77,20 @@ func (oe *OpenEdge[V]) String() string { // the previous edge value. // // NOTE I _think_ this can be factored out once Graph is genericized. -func (oe *OpenEdge[V]) WithEdgeValue(val V) *OpenEdge[V] { +func (oe *OpenEdge[E, V]) WithEdgeValue(val E) *OpenEdge[E, V] { oeCp := *oe oeCp.edgeVal = val return &oeCp } // EdgeValue returns the Value which lies on the edge itself. -func (oe OpenEdge[V]) EdgeValue() V { +func (oe OpenEdge[E, V]) EdgeValue() E { return oe.edgeVal } // 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) { +func (oe OpenEdge[E, V]) FromValue() (V, bool) { if oe.val == nil { var zero V return zero, false @@ -99,7 +101,7 @@ func (oe OpenEdge[V]) FromValue() (V, bool) { // 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) { +func (oe OpenEdge[E, V]) FromTuple() ([]*OpenEdge[E, V], bool) { if oe.val != nil { return nil, false } @@ -109,8 +111,8 @@ func (oe OpenEdge[V]) FromTuple() ([]*OpenEdge[V], bool) { // ValueOut creates a OpenEdge which, when used to construct a Graph, represents // an edge (with edgeVal attached to it) coming from the vertex containing val. -func ValueOut[V Value](val, edgeVal V) *OpenEdge[V] { - return &OpenEdge[V]{ +func ValueOut[E, V Value](val V, edgeVal E) *OpenEdge[E, V] { + return &OpenEdge[E, V]{ val: &val, edgeVal: edgeVal, } @@ -119,7 +121,7 @@ func ValueOut[V Value](val, edgeVal V) *OpenEdge[V] { // TupleOut creates an OpenEdge which, when used to construct a Graph, // represents an edge (with edgeVal attached to it) coming from the vertex // comprised of the given ordered-set of input edges. -func TupleOut[V Value](ins []*OpenEdge[V], edgeVal V) *OpenEdge[V] { +func TupleOut[E, V Value](ins []*OpenEdge[E, V], edgeVal E) *OpenEdge[E, V] { if len(ins) == 1 { @@ -138,44 +140,44 @@ func TupleOut[V Value](ins []*OpenEdge[V], edgeVal V) *OpenEdge[V] { } - return &OpenEdge[V]{ + return &OpenEdge[E, V]{ tup: ins, edgeVal: edgeVal, } } -type graphValueIn[V Value] struct { +type graphValueIn[E, V Value] struct { val V - edge *OpenEdge[V] + edge *OpenEdge[E, V] } -func (valIn graphValueIn[V]) equal(valIn2 graphValueIn[V]) bool { +func (valIn graphValueIn[E, V]) equal(valIn2 graphValueIn[E, V]) bool { return valIn.val.Equal(valIn2.val) && valIn.edge.equal(valIn2.edge) } // Graph is an immutable container of a set of vertices. The Graph keeps track -// of all Values which terminate an OpenEdge (which may be a tree of Value/Tuple -// vertices). +// of all Values which terminate an OpenEdge. E indicates the type of edge +// values, while V indicates the type of vertex values. // // NOTE The current implementation of Graph is incredibly inefficient, there's // lots of O(N) operations, unnecessary copying on changes, and duplicate data // in memory. -type Graph[V Value] struct { - edges []*OpenEdge[V] - valIns []graphValueIn[V] +type Graph[E, V Value] struct { + edges []*OpenEdge[E, V] + valIns []graphValueIn[E, V] } -func (g *Graph[V]) cp() *Graph[V] { - cp := &Graph[V]{ - edges: make([]*OpenEdge[V], len(g.edges)), - valIns: make([]graphValueIn[V], len(g.valIns)), +func (g *Graph[E, V]) cp() *Graph[E, V] { + cp := &Graph[E, V]{ + edges: make([]*OpenEdge[E, V], len(g.edges)), + valIns: make([]graphValueIn[E, V], len(g.valIns)), } copy(cp.edges, g.edges) copy(cp.valIns, g.valIns) return cp } -func (g *Graph[V]) String() string { +func (g *Graph[E, V]) String() string { var strs []string @@ -192,7 +194,7 @@ func (g *Graph[V]) String() string { // NOTE this method is used more for its functionality than for any performance // reasons... it's incredibly inefficient in how it deduplicates edges, but by // doing the deduplication we enable the graph map operation to work correctly. -func (g *Graph[V]) dedupeEdge(edge *OpenEdge[V]) *OpenEdge[V] { +func (g *Graph[E, V]) dedupeEdge(edge *OpenEdge[E, V]) *OpenEdge[E, V] { // check if there's an existing edge which is fully equivalent in the graph // already, and if so return that. @@ -210,7 +212,7 @@ func (g *Graph[V]) dedupeEdge(edge *OpenEdge[V]) *OpenEdge[V] { // this edge is a tuple edge, it's possible that one of its sub-edges is // already in the graph. dedupe each sub-edge individually. - tupEdges := make([]*OpenEdge[V], len(edge.tup)) + tupEdges := make([]*OpenEdge[E, V], len(edge.tup)) for i := range edge.tup { tupEdges[i] = g.dedupeEdge(edge.tup[i]) @@ -223,9 +225,9 @@ func (g *Graph[V]) dedupeEdge(edge *OpenEdge[V]) *OpenEdge[V] { // Graph (ie, all those added via AddValueIn). // // The returned slice should not be modified. -func (g *Graph[V]) ValueIns(val Value) []*OpenEdge[V] { +func (g *Graph[E, V]) ValueIns(val Value) []*OpenEdge[E, V] { - var edges []*OpenEdge[V] + var edges []*OpenEdge[E, V] for _, valIn := range g.valIns { if valIn.val.Equal(val) { @@ -238,9 +240,9 @@ func (g *Graph[V]) ValueIns(val Value) []*OpenEdge[V] { // AddValueIn takes a OpenEdge and connects it to the Value vertex containing // val, returning the new Graph which reflects that connection. -func (g *Graph[V]) AddValueIn(oe *OpenEdge[V], val V) *Graph[V] { +func (g *Graph[E, V]) AddValueIn(oe *OpenEdge[E, V], val V) *Graph[E, V] { - valIn := graphValueIn[V]{ + valIn := graphValueIn[E, V]{ val: val, edge: oe, } @@ -260,7 +262,7 @@ func (g *Graph[V]) AddValueIn(oe *OpenEdge[V], val V) *Graph[V] { } // Equal returns whether or not the two Graphs are equivalent in value. -func (g *Graph[V]) Equal(g2 *Graph[V]) bool { +func (g *Graph[E, V]) Equal(g2 *Graph[E, V]) bool { if len(g.valIns) != len(g2.valIns) { return false diff --git a/graph/graph_test.go b/graph/graph_test.go index a5d09f3..fbc9c49 100644 --- a/graph/graph_test.go +++ b/graph/graph_test.go @@ -17,11 +17,11 @@ func TestEqual(t *testing.T) { var ( zeroValue S - zeroGraph = new(Graph[S]) + zeroGraph = new(Graph[S, S]) ) tests := []struct { - a, b *Graph[S] + a, b *Graph[S, S] exp bool }{ { @@ -31,78 +31,78 @@ func TestEqual(t *testing.T) { }, { a: zeroGraph, - b: zeroGraph.AddValueIn(ValueOut[S]("in", "incr"), "out"), + b: zeroGraph.AddValueIn(ValueOut[S, S]("in", "incr"), "out"), exp: false, }, { - a: zeroGraph.AddValueIn(ValueOut[S]("in", "incr"), "out"), - b: zeroGraph.AddValueIn(ValueOut[S]("in", "incr"), "out"), + a: zeroGraph.AddValueIn(ValueOut[S, S]("in", "incr"), "out"), + b: zeroGraph.AddValueIn(ValueOut[S, S]("in", "incr"), "out"), exp: true, }, { - a: zeroGraph.AddValueIn(ValueOut[S]("in", "incr"), "out"), - b: zeroGraph.AddValueIn(TupleOut[S]([]*OpenEdge[S]{ - ValueOut[S]("in", "ident"), - ValueOut[S]("1", "ident"), + a: zeroGraph.AddValueIn(ValueOut[S, S]("in", "incr"), "out"), + b: zeroGraph.AddValueIn(TupleOut[S, S]([]*OpenEdge[S, S]{ + ValueOut[S, S]("in", "ident"), + ValueOut[S, S]("1", "ident"), }, "add"), "out"), exp: false, }, { // tuples are different order - a: zeroGraph.AddValueIn(TupleOut[S]([]*OpenEdge[S]{ - ValueOut[S]("1", "ident"), - ValueOut[S]("in", "ident"), + a: zeroGraph.AddValueIn(TupleOut[S, S]([]*OpenEdge[S, S]{ + ValueOut[S, S]("1", "ident"), + ValueOut[S, S]("in", "ident"), }, "add"), "out"), - b: zeroGraph.AddValueIn(TupleOut[S]([]*OpenEdge[S]{ - ValueOut[S]("in", "ident"), - ValueOut[S]("1", "ident"), + b: zeroGraph.AddValueIn(TupleOut[S, S]([]*OpenEdge[S, S]{ + ValueOut[S, S]("in", "ident"), + ValueOut[S, S]("1", "ident"), }, "add"), "out"), exp: false, }, { // tuple with no edge value and just a single input edge should be // equivalent to just that edge. - a: zeroGraph.AddValueIn(TupleOut[S]([]*OpenEdge[S]{ - ValueOut[S]("1", "ident"), + a: zeroGraph.AddValueIn(TupleOut[S, S]([]*OpenEdge[S, S]{ + ValueOut[S, S]("1", "ident"), }, zeroValue), "out"), - b: zeroGraph.AddValueIn(ValueOut[S]("1", "ident"), "out"), + b: zeroGraph.AddValueIn(ValueOut[S, S]("1", "ident"), "out"), exp: true, }, { // tuple with an edge value and just a single input edge that has no // edgeVal should be equivalent to just that edge with the tuple's // edge value. - a: zeroGraph.AddValueIn(TupleOut[S]([]*OpenEdge[S]{ - ValueOut[S]("1", zeroValue), + a: zeroGraph.AddValueIn(TupleOut[S, S]([]*OpenEdge[S, S]{ + ValueOut[S, S]("1", zeroValue), }, "ident"), "out"), - b: zeroGraph.AddValueIn(ValueOut[S]("1", "ident"), "out"), + b: zeroGraph.AddValueIn(ValueOut[S, S]("1", "ident"), "out"), exp: true, }, { a: zeroGraph. - AddValueIn(ValueOut[S]("in", "incr"), "out"). - AddValueIn(ValueOut[S]("in2", "incr2"), "out2"), + AddValueIn(ValueOut[S, S]("in", "incr"), "out"). + AddValueIn(ValueOut[S, S]("in2", "incr2"), "out2"), b: zeroGraph. - AddValueIn(ValueOut[S]("in", "incr"), "out"), + AddValueIn(ValueOut[S, S]("in", "incr"), "out"), exp: false, }, { a: zeroGraph. - AddValueIn(ValueOut[S]("in", "incr"), "out"). - AddValueIn(ValueOut[S]("in2", "incr2"), "out2"), + AddValueIn(ValueOut[S, S]("in", "incr"), "out"). + AddValueIn(ValueOut[S, S]("in2", "incr2"), "out2"), b: zeroGraph. - AddValueIn(ValueOut[S]("in", "incr"), "out"). - AddValueIn(ValueOut[S]("in2", "incr2"), "out2"), + AddValueIn(ValueOut[S, S]("in", "incr"), "out"). + AddValueIn(ValueOut[S, S]("in2", "incr2"), "out2"), exp: true, }, { // order of value ins shouldn't matter a: zeroGraph. - AddValueIn(ValueOut[S]("in", "incr"), "out"). - AddValueIn(ValueOut[S]("in2", "incr2"), "out2"), + AddValueIn(ValueOut[S, S]("in", "incr"), "out"). + AddValueIn(ValueOut[S, S]("in2", "incr2"), "out2"), b: zeroGraph. - AddValueIn(ValueOut[S]("in2", "incr2"), "out2"). - AddValueIn(ValueOut[S]("in", "incr"), "out"), + AddValueIn(ValueOut[S, S]("in2", "incr2"), "out2"). + AddValueIn(ValueOut[S, S]("in", "incr"), "out"), exp: true, }, } diff --git a/vm/op.go b/vm/op.go index ec3401c..f9224f6 100644 --- a/vm/op.go +++ b/vm/op.go @@ -17,12 +17,12 @@ var ( // The Scope passed into Perform can be used to Evaluate the OpenEdge, as // needed. type Operation interface { - Perform(*graph.OpenEdge[gg.Value], Scope) (Value, error) + Perform(*gg.OpenEdge, Scope) (Value, error) } func preEvalValOp(fn func(Value) (Value, error)) Operation { - return OperationFunc(func(edge *graph.OpenEdge[gg.Value], scope Scope) (Value, error) { + return OperationFunc(func(edge *gg.OpenEdge, scope Scope) (Value, error) { edgeVal, err := EvaluateEdge(edge, scope) @@ -36,20 +36,20 @@ func preEvalValOp(fn func(Value) (Value, error)) Operation { // NOTE this is a giant hack to get around the fact that we're not yet // using a genericized Graph implementation, so when we do AddValueIn -// on a graph.Graph[gg.Value] we can't use a Tuple value (because gg has no Tuple +// on a gg.Graph we can't use a Tuple value (because gg has no Tuple // value), we have to use a Tuple vertex instead. // // This also doesn't yet support passing an operation as a value to another // operation. -func preEvalEdgeOp(fn func(*graph.OpenEdge[gg.Value]) (Value, error)) Operation { +func preEvalEdgeOp(fn func(*gg.OpenEdge) (Value, error)) Operation { return preEvalValOp(func(val Value) (Value, error) { - var edge *graph.OpenEdge[gg.Value] + var edge *gg.OpenEdge if len(val.Tuple) > 0 { - tupEdges := make([]*graph.OpenEdge[gg.Value], len(val.Tuple)) + tupEdges := make([]*gg.OpenEdge, len(val.Tuple)) for i := range val.Tuple { tupEdges[i] = graph.ValueOut[gg.Value](val.Tuple[i].Value, gg.ZeroValue) @@ -69,7 +69,7 @@ func preEvalEdgeOp(fn func(*graph.OpenEdge[gg.Value]) (Value, error)) Operation } type graphOp struct { - *graph.Graph[gg.Value] + *gg.Graph scope Scope } @@ -80,16 +80,16 @@ type graphOp struct { // of the given Graph, then that resultant graph and the given parent Scope are // used to construct a new Scope. The "out" name value is Evaluated on that // Scope to obtain a resultant Value. -func OperationFromGraph(g *graph.Graph[gg.Value], scope Scope) Operation { +func OperationFromGraph(g *gg.Graph, scope Scope) Operation { return &graphOp{ Graph: g, scope: scope, } } -func (g *graphOp) Perform(edge *graph.OpenEdge[gg.Value], scope Scope) (Value, error) { +func (g *graphOp) Perform(edge *gg.OpenEdge, scope Scope) (Value, error) { - return preEvalEdgeOp(func(edge *graph.OpenEdge[gg.Value]) (Value, error) { + return preEvalEdgeOp(func(edge *gg.OpenEdge) (Value, error) { scope = ScopeFromGraph( g.Graph.AddValueIn(edge, inVal.Value), @@ -103,9 +103,9 @@ func (g *graphOp) Perform(edge *graph.OpenEdge[gg.Value], scope Scope) (Value, e } // OperationFunc is a function which implements the Operation interface. -type OperationFunc func(*graph.OpenEdge[gg.Value], Scope) (Value, error) +type OperationFunc func(*gg.OpenEdge, Scope) (Value, error) // Perform calls the underlying OperationFunc directly. -func (f OperationFunc) Perform(edge *graph.OpenEdge[gg.Value], scope Scope) (Value, error) { +func (f OperationFunc) Perform(edge *gg.OpenEdge, scope Scope) (Value, error) { return f(edge, scope) } diff --git a/vm/scope.go b/vm/scope.go index dbe1949..fe23bc1 100644 --- a/vm/scope.go +++ b/vm/scope.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/mediocregopher/ginger/gg" - "github.com/mediocregopher/ginger/graph" ) // Scope encapsulates a set of names and the values they indicate, or the means @@ -23,7 +22,7 @@ type Scope interface { // edgeToValue ignores the edgeValue, it only evaluates the edge's vertex as a // Value. -func edgeToValue(edge *graph.OpenEdge[gg.Value], scope Scope) (Value, error) { +func edgeToValue(edge *gg.OpenEdge, scope Scope) (Value, error) { if ggVal, ok := edge.FromValue(); ok { @@ -61,7 +60,7 @@ func edgeToValue(edge *graph.OpenEdge[gg.Value], scope Scope) (Value, error) { // EvaluateEdge will use the given Scope to evaluate the edge's ultimate Value, // after passing all leaf vertices up the tree through all Operations found on // edge values. -func EvaluateEdge(edge *graph.OpenEdge[gg.Value], scope Scope) (Value, error) { +func EvaluateEdge(edge *gg.OpenEdge, scope Scope) (Value, error) { edgeVal := Value{Value: edge.EdgeValue()} @@ -122,7 +121,7 @@ func (m ScopeMap) NewScope() Scope { } type graphScope struct { - *graph.Graph[gg.Value] + *gg.Graph parent Scope } @@ -139,7 +138,7 @@ type graphScope struct { // // NewScope will return the parent scope, if one is given, or an empty ScopeMap // if not. -func ScopeFromGraph(g *graph.Graph[gg.Value], parent Scope) Scope { +func ScopeFromGraph(g *gg.Graph, parent Scope) Scope { return &graphScope{ Graph: g, parent: parent,