Library Prog

Prog.v: Composition of distributions


Require Export Probas.



Conditional


Definition Mif (A:Type) (b:distr bool) (m1 m2: distr A)
    := Mlet b (fun x:boolif x then m1 else m2).

Lemma Mif_le_compat : (A:Type) (b1 b2:distr bool) (m1 m2 n1 n2: distr A),
    b1 b2m1 m2n1 n2Mif b1 m1 n1 Mif b2 m2 n2.

Hint Resolve Mif_le_compat.

Instance Mif_mon2 : (A:Type) b, monotonic2 (Mif (A:=A) b).
Save.

Definition MIf : (A:Type), distr bool -m> distr A -m> distr A -m> distr A.
Defined.

Lemma MIf_simpl : A b d1 d2, MIf A b d1 d2 = Mif b d1 d2.

Instance if_mon : `{o:ord A} (b:bool), monotonic2 (fun (x y:A) ⇒ if b then x else y).
Save.

Definition If `{o:ord A} (b:bool) : A -m> A -m> A := mon2 (fun (x y:A) ⇒ if b then x else y).

Instance Mif_continuous2 : (A:Type) b, continuous2 (MIf A b).
Save.

Hint Resolve Mif_continuous2.

Instance Mif_cond_continuous : (A:Type), continuous (MIf A).
Save.

Hint Resolve Mif_cond_continuous.

Probabilistic choice


The distribution associated to pchoice p m1 m2 is

f --> p (m1 f) + (1-p) (m2 f)

Definition pchoice : A, UM AM AM A.
Defined.

Lemma pchoice_simpl : A p (m1 m2:M A) f,
      pchoice p m1 m2 f = p * m1 f + [1-]p * m2 f.

Definition Mchoice (A:Type) (p:U) (m1 m2: distr A) : distr A.
Defined.

Lemma Mchoice_simpl : A p (m1 m2:distr A) f,
      μ (Mchoice p m1 m2) f = p * μ m1 f + [1-]p * μ m2 f.

Lemma Mchoice_le_compat : (A:Type) (p:U) (m1 m2 n1 n2: distr A),
        m1m2n1n2Mchoice p m1 n1 Mchoice p m2 n2.
Hint Resolve Mchoice_le_compat.

Add Parametric Morphism (A:Type) : (Mchoice (A:=A))
  with signature Oeq Oeq Oeq Oeq
as Mchoice_eq_compat.
Save.
Hint Immediate Mchoice_eq_compat.

Instance Mchoice_mon2 : (A:Type) (p:U), monotonic2 (Mchoice (A:=A) p).
Save.

Definition MChoice A (p:U) : distr A -m> distr A -m> distr A :=
               mon2 (Mchoice (A:=A) p).

Lemma MChoice_simpl : A (p:U) (m1 m2 : distr A),
MChoice A p m1 m2 = Mchoice p m1 m2.

Lemma Mchoice_sym_le : (A:Type) (p:U) (m1 m2: distr A),
            Mchoice p m1 m2 Mchoice ([1-]p) m2 m1.
Hint Resolve Mchoice_sym_le.

Lemma Mchoice_sym : (A:Type) (p:U) (m1 m2: distr A),
            Mchoice p m1 m2 Mchoice ([1-]p) m2 m1.

Lemma Mchoice_continuous_right
    : (A:Type) (p:U) (m: distr A), continuous (D1:=distr A) (D2:=distr A) (MChoice A p m).
Hint Resolve Mchoice_continuous_right.

Lemma Mchoice_continuous_left : (A:Type) (p:U),
    continuous (D1:=distr A) (D2:=distr A -m> distr A) (MChoice A p).

Lemma Mchoice_continuous :
(A:Type) (p:U), continuous2 (D1:=distr A) (D2:=distr A) (D3:=distr A) (MChoice A p).

Image distribution


Definition im_distr (A B : Type) (f:AB) (m:distr A) : distr B :=
    Mlet m (fun aMunit (f a)).

Lemma im_distr_simpl : A B (f:AB) (m:distr A)(h:BU),
     μ (im_distr f m) h = μ m (fun ah (f a)).

Add Parametric Morphism (A B : Type) : (im_distr (A:=A) (B:=B))
  with signature (feq (A:=A) (B:=B)) Oeq Oeq
  as im_distr_eq_compat.
