Ltac fresh_tac :=
   solve [auto]
 || rewrite freshmax_norm in *
 || match goal with
  | H : List.In _ (match ?D with | PureClause _ _ _ _ => _
          | PosSpaceClause _ _ _ => _ | NegSpaceClause _ _ _ => _ end)
     |- _  => destruct D
  | H : List.In _ (match ?D with nil => _ | _ :: _ => _ end) |- _  => destruct D
  | H : List.In _ (match ?D with Eqv _ _ => _ end) |- _  => destruct D
  | H : List.In _ (if ?D then _ else _) |- _ =>
      let H' := fresh in revert H; case_eq D; intros H' H;
           repeat rewrite <- andb_assoc in H';
           try (rewrite andb_true_iff in H'; destruct H' as [H' _])
  | H : expr_eq _ ?e1 = true |- _ => symmetry in H; apply expr_eq_eq' in H;
                                        subst e1
  | H : Ile _ _ |- _ => apply var_max_split' in H; destruct H
  | H : List.In ?c (_ :: _) |- _ => destruct H; [ subst c | ]
  | |- Ile (freshmax_pure_atom (norm_pure_atom _)) _ => unfold norm_pure_atom
  | |- Ile (freshmax_pure_atom (if ?D then _ else _)) _ => destruct D
  end
 || apply freshmax_list_merge
 || simpl freshmax_clause
 || apply Ile_minid
 || apply var_max_intro'
 || (rewrite comp_refl in *; auto)
 || (rewrite freshmax_list_sort; [auto | apply pure_atom_cmp_eq])
 || apply freshmax_insu.

(* Specifications: *)
Lemma freshmax_delete_resolved: forall c m, Ile (freshmax_clause c) m -> Ile (freshmax_clause (delete_resolved c)) m.
Lemma freshmax_rewrite_by: forall m e e' a, Ile (freshmax_expr e) m -> Ile (freshmax_expr e') m -> Ile (freshmax_pure_atom a) m -> Ile (freshmax_pure_atom (rewrite_by e e' a)) m.
Lemma freshmax_demodulate: forall a c m, Ile (freshmax_clause a) m -> Ile (freshmax_clause c) m -> Ile (freshmax_clause (demodulate a c)) m.
Lemma varbound_remove: forall s x s', Included _ (varbound (s, M.remove x s')) (varbound (s, s')).
Lemma freshmax_simplify: forall m l g, (forall c : M.elt, List.In c l -> Ile (freshmax_clause c) m) -> Ile (freshmax_clause g) m -> Ile (freshmax_clause (simplify l g)) m.
Lemma freshmax_sp: forall m d a l, Ile (freshmax_clause d) m -> Ile (freshmax_clause a) m -> (forall c, List.In c l -> Ile (freshmax_clause c) m) -> forall c, List.In c (sp d a l) -> Ile (freshmax_clause c) m.
Lemma freshmax_superpose: forall m d a l, Ile (freshmax_clause d) m -> Ile (freshmax_clause a) m -> (forall c, List.In c l -> Ile (freshmax_clause c) m) -> forall c, List.In c (superpose d a l) -> Ile (freshmax_clause c) m.
Lemma freshmax_infer_list: forall d l m, Ile (freshmax_clause d) m -> (forall c, List.In c l -> Ile (freshmax_clause c) m) -> forall c, List.In c (infer_list d l) -> Ile (freshmax_clause c) m.
Lemma varbound_nonincreasing: forall given unselected giv, M.In giv unselected -> Included _ (varbound (M.add (simplify (M.elements given) giv) given, fold_left (fun (s0 : M.t) (c : M.elt) => if M.mem c (M.add (simplify (M.elements given) giv) given) then s0 else M.add c s0) (infer_list (simplify (M.elements given) giv) (simplify (M.elements given) giv :: M.elements given)) (M.remove giv unselected))) (varbound (given, unselected)).
Lemma varbound_nonincreasing': forall given unselected giv, M.In giv unselected -> Included _ (varbound (M.add (simplify (M.elements given) giv) given, fold_left (fun (s0 : M.t) (c : M.elt) => if M.mem c (M.add (simplify (M.elements given) giv) given) then s0 else M.add c s0) (infer_list (simplify (M.elements given) giv) (M.elements given)) (M.remove giv unselected))) (varbound (given, unselected)).
Lemma simplify_nodup: forall n l c, clause_bound' n (simplify l c) -> clause_bound n (simplify l c).
Lemma one_inference_step_order: forall given unselected new_given new_unselected, M.mem empty_clause unselected = false -> M.is_empty new_unselected = false -> one_inference_step (given, unselected) = (new_given, new_unselected) -> superpose_loop_order (new_given, new_unselected) (given, unselected).