def preconstrain(self, value, variable): """ Add a preconstraint that ``variable == value`` to the state. :param value: The concrete value. Can be a bitvector or a bytestring or an integer. :param variable: The BVS to preconstrain. """ if not isinstance(value, claripy.ast.Base): value = self.state.solver.BVV(value, len(variable)) elif value.op != 'BVV': raise ValueError("Passed a value to preconstrain that was not a BVV or a string") if variable.op not in claripy.operations.leaf_operations: l.warning("The variable %s to preconstrain is not a leaf AST. This may cause replacement failures in the " "claripy replacement backend.", variable) l.warning("Please use a leaf AST as the preconstraining variable instead.") # Add the constraint with a simplification avoidance tag. If # this is not added, claripy may simplify new constraints if # they are redundant with respect to the preconstraints. This # is problematic when the preconstraints are removed. constraint = (variable == value).annotate(claripy.SimplificationAvoidanceAnnotation()) l.debug("Preconstraint: %s", constraint) # add the constraint for reconstraining later if next(iter(variable.variables)) in self.variable_map: l.warning("%s is already preconstrained. Are you misusing preconstrainer?", next(iter(variable.variables))) self.variable_map[next(iter(variable.variables))] = constraint self.preconstraints.append(constraint) if o.REPLACEMENT_SOLVER in self.state.options: self.state.solver._solver.add_replacement(variable, value, invalidate_cache=False) else: self.state.add_constraints(constraint) if not self.state.satisfiable(): l.warning("State went unsat while adding preconstraints")
def test_simplification_annotations(): s = claripy.Solver() x = claripy.BVS("x", 32) s.add(x > 10) s.add(x > 11) s.add((x > 12).annotate(claripy.SimplificationAvoidanceAnnotation())) assert len(s.constraints) == 3 s.simplify() assert len(s.constraints) == 2