docs: def remove_preconstraints(self, to_composite_solver=True, simplify=True):
          """
          Remove the preconstraints from the state.
  
          If you are using the zen plugin, this will also use that to filter the constraints.
  
          :param to_composite_solver:     Whether to convert the replacement solver to a composite solver. You probably
                                          want this if you're switching from tracing to symbolic analysis.
          :param simplify:                Whether to simplify the resulting set of constraints.
          """
          if not self.preconstraints:
              return
  
          # cache key set creation
          precon_cache_keys = set()
  
          for con in self.preconstraints:
              precon_cache_keys.add(con.cache_key)
  
          # if we used the replacement solver we didn't add constraints we need to remove so keep all constraints
          if o.REPLACEMENT_SOLVER in self.state.options:
              new_constraints = self.state.solver.constraints
          else:
              new_constraints = list(filter(lambda x: x.cache_key not in precon_cache_keys, self.state.solver.constraints))
  
  
          if self.state.has_plugin("zen_plugin"):
              new_constraints = self.state.get_plugin("zen_plugin").filter_constraints(new_constraints)
  
          if to_composite_solver:
              self.state.options.discard(o.REPLACEMENT_SOLVER)
              self.state.options.add(o.COMPOSITE_SOLVER)
  
          # clear the solver's internal memory and replace it with the new solver options and constraints
          self.state.solver.reload_solver(new_constraints)
  
          if simplify:
              l.debug("simplifying solver...")
              self.state.solver.simplify()
              l.debug("...simplification done")