(* -*- coding: utf-8 -*- *) (************************************************************************) (* * The Rocq Prover / The Rocq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \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 relations, tactics and standard instances
This is the basic theory needed to formalize morphisms and setoids.
Author: Matthieu Sozeau Institution: LRI, CNRS UMR 8623 - University Paris Sud
*)
(** Rewrite relation on a given support: declares a relation as a rewrite relation for use by the generalized rewriting tactic. It helps choosing if a rewrite should be handled by the generalized or the regular rewriting tactic using leibniz equality. Users can declare an [RewriteRelation A RA] anywhere to declare default relations on a given type `A`. This is also done automatically by the [Declare Relation A RA] commands. It has no mode declaration: it will assign `?A := Prop, ?R := iff` on an entirely unspecified query
`RewriteRelation ?A ?R`, or any prefered rewrite relation of priority < 2. *)
Class RewriteRelation (RA : relation A).
(** Leibniz equality. *) Section Leibniz. GlobalInstance eq_Reflexive : Reflexive (@eq A) := @eq_refl A. GlobalInstance eq_Symmetric : Symmetric (@eq A) := @eq_sym A. GlobalInstance eq_Transitive : Transitive (@eq A) := @eq_trans A.
(** Leibinz equality [eq] is an equivalence relation. The instance has low priority as it is always applicable
if only the type is constrained. *)
GlobalProgramInstance eq_equivalence : Equivalence (@eq A) | 10. End Leibniz.
(** Leibniz disequality. *) Section LeibnizNot. (** Disequality is symmetric. *) GlobalInstance neq_Symmetric : Symmetric (fun x y : A => x <> y) := (@not_eq_sym A). End LeibnizNot. End Defs.
(** Any [Equivalence] declared in the context is automatically considered a rewrite relation. This only applies if the relation is at least partially
defined: setoid_rewrite won't try to infer arbitrary user rewrite relations. *)
Ltac equiv_rewrite_relation R :=
tryif is_evar R then fail else class_apply equivalence_rewrite_relation.
#[global] Hint Extern 10 (@RewriteRelation ?A ?R) => equiv_rewrite_relation R : typeclass_instances.
(** Hints to drive the typeclass resolution avoiding loops
due to the use of full unification. *)
#[global] Hint Extern 1 (Reflexive (complement _)) => class_apply @irreflexivity : typeclass_instances.
#[global] Hint Extern 3 (Symmetric (complement _)) => class_apply complement_Symmetric : typeclass_instances.
#[global] Hint Extern 3 (Irreflexive (complement _)) => class_apply complement_Irreflexive : typeclass_instances.
(** We now develop a generalization of results on relations for arbitrary predicates. The resulting theory can be applied to homogeneous binary relations but also to
arbitrary n-ary predicates. *)
LocalOpenScope list_scope.
(** A compact representation of non-dependent arities, with the codomain singled-out. *)
(* Note, we do not use [list Type] because it imposes unnecessary universe constraints *) Inductive Tlist : Type := Tnil : Tlist | Tcons : Type -> Tlist -> Tlist. LocalInfix"::" := Tcons.
Fixpoint arrows (l : Tlist) (r : Type) : Type := match l with
| Tnil => r
| A :: l' => A -> arrows l' r end.
(** We can define abbreviations for operation and relation types based on [arrows]. *)
Definition unary_operation A := arrows (A::Tnil) A. Definition binary_operation A := arrows (A::A::Tnil) A. Definition ternary_operation A := arrows (A::A::A::Tnil) A.
(** We define n-ary [predicate]s as functions into [Prop]. *)
Notation predicate l := (arrows l Prop).
(** Unary predicates, or sets. *)
Definition unary_predicate A := predicate (A::Tnil).
(** Homogeneous binary relations, equivalent to [relation A]. *)
Definition binary_relation A := predicate (A::A::Tnil).
(** We can close a predicate by universal or existential quantification. *)
Fixpoint predicate_all (l : Tlist) : predicate l -> Prop := match l with
| Tnil => fun f => f
| A :: tl => fun f => forall x : A, predicate_all tl (f x) end.
Fixpoint predicate_exists (l : Tlist) : predicate l -> Prop := match l with
| Tnil => fun f => f
| A :: tl => fun f => exists x : A, predicate_exists tl (f x) end.
(** Pointwise extension of a binary operation on [T] to a binary operation on functions whose codomain is [T].
For an operator on [Prop] this lifts the operator to a binary operation. *)
Fixpoint pointwise_extension {T : Type} (op : binary_operation T)
(l : Tlist) : binary_operation (arrows l T) := match l with
| Tnil => fun R R' => op R R'
| A :: tl => fun R R' => fun x => pointwise_extension op tl (R x) (R' x) end.
(** Pointwise lifting, equivalent to doing [pointwise_extension] and closing using [predicate_all]. *)
Fixpoint pointwise_lifting (op : binary_relation Prop) (l : Tlist) : binary_relation (predicate l) := match l with
| Tnil => fun R R' => op R R'
| A :: tl => fun R R' => forall x, pointwise_lifting op tl (R x) (R' x) end.
(** The n-ary equivalence relation, defined by lifting the 0-ary [iff] relation. *)
Next Obligation. intro l; induction l ; firstorder. Qed.
Next Obligation. intro l; induction l ; firstorder. Qed.
Next Obligation. intro l.
fold pointwise_lifting. induction l as [|T l IHl].
- firstorder.
- intros x y z H H0 x0. pose (IHl (x x0) (y x0) (z x0)).
firstorder. Qed.
#[global] ProgramInstance predicate_implication_preorder {l} :
PreOrder (@predicate_implication l).
Next Obligation. intro l; induction l ; firstorder. Qed.
Next Obligation. intro l. induction l as [|T l IHl].
- firstorder.
- intros x y z H H0 x0. pose (IHl (x x0) (y x0) (z x0)). firstorder. Qed.
(** We define the various operations which define the algebra on binary relations,
from the general ones. *)
Section Binary.
Context {A : Type}.
Definition relation_equivalence : relation (relation A) :=
@predicate_equivalence (_::_::Tnil).
(** *** Partial Order. A partial order is a preorder which is additionally antisymmetric. We give an equivalent definition, up-to an equivalence relation
on the carrier. *)
Class PartialOrder eqA `{equ : Equivalence A eqA} R `{preo : PreOrder A R} :=
partial_order_equivalence : relation_equivalence eqA (relation_conjunction R (flip R)).
(** The equivalence proof is sufficient for proving that [R] must be a morphism for equivalence (see Morphisms). It is also sufficient to
show that [R] is antisymmetric w.r.t. [eqA] *)
GlobalInstance partial_order_antisym `(PartialOrder eqA R) : Antisymmetric A eqA R. Proofwithauto.
reduce_goal. poseproof partial_order_equivalence as poe. do 3 red in poe. apply <- poe. firstorder. Qed.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.