MathClasses.misc.setoid_tactics

Require Import Setoid canonical_names.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y) :=
  setoidreplace ((=) x y) idtac.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y)
  "at" int_or_var_list(o) :=
  setoidreplaceat ((=) x y) idtac o.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y)
  "in" hyp(id) :=
  setoidreplacein ((=) x y) id idtac.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y)
  "in" hyp(id)
  "at" int_or_var_list(o) :=
  setoidreplaceinat ((=) x y) id idtac o.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y)
  "by" tactic3(t) :=
  setoidreplace ((=) x y) ltac:t.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y)
  "at" int_or_var_list(o)
  "by" tactic3(t) :=
  setoidreplaceat ((=) x y) ltac:t o.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y)
  "in" hyp(id)
  "by" tactic3(t) :=
  setoidreplacein ((=) x y) id ltac:t.

Tactic Notation "mc_setoid_replace" constr(x) "with" constr(y)
  "in" hyp(id)
  "at" int_or_var_list(o)
  "by" tactic3(t) :=
  setoidreplaceinat ((=) x y) id ltac:t o.

Ltac setoid_subst :=
  repeat (match goal with
  | E : ?x = ?e |- _is_var x; lazymatch e with context [x] ⇒ fail | _rewrite ?E in *; clear x E end
  | E : ?e = ?x |- _is_var x; lazymatch e with context [x] ⇒ fail | _rewrite <-?E in *; clear x E end
  | E : ?x ?e |- _is_var x; lazymatch e with context [x] ⇒ fail | _rewrite ?E in *; clear x E end
  | E : ?e ?x |- _is_var x; lazymatch e with context [x] ⇒ fail | _rewrite <-?E in *; clear x E end
  end).

Ltac setoid_discriminate :=
  repeat intro; exfalso;
  match goal with
  | E : _ = _ |- _solve [inversion E]
  | E : _ _ |- _discriminate E
  end.