let reduce_by_disjunction ~result ~env states n p =
  if State_set.is_empty states
  then states
  else if (State_set.length states) * (count_disjunction p) <= n
  then begin
      let treat_state acc state =
        let env = overwrite_current_state env state in
        let treat_pred pred acc =
          let result = reduce_by_predicate ~result env true pred in
          if Cvalue.Model.equal (env_current_state result) state
          then raise Does_not_improve
          else State_set.add (env_current_state result) acc
        in
        try
          fold_on_disjunction treat_pred p acc
        with
          Does_not_improve -> State_set.add state acc
      in
      State_set.fold treat_state State_set.empty states
    end
  else
    State_set.fold
      (fun acc state ->
        let env = overwrite_current_state env state in
        let reduced = reduce_by_predicate ~result env true p in
        State_set.add (env_current_state reduced) acc)
      State_set.empty
      states