Reputation: 35
I can't use Ssreflect's rewrite with setoids. Although I don't think this information is relevant to solve the problem, I'm using this formulation of category theory in coq: https://github.com/jwiegley/category-theory.
As far as I know, Ssreflect's rewriting can use user-defined equivalence relations if a suitable RewriteRelation
Typeclass instance can be resolved.
Context { x y : obj[C]}.
About RewriteRelation.
(* ∀ A : Type, crelation A → Prop *)
Instance equivrw : (@RewriteRelation (x ~> y) (@equiv (x ~> y) (homset x y))) := {}. (* defined and correctly type-checked *)
About equivrw.
(* RewriteRelation equiv (coq omits implicit arguments) *)
Lemma test_rwrel (a b c : x ~> y) : (@equiv (x ~> y) (homset x y) a b) -> (@equiv (x ~> y) (homset x y) b c) -> (@equiv (x ~> y) (homset x y) a c).
Proof.
move => ->.
(* Fails: not a rewritable relation: (a ≈ b) in rule __top_assumption_ *)
Using the default rewrite tactic instead works (even without manually declaring the instance, because something similar is already declared in the library).
Something funny:
Instance equivrw : (@RewriteRelation False equiv) := {}.
Lemma test_rwrel (a b c : False) : (equiv a b) -> (equiv b c) -> (equiv a c).
Proof.
move => ->.
by [].
Qed.
This works fine.
Why doesn't SSReflect use the RewriteRelation instance I have manually declared to rewrite by user-defined equivalence? Thanks in advance.
EDIT:
I have figured out why Ssreflect doesn't see my relation. Apparently, you can add relations to be used with Ssreflect's rewrite only with Add Parametric Relation
which is documented in the manual, and RewriteRelation
instances don't change anything. I have tried to create a fake relation using axioms and adding it with Add Parametric Relation
and rewriting
works correctly. But now I'm again in trouble. The relation that I want to be able to use has type crelation (x ~> y)
(which is (x ~> y) -> (x ~> y) -> Type
), but to use Add Parametric Relation
I need a term with type relation (x ~> y)
(which is (x ~> y) -> (x ~> y) -> Prop
. Why two different kinds of relations (relation
and crelation
) have been defined in the standard library?
How can I convert a crelation
to a relation
without getting universe inconsistency errors?
And I still can't understand why the above example with False
works.
Upvotes: 1
Views: 550
Reputation: 33389
It's not sufficient nor necessary to declare a relation as a RewriteRelation
. You must prove properties that ensure that the rewriting is logically valid, the most common one being transitivity (but you often want also reflexivity, and even symmetry as well).
As you have noticed already, the setoid rewriting plugin is actually made of two twin systems, one for relations in Prop
, and one for relations in Type
(whose module names are prefixed with C
). You generally use just one or the other, depending on the sort of your relations.
I'm not sure whether SSReflect changes things, but here is an example usage of setoid rewriting without it:
Require Setoid.
to activate the plugin.Require Import CEquivalence.
if you use Type
relations, or Require Import Equivalence.
if you use Prop
relations.Reflexive
, Symmetric
, Transitive
, or Equivalence
for all 3).Proper
lemmas if the terms you are rewriting are not at the toplevel of the goal.Note that at step 3, if you do not/cannot prove all three properties, then you will not be allowed to rewrite in all directions.
To the best of my knowledge, commands such as Add Parametric Relation
you may find in the documentation are just boilerplate that desugar to these instances. But in my opinion as a user, they add an unnecessary layer of indirection; declaring the instances directly makes things more understandable (especially if you're already familiar with type classes).
Require Setoid. (* 1 *)
Require Import CMorphisms. (* 2 *)
Axiom obj : Type.
Axiom equiv : obj -> obj -> Type.
Axiom cat : forall a b c, equiv a b -> equiv b c -> equiv a c.
(* 3 *)
Instance Transitive_equiv : Transitive equiv.
Proof.
exact cat.
Qed.
(* Example usage *)
Goal forall a b c,
equiv a b -> equiv b c -> equiv a c.
Proof.
intros a b c H1 H2.
rewrite H1.
(* or,
rewrite H2
*)
Upvotes: 2