proposition: Lemma GEN_GEN_HYB_equiv i: GEN_HYB_pkg i ≈₀ GEN_HYB_EVAL_pkg i ∘ EVAL true.
proof: Proof. apply eq_rel_perf_ind with ( (heap_ignore (fset1 k_loc)) ⋊ couple_rhs count_loc k_loc (fun count k => count <= i -> k = None) ). 1: { ssprove_invariant=> //=. 1: rewrite fsub1set. all: by rewrite /GEN_HYB_locs /EVAL_locs_tt !fset_cons !in_fsetU !in_fset1 eq_refl !Bool.orb_true_r. } simplify_eq_rel m. ssprove_code_simpl. apply: r_get_vs_get_remember => count. case: (eq_dec count i) => Heq. - rewrite Heq eq_refl ltnn /=. ssprove_swap_rhs 0. apply: r_get_remember_rhs => k. apply: (r_rem_couple_rhs count_loc k_loc) => Hinv. rewrite Hinv //. apply: r_put_vs_put. ssprove_sync=> s. apply: r_put_rhs. apply: r_get_remind_rhs. 1: { apply: is_remembering_rhs => s0 s1 [h [_ ->]] /=. by rewrite get_set_heap_eq. } ssprove_restore_mem; last by apply: r_ret. ssprove_invariant. 2: by rewrite -subnE subSnn. move {Hinv k Heq} => s0 s1 [[[Hinv _] _] _] loc H. rewrite (get_set_heap_neq _ k_loc) -?in_fset1 //. case: (eq_dec loc count_loc)=> Heq. + by rewrite Heq !get_set_heap_eq. + move /eqP in Heq. by rewrite !get_set_heap_neq // Hinv. - move /eqP /negPf in Heq. rewrite Heq /=. destruct (count < i) eqn:Hlt. all: apply: r_put_vs_put. all: ssprove_sync=> x. 1: ssprove_sync=> y. all: ssprove_restore_mem; last by apply: r_ret. all: ssprove_invariant. all: move=> s0 s1 [[Hinv _] H] /=. all: rewrite /couple_rhs get_set_heap_eq get_set_heap_neq //. all: move /eqP in Hlt. + rewrite Hinv // H -subnE eqnE. by rewrite subn_eq0 ltnW // -subn_eq0 Hlt. + move /eqP /negPf in Hlt. by rewrite -subnE eqnE Hlt. Qed.
imports: Relational(OrderEnrichedCategory GenericRulesSimple) mathcomp(all_ssreflect all_algebra reals distr realsum ssrnat ssreflect ssrfun ssrbool ssrnum eqtype choice seq) Mon(SPropBase) Crypt(Axioms ChoiceAsOrd SubDistr Couplings UniformDistrLemmas FreeProbProg Theta_dens RulesStateProb pkg_core_definition choice_type pkg_composition pkg_rhl Package Prelude) extructures(ord fset fmap) Equations(Equations)