(* Copyright 2010 IMDEA Software Institute Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *)
(******************************************************************************)
(* This file defines ordType - the structure for types with a decidable       *)
(* (strict) order relation.                                                   *)
(* ordType is a subclass of mathcomp's eqType                                 *)
(* This file also defines some important instances of ordType                 *)
(******************************************************************************)
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Module Ordered.
Section RawMixin.
Structure mixin_of (T : eqType) :=
Mixin {ordering : rel T;
_ : irreflexive ordering;
_ : transitive ordering;
_ : forall x y, [|| ordering x y, x == y | ordering y x]}.
End RawMixin.
(* the class takes a naked type T and returns all the *)
(* relatex mixins; the inherited ones and the added ones *)
Section ClassDef.
Record class_of (T : Type) := Class {
base : Equality.class_of T;
mixin : mixin_of (EqType T base)}.
Local Coercion base : class_of >-> Equality.class_of.
Structure type : Type := Pack {sort : Type; _ : class_of sort}.
Local Coercion sort : type >-> Sortclass.
Variables (T : Type) (cT : type).
Definition class := let: Pack _ c as cT' := cT return class_of cT' in c.
Definition clone c of phant_id class c := @Pack T c.
(* produce an ordered type out of the inherited mixins *)
(* equalize m0 and m by means of a phantom; will be exploited *)
(* further down in the definition of OrdType *)
Definition pack b (m0 : mixin_of (EqType T b)) :=
fun m & phant_id m0 m => Pack (@Class T b m).
Definition eqType := Eval hnf in EqType cT class.
End ClassDef.
Module Exports.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical Structure eqType.
Notation ordType := Ordered.type.
Notation OrdMixin := Mixin.
Notation OrdType T m := (@pack T _ m _ id).
Definition ord T : rel (sort T) := (ordering (mixin (class T))).
Notation "[ 'ordType' 'of' T 'for' cT ]" := (@clone T cT _ id)
(at level 0, format "[ 'ordType'  'of'  T  'for'  cT ]") : form_scope.
Notation "[ 'ordType' 'of' T ]" := (@clone T _ _ id)
(at level 0, format "[ 'ordType'  'of'  T ]") : form_scope.
End Exports.
End Ordered.
Export Ordered.Exports.
Definition oleq (T : ordType) (t1 t2 : T) := ord t1 t2 || (t1 == t2).
Prenex Implicits ord oleq.
Section Lemmas.
Variable T : ordType.
Implicit Types x y : T.

(* Specifications: *)
Lemma irr : irreflexive (@ord T).
Lemma sorted_oleq s : sorted (@ord T) s -> sorted (@oleq T) s.
End Totality.