Skip to content

Commit

Permalink
[bug]: implement correctly UsortVerifyMultiplicityBody hint (#398)
Browse files Browse the repository at this point in the history
* implement correctly UsortVerifyMultiplicityBody

* reassign positions in the scope after popping element

* address comments

* change for fields instead of int64

* correct pointer error
  • Loading branch information
TAdev0 committed May 10, 2024
1 parent 88e8dfa commit 1033f3e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 27 deletions.
31 changes: 10 additions & 21 deletions pkg/hintrunner/zero/zerohint_usort.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(&currentPos, &lastPosFelt)
newNextItemIndexMemoryValue := memory.MemoryValueFromFieldElement(&newNextItemIndexValue)

// Save `next_item_index` value in address
addrNextItemIndex, err := nextItemIndex.GetAddress(vm)
Expand All @@ -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(&currentPos, &utils.FeltOne))
},
}
}
Expand Down
52 changes: 46 additions & 6 deletions pkg/hintrunner/zero/zerohint_usort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,61 @@ 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 {
return newUsortVerifyMultiplicityBodyHint(ctx.operanders["next_item_index"])
},
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)
},
},
},
Expand Down
9 changes: 9 additions & 0 deletions pkg/hintrunner/zero/zerohint_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package zero

import (
"fmt"
"reflect"

"math/big"
"testing"
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 1033f3e

Please sign in to comment.