Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
Typeclass-based setoids, tactics and standard instances.
Set Implicit Arguments. Unset Strict Implicit. Generalizable Variables A. Require Import Coq.Program.Program. Require Import Relation_Definitions. Require Export Coq.Classes.RelationClasses. Require Export Coq.Classes.Morphisms.
A setoid wraps an equivalence.
Class Setoid A := { equiv : relation A ; setoid_equiv :> Equivalence equiv }. (* Too dangerous instance *) (* Program Instance [ eqa : Equivalence A eqA ] => *) (* equivalence_setoid : Setoid A := *) (* equiv := eqA ; setoid_equiv := eqa. *)
Shortcuts to make proof search easier.
A:Typesa:Setoid AReflexive equivtypeclasses eauto. Qed.A:Typesa:Setoid AReflexive equivA:Typesa:Setoid ASymmetric equivtypeclasses eauto. Qed.A:Typesa:Setoid ASymmetric equivA:Typesa:Setoid ATransitive equivtypeclasses eauto. Qed. Existing Instance setoid_refl. Existing Instance setoid_sym. Existing Instance setoid_trans.A:Typesa:Setoid ATransitive equiv
Standard setoids.
(* Program Instance eq_setoid : Setoid A := *) (* equiv := eq ; setoid_equiv := eq_equivalence. *) Instance iff_setoid : Setoid Prop := { equiv := iff ; setoid_equiv := iff_equivalence }.
Overloaded notations for setoid equivalence and inequivalence. Not to be confused with eq and =.
Subset objects should be first coerced to their underlying type, but that notation doesn't work in the standard case then.
(* Notation " x == y " := (equiv (x :>) (y :>)) (at level 70, no associativity) : type_scope. *) Notation " x == y " := (equiv x y) (at level 70, no associativity) : type_scope. Notation " x =/= y " := (complement equiv x y) (at level 70, no associativity) : type_scope.
Use the clsubstitute command which substitutes an equality in every hypothesis.
Ltac clsubst H := lazymatch type of H with ?x == ?y => substitute H ; clear H x end. Ltac clsubst_nofail := match goal with | [ H : ?x == ?y |- _ ] => clsubst H ; clsubst_nofail | _ => idtac end.
subst× will try its best at substituting every equality in the goal.
Tactic Notation "clsubst" "*" := clsubst_nofail.forall (A : Type) (H : Setoid A) (x y z : A), x =/= y -> y == z -> x =/= zforall (A : Type) (H : Setoid A) (x y z : A), x =/= y -> y == z -> x =/= zA:TypeH:Setoid Ax, y, z:AH0:x =/= yH1:y == zH2:x == zFalseA:TypeH:Setoid Ax, y, z:AH0:x =/= yH1:y == zH2:x == zH3:z == yFalsecontradiction. Qed.A:TypeH:Setoid Ax, y, z:AH0:x =/= yH1:y == zH2:x == zH3:z == yH4:x == yFalseforall (A : Type) (H : Setoid A) (x y z : A), x == y -> y =/= z -> x =/= zforall (A : Type) (H : Setoid A) (x y z : A), x == y -> y =/= z -> x =/= zA:TypeH:Setoid Ax, y, z:AH0:x == yH1:y =/= zH2:x == zFalseA:TypeH:Setoid Ax, y, z:AH0:x == yH1:y =/= zH2:x == zH3:y == xFalsecontradiction. Qed. Ltac setoid_simplify_one := match goal with | [ H : (?x == ?x)%type |- _ ] => clear H | [ H : (?x == ?y)%type |- _ ] => clsubst H | [ |- (?x =/= ?y)%type ] => let name:=fresh "Hneq" in intro name end. Ltac setoid_simplify := repeat setoid_simplify_one. Ltac setoidify_tac := match goal with | [ s : Setoid ?A, H : ?R ?x ?y |- _ ] => change R with (@equiv A R s) in H | [ s : Setoid ?A |- context C [ ?R ?x ?y ] ] => change (R x y) with (@equiv A R s x y) end. Ltac setoidify := repeat setoidify_tac.A:TypeH:Setoid Ax, y, z:AH0:x == yH1:y =/= zH2:x == zH3:y == xH4:y == zFalse
Every setoid relation gives rise to a morphism, in fact every partial setoid does.
Instance setoid_morphism `(sa : Setoid A) : Proper (equiv ++> equiv ++> iff) equiv := proper_prf. Instance setoid_partial_app_morphism `(sa : Setoid A) (x : A) : Proper (equiv ++> iff) (equiv x) := proper_prf.
Partial setoids don't require reflexivity so we can build a partial setoid on the function space.
Class PartialSetoid (A : Type) :=
{ pequiv : relation A ; pequiv_prf :> PER pequiv }.
Overloaded notation for partial setoid equivalence.
Infix "=~=" := pequiv (at level 70, no associativity) : type_scope.
Reset the default Program tactic.
Obligation Tactic := program_simpl.