diff --git a/sot/opcode_translator/executor/variables/container.py b/sot/opcode_translator/executor/variables/container.py index 0df587ac4..530156217 100644 --- a/sot/opcode_translator/executor/variables/container.py +++ b/sot/opcode_translator/executor/variables/container.py @@ -1,8 +1,12 @@ from __future__ import annotations +import operator +from functools import reduce from typing import TYPE_CHECKING, Any +from ....utils import log_do from ....utils.exceptions import InnerError, NotImplementException +from ..guard import StringifyExpression from ..pycode_generator import PyCodeGen from ..tracker import ( ConstTracker, @@ -38,6 +42,28 @@ def bool(self): bool(self), self.graph, DummyTracker([self]) ) + def make_stringify_guard(self) -> StringifyExpression: + assert ( + self.tracker.is_traceable() + ), "Cannot make guard from a non-traceable variable." + + frame_value_tracer = self.tracker.trace_value_from_frame() + log_do( + 4, + lambda: print( + f"[Guard]: guard_fn for {self}, tracker={self.tracker.__class__.__name__}, value={frame_value_tracer.expr}" + ), + ) + len_guard = StringifyExpression( + f"len({frame_value_tracer.expr}) == {len(self)}", + frame_value_tracer.free_vars, + ) + return reduce( + operator.and_, + [len_guard] + + [item.make_stringify_guard() for item in self.get_items()], + ) + class ListVariable(ContainerVariable): def __init__(