src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML
changeset 33629 5f35cf91c6a4
parent 33628 ed2111a5c3ed
child 33650 dd3ea99d5c76
equal deleted inserted replaced
33628:ed2111a5c3ed 33629:5f35cf91c6a4
   139 
   139 
   140 fun gen_split_smode (mk_tuple, strip_tuple) smode ts =
   140 fun gen_split_smode (mk_tuple, strip_tuple) smode ts =
   141   let
   141   let
   142     fun split_tuple' _ _ [] = ([], [])
   142     fun split_tuple' _ _ [] = ([], [])
   143     | split_tuple' is i (t::ts) =
   143     | split_tuple' is i (t::ts) =
   144       (if i mem is then apfst else apsnd) (cons t)
   144       (if member (op =) is i then apfst else apsnd) (cons t)
   145         (split_tuple' is (i+1) ts)
   145         (split_tuple' is (i+1) ts)
   146     fun split_tuple is t = split_tuple' is 1 (strip_tuple t)
   146     fun split_tuple is t = split_tuple' is 1 (strip_tuple t)
   147     fun split_smode' _ _ [] = ([], [])
   147     fun split_smode' _ _ [] = ([], [])
   148       | split_smode' smode i (t::ts) =
   148       | split_smode' smode i (t::ts) =
   149         (if i mem (map fst smode) then
   149         (if member (op =) (map fst smode) i then
   150           case (the (AList.lookup (op =) smode i)) of
   150           case (the (AList.lookup (op =) smode i)) of
   151             NONE => apfst (cons t)
   151             NONE => apfst (cons t)
   152             | SOME is =>
   152             | SOME is =>
   153               let
   153               let
   154                 val (ts1, ts2) = split_tuple is t
   154                 val (ts1, ts2) = split_tuple is t
   459   let
   459   let
   460     val ([outp_pred], ctxt') = Variable.import_terms false [inp_pred] ctxt
   460     val ([outp_pred], ctxt') = Variable.import_terms false [inp_pred] ctxt
   461     val (paramTs, _) = chop nparams (binder_types (fastype_of outp_pred))
   461     val (paramTs, _) = chop nparams (binder_types (fastype_of outp_pred))
   462     val (param_names, ctxt'') = Variable.variant_fixes (map (fn i => "p" ^ (string_of_int i))
   462     val (param_names, ctxt'') = Variable.variant_fixes (map (fn i => "p" ^ (string_of_int i))
   463       (1 upto nparams)) ctxt'
   463       (1 upto nparams)) ctxt'
   464     val params = map Free (param_names ~~ paramTs)
   464     val params = map2 (curry Free) param_names paramTs
   465     in (((outp_pred, params), []), ctxt') end
   465     in (((outp_pred, params), []), ctxt') end
   466   | import_intros inp_pred nparams (th :: ths) ctxt =
   466   | import_intros inp_pred nparams (th :: ths) ctxt =
   467     let
   467     let
   468       val ((_, [th']), ctxt') = Variable.import false [th] ctxt
   468       val ((_, [th']), ctxt') = Variable.import false [th] ctxt
   469       val thy = ProofContext.theory_of ctxt'
   469       val thy = ProofContext.theory_of ctxt'
   506     val argvs = map2 (curry Free) argnames argsT
   506     val argvs = map2 (curry Free) argnames argsT
   507     fun mk_case intro =
   507     fun mk_case intro =
   508       let
   508       let
   509         val (_, (_, args)) = strip_intro_concl nparams intro
   509         val (_, (_, args)) = strip_intro_concl nparams intro
   510         val prems = Logic.strip_imp_prems intro
   510         val prems = Logic.strip_imp_prems intro
   511         val eqprems = map (HOLogic.mk_Trueprop o HOLogic.mk_eq) (argvs ~~ args)
   511         val eqprems = map2 (HOLogic.mk_Trueprop oo (curry HOLogic.mk_eq)) argvs args
   512         val frees = (fold o fold_aterms)
   512         val frees = (fold o fold_aterms)
   513           (fn t as Free _ =>
   513           (fn t as Free _ =>
   514               if member (op aconv) params t then I else insert (op aconv) t
   514               if member (op aconv) params t then I else insert (op aconv) t
   515            | _ => I) (args @ prems) []
   515            | _ => I) (args @ prems) []
   516       in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end
   516       in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end
   562     val eq = Goal.prove ctxt' [] [] (Logic.mk_equals ((Thm.prop_of elimrule), elimrule')) tac
   562     val eq = Goal.prove ctxt' [] [] (Logic.mk_equals ((Thm.prop_of elimrule), elimrule')) tac
   563   in
   563   in
   564     Thm.equal_elim eq elimrule |> singleton (Variable.export ctxt' ctxt)
   564     Thm.equal_elim eq elimrule |> singleton (Variable.export ctxt' ctxt)
   565   end;
   565   end;
   566 
   566 
   567 (* special case: predicate with no introduction rule *)
       
   568 fun noclause thy predname elim = let
       
   569   val T = (Logic.unvarifyT o Sign.the_const_type thy) predname
       
   570   val Ts = binder_types T
       
   571   val names = Name.variant_list []
       
   572         (map (fn i => "x" ^ (string_of_int i)) (1 upto (length Ts)))
       
   573   val vs = map2 (curry Free) names Ts
       
   574   val clausehd = HOLogic.mk_Trueprop (list_comb (Const (predname, T), vs))
       
   575   val intro_t = Logic.mk_implies (@{prop False}, clausehd)
       
   576   val P = HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT))
       
   577   val elim_t = Logic.list_implies ([clausehd, Logic.mk_implies (@{prop False}, P)], P)
       
   578   val intro = Goal.prove (ProofContext.init thy) names [] intro_t
       
   579         (fn _ => etac @{thm FalseE} 1)
       
   580   val elim = Goal.prove (ProofContext.init thy) ("P" :: names) [] elim_t
       
   581         (fn _ => etac elim 1) 
       
   582 in
       
   583   ([intro], elim)
       
   584 end
       
   585 
       
   586 fun expand_tuples_elim th = th
   567 fun expand_tuples_elim th = th
   587 
   568 
   588 (* updaters *)
   569 (* updaters *)
   589 
   570 
   590 fun apfst4 f (x1, x2, x3, x4) = (f x1, x2, x3, x4)
   571 fun apfst4 f (x1, x2, x3, x4) = (f x1, x2, x3, x4)
   612         (*val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams 
   593         (*val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams 
   613           (expand_tuples_elim pre_elim))*)
   594           (expand_tuples_elim pre_elim))*)
   614         val elim =
   595         val elim =
   615           (Drule.standard o Skip_Proof.make_thm thy)
   596           (Drule.standard o Skip_Proof.make_thm thy)
   616           (mk_casesrule (ProofContext.init thy) pred nparams intros)
   597           (mk_casesrule (ProofContext.init thy) pred nparams intros)
   617         val (intros, elim) = (*if null intros then noclause thy name elim else*) (intros, elim)
       
   618       in
   598       in
   619         mk_pred_data ((intros, SOME elim, nparams), no_compilation)
   599         mk_pred_data ((intros, SOME elim, nparams), no_compilation)
   620       end
   600       end
   621   | NONE => error ("No such predicate: " ^ quote name)
   601   | NONE => error ("No such predicate: " ^ quote name)
   622 
   602 
   648   in
   628   in
   649     (data, keys)
   629     (data, keys)
   650   end;
   630   end;
   651 *)
   631 *)
   652 
   632 
   653 fun add_intro thm thy = let
   633 fun add_intro thm thy =
   654    val (name, T) = dest_Const (fst (strip_intro_concl 0 (prop_of thm)))
   634   let
   655    fun cons_intro gr =
   635     val (name, T) = dest_Const (fst (strip_intro_concl 0 (prop_of thm)))
       
   636     fun cons_intro gr =
   656      case try (Graph.get_node gr) name of
   637      case try (Graph.get_node gr) name of
   657        SOME pred_data => Graph.map_node name (map_pred_data
   638        SOME pred_data => Graph.map_node name (map_pred_data
   658          (apfst (fn (intros, elim, nparams) => (intros @ [thm], elim, nparams)))) gr
   639          (apfst (fn (intros, elim, nparams) => (intros @ [thm], elim, nparams)))) gr
   659      | NONE =>
   640      | NONE =>
   660        let
   641        let
   661          val nparams = the_default (guess_nparams T)
   642          val nparams = the_default (guess_nparams T)
   662            (try (#nparams o rep_pred_data o (fetch_pred_data thy)) name)
   643            (try (#nparams o rep_pred_data o (fetch_pred_data thy)) name)
   663        in Graph.new_node (name, mk_pred_data (([thm], NONE, nparams), no_compilation)) gr end;
   644        in Graph.new_node (name, mk_pred_data (([thm], NONE, nparams), no_compilation)) gr end;
   664   in PredData.map cons_intro thy end
   645   in PredData.map cons_intro thy end
   665 
   646 
   666 fun set_elim thm = let
   647 fun set_elim thm =
       
   648   let
   667     val (name, _) = dest_Const (fst 
   649     val (name, _) = dest_Const (fst 
   668       (strip_comb (HOLogic.dest_Trueprop (hd (prems_of thm)))))
   650       (strip_comb (HOLogic.dest_Trueprop (hd (prems_of thm)))))
   669     fun set (intros, _, nparams) = (intros, SOME thm, nparams)  
   651     fun set (intros, _, nparams) = (intros, SOME thm, nparams)  
   670   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   652   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   671 
   653 
   672 fun set_nparams name nparams = let
   654 fun set_nparams name nparams =
       
   655   let
   673     fun set (intros, elim, _ ) = (intros, elim, nparams) 
   656     fun set (intros, elim, _ ) = (intros, elim, nparams) 
   674   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   657   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   675 
   658 
   676 fun register_predicate (constname, pre_intros, pre_elim, nparams) thy =
   659 fun register_predicate (constname, pre_intros, pre_elim, nparams) thy =
   677   let
   660   let
  1150 
  1133 
  1151 fun mk_Eval_of additional_arguments ((x, T), NONE) names = (x, names)
  1134 fun mk_Eval_of additional_arguments ((x, T), NONE) names = (x, names)
  1152   | mk_Eval_of additional_arguments ((x, T), SOME mode) names =
  1135   | mk_Eval_of additional_arguments ((x, T), SOME mode) names =
  1153   let
  1136   let
  1154     val Ts = binder_types T
  1137     val Ts = binder_types T
  1155     (*val argnames = Name.variant_list names
       
  1156         (map (fn i => "x" ^ string_of_int i) (1 upto (length Ts)));
       
  1157     val args = map Free (argnames ~~ Ts)
       
  1158     val (inargs, outargs) = split_smode mode args*)
       
  1159     fun mk_split_lambda [] t = lambda (Free (Name.variant names "x", HOLogic.unitT)) t
  1138     fun mk_split_lambda [] t = lambda (Free (Name.variant names "x", HOLogic.unitT)) t
  1160       | mk_split_lambda [x] t = lambda x t
  1139       | mk_split_lambda [x] t = lambda x t
  1161       | mk_split_lambda xs t =
  1140       | mk_split_lambda xs t =
  1162       let
  1141       let
  1163         fun mk_split_lambda' (x::y::[]) t = HOLogic.mk_split (lambda x (lambda y t))
  1142         fun mk_split_lambda' (x::y::[]) t = HOLogic.mk_split (lambda x (lambda y t))
  1180           | Ts =>
  1159           | Ts =>
  1181             let
  1160             let
  1182               val vnames = Name.variant_list names
  1161               val vnames = Name.variant_list names
  1183                 (map (fn j => "x" ^ string_of_int i ^ "p" ^ string_of_int j)
  1162                 (map (fn j => "x" ^ string_of_int i ^ "p" ^ string_of_int j)
  1184                   (1 upto length Ts))
  1163                   (1 upto length Ts))
  1185               val args = map Free (vnames ~~ Ts)
  1164               val args = map2 (curry Free) vnames Ts
  1186               fun split_args (i, arg) (ins, outs) =
  1165               fun split_args (i, arg) (ins, outs) =
  1187                 if member (op =) pis i then
  1166                 if member (op =) pis i then
  1188                   (arg::ins, outs)
  1167                   (arg::ins, outs)
  1189                 else
  1168                 else
  1190                   (ins, arg::outs)
  1169                   (ins, arg::outs)
  1269 (*FIXME function can be removed*)
  1248 (*FIXME function can be removed*)
  1270 fun mk_funcomp f t =
  1249 fun mk_funcomp f t =
  1271   let
  1250   let
  1272     val names = Term.add_free_names t [];
  1251     val names = Term.add_free_names t [];
  1273     val Ts = binder_types (fastype_of t);
  1252     val Ts = binder_types (fastype_of t);
  1274     val vs = map Free
  1253     val vs = map2 (curry Free)
  1275       (Name.variant_list names (replicate (length Ts) "x") ~~ Ts)
  1254       (Name.variant_list names (replicate (length Ts) "x")) Ts
  1276   in
  1255   in
  1277     fold_rev lambda vs (f (list_comb (t, vs)))
  1256     fold_rev lambda vs (f (list_comb (t, vs)))
  1278   end;
  1257   end;
  1279 
  1258 
  1280 fun compile_param compilation_modifiers compfuns thy (NONE, t) = t
  1259 fun compile_param compilation_modifiers compfuns thy NONE t = t
  1281   | compile_param compilation_modifiers compfuns thy (m as SOME (Mode (mode, _, ms)), t) =
  1260   | compile_param compilation_modifiers compfuns thy (m as SOME (Mode (mode, _, ms))) t =
  1282    let
  1261    let
  1283      val (f, args) = strip_comb (Envir.eta_contract t)
  1262      val (f, args) = strip_comb (Envir.eta_contract t)
  1284      val (params, args') = chop (length ms) args
  1263      val (params, args') = chop (length ms) args
  1285      val params' = map (compile_param compilation_modifiers compfuns thy) (ms ~~ params)
  1264      val params' = map2 (compile_param compilation_modifiers compfuns thy) ms params
  1286      val f' =
  1265      val f' =
  1287        case f of
  1266        case f of
  1288          Const (name, T) => Const (Comp_Mod.function_name_of compilation_modifiers thy name mode,
  1267          Const (name, T) => Const (Comp_Mod.function_name_of compilation_modifiers thy name mode,
  1289            Comp_Mod.funT_of compilation_modifiers compfuns mode T)
  1268            Comp_Mod.funT_of compilation_modifiers compfuns mode T)
  1290        | Free (name, T) => Free (name, Comp_Mod.funT_of compilation_modifiers compfuns mode T)
  1269        | Free (name, T) => Free (name, Comp_Mod.funT_of compilation_modifiers compfuns mode T)
  1296 fun compile_expr compilation_modifiers compfuns thy ((Mode (mode, _, ms)), t)
  1275 fun compile_expr compilation_modifiers compfuns thy ((Mode (mode, _, ms)), t)
  1297   inargs additional_arguments =
  1276   inargs additional_arguments =
  1298   case strip_comb t of
  1277   case strip_comb t of
  1299     (Const (name, T), params) =>
  1278     (Const (name, T), params) =>
  1300        let
  1279        let
  1301          val params' = map (compile_param compilation_modifiers compfuns thy) (ms ~~ params)
  1280          val params' = map2 (compile_param compilation_modifiers compfuns thy) ms params
  1302          val name' = Comp_Mod.function_name_of compilation_modifiers thy name mode
  1281          val name' = Comp_Mod.function_name_of compilation_modifiers thy name mode
  1303          val T' = Comp_Mod.funT_of compilation_modifiers compfuns mode T
  1282          val T' = Comp_Mod.funT_of compilation_modifiers compfuns mode T
  1304        in
  1283        in
  1305          (list_comb (Const (name', T'), params' @ inargs @ additional_arguments))
  1284          (list_comb (Const (name', T'), params' @ inargs @ additional_arguments))
  1306        end
  1285        end
  1408                ("x" ^ string_of_int i), nth Ts2 (i - 1))]
  1387                ("x" ^ string_of_int i), nth Ts2 (i - 1))]
  1409              | Ts => let
  1388              | Ts => let
  1410                val vnames = Name.variant_list (all_vs @ param_vs)
  1389                val vnames = Name.variant_list (all_vs @ param_vs)
  1411                 (map (fn j => "x" ^ string_of_int i ^ "p" ^ string_of_int j)
  1390                 (map (fn j => "x" ^ string_of_int i ^ "p" ^ string_of_int j)
  1412                   pis)
  1391                   pis)
  1413              in if null pis then []
  1392              in
  1414                else [HOLogic.mk_tuple (map Free (vnames ~~ map (fn j => nth Ts (j - 1)) pis))] end
  1393                if null pis then
       
  1394                  []
       
  1395                else
       
  1396                  [HOLogic.mk_tuple (map2 (curry Free) vnames (map (fn j => nth Ts (j - 1)) pis))]
       
  1397              end
  1415     val in_ts = maps mk_input_term (snd mode)
  1398     val in_ts = maps mk_input_term (snd mode)
  1416     val params = map2 (fn s => fn T => Free (s, T)) param_vs Ts1'
  1399     val params = map2 (fn s => fn T => Free (s, T)) param_vs Ts1'
  1417     val additional_arguments = Comp_Mod.additional_arguments compilation_modifiers
  1400     val additional_arguments = Comp_Mod.additional_arguments compilation_modifiers
  1418       (all_vs @ param_vs)
  1401       (all_vs @ param_vs)
  1419     val cl_ts =
  1402     val cl_ts =
  1452   val (Ts1, Ts2) = chop (length iss) Ts;
  1435   val (Ts1, Ts2) = chop (length iss) Ts;
  1453   val Ts1' =
  1436   val Ts1' =
  1454     map2 (fn NONE => I | SOME is => funT_of (PredicateCompFuns.compfuns) ([], is)) iss Ts1
  1437     map2 (fn NONE => I | SOME is => funT_of (PredicateCompFuns.compfuns) ([], is)) iss Ts1
  1455   val param_names = Name.variant_list []
  1438   val param_names = Name.variant_list []
  1456     (map (fn i => "x" ^ string_of_int i) (1 upto (length Ts1)));
  1439     (map (fn i => "x" ^ string_of_int i) (1 upto (length Ts1)));
  1457   val params = map Free (param_names ~~ Ts1')
  1440   val params = map2 (curry Free) param_names Ts1'
  1458   fun mk_args (i, T) argnames =
  1441   fun mk_args (i, T) argnames =
  1459     let
  1442     let
  1460       val vname = Name.variant (param_names @ argnames) ("x" ^ string_of_int (length Ts1' + i))
  1443       val vname = Name.variant (param_names @ argnames) ("x" ^ string_of_int (length Ts1' + i))
  1461       val default = (Free (vname, T), vname :: argnames)
  1444       val default = (Free (vname, T), vname :: argnames)
  1462     in
  1445     in
  1470              | Ts => 
  1453              | Ts => 
  1471             let
  1454             let
  1472               val vnames = Name.variant_list (param_names @ argnames)
  1455               val vnames = Name.variant_list (param_names @ argnames)
  1473                 (map (fn j => "x" ^ string_of_int (length Ts1' + i) ^ "p" ^ string_of_int j)
  1456                 (map (fn j => "x" ^ string_of_int (length Ts1' + i) ^ "p" ^ string_of_int j)
  1474                   (1 upto (length Ts)))
  1457                   (1 upto (length Ts)))
  1475              in (HOLogic.mk_tuple (map Free (vnames ~~ Ts)), vnames  @ argnames) end
  1458              in (HOLogic.mk_tuple (map2 (curry Free) vnames Ts), vnames @ argnames) end
  1476     end
  1459     end
  1477   val (args, argnames) = fold_map mk_args (1 upto (length Ts2) ~~ Ts2) []
  1460   val (args, argnames) = fold_map mk_args (1 upto (length Ts2) ~~ Ts2) []
  1478   val (inargs, outargs) = split_smode is args
  1461   val (inargs, outargs) = split_smode is args
  1479   val param_names' = Name.variant_list (param_names @ argnames)
  1462   val param_names' = Name.variant_list (param_names @ argnames)
  1480     (map (fn i => "p" ^ string_of_int i) (1 upto (length iss)))
  1463     (map (fn i => "p" ^ string_of_int i) (1 upto (length iss)))
  1481   val param_vs = map Free (param_names' ~~ Ts1)
  1464   val param_vs = map2 (curry Free) param_names' Ts1
  1482   val (params', names) = fold_map (mk_Eval_of []) ((params ~~ Ts1) ~~ iss) []
  1465   val (params', names) = fold_map (mk_Eval_of []) ((params ~~ Ts1) ~~ iss) []
  1483   val predpropI = HOLogic.mk_Trueprop (list_comb (pred, param_vs @ args))
  1466   val predpropI = HOLogic.mk_Trueprop (list_comb (pred, param_vs @ args))
  1484   val predpropE = HOLogic.mk_Trueprop (list_comb (pred, params' @ args))
  1467   val predpropE = HOLogic.mk_Trueprop (list_comb (pred, params' @ args))
  1485   val param_eqs = map (HOLogic.mk_Trueprop o HOLogic.mk_eq) (param_vs ~~ params')
  1468   val param_eqs = map2 (HOLogic.mk_Trueprop oo (curry HOLogic.mk_eq)) param_vs params'
  1486   val funargs = params @ inargs
  1469   val funargs = params @ inargs
  1487   val funpropE = HOLogic.mk_Trueprop (PredicateCompFuns.mk_Eval (list_comb (funtrm, funargs),
  1470   val funpropE = HOLogic.mk_Trueprop (PredicateCompFuns.mk_Eval (list_comb (funtrm, funargs),
  1488                   if null outargs then Free("y", HOLogic.unitT) else HOLogic.mk_tuple outargs))
  1471                   if null outargs then Free("y", HOLogic.unitT) else HOLogic.mk_tuple outargs))
  1489   val funpropI = HOLogic.mk_Trueprop (PredicateCompFuns.mk_Eval (list_comb (funtrm, funargs),
  1472   val funpropI = HOLogic.mk_Trueprop (PredicateCompFuns.mk_Eval (list_comb (funtrm, funargs),
  1490                    HOLogic.mk_tuple outargs))
  1473                    HOLogic.mk_tuple outargs))
  1513 
  1496 
  1514 fun split_tupleT is T =
  1497 fun split_tupleT is T =
  1515   let
  1498   let
  1516     fun split_tuple' _ _ [] = ([], [])
  1499     fun split_tuple' _ _ [] = ([], [])
  1517       | split_tuple' is i (T::Ts) =
  1500       | split_tuple' is i (T::Ts) =
  1518       (if i mem is then apfst else apsnd) (cons T)
  1501       (if member (op =) is i then apfst else apsnd) (cons T)
  1519         (split_tuple' is (i+1) Ts)
  1502         (split_tuple' is (i+1) Ts)
  1520   in
  1503   in
  1521     split_tuple' is 1 (HOLogic.strip_tupleT T)
  1504     split_tuple' is 1 (HOLogic.strip_tupleT T)
  1522   end
  1505   end
  1523   
  1506   
  1526     val n = length (HOLogic.strip_tupleT T)
  1509     val n = length (HOLogic.strip_tupleT T)
  1527     val ni = length pis
  1510     val ni = length pis
  1528     fun mk_proj i j t =
  1511     fun mk_proj i j t =
  1529       (if i = j then I else HOLogic.mk_fst)
  1512       (if i = j then I else HOLogic.mk_fst)
  1530         (funpow (i - 1) HOLogic.mk_snd t)
  1513         (funpow (i - 1) HOLogic.mk_snd t)
  1531     fun mk_arg' i (si, so) = if i mem pis then
  1514     fun mk_arg' i (si, so) =
       
  1515       if member (op =) pis i then
  1532         (mk_proj si ni xin, (si+1, so))
  1516         (mk_proj si ni xin, (si+1, so))
  1533       else
  1517       else
  1534         (mk_proj so (n - ni) xout, (si, so+1))
  1518         (mk_proj so (n - ni) xout, (si, so+1))
  1535     val (args, _) = fold_map mk_arg' (1 upto n) (1, 1)
  1519     val (args, _) = fold_map mk_arg' (1 upto n) (1, 1)
  1536   in
  1520   in
  1549       val (Us1, Us2) =  split_smodeT is Ts2
  1533       val (Us1, Us2) =  split_smodeT is Ts2
  1550       val Ts1' = map2 (fn NONE => I | SOME is => funT_of compfuns ([], is)) iss Ts1
  1534       val Ts1' = map2 (fn NONE => I | SOME is => funT_of compfuns ([], is)) iss Ts1
  1551       val funT = (Ts1' @ Us1) ---> (mk_predT compfuns (HOLogic.mk_tupleT Us2))
  1535       val funT = (Ts1' @ Us1) ---> (mk_predT compfuns (HOLogic.mk_tupleT Us2))
  1552       val names = Name.variant_list []
  1536       val names = Name.variant_list []
  1553         (map (fn i => "x" ^ string_of_int i) (1 upto (length Ts)));
  1537         (map (fn i => "x" ^ string_of_int i) (1 upto (length Ts)));
  1554       (* old *)
       
  1555       (*
       
  1556       val xs = map Free (names ~~ (Ts1' @ Ts2))
       
  1557       val (xparams, xargs) = chop (length iss) xs
       
  1558       val (xins, xouts) = split_smode is xargs
       
  1559       *)
       
  1560       (* new *)
       
  1561       val param_names = Name.variant_list []
  1538       val param_names = Name.variant_list []
  1562         (map (fn i => "x" ^ string_of_int i) (1 upto (length Ts1')))
  1539         (map (fn i => "x" ^ string_of_int i) (1 upto (length Ts1')))
  1563       val xparams = map Free (param_names ~~ Ts1')
  1540       val xparams = map2 (curry Free) param_names Ts1'
  1564       fun mk_vars (i, T) names =
  1541       fun mk_vars (i, T) names =
  1565         let
  1542         let
  1566           val vname = Name.variant names ("x" ^ string_of_int (length Ts1' + i))
  1543           val vname = Name.variant names ("x" ^ string_of_int (length Ts1' + i))
  1567         in
  1544         in
  1568           case AList.lookup (op =) is i of
  1545           case AList.lookup (op =) is i of
  1648         | _ => false) end))
  1625         | _ => false) end))
  1649   else false
  1626   else false
  1650 
  1627 
  1651 (* MAJOR FIXME:  prove_params should be simple
  1628 (* MAJOR FIXME:  prove_params should be simple
  1652  - different form of introrule for parameters ? *)
  1629  - different form of introrule for parameters ? *)
  1653 fun prove_param thy (NONE, t) = TRY (rtac @{thm refl} 1)
  1630 fun prove_param thy NONE t = TRY (rtac @{thm refl} 1)
  1654   | prove_param thy (m as SOME (Mode (mode, is, ms)), t) =
  1631   | prove_param thy (m as SOME (Mode (mode, is, ms))) t =
  1655   let
  1632   let
  1656     val  (f, args) = strip_comb (Envir.eta_contract t)
  1633     val  (f, args) = strip_comb (Envir.eta_contract t)
  1657     val (params, _) = chop (length ms) args
  1634     val (params, _) = chop (length ms) args
  1658     val f_tac = case f of
  1635     val f_tac = case f of
  1659       Const (name, T) => simp_tac (HOL_basic_ss addsimps 
  1636       Const (name, T) => simp_tac (HOL_basic_ss addsimps 
  1666     REPEAT_DETERM (etac @{thm thin_rl} 1)
  1643     REPEAT_DETERM (etac @{thm thin_rl} 1)
  1667     THEN REPEAT_DETERM (rtac @{thm ext} 1)
  1644     THEN REPEAT_DETERM (rtac @{thm ext} 1)
  1668     THEN print_tac "prove_param"
  1645     THEN print_tac "prove_param"
  1669     THEN f_tac
  1646     THEN f_tac
  1670     THEN print_tac "after simplification in prove_args"
  1647     THEN print_tac "after simplification in prove_args"
  1671     THEN (EVERY (map (prove_param thy) (ms ~~ params)))
  1648     THEN (EVERY (map2 (prove_param thy) ms params))
  1672     THEN (REPEAT_DETERM (atac 1))
  1649     THEN (REPEAT_DETERM (atac 1))
  1673   end
  1650   end
  1674 
  1651 
  1675 fun prove_expr thy (Mode (mode, is, ms), t, us) (premposition : int) =
  1652 fun prove_expr thy (Mode (mode, is, ms), t, us) (premposition : int) =
  1676   case strip_comb t of
  1653   case strip_comb t of
  1687         THEN rtac introrule 1
  1664         THEN rtac introrule 1
  1688         THEN print_tac "after intro rule"
  1665         THEN print_tac "after intro rule"
  1689         (* work with parameter arguments *)
  1666         (* work with parameter arguments *)
  1690         THEN (atac 1)
  1667         THEN (atac 1)
  1691         THEN (print_tac "parameter goal")
  1668         THEN (print_tac "parameter goal")
  1692         THEN (EVERY (map (prove_param thy) (ms ~~ args1)))
  1669         THEN (EVERY (map2 (prove_param thy) ms args1))
  1693         THEN (REPEAT_DETERM (atac 1))
  1670         THEN (REPEAT_DETERM (atac 1))
  1694       end
  1671       end
  1695   | _ => rtac @{thm bindI} 1
  1672   | _ => rtac @{thm bindI} 1
  1696     THEN asm_full_simp_tac
  1673     THEN asm_full_simp_tac
  1697       (HOL_basic_ss' addsimps [@{thm "split_eta"}, @{thm "split_beta"}, @{thm "fst_conv"},
  1674       (HOL_basic_ss' addsimps [@{thm "split_eta"}, @{thm "split_beta"}, @{thm "fst_conv"},
  1780                   simp_tac (HOL_basic_ss addsimps
  1757                   simp_tac (HOL_basic_ss addsimps
  1781                     [predfun_definition_of thy (the name) (iss, is)]) 1
  1758                     [predfun_definition_of thy (the name) (iss, is)]) 1
  1782                   THEN rtac @{thm not_predI} 1
  1759                   THEN rtac @{thm not_predI} 1
  1783                   THEN simp_tac (HOL_basic_ss addsimps [@{thm not_False_eq_True}]) 1
  1760                   THEN simp_tac (HOL_basic_ss addsimps [@{thm not_False_eq_True}]) 1
  1784                   THEN (REPEAT_DETERM (atac 1))
  1761                   THEN (REPEAT_DETERM (atac 1))
  1785                   (* FIXME: work with parameter arguments *)
  1762                   THEN (EVERY (map2 (prove_param thy) param_modes params))
  1786                   THEN (EVERY (map (prove_param thy) (param_modes ~~ params)))
       
  1787                 else
  1763                 else
  1788                   rtac @{thm not_predI'} 1)
  1764                   rtac @{thm not_predI'} 1)
  1789                   THEN simp_tac (HOL_basic_ss addsimps [@{thm not_False_eq_True}]) 1
  1765                   THEN simp_tac (HOL_basic_ss addsimps [@{thm not_False_eq_True}]) 1
  1790               THEN rec_tac
  1766               THEN rec_tac
  1791             end
  1767             end
  1864 (* VERY LARGE SIMILIRATIY to function prove_param 
  1840 (* VERY LARGE SIMILIRATIY to function prove_param 
  1865 -- join both functions
  1841 -- join both functions
  1866 *)
  1842 *)
  1867 (* TODO: remove function *)
  1843 (* TODO: remove function *)
  1868 
  1844 
  1869 fun prove_param2 thy (NONE, t) = all_tac 
  1845 fun prove_param2 thy NONE t = all_tac 
  1870   | prove_param2 thy (m as SOME (Mode (mode, is, ms)), t) = let
  1846   | prove_param2 thy (m as SOME (Mode (mode, is, ms))) t =
       
  1847   let
  1871     val  (f, args) = strip_comb (Envir.eta_contract t)
  1848     val  (f, args) = strip_comb (Envir.eta_contract t)
  1872     val (params, _) = chop (length ms) args
  1849     val (params, _) = chop (length ms) args
  1873     val f_tac = case f of
  1850     val f_tac = case f of
  1874         Const (name, T) => full_simp_tac (HOL_basic_ss addsimps 
  1851         Const (name, T) => full_simp_tac (HOL_basic_ss addsimps 
  1875            (@{thm eval_pred}::(predfun_definition_of thy name mode)
  1852            (@{thm eval_pred}::(predfun_definition_of thy name mode)
  1876            :: @{thm "Product_Type.split_conv"}::[])) 1
  1853            :: @{thm "Product_Type.split_conv"}::[])) 1
  1877       | Free _ => all_tac
  1854       | Free _ => all_tac
  1878       | _ => error "prove_param2: illegal parameter term"
  1855       | _ => error "prove_param2: illegal parameter term"
  1879   in  
  1856   in
  1880     print_tac "before simplification in prove_args:"
  1857     print_tac "before simplification in prove_args:"
  1881     THEN f_tac
  1858     THEN f_tac
  1882     THEN print_tac "after simplification in prove_args"
  1859     THEN print_tac "after simplification in prove_args"
  1883     THEN (EVERY (map (prove_param2 thy) (ms ~~ params)))
  1860     THEN (EVERY (map2 (prove_param2 thy) ms params))
  1884   end
  1861   end
  1885 
  1862 
  1886 
  1863 
  1887 fun prove_expr2 thy (Mode (mode, is, ms), t) = 
  1864 fun prove_expr2 thy (Mode (mode, is, ms), t) = 
  1888   (case strip_comb t of
  1865   (case strip_comb t of
  1892       THEN print_tac "prove_expr2-before"
  1869       THEN print_tac "prove_expr2-before"
  1893       THEN (debug_tac (Syntax.string_of_term_global thy
  1870       THEN (debug_tac (Syntax.string_of_term_global thy
  1894         (prop_of (predfun_elim_of thy name mode))))
  1871         (prop_of (predfun_elim_of thy name mode))))
  1895       THEN (etac (predfun_elim_of thy name mode) 1)
  1872       THEN (etac (predfun_elim_of thy name mode) 1)
  1896       THEN print_tac "prove_expr2"
  1873       THEN print_tac "prove_expr2"
  1897       THEN (EVERY (map (prove_param2 thy) (ms ~~ args)))
  1874       THEN (EVERY (map2 (prove_param2 thy) ms args))
  1898       THEN print_tac "finished prove_expr2"      
  1875       THEN print_tac "finished prove_expr2"      
  1899     | _ => etac @{thm bindE} 1)
  1876     | _ => etac @{thm bindE} 1)
  1900     
  1877     
  1901 (* FIXME: what is this for? *)
  1878 (* FIXME: what is this for? *)
  1902 (* replace defined by has_mode thy pred *)
  1879 (* replace defined by has_mode thy pred *)
  1963             THEN (if is_some name then
  1940             THEN (if is_some name then
  1964                 full_simp_tac (HOL_basic_ss addsimps
  1941                 full_simp_tac (HOL_basic_ss addsimps
  1965                   [predfun_definition_of thy (the name) (iss, is)]) 1
  1942                   [predfun_definition_of thy (the name) (iss, is)]) 1
  1966                 THEN etac @{thm not_predE} 1
  1943                 THEN etac @{thm not_predE} 1
  1967                 THEN simp_tac (HOL_basic_ss addsimps [@{thm not_False_eq_True}]) 1
  1944                 THEN simp_tac (HOL_basic_ss addsimps [@{thm not_False_eq_True}]) 1
  1968                 THEN (EVERY (map (prove_param2 thy) (param_modes ~~ params)))
  1945                 THEN (EVERY (map2 (prove_param2 thy) param_modes params))
  1969               else
  1946               else
  1970                 etac @{thm not_predE'} 1)
  1947                 etac @{thm not_predE'} 1)
  1971             THEN rec_tac
  1948             THEN rec_tac
  1972           end 
  1949           end 
  1973         | Sidecond t =>
  1950         | Sidecond t =>
  2054 
  2031 
  2055 (* preparation of introduction rules into special datastructures *)
  2032 (* preparation of introduction rules into special datastructures *)
  2056 
  2033 
  2057 fun dest_prem thy params t =
  2034 fun dest_prem thy params t =
  2058   (case strip_comb t of
  2035   (case strip_comb t of
  2059     (v as Free _, ts) => if v mem params then Prem (ts, v) else Sidecond t
  2036     (v as Free _, ts) => if member (op =) params v then Prem (ts, v) else Sidecond t
  2060   | (c as Const (@{const_name Not}, _), [t]) => (case dest_prem thy params t of
  2037   | (c as Const (@{const_name Not}, _), [t]) => (case dest_prem thy params t of
  2061       Prem (ts, t) => Negprem (ts, t)
  2038       Prem (ts, t) => Negprem (ts, t)
  2062     | Negprem _ => error ("Double negation not allowed in premise: " ^
  2039     | Negprem _ => error ("Double negation not allowed in premise: " ^
  2063         Syntax.string_of_term_global thy (c $ t)) 
  2040         Syntax.string_of_term_global thy (c $ t)) 
  2064     | Sidecond t => Sidecond (c $ t))
  2041     | Sidecond t => Sidecond (c $ t))
  2084         [] =>
  2061         [] =>
  2085           let
  2062           let
  2086             val (paramTs, _) = chop nparams (binder_types (snd (hd preds)))
  2063             val (paramTs, _) = chop nparams (binder_types (snd (hd preds)))
  2087             val param_names = Name.variant_list [] (map (fn i => "p" ^ string_of_int i)
  2064             val param_names = Name.variant_list [] (map (fn i => "p" ^ string_of_int i)
  2088               (1 upto length paramTs))
  2065               (1 upto length paramTs))
  2089           in map Free (param_names ~~ paramTs) end
  2066           in map2 (curry Free) param_names paramTs end
  2090       | intr :: _ => fst (chop nparams
  2067       | intr :: _ => fst (chop nparams
  2091         (snd (strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl intr)))))
  2068         (snd (strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl intr)))))
  2092     val param_vs = maps term_vs params
  2069     val param_vs = maps term_vs params
  2093     val all_vs = terms_vs intrs
  2070     val all_vs = terms_vs intrs
  2094     fun add_clause intr (clauses, arities) =
  2071     fun add_clause intr (clauses, arities) =
  2140 
  2117 
  2141 fun check_format_of_intro_rule thy intro =
  2118 fun check_format_of_intro_rule thy intro =
  2142   let
  2119   let
  2143     val concl = Logic.strip_imp_concl (prop_of intro)
  2120     val concl = Logic.strip_imp_concl (prop_of intro)
  2144     val (p, args) = strip_comb (HOLogic.dest_Trueprop concl)
  2121     val (p, args) = strip_comb (HOLogic.dest_Trueprop concl)
  2145     val params = List.take (args, nparams_of thy (fst (dest_Const p)))
  2122     val params = fst (chop (nparams_of thy (fst (dest_Const p))) args)
  2146     fun check_arg arg = case HOLogic.strip_tupleT (fastype_of arg) of
  2123     fun check_arg arg = case HOLogic.strip_tupleT (fastype_of arg) of
  2147       (Ts as _ :: _ :: _) =>
  2124       (Ts as _ :: _ :: _) =>
  2148         if (length (HOLogic.strip_tuple arg) = length Ts) then true
  2125         if length (HOLogic.strip_tuple arg) = length Ts then
       
  2126           true
  2149         else
  2127         else
  2150         error ("Format of introduction rule is invalid: tuples must be expanded:"
  2128           error ("Format of introduction rule is invalid: tuples must be expanded:"
  2151         ^ (Syntax.string_of_term_global thy arg) ^ " in " ^
  2129           ^ (Syntax.string_of_term_global thy arg) ^ " in " ^
  2152         (Display.string_of_thm_global thy intro)) 
  2130           (Display.string_of_thm_global thy intro)) 
  2153       | _ => true
  2131       | _ => true
  2154     val prems = Logic.strip_imp_prems (prop_of intro)
  2132     val prems = Logic.strip_imp_prems (prop_of intro)
  2155     fun check_prem (Prem (args, _)) = forall check_arg args
  2133     fun check_prem (Prem (args, _)) = forall check_arg args
  2156       | check_prem (Negprem (args, _)) = forall check_arg args
  2134       | check_prem (Negprem (args, _)) = forall check_arg args
  2157       | check_prem _ = true
  2135       | check_prem _ = true
  2181 
  2159 
  2182 (* create code equation *)
  2160 (* create code equation *)
  2183 
  2161 
  2184 fun add_code_equations thy nparams preds result_thmss =
  2162 fun add_code_equations thy nparams preds result_thmss =
  2185   let
  2163   let
  2186     fun add_code_equation ((predname, T), (pred, result_thms)) =
  2164     fun add_code_equation (predname, T) (pred, result_thms) =
  2187       let
  2165       let
  2188         val full_mode = (replicate nparams NONE,
  2166         val full_mode = (replicate nparams NONE,
  2189           map (rpair NONE) (1 upto (length (binder_types T) - nparams)))
  2167           map (rpair NONE) (1 upto (length (binder_types T) - nparams)))
  2190       in
  2168       in
  2191         if member (op =) (modes_of thy predname) full_mode then
  2169         if member (op =) (modes_of thy predname) full_mode then
  2192           let
  2170           let
  2193             val Ts = binder_types T
  2171             val Ts = binder_types T
  2194             val arg_names = Name.variant_list []
  2172             val arg_names = Name.variant_list []
  2195               (map (fn i => "x" ^ string_of_int i) (1 upto length Ts))
  2173               (map (fn i => "x" ^ string_of_int i) (1 upto length Ts))
  2196             val args = map Free (arg_names ~~ Ts)
  2174             val args = map2 (curry Free) arg_names Ts
  2197             val predfun = Const (predfun_name_of thy predname full_mode,
  2175             val predfun = Const (predfun_name_of thy predname full_mode,
  2198               Ts ---> PredicateCompFuns.mk_predT @{typ unit})
  2176               Ts ---> PredicateCompFuns.mk_predT @{typ unit})
  2199             val rhs = PredicateCompFuns.mk_Eval (list_comb (predfun, args), @{term "Unity"})
  2177             val rhs = PredicateCompFuns.mk_Eval (list_comb (predfun, args), @{term "Unity"})
  2200             val eq_term = HOLogic.mk_Trueprop
  2178             val eq_term = HOLogic.mk_Trueprop
  2201               (HOLogic.mk_eq (list_comb (Const (predname, T), args), rhs))
  2179               (HOLogic.mk_eq (list_comb (Const (predname, T), args), rhs))
  2208           end
  2186           end
  2209         else
  2187         else
  2210           (pred, result_thms)
  2188           (pred, result_thms)
  2211       end
  2189       end
  2212   in
  2190   in
  2213     map add_code_equation (preds ~~ result_thmss)
  2191     map2 add_code_equation preds result_thmss
  2214   end
  2192   end
  2215 
  2193 
  2216 (** main function of predicate compiler **)
  2194 (** main function of predicate compiler **)
  2217 
  2195 
  2218 datatype steps = Steps of
  2196 datatype steps = Steps of