src/HOL/Tools/Predicate_Compile/predicate_compile_specialisation.ML
author wenzelm
Sun, 10 Dec 2023 13:39:40 +0100
changeset 79232 99bc2dd45111
parent 74561 8e6c973003c8
child 80636 4041e7c8059d
permissions -rw-r--r--
more general Logic.incr_indexes_operation; more special Logic.incr_indexes;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     1
(*  Title:      HOL/Tools/Predicate_Compile/predicate_compile_specialisation.ML
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     2
    Author:     Lukas Bulwahn, TU Muenchen
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     3
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     4
Deriving specialised predicates and their intro rules
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     5
*)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     6
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     7
signature PREDICATE_COMPILE_SPECIALISATION =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
     8
sig
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
     9
  val find_specialisations : string list -> (string * thm list) list ->
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    10
    theory -> (string * thm list) list * theory
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    11
end;
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    12
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    13
structure Predicate_Compile_Specialisation : PREDICATE_COMPILE_SPECIALISATION =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    14
struct
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    15
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    16
open Predicate_Compile_Aux;
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    17
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    18
(* table of specialisations *)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    19
structure Specialisations = Theory_Data
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    20
(
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    21
  type T = (term * term) Item_Net.T
59058
a78612c67ec0 renamed "pairself" to "apply2", in accordance to @{apply 2};
wenzelm
parents: 58950
diff changeset
    22
  val empty : T = Item_Net.init (op aconv o apply2 fst) (single o fst)
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    23
  val merge = Item_Net.merge
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    24
)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    25
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    26
fun specialisation_of thy atom =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    27
  Item_Net.retrieve (Specialisations.get thy) atom
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    28
50056
72efd6b4038d dropped dead code
haftmann
parents: 45906
diff changeset
    29
fun import (_, intros) args ctxt =
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    30
  let
