Skip to content

Commit

Permalink
[feat]: Annotate usort and dict hints + few improvements (#389)
Browse files Browse the repository at this point in the history
* usort and dict description + few improvements

* add comments for errors in UsortVerifyMultiplicityBody hint

* address comments

* fix

* fmt

* update comments

* fix

* add comment for wrong UsortVerifyMultiplicityBody impl

* fix
  • Loading branch information
TAdev0 committed May 8, 2024
1 parent 998c901 commit 878c28c
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 13 deletions.
6 changes: 5 additions & 1 deletion pkg/hintrunner/zero/zerohint_dictionaries.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import (
f "github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
)

// SquashDictInnerAssertLenKeys hint asserts that the length
// of the `keys` descending list is zero during the squashing process
//
// `newSquashDictInnerAssertLenKeysHint` doesn't take any operander as argument
func newSquashDictInnerAssertLenKeysHint() hinter.Hinter {
return &GenericZeroHinter{
Name: "SquashDictInnerAssertKeys",
Name: "SquashDictInnerAssertLenKeys",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
//> assert len(keys) == 0
keys_, err := ctx.ScopeManager.GetVariableValue("keys")
Expand Down
2 changes: 1 addition & 1 deletion pkg/hintrunner/zero/zerohint_ec.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ func createEcDoubleAssignNewXV1Hinter(resolver hintReferenceResolver) (hinter.Hi
return newEcDoubleAssignNewXV1Hint(slope, point), nil
}

// ComputeSlopeV1Hint hint computes the slope between two points on an elliptic curve
// ComputeSlopeV1 hint computes the slope between two points on an elliptic curve
//
// `newComputeSlopeV1Hint` takes 2 operanders as arguments
// - `point0` is the first point on an elliptic curve to operate on
Expand Down
2 changes: 1 addition & 1 deletion pkg/hintrunner/zero/zerohint_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func createVMExitScopeHinter() (hinter.Hinter, error) {
}, nil
}

// MemcpyEnterScopeHint hint enters a new scope for the memory copy operation with a specified length
// MemcpyEnterScope hint enters a new scope for the memory copy operation with a specified length
//
// `newMemcpyEnterScopeHint` takes 1 operander as argument
// - `len` is the length value that is added in the new scope
Expand Down
47 changes: 41 additions & 6 deletions pkg/hintrunner/zero/zerohint_usort.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import (
"github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
)

func newUsortEnterScopeHinter() hinter.Hinter {
// UsortEnterScope hint enters a new scope with `__usort_max_size` value
//
// `newUsortEnterScopeHint` doesn't take any operander as argument
//
// `newUsortEnterScopeHint` gets `__usort_max_size` value from the current
// scope and enters a new scope with this same value
func newUsortEnterScopeHint() hinter.Hinter {
return &GenericZeroHinter{
Name: "UsortEnterScope",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
Expand All @@ -31,10 +37,17 @@ func newUsortEnterScopeHinter() hinter.Hinter {
}

func createUsortEnterScopeHinter() (hinter.Hinter, error) {
return newUsortEnterScopeHinter(), nil
return newUsortEnterScopeHint(), nil
}

func newUsortVerifyMultiplicityAssertHinter() hinter.Hinter {
// UsortVerifyMultiplicityAssert hint checks that the `positions` variable in scope
// doesn't contain any value
//
// `newUsortVerifyMultiplicityAssertHint` doesn't take any operander as argument
//
// This hint is used when sorting an array of field elements while removing duplicates
// in `usort` Cairo function
func newUsortVerifyMultiplicityAssertHint() hinter.Hinter {
return &GenericZeroHinter{
Name: "UsortVerifyMultiplicityAssert",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
Expand All @@ -60,10 +73,20 @@ func newUsortVerifyMultiplicityAssertHinter() hinter.Hinter {
}

func createUsortVerifyMultiplicityAssertHinter() (hinter.Hinter, error) {
return newUsortEnterScopeHinter(), nil
return newUsortEnterScopeHint(), nil
}

func newUsortVerifyHinter(value hinter.ResOperander) hinter.Hinter {
// UsortVerify hint prepares for verifying the presence of duplicates of
// a specific value in the sorted output (array of fields)
//
// `newUsortVerifyHint` takes one operander as argument
// - `value` is the value at the given position in the output
//
// `last_pos` is set to zero
// `positions` is set to the reversed order list associated with `ids.value`
// key in `positions_dict`
// `newUsortVerifyHint` assigns `last_pos` and `positions` in the current scope
func newUsortVerifyHint(value hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "UsortVerify",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
Expand Down Expand Up @@ -106,9 +129,18 @@ func createUsortVerifyHinter(resolver hintReferenceResolver) (hinter.Hinter, err
return nil, err
}

return newUsortVerifyHinter(value), nil
return newUsortVerifyHint(value), nil
}

// UsortVerifyMultiplicityBody hint extracts a specific value
// of the sorted output with `pop`, updating indices for the verification
// of the next value
//
// `newUsortVerifyMultiplicityBodyHint` takes one operander as argument
// - `nextItemIndex` is the index of the next item
//
// `next_item_index` is set to `current_pos - last_pos` for the next iteration
// `newUsortVerifyMultiplicityBodyHint` assigns `last_pos` in the current scope
func newUsortVerifyMultiplicityBodyHint(nextItemIndex hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "UsortVerifyMultiplicityBody",
Expand All @@ -132,6 +164,8 @@ func newUsortVerifyMultiplicityBodyHint(nextItemIndex hinter.ResOperander) hinte
return err
}

// TODO : This is not correct, `newCurrentPos` should be used
// and there is not `current_pos` variable to retrieve in scope
currentPos, err := ctx.ScopeManager.GetVariableValue("current_pos")
if err != nil {
return err
Expand Down Expand Up @@ -167,6 +201,7 @@ func newUsortVerifyMultiplicityBodyHint(nextItemIndex hinter.ResOperander) hinte
return err
}

// TODO : Only last_pos should be assigned in current scope
// Save `current_pos` and `last_pos` values in scope variables
return ctx.ScopeManager.AssignVariables(map[string]any{
"current_pos": newCurrentPos,
Expand Down
8 changes: 4 additions & 4 deletions pkg/hintrunner/zero/zerohint_usort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestZeroHintUsort(t *testing.T) {
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newUsortEnterScopeHinter()
return newUsortEnterScopeHint()
},
check: varValueInScopeEquals("__usort_max_size", feltUint64(1)),
},
Expand All @@ -33,7 +33,7 @@ func TestZeroHintUsort(t *testing.T) {
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newUsortVerifyMultiplicityAssertHinter()
return newUsortVerifyMultiplicityAssertHint()
},
errCheck: errorTextContains("assertion `len(positions) == 0` failed"),
},
Expand All @@ -45,7 +45,7 @@ func TestZeroHintUsort(t *testing.T) {
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newUsortVerifyMultiplicityAssertHinter()
return newUsortVerifyMultiplicityAssertHint()
},
errCheck: errorIsNil,
},
Expand All @@ -64,7 +64,7 @@ func TestZeroHintUsort(t *testing.T) {
{Name: "value", Kind: fpRelative, Value: feltUint64(0)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newUsortVerifyHinter(ctx.operanders["value"])
return newUsortVerifyHint(ctx.operanders["value"])
},
check: func(t *testing.T, ctx *hintTestContext) {
positions, err := ctx.runnerContext.ScopeManager.GetVariableValue("positions")
Expand Down

0 comments on commit 878c28c

Please sign in to comment.