(* Copyright 2012-2015 by Adam Petcher.				* * Use of this source code is governed by the license described	* * in the LICENSE file at the root of the source tree.		*)
(* Rules used to prove facts based on the distribution semantics *)
Set Implicit Arguments.
Local Open Scope rat_scope.
Local Open Scope comp_scope.
Local Open Scope list_scope.
intuition.
unfold evalDist.
eapply eqRat_refl.
Qed.
intros.
specialize (getSupport_correct c1).
specialize (getSupport_correct c2).
intros.
inversion H0; clear H0.
inversion H1; clear H1.
intuition.
apply H3.
intuition.
eapply H4; eauto.
eapply eqRat_trans.
eapply H.
eauto.
eapply H4.
intuition.
eapply H3; eauto.
eapply eqRat_trans.
eapply eqRat_symm.
eapply H.
eauto.
Qed.
intuition.
eapply NoDup_Permutation; intuition.
apply in_map_iff in H3.
destruct H3.
intuition.
subst.
eapply H0.
trivial.
eapply in_map_iff.
econstructor.
split.
2:{
eapply H0.
assert (x = f (f_inv x)).
symmetry.
eapply H.
trivial.
rewrite H4 in H3.
eapply H3.
}
eapply H.
trivial.
Qed.
induction ls; intuition.
simpl in *.
intuition.
eapply H1.
rewrite <- (H a).
rewrite <- (H a0).
f_equal.
trivial.
eapply IHls; eauto.
Qed.
induction ls; intuition; simpl in *.
econstructor.
inversion H0; clear H0; subst.
econstructor; eauto.
intuition.
apply in_map_iff in H0.
destruct H0.
intuition.
assert (x = a).
rewrite <- (H x); intuition.
rewrite <- (H a); intuition.
f_equal.
trivial.
subst.
intuition.
Qed.
intuition.
specialize (getSupport_correct c); intuition.
inversion H.
eauto.
Qed.
induction ls; simpl in *; intuition.
inversion H; clear H; subst.
destruct (P a).
econstructor; eauto.
intuition.
eapply filter_In in H.
intuition.
eapply IHls; eauto.
Qed.

Lemma evalDist_getSupport_perm : forall (A B : Set)(c1 : Comp A)(c2 : Comp B) (f : A -> B)(f_inv : B -> A),
(forall b, In b (getSupport c2) -> (f (f_inv b)) = b) ->
(forall a, In a (getSupport c1) -> (f_inv (f a)) = a) ->
(forall a, In a (getSupport c1) -> eqRat (evalDist c1 a) (evalDist c2 (f a))) ->
(forall a, In a (getSupport c2) -> eqRat (evalDist c2 a) (evalDist c1 (f_inv a))) ->
Permutation (map f (getSupport c1)) (getSupport c2).