Недостаточно и не нужно объявлять отношение как RewriteRelation
. Вы должны доказать свойства, обеспечивающие логическую корректность перезаписи, наиболее распространенной из которых является транзитивность (но вам часто требуется и рефлексивность, и даже симметрия).
Как вы уже заметили, плагин для переписывания setoid на самом деле состоит из двух систем-близнецов, одна для отношений в Prop
, а другая для отношений в Type
(имена модулей имеют префикс C
). Обычно вы используете только одно или другое, в зависимости от вида ваших отношений.
Я не уверен, что SSReflect меняет ситуацию, но вот пример использования переписывания setoid без него:
Require Setoid.
для активации плагина. Require Import CEquivalence.
, если вы используете Type
отношения, или Require Import Equivalence.
, если вы используете Prop
отношения. - Реализация экземпляров для свойства отношений эквивалентности (любые из
Reflexive
, Symmetric
, Transitive
или Equivalence
для всех 3). - Вам также может потребоваться доказать
Proper
лемм, если термины, которые вы переписываете не находятся на верхнем уровне цели.
Обратите внимание, что на шаге 3, если вы не можете / не можете доказать все три свойства, вам не разрешат переписывать во всех направлениях.
Насколько мне известно, такие команды, как Add Parametric Relation
, которые вы можете найти в документации, являются просто образцом, который предназначен для этих случаев. Но, по моему мнению, как пользователь, они добавляют ненужный слой косвенности; прямое объявление экземпляров делает вещи более понятными (особенно если вы уже знакомы с классами типов).
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
*)