Example #1
0
class ConstraintForeachModel(ConstraintScopeModel):
    def __init__(self, lhs: 'FieldArrayModel'):
        super().__init__()
        self.lhs = lhs
        self.index = FieldScalarModel("index", 32, False, False)

        self.iterator = FieldScalarModel("iterator", 32, False, False)

    def build(self, btor) -> 'BoolectorNode':
        # Unroll the constraints
        size = int(self.lhs.size.get_val())
        ret_l = []

        for i in range(size):
            # Set the index variable
            self.index.set_val(i)

            # Build out the constraints for this index
            # Note: some could be redundant
            for c in self.constraint_l:
                ret_l.append(c.build(btor))

        return btor.And(*ret_l)

    def accept(self, v):
        v.visit_constraint_foreach(self)

    def clone(self, deep=False) -> 'ConstraintModel':
        ret = ConstraintForeachModel(self.lhs)

        if deep:
            for c in self.constraint_l:
                ret.constraint_l.append(c.clone(deep))

        return ret
Example #2
0
class FieldArrayModel(FieldCompositeModel):
    """All arrays are processed as if they were variable size."""
    def __init__(self, name, is_scalar, enums, width, is_signed, is_rand,
                 is_rand_sz):
        super().__init__(name, is_rand)
        # width and is_signed only needed for scalar fields
        self.is_enum = (enums is not None)
        self.enums = enums
        self.is_scalar = is_scalar
        self.width = width
        self.is_signed = is_signed
        self.is_rand_sz = is_rand_sz

        # Holds a cached version of the sum constraint
        self.sum_expr_btor = None
        self.sum_expr = None

        # Holds a cached version of the sum constraint
        self.product_expr_btor = None
        self.product_expr = None

        self.size = FieldScalarModel("size", 32, False, is_rand_sz)
        self._set_size(0)

    def append(self, fm):
        super().add_field(fm)
        self._set_size(len(self.field_l))
        fm.is_declared_rand = self.is_declared_rand
        fm.rand_mode = self.is_declared_rand
        self.name_elems()

    def clear(self):
        self.field_l.clear()
        self._set_size(0)

    def pop(self, idx=0):
        self.field_l.pop(idx)
        self._set_size(len(self.field_l))
        self.name_elems()

    def _set_size(self, sz):
        if sz != int(self.size.get_val()):
            self.size.set_val(sz)
            self.sum_expr = None
            self.sum_expr_btor = None
            self.product_expr = None
            self.product_expr_btor = None

    def name_elems(self):
        """Apply an index-based name to all fields"""
        for i, f in enumerate(self.field_l):
            f.name = self.name + "[" + str(i) + "]"

    def pre_randomize(self):
        # Set the size field for arrays that don't
        # have a random size
        if not self.is_rand_sz:
            self._set_size(len(self.field_l))
        FieldCompositeModel.pre_randomize(self)

    def post_randomize(self):
        FieldCompositeModel.post_randomize(self)
        self.sum_expr = None
        self.sum_expr_btor = None

    def add_field(self) -> FieldScalarModel:
        fid = len(self.field_l)
        if self.is_enum:
            ret = super().add_field(
                EnumFieldModel(self.name + "[" + str(fid) + "]", self.enums,
                               self.is_declared_rand))
        else:
            ret = super().add_field(
                FieldScalarModel(self.name + "[" + str(fid) + "]", self.width,
                                 self.is_signed, self.is_declared_rand))
        # Update the size
        self._set_size(len(self.field_l))
        return ret

    def build(self, builder):
        # Called before randomization
        self._set_size(len(self.field_l))
        super().build(builder)

    def get_sum_expr(self):
        if self.sum_expr is None:
            # Build

            # Force the result to be 32-bit, in order to
            # match user expectation
            ret = ExprLiteralModel(0, self.is_signed, 32)
            for i in range(int(self.size.get_val())):
                f = self.field_l[i]
                if ret is None:
                    ret = ExprFieldRefModel(f)
                else:
                    ret = ExprBinModel(ret, BinExprType.Add,
                                       ExprFieldRefModel(f))

            if ret is None:
                ret = ExprLiteralModel(0, self.is_signed, 32)
            self.sum_expr = ret

        return self.sum_expr

    def build_sum_expr(self, btor):
        if self.sum_expr_btor is None:
            self.sum_expr_btor = self.get_sum_expr().build(btor)
        return self.sum_expr_btor

    def get_product_expr(self):
        if self.product_expr is None:
            # Build

            # Force the result to be 32-bit, in order to
            # match user expectation
            if int(self.size.get_val()) == 0:
                ret = ExprLiteralModel(0, self.is_signed, 64)
            else:
                ret = ExprLiteralModel(1, self.is_signed, 64)
            for i in range(int(self.size.get_val())):
                f = self.field_l[i]
                ret = ExprBinModel(ret, BinExprType.Mul, ExprFieldRefModel(f))

            self.product_expr = ret

        return self.product_expr

    def build_product_expr(self, btor):
        if self.product_expr_btor is None:
            self.product_expr_btor = self.get_product_expr().build(btor)
        return self.product_expr_btor

    def accept(self, v):
        v.visit_field_scalar_array(self)
Example #3
0
class FieldArrayModel(FieldCompositeModel):
    """All arrays are processed as if they were variable size."""
    def __init__(self, name, is_scalar, width, is_signed, is_rand, is_rand_sz):
        super().__init__(name, is_rand)
        # width and is_signed only needed for scalar fields
        self.is_scalar = is_scalar
        self.width = width
        self.is_signed = is_signed
        self.is_rand_sz = is_rand_sz
        # Holds a cached version of the sum constraint
        self.sum_expr_btor = None
        self.sum_expr = None

        self.size = FieldScalarModel("size", 32, False, is_rand_sz)

    def append(self, fm):
        super().add_field(fm)
        self.name_elems()

    def clear(self):
        self.field_l.clear()
        self.size.set_val(0)

    def pop(self, idx=0):
        self.field_l.pop(idx)
        self.name_elems()

    def name_elems(self):
        """Apply an index-based name to all fields"""
        for i, f in enumerate(self.field_l):
            f.name = self.name + "[" + str(i) + "]"

    def pre_randomize(self):
        # Set the size field for arrays that don't
        # have a random size
        if not self.is_rand_sz:
            self.size.set_val(len(self.field_l))
        FieldCompositeModel.pre_randomize(self)

    def post_randomize(self):
        FieldCompositeModel.post_randomize(self)
        self.sum_expr = None
        self.sum_expr_btor = None

    def add_field(self) -> FieldScalarModel:
        fid = len(self.field_l)
        return super().add_field(
            FieldScalarModel(self.name + "[" + str(fid) + "]", self.width,
                             self.is_signed, self.is_declared_rand))

    def build(self, builder):
        # Called before randomization
        self.size.set_val(int(len(self.field_l)))
        super().build(builder)

    def get_sum_expr(self):
        if self.sum_expr is None:
            # Build
            ret = None
            for f in self.field_l:
                if ret is None:
                    ret = ExprFieldRefModel(f)
                else:
                    ret = ExprBinModel(ret, BinExprType.Add,
                                       ExprFieldRefModel(f))

            if ret is None:
                ret = ExprLiteralModel(0, False, 32)
            self.sum_expr = ret

        return self.sum_expr

    def build_sum_expr(self, btor):
        if self.sum_expr_btor is None:
            self.sum_expr_btor = self.get_sum_expr().build(btor)
        return self.sum_expr_btor

    def accept(self, v):
        v.visit_field_scalar_array(self)