Library prosa.classic.util.bigord

Require Import prosa.classic.util.tactics.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop.

(* Lemmas about big operators over Ordinals that use Ordinal functions.
   There is no support for them in ssreflect. *)

Section BigOrdFunOrd.

  Definition fun_ord_to_nat {n} {T} (x0: T) (f: 'I_n T) : T.
  (* if x < n, apply the function f in the (Ordinal x: 'I_n), else return default x0. *)
    intro x; destruct (x < n) eqn:LT;
      [by apply (f (Ordinal LT)) | by apply ].
  Defined.

  Lemma eq_fun_ord_to_nat :
     n {T: Type} x0 (f: 'I_n T) (x: 'I_n),
      (fun_ord_to_nat f) x = f x.
  Proof.
    ins; unfold fun_ord_to_nat; des_eqrefl.
      by f_equal; apply ord_inj.
      by destruct x; ins; rewrite i in EQ.
  Qed.


  Lemma eq_bigr_ord T n op idx r (P : pred 'I_n)
                    (F1: T) (F2: 'I_n T) :
    ( i, P i i = i)
    \big[op/idx]_(i r | P i) i = \big[op/idx]_(i r | P i) i.
  Proof.
    induction r; ins; first by rewrite 2!big_nil.
    rewrite 2!big_cons; destruct (P a) eqn:EQ;
      by rewrite IHr; ins; rewrite H; ins.
  Qed.


  Lemma big_mkord_ord {T} {n} {op} {idx} x0 (P : pred 'I_n) (F: 'I_n T) :
    \big[op/idx]_(i < n | P i) F i =
      \big[op/idx]_(i < n | P i) (fun_ord_to_nat F) i.
  Proof.
    have EQ := eq_bigr_ord T n op idx _ _ (fun_ord_to_nat F) F.
    rewrite EQ; [by ins | by ins; rewrite eq_fun_ord_to_nat].
  Qed.


End BigOrdFunOrd.