src/HOL/ex/predicate_compile.ML
changeset 32314 66bbad0bfef9
parent 32313 a984c04927b4
child 32315 79f324944be4
equal deleted inserted replaced
32313:a984c04927b4 32314:66bbad0bfef9
     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: bool -> string list -> theory -> theory *)
    10   (*val add_equations_of: bool -> 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 is_registered : theory -> string -> bool
    12   val is_registered : theory -> string -> bool
    13   val fetch_pred_data : theory -> string -> (thm list * thm * int)  
    13  (* val fetch_pred_data : theory -> string -> (thm list * thm * int)  *)
    14   val predfun_intro_of: theory -> string -> mode -> thm
    14   val predfun_intro_of: theory -> string -> mode -> thm
    15   val predfun_elim_of: theory -> string -> mode -> thm
    15   val predfun_elim_of: theory -> string -> mode -> thm
    16   val strip_intro_concl: int -> term -> term * (term list * term list)
    16   val strip_intro_concl: int -> term -> term * (term list * term list)
    17   val predfun_name_of: theory -> string -> mode -> string
    17   val predfun_name_of: theory -> string -> mode -> string
    18   val all_preds_of : theory -> string list
    18   val all_preds_of : theory -> string list
    76     theory -> (moded_clause list) pred_mode_table -> unit
    76     theory -> (moded_clause list) pred_mode_table -> unit
    77   val print_compiled_terms : theory -> term pred_mode_table -> unit
    77   val print_compiled_terms : theory -> term pred_mode_table -> unit
    78   (*val rpred_prove_preds : theory -> term pred_mode_table -> thm pred_mode_table*)
    78   (*val rpred_prove_preds : theory -> term pred_mode_table -> thm pred_mode_table*)
    79   val rpred_compfuns : compilation_funs
    79   val rpred_compfuns : compilation_funs
    80   val dest_funT : typ -> typ * typ
    80   val dest_funT : typ -> typ * typ
    81   val depending_preds_of : theory -> thm list -> string list
    81  (* val depending_preds_of : theory -> thm list -> string list *)
    82   val add_quickcheck_equations : string list -> theory -> theory
    82   val add_quickcheck_equations : string list -> theory -> theory
    83   val add_sizelim_equations : string list -> theory -> theory
    83   val add_sizelim_equations : string list -> theory -> theory
    84   val is_inductive_predicate : theory -> string -> bool
    84   val is_inductive_predicate : theory -> string -> bool
    85   val terms_vs : term list -> string list
    85   val terms_vs : term list -> string list
    86   val subsets : int -> int -> int list list
    86   val subsets : int -> int -> int list list
   102 
   102 
   103 (* debug stuff *)
   103 (* debug stuff *)
   104 
   104 
   105 fun tracing s = (if ! Toplevel.debug then Output.tracing s else ());
   105 fun tracing s = (if ! Toplevel.debug then Output.tracing s else ());
   106 
   106 
   107 fun print_tac s = (if ! Toplevel.debug then Tactical.print_tac s else Seq.single);
   107 fun print_tac s = Seq.single; (* (if ! Toplevel.debug then Tactical.print_tac s else Seq.single); *)
   108 fun debug_tac msg = (fn st => (Output.tracing msg; Seq.single st));
   108 fun debug_tac msg = (fn st => (Output.tracing msg; Seq.single st));
   109 
   109 
   110 val do_proofs = ref true;
   110 val do_proofs = ref true;
   111 
   111 
   112 fun mycheat_tac thy i st =
   112 fun mycheat_tac thy i st =
   463   val intro = Goal.prove (ProofContext.init thy) names [] intro_t
   463   val intro = Goal.prove (ProofContext.init thy) names [] intro_t
   464         (fn {...} => etac @{thm FalseE} 1)
   464         (fn {...} => etac @{thm FalseE} 1)
   465   val elim = Goal.prove (ProofContext.init thy) ("P" :: names) [] elim_t
   465   val elim = Goal.prove (ProofContext.init thy) ("P" :: names) [] elim_t
   466         (fn {...} => etac elim 1) 
   466         (fn {...} => etac elim 1) 
   467 in
   467 in
   468   ([intro], elim, 0)
   468   ([intro], elim)
   469 end
   469 end
   470 
   470 
   471 fun fetch_pred_data thy name =
   471 fun fetch_pred_data thy name =
   472   case try (Inductive.the_inductive (ProofContext.init thy)) name of
   472   case try (Inductive.the_inductive (ProofContext.init thy)) name of
   473     SOME (info as (_, result)) => 
   473     SOME (info as (_, result)) => 
   479         val intros = ind_set_codegen_preproc thy ((map (preprocess_intro thy))
   479         val intros = ind_set_codegen_preproc thy ((map (preprocess_intro thy))
   480           (filter is_intro_of (#intrs result)))
   480           (filter is_intro_of (#intrs result)))
   481         val pre_elim = nth (#elims result) (find_index (fn s => s = name) (#names (fst info)))
   481         val pre_elim = nth (#elims result) (find_index (fn s => s = name) (#names (fst info)))
   482         val nparams = length (Inductive.params_of (#raw_induct result))
   482         val nparams = length (Inductive.params_of (#raw_induct result))
   483         val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim)
   483         val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim)
       
   484         val (intros, elim) = if null intros then noclause thy name elim else (intros, elim)
   484       in
   485       in
   485         if null intros then noclause thy name elim else (intros, elim, nparams)
   486         mk_pred_data ((intros, SOME elim, nparams), ([], [], []))
   486       end                                                                    
   487       end                                                                    
   487   | NONE => error ("No such predicate: " ^ quote name)
   488   | NONE => error ("No such predicate: " ^ quote name)
   488   
   489   
   489 (* updaters *)
   490 (* updaters *)
   490 
   491 
   498   in PredData.map (Graph.map_node name (map_pred_data add)) end
   499   in PredData.map (Graph.map_node name (map_pred_data add)) end
   499 
   500 
   500 fun is_inductive_predicate thy name =
   501 fun is_inductive_predicate thy name =
   501   is_some (try (Inductive.the_inductive (ProofContext.init thy)) name)
   502   is_some (try (Inductive.the_inductive (ProofContext.init thy)) name)
   502 
   503 
   503 fun depending_preds_of thy intros = fold Term.add_const_names (map Thm.prop_of intros) []
   504 fun depending_preds_of thy (key, value) =
   504     |> filter (fn c => is_inductive_predicate thy c orelse is_registered thy c)
   505   let
   505 
   506     val intros = (#intros o rep_pred_data) value
       
   507   in
       
   508     fold Term.add_const_names (map Thm.prop_of intros) []
       
   509       |> filter (fn c => (not (c = key)) andalso (is_inductive_predicate thy c orelse is_registered thy c))
       
   510   end;
       
   511     
       
   512     
   506 (* code dependency graph *)    
   513 (* code dependency graph *)    
   507 
   514 (*
   508 fun dependencies_of thy name =
   515 fun dependencies_of thy name =
   509   let
   516   let
   510     val (intros, elim, nparams) = fetch_pred_data thy name 
   517     val (intros, elim, nparams) = fetch_pred_data thy name 
   511     val data = mk_pred_data ((intros, SOME elim, nparams), ([], [], []))
   518     val data = mk_pred_data ((intros, SOME elim, nparams), ([], [], []))
   512     val keys = depending_preds_of thy intros
   519     val keys = depending_preds_of thy intros
   513   in
   520   in
   514     (data, keys)
   521     (data, keys)
   515   end;
   522   end;
       
   523 *)
   516 
   524 
   517 (* TODO: add_edges - by analysing dependencies *)
   525 (* TODO: add_edges - by analysing dependencies *)
   518 fun add_intro thm thy = let
   526 fun add_intro thm thy = let
   519    val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm)))
   527    val (name, _) = dest_Const (fst (strip_intro_concl 0 (prop_of thm)))
   520    fun cons_intro gr =
   528    fun cons_intro gr =
   521      case try (Graph.get_node gr) name of
   529      case try (Graph.get_node gr) name of
   522        SOME pred_data => Graph.map_node name (map_pred_data
   530        SOME pred_data => Graph.map_node name (map_pred_data
   523          (apfst (fn (intro, elim, nparams) => (thm::intro, elim, nparams)))) gr
   531          (apfst (fn (intro, elim, nparams) => (thm::intro, elim, nparams)))) gr
   524      | NONE =>
   532      | NONE =>
   525        let
   533        let
   526          val nparams = the_default 0 (try (#3 o fetch_pred_data thy) name)
   534          val nparams = the_default 0 (try (#nparams o rep_pred_data o (fetch_pred_data thy)) name)
   527        in Graph.new_node (name, mk_pred_data (([thm], NONE, nparams), ([], [], []))) gr end;
   535        in Graph.new_node (name, mk_pred_data (([thm], NONE, nparams), ([], [], []))) gr end;
   528   in PredData.map cons_intro thy end
   536   in PredData.map cons_intro thy end
   529 
   537 
   530 fun set_elim thm = let
   538 fun set_elim thm = let
   531     val (name, _) = dest_Const (fst 
   539     val (name, _) = dest_Const (fst 
   535 
   543 
   536 fun set_nparams name nparams = let
   544 fun set_nparams name nparams = let
   537     fun set (intros, elim, _ ) = (intros, elim, nparams) 
   545     fun set (intros, elim, _ ) = (intros, elim, nparams) 
   538   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   546   in PredData.map (Graph.map_node name (map_pred_data (apfst set))) end
   539     
   547     
   540 fun register_predicate (intros, elim, nparams) = let
   548 fun register_predicate (pre_intros, pre_elim, nparams) thy = let
   541     val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd intros))))
   549     val (name, _) = dest_Const (fst (strip_intro_concl nparams (prop_of (hd pre_intros))))
   542   in
   550     (* preprocessing *)
   543     PredData.map (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), ([], [], []))))
   551     val intros = ind_set_codegen_preproc thy (map (preprocess_intro thy) pre_intros)
       
   552     val elim = singleton (ind_set_codegen_preproc thy) (preprocess_elim thy nparams pre_elim)
       
   553   in
       
   554     PredData.map
       
   555       (Graph.new_node (name, mk_pred_data ((intros, SOME elim, nparams), ([], [], [])))) thy
   544   end
   556   end
   545 
   557 
   546 fun set_generator_name pred mode name = 
   558 fun set_generator_name pred mode name = 
   547   let
   559   let
   548     val set = (apsnd o apsnd3 o cons) (mode, mk_function_data (name, NONE))
   560     val set = (apsnd o apsnd3 o cons) (mode, mk_function_data (name, NONE))
  1811     val intrs = maps (intros_of thy) prednames
  1823     val intrs = maps (intros_of thy) prednames
  1812       |> map (Logic.unvarify o prop_of)
  1824       |> map (Logic.unvarify o prop_of)
  1813     val nparams = nparams_of thy (hd prednames)
  1825     val nparams = nparams_of thy (hd prednames)
  1814     val preds = distinct (op =) (map (dest_Const o fst o (strip_intro_concl nparams)) intrs)
  1826     val preds = distinct (op =) (map (dest_Const o fst o (strip_intro_concl nparams)) intrs)
  1815     val extra_modes = all_modes_of thy |> filter_out (fn (name, _) => member (op =) prednames name)
  1827     val extra_modes = all_modes_of thy |> filter_out (fn (name, _) => member (op =) prednames name)
  1816     val _ = Output.tracing ("extra_modes are: " ^
  1828     (*val _ = Output.tracing ("extra_modes are: " ^
  1817       cat_lines (map (fn (name, modes) => name ^ " has modes:" ^
  1829       cat_lines (map (fn (name, modes) => name ^ " has modes:" ^
  1818       (commas (map string_of_mode modes))) extra_modes))
  1830       (commas (map string_of_mode modes))) extra_modes)) *)
  1819     val _ $ u = Logic.strip_imp_concl (hd intrs);
  1831     val _ $ u = Logic.strip_imp_concl (hd intrs);
  1820     val params = List.take (snd (strip_comb u), nparams);
  1832     val params = List.take (snd (strip_comb u), nparams);
  1821     val param_vs = maps term_vs params
  1833     val param_vs = maps term_vs params
  1822     val all_vs = terms_vs intrs
  1834     val all_vs = terms_vs intrs
  1823     fun dest_prem t =
  1835     fun dest_prem t =
  1882     |> Theory.checkpoint
  1894     |> Theory.checkpoint
  1883 in
  1895 in
  1884   thy''
  1896   thy''
  1885 end
  1897 end
  1886 
  1898 
       
  1899 fun extend' value_of edges_of key (G, visited) =
       
  1900   let
       
  1901     val _ = Output.tracing ("calling extend' with " ^ key)  
       
  1902     val (G', v) = case try (Graph.get_node G) key of
       
  1903         SOME v => (G, v)
       
  1904       | NONE => (Graph.new_node (key, value_of key) G, value_of key)
       
  1905     val (G'', visited') = fold (extend' value_of edges_of) (edges_of (key, v) \\ visited)
       
  1906       (G', key :: visited) 
       
  1907   in
       
  1908     (fold (Graph.add_edge o (pair key)) (edges_of (key, v)) G'', visited')
       
  1909   end;
       
  1910 
       
  1911 fun extend value_of edges_of key G = fst (extend' value_of edges_of key (G, [])) 
       
  1912   
  1887 fun gen_add_equations steps names thy =
  1913 fun gen_add_equations steps names thy =
  1888   let
  1914   let
  1889     val thy' = PredData.map (fold (Graph.extend (dependencies_of thy)) names) thy |> Theory.checkpoint;
  1915     val thy' = PredData.map (fold (extend (fetch_pred_data thy) (depending_preds_of thy)) names) thy |> Theory.checkpoint;
  1890     fun strong_conn_of gr keys =
  1916     fun strong_conn_of gr keys =
  1891       Graph.strong_conn (Graph.subgraph (member (op =) (Graph.all_succs gr keys)) gr)
  1917       Graph.strong_conn (Graph.subgraph (member (op =) (Graph.all_succs gr keys)) gr)
  1892     val scc = strong_conn_of (PredData.get thy') names
  1918     val scc = strong_conn_of (PredData.get thy') names
  1893     val thy'' = fold_rev
  1919     val thy'' = fold_rev
  1894       (fn preds => fn thy =>
  1920       (fn preds => fn thy =>
  1960 
  1986 
  1961 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *)
  1987 (* TODO: make TheoryDataFun to GenericDataFun & remove duplication of local theory and theory *)
  1962 (* TODO: must create state to prove multiple cases *)
  1988 (* TODO: must create state to prove multiple cases *)
  1963 fun generic_code_pred prep_const raw_const lthy =
  1989 fun generic_code_pred prep_const raw_const lthy =
  1964   let
  1990   let
  1965   
       
  1966     val thy = ProofContext.theory_of lthy
  1991     val thy = ProofContext.theory_of lthy
  1967     val const = prep_const thy raw_const
  1992     val const = prep_const thy raw_const
  1968     val _ = Output.tracing "extending graph"
  1993     val lthy' = LocalTheory.theory (PredData.map
  1969     val lthy' = LocalTheory.theory (PredData.map (Graph.extend (dependencies_of thy) const)) lthy
  1994         (extend (fetch_pred_data thy) (depending_preds_of thy) const)) lthy
  1970       |> LocalTheory.checkpoint
  1995       |> LocalTheory.checkpoint
  1971     val _ = Output.tracing "code_pred graph extended..."  
       
  1972     val thy' = ProofContext.theory_of lthy'
  1996     val thy' = ProofContext.theory_of lthy'
  1973     val preds = Graph.all_preds (PredData.get thy') [const] |> filter_out (has_elim thy')
  1997     val preds = Graph.all_preds (PredData.get thy') [const] |> filter_out (has_elim thy')
  1974     
       
  1975     fun mk_cases const =
  1998     fun mk_cases const =
  1976       let
  1999       let
  1977         val nparams = nparams_of thy' const
  2000         val nparams = nparams_of thy' const
  1978         val intros = intros_of thy' const
  2001         val intros = intros_of thy' const
  1979       in mk_casesrule lthy' nparams intros end  
  2002       in mk_casesrule lthy' nparams intros end