github.com/consensys/gnark@v0.11.0/constraint/instruction_tree.go (about)

     1  package constraint
     2  
     3  import (
     4  	"github.com/consensys/gnark/debug"
     5  )
     6  
     7  type Level int
     8  
     9  const (
    10  	LevelUnset Level = -1
    11  )
    12  
    13  type InstructionTree interface {
    14  	// InsertWire inserts a wire in the instruction tree at the given level.
    15  	// If the wire is already in the instruction tree, it panics.
    16  	InsertWire(wire uint32, level Level)
    17  
    18  	// HasWire returns true if the wire is in the instruction tree.
    19  	// False if it's a constant or an input.
    20  	HasWire(wire uint32) bool
    21  
    22  	// GetWireLevel returns the level of the wire in the instruction tree.
    23  	// If HasWire(wire) returns false, behavior is undefined.
    24  	GetWireLevel(wire uint32) Level
    25  }
    26  
    27  // the instruction tree is a simple array of levels.
    28  // it's morally a map[uint32 (wireID)]Level, but we use an array for performance reasons.
    29  
    30  func (system *System) HasWire(wireID uint32) bool {
    31  	offset := system.internalWireOffset()
    32  	if wireID < offset {
    33  		// it's a input.
    34  		return false
    35  	}
    36  	// if wireID == maxUint32, it's a constant.
    37  	return (wireID - offset) < uint32(len(system.lbWireLevel))
    38  }
    39  
    40  func (system *System) GetWireLevel(wireID uint32) Level {
    41  	return system.lbWireLevel[wireID-system.internalWireOffset()]
    42  }
    43  
    44  func (system *System) InsertWire(wireID uint32, level Level) {
    45  	if debug.Debug {
    46  		if level < 0 {
    47  			panic("level must be >= 0")
    48  		}
    49  		if wireID < system.internalWireOffset() {
    50  			panic("cannot insert input wire in instruction tree")
    51  		}
    52  	}
    53  	wireID -= system.internalWireOffset()
    54  	if system.lbWireLevel[wireID] != LevelUnset {
    55  		panic("wire already exist in instruction tree")
    56  	}
    57  
    58  	system.lbWireLevel[wireID] = level
    59  }
    60  
    61  // internalWireOffset returns the position of the first internal wire in the wireIDs.
    62  func (system *System) internalWireOffset() uint32 {
    63  	return uint32(system.GetNbPublicVariables() + system.GetNbSecretVariables())
    64  }