Skip to content

Commit

Permalink
feat: SquashDictInnerContinueLoop hint (#406)
Browse files Browse the repository at this point in the history
* temp

* temp

* SquashDictInnerContinueLoop

* update comment

* address comments

* use 3 as offset instead of 4

* temp

* address comments
  • Loading branch information
TAdev0 committed May 16, 2024
1 parent 9265163 commit 464e81f
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions pkg/hintrunner/zero/hintcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const (
// ------ Dictionaries hints related code ------
defaultDictNewCode string = "if '__dict_manager' not in globals():\n from starkware.cairo.common.dict import DictManager\n __dict_manager = DictManager()\n\nmemory[ap] = __dict_manager.new_default_dict(segments, ids.default_value)"
squashDictInnerAssertLenKeys string = "assert len(keys) == 0"
squashDictInnerContinueLoop string = "ids.loop_temps.should_continue = 1 if current_access_indices else 0"
squashDictInnerLenAssert string = "assert len(current_access_indices) == 0"
squashDictInnerNextKey string = "assert len(keys) > 0, 'No keys left but remaining_accesses > 0.'\nids.next_key = key = keys.pop()"

Expand Down
2 changes: 2 additions & 0 deletions pkg/hintrunner/zero/zerohint.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64
return createDefaultDictNewHinter(resolver)
case squashDictInnerAssertLenKeys:
return createSquashDictInnerAssertLenKeysHinter()
case squashDictInnerContinueLoop:
return createSquashDictInnerContinueLoopHinter(resolver)
case squashDictInnerLenAssert:
return createSquashDictInnerLenAssertHinter()
case squashDictInnerNextKey:
Expand Down
51 changes: 51 additions & 0 deletions pkg/hintrunner/zero/zerohint_dictionaries.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/NethermindEth/cairo-vm-go/pkg/utils"
VM "github.com/NethermindEth/cairo-vm-go/pkg/vm"
"github.com/NethermindEth/cairo-vm-go/pkg/vm/memory"
"github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
f "github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
)

Expand Down Expand Up @@ -88,6 +89,56 @@ func createSquashDictInnerAssertLenKeysHinter() (hinter.Hinter, error) {
return newSquashDictInnerAssertLenKeysHint(), nil
}

// SquashDictInnerContinueLoop hint determines if the loop should continue
// based on remaining access indices
//
// `newSquashDictInnerContinueLoopHint` takes 1 operander as argument
// - `loopTemps` variable is a struct containing a `should_continue` field
//
// `newSquashDictInnerContinueLoopHint`writes 0 or 1 in the `should_continue` field
// depending on whether the `current_access_indices` array contains items or not
func newSquashDictInnerContinueLoopHint(loopTemps hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "SquashDictInnerContinueLoop",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
//> ids.loop_temps.should_continue = 1 if current_access_indices else 0

currentAccessIndices_, err := ctx.ScopeManager.GetVariableValue("current_access_indices")
if err != nil {
return err
}

currentAccessIndices, ok := currentAccessIndices_.([]fp.Element)
if !ok {
return fmt.Errorf("casting currentAccessIndices_ into an array of felts failed")
}

loopTempsAddr, err := loopTemps.GetAddress(vm)
if err != nil {
return err
}

if len(currentAccessIndices) == 0 {
resultMemZero := memory.MemoryValueFromFieldElement(&utils.FeltZero)
return hinter.WriteToNthStructField(vm, loopTempsAddr, resultMemZero, int16(3))

} else {
resultMemOne := memory.MemoryValueFromFieldElement(&utils.FeltOne)
return hinter.WriteToNthStructField(vm, loopTempsAddr, resultMemOne, int16(3))
}
},
}
}

func createSquashDictInnerContinueLoopHinter(resolver hintReferenceResolver) (hinter.Hinter, error) {
loopTemps, err := resolver.GetResOperander("loop_temps")
if err != nil {
return nil, err
}

return newSquashDictInnerContinueLoopHint(loopTemps), nil
}

// SquashDictInnerAssertLenKeys hint asserts the length of the current
// access indices for a given key is zero
// `current_access_indices` is a reversed order list of access indices
Expand Down
38 changes: 38 additions & 0 deletions pkg/hintrunner/zero/zerohint_dictionaries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,44 @@ func TestZeroHintDictionaries(t *testing.T) {
errCheck: errorTextContains("assertion `len(keys) == 0` failed"),
},
},
"SquashDictInnerContinueLoop": {
{
operanders: []*hintOperander{
{Name: "loop_temps.index_delta_minus1", Kind: apRelative, Value: feltInt64(0)},
{Name: "loop_temps.index_delta", Kind: apRelative, Value: feltInt64(0)},
{Name: "loop_temps.ptr_delta", Kind: apRelative, Value: feltInt64(0)},
{Name: "loop_temps.should_continue", Kind: uninitialized},
},
ctxInit: func(ctx *hinter.HintRunnerContext) {
err := ctx.ScopeManager.AssignVariable("current_access_indices", []fp.Element{*feltUint64(1), *feltUint64(2), *feltUint64(3)})
if err != nil {
t.Fatal(err)
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newSquashDictInnerContinueLoopHint(ctx.operanders["loop_temps.index_delta_minus1"])
},
check: varValueEquals("loop_temps.should_continue", feltInt64(1)),
},
{
operanders: []*hintOperander{
{Name: "loop_temps.index_delta_minus1", Kind: apRelative, Value: feltInt64(0)},
{Name: "loop_temps.index_delta", Kind: apRelative, Value: feltInt64(0)},
{Name: "loop_temps.ptr_delta", Kind: apRelative, Value: feltInt64(0)},
{Name: "loop_temps.should_continue", Kind: uninitialized},
},
ctxInit: func(ctx *hinter.HintRunnerContext) {
err := ctx.ScopeManager.AssignVariable("current_access_indices", []fp.Element{})
if err != nil {
t.Fatal(err)
}
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newSquashDictInnerContinueLoopHint(ctx.operanders["loop_temps.index_delta_minus1"])
},
check: varValueEquals("loop_temps.should_continue", feltInt64(0)),
},
},
"SquashDictInnerLenAssert": {
{
operanders: []*hintOperander{},
Expand Down

0 comments on commit 464e81f

Please sign in to comment.