def not_inside(self, rhs): lhs_e = pop_expr() if isinstance(rhs, rangelist): return expr(ExprUnaryModel( UnaryExprType.Not, ExprInModel(lhs_e, rhs.range_l))) elif isinstance(rhs, list_t): return expr(ExprUnaryModel( UnaryExprType.Not, ExprInModel(lhs_e, ExprRangelistModel( [ExprFieldRefModel(rhs.get_model())])))) else: raise Exception("Unsupported 'not_inside' argument of type " + str(type(rhs)))
def visit_expr_unary(self, e : ExprUnaryModel): if self.do_copy_level > 0: self._expr = ExprUnaryModel( e.op, self.expr(e.expr)) else: super().visit_expr_unary(e)
def __invert__(self): self.to_expr() lhs = pop_expr() return expr(ExprUnaryModel(UnaryExprType.Not, lhs))
def visit_constraint_dist(self, c): # We replace the dist constraint with an equivalent # set of hard and soft constraints scope = ConstraintDistScopeModel(c) ranges = ExprRangelistModel() for w in c.weights: if w.rng_rhs is not None: # two-value range ranges.add_range(ExprRangeModel(w.rng_lhs, w.rng_rhs)) else: # single value ranges.add_range(w.rng_lhs) # First, create an 'in' constraint to restrict # values to the appropriate value set in_c = ConstraintExprModel(ExprInModel(c.lhs, ranges)) scope.addConstraint(in_c) # Now, we need to add exclusion constraints for any # zero weights # (!w) -> (lhs != [val]) # (!w) -> (lns not in [rng]) for w in c.weights: if w.rng_rhs is not None: scope.addConstraint( ConstraintImpliesModel( ExprBinModel(w.weight, BinExprType.Eq, ExprLiteralModel(0, False, 8)), [ ConstraintExprModel( ExprUnaryModel( UnaryExprType.Not, ExprBinModel( ExprBinModel(c.lhs, BinExprType.Ge, w.rng_lhs), BinExprType.And, ExprBinModel(c.lhs, BinExprType.Le, w.rng_rhs)))) ])) else: scope.addConstraint( ConstraintImpliesModel( ExprBinModel(w.weight, BinExprType.Eq, ExprLiteralModel(0, False, 8)), [ ExprUnaryModel( UnaryExprType.Not, ExprBinModel(c.lhs, BinExprType.Eq, w.rng_lhs)) ])) # Form a list of non-zero weighted tuples of weight/range # Sort in ascending order weight_l = [] total_w = 0 for i, w in enumerate(c.weights): weight = int(w.weight.val()) total_w += weight if weight > 0: weight_l.append((weight, i)) weight_l.sort(key=lambda w: w[0]) seed_v = self.rng.randint(1, total_w) # Find the first range i = 0 while i < len(weight_l): seed_v -= weight_l[i][0] if seed_v <= 0: break i += 1 if i >= len(weight_l): i = len(weight_l) - 1 scope.target_range = weight_l[i][1] target_w = c.weights[weight_l[i][1]] dist_soft_c = None if target_w.rng_rhs is not None: dist_soft_c = ConstraintSoftModel( ExprBinModel( ExprBinModel(c.lhs, BinExprType.Ge, target_w.rng_lhs), BinExprType.And, ExprBinModel(c.lhs, BinExprType.Le, target_w.rng_rhs))) else: dist_soft_c = ConstraintSoftModel( ExprBinModel(c.lhs, BinExprType.Eq, target_w.rng_lhs)) # Give dist constraints a high priority to allow # them to override all user-defined soft constraints dist_soft_c.priority = 1000000 scope.set_dist_soft_c(dist_soft_c) self.override_constraint(scope)