github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/internal/core/adt/composite.go (about)

     1  // Copyright 2020 CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package adt
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/joomcode/cue/cue/ast"
    21  	"github.com/joomcode/cue/cue/errors"
    22  	"github.com/joomcode/cue/cue/token"
    23  )
    24  
    25  // TODO: unanswered questions about structural cycles:
    26  //
    27  // 1. When detecting a structural cycle, should we consider this as:
    28  //    a) an unevaluated value,
    29  //    b) an incomplete error (which does not affect parent validity), or
    30  //    c) a special value.
    31  //
    32  // Making it an error is the simplest way to ensure reentrancy is disallowed:
    33  // without an error it would require an additional mechanism to stop reentrancy
    34  // from continuing to process. Even worse, in some cases it may only partially
    35  // evaluate, resulting in unexpected results. For this reason, we are taking
    36  // approach `b` for now.
    37  //
    38  // This has some consequences of how disjunctions are treated though. Consider
    39  //
    40  //     list: {
    41  //        head: _
    42  //        tail: list | null
    43  //     }
    44  //
    45  // When making it an error, evaluating the above will result in
    46  //
    47  //     list: {
    48  //        head: _
    49  //        tail: null
    50  //     }
    51  //
    52  // because list will result in a structural cycle, and thus an error, it will be
    53  // stripped from the disjunction. This may or may not be a desirable property. A
    54  // nice thing is that it is not required to write `list | *null`. A disadvantage
    55  // is that this is perhaps somewhat inexplicit.
    56  //
    57  // When not making it an error (and simply cease evaluating child arcs upon
    58  // cycle detection), the result would be:
    59  //
    60  //     list: {
    61  //        head: _
    62  //        tail: list | null
    63  //     }
    64  //
    65  // In other words, an evaluation would result in a cycle and thus an error.
    66  // Implementations can recognize such cases by having unevaluated arcs. An
    67  // explicit structure cycle marker would probably be less error prone.
    68  //
    69  // Note that in both cases, a reference to list will still use the original
    70  // conjuncts, so the result will be the same for either method in this case.
    71  //
    72  //
    73  // 2. Structural cycle allowance.
    74  //
    75  // Structural cycle detection disallows reentrancy as well. This means one
    76  // cannot use structs for recursive computation. This will probably preclude
    77  // evaluation of some configuration. Given that there is no real alternative
    78  // yet, we could allow structural cycle detection to be optionally disabled.
    79  
    80  // An Environment links the parent scopes for identifier lookup to a composite
    81  // node. Each conjunct that make up node in the tree can be associated with
    82  // a different environment (although some conjuncts may share an Environment).
    83  type Environment struct {
    84  	Up     *Environment
    85  	Vertex *Vertex
    86  
    87  	// DynamicLabel is only set when instantiating a field from a pattern
    88  	// constraint. It is used to resolve label references.
    89  	DynamicLabel Feature
    90  
    91  	// TODO(perf): make the following public fields a shareable struct as it
    92  	// mostly is going to be the same for child nodes.
    93  
    94  	// Cyclic indicates a structural cycle was detected for this conjunct or one
    95  	// of its ancestors.
    96  	Cyclic bool
    97  
    98  	// Deref keeps track of nodes that should dereference to Vertex. It is used
    99  	// for detecting structural cycle.
   100  	//
   101  	// The detection algorithm is based on Tomabechi's quasi-destructive graph
   102  	// unification. This detection requires dependencies to be resolved into
   103  	// fully dereferenced vertices. This is not the case in our algorithm:
   104  	// the result of evaluating conjuncts is placed into dereferenced vertices
   105  	// _after_ they are evaluated, but the Environment still points to the
   106  	// non-dereferenced context.
   107  	//
   108  	// In order to be able to detect structural cycles, we need to ensure that
   109  	// at least one node that is part of a cycle in the context in which
   110  	// conjunctions are evaluated dereferences correctly.
   111  	//
   112  	// The only field necessary to detect a structural cycle, however, is
   113  	// the Status field of the Vertex. So rather than dereferencing a node
   114  	// proper, it is sufficient to copy the Status of the dereferenced nodes
   115  	// to these nodes (will always be EvaluatingArcs).
   116  	Deref []*Vertex
   117  
   118  	// Cycles contains vertices for which cycles are detected. It is used
   119  	// for tracking self-references within structural cycles.
   120  	//
   121  	// Unlike Deref, Cycles is not incremented with child nodes.
   122  	// TODO: Cycles is always a tail end of Deref, so this can be optimized.
   123  	Cycles []*Vertex
   124  
   125  	cache map[Expr]Value
   126  }
   127  
   128  type ID int32
   129  
   130  // evalCached is used to look up let expressions. Caching let expressions
   131  // prevents a possible combinatorial explosion.
   132  func (e *Environment) evalCached(c *OpContext, x Expr) Value {
   133  	if v, ok := x.(Value); ok {
   134  		return v
   135  	}
   136  	v, ok := e.cache[x]
   137  	if !ok {
   138  		if e.cache == nil {
   139  			e.cache = map[Expr]Value{}
   140  		}
   141  		env, src := c.e, c.src
   142  		c.e, c.src = e, x.Source()
   143  		v = c.evalState(x, Partial) // TODO: should this be Finalized?
   144  		c.e, c.src = env, src
   145  		if b, ok := v.(*Bottom); !ok || !b.IsIncomplete() {
   146  			e.cache[x] = v
   147  		}
   148  	}
   149  	return v
   150  }
   151  
   152  // A Vertex is a node in the value tree. It may be a leaf or internal node.
   153  // It may have arcs to represent elements of a fully evaluated struct or list.
   154  //
   155  // For structs, it only contains definitions and concrete fields.
   156  // optional fields are dropped.
   157  //
   158  // It maintains source information such as a list of conjuncts that contributed
   159  // to the value.
   160  type Vertex struct {
   161  	// Parent links to a parent Vertex. This parent should only be used to
   162  	// access the parent's Label field to find the relative location within a
   163  	// tree.
   164  	Parent *Vertex
   165  
   166  	// Label is the feature leading to this vertex.
   167  	Label Feature
   168  
   169  	// State:
   170  	//   eval: nil, BaseValue: nil -- unevaluated
   171  	//   eval: *,   BaseValue: nil -- evaluating
   172  	//   eval: *,   BaseValue: *   -- finalized
   173  	//
   174  	state *nodeContext
   175  	// TODO: move the following status fields to nodeContext.
   176  
   177  	// status indicates the evaluation progress of this vertex.
   178  	status VertexStatus
   179  
   180  	// isData indicates that this Vertex is to be interepreted as data: pattern
   181  	// and additional constraints, as well as optional fields, should be
   182  	// ignored.
   183  	isData                bool
   184  	Closed                bool
   185  	nonMonotonicReject    bool
   186  	nonMonotonicInsertGen int32
   187  	nonMonotonicLookupGen int32
   188  
   189  	// EvalCount keeps track of temporary dereferencing during evaluation.
   190  	// If EvalCount > 0, status should be considered to be EvaluatingArcs.
   191  	EvalCount int32
   192  
   193  	// SelfCount is used for tracking self-references.
   194  	SelfCount int32
   195  
   196  	// BaseValue is the value associated with this vertex. For lists and structs
   197  	// this is a sentinel value indicating its kind.
   198  	BaseValue BaseValue
   199  
   200  	// ChildErrors is the collection of all errors of children.
   201  	ChildErrors *Bottom
   202  
   203  	// The parent of nodes can be followed to determine the path within the
   204  	// configuration of this node.
   205  	// Value  Value
   206  	Arcs []*Vertex // arcs are sorted in display order.
   207  
   208  	// Conjuncts lists the structs that ultimately formed this Composite value.
   209  	// This includes all selected disjuncts.
   210  	//
   211  	// This value may be nil, in which case the Arcs are considered to define
   212  	// the final value of this Vertex.
   213  	Conjuncts []Conjunct
   214  
   215  	// Structs is a slice of struct literals that contributed to this value.
   216  	// This information is used to compute the topological sort of arcs.
   217  	Structs []*StructInfo
   218  }
   219  
   220  func (v *Vertex) Clone() *Vertex {
   221  	c := *v
   222  	c.state = nil
   223  	return &c
   224  }
   225  
   226  type StructInfo struct {
   227  	*StructLit
   228  
   229  	Env *Environment
   230  
   231  	CloseInfo
   232  
   233  	// Embed indicates the struct in which this struct is embedded (originally),
   234  	// or nil if this is a root structure.
   235  	// Embed   *StructInfo
   236  	// Context *RefInfo // the location from which this struct originates.
   237  	Disable bool
   238  
   239  	Embedding bool
   240  }
   241  
   242  // TODO(perf): this could be much more aggressive for eliminating structs that
   243  // are immaterial for closing.
   244  func (s *StructInfo) useForAccept() bool {
   245  	if c := s.closeInfo; c != nil {
   246  		return !c.noCheck
   247  	}
   248  	return true
   249  }
   250  
   251  // VertexStatus indicates the evaluation progress of a Vertex.
   252  type VertexStatus int8
   253  
   254  const (
   255  	// Unprocessed indicates a Vertex has not been processed before.
   256  	// Value must be nil.
   257  	Unprocessed VertexStatus = iota
   258  
   259  	// Evaluating means that the current Vertex is being evaluated. If this is
   260  	// encountered it indicates a reference cycle. Value must be nil.
   261  	Evaluating
   262  
   263  	// Partial indicates that the result was only partially evaluated. It will
   264  	// need to be fully evaluated to get a complete results.
   265  	//
   266  	// TODO: this currently requires a renewed computation. Cache the
   267  	// nodeContext to allow reusing the computations done so far.
   268  	Partial
   269  
   270  	// AllArcs is request only. It must be past Partial, but
   271  	// before recursively resolving arcs.
   272  	AllArcs
   273  
   274  	// EvaluatingArcs indicates that the arcs of the Vertex are currently being
   275  	// evaluated. If this is encountered it indicates a structural cycle.
   276  	// Value does not have to be nil
   277  	EvaluatingArcs
   278  
   279  	// Finalized means that this node is fully evaluated and that the results
   280  	// are save to use without further consideration.
   281  	Finalized
   282  )
   283  
   284  func (s VertexStatus) String() string {
   285  	switch s {
   286  	case Unprocessed:
   287  		return "unprocessed"
   288  	case Evaluating:
   289  		return "evaluating"
   290  	case Partial:
   291  		return "partial"
   292  	case AllArcs:
   293  		return "allarcs"
   294  	case EvaluatingArcs:
   295  		return "evaluatingArcs"
   296  	case Finalized:
   297  		return "finalized"
   298  	default:
   299  		return "unknown"
   300  	}
   301  }
   302  
   303  func (v *Vertex) Status() VertexStatus {
   304  	if v.EvalCount > 0 {
   305  		return EvaluatingArcs
   306  	}
   307  	return v.status
   308  }
   309  
   310  func (v *Vertex) UpdateStatus(s VertexStatus) {
   311  	Assertf(v.status <= s+1, "attempt to regress status from %d to %d", v.Status(), s)
   312  
   313  	if s == Finalized && v.BaseValue == nil {
   314  		// panic("not finalized")
   315  	}
   316  	v.status = s
   317  }
   318  
   319  // Value returns the Value of v without definitions if it is a scalar
   320  // or itself otherwise.
   321  func (v *Vertex) Value() Value {
   322  	switch x := v.BaseValue.(type) {
   323  	case nil:
   324  		return nil
   325  	case *StructMarker, *ListMarker:
   326  		return v
   327  	case Value:
   328  		// TODO: recursively descend into Vertex?
   329  		return x
   330  	default:
   331  		panic(fmt.Sprintf("unexpected type %T", v.BaseValue))
   332  	}
   333  }
   334  
   335  // isUndefined reports whether a vertex does not have a useable BaseValue yet.
   336  func (v *Vertex) isUndefined() bool {
   337  	switch v.BaseValue {
   338  	case nil, cycle:
   339  		return true
   340  	}
   341  	return false
   342  }
   343  
   344  func (x *Vertex) IsConcrete() bool {
   345  	return x.Concreteness() <= Concrete
   346  }
   347  
   348  // IsData reports whether v should be interpreted in data mode. In other words,
   349  // it tells whether optional field matching and non-regular fields, like
   350  // definitions and hidden fields, should be ignored.
   351  func (v *Vertex) IsData() bool {
   352  	return v.isData || len(v.Conjuncts) == 0
   353  }
   354  
   355  // ToDataSingle creates a new Vertex that represents just the regular fields
   356  // of this vertex. Arcs are left untouched.
   357  // It is used by cue.Eval to convert nodes to data on per-node basis.
   358  func (v *Vertex) ToDataSingle() *Vertex {
   359  	w := *v
   360  	w.isData = true
   361  	w.state = nil
   362  	w.status = Finalized
   363  	return &w
   364  }
   365  
   366  // ToDataAll returns a new v where v and all its descendents contain only
   367  // the regular fields.
   368  func (v *Vertex) ToDataAll() *Vertex {
   369  	arcs := make([]*Vertex, 0, len(v.Arcs))
   370  	for _, a := range v.Arcs {
   371  		if a.Label.IsRegular() {
   372  			arcs = append(arcs, a.ToDataAll())
   373  		}
   374  	}
   375  	w := *v
   376  	w.state = nil
   377  	w.status = Finalized
   378  
   379  	w.BaseValue = toDataAll(w.BaseValue)
   380  	w.Arcs = arcs
   381  	w.isData = true
   382  	w.Conjuncts = make([]Conjunct, len(v.Conjuncts))
   383  	// TODO(perf): this is not strictly necessary for evaluation, but it can
   384  	// hurt performance greatly. Drawback is that it may disable ordering.
   385  	for _, s := range w.Structs {
   386  		s.Disable = true
   387  	}
   388  	copy(w.Conjuncts, v.Conjuncts)
   389  	for i, c := range w.Conjuncts {
   390  		if v, _ := c.x.(Value); v != nil {
   391  			w.Conjuncts[i].x = toDataAll(v).(Value)
   392  		}
   393  	}
   394  	return &w
   395  }
   396  
   397  func toDataAll(v BaseValue) BaseValue {
   398  	switch x := v.(type) {
   399  	default:
   400  		return x
   401  
   402  	case *Vertex:
   403  		return x.ToDataAll()
   404  
   405  	// The following cases are always erroneous, but we handle them anyway
   406  	// to avoid issues with the closedness algorithm down the line.
   407  	case *Disjunction:
   408  		d := *x
   409  		d.Values = make([]*Vertex, len(x.Values))
   410  		for i, v := range x.Values {
   411  			d.Values[i] = v.ToDataAll()
   412  		}
   413  		return &d
   414  
   415  	case *Conjunction:
   416  		c := *x
   417  		c.Values = make([]Value, len(x.Values))
   418  		for i, v := range x.Values {
   419  			// This case is okay because the source is of type Value.
   420  			c.Values[i] = toDataAll(v).(Value)
   421  		}
   422  		return &c
   423  	}
   424  }
   425  
   426  // func (v *Vertex) IsEvaluating() bool {
   427  // 	return v.Value == cycle
   428  // }
   429  
   430  func (v *Vertex) IsErr() bool {
   431  	// if v.Status() > Evaluating {
   432  	if _, ok := v.BaseValue.(*Bottom); ok {
   433  		return true
   434  	}
   435  	// }
   436  	return false
   437  }
   438  
   439  func (v *Vertex) Err(c *OpContext, state VertexStatus) *Bottom {
   440  	c.Unify(v, state)
   441  	if b, ok := v.BaseValue.(*Bottom); ok {
   442  		return b
   443  	}
   444  	return nil
   445  }
   446  
   447  // func (v *Vertex) Evaluate()
   448  
   449  func (v *Vertex) Finalize(c *OpContext) {
   450  	// Saving and restoring the error context prevents v from panicking in
   451  	// case the caller did not handle existing errors in the context.
   452  	err := c.errs
   453  	c.errs = nil
   454  	c.Unify(v, Finalized)
   455  	c.errs = err
   456  }
   457  
   458  func (v *Vertex) AddErr(ctx *OpContext, b *Bottom) {
   459  	v.SetValue(ctx, Finalized, CombineErrors(nil, v.Value(), b))
   460  }
   461  
   462  func (v *Vertex) SetValue(ctx *OpContext, state VertexStatus, value BaseValue) *Bottom {
   463  	v.BaseValue = value
   464  	v.UpdateStatus(state)
   465  	return nil
   466  }
   467  
   468  // ToVertex wraps v in a new Vertex, if necessary.
   469  func ToVertex(v Value) *Vertex {
   470  	switch x := v.(type) {
   471  	case *Vertex:
   472  		return x
   473  	default:
   474  		n := &Vertex{
   475  			status:    Finalized,
   476  			BaseValue: x,
   477  		}
   478  		n.AddConjunct(MakeRootConjunct(nil, v))
   479  		return n
   480  	}
   481  }
   482  
   483  // Unwrap returns the possibly non-concrete scalar value of v or nil if v is
   484  // a list, struct or of undefined type.
   485  func Unwrap(v Value) Value {
   486  	x, ok := v.(*Vertex)
   487  	if !ok {
   488  		return v
   489  	}
   490  	x = x.Indirect()
   491  	if n := x.state; n != nil && isCyclePlaceholder(x.BaseValue) {
   492  		if n.errs != nil && !n.errs.IsIncomplete() {
   493  			return n.errs
   494  		}
   495  		if n.scalar != nil {
   496  			return n.scalar
   497  		}
   498  	}
   499  	return x.Value()
   500  }
   501  
   502  // Indirect unrolls indirections of Vertex values. These may be introduced,
   503  // for instance, by temporary bindings such as comprehension values.
   504  // It returns v itself if v does not point to another Vertex.
   505  func (v *Vertex) Indirect() *Vertex {
   506  	for {
   507  		arc, ok := v.BaseValue.(*Vertex)
   508  		if !ok {
   509  			return v
   510  		}
   511  		v = arc
   512  	}
   513  }
   514  
   515  // OptionalType is a bit field of the type of optional constraints in use by an
   516  // Acceptor.
   517  type OptionalType int8
   518  
   519  const (
   520  	HasField          OptionalType = 1 << iota // X: T
   521  	HasDynamic                                 // (X): T or "\(X)": T
   522  	HasPattern                                 // [X]: T
   523  	HasComplexPattern                          // anything but a basic type
   524  	HasAdditional                              // ...T
   525  	IsOpen                                     // Defined for all fields
   526  )
   527  
   528  func (v *Vertex) Kind() Kind {
   529  	// This is possible when evaluating comprehensions. It is potentially
   530  	// not known at this time what the type is.
   531  	switch {
   532  	case v.state != nil:
   533  		return v.state.kind
   534  	case v.BaseValue == nil:
   535  		return TopKind
   536  	default:
   537  		return v.BaseValue.Kind()
   538  	}
   539  }
   540  
   541  func (v *Vertex) OptionalTypes() OptionalType {
   542  	var mask OptionalType
   543  	for _, s := range v.Structs {
   544  		mask |= s.OptionalTypes()
   545  	}
   546  	return mask
   547  }
   548  
   549  // IsOptional reports whether a field is explicitly defined as optional,
   550  // as opposed to whether it is allowed by a pattern constraint.
   551  func (v *Vertex) IsOptional(label Feature) bool {
   552  	for _, s := range v.Structs {
   553  		if s.IsOptional(label) {
   554  			return true
   555  		}
   556  	}
   557  	return false
   558  }
   559  
   560  func (v *Vertex) accepts(ok, required bool) bool {
   561  	return ok || (!required && !v.Closed)
   562  }
   563  
   564  func (v *Vertex) IsClosedStruct() bool {
   565  	switch x := v.BaseValue.(type) {
   566  	default:
   567  		return false
   568  
   569  	case *StructMarker:
   570  		if x.NeedClose {
   571  			return true
   572  		}
   573  
   574  	case *Disjunction:
   575  	}
   576  	return v.Closed || isClosed(v)
   577  }
   578  
   579  func (v *Vertex) IsClosedList() bool {
   580  	if x, ok := v.BaseValue.(*ListMarker); ok {
   581  		return !x.IsOpen
   582  	}
   583  	return false
   584  }
   585  
   586  // TODO: return error instead of boolean? (or at least have version that does.)
   587  func (v *Vertex) Accept(ctx *OpContext, f Feature) bool {
   588  	if x, ok := v.BaseValue.(*Disjunction); ok {
   589  		for _, v := range x.Values {
   590  			if v.Accept(ctx, f) {
   591  				return true
   592  			}
   593  		}
   594  		return false
   595  	}
   596  
   597  	if f.IsInt() {
   598  		switch v.BaseValue.(type) {
   599  		case *ListMarker:
   600  			// TODO(perf): use precomputed length.
   601  			if f.Index() < len(v.Elems()) {
   602  				return true
   603  			}
   604  			return !v.IsClosedList()
   605  
   606  		default:
   607  			return v.Kind()&ListKind != 0
   608  		}
   609  	}
   610  
   611  	if k := v.Kind(); k&StructKind == 0 && f.IsString() {
   612  		// If the value is bottom, we may not really know if this used to
   613  		// be a struct.
   614  		if k != BottomKind || len(v.Structs) == 0 {
   615  			return false
   616  		}
   617  	}
   618  
   619  	if f.IsHidden() || !v.IsClosedStruct() || v.Lookup(f) != nil {
   620  		return true
   621  	}
   622  
   623  	// TODO(perf): collect positions in error.
   624  	defer ctx.ReleasePositions(ctx.MarkPositions())
   625  
   626  	return v.accepts(Accept(ctx, v, f))
   627  }
   628  
   629  // MatchAndInsert finds the conjuncts for optional fields, pattern
   630  // constraints, and additional constraints that match f and inserts them in
   631  // arc. Use f is 0 to match all additional constraints only.
   632  func (v *Vertex) MatchAndInsert(ctx *OpContext, arc *Vertex) {
   633  	if !v.Accept(ctx, arc.Label) {
   634  		return
   635  	}
   636  
   637  	// Go backwards to simulate old implementation.
   638  	for i := len(v.Structs) - 1; i >= 0; i-- {
   639  		s := v.Structs[i]
   640  		if s.Disable {
   641  			continue
   642  		}
   643  		s.MatchAndInsert(ctx, arc)
   644  	}
   645  }
   646  
   647  func (v *Vertex) IsList() bool {
   648  	_, ok := v.BaseValue.(*ListMarker)
   649  	return ok
   650  }
   651  
   652  // Lookup returns the Arc with label f if it exists or nil otherwise.
   653  func (v *Vertex) Lookup(f Feature) *Vertex {
   654  	for _, a := range v.Arcs {
   655  		if a.Label == f {
   656  			a = a.Indirect()
   657  			return a
   658  		}
   659  	}
   660  	return nil
   661  }
   662  
   663  // Elems returns the regular elements of a list.
   664  func (v *Vertex) Elems() []*Vertex {
   665  	// TODO: add bookkeeping for where list arcs start and end.
   666  	a := make([]*Vertex, 0, len(v.Arcs))
   667  	for _, x := range v.Arcs {
   668  		if x.Label.IsInt() {
   669  			a = append(a, x)
   670  		}
   671  	}
   672  	return a
   673  }
   674  
   675  // GetArc returns a Vertex for the outgoing arc with label f. It creates and
   676  // ads one if it doesn't yet exist.
   677  func (v *Vertex) GetArc(c *OpContext, f Feature) (arc *Vertex, isNew bool) {
   678  	arc = v.Lookup(f)
   679  	if arc == nil {
   680  		for _, a := range v.state.usedArcs {
   681  			if a.Label == f {
   682  				arc = a
   683  				v.Arcs = append(v.Arcs, arc)
   684  				isNew = true
   685  				if c.nonMonotonicInsertNest > 0 {
   686  					a.nonMonotonicInsertGen = c.nonMonotonicGeneration
   687  				}
   688  				break
   689  			}
   690  		}
   691  	}
   692  	if arc == nil {
   693  		arc = &Vertex{Parent: v, Label: f}
   694  		v.Arcs = append(v.Arcs, arc)
   695  		isNew = true
   696  		if c.nonMonotonicInsertNest > 0 {
   697  			arc.nonMonotonicInsertGen = c.nonMonotonicGeneration
   698  		}
   699  	}
   700  	if c.nonMonotonicInsertNest == 0 {
   701  		arc.nonMonotonicInsertGen = 0
   702  	}
   703  	return arc, isNew
   704  }
   705  
   706  func (v *Vertex) Source() ast.Node {
   707  	if v != nil {
   708  		if b, ok := v.BaseValue.(Value); ok {
   709  			return b.Source()
   710  		}
   711  	}
   712  	return nil
   713  }
   714  
   715  // AddConjunct adds the given Conjuncts to v if it doesn't already exist.
   716  func (v *Vertex) AddConjunct(c Conjunct) *Bottom {
   717  	if v.BaseValue != nil {
   718  		// TODO: investigate why this happens at all. Removing it seems to
   719  		// change the order of fields in some cases.
   720  		//
   721  		// This is likely a bug in the evaluator and should not happen.
   722  		return &Bottom{Err: errors.Newf(token.NoPos, "cannot add conjunct")}
   723  	}
   724  	v.addConjunct(c)
   725  	return nil
   726  }
   727  
   728  func (v *Vertex) addConjunct(c Conjunct) {
   729  	for _, x := range v.Conjuncts {
   730  		if x == c {
   731  			return
   732  		}
   733  	}
   734  	v.Conjuncts = append(v.Conjuncts, c)
   735  }
   736  
   737  func (v *Vertex) AddStruct(s *StructLit, env *Environment, ci CloseInfo) *StructInfo {
   738  	info := StructInfo{
   739  		StructLit: s,
   740  		Env:       env,
   741  		CloseInfo: ci,
   742  	}
   743  	for _, t := range v.Structs {
   744  		if *t == info {
   745  			return t
   746  		}
   747  	}
   748  	t := &info
   749  	v.Structs = append(v.Structs, t)
   750  	return t
   751  }
   752  
   753  // Path computes the sequence of Features leading from the root to of the
   754  // instance to this Vertex.
   755  //
   756  // NOTE: this is for debugging purposes only.
   757  func (v *Vertex) Path() []Feature {
   758  	return appendPath(nil, v)
   759  }
   760  
   761  func appendPath(a []Feature, v *Vertex) []Feature {
   762  	if v.Parent == nil {
   763  		return a
   764  	}
   765  	a = appendPath(a, v.Parent)
   766  	if v.Label != 0 {
   767  		// A Label may be 0 for programmatically inserted nodes.
   768  		a = append(a, v.Label)
   769  	}
   770  	return a
   771  }
   772  
   773  // An Conjunct is an Environment-Expr pair. The Environment is the starting
   774  // point for reference lookup for any reference contained in X.
   775  type Conjunct struct {
   776  	Env *Environment
   777  	x   Node
   778  
   779  	// CloseInfo is a unique number that tracks a group of conjuncts that need
   780  	// belong to a single originating definition.
   781  	CloseInfo CloseInfo
   782  }
   783  
   784  // TODO(perf): replace with composite literal if this helps performance.
   785  
   786  // MakeRootConjunct creates a conjunct from the given environment and node.
   787  // It panics if x cannot be used as an expression.
   788  func MakeRootConjunct(env *Environment, x Node) Conjunct {
   789  	return MakeConjunct(env, x, CloseInfo{})
   790  }
   791  
   792  func MakeConjunct(env *Environment, x Node, id CloseInfo) Conjunct {
   793  	if env == nil {
   794  		// TODO: better is to pass one.
   795  		env = &Environment{}
   796  	}
   797  	switch x.(type) {
   798  	case Elem, interface{ expr() Expr }:
   799  	default:
   800  		panic(fmt.Sprintf("invalid Node type %T", x))
   801  	}
   802  	return Conjunct{env, x, id}
   803  }
   804  
   805  func (c *Conjunct) Source() ast.Node {
   806  	return c.x.Source()
   807  }
   808  
   809  func (c *Conjunct) Field() Node {
   810  	return c.x
   811  }
   812  
   813  // Elem retrieves the Elem form of the contained conjunct.
   814  // If it is a Field, it will return the field value.
   815  func (c *Conjunct) Elem() Elem {
   816  	switch x := c.x.(type) {
   817  	case interface{ expr() Expr }:
   818  		return x.expr()
   819  	case Elem:
   820  		return x
   821  	default:
   822  		panic("unreachable")
   823  	}
   824  }
   825  
   826  // Expr retrieves the expression form of the contained conjunct.
   827  // If it is a field or comprehension, it will return its associated value.
   828  func (c *Conjunct) Expr() Expr {
   829  	switch x := c.x.(type) {
   830  	case Expr:
   831  		return x
   832  	// TODO: comprehension.
   833  	case interface{ expr() Expr }:
   834  		return x.expr()
   835  	default:
   836  		panic("unreachable")
   837  	}
   838  }