Theory Refine_Info

theory
  Refine_Info
  imports
    Refine_Unions
    Refine_Vector_List
begin

consts i_info::"interfaceinterfaceinterface"

definition info_rel_internal: "info_rel I S = (I ×r S) O br snd top"
lemma info_rel_def: "I, Sinfo_rel = (I ×r S) O br snd top"
  by (auto simp: relAPP_def info_rel_internal)
lemmas [autoref_rel_intf] = REL_INTFI[of "info_rel" i_info]

lemma info_rel_br: "br a I, (br b J)info_rel = br (λy. b (snd y)) (λx. I (fst x)  J (snd x))"
  by (auto simp: info_rel_def br_def prod_rel_def)

lemma sv_info_rel[relator_props]:
  "single_valued S single_valued I  single_valued (I, Sinfo_rel)"
  by (auto simp: info_rel_def intro!: relator_props)

definition [simp]: "op_info_is_empty = is_empty"
context includes autoref_syntax begin
lemma [autoref_op_pat]:  "is_empty  OP op_info_is_empty"
  by simp
end

lemma op_set_isEmpty_info_rel_set[autoref_rules]:
  "GEN_OP empty_i (is_empty) (A  bool_rel)  (λx. empty_i (snd x), op_info_is_empty)  I, Ainfo_rel  bool_rel"
  by (auto simp: info_rel_def br_def op_set_isEmpty_def[abs_def] dest: fun_relD)

definition [refine_vcg_def]: "get_info X = SPEC (λ(h, Y). Y = X)"
lemma get_info_autoref[autoref_rules]:
  shows "(λx. RETURN x, get_info)  I, Ainfo_rel  I ×r Anres_rel"
  by (force simp: get_info_def info_rel_def nres_rel_def br_def intro!: RETURN_SPEC_refine)

definition with_info::"'b  'a set  'a set"
  where [simp, refine_vcg_def]: "with_info h x = x"

lemma with_stepsize_autoref[autoref_rules]:
  "((λh x. (h, x)), with_info)  R  A  R, Ainfo_rel"
  by (auto simp: info_rel_def br_def intro!: prod_relI)

definition with_half_stepsizes::"'a set  'a set"
  where [simp, refine_vcg_def]: "with_half_stepsizes x = x"
lemma with_half_stepsize_autoref[autoref_rules]:
  "((map (λ(h, x). (h/2, x))), with_half_stepsizes) 
  clw_rel (rnv_rel, Ainfo_rel)  clw_rel (rnv_rel, Ainfo_rel)"
  if  [unfolded autoref_tag_defs, relator_props]: "single_valued A"
  unfolding with_half_stepsizes_def
  apply (rule lift_clw_rel_map)
     apply (rule relator_props)+
  by (auto simp: info_rel_def br_def prod_rel_def)

definition with_infos::"'b  'a set  'a set"
  where [simp, refine_vcg_def]: "with_infos h x = x"
lemma with_infos_autoref[autoref_rules]:
  "(λh. map (Pair h), with_infos)  R  clw_rel A  clw_rel (R, Ainfo_rel)"
  if [unfolded autoref_tag_defs, relator_props]: "PREFER single_valued A" "PREFER single_valued R"
  unfolding with_infos_def
  apply (rule fun_relI)
  apply (rule lift_clw_rel_map)
     apply (rule relator_props)+
  by (auto simp: info_rel_def br_def prod_rel_def)

abbreviation "with_stepsize  (with_info::real_)"

definition split_with_info::"'a set  ('c × 'a set × 'a set) nres"
  where [refine_vcg_def]: "split_with_info X = SPEC (λ(S, Y, YS). X = Y  YS)"

context includes autoref_syntax begin
lemma split_with_info_appr_plane_autoref[autoref_rules]:
  assumes "PREFER single_valued A"
  assumes "PREFER single_valued S"
  assumes "(xs, X)  clw_rel (A,Sinfo_rel)"
  shows
    "(if xs = [] then SUCCEED else let s = fst (hd xs); (a, b) = List.partition (λ(sctn, _). sctn = s) xs in RETURN (s, map snd a, b),
    split_with_info $ X) 
    A ×r clw_rel S ×r clw_rel (A, Sinfo_rel)nres_rel"
  using assms
  by (fastforce simp: Let_def split_with_info_def split_beta'
      lw_rel_def Union_rel_br info_rel_br ex_br_conj_iff Id_br[where 'a="'a sctn"]
      split: if_splits
      elim!: single_valued_as_brE
      intro!: nres_relI RETURN_SPEC_refine brI hd_in_set
      dest!: brD )

definition
  "explicit_info_set X0 =
    do {
      e  isEmpty_spec X0;
      (_, _, Xis)  WHILE⇗λ(e, X, Y).
          (e  X = {}) 
          X0 = X  ((sctn, IS)Y. IS)(λ(e, X, Y). ¬e)
        (λ(e, X, Y).
          do {
            (sctn, S, X')  split_with_info X;
            e  isEmpty_spec X';
            RETURN (e, X', insert (sctn, S) Y)
          }
        )
        (e, X0, {});
      RETURN Xis
    }"

schematic_goal explicit_info_setc:
  fixes po :: "'d  'a::executable_euclidean_space set"
  assumes [THEN PREFER_sv_D, relator_props]: "PREFER single_valued A"
  assumes [THEN PREFER_sv_D, relator_props]: "PREFER single_valued S"
  assumes [autoref_rules]: "(XSi, XS)  clw_rel (S, Ainfo_rel)"
  shows "(nres_of ?f, explicit_info_set $ XS)  S ×r clw_rel Alist_wset_relnres_rel"
  unfolding autoref_tag_defs
  unfolding explicit_info_set_def
  including art
  by autoref_monadic
concrete_definition explicit_info_setc for XSi uses explicit_info_setc
lemmas [autoref_rules] = explicit_info_setc.refine

lemma explicit_info_set[THEN order_trans, refine_vcg]:
  "explicit_info_set X  SPEC (λR. X = ((sctn, IS)  R. IS))"
  unfolding explicit_info_set_def
  by (refine_vcg) (auto simp: split_beta' subset_iff)

lemmas [relator_props del] = sv_info_rel
lemma sv_info_rel'[relator_props]:
  "single_valued S  single_valued (I, Sinfo_rel)"
  by (auto simp: info_rel_def single_valued_def br_def)

lemma
  is_empty_info_rel_autoref[autoref_rules]:
  "GEN_OP ie is_empty (A  bool_rel)  (λx. ie(snd x), is_empty)  R, Ainfo_rel  bool_rel"
  by (force simp: info_rel_def br_def dest: fun_relD)

definition with_coll_infos::"'c set  'a set  'a set nres"
  where [simp, refine_vcg_def]: "with_coll_infos h x = SPEC (λr. r = x)"

lemma with_coll_infos_autoref[autoref_rules]:
  "((λri ai. nres_of (if ri = [] then dSUCCEED else dRETURN (List.product ri ai))), with_coll_infos) 
    clw_rel R  clw_rel A  clw_rel (R, Ainfo_rel)nres_rel"
  if "PREFER single_valued R" "PREFER single_valued A"
  using that
  by (force simp: relcomp_unfold nres_rel_def info_rel_br list_wset_rel_def Union_rel_br
      Id_arbitrary_interface_def RETURN_RES_refine_iff set_rel_br
      elim!: single_valued_as_brE
      intro!: brI dest!: brD
      split: if_splits)

end

end