Skip to content

Commit

Permalink
internal/core/adt: unexport Unify
Browse files Browse the repository at this point in the history
We are moving away from using states.
Replace Unify with alternative methods.

The CompleteArcs method has been introduced to
deal with the case where only the arc set needs
to be known, not a full evaluation.

The unify calls have also been updated for code
internal to adt if this code is expected to be
sharable with the new evaluator.

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: I9f3143dda4c04e556473e4487c85e65e1dfddba1
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/551408
Reviewed-by: Aram Hăvărneanu <aram@cue.works>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
  • Loading branch information
mpvl committed Mar 24, 2023
1 parent dbf7bb8 commit 7851142
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 37 deletions.
4 changes: 2 additions & 2 deletions cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2368,8 +2368,8 @@ func (v Value) Expr() (Op, []Value) {
b.AddConjunct(adt.MakeRootConjunct(env, disjunct.Val))

ctx := eval.NewContext(v.idx, nil)
ctx.Unify(&a, adt.Finalized)
ctx.Unify(&b, adt.Finalized)
a.Finalize(ctx)
b.Finalize(ctx)
if allowed(ctx, v.v, &b) != nil {
// Everything subsumed bottom
continue outerExpr
Expand Down
4 changes: 2 additions & 2 deletions internal/core/adt/binop.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func BinOp(c *OpContext, op Op, left, right Value) Value {

n := &Vertex{}
n.AddConjunct(MakeConjunct(c.Env(0), list, c.ci))
c.Unify(n, Conjuncts)
n.CompleteArcs(c)

return n
}
Expand Down Expand Up @@ -269,7 +269,7 @@ func BinOp(c *OpContext, op Op, left, right Value) Value {

n := &Vertex{}
n.AddConjunct(MakeConjunct(c.Env(0), list, c.ci))
c.Unify(n, Conjuncts)
n.CompleteArcs(c)

return n
}
Expand Down
11 changes: 8 additions & 3 deletions internal/core/adt/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func (v *Vertex) IsDefined(c *OpContext) bool {
if v.isDefined() {
return true
}
c.Unify(v, Finalized)
v.Finalize(c)
return v.isDefined()
}

Expand Down Expand Up @@ -566,7 +566,7 @@ func (v *Vertex) IsErr() bool {
}

func (v *Vertex) Err(c *OpContext, state VertexStatus) *Bottom {
c.Unify(v, state)
c.unify(v, state)
if b, ok := v.BaseValue.(*Bottom); ok {
return b
}
Expand All @@ -580,10 +580,15 @@ func (v *Vertex) Finalize(c *OpContext) {
// case the caller did not handle existing errors in the context.
err := c.errs
c.errs = nil
c.Unify(v, Finalized)
c.unify(v, Finalized)
c.errs = err
}

// CompleteArcs ensures the set of arcs has been computed.
func (v *Vertex) CompleteArcs(c *OpContext) {
c.unify(v, Conjuncts)
}

func (v *Vertex) AddErr(ctx *OpContext, b *Bottom) {
v.SetValue(ctx, Finalized, CombineErrors(nil, v.Value(), b))
}
Expand Down
10 changes: 5 additions & 5 deletions internal/core/adt/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ func (c *OpContext) Env(upCount int32) *Environment {

func (c *OpContext) relNode(upCount int32) *Vertex {
e := c.e.up(upCount)
c.Unify(e.Vertex, Partial)
c.unify(e.Vertex, Partial)
return e.Vertex
}

Expand Down Expand Up @@ -779,7 +779,7 @@ func (c *OpContext) unifyNode(v Expr, state VertexStatus) (result Value) {
}

if v.isUndefined() || state > v.status {
c.Unify(v, state)
c.unify(v, state)
}

return v
Expand Down Expand Up @@ -859,9 +859,9 @@ func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, state VertexStat
// hasAllConjuncts, but that are finalized too early, get conjuncts
// processed beforehand.
if state > a.status {
c.Unify(a, state)
c.unify(a, state)
} else if a.state != nil {
c.Unify(a, Partial)
c.unify(a, Partial)
}

if a.IsConstraint() {
Expand Down Expand Up @@ -1329,6 +1329,6 @@ func (c *OpContext) NewList(values ...Value) *Vertex {
for _, x := range values {
list.Elems = append(list.Elems, x)
}
c.Unify(v, Finalized)
v.Finalize(c)
return v
}
16 changes: 9 additions & 7 deletions internal/core/adt/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ var incompleteSentinel = &Bottom{
func (c *OpContext) evaluate(v *Vertex, r Resolver, state VertexStatus) Value {
if v.isUndefined() {
// Use node itself to allow for cycle detection.
c.Unify(v, state)
c.unify(v, state)

if v.ArcType == ArcVoid {
if v.status == Evaluating {
Expand Down Expand Up @@ -145,10 +145,12 @@ func (c *OpContext) evaluate(v *Vertex, r Resolver, state VertexStatus) Value {
return v
}

// Unify fully unifies all values of a Vertex to completion and stores
// the result in the Vertex. If unify was called on v before it returns
// the cached results.
func (c *OpContext) Unify(v *Vertex, state VertexStatus) {
// unify unifies values of a Vertex to and stores the result in the Vertex. If
// unify was called on v before it returns the cached results.
// state can be used to indicate to which extent processing should continue.
// state == finalized means it is evaluated to completion. See vertexStatus
// for more details.
func (c *OpContext) unify(v *Vertex, state VertexStatus) {
// defer c.PopVertex(c.PushVertex(v))
if Debug {
c.nest++
Expand Down Expand Up @@ -752,7 +754,7 @@ func (n *nodeContext) completeArcs(state VertexStatus) {

wasVoid := a.ArcType == ArcVoid

ctx.Unify(a, Finalized)
ctx.unify(a, Finalized)

if a.ArcType == ArcVoid {
continue
Expand Down Expand Up @@ -1619,7 +1621,7 @@ func (n *nodeContext) addVertexConjuncts(c Conjunct, arc *Vertex, inline bool) {
// is necessary to prevent lookups in unevaluated structs.
// TODO(cycles): this can probably most easily be fixed with a
// having a more recursive implementation.
n.ctx.Unify(arc, Partial)
n.ctx.unify(arc, Partial)
}

// Don't add conjuncts if a node is referring to itself.
Expand Down
18 changes: 9 additions & 9 deletions internal/core/adt/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (x *StructLit) evaluate(c *OpContext, state VertexStatus) Value {
// used in a context where more conjuncts are added. It may also lead
// to disjuncts being in a partially expanded state, leading to
// misaligned nodeContexts.
c.Unify(v, Conjuncts)
v.CompleteArcs(c)
return v
}

Expand Down Expand Up @@ -292,7 +292,7 @@ func (x *ListLit) evaluate(c *OpContext, state VertexStatus) Value {
IsDynamic: true,
Conjuncts: []Conjunct{{e, x, c.ci}},
}
c.Unify(v, Conjuncts)
v.CompleteArcs(c)
return v
}

Expand Down Expand Up @@ -900,7 +900,7 @@ func (x *LetReference) resolve(ctx *OpContext, state VertexStatus) *Vertex {
// now, though, as it is not entirely clear it is fine to remove this.
// We can reevaluate this once we have redone some of the planned order of
// evaluation work.
ctx.Unify(arc, Finalized)
arc.Finalize(ctx)
b, ok := arc.BaseValue.(*Bottom)
if !arc.MultiLet && !ok {
return arc
Expand Down Expand Up @@ -1252,9 +1252,9 @@ func (x *BinaryExpr) evaluate(c *OpContext, state VertexStatus) Value {
// evaluate the struct regardless to ensure that cycle reporting
// keeps working.
if env.Vertex.IsDynamic || c.inValidator > 0 {
c.Unify(v, Finalized)
v.Finalize(c)
} else {
c.Unify(v, Conjuncts)
v.CompleteArcs(c)
}

return v
Expand Down Expand Up @@ -1340,7 +1340,7 @@ func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, stat
// - walk over all fields and verify that fields are not contradicting
// previously marked fields.
//
c.Unify(v, Finalized)
v.Finalize(c)

if v.status == EvaluatingArcs {
// We have a cycle, which may be an error. Cycle errors may occur
Expand Down Expand Up @@ -1606,7 +1606,7 @@ func (x *Builtin) call(c *OpContext, p token.Pos, validate bool, args []Value) E
IsDynamic: true,
Conjuncts: []Conjunct{{env, x, c.ci}},
}
c.Unify(n, Finalized)
n.Finalize(c)
if _, ok := n.BaseValue.(*Bottom); ok {
c.addErrf(0, pos(a),
"cannot use %s as %s in argument %d to %s",
Expand Down Expand Up @@ -1741,7 +1741,7 @@ func (x *DisjunctionExpr) Source() ast.Node {
func (x *DisjunctionExpr) evaluate(c *OpContext, state VertexStatus) Value {
e := c.Env(0)
v := &Vertex{Conjuncts: []Conjunct{{e, x, c.ci}}}
c.Unify(v, Finalized) // TODO: also partial okay?
v.Finalize(c) // TODO: also partial okay?
// TODO: if the disjunction result originated from a literal value, we may
// consider the result closed to create more permanent errors.
return v
Expand Down Expand Up @@ -1881,7 +1881,7 @@ func (x *ForClause) yield(s *compState) {
continue
}

c.Unify(a, Partial)
c.unify(a, Partial)
if a.ArcType == ArcVoid {
continue
}
Expand Down
2 changes: 1 addition & 1 deletion internal/core/compile/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ var orBuiltin = &adt.Builtin{
&adt.DisjunctionExpr{Values: d, HasDefaults: false},
closeInfo,
))
c.Unify(v, adt.Conjuncts)
v.CompleteArcs(c)
return v
},
}
Expand Down
6 changes: 1 addition & 5 deletions internal/core/eval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func Evaluate(r adt.Runtime, v *adt.Vertex) {
Runtime: r,
Format: format,
})
c.Unify(v, adt.Finalized)
v.Finalize(c)
}

func New(r adt.Runtime) *Unifier {
Expand All @@ -40,10 +40,6 @@ type Unifier struct {
e *adt.OpContext
}

func (e *Unifier) Unify(ctx *adt.OpContext, v *adt.Vertex, state adt.VertexStatus) {
e.e.Unify(v, state)
}

func (e *Unifier) Stats() *stats.Counts {
return e.e.Stats()
}
Expand Down
2 changes: 1 addition & 1 deletion internal/core/validate/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ y: conflicting values 4 and 2:
if err != nil {
t.Fatal(err)
}
ctx.Unify(v, adt.Finalized)
v.Finalize(ctx)
if tc.lookup != "" {
v = v.Lookup(adt.MakeIdentLabel(r, tc.lookup, "main"))
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/internal/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (c *CallCtxt) Struct(i int) Struct {
x := c.args[i]
switch v, ok := x.(*adt.Vertex); {
case ok && !v.IsList():
c.ctx.Unify(v, adt.Conjuncts)
v.CompleteArcs(c.ctx)
return Struct{c.ctx, v}

case v != nil:
Expand Down
2 changes: 1 addition & 1 deletion pkg/list/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func makeValueSorter(list []cue.Value, cmp cue.Value) (s valueSorter) {
Parent: v.V.Parent,
Conjuncts: v.V.Conjuncts,
}
ctx.Unify(n, adt.Conjuncts)
n.CompleteArcs(ctx)

s = valueSorter{
a: list,
Expand Down

0 comments on commit 7851142

Please sign in to comment.