Save.

Lemma im_distr_comp : A B C (f:AB) (g:BC) (m:distr A),
            im_distr g (im_distr f m) im_distr (fun ag (f a)) m.

Lemma im_distr_id : A (f:AA) (m:distr A), ( x, f x = x) →
            im_distr f m m.

Product distribution


Definition prod_distr (A B : Type)(d1:distr A)(d2:distr B) : distr (A*B) :=
                Mlet d1 (fun xMlet d2 (fun yMunit (x,y))).

Add Parametric Morphism (A B : Type) : (prod_distr (A:=A) (B:=B))
with signature Ole ++> Ole ++> Ole
as prod_distr_le_compat.
Save.
Hint Resolve prod_distr_le_compat.

Add Parametric Morphism (A B : Type) : (prod_distr (A:=A) (B:=B))
with signature Oeq Oeq Oeq
as prod_distr_eq_compat.
Save.
Hint Immediate prod_distr_eq_compat.

Instance prod_distr_mon2 : (A B :Type), monotonic2 (prod_distr (A:=A) (B:=B)).
Save.

Definition Prod_distr (A B :Type): distr A -m> distr B -m> distr (A*B) :=
     mon2 (prod_distr (A:=A) (B:=B)).

Lemma Prod_distr_simpl : (A B:Type)(d1: distr A) (d2:distr B),
     Prod_distr A B d1 d2 = prod_distr d1 d2.

Lemma prod_distr_rect : (A B : Type) (d1: distr A) (d2:distr B) (f:AU)(g:BU),
         μ (prod_distr d1 d2) (fun xyf (fst xy) * g (snd xy)) μ d1 f * μ d2 g.

Lemma prod_distr_fst : (A B : Type) (d1: distr A) (d2:distr B) (f:AU),
             μ (prod_distr d1 d2) (fun xyf (fst xy)) pone d2 * μ d1 f.

Lemma prod_distr_snd : (A B : Type) (d1: distr A) (d2:distr B) (g:BU),
             μ (prod_distr d1 d2) (fun xyg (snd xy)) pone d1 * μ d2 g.

Lemma prod_distr_fst_eq : (A B : Type) (d1: distr A) (d2:distr B),
     pone d2 1 → im_distr (fst (A:=A) (B:=B)) (prod_distr d1 d2) d1.

Lemma prod_distr_snd_eq : (A B : Type) (d1: distr A) (d2:distr B),
       pone d1 1 → im_distr (snd (A:=A) (B:=B)) (prod_distr d1 d2) d2.

Definition swap A B (x:A*B) : B * A := (snd x,fst x).

Definition arg_swap A B (f : MF (A*B)) : MF (B*A) := fun zf (swap z).

Definition Arg_swap A B : MF (A*B) -m> MF (B*A).
Defined.

Lemma Arg_swap_simpl : A B f, Arg_swap A B f = arg_swap f.

Definition prod_distr_com A B (d1: distr A) (d2:distr B) (f : MF (A * B)) :=
      μ (prod_distr d1 d2) f μ (prod_distr d2 d1) (arg_swap f).

Lemma prod_distr_com_eq_compat : A B (d1: distr A) (d2:distr B) (f g: MF (A * B)),
  f gprod_distr_com d1 d2 fprod_distr_com d1 d2 g.

Lemma prod_distr_com_rect : (A B : Type) (d1: distr A) (d2:distr B) (f:AU)(g:BU),
         prod_distr_com d1 d2 (fun xyf (fst xy) * g (snd xy)).

Lemma prod_distr_com_cte : (A B : Type) (d1: distr A) (d2:distr B) (c:U),
         prod_distr_com d1 d2 (fcte (A*B) c).

Lemma prod_distr_com_one : (A B : Type) (d1: distr A) (d2:distr B),
         prod_distr_com d1 d2 (fone (A*B)).

Lemma prod_distr_com_plus : (A B : Type) (d1: distr A) (d2:distr B) (f g:MF (A*B)),
         fplusok f g
         prod_distr_com d1 d2 fprod_distr_com d1 d2 g
         prod_distr_com d1 d2 (fplus f g).

Lemma prod_distr_com_mult : (A B : Type) (d1: distr A) (d2:distr B) (k:U)(f:MF (A*B)),
         prod_distr_com d1 d2 fprod_distr_com d1 d2 (fmult k f).

Lemma prod_distr_com_inv : (A B : Type) (d1: distr A) (d2:distr B) (f:MF (A*B)),
         prod_distr_com d1 d2 fprod_distr_com d1 d2 (finv f).

Lemma prod_distr_com_lub : (A B : Type) (d1: distr A) (d2:distr B) (f:nat -m> MF (A*B)),
         ( n, prod_distr_com d1 d2 (f n)) → prod_distr_com d1 d2 (lub f).

Lemma prod_distr_com_sym : A B (d1:distr A) (d2:distr B) (f:MF (A*B)),
     prod_distr_com d1 d2 fprod_distr_com d2 d1 (arg_swap f).

Lemma discrete_commute : A B (d1:distr A) (d2:distr B) (f:MF (A*B)),
    is_discrete d1prod_distr_com d1 d2 f.

Lemma is_discrete_swap: A B C (d1:distr A) (d2:distr B) (f:ABdistr C),
   is_discrete d1
   Mlet d1 (fun xMlet d2 (fun yf x y)) Mlet d2 (fun yMlet d1 (fun xf x y)).

Definition fst_distr A B (m : distr (A*B)) : distr A := im_distr (fst (B:=B)) m.
Definition snd_distr A B (m : distr (A*B)) : distr B := im_distr (snd (B:=B)) m.

Add Parametric Morphism (A B : Type) : (fst_distr (A:=A) (B:=B))
   with signature Oeq Oeq as fst_distr_eq_compat.
Save.

Add Parametric Morphism (A B : Type) : (snd_distr (A:=A) (B:=B))
   with signature Oeq Oeq as snd_distr_eq_compat.
Save.

Lemma fst_prod_distr : A B (m1:distr A) (m2:distr B),
           fst_distr (prod_distr m1 m2) distr_scale (pone m2) m1.

Lemma snd_prod_distr : A B (m1:distr A) (m2:distr B),
          snd_distr (prod_distr m1 m2) distr_scale (pone m1) m2.

Lemma pone_prod : A B (m1:distr A) (m2:distr B),
          pone (prod_distr m1 m2) pone m1 * pone m2.

Independance of distribution


Definition prod_indep A B (m:distr (A*B)) :=
        distr_scale (pone m) m prod_distr (fst_distr m) (snd_distr m).

Lemma prod_distr_indep : A B (m1:distr A) (m2:distr B), prod_indep (prod_distr m1 m2).

Add Parametric Morphism A B : (prod_indep (A:=A) (B:=B))
   with signature Oeq Basics.impl
   as prod_indep_eq_compat.
Save.
Hint Resolve prod_indep_eq_compat.

Lemma distr_indep_mult
   : A B (m:distr (A*B)), prod_indep m
                      (f1 : MF A) (f2:MF B),
                     pone m * μ m (fun pf1 (fst p) * f2 (snd p))
                     μ (fst_distr m) f1 * μ (snd_distr m) f2.

Range of a distribution


Definition range A (P:AProp) (d: distr A) :=
    f, ( x, P x → 0 f x) → 0 μ d f.

Lemma range_le : A (P:AProp) (d:distr A), range P d
        f g, ( a, P af a g a) → μ d f μ d g.

Lemma range_eq : A (P:AProp) (d:distr A), range P d
        f g, ( a, P af a g a) → μ d f μ d g.

Prog.v: Axiomatic semantics

Definition of correctness judgements

ok p e q is defined as pμ e q up p e q is defined as μ e qp

Definition ok (A:Type) (p:U) (e:distr A) (q:AU) := p μ e q.

Definition okfun (A B:Type)(p:AU)(e:Adistr B)(q:ABU)
  := x:A, ok (p x) (e x) (q x).

Definition okup (A:Type) (p:U) (e:distr A) (q:AU) := μ e q p.

Definition upfun (A B:Type)(p:AU)(e:Adistr B)(q:ABU)
  := x:A, okup (p x) (e x) (q x).

Stability properties

Lemma ok_le_compat : (A:Type) (p p':U) (e:distr A) (q q':AU),
    p' pq q'ok p e qok p' e q'.

Lemma ok_eq_compat : (A:Type) (p p':U) (e e':distr A) (q q':AU),
    p' pq q'e e'ok p e qok p' e' q'.

Add Parametric Morphism (A:Type) : (@ok A)
  with signature Ole --> Oeq Ole Basics.impl
  as ok_le_morphism.
Save.

Add Parametric Morphism (A:Type) : (@ok A)
  with signature Oeq --> Oeq Oeq iff
  as ok_eq_morphism.
Save.

Lemma okfun_le_compat :
(A B:Type) (p p':AU) (e:Adistr B) (q q':ABU),
    p' pq q'okfun p e qokfun p' e q'.

Lemma okfun_eq_compat :
(A B:Type) (p p':AU) (e e':Adistr B) (q q':ABU),
    p' pq q'e e'okfun p e qokfun p' e' q'.

Add Parametric Morphism (A B:Type) : (@okfun A B)
  with signature Ole --> Oeq Ole Basics.impl
  as okfun_le_morphism.
Save.

Add Parametric Morphism (A B:Type) : (@okfun A B)
  with signature Oeq --> Oeq Oeq iff
  as okfun_eq_morphism.
Save.

Lemma ok_mult : (A:Type)(k p:U)(e:distr A)(f : AU),
                           ok p e fok (k*p) e (fmult k f).

Lemma ok_inv : (A:Type)(p:U)(e:distr A)(f : AU),
             ok p e fμ e (finv f) [1-]p.

Lemma okup_le_compat : (A:Type) (p p':U) (e:distr A) (q q':AU),
    p p'q' qokup p e qokup p' e q'.

Lemma okup_eq_compat : (A:Type) (p p':U) (e e':distr A) (q q':AU),
    p p'q q'e e'okup p e qokup p' e' q'.

Lemma upfun_le_compat : (A B:Type) (p p':AU) (e:Adistr B)
    (q q':ABU),
    p p'q'qupfun p e qupfun p' e q'.

Lemma okup_mult : (A:Type)(k p:U)(e:distr A)(f : AU), okup p e fokup (k*p) e (fmult k f).

Basic rules

Rules for application:

  • ok r a p and x, ok (p x) (f x) q implies ok r (f a) q
  • up r a p and x, up (p x) (f x) q implies up r (f a) q

Lemma apply_rule : (A B:Type)(a:(distr A))(f:Adistr B)(r:U)(p:AU)(q:BU),
    ok r a pokfun p f (fun xq) → ok r (Mlet a f) q.

Lemma okup_apply_rule : (A B:Type)(a:distr A)(f:Adistr B)(r:U)(p:AU)(q:BU),
    okup r a pupfun p f (fun xq) → okup r (Mlet a f) q.

Rules for abstraction

Lemma lambda_rule : (A B:Type)(f:Adistr B)(p:AU)(q:ABU),
   ( x:A, ok (p x) (f x) (q x)) → okfun p f q.

Lemma okup_lambda_rule : (A B:Type)(f:Adistr B)(p:AU)(q:ABU),
   ( x:A, okup (p x) (f x) (q x)) → upfun p f q.


Rules for conditional

  • ok p1 e1 q and ok p2 e2 q implies ok (p1 * μ b (χ true) + p2 * μ b (χ false) if( b then e1 else e2) q
  • up p1 e1 q and up p2 e2 q implies up (p1 * μ b (χ true) + p2 * μ b (χ false) if( b then e1 else e2) q

Lemma combiok : (A:Type) p q (f1 f2 : AU), p [1-]qfplusok (fmult p f1) (fmult q f2).
Hint Extern 1 ⇒ apply combiok.

Lemma fmult_fplusok : (A:Type) p q (f1 f2 : AU), fplusok f1 f2fplusok (fmult p f1) (fmult q f2).
Hint Resolve fmult_fplusok.

Lemma ifok : f1 f2, fplusok (fmult f1 ctrue) (fmult f2 cfalse).
Hint Resolve ifok.

Lemma Mif_eq : (A:Type)(b:(distr bool))(f1 f2:distr A)(q:MF A),
        μ (Mif b f1 f2) q (μ f1 q) * (μ b ctrue) + (μ f2 q) * (μ b cfalse).

Lemma Mif_eq2 : (A : Type) (b : distr bool) (f1 f2 : distr A) (q : MF A),
  μ (Mif b f1 f2) q μ b ctrue * μ f1 q + μ b cfalse * μ f2 q.

Lemma ifrule :
   (A:Type)(b:(distr bool))(f1 f2:distr A)(p1 p2:U)(q:AU),
       ok p1 f1 qok p2 f2 q
       → ok (p1 * (μ b ctrue) + p2 * (μ b cfalse)) (Mif b f1 f2) q.

Lemma okup_ifrule :
   (A:Type)(b:(distr bool))(f1 f2:distr A)(p1 p2:U)(q:AU),
       okup p1 f1 qokup p2 f2 q
       → okup (p1 * (μ b ctrue) + p2 * (μ b cfalse)) (Mif b f1 f2) q.


Rule for fixpoints

with φ x = F φ x, p an increasing sequence of functions starting from 0

f i, ( x, ok (p i x) f q x, ok p (i+1) x (F f x) q) implies x, ok (lub p x) (φ x) q
Section Fixrule.
Variables A B : Type.

Variable F : (Adistr B) -m> (Adistr B).

Section Ruleseq.
Variable q : ABU.

Lemma fixrule_Ulub : (p : AnatU),
   ( x:A, p x O 0)->
   ( (i:nat) (f:Adistr B),
      (okfun (fun xp x i) f q) → okfun (fun xp x (S i)) (fun xF f x) q)
   → okfun (fun xUlub (p x)) (Mfix F) q.

Lemma fixrule : (p : Anat -m> U),
   ( x:A, p x O 0)->
   ( (i:nat) (f:Adistr B),
      (okfun (fun xp x i) f q) → okfun (fun xp x (S i)) (fun xF f x) q)
   → okfun (fun xlub (p x)) (Mfix F) q.

Lemma fixrule_up_Ulub : (p : AnatU),
   ( (i:nat) (f:Adistr B),
      (upfun (fun xp x i) f q) → upfun (fun xp x (S i)) (fun xF f x) q)
   → upfun (fun xUlub (p x)) (Mfix F) q.

Lemma fixrule_up_lub : (p : Anat -m> U),
   ( (i:nat) (f:Adistr B),
      (upfun (fun xp x i) f q) → upfun (fun xp x (S i)) (fun xF f x) q)
   → upfun (fun xlub (p x)) (Mfix F) q.

Lemma okup_fixrule_glb :
    p : Anat -m U,
   ( (i:nat) (f:Adistr B),
       (upfun (fun xp x i) f q) → upfun (fun xp x (S i)) (fun xF f x) q)
   → upfun (fun xglb (p x)) (Mfix F) q.
End Ruleseq.

Lemma okup_fixrule_inv : (p : AU) (q : ABU),
   ( (f:Adistr B), upfun p f qupfun p (fun xF f x) q)
           → upfun p (Mfix F) q.


Rules using commutation properties


Section TransformFix.

Section Fix_muF.
Variable q : ABU.
Variable muF : MF A -m> MF A.

Definition admissible (P:(Adistr B) → Prop) := P 0 f, P fP (F f).

Lemma admissible_true : admissible (fun fTrue).

Lemma admissible_le_fix :
  continuous (D1:=Adistr B) (D2:=Adistr B) Fadmissible (fun ff Mfix F).
BUG: rewrite fails

Lemma muF_stable : stable muF.

Definition mu_muF_commute_le :=
   f x, f Mfix Fμ (F f x) (q x) muF (fun yμ (f y) (q y)) x.
Hint Unfold mu_muF_commute_le.

Section F_muF_results.
Hypothesis F_muF_le : mu_muF_commute_le.

Lemma mu_mufix_le : x, μ (Mfix F x) (q x) mufix muF x.
Hint Resolve mu_mufix_le.

Lemma muF_le : f, muF f f
      → x, μ (Mfix F x) (q x) f x.

Hypothesis muF_F_le :
     f x, f Mfix FmuF (fun yμ (f y) (q y)) x μ (F f x) (q x).

Lemma mufix_mu_le : x, mufix muF x μ (Mfix F x) (q x).

End F_muF_results.
Hint Resolve mu_mufix_le mufix_mu_le.

Lemma mufix_mu :
   ( f x, f Mfix Fμ (F f x) (q x) muF (fun yμ (f y) (q y)) x)
   → x, mufix muF x μ (Mfix F x) (q x).
Hint Resolve mufix_mu.
End Fix_muF.

Section Fix_Term.

Definition pterm : MF A := fun (x:A) ⇒ μ (Mfix F x) (fone B).
Variable muFone : MF A -m> MF A.

Hypothesis F_muF_eq_one :
   f x, f Mfix Fμ (F f x) (fone B) muFone (fun yμ (f y) (fone B)) x.

Hypothesis muF_cont : continuous muFone.

Lemma muF_pterm : pterm muFone pterm.
Hint Resolve muF_pterm.
End Fix_Term.

Section Fix_muF_Term.

Variable q : ABU.
Definition qinv x y := [1-]q x y.

Variable muFqinv : MF A -m> MF A.

Hypothesis F_muF_le_inv : mu_muF_commute_le qinv muFqinv.

Lemma muF_le_term : f, muFqinv (finv f) finv f
     x, f x & pterm x μ (Mfix F x) (q x).

Lemma muF_le_term_minus :
f, f ptermmuFqinv (fminus pterm f) fminus pterm f
     x, f x μ (Mfix F x) (q x).

Variable muFq : MF A -m> MF A.

Hypothesis F_muF_le : mu_muF_commute_le q muFq.

Lemma muF_eq : f, muFq f fmuFqinv (finv f) finv f
     x, pterm x 1 → μ (Mfix F x) (q x) f x.

End Fix_muF_Term.
End TransformFix.

Section LoopRule.
Variable q : ABU.
Variable stop : Adistr bool.
Variable step : Adistr A.
Variable a : U.

Definition Loop : MF A -m> MF A.
Defined.

Lemma Loop_eq :
     f x, Loop f x = μ (stop x) (fun bif b then a else μ (step x) f).

Definition loop := mufix Loop.

Lemma Mfixvar :
  ( (f:Adistr B),
      okfun (fun xLoop (fun yμ (f y) (q y)) x) (fun xF f x) q)
 → okfun loop (Mfix F) q.

Definition up_loop : MF A := nufix Loop.

Lemma Mfixvar_up :
  ( (f:Adistr B),
      upfun (fun xLoop (fun yμ (f y) (q y)) x) (fun xF f x) q)
 → upfun up_loop (Mfix F) q.

End LoopRule.

End Fixrule.

Rules for intervals

Distributions operates on intervals

Definition Imu : A:Type, distr A → (AIU) → IU.
Defined.

Lemma low_Imu : (A:Type) (e:distr A) (F: AIU),
             low (Imu e F) = μ e (fun xlow (F x)).

Lemma up_Imu : (A:Type) (e:distr A) (F: AIU),
             up (Imu e F) = μ e (fun xup (F x)).

Lemma Imu_monotonic : (A:Type) (e:distr A) (F G : AIU),
            ( x, Iincl (F x) (G x)) → Iincl (Imu e F) (Imu e G).

Lemma Imu_stable_eq : (A:Type) (e:distr A) (F G : AIU),
            ( x, Ieq (F x) (G x)) → Ieq (Imu e F) (Imu e G).
Hint Resolve Imu_monotonic Imu_stable_eq.

Lemma Imu_singl : (A:Type) (e:distr A) (f:AU),
           Ieq (Imu e (fun xsingl (f x))) (singl (μ e f)).

Lemma Imu_inf : (A:Type) (e:distr A) (f:AU),
           Ieq (Imu e (fun xinf (f x))) (inf (μ e f)).

Lemma Imu_sup : (A:Type) (e:distr A) (f:AU),
           Iincl (Imu e (fun xsup (f x))) (sup (μ e f)).

Lemma Iin_mu_Imu :
    (A:Type) (e:distr A) (F:AIU) (f:AU),
           ( x, Iin (f x) (F x)) → Iin (μ e f) (Imu e F).
Hint Resolve Iin_mu_Imu.

Definition Iok (A:Type) (I:IU) (e:distr A) (F:AIU) := Iincl (Imu e F) I.
Definition Iokfun (A B:Type)(I:AIU) (e:Adistr B) (F:ABIU)
               := x, Iok (I x) (e x) (F x).

Lemma Iin_mu_Iok :
    (A:Type) (I:IU) (e:distr A) (F:AIU) (f:AU),
           ( x, Iin (f x) (F x)) → Iok I e FIin (μ e f) I.

Stability

Lemma Iok_le_compat : (A:Type) (I J:IU) (e:distr A) (F G:AIU),
   Iincl I J → ( x, Iincl (G x) (F x)) → Iok I e FIok J e G.

Lemma Iokfun_le_compat : (A B:Type) (I J:AIU) (e:Adistr B) (F G:ABIU),
   ( x, Iincl (I x) (J x)) → ( x y, Iincl (G x y) (F x y)) → Iokfun I e FIokfun J e G.

Rule for values


Lemma Iunit_eq : (A: Type) (a:A) (F:AIU), Ieq (Imu (Munit a) F) (F a).

Rule for application


Lemma Ilet_eq : (A B : Type) (a:distr A) (f:Adistr B)(I:IU)(G:BIU),
   Ieq (Imu (Mlet a f) G) (Imu a (fun xImu (f x) G)).
Hint Resolve Ilet_eq.

Lemma Iapply_rule : (A B : Type) (a:distr A) (f:Adistr B)(I:IU)(F:AIU)(G:BIU),
    Iok I a FIokfun F f (fun xG) → Iok I (Mlet a f) G.

Rule for abstraction

Lemma Ilambda_rule : (A B:Type)(f:Adistr B)(F:AIU)(G:ABIU),
   ( x:A, Iok (F x) (f x) (G x)) → Iokfun F f G.

Rule for conditional


Lemma Imu_Mif_eq : (A:Type)(b:distr bool)(f1 f2:distr A)(F:AIU),
 Ieq (Imu (Mif b f1 f2) F) (Iplus (Imultk (μ b ctrue) (Imu f1 F)) (Imultk (μ b cfalse) (Imu f2 F))).

Lemma Iifrule :
   (A:Type)(b:(distr bool))(f1 f2:distr A)(I1 I2:IU)(F:AIU),
       Iok I1 f1 FIok I2 f2 F
       → Iok (Iplus (Imultk (μ b ctrue) I1) (Imultk (μ b cfalse) I2)) (Mif b f1 f2) F.

Rule for fixpoints

with φ x = F φ x , p a decreasing sequence of intervals functions ( p (i+1) x is a bubset of (p i x) such that (p 0 x) contains 0 for all x.

f i, ( x, iok (p i x) f (q x)) ⇒ x, iok (p (i+1) x) (F f x) (q x) implies x, iok (lub p x) (φ x) (q x)
Section IFixrule.
Variables A B : Type.

Variable F : (Adistr B) -m> (Adistr B).

Section IRuleseq.
Variable Q : ABIU.

Variable I : Anat -m> IU.

Lemma Ifixrule :
   ( x:A, Iin 0 (I x O)) →
   ( (i:nat) (f:Adistr B),
      (Iokfun (fun xI x i) f Q) → Iokfun (fun xI x (S i)) (fun xF f x) Q)
   → Iokfun (fun xIlim (I x)) (Mfix F) Q.
End IRuleseq.

Section ITransformFix.

Section IFix_muF.
Variable Q : ABIU.
Variable ImuF : (AIU) -m> (AIU).

Lemma ImuF_stable : I J, IJImuF I ImuF J.

Section IF_muF_results.
Hypothesis Iincl_F_ImuF :
     f x, f Mfix F
                      Iincl (Imu (F f x) (Q x)) (ImuF (fun yImu (f y) (Q y)) x).

Lemma Iincl_fix_ifix : x, Iincl (Imu (Mfix F x) (Q x)) (fixp (D:=AIU) ImuF x).
Hint Resolve Iincl_fix_ifix.

End IF_muF_results.

End IFix_muF.
End ITransformFix.
End IFixrule.

Rules for Flip


Lemma Flip_ctrue : μ Flip ctrue ½.

Lemma Flip_cfalse : μ Flip cfalse ½.

Lemma ok_Flip : q : boolU, ok (½ * q true + ½ * q false) Flip q.

Lemma okup_Flip : q : boolU, okup (½ * q true + ½ * q false) Flip q.

Hint Resolve ok_Flip okup_Flip Flip_ctrue Flip_cfalse.

Lemma Flip_eq : q : boolU, μ Flip q ½ * q true + ½ * q false.
Hint Resolve Flip_eq.

Lemma IFlip_eq : Q : boolIU, Ieq (Imu Flip Q) (Iplus (Imultk ½ (Q true)) (Imultk ½ (Q false))).
Hint Resolve IFlip_eq.

Rules for total (well-founded) fixpoints


Section Wellfounded.
Variables A B : Type.
Variable R : AAProp.
Hypothesis Rwf : well_founded R.
Variable F : x, ( y, R y xdistr B) → distr B.

Definition WfFix : Adistr B := Fix Rwf (fun _distr B) F.

Hypothesis Fext : x f g, ( y (p:R y x), f y p g y p) → F f F g.

Lemma Acc_iter_distr :
    x, r s : Acc R x, Acc_iter (fun _distr B) F r Acc_iter (fun _distr B) F s.

Lemma WfFix_eq : x, WfFix x F (fun (y:A) (p:R y x) ⇒ WfFix y).

Variable P : distr BProp.
Hypothesis Pext : m1 m2, m1 m2P m1P m2.

Lemma WfFix_ind :
     ( x f, ( y (p:R y x), P (f y p)) → P (F f))
  → x, P (WfFix x).

End Wellfounded.

Ltac distrsimpl := match goal with
 | |- (Ole (fmont (μ ?d1) ?f) (fmont (μ ?d2) ?g)) ⇒ apply (mu_le_compat (m1:=d1) (m2:=d2) (Ole_refl d1) (f:=f) (g:=g)); intro
 | |- (Oeq (fmont (μ ?d1) ?f) (fmont (μ ?d2) ?g)) ⇒ apply (mu_eq_compat (m1:=d1) (m2:=d2) (Oeq_refl d1) (f:=f) (g:=g)); intro
 | |- (Oeq (Munit ?x) (Munit ?y)) ⇒ apply (Munit_eq_compat x y)
 | |- (Oeq (Mlet ?x1 ?f) (Mlet ?x2 ?g))
              ⇒ apply (Mlet_eq_compat (m1:=x1) (m2:=x2) (M1:=f) (M2:=g) (Oeq_refl x1)); intro
 | |- (Ole (Mlet ?x1 ?f) (Mlet ?x2 ?g))
              ⇒ apply (Mlet_le_compat (m1:=x1) (m2:=x2) (M1:=f) (M2:=g) (Ole_refl x1)); intro
 | |- context [(fmont (μ (Mlet ?m ?M)) ?f)] ⇒ rewrite (Mlet_simpl m M f)
 | |- context [(fmont (μ (Munit ?x)) ?f)] ⇒ rewrite (Munit_simpl f x)
 | |- context [(Mlet (Mlet ?m ?M) ?f)] ⇒ rewrite (Mlet_assoc m M f)
 | |- context [(Mlet (Munit ?x) ?f)] ⇒ rewrite (Mlet_unit x f)
 | |- context [(fmont (μ Flip) ?f)] ⇒ rewrite (Flip_simpl f)
 | |- context [(fmont (μ (Discrete ?d)) ?f)] ⇒ rewrite (Discrete_simpl d);
                                                           rewrite (discrete_simpl (coeff d) (points d) f)
 | |- context [(fmont (μ (Random ?n)) ?f)] ⇒ rewrite (Random_simpl n);
                                                           rewrite (random_simpl n f)
 | |- context [(fmont (μ (Mif ?b ?f ?g)) ?h)] ⇒ unfold Mif
 | |- context [(fmont (μ (Mchoice ?p ?m1 ?m2)) ?f)] ⇒ rewrite (Mchoice_simpl p m1 m2 f)
 | |- context [(fmont (μ (im_distr ?f ?m)) ?h)] ⇒ rewrite (im_distr_simpl f m h)
 | |- context [(fmont (μ (prod_distr ?m1 ?m2)) ?h)] ⇒ unfold prod_distr
 | |- context [((mon ?f (fmonotonic:=?mf)) ?x)] ⇒ rewrite (mon_simpl f (mf:=mf) x)
end.