50056
72efd6b4038d dropped dead code
haftmann
parents: 45906
diff changeset
    31
    val ((_, intros'), ctxt') = Variable.importT intros ctxt
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    32
    val pred' =
59582
0fbed69ff081 tuned signature -- prefer qualified names;
wenzelm
parents: 59058
diff changeset
    33
      fst (strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl (Thm.prop_of (hd intros')))))
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    34
    val Ts = binder_types (fastype_of pred')
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    35
    val argTs = map fastype_of args
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    36
    val Tsubst = Type.raw_matches (argTs, Ts) Vartab.empty
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    37
    val args' = map (Envir.subst_term_types Tsubst) args
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    38
  in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    39
    (((pred', intros'), args'), ctxt')
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    40
  end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    41
36036
ea7d0df15be0 no specialisation for patterns with only tuples in the predicate compiler
bulwahn
parents: 36032
diff changeset
    42
(* patterns only constructed of variables and pairs/tuples are trivial constructor terms*)
62581
fc5198b44314 clarified: constructors in the sense of the code generator are not invertible;
haftmann
parents: 62391
diff changeset
    43
fun is_nontrivial_constrt ctxt t =
36036
ea7d0df15be0 no specialisation for patterns with only tuples in the predicate compiler
bulwahn
parents: 36032
diff changeset
    44
  let
62581
fc5198b44314 clarified: constructors in the sense of the code generator are not invertible;
haftmann
parents: 62391
diff changeset
    45
    val lookup_constr = lookup_constr ctxt
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    46
    fun check t =
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    47
      (case strip_comb t of
36036
ea7d0df15be0 no specialisation for patterns with only tuples in the predicate compiler
bulwahn
parents: 36032
diff changeset
    48
        (Var _, []) => (true, true)
ea7d0df15be0 no specialisation for patterns with only tuples in the predicate compiler
bulwahn
parents: 36032
diff changeset
    49
      | (Free _, []) => (true, true)
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 63617
diff changeset
    50
      | (Const (\<^const_name>\<open>Pair\<close>, _), ts) =>
59058
a78612c67ec0 renamed "pairself" to "apply2", in accordance to @{apply 2};
wenzelm
parents: 58950
diff changeset
    51
        apply2 (forall I) (split_list (map check ts))
62581
fc5198b44314 clarified: constructors in the sense of the code generator are not invertible;
haftmann
parents: 62391
diff changeset
    52
      | (Const cT, ts) =>
fc5198b44314 clarified: constructors in the sense of the code generator are not invertible;
haftmann
parents: 62391
diff changeset
    53
          (case lookup_constr cT of
fc5198b44314 clarified: constructors in the sense of the code generator are not invertible;
haftmann
parents: 62391
diff changeset
    54
            SOME i => (false,
fc5198b44314 clarified: constructors in the sense of the code generator are not invertible;
haftmann
parents: 62391
diff changeset
    55
              length ts = i andalso forall (snd o check) ts)
36036
ea7d0df15be0 no specialisation for patterns with only tuples in the predicate compiler
bulwahn
parents: 36032
diff changeset
    56
          | _ => (false, false))
ea7d0df15be0 no specialisation for patterns with only tuples in the predicate compiler
bulwahn
parents: 36032
diff changeset
    57
      | _ => (false, false))
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    58
  in check t = (false, true) end
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    59
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    60
fun specialise_intros black_list (pred, intros) pats thy =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    61
  let
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 40053
diff changeset
    62
    val ctxt = Proof_Context.init_global thy
59582
0fbed69ff081 tuned signature -- prefer qualified names;
wenzelm
parents: 59058
diff changeset
    63
    val maxidx = fold (Term.maxidx_term o Thm.prop_of) intros ~1
79232
99bc2dd45111 more general Logic.incr_indexes_operation;
wenzelm
parents: 74561
diff changeset
    64
    val pats = map (Logic.incr_indexes ([], maxidx + 1)) pats
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    65
    val (((pred, intros), pats), ctxt') = import (pred, intros) pats ctxt
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    66
    val result_pats = map Var (fold_rev Term.add_vars pats [])
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    67
    fun mk_fresh_name names =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    68
      let
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    69
        val name =
43324
2b47822868e4 discontinued Name.variant to emphasize that this is old-style / indirect;
wenzelm
parents: 42361
diff changeset
    70
          singleton (Name.variant_list names)
2b47822868e4 discontinued Name.variant to emphasize that this is old-style / indirect;
wenzelm
parents: 42361
diff changeset
    71
            ("specialised_" ^ Long_Name.base_name (fst (dest_Const pred)))
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    72
        val bname = Sign.full_bname thy name
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    73
      in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    74
        if Sign.declared_const thy bname then
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    75
          mk_fresh_name (name :: names)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    76
        else
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    77
          bname
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    78
      end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    79
    val constname = mk_fresh_name []
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 63617
diff changeset
    80
    val constT = map fastype_of result_pats ---> \<^typ>\<open>bool\<close>
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    81
    val specialised_const = Const (constname, constT)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    82
    fun specialise_intro intro =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    83
      (let
59582
0fbed69ff081 tuned signature -- prefer qualified names;
wenzelm
parents: 59058
diff changeset
    84
        val (prems, concl) = Logic.strip_horn (Thm.prop_of intro)
58950
d07464875dd4 optional proof context for unify operations, for the sake of proper local options;
wenzelm
parents: 56239
diff changeset
    85
        val env = Pattern.unify (Context.Theory thy)
63617
3646e2ba554c clarified -- more standard maxidx;
wenzelm
parents: 62581
diff changeset
    86
          (HOLogic.mk_Trueprop (list_comb (pred, pats)), concl) Envir.init
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    87
        val prems = map (Envir.norm_term env) prems
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    88
        val args = map (Envir.norm_term env) result_pats
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    89
        val concl = HOLogic.mk_Trueprop (list_comb (specialised_const, args))
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    90
        val intro = Logic.list_implies (prems, concl)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    91
      in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    92
        SOME intro
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    93
      end handle Pattern.Unif => NONE)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    94
    val specialised_intros_t = map_filter I (map specialise_intro intros)
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
    95
    val thy' =
56239
17df7145a871 tuned signature;
wenzelm
parents: 55440
diff changeset
    96
      Sign.add_consts [(Binding.name (Long_Name.base_name constname), constT, NoSyn)] thy
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    97
    val specialised_intros = map (Skip_Proof.make_thm thy') specialised_intros_t
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    98
    val exported_intros = Variable.exportT ctxt' ctxt specialised_intros
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
    99
    val [t, specialised_t] = Variable.exportT_terms ctxt' ctxt
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   100
      [list_comb (pred, pats), list_comb (specialised_const, result_pats)]
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   101
    val thy'' = Specialisations.map (Item_Net.update (t, specialised_t)) thy'
36246
43fecedff8cf added peephole optimisations to the predicate compiler; added structure Predicate_Compile_Simps for peephole optimisations
bulwahn
parents: 36052
diff changeset
   102
    val optimised_intros =
43fecedff8cf added peephole optimisations to the predicate compiler; added structure Predicate_Compile_Simps for peephole optimisations
bulwahn
parents: 36052
diff changeset
   103
      map_filter (Predicate_Compile_Aux.peephole_optimisation thy'') exported_intros
43fecedff8cf added peephole optimisations to the predicate compiler; added structure Predicate_Compile_Simps for peephole optimisations
bulwahn
parents: 36052
diff changeset
   104
    val ([spec], thy''') = find_specialisations black_list [(constname, optimised_intros)] thy''
40053
3fa49ea76cbb using a signature in core_data and moving some more functions to core_data
bulwahn
parents: 38759
diff changeset
   105
    val thy'''' = Core_Data.register_intros spec thy'''
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   106
  in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   107
    thy''''
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   108
  end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   109
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   110
and find_specialisations black_list specs thy =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   111
  let
55399
5c8e91f884af ported predicate compiler to 'ctr_sugar'
blanchet
parents: 50056
diff changeset
   112
    val ctxt = Proof_Context.init_global thy
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   113
    val add_vars = fold_aterms (fn Var v => cons v | _ => I);
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   114
    fun fresh_free T free_names =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   115
      let
43324
2b47822868e4 discontinued Name.variant to emphasize that this is old-style / indirect;
wenzelm
parents: 42361
diff changeset
   116
        val free_name = singleton (Name.variant_list free_names) "x"
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   117
      in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   118
        (Free (free_name, T), free_name :: free_names)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   119
      end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   120
    fun replace_term_and_restrict thy T t Tts free_names =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   121
      let
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   122
        val (free, free_names') = fresh_free T free_names
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   123
        val Tts' = map (apsnd (Pattern.rewrite_term thy [(t, free)] [])) Tts
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   124
        val (ts', free_names'') = restrict_pattern' thy Tts' free_names'
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   125
      in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   126
        (free :: ts', free_names'')
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   127
      end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   128
    and restrict_pattern' thy [] free_names = ([], free_names)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   129
      | restrict_pattern' thy ((T, Free (x, _)) :: Tts) free_names =
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   130
          let
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   131
            val (ts', free_names') = restrict_pattern' thy Tts free_names
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   132
          in
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   133
            (Free (x, T) :: ts', free_names')
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   134
          end
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   135
      | restrict_pattern' thy ((T as TFree _, t) :: Tts) free_names =
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   136
          replace_term_and_restrict thy T t Tts free_names
50056
72efd6b4038d dropped dead code
haftmann
parents: 45906
diff changeset
   137
      | restrict_pattern' thy ((T as Type (Tcon, _), t) :: Tts) free_names =
55399
5c8e91f884af ported predicate compiler to 'ctr_sugar'
blanchet
parents: 50056
diff changeset
   138
        case Ctr_Sugar.ctr_sugar_of ctxt Tcon of
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   139
          NONE => replace_term_and_restrict thy T t Tts free_names
55440
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   140
        | SOME {ctrs, ...} =>
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   141
          (case strip_comb t of
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   142
            (Const (s, _), ats) =>
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   143
              (case AList.lookup (op =) (map_filter (try dest_Const) ctrs) s of
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   144
                SOME constr_T =>
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   145
                  let
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   146
                    val (Ts', T') = strip_type constr_T
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   147
                    val Tsubst = Type.raw_match (T', T) Vartab.empty
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   148
                    val Ts = map (Envir.subst_type Tsubst) Ts'
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   149
                    val (bts', free_names') = restrict_pattern' thy ((Ts ~~ ats) @ Tts) free_names
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   150
                    val (ats', ts') = chop (length ats) bts'
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   151
                  in
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   152
                    (list_comb (Const (s, map fastype_of ats' ---> T), ats') :: ts', free_names')
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   153
                  end
721b4561007a merged, resolving some conflicts;
wenzelm
parents: 55399 55437
diff changeset
   154
              | NONE => replace_term_and_restrict thy T t Tts free_names))
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   155
    fun restrict_pattern thy Ts args =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   156
      let
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   157
        val args = map Logic.unvarify_global args
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   158
        val Ts = map Logic.unvarifyT_global Ts
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   159
        val free_names = fold Term.add_free_names args []
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   160
        val (pat, _) = restrict_pattern' thy (Ts ~~ args) free_names
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   161
      in map Logic.varify_global pat end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   162
    fun detect' atom thy =
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   163
      (case strip_comb atom of
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   164
        (pred as Const (pred_name, _), args) =>
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   165
          let
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   166
            val Ts = binder_types (Sign.the_const_type thy pred_name)
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   167
            val pats = restrict_pattern thy Ts args
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   168
          in
62581
fc5198b44314 clarified: constructors in the sense of the code generator are not invertible;
haftmann
parents: 62391
diff changeset
   169
            if (exists (is_nontrivial_constrt ctxt) pats)
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   170
              orelse (has_duplicates (op =) (fold add_vars pats [])) then
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   171
              let
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   172
                val thy' =
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   173
                  (case specialisation_of thy atom of
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   174
                    [] =>
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   175
                      if member (op =) ((map fst specs) @ black_list) pred_name then
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   176
                        thy
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   177
                      else
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   178
                        (case try (Core_Data.intros_of (Proof_Context.init_global thy)) pred_name of
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   179
                          NONE => thy
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   180
                        | SOME [] => thy
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   181
                        | SOME intros =>
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   182
                            specialise_intros ((map fst specs) @ (pred_name :: black_list))
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   183
                              (pred, intros) pats thy)
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   184
                  | _ :: _ => thy)
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   185
                val atom' =
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   186
                  (case specialisation_of thy' atom of
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   187
                    [] => atom
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   188
                  | (t, specialised_t) :: _ =>
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   189
                    let
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   190
                      val subst = Pattern.match thy' (t, atom) (Vartab.empty, Vartab.empty)
55437
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   191
                    in Envir.subst_term subst specialised_t end handle Pattern.MATCH => atom)
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   192
                    (*FIXME: this exception could be handled earlier in specialisation_of *)
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   193
              in
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   194
                (atom', thy')
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   195
              end
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   196
            else (atom, thy)
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   197
          end
3fd63b92ea3b tuned whitespace;
wenzelm
parents: 50056
diff changeset
   198
      | _ => (atom, thy))
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   199
    fun specialise' (constname, intros) thy =
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   200
      let
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   201
        (* FIXME: only necessary because of sloppy Logic.unvarify in restrict_pattern *)
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   202
        val intros = Drule.zero_var_indexes_list intros
59582
0fbed69ff081 tuned signature -- prefer qualified names;
wenzelm
parents: 59058
diff changeset
   203
        val (intros_t', thy') = (fold_map o fold_map_atoms) detect' (map Thm.prop_of intros) thy
36032
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   204
      in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   205
        ((constname, map (Skip_Proof.make_thm thy') intros_t'), thy')
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   206
      end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   207
  in
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   208
    fold_map specialise' specs thy
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   209
  end
dfd30b5b4e73 adding specialisation of predicates to the predicate compiler
bulwahn
parents:
diff changeset
   210
62391
1658fc9b2618 more canonical names
nipkow
parents: 59787
diff changeset
   211
end