CoRN.model.structures.QposInf


Require Export QArith.
Require Export Qpossec.
Require Import QposMinMax.


Set Implicit Arguments.

Open Local Scope Q_scope.
Open Local Scope Qpos_scope.

Qpos

We choose to define Q+ as the disjoint union of Qpos and an Infinity token.

Inductive Q+ : Set :=
| Qpos2QposInf : QposQ+
| : Q+.

Bind Scope QposInf_scope with Q+.
Delimit Scope QposInf_scope with Q+.

Qpos2QposInf is an injection from Qpos to Q+ that we declare as a coercion.
Coercion Qpos2QposInf : Qpos >-> Q+.

This bind operation is useful for lifting operations to work on Q+. It will map to .
Definition QposInf_bind (f : QposQ+) (x:Q+) :=
 match x with
 | Qpos2QposInf x'f x'
 |
 end.

Lemma QposInf_bind_id : x, QposInf_bind (fun ee) x = x.
Proof.
 intros [x|]; reflexivity.
Qed.

Equality
Definition QposInfEq (a b:Q+) :=
 match a, b with
 | Qpos2QposInf x, Qpos2QposInf yQeq x y
 | , True
 | _, _False
 end.

Lemma QposInfEq_refl x : QposInfEq x x.
Proof.
  destruct x as [x|]. apply Qeq_refl.
  simpl. trivial.
Qed.

Lemma QposInfEq_sym x y : QposInfEq x yQposInfEq y x.
Proof.
  destruct x as [x|], y as [y|]; simpl; trivial. apply Qeq_sym.
Qed.

Lemma QposInfEq_trans x y z : QposInfEq x yQposInfEq y zQposInfEq x z.
Proof.
  destruct x as [x|], y as [y|], z as [z|]; simpl; try tauto. apply Qeq_trans.
Qed.

Add Relation Q+ QposInfEq
 reflexivity proved by QposInfEq_refl
 symmetry proved by QposInfEq_sym
 transitivity proved by QposInfEq_trans as QposInfSetoid.

Instance: Proper (QposEq ==> QposInfEq) Qpos2QposInf.
Proof. firstorder. Qed.

Instance QposInf_bind_wd (f : QposQ+) {f_wd : Proper (QposEq ==> QposInfEq) f} :
  Proper (QposInfEq ==> QposInfEq) (QposInf_bind f).
Proof.
  intros [x|] [y|] E; simpl; auto.
   destruct E.
  destruct E.
Qed.

Addition
Definition QposInf_plus (x y : Q+) : Q+ :=
QposInf_bind (fun x'QposInf_bind (fun y'x'+y') y) x.

Instance: Proper (QposInfEq ==> QposInfEq ==> QposInfEq) QposInf_plus.
Proof with auto.
  intros [x1|] [y1|] E1 [x2|] [y2|] E2; simpl...
  apply Qplus_comp...
Qed.

Multiplication
Definition QposInf_mult (x y : Q+) : Q+ :=
QposInf_bind (fun x'QposInf_bind (fun y'x'×y') y) x.

Instance: Proper (QposInfEq ==> QposInfEq ==> QposInfEq) QposInf_mult.
Proof with auto.
  intros [x1|] [y1|] E1 [x2|] [y2|] E2; simpl...
  apply Qmult_comp...
Qed.

Order
Definition QposInf_le (x y: Q+) : Prop :=
match y with
| True
| Qpos2QposInf y'
 match x with
 | False
 | Qpos2QposInf x'x' y'
 end
end.

Minimum
Definition QposInf_min (x y : Q+) : Q+ :=
match x with
| y
| Qpos2QposInf x'
 match y with
 | x'
 | Qpos2QposInf y'Qpos2QposInf (Qpos_min x' y')
 end
end.

Instance: Proper (QposInfEq ==> QposInfEq ==> QposInfEq) QposInf_min.
Proof with intuition.
  intros [x1|] [y1|] E1 [x2|] [y2|] E2; simpl in ×...
  apply Qpos_min_compat_Proper...
Qed.

Lemma QposInf_min_lb_l : x y, QposInf_le (QposInf_min x y) x.
Proof.
 intros [x|] [y|]; simpl; try auto.
  apply Qpos_min_lb_l.
 apply Qle_refl.
Qed.

Lemma QposInf_min_lb_r : x y, QposInf_le (QposInf_min x y) y.
Proof.
 intros [x|] [y|]; simpl; try auto.
  apply Qpos_min_lb_r.
 apply Qle_refl.
Qed.

Infix "+" := QposInf_plus : QposInf_scope.
Infix "×" := QposInf_mult : QposInf_scope.