src/HOL/Imperative_HOL/Heap_Monad.thy
changeset 31871 cc1486840914
parent 31724 9b5a128cdb5c
child 31893 7d8a89390cbf
equal deleted inserted replaced
31870:5274d3d0a6f2 31871:cc1486840914
   304 code_const "op \<guillemotright>=" (OCaml "!(fun/ f'_/ ()/ ->/ f'_/ (_/ ())/ ())")
   304 code_const "op \<guillemotright>=" (OCaml "!(fun/ f'_/ ()/ ->/ f'_/ (_/ ())/ ())")
   305 code_const return (OCaml "!(fun/ ()/ ->/ _)")
   305 code_const return (OCaml "!(fun/ ()/ ->/ _)")
   306 code_const "Heap_Monad.Fail" (OCaml "Failure")
   306 code_const "Heap_Monad.Fail" (OCaml "Failure")
   307 code_const "Heap_Monad.raise_exc" (OCaml "!(fun/ ()/ ->/ raise/ _)")
   307 code_const "Heap_Monad.raise_exc" (OCaml "!(fun/ ()/ ->/ raise/ _)")
   308 
   308 
   309 setup {* let
   309 setup {*
   310   open Code_Thingol;
   310 
   311 
   311 let
   312   fun lookup naming = the o Code_Thingol.lookup_const naming;
   312 
   313 
   313 open Code_Thingol;
   314   fun imp_monad_bind'' bind' return' unit' ts =
   314 
   315     let
   315 fun imp_program naming =
   316       val dummy_name = "";
   316 
   317       val dummy_type = ITyVar dummy_name;
   317   let
   318       val dummy_case_term = IVar dummy_name;
   318     fun is_const c = case lookup_const naming c
   319       (*assumption: dummy values are not relevant for serialization*)
   319      of SOME c' => (fn c'' => c' = c'')
   320       val unitt = IConst (unit', (([], []), []));
   320       | NONE => K false;
   321       fun dest_abs ((v, ty) `|=> t, _) = ((v, ty), t)
   321     val is_bindM = is_const @{const_name bindM};
   322         | dest_abs (t, ty) =
   322     val is_return = is_const @{const_name return};
   323             let
   323     val dummy_name = "X";
   324               val vs = Code_Thingol.fold_varnames cons t [];
   324     val dummy_type = ITyVar dummy_name;
   325               val v = Name.variant vs "x";
   325     val dummy_case_term = IVar "";
   326               val ty' = (hd o fst o Code_Thingol.unfold_fun) ty;
   326     (*assumption: dummy values are not relevant for serialization*)
   327             in ((v, ty'), t `$ IVar v) end;
   327     val unitt = case lookup_const naming @{const_name Unity}
   328       fun force (t as IConst (c, _) `$ t') = if c = return'
   328      of SOME unit' => IConst (unit', (([], []), []))
   329             then t' else t `$ unitt
   329       | NONE => error ("Must include " ^ @{const_name Unity} ^ " in generated constants.");
   330         | force t = t `$ unitt;
   330     fun dest_abs ((v, ty) `|=> t, _) = ((v, ty), t)
   331       fun tr_bind' [(t1, _), (t2, ty2)] =
   331       | dest_abs (t, ty) =
   332         let
   332           let
   333           val ((v, ty), t) = dest_abs (t2, ty2);
   333             val vs = fold_varnames cons t [];
   334         in ICase (((force t1, ty), [(IVar v, tr_bind'' t)]), dummy_case_term) end
   334             val v = Name.variant vs "x";
   335       and tr_bind'' t = case Code_Thingol.unfold_app t
   335             val ty' = (hd o fst o unfold_fun) ty;
   336            of (IConst (c, (_, ty1 :: ty2 :: _)), [x1, x2]) => if c = bind'
   336           in ((v, ty'), t `$ IVar v) end;
   337                 then tr_bind' [(x1, ty1), (x2, ty2)]
   337     fun force (t as IConst (c, _) `$ t') = if is_return c
   338                 else force t
   338           then t' else t `$ unitt
   339             | _ => force t;
   339       | force t = t `$ unitt;
   340     in (dummy_name, dummy_type) `|=> ICase (((IVar dummy_name, dummy_type),
   340     fun tr_bind' [(t1, _), (t2, ty2)] =
   341       [(unitt, tr_bind' ts)]), dummy_case_term) end
   341       let
   342   and imp_monad_bind' bind' return' unit' (const as (c, (_, tys))) ts = if c = bind' then case (ts, tys)
   342         val ((v, ty), t) = dest_abs (t2, ty2);
   343      of ([t1, t2], ty1 :: ty2 :: _) => imp_monad_bind'' bind' return' unit' [(t1, ty1), (t2, ty2)]
   343       in ICase (((force t1, ty), [(IVar v, tr_bind'' t)]), dummy_case_term) end
   344       | ([t1, t2, t3], ty1 :: ty2 :: _) => imp_monad_bind'' bind' return' unit' [(t1, ty1), (t2, ty2)] `$ t3
   344     and tr_bind'' t = case unfold_app t
   345       | (ts, _) => imp_monad_bind bind' return' unit' (eta_expand 2 (const, ts))
   345          of (IConst (c, (_, ty1 :: ty2 :: _)), [x1, x2]) => if is_bindM c
   346     else IConst const `$$ map (imp_monad_bind bind' return' unit') ts
   346               then tr_bind' [(x1, ty1), (x2, ty2)]
   347   and imp_monad_bind bind' return' unit' (IConst const) = imp_monad_bind' bind' return' unit' const []
   347               else force t
   348     | imp_monad_bind bind' return' unit' (t as IVar _) = t
   348           | _ => force t;
   349     | imp_monad_bind bind' return' unit' (t as _ `$ _) = (case unfold_app t
   349     fun imp_monad_bind'' ts = (dummy_name, dummy_type) `|=> ICase (((IVar dummy_name, dummy_type),
   350        of (IConst const, ts) => imp_monad_bind' bind' return' unit' const ts
   350       [(unitt, tr_bind' ts)]), dummy_case_term)
   351         | (t, ts) => imp_monad_bind bind' return' unit' t `$$ map (imp_monad_bind bind' return' unit') ts)
   351     and imp_monad_bind' (const as (c, (_, tys))) ts = if is_bindM c then case (ts, tys)
   352     | imp_monad_bind bind' return' unit' (v_ty `|=> t) = v_ty `|=> imp_monad_bind bind' return' unit' t
   352        of ([t1, t2], ty1 :: ty2 :: _) => imp_monad_bind'' [(t1, ty1), (t2, ty2)]
   353     | imp_monad_bind bind' return' unit' (ICase (((t, ty), pats), t0)) = ICase
   353         | ([t1, t2, t3], ty1 :: ty2 :: _) => imp_monad_bind'' [(t1, ty1), (t2, ty2)] `$ t3
   354         (((imp_monad_bind bind' return' unit' t, ty), (map o pairself) (imp_monad_bind bind' return' unit') pats), imp_monad_bind bind' return' unit' t0);
   354         | (ts, _) => imp_monad_bind (eta_expand 2 (const, ts))
   355 
   355       else IConst const `$$ map imp_monad_bind ts
   356   fun imp_program naming = (Graph.map_nodes o map_terms_stmt)
   356     and imp_monad_bind (IConst const) = imp_monad_bind' const []
   357     (imp_monad_bind (lookup naming @{const_name bindM})
   357       | imp_monad_bind (t as IVar _) = t
   358       (lookup naming @{const_name return})
   358       | imp_monad_bind (t as _ `$ _) = (case unfold_app t
   359       (lookup naming @{const_name Unity}));
   359          of (IConst const, ts) => imp_monad_bind' const ts
       
   360           | (t, ts) => imp_monad_bind t `$$ map imp_monad_bind ts)
       
   361       | imp_monad_bind (v_ty `|=> t) = v_ty `|=> imp_monad_bind t
       
   362       | imp_monad_bind (ICase (((t, ty), pats), t0)) = ICase
       
   363           (((imp_monad_bind t, ty),
       
   364             (map o pairself) imp_monad_bind pats),
       
   365               imp_monad_bind t0);
       
   366 
       
   367   in (Graph.map_nodes o map_terms_stmt) imp_monad_bind end;
   360 
   368 
   361 in
   369 in
   362 
   370 
   363   Code_Target.extend_target ("SML_imp", ("SML", imp_program))
   371 Code_Target.extend_target ("SML_imp", ("SML", imp_program))
   364   #> Code_Target.extend_target ("OCaml_imp", ("OCaml", imp_program))
   372 #> Code_Target.extend_target ("OCaml_imp", ("OCaml", imp_program))
   365 
   373 
   366 end
   374 end
       
   375 
   367 *}
   376 *}
   368 
       
   369 
   377 
   370 code_reserved OCaml Failure raise
   378 code_reserved OCaml Failure raise
   371 
   379 
   372 
   380 
   373 subsubsection {* Haskell *}
   381 subsubsection {* Haskell *}