diff --git a/pkg/hintrunner/zero/zerohint_usort.go b/pkg/hintrunner/zero/zerohint_usort.go index 1fe34bac..1cad2159 100644 --- a/pkg/hintrunner/zero/zerohint_usort.go +++ b/pkg/hintrunner/zero/zerohint_usort.go @@ -154,41 +154,35 @@ func newUsortVerifyMultiplicityBodyHint(nextItemIndex hinter.ResOperander) hinte return err } - positions, ok := positionsInterface.([]int64) + positions, ok := positionsInterface.([]fp.Element) if !ok { - return fmt.Errorf("cannot cast positionsInterface to []int64") + return fmt.Errorf("cannot cast positionsInterface to []fp.Element") } - newCurrentPos, err := utils.Pop(&positions) + currentPos, err := utils.Pop(&positions) if err != nil { 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") + err = ctx.ScopeManager.AssignVariable("positions", positions) if err != nil { return err } - currentPosInt, ok := currentPos.(int64) - if !ok { - return fmt.Errorf("cannot cast current_pos to int64") - } - lastPos, err := ctx.ScopeManager.GetVariableValue("last_pos") if err != nil { return err } - lastPosInt, ok := lastPos.(int64) + lastPosFelt, ok := lastPos.(fp.Element) if !ok { - return fmt.Errorf("cannot cast last_pos to int64") + return fmt.Errorf("cannot cast last_pos to felt") } // Calculate `next_item_index` memory value - newNextItemIndexValue := currentPosInt - lastPosInt - newNextItemIndexMemoryValue := memory.MemoryValueFromInt(newNextItemIndexValue) + var newNextItemIndexValue fp.Element + newNextItemIndexValue.Sub(¤tPos, &lastPosFelt) + newNextItemIndexMemoryValue := memory.MemoryValueFromFieldElement(&newNextItemIndexValue) // Save `next_item_index` value in address addrNextItemIndex, err := nextItemIndex.GetAddress(vm) @@ -201,12 +195,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, - "last_pos": int64(currentPosInt + 1), - }) + return ctx.ScopeManager.AssignVariable("last_pos", *currentPos.Add(¤tPos, &utils.FeltOne)) }, } } diff --git a/pkg/hintrunner/zero/zerohint_usort_test.go b/pkg/hintrunner/zero/zerohint_usort_test.go index 84b2cf15..173f30fb 100644 --- a/pkg/hintrunner/zero/zerohint_usort_test.go +++ b/pkg/hintrunner/zero/zerohint_usort_test.go @@ -96,9 +96,8 @@ func TestZeroHintUsort(t *testing.T) { }, ctxInit: func(ctx *hinter.HintRunnerContext) { ctx.ScopeManager.EnterScope(map[string]any{ - "positions": []int64{8, 6, 4}, - "current_pos": int64(2), - "last_pos": int64(1), + "positions": []fp.Element{*feltInt64(8), *feltInt64(6), *feltInt64(4)}, + "last_pos": *feltInt64(2), }) }, makeHinter: func(ctx *hintTestContext) hinter.Hinter { @@ -106,11 +105,52 @@ func TestZeroHintUsort(t *testing.T) { }, check: func(t *testing.T, ctx *hintTestContext) { allVarValueInScopeEquals(map[string]any{ - "current_pos": int64(4), - "last_pos": int64(3), + "last_pos": *feltInt64(5), "positions": []fp.Element{*feltInt64(8), *feltInt64(6)}, })(t, ctx) - varValueEquals("next_item_index", feltInt64(1))(t, ctx) + varValueEquals("next_item_index", feltInt64(2))(t, ctx) + }, + }, + { + operanders: []*hintOperander{ + {Name: "next_item_index", Kind: uninitialized}, + }, + ctxInit: func(ctx *hinter.HintRunnerContext) { + ctx.ScopeManager.EnterScope(map[string]any{ + "positions": []fp.Element{*feltInt64(90), *feltInt64(80), *feltInt64(70), *feltInt64(60), *feltInt64(50)}, + "last_pos": *feltInt64(0), + }) + }, + makeHinter: func(ctx *hintTestContext) hinter.Hinter { + return newUsortVerifyMultiplicityBodyHint(ctx.operanders["next_item_index"]) + }, + check: func(t *testing.T, ctx *hintTestContext) { + allVarValueInScopeEquals(map[string]any{ + "last_pos": *feltInt64(51), "positions": []fp.Element{*feltInt64(90), *feltInt64(80), *feltInt64(70), *feltInt64(60)}, + })(t, ctx) + + varValueEquals("next_item_index", feltInt64(50))(t, ctx) + }, + }, + { + operanders: []*hintOperander{ + {Name: "next_item_index", Kind: uninitialized}, + }, + ctxInit: func(ctx *hinter.HintRunnerContext) { + ctx.ScopeManager.EnterScope(map[string]any{ + "positions": []fp.Element{*feltInt64(87), *feltInt64(51), *feltInt64(43), *feltInt64(37)}, + "last_pos": *feltInt64(29), + }) + }, + makeHinter: func(ctx *hintTestContext) hinter.Hinter { + return newUsortVerifyMultiplicityBodyHint(ctx.operanders["next_item_index"]) + }, + check: func(t *testing.T, ctx *hintTestContext) { + allVarValueInScopeEquals(map[string]any{ + "last_pos": *feltInt64(38), "positions": []fp.Element{*feltInt64(87), *feltInt64(51), *feltInt64(43)}, + })(t, ctx) + + varValueEquals("next_item_index", feltInt64(8))(t, ctx) }, }, }, diff --git a/pkg/hintrunner/zero/zerohint_utils_test.go b/pkg/hintrunner/zero/zerohint_utils_test.go index 19ed9f80..2a4af3bc 100644 --- a/pkg/hintrunner/zero/zerohint_utils_test.go +++ b/pkg/hintrunner/zero/zerohint_utils_test.go @@ -2,6 +2,7 @@ package zero import ( "fmt" + "reflect" "math/big" "testing" @@ -171,6 +172,14 @@ func varValueInScopeEquals(varName string, expected any) func(t *testing.T, ctx t.Fatalf("%s scope value mismatch:\nhave: %v\nwant: %v", varName, value, expected) } } + case []fp.Element: + { + valueArray := value.([]fp.Element) + expectedArray := expected.([]fp.Element) + if !reflect.DeepEqual(valueArray, expectedArray) { + t.Fatalf("%s scope value mismatch:\nhave: %v\nwant: %v", varName, value, expected) + } + } default: { if value != expected {