docs: def run(
      draco_query: List[str],
      constants: Dict[str, str] = None,
      files: List[str] = None,
      relax_hard=False,
      silence_warnings=False,
      debug=False,
      clear_cache=False,
  ) -> Optional[Result]:
      """ Run clingo to compute a completion of a partial spec or violations. """
  
      # Clear file cache. useful during development in notebooks.
      if clear_cache and file_cache:
          logger.warning("Cleared file cache")
          file_cache.clear()
  
      stderr, stdout = run_clingo(
          draco_query, constants, files, relax_hard, silence_warnings, debug
      )
  
      try:
          json_result = json.loads(stdout)
      except json.JSONDecodeError:
          logger.error("stdout: %s", stdout)
          logger.error("stderr: %s", stderr)
          raise
  
      if stderr:
          logger.error(stderr)
  
      result = json_result["Result"]
  
      if result == "UNSATISFIABLE":
          logger.info("Constraints are unsatisfiable.")
          return None
      elif result == "OPTIMUM FOUND":
          # get the last witness, which is the best result
          answers = json_result["Call"][0]["Witnesses"][-1]
  
          logger.debug(answers["Value"])
  
          return Result(
              clyngor.Answers(answers["Value"]).sorted,
              cost=json_result["Models"]["Costs"][0],
          )
      elif result == "SATISFIABLE":
          answers = json_result["Call"][0]["Witnesses"][-1]
  
          assert (
              json_result["Models"]["Number"] == 1
          ), "Should not have more than one model if we don't optimize"
  
          logger.debug(answers["Value"])
  
          return Result(clyngor.Answers(answers["Value"]).sorted)
      else:
          logger.error("Unsupported result: %s", result)
          return None