<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def DeleteArtifactsFromDatastore(artifact_names, reload_artifacts=True):
 """Deletes a list of artifacts from the data store."""

  artifacts_list = sorted(
      REGISTRY.GetArtifacts(reload_datastore_artifacts=reload_artifacts))

  to_delete = set(artifact_names)
  deps = set()
  for artifact_obj in artifacts_list:
    if artifact_obj.name in to_delete:
      continue

    if GetArtifactDependencies(artifact_obj) & to_delete:
      deps.add(str(artifact_obj.name))

  if deps:
    raise ValueError(
        "Artifact(s) %s depend(s) on one of the artifacts to delete." %
        (",".join(deps)))

  store = ArtifactCollection(rdfvalue.RDFURN("aff4:/artifact_store"))
  all_artifacts = list(store)

  filtered_artifacts, found_artifact_names = set(), set()
  for artifact_value in all_artifacts:
    if artifact_value.name in to_delete:
      found_artifact_names.add(artifact_value.name)
    else:
      filtered_artifacts.add(artifact_value)

  if len(found_artifact_names) != len(to_delete):
    not_found = to_delete - found_artifact_names
    raise ValueError("Artifact(s) to delete (%s) not found." %
                     ",".join(not_found))

  # TODO(user): this is ugly and error- and race-condition- prone.
  # We need to store artifacts not in a *Collection, which is an
  # append-only object, but in some different way that allows easy
  # deletion. Possible option - just store each artifact in a separate object
  # in the same folder.
  store.Delete()

  with data_store.DB.GetMutationPool() as pool:
    for artifact_value in filtered_artifacts:
      store.Add(artifact_value, mutation_pool=pool)

  if data_store.RelationalDBEnabled():
    for artifact_name in to_delete:
      data_store.REL_DB.DeleteArtifact(str(artifact_name))

  for artifact_value in to_delete:
    REGISTRY.UnregisterArtifact(artifact_value)