src/HOL/ex/predicate_compile.ML
changeset 31876 9ab571673059
parent 31784 bd3486c57ba3
child 31877 e3de75d3b898
equal deleted inserted replaced
31845:cc7ddda02436 31876:9ab571673059
     7 signature PREDICATE_COMPILE =
     7 signature PREDICATE_COMPILE =
     8 sig
     8 sig
     9   type mode = int list option list * int list
     9   type mode = int list option list * int list
    10   val add_equations_of: string list -> theory -> theory
    10   val add_equations_of: string list -> theory -> theory
    11   val register_predicate : (thm list * thm * int) -> theory -> theory
    11   val register_predicate : (thm list * thm * int) -> theory -> theory
       
    12   val fetch_pred_data : theory -> string -> (thm list * thm * int)  
    12   val predfun_intro_of: theory -> string -> mode -> thm
    13   val predfun_intro_of: theory -> string -> mode -> thm
    13   val predfun_elim_of: theory -> string -> mode -> thm
    14   val predfun_elim_of: theory -> string -> mode -> thm
    14   val strip_intro_concl: int -> term -> term * (term list * term list)
    15   val strip_intro_concl: int -> term -> term * (term list * term list)
    15   val predfun_name_of: theory -> string -> mode -> string
    16   val predfun_name_of: theory -> string -> mode -> string
    16   val all_preds_of : theory -> string list
    17   val all_preds_of : theory -> string list
    17   val modes_of: theory -> string -> mode list
    18   val modes_of: theory -> string -> mode list
    18   val intros_of: theory -> string -> thm list
    19   val intros_of: theory -> string -> thm list
    19   val nparams_of: theory -> string -> int
    20   val nparams_of: theory -> string -> int
       
    21   val add_intro: thm -> theory -> theory
       
    22   val set_elim: thm -> theory -> theory
    20   val setup: theory -> theory
    23   val setup: theory -> theory
    21   val code_pred: string -> Proof.context -> Proof.state
    24   val code_pred: string -> Proof.context -> Proof.state
    22   val code_pred_cmd: string -> Proof.context -> Proof.state
    25   val code_pred_cmd: string -> Proof.context -> Proof.state
    23 (*  val print_alternative_rules: theory -> theory (*FIXME diagnostic command?*) *)
    26   val print_stored_rules: theory -> unit
    24   val do_proofs: bool ref
    27   val do_proofs: bool ref
       
    28   val mk_casesrule : Proof.context -> int -> thm list -> term
    25   val analyze_compr: theory -> term -> term
    29   val analyze_compr: theory -> term -> term
    26   val eval_ref: (unit -> term Predicate.pred) option ref
    30   val eval_ref: (unit -> term Predicate.pred) option ref
    27   val add_equations : string -> theory -> theory
    31   val add_equations : string -> theory -> theory
       
    32   val code_pred_intros_attrib : attribute
    28 end;
    33 end;
    29 
    34 
    30 structure Predicate_Compile : PREDICATE_COMPILE =
    35 structure Predicate_Compile : PREDICATE_COMPILE =
    31 struct
    36 struct
    32 
    37 
   221 
   226 
   222 val predfun_intro_of = #intro ooo the_predfun_data
   227 val predfun_intro_of = #intro ooo the_predfun_data
   223 
   228 
   224 val predfun_elim_of = #elim ooo the_predfun_data
   229 val predfun_elim_of = #elim ooo the_predfun_data
   225 
   230 
   226 
   231 fun print_stored_rules thy =
   227 (* replaces print_alternative_rules *)
   232   let
   228 (* TODO:
   233     val preds = (Graph.keys o PredData.get) thy
   229 fun print_alternative_rules thy = let
   234     fun print pred () = let
   230     val d = IndCodegenData.get thy
   235       val _ = writeln ("predicate: " ^ pred)
   231     val preds = (Symtab.keys (#intro_rules d)) union (Symtab.keys (#elim_rules d))
   236       val _ = writeln ("number of parameters: " ^ string_of_int (nparams_of thy pred))
   232     val _ = tracing ("preds: " ^ (makestring preds))
   237       val _ = writeln ("introrules: ")
   233     fun print pred = let
   238       val _ = fold (fn thm => fn u =>  writeln (Display.string_of_thm thm))
   234       val _ = tracing ("predicate: " ^ pred)
   239         (rev (intros_of thy pred)) ()
   235       val _ = tracing ("introrules: ")
   240     in
   236       val _ = fold (fn thm => fn u => tracing (makestring thm))
   241       if (has_elim thy pred) then
   237         (rev (Symtab.lookup_list (#intro_rules d) pred)) ()
   242         writeln ("elimrule: " ^ Display.string_of_thm (the_elim_of thy pred))
   238       val _ = tracing ("casesrule: ")
   243       else
   239       val _ = tracing (makestring (Symtab.lookup (#elim_rules d) pred))
   244         writeln ("no elimrule defined")
   240     in () end
   245     end
   241     val _ = map print preds
   246   in
   242  in thy end;
   247     fold print preds ()
   243 *)
   248   end;
   244 
   249 
       
   250 (** preprocessing rules **)  
   245 
   251 
   246 fun imp_prems_conv cv ct =
   252 fun imp_prems_conv cv ct =
   247   case Thm.term_of ct of
   253   case Thm.term_of ct of
   248     Const ("==>", _) $ _ $ _ => Conv.combination_conv (Conv.arg_conv cv) (imp_prems_conv cv) ct
   254     Const ("==>", _) $ _ $ _ => Conv.combination_conv (Conv.arg_conv cv) (imp_prems_conv cv) ct
   249   | _ => Conv.all_conv ct
   255   | _ => Conv.all_conv ct
   296 
   302 
   297 fun add_predfun name mode data = let
   303 fun add_predfun name mode data = let
   298     val add = apsnd (cons (mode, mk_predfun_data data))
   304     val add = apsnd (cons (mode, mk_predfun_data data))
   299   in PredData.map (Graph.map_node name (map_pred_data add)) end
   305   in PredData.map (Graph.map_node name (map_pred_data add)) end
   300 
   306 
       
   307 fun is_inductive_predicate thy name =
       
   308   is_some (try (Inductive.the_inductive (ProofContext.init thy)) name)
       
   309 
       
   310 fun depending_preds_of thy intros = fold Term.add_consts (map Thm.prop_of intros) [] |> map fst
       
   311     |> filter (fn c => is_inductive_predicate thy c orelse is_pred thy c)
       
   312 
       
   313 (* code dependency graph *)    
       
   314 fun dependencies_of thy name =
       
   315   let
       
   316     val (intros, elim, nparams) = fetch_pred_data thy name 
       
   317     val data = mk_pred_data ((intros, SOME elim, nparams), [])
       
   318     val keys = depending_preds_of thy intros
       
   319   in
       
   320     (data, keys)
       
   321   end;
       
   322 
       
   323 (* TODO: add_edges - by analysing dependencies *)
   301 fun add_intro thm thy = let
   324 fun add_intro thm thy = let
   302    val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm)))
   325    val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm)))
   303    fun cons_intro gr =
   326    fun cons_intro gr =
   304      case try (Graph.get_node gr) name of
   327      case try (Graph.get_node gr) name of
   305        SOME pred_data => Graph.map_node name (map_pred_data
   328        SOME pred_data => Graph.map_node name (map_pred_data
   318 
   341 
   319 fun set_nparams name nparams = let
   342 fun set_nparams name nparams = let
   320     fun set (intros, elim, _ ) = (intros, elim, nparams) 
   343     fun set (intros, elim, _ ) = (intros, elim, nparams) 
   321   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   344   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   322 
   345 
   323 fun register_predicate (intros, elim, nparams) = let
   346 fun register_predicate (intros, elim, nparams) thy = let
   324     val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd intros))))
   347     val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd intros))))
   325     fun set _ = (intros, SOME elim, nparams)
   348     fun set _ = (intros, SOME elim, nparams)
   326   in PredData.map (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), []))) end
   349   in
       
   350     PredData.map (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), []))
       
   351       #> fold Graph.add_edge (map (pair name) (depending_preds_of thy intros))) thy
       
   352   end
   327 
   353 
   328   
   354   
   329 (* Mode analysis *)
   355 (* Mode analysis *)
   330 
   356 
   331 (*** check if a term contains only constructor functions ***)
   357 (*** check if a term contains only constructor functions ***)
  1241        THEN print_tac "after prove_match2:"
  1267        THEN print_tac "after prove_match2:"
  1242        THEN rest_tac
  1268        THEN rest_tac
  1243     end;
  1269     end;
  1244   val prems_tac = prove_prems2 in_ts' param_vs ps 
  1270   val prems_tac = prove_prems2 in_ts' param_vs ps 
  1245 in
  1271 in
  1246   print_tac "starting prove_clause2"
  1272   new_print_tac "starting prove_clause2"
  1247   THEN etac @{thm bindE} 1
  1273   THEN etac @{thm bindE} 1
  1248   THEN (etac @{thm singleE'} 1)
  1274   THEN (etac @{thm singleE'} 1)
  1249   THEN (TRY (etac @{thm Pair_inject} 1))
  1275   THEN (TRY (etac @{thm Pair_inject} 1))
  1250   THEN print_tac "after singleE':"
  1276   THEN print_tac "after singleE':"
  1251   THEN prems_tac
  1277   THEN prems_tac
  1257     THEN (prove_clause2 thy all_vs param_vs modes mode clause pred i)
  1283     THEN (prove_clause2 thy all_vs param_vs modes mode clause pred i)
  1258 in
  1284 in
  1259   (DETERM (TRY (rtac @{thm unit.induct} 1)))
  1285   (DETERM (TRY (rtac @{thm unit.induct} 1)))
  1260    THEN (REPEAT_DETERM (CHANGED (rewtac @{thm split_paired_all})))
  1286    THEN (REPEAT_DETERM (CHANGED (rewtac @{thm split_paired_all})))
  1261    THEN (rtac (predfun_intro_of thy pred mode) 1)
  1287    THEN (rtac (predfun_intro_of thy pred mode) 1)
       
  1288    THEN (REPEAT_DETERM (rtac @{thm refl} 2))
  1262    THEN (EVERY (map prove_clause (clauses ~~ (1 upto (length clauses)))))
  1289    THEN (EVERY (map prove_clause (clauses ~~ (1 upto (length clauses)))))
  1263 end;
  1290 end;
  1264 
  1291 
  1265 fun prove_pred thy all_vs param_vs modes clauses (((pred, T), mode), t) = let
  1292 fun prove_pred thy all_vs param_vs modes clauses (((pred, T), mode), t) = let
  1266   val ctxt = ProofContext.init thy
  1293   val ctxt = ProofContext.init thy
  1407         in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end
  1434         in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end
  1408     val assm = HOLogic.mk_Trueprop (list_comb (pred, params @ argvs))
  1435     val assm = HOLogic.mk_Trueprop (list_comb (pred, params @ argvs))
  1409     val cases = map mk_case intros
  1436     val cases = map mk_case intros
  1410   in Logic.list_implies (assm :: cases, prop) end;
  1437   in Logic.list_implies (assm :: cases, prop) end;
  1411 
  1438 
  1412 (* code dependency graph *)
       
  1413 
       
  1414 fun dependencies_of thy name =
       
  1415   let
       
  1416     fun is_inductive_predicate thy name =
       
  1417       is_some (try (Inductive.the_inductive (ProofContext.init thy)) name)
       
  1418     val (intro, elim, nparams) = fetch_pred_data thy name 
       
  1419     val data = mk_pred_data ((intro, SOME elim, nparams), [])
       
  1420     val intros = map Thm.prop_of (#intros (rep_pred_data data))
       
  1421     val keys = fold Term.add_consts intros [] |> map fst
       
  1422     |> filter (is_inductive_predicate thy)
       
  1423   in
       
  1424     (data, keys)
       
  1425   end;
       
  1426 
       
  1427 fun add_equations name thy =
  1439 fun add_equations name thy =
  1428   let
  1440   let
  1429     val thy' = PredData.map (Graph.extend (dependencies_of thy) name) thy |> Theory.checkpoint;
  1441     val thy' = PredData.map (Graph.extend (dependencies_of thy) name) thy |> Theory.checkpoint;
  1430     (*val preds = Graph.all_preds (PredData.get thy') [name] |> filter_out (has_elim thy') *)
  1442     (*val preds = Graph.all_preds (PredData.get thy') [name] |> filter_out (has_elim thy') *)
  1431     fun strong_conn_of gr keys =
  1443     fun strong_conn_of gr keys =
  1435       (fn preds => fn thy =>
  1447       (fn preds => fn thy =>
  1436         if forall (null o modes_of thy) preds then add_equations_of preds thy else thy)
  1448         if forall (null o modes_of thy) preds then add_equations_of preds thy else thy)
  1437       scc thy' |> Theory.checkpoint
  1449       scc thy' |> Theory.checkpoint
  1438   in thy'' end
  1450   in thy'' end
  1439 
  1451 
       
  1452   
       
  1453 fun attrib f = Thm.declaration_attribute (fn thm => Context.mapping (f thm) I);
       
  1454 
       
  1455 val code_pred_intros_attrib = attrib add_intro;
       
  1456 
  1440 (** user interface **)
  1457 (** user interface **)
  1441 
  1458 
  1442 local
  1459 local
  1443 
       
  1444 fun attrib f = Thm.declaration_attribute (fn thm => Context.mapping (f thm) I);
       
  1445 
       
  1446 (*
       
  1447 val add_elim_attrib = attrib set_elim;
       
  1448 *)
       
  1449 
       
  1450 
  1460 
  1451 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *)
  1461 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *)
  1452 (* TODO: must create state to prove multiple cases *)
  1462 (* TODO: must create state to prove multiple cases *)
  1453 fun generic_code_pred prep_const raw_const lthy =
  1463 fun generic_code_pred prep_const raw_const lthy =
  1454   let
  1464   let