src/HOL/Tools/Predicate_Compile/mode_inference.ML
author wenzelm
Sun, 13 Mar 2011 15:10:00 +0100
changeset 41941 f823f7fae9a2
parent 40052 ea46574ca815
child 42011 dee23d63d466
permissions -rw-r--r--
tuned headers;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
40052
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     1
(*  Title:      HOL/Tools/Predicate_Compile/mode_inference.ML
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     2
    Author:     Lukas Bulwahn, TU Muenchen
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     3
41941
f823f7fae9a2 tuned headers;
wenzelm
parents: 40052
diff changeset
     4
Mode inference for the predicate compiler.
40052
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     5
*)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     6
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     7
signature MODE_INFERENCE =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     8
sig
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
     9
  type mode = Predicate_Compile_Aux.mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    10
  
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    11
  (* options *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    12
  type mode_analysis_options =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    13
  {use_generators : bool,
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    14
  reorder_premises : bool,
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    15
  infer_pos_and_neg_modes : bool}
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    16
  
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    17
  (* mode operation *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    18
  val all_input_of : typ -> mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    19
  (* mode derivation and operations *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    20
  datatype mode_derivation = Mode_App of mode_derivation * mode_derivation | Context of mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    21
    | Mode_Pair of mode_derivation * mode_derivation | Term of mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    22
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    23
  val head_mode_of : mode_derivation -> mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    24
  val param_derivations_of : mode_derivation -> mode_derivation list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    25
  val collect_context_modes : mode_derivation -> mode list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    26
  
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    27
  type moded_clause = term list * (Predicate_Compile_Aux.indprem * mode_derivation) list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    28
  type 'a pred_mode_table = (string * ((bool * mode) * 'a) list) list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    29
 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    30
  (* mode inference operations *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    31
  val all_derivations_of :
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    32
    Proof.context -> (string * mode list) list -> string list -> term
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    33
      -> (mode_derivation * string list) list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    34
  (* TODO: move all_modes creation to infer_modes *) 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    35
  val infer_modes : 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    36
    mode_analysis_options -> Predicate_Compile_Aux.options ->
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    37
     (string -> mode list) * (string -> mode list)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    38
       * (string -> mode -> bool) -> Proof.context -> (string * typ) list ->
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    39
      (string * mode list) list ->
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    40
      string list -> (string * (Term.term list * Predicate_Compile_Aux.indprem list) list) list ->
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    41
      ((moded_clause list pred_mode_table * (string * mode list) list) * string list)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    42
  
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    43
  (* mode and term operations -- to be moved to Predicate_Compile_Aux *) 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    44
  val collect_non_invertible_subterms :
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    45
    Proof.context -> term -> string list * term list ->  (term * (string list * term list))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    46
  val is_all_input : mode -> bool
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    47
  val term_vs : term -> string list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    48
  val terms_vs : term list -> string list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    49
  
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    50
end;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    51
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    52
structure Mode_Inference : MODE_INFERENCE =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    53
struct
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    54
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    55
open Predicate_Compile_Aux;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    56
open Core_Data;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    57
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    58
(* derivation trees for modes of premises *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    59
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    60
datatype mode_derivation = Mode_App of mode_derivation * mode_derivation | Context of mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    61
  | Mode_Pair of mode_derivation * mode_derivation | Term of mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    62
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    63
fun string_of_derivation (Mode_App (m1, m2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    64
  "App (" ^ string_of_derivation m1 ^ ", " ^ string_of_derivation m2 ^ ")"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    65
  | string_of_derivation (Mode_Pair (m1, m2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    66
  "Pair (" ^ string_of_derivation m1 ^ ", " ^ string_of_derivation m2 ^ ")"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    67
  | string_of_derivation (Term m) = "Term (" ^ string_of_mode m ^ ")"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    68
  | string_of_derivation (Context m) = "Context (" ^ string_of_mode m ^ ")"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    69
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    70
fun strip_mode_derivation deriv =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    71
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    72
    fun strip (Mode_App (deriv1, deriv2)) ds = strip deriv1 (deriv2 :: ds)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    73
      | strip deriv ds = (deriv, ds)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    74
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    75
    strip deriv []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    76
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    77
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    78
fun mode_of (Context m) = m
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    79
  | mode_of (Term m) = m
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    80
  | mode_of (Mode_App (d1, d2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    81
    (case mode_of d1 of Fun (m, m') =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    82
        (if eq_mode (m, mode_of d2) then m' else raise Fail "mode_of: derivation has mismatching modes")
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    83
      | _ => raise Fail "mode_of: derivation has a non-functional mode")
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    84
  | mode_of (Mode_Pair (d1, d2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    85
    Pair (mode_of d1, mode_of d2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    86
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    87
fun head_mode_of deriv = mode_of (fst (strip_mode_derivation deriv))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    88
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    89
fun param_derivations_of deriv =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    90
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    91
    val (_, argument_derivs) = strip_mode_derivation deriv
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    92
    fun param_derivation (Mode_Pair (m1, m2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    93
        param_derivation m1 @ param_derivation m2
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    94
      | param_derivation (Term _) = []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    95
      | param_derivation m = [m]
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    96
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    97
    maps param_derivation argument_derivs
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    98
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
    99
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   100
fun collect_context_modes (Mode_App (m1, m2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   101
      collect_context_modes m1 @ collect_context_modes m2
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   102
  | collect_context_modes (Mode_Pair (m1, m2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   103
      collect_context_modes m1 @ collect_context_modes m2
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   104
  | collect_context_modes (Context m) = [m]
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   105
  | collect_context_modes (Term _) = []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   106
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   107
type moded_clause = term list * (Predicate_Compile_Aux.indprem * mode_derivation) list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   108
type 'a pred_mode_table = (string * ((bool * mode) * 'a) list) list
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   109
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   110
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   111
(** string_of functions **)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   112
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   113
fun string_of_prem ctxt (Prem t) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   114
    (Syntax.string_of_term ctxt t) ^ "(premise)"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   115
  | string_of_prem ctxt (Negprem t) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   116
    (Syntax.string_of_term ctxt (HOLogic.mk_not t)) ^ "(negative premise)"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   117
  | string_of_prem ctxt (Sidecond t) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   118
    (Syntax.string_of_term ctxt t) ^ "(sidecondition)"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   119
  | string_of_prem ctxt _ = raise Fail "string_of_prem: unexpected input"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   120
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   121
fun string_of_clause ctxt pred (ts, prems) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   122
  (space_implode " --> "
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   123
  (map (string_of_prem ctxt) prems)) ^ " --> " ^ pred ^ " "
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   124
   ^ (space_implode " " (map (Syntax.string_of_term ctxt) ts))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   125
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   126
type mode_analysis_options =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   127
  {use_generators : bool,
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   128
  reorder_premises : bool,
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   129
  infer_pos_and_neg_modes : bool}
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   130
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   131
fun is_constrt thy =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   132
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   133
    val cnstrs = flat (maps
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   134
      (map (fn (_, (Tname, _, cs)) => map (apsnd (rpair Tname o length)) cs) o #descr o snd)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   135
      (Symtab.dest (Datatype.get_all thy)));
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   136
    fun check t = (case strip_comb t of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   137
        (Free _, []) => true
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   138
      | (Const (s, T), ts) => (case (AList.lookup (op =) cnstrs s, body_type T) of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   139
            (SOME (i, Tname), Type (Tname', _)) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   140
              length ts = i andalso Tname = Tname' andalso forall check ts
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   141
          | _ => false)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   142
      | _ => false)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   143
  in check end;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   144
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   145
(*** check if a type is an equality type (i.e. doesn't contain fun)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   146
  FIXME this is only an approximation ***)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   147
fun is_eqT (Type (s, Ts)) = s <> "fun" andalso forall is_eqT Ts
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   148
  | is_eqT _ = true;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   149
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   150
fun term_vs tm = fold_aterms (fn Free (x, T) => cons x | _ => I) tm [];
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   151
val terms_vs = distinct (op =) o maps term_vs;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   152
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   153
(** collect all Frees in a term (with duplicates!) **)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   154
fun term_vTs tm =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   155
  fold_aterms (fn Free xT => cons xT | _ => I) tm [];
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   156
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   157
fun subsets i j =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   158
  if i <= j then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   159
    let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   160
      fun merge xs [] = xs
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   161
        | merge [] ys = ys
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   162
        | merge (x::xs) (y::ys) = if length x >= length y then x::merge xs (y::ys)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   163
            else y::merge (x::xs) ys;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   164
      val is = subsets (i+1) j
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   165
    in merge (map (fn ks => i::ks) is) is end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   166
  else [[]];
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   167
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   168
fun print_failed_mode options thy modes p (pol, m) rs is =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   169
  if show_mode_inference options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   170
    let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   171
      val _ = tracing ("Clauses " ^ commas (map (fn i => string_of_int (i + 1)) is) ^ " of " ^
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   172
        p ^ " violates mode " ^ string_of_mode m)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   173
    in () end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   174
  else ()
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   175
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   176
fun error_of p (pol, m) is =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   177
  "  Clauses " ^ commas (map (fn i => string_of_int (i + 1)) is) ^ " of " ^
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   178
        p ^ " violates mode " ^ string_of_mode m
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   179
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   180
fun is_all_input mode =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   181
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   182
    fun is_all_input' (Fun _) = true
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   183
      | is_all_input' (Pair (m1, m2)) = is_all_input' m1 andalso is_all_input' m2
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   184
      | is_all_input' Input = true
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   185
      | is_all_input' Output = false
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   186
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   187
    forall is_all_input' (strip_fun_mode mode)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   188
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   189
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   190
fun all_input_of T =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   191
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   192
    val (Ts, U) = strip_type T
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   193
    fun input_of (Type (@{type_name Product_Type.prod}, [T1, T2])) = Pair (input_of T1, input_of T2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   194
      | input_of _ = Input
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   195
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   196
    if U = HOLogic.boolT then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   197
      fold_rev (curry Fun) (map input_of Ts) Bool
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   198
    else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   199
      raise Fail "all_input_of: not a predicate"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   200
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   201
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   202
fun find_least ord xs =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   203
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   204
    fun find' x y = (case y of NONE => SOME x | SOME y' => if ord (x, y') = LESS then SOME x else y) 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   205
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   206
    fold find' xs NONE
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   207
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   208
  
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   209
fun term_vs tm = fold_aterms (fn Free (x, T) => cons x | _ => I) tm [];
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   210
val terms_vs = distinct (op =) o maps term_vs;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   211
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   212
fun input_mode T =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   213
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   214
    val (Ts, U) = strip_type T
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   215
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   216
    fold_rev (curry Fun) (map (K Input) Ts) Input
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   217
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   218
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   219
fun output_mode T =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   220
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   221
    val (Ts, U) = strip_type T
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   222
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   223
    fold_rev (curry Fun) (map (K Output) Ts) Output
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   224
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   225
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   226
fun is_invertible_function ctxt (Const (f, _)) = is_constr ctxt f
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   227
  | is_invertible_function ctxt _ = false
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   228
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   229
fun non_invertible_subterms ctxt (t as Free _) = []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   230
  | non_invertible_subterms ctxt t = 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   231
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   232
    val (f, args) = strip_comb t
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   233
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   234
    if is_invertible_function ctxt f then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   235
      maps (non_invertible_subterms ctxt) args
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   236
    else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   237
      [t]
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   238
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   239
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   240
fun collect_non_invertible_subterms ctxt (f as Free _) (names, eqs) = (f, (names, eqs))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   241
  | collect_non_invertible_subterms ctxt t (names, eqs) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   242
    case (strip_comb t) of (f, args) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   243
      if is_invertible_function ctxt f then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   244
          let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   245
            val (args', (names', eqs')) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   246
              fold_map (collect_non_invertible_subterms ctxt) args (names, eqs)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   247
          in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   248
            (list_comb (f, args'), (names', eqs'))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   249
          end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   250
        else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   251
          let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   252
            val s = Name.variant names "x"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   253
            val v = Free (s, fastype_of t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   254
          in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   255
            (v, (s :: names, HOLogic.mk_eq (v, t) :: eqs))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   256
          end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   257
(*
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   258
  if is_constrt thy t then (t, (names, eqs)) else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   259
    let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   260
      val s = Name.variant names "x"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   261
      val v = Free (s, fastype_of t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   262
    in (v, (s::names, HOLogic.mk_eq (v, t)::eqs)) end;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   263
*)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   264
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   265
fun is_possible_output ctxt vs t =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   266
  forall
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   267
    (fn t => is_eqT (fastype_of t) andalso forall (member (op =) vs) (term_vs t))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   268
      (non_invertible_subterms ctxt t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   269
  andalso
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   270
    (forall (is_eqT o snd)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   271
      (inter (fn ((f', _), f) => f = f') vs (Term.add_frees t [])))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   272
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   273
fun vars_of_destructable_term ctxt (Free (x, _)) = [x]
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   274
  | vars_of_destructable_term ctxt t =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   275
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   276
    val (f, args) = strip_comb t
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   277
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   278
    if is_invertible_function ctxt f then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   279
      maps (vars_of_destructable_term ctxt) args
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   280
    else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   281
      []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   282
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   283
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   284
fun is_constructable vs t = forall (member (op =) vs) (term_vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   285
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   286
fun missing_vars vs t = subtract (op =) vs (term_vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   287
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   288
fun output_terms (Const (@{const_name Pair}, _) $ t1 $ t2, Mode_Pair (d1, d2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   289
    output_terms (t1, d1)  @ output_terms (t2, d2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   290
  | output_terms (t1 $ t2, Mode_App (d1, d2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   291
    output_terms (t1, d1)  @ output_terms (t2, d2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   292
  | output_terms (t, Term Output) = [t]
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   293
  | output_terms _ = []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   294
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   295
fun lookup_mode modes (Const (s, T)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   296
   (case (AList.lookup (op =) modes s) of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   297
      SOME ms => SOME (map (fn m => (Context m, [])) ms)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   298
    | NONE => NONE)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   299
  | lookup_mode modes (Free (x, _)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   300
    (case (AList.lookup (op =) modes x) of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   301
      SOME ms => SOME (map (fn m => (Context m , [])) ms)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   302
    | NONE => NONE)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   303
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   304
fun derivations_of (ctxt : Proof.context) modes vs (Const (@{const_name Pair}, _) $ t1 $ t2) (Pair (m1, m2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   305
    map_product
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   306
      (fn (m1, mvars1) => fn (m2, mvars2) => (Mode_Pair (m1, m2), union (op =) mvars1 mvars2))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   307
        (derivations_of ctxt modes vs t1 m1) (derivations_of ctxt modes vs t2 m2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   308
  | derivations_of ctxt modes vs t (m as Fun _) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   309
    (*let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   310
      val (p, args) = strip_comb t
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   311
    in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   312
      (case lookup_mode modes p of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   313
        SOME ms => map_filter (fn (Context m, []) => let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   314
          val ms = strip_fun_mode m
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   315
          val (argms, restms) = chop (length args) ms
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   316
          val m' = fold_rev (curry Fun) restms Bool
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   317
        in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   318
          if forall (fn m => eq_mode (Input, m)) argms andalso eq_mode (m', mode) then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   319
            SOME (fold (curry Mode_App) (map Term argms) (Context m), missing_vars vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   320
          else NONE
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   321
        end) ms
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   322
      | NONE => (if is_all_input mode then [(Context mode, [])] else []))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   323
    end*)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   324
    (case try (all_derivations_of ctxt modes vs) t  of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   325
      SOME derivs =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   326
        filter (fn (d, mvars) => eq_mode (mode_of d, m) andalso null (output_terms (t, d))) derivs
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   327
    | NONE => (if is_all_input m then [(Context m, [])] else []))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   328
  | derivations_of ctxt modes vs t m =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   329
    if eq_mode (m, Input) then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   330
      [(Term Input, missing_vars vs t)]
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   331
    else if eq_mode (m, Output) then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   332
      (if is_possible_output ctxt vs t then [(Term Output, [])] else [])
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   333
    else []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   334
and all_derivations_of ctxt modes vs (Const (@{const_name Pair}, _) $ t1 $ t2) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   335
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   336
    val derivs1 = all_derivations_of ctxt modes vs t1
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   337
    val derivs2 = all_derivations_of ctxt modes vs t2
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   338
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   339
    map_product
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   340
      (fn (m1, mvars1) => fn (m2, mvars2) => (Mode_Pair (m1, m2), union (op =) mvars1 mvars2))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   341
        derivs1 derivs2
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   342
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   343
  | all_derivations_of ctxt modes vs (t1 $ t2) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   344
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   345
    val derivs1 = all_derivations_of ctxt modes vs t1
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   346
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   347
    maps (fn (d1, mvars1) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   348
      case mode_of d1 of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   349
        Fun (m', _) => map (fn (d2, mvars2) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   350
          (Mode_App (d1, d2), union (op =) mvars1 mvars2)) (derivations_of ctxt modes vs t2 m')
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   351
        | _ => raise Fail "all_derivations_of: derivation has an unexpected non-functional mode") derivs1
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   352
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   353
  | all_derivations_of _ modes vs (Const (s, T)) = the (lookup_mode modes (Const (s, T)))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   354
  | all_derivations_of _ modes vs (Free (x, T)) = the (lookup_mode modes (Free (x, T)))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   355
  | all_derivations_of _ modes vs _ = raise Fail "all_derivations_of: unexpected term"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   356
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   357
fun rev_option_ord ord (NONE, NONE) = EQUAL
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   358
  | rev_option_ord ord (NONE, SOME _) = GREATER
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   359
  | rev_option_ord ord (SOME _, NONE) = LESS
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   360
  | rev_option_ord ord (SOME x, SOME y) = ord (x, y)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   361
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   362
fun random_mode_in_deriv modes t deriv =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   363
  case try dest_Const (fst (strip_comb t)) of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   364
    SOME (s, _) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   365
      (case AList.lookup (op =) modes s of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   366
        SOME ms =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   367
          (case AList.lookup (op =) (map (fn ((p, m), r) => (m, r)) ms) (head_mode_of deriv) of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   368
            SOME r => r
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   369
          | NONE => false)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   370
      | NONE => false)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   371
  | NONE => false
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   372
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   373
fun number_of_output_positions mode =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   374
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   375
    val args = strip_fun_mode mode
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   376
    fun contains_output (Fun _) = false
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   377
      | contains_output Input = false
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   378
      | contains_output Output = true
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   379
      | contains_output (Pair (m1, m2)) = contains_output m1 orelse contains_output m2
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   380
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   381
    length (filter contains_output args)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   382
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   383
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   384
fun lex_ord ord1 ord2 (x, x') =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   385
  case ord1 (x, x') of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   386
    EQUAL => ord2 (x, x')
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   387
  | ord => ord
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   388
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   389
fun lexl_ord [] (x, x') = EQUAL
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   390
  | lexl_ord (ord :: ords') (x, x') =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   391
    case ord (x, x') of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   392
      EQUAL => lexl_ord ords' (x, x')
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   393
    | ord => ord
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   394
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   395
fun deriv_ord' ctxt pol pred modes t1 t2 ((deriv1, mvars1), (deriv2, mvars2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   396
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   397
    (* prefer functional modes if it is a function *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   398
    fun fun_ord ((t1, deriv1, mvars1), (t2, deriv2, mvars2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   399
      let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   400
        fun is_functional t mode =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   401
          case try (fst o dest_Const o fst o strip_comb) t of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   402
            NONE => false
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   403
          | SOME c => is_some (alternative_compilation_of ctxt c mode)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   404
      in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   405
        case (is_functional t1 (head_mode_of deriv1), is_functional t2 (head_mode_of deriv2)) of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   406
          (true, true) => EQUAL
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   407
        | (true, false) => LESS
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   408
        | (false, true) => GREATER
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   409
        | (false, false) => EQUAL
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   410
      end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   411
    (* prefer modes without requirement for generating random values *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   412
    fun mvars_ord ((t1, deriv1, mvars1), (t2, deriv2, mvars2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   413
      int_ord (length mvars1, length mvars2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   414
    (* prefer non-random modes *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   415
    fun random_mode_ord ((t1, deriv1, mvars1), (t2, deriv2, mvars2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   416
      int_ord (if random_mode_in_deriv modes t1 deriv1 then 1 else 0,
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   417
               if random_mode_in_deriv modes t2 deriv2 then 1 else 0)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   418
    (* prefer modes with more input and less output *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   419
    fun output_mode_ord ((t1, deriv1, mvars1), (t2, deriv2, mvars2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   420
      int_ord (number_of_output_positions (head_mode_of deriv1),
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   421
        number_of_output_positions (head_mode_of deriv2))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   422
    (* prefer recursive calls *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   423
    fun is_rec_premise t =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   424
      case fst (strip_comb t) of Const (c, T) => c = pred | _ => false
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   425
    fun recursive_ord ((t1, deriv1, mvars1), (t2, deriv2, mvars2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   426
      int_ord (if is_rec_premise t1 then 0 else 1,
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   427
        if is_rec_premise t2 then 0 else 1)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   428
    val ord = lexl_ord [mvars_ord, fun_ord, random_mode_ord, output_mode_ord, recursive_ord]
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   429
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   430
    ord ((t1, deriv1, mvars1), (t2, deriv2, mvars2))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   431
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   432
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   433
fun deriv_ord ctxt pol pred modes t = deriv_ord' ctxt pol pred modes t t
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   434
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   435
fun premise_ord thy pol pred modes ((prem1, a1), (prem2, a2)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   436
  rev_option_ord (deriv_ord' thy pol pred modes (dest_indprem prem1) (dest_indprem prem2)) (a1, a2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   437
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   438
fun print_mode_list modes =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   439
  tracing ("modes: " ^ (commas (map (fn (s, ms) => s ^ ": " ^
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   440
    commas (map (fn (m, r) => string_of_mode m ^ (if r then " random " else " not ")) ms)) modes)))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   441
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   442
fun select_mode_prem (mode_analysis_options : mode_analysis_options) (ctxt : Proof.context) pred
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   443
  pol (modes, (pos_modes, neg_modes)) vs ps =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   444
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   445
    fun choose_mode_of_prem (Prem t) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   446
          find_least (deriv_ord ctxt pol pred modes t) (all_derivations_of ctxt pos_modes vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   447
      | choose_mode_of_prem (Sidecond t) = SOME (Context Bool, missing_vars vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   448
      | choose_mode_of_prem (Negprem t) = find_least (deriv_ord ctxt (not pol) pred modes t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   449
          (filter (fn (d, missing_vars) => is_all_input (head_mode_of d))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   450
             (all_derivations_of ctxt neg_modes vs t))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   451
      | choose_mode_of_prem p = raise Fail ("choose_mode_of_prem: unexpected premise " ^ string_of_prem ctxt p)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   452
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   453
    if #reorder_premises mode_analysis_options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   454
      find_least (premise_ord ctxt pol pred modes) (ps ~~ map choose_mode_of_prem ps)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   455
    else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   456
      SOME (hd ps, choose_mode_of_prem (hd ps))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   457
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   458
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   459
fun check_mode_clause' (mode_analysis_options : mode_analysis_options) ctxt pred param_vs (modes :
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   460
  (string * ((bool * mode) * bool) list) list) ((pol, mode) : bool * mode) (ts, ps) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   461
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   462
    val vTs = distinct (op =) (fold Term.add_frees (map dest_indprem ps) (fold Term.add_frees ts []))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   463
    val modes' = modes @ (param_vs ~~ map (fn x => [((true, x), false), ((false, x), false)]) (ho_arg_modes_of mode))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   464
    fun retrieve_modes_of_pol pol = map (fn (s, ms) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   465
      (s, map_filter (fn ((p, m), r) => if p = pol then SOME m else NONE | _ => NONE) ms))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   466
    val (pos_modes', neg_modes') =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   467
      if #infer_pos_and_neg_modes mode_analysis_options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   468
        (retrieve_modes_of_pol pol modes', retrieve_modes_of_pol (not pol) modes')
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   469
      else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   470
        let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   471
          val modes = map (fn (s, ms) => (s, map (fn ((p, m), r) => m) ms)) modes'
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   472
        in (modes, modes) end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   473
    val (in_ts, out_ts) = split_mode mode ts
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   474
    val in_vs = union (op =) param_vs (maps (vars_of_destructable_term ctxt) in_ts)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   475
    val out_vs = terms_vs out_ts
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   476
    fun known_vs_after p vs = (case p of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   477
        Prem t => union (op =) vs (term_vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   478
      | Sidecond t => union (op =) vs (term_vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   479
      | Negprem t => union (op =) vs (term_vs t)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   480
      | _ => raise Fail "unexpected premise")
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   481
    fun check_mode_prems acc_ps rnd vs [] = SOME (acc_ps, vs, rnd)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   482
      | check_mode_prems acc_ps rnd vs ps =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   483
        (case
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   484
          (select_mode_prem mode_analysis_options ctxt pred pol (modes', (pos_modes', neg_modes')) vs ps) of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   485
          SOME (p, SOME (deriv, [])) => check_mode_prems ((p, deriv) :: acc_ps) rnd
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   486
            (known_vs_after p vs) (filter_out (equal p) ps)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   487
        | SOME (p, SOME (deriv, missing_vars)) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   488
          if #use_generators mode_analysis_options andalso pol then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   489
            check_mode_prems ((p, deriv) :: (map
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   490
              (fn v => (Generator (v, the (AList.lookup (op =) vTs v)), Term Output))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   491
                (distinct (op =) missing_vars))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   492
                @ acc_ps) true (known_vs_after p vs) (filter_out (equal p) ps)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   493
          else NONE
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   494
        | SOME (p, NONE) => NONE
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   495
        | NONE => NONE)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   496
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   497
    case check_mode_prems [] false in_vs ps of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   498
      NONE => NONE
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   499
    | SOME (acc_ps, vs, rnd) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   500
      if forall (is_constructable vs) (in_ts @ out_ts) then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   501
        SOME (ts, rev acc_ps, rnd)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   502
      else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   503
        if #use_generators mode_analysis_options andalso pol then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   504
          let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   505
             val generators = map
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   506
              (fn v => (Generator (v, the (AList.lookup (op =) vTs v)), Term Output))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   507
                (subtract (op =) vs (terms_vs (in_ts @ out_ts)))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   508
          in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   509
            SOME (ts, rev (generators @ acc_ps), true)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   510
          end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   511
        else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   512
          NONE
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   513
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   514
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   515
datatype result = Success of bool | Error of string
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   516
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   517
fun check_modes_pred' mode_analysis_options options thy param_vs clauses modes (p, (ms : ((bool * mode) * bool) list)) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   518
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   519
    fun split xs =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   520
      let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   521
        fun split' [] (ys, zs) = (rev ys, rev zs)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   522
          | split' ((m, Error z) :: xs) (ys, zs) = split' xs (ys, z :: zs)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   523
          | split' (((m : bool * mode), Success rnd) :: xs) (ys, zs) = split' xs ((m, rnd) :: ys, zs)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   524
       in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   525
         split' xs ([], [])
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   526
       end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   527
    val rs = these (AList.lookup (op =) clauses p)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   528
    fun check_mode m =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   529
      let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   530
        val res = Output.cond_timeit false "work part of check_mode for one mode" (fn _ => 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   531
          map (check_mode_clause' mode_analysis_options thy p param_vs modes m) rs)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   532
      in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   533
        Output.cond_timeit false "aux part of check_mode for one mode" (fn _ => 
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   534
        case find_indices is_none res of
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   535
          [] => Success (exists (fn SOME (_, _, true) => true | _ => false) res)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   536
        | is => (print_failed_mode options thy modes p m rs is; Error (error_of p m is)))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   537
      end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   538
    val _ = if show_mode_inference options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   539
        tracing ("checking " ^ string_of_int (length ms) ^ " modes ...")
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   540
      else ()
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   541
    val res = Output.cond_timeit false "check_mode" (fn _ => map (fn (m, _) => (m, check_mode m)) ms)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   542
    val (ms', errors) = split res
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   543
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   544
    ((p, (ms' : ((bool * mode) * bool) list)), errors)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   545
  end;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   546
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   547
fun get_modes_pred' mode_analysis_options thy param_vs clauses modes (p, ms) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   548
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   549
    val rs = these (AList.lookup (op =) clauses p)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   550
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   551
    (p, map (fn (m, rnd) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   552
      (m, map
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   553
        ((fn (ts, ps, rnd) => (ts, ps)) o the o
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   554
          check_mode_clause' mode_analysis_options thy p param_vs modes m) rs)) ms)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   555
  end;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   556
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   557
fun fixp f (x : (string * ((bool * mode) * bool) list) list) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   558
  let val y = f x
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   559
  in if x = y then x else fixp f y end;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   560
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   561
fun fixp_with_state f (x : (string * ((bool * mode) * bool) list) list, state) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   562
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   563
    val (y, state') = f (x, state)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   564
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   565
    if x = y then (y, state') else fixp_with_state f (y, state')
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   566
  end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   567
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   568
fun string_of_ext_mode ((pol, mode), rnd) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   569
  string_of_mode mode ^ "(" ^ (if pol then "pos" else "neg") ^ ", "
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   570
  ^ (if rnd then "rnd" else "nornd") ^ ")"
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   571
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   572
fun print_extra_modes options modes =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   573
  if show_mode_inference options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   574
    tracing ("Modes of inferred predicates: " ^
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   575
      cat_lines (map (fn (s, ms) => s ^ ": " ^ commas (map string_of_ext_mode ms)) modes))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   576
  else ()
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   577
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   578
fun infer_modes mode_analysis_options options (lookup_mode, lookup_neg_mode, needs_random) ctxt
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   579
  preds all_modes param_vs clauses =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   580
  let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   581
    fun appair f (x1, x2) (y1, y2) = (f x1 y1, f x2 y2)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   582
    fun add_needs_random s (false, m) = ((false, m), false)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   583
      | add_needs_random s (true, m) = ((true, m), needs_random s m)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   584
    fun add_polarity_and_random_bit s b ms = map (fn m => add_needs_random s (b, m)) ms
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   585
    val prednames = map fst preds
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   586
    (* extramodes contains all modes of all constants, should we only use the necessary ones
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   587
       - what is the impact on performance? *)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   588
    fun predname_of (Prem t) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   589
        (case try dest_Const (fst (strip_comb t)) of SOME (c, _) => insert (op =) c | NONE => I)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   590
      | predname_of (Negprem t) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   591
        (case try dest_Const (fst (strip_comb t)) of SOME (c, _) => insert (op =) c | NONE => I)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   592
      | predname_of _ = I
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   593
    val relevant_prednames = fold (fn (_, clauses') =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   594
      fold (fn (_, ps) => fold Term.add_const_names (map dest_indprem ps)) clauses') clauses []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   595
      |> filter_out (fn name => member (op =) prednames name)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   596
    val extra_modes =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   597
      if #infer_pos_and_neg_modes mode_analysis_options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   598
        let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   599
          val pos_extra_modes =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   600
            map_filter (fn name => Option.map (pair name) (try lookup_mode name))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   601
            relevant_prednames
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   602
          val neg_extra_modes =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   603
            map_filter (fn name => Option.map (pair name) (try lookup_neg_mode name))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   604
              relevant_prednames
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   605
        in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   606
          map (fn (s, ms) => (s, (add_polarity_and_random_bit s true ms)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   607
                @ add_polarity_and_random_bit s false (the (AList.lookup (op =) neg_extra_modes s))))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   608
            pos_extra_modes
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   609
        end
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   610
      else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   611
        map (fn (s, ms) => (s, (add_polarity_and_random_bit s true ms)))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   612
          (map_filter (fn name => Option.map (pair name) (try lookup_mode name))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   613
            relevant_prednames)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   614
    val _ = print_extra_modes options extra_modes
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   615
    val start_modes =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   616
      if #infer_pos_and_neg_modes mode_analysis_options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   617
        map (fn (s, ms) => (s, map (fn m => ((true, m), false)) ms @
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   618
          (map (fn m => ((false, m), false)) ms))) all_modes
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   619
      else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   620
        map (fn (s, ms) => (s, map (fn m => ((true, m), false)) ms)) all_modes
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   621
    fun iteration modes = map
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   622
      (check_modes_pred' mode_analysis_options options ctxt param_vs clauses
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   623
        (modes @ extra_modes)) modes
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   624
    val ((modes : (string * ((bool * mode) * bool) list) list), errors) =
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   625
      Output.cond_timeit false "Fixpount computation of mode analysis" (fn () =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   626
      if show_invalid_clauses options then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   627
        fixp_with_state (fn (modes, errors) =>
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   628
          let
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   629
            val (modes', new_errors) = split_list (iteration modes)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   630
          in (modes', errors @ flat new_errors) end) (start_modes, [])
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   631
        else
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   632
          (fixp (fn modes => map fst (iteration modes)) start_modes, []))
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   633
    val moded_clauses = map (get_modes_pred' mode_analysis_options ctxt param_vs clauses
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   634
      (modes @ extra_modes)) modes
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   635
    val need_random = fold (fn (s, ms) => if member (op =) (map fst preds) s then
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   636
      cons (s, (map_filter (fn ((true, m), true) => SOME m | _ => NONE) ms)) else I)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   637
      modes []
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   638
  in
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   639
    ((moded_clauses, need_random), errors)
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   640
  end;
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   641
ea46574ca815 splitting large core file into core_data, mode_inference and predicate_compile_proof
bulwahn
parents:
diff changeset
   642
end;