Theory Sepref_Misc

theory Sepref_Misc
imports 
  "../Refine_Monadic_Add"
  PO_Normalizer
  "List-Index.List_Index"
  "Refine_Imperative_HOL.Named_Theorems_Rev"
  "HOL-Eisbach.Eisbach"
begin

  hide_const (open) CONSTRAINT

  
  ML 
    fun SIMPLE_METHOD_NOPARAM' tac = Scan.succeed (fn ctxt => SIMPLE_METHOD' (IF_EXGOAL (tac ctxt)))
    fun SIMPLE_METHOD_NOPARAM tac = Scan.succeed (fn ctxt => SIMPLE_METHOD (tac ctxt))
  
  
  
  lemma not_None_eq2[simp]: "None  x  (y. x = Some y)"
    by (cases x) auto
  
  (* Additions for List_Index *)  
  lemma index_of_last_distinct[simp]: 
    "distinct l  index l (last l) = length l - 1"  
    apply (cases l rule: rev_cases)
    apply (auto simp: index_append)
    done

  lemma index_eqlen_conv[simp]: "index l x = length l  xset l"
    by (auto simp: index_size_conv)


  subsection Iterated Curry and Uncurry    


  text Uncurry0  
  definition "uncurry0 c  λ_::unit. c"
  definition curry0 :: "(unit  'a)  'a" where "curry0 f = f ()"
  lemma uncurry0_apply[simp]: "uncurry0 c x = c" by (simp add: uncurry0_def)

  lemma curry_uncurry0_id[simp]: "curry0 (uncurry0 f) = f" by (simp add: curry0_def)
  lemma uncurry_curry0_id[simp]: "uncurry0 (curry0 g) = g" by (auto simp: curry0_def)
  lemma param_uncurry0[param]: "(uncurry0,uncurry0)  A  (unit_relA)" by auto
    
  text Abbreviations for higher-order uncurries    
  abbreviation "uncurry2 f  uncurry (uncurry f)"
  abbreviation "curry2 f  curry (curry f)"
  abbreviation "uncurry3 f  uncurry (uncurry2 f)"
  abbreviation "curry3 f  curry (curry2 f)"
  abbreviation "uncurry4 f  uncurry (uncurry3 f)"
  abbreviation "curry4 f  curry (curry3 f)"
  abbreviation "uncurry5 f  uncurry (uncurry4 f)"
  abbreviation "curry5 f  curry (curry4 f)"
  abbreviation "uncurry6 f  uncurry (uncurry5 f)"
  abbreviation "curry6 f  curry (curry5 f)"
  abbreviation "uncurry7 f  uncurry (uncurry6 f)"
  abbreviation "curry7 f  curry (curry6 f)"
  abbreviation "uncurry8 f  uncurry (uncurry7 f)"
  abbreviation "curry8 f  curry (curry7 f)"
  abbreviation "uncurry9 f  uncurry (uncurry8 f)"
  abbreviation "curry9 f  curry (curry8 f)"
  abbreviation "uncurry10 f  uncurry (uncurry9 f)"
  abbreviation "curry10 f  curry (curry9 f)"
  abbreviation "uncurry11 f  uncurry (uncurry10 f)"
  abbreviation "curry11 f  curry (curry10 f)"
  abbreviation "uncurry12 f  uncurry (uncurry11 f)"
  abbreviation "curry12 f  curry (curry11 f)"
  abbreviation "uncurry13 f  uncurry (uncurry12 f)"
  abbreviation "curry13 f  curry (curry12 f)"
  abbreviation "uncurry14 f  uncurry (uncurry13 f)"
  abbreviation "curry14 f  curry (curry13 f)"
  abbreviation "uncurry15 f  uncurry (uncurry14 f)"
  abbreviation "curry15 f  curry (curry14 f)"
  abbreviation "uncurry16 f  uncurry (uncurry15 f)"
  abbreviation "curry16 f  curry (curry15 f)"
  abbreviation "uncurry17 f  uncurry (uncurry16 f)"
  abbreviation "curry17 f  curry (curry16 f)"
  abbreviation "uncurry18 f  uncurry (uncurry17 f)"
  abbreviation "curry18 f  curry (curry17 f)"
  abbreviation "uncurry19 f  uncurry (uncurry18 f)"
  abbreviation "curry19 f  curry (curry18 f)"
  abbreviation "uncurry20 f  uncurry (uncurry19 f)"
  abbreviation "curry20 f  curry (curry19 f)"


  abbreviation comp4  (infixl "oooo" 55)       where "f oooo g        λx. f ooo (g x)"
  abbreviation comp5  (infixl "ooooo" 55)      where "f ooooo g       λx. f oooo (g x)"
  abbreviation comp6  (infixl "oooooo" 55)     where "f oooooo g      λx. f ooooo (g x)"
  abbreviation comp7  (infixl "ooooooo" 55)    where "f ooooooo g     λx. f oooooo (g x)"
  abbreviation comp8  (infixl "oooooooo" 55)   where "f oooooooo g    λx. f ooooooo (g x)"
  abbreviation comp9  (infixl "ooooooooo" 55)  where "f ooooooooo g   λx. f oooooooo (g x)"
  abbreviation comp10 (infixl "oooooooooo" 55) where "f oooooooooo g  λx. f ooooooooo (g x)"
  abbreviation comp11 (infixl "o11" 55) where "f o11 g  λx. f oooooooooo (g x)"
  abbreviation comp12 (infixl "o12" 55) where "f o12 g  λx. f o11 (g x)"
  abbreviation comp13 (infixl "o13" 55) where "f o13 g  λx. f o12 (g x)"
  abbreviation comp14 (infixl "o14" 55) where "f o14 g  λx. f o13 (g x)"
  abbreviation comp15 (infixl "o15" 55) where "f o15 g  λx. f o14 (g x)"
  abbreviation comp16 (infixl "o16" 55) where "f o16 g  λx. f o15 (g x)"
  abbreviation comp17 (infixl "o17" 55) where "f o17 g  λx. f o16 (g x)"
  abbreviation comp18 (infixl "o18" 55) where "f o18 g  λx. f o17 (g x)"
  abbreviation comp19 (infixl "o19" 55) where "f o19 g  λx. f o18 (g x)"
  abbreviation comp20 (infixl "o20" 55) where "f o20 g  λx. f o19 (g x)"
  
  (* TODO: Why are the number of o off by one?*)
  notation
    comp4 (infixl "∘∘∘" 55) and
    comp5 (infixl "∘∘∘∘" 55) and
    comp6 (infixl "∘∘∘∘∘" 55) and
    comp7 (infixl "∘∘∘∘∘∘" 55) and
    comp8 (infixl "∘∘∘∘∘∘∘" 55) and
    comp9 (infixl "∘∘∘∘∘∘∘∘" 55) and
    comp10 (infixl "∘∘∘∘∘∘∘∘∘" 55) and
    comp11 (infixl "11" 55) and
    comp12 (infixl "12" 55) and
    comp13 (infixl "13" 55) and
    comp14 (infixl "14" 55) and
    comp15 (infixl "15" 55) and
    comp16 (infixl "16" 55) and
    comp17 (infixl "17" 55) and
    comp18 (infixl "18" 55) and
    comp19 (infixl "19" 55) and
    comp20 (infixl "20" 55)
    
    
    
    
    
  
  
  
  
  
  
    
    
  lemma fold_partial_uncurry: "uncurry (λ(ps, cf). f ps cf) = uncurry2 f" by auto

  lemma curry_shl: 
    "g f. (g  curry f)  (uncurry g  f)"
    "g f. (g  curry0 f)  (uncurry0 g  f)"
    by (atomize (full); auto)+
  
  lemma curry_shr: 
    "f g. (curry f  g)  (f  uncurry g)"
    "f g. (curry0 f  g)  (f  uncurry0 g)"
    by (atomize (full); auto)+
  
  lemmas uncurry_shl = curry_shr[symmetric]  
  lemmas uncurry_shr = curry_shl[symmetric]  
  
end