src/Tools/isac/BaseDefinitions/model-pattern.sml
author wneuper <Walther.Neuper@jku.at>
Sat, 15 Jul 2023 17:44:37 +0200
changeset 60722 14ff64a7e3bd
parent 60721 1170b3685197
child 60763 2121f1a39a64
permissions -rw-r--r--
prepare 7: extend I_Model.of_max_variant with make_envs_preconds
walther@59945
     1
(* Title:  BaseDefinitions/model-pattern.sml
walther@59882
     2
   Author: Walther Neuper
walther@59882
     3
   (c) due to copyright terms
walther@59882
     4
walther@60004
     5
A \<open>Model_Pattern\<close> defines a -> \<open>Problem\<close>-type: its \<open>variables\<close> are to be instantiated
Walther@60654
     6
by the values for particular \<open>Problem\<close>s in a \<open>Formalise.model\<close>.
walther@60004
     7
The \<open>variables\<close> are used twice, in a model and as formal arguments in a \<open>Program\<close>.
walther@60004
     8
The \<open>descriptor\<close>s are unique identifiers within one \<open>Model_Pattern\<close>.
walther@59945
     9
*)
walther@59945
    10
signature MODEL_PATTERN =
walther@59882
    11
sig
walther@59945
    12
  type T
walther@59945
    13
  type single
Walther@60655
    14
  val to_string: Proof.context -> single list -> string
Walther@60710
    15
  val pat2str: Proof.context -> single -> string
Walther@60624
    16
Walther@60624
    17
  type model_input_pos
Walther@60698
    18
  type empty_input
Walther@60602
    19
  type pre_model
Walther@60701
    20
  type pre_model'
Walther@60603
    21
walther@59952
    22
  type m_field = string
walther@59952
    23
  type descriptor = term
Walther@60624
    24
  val parse_pos: Proof.context -> (m_field * (string * Position.T) list) list ->
Walther@60624
    25
    pre_model * (term * Position.T) list
Walther@60701
    26
  val parse_pos_empty: Proof.context -> (m_field * (string * Position.T) list) list ->
Walther@60701
    27
    pre_model' * (term * Position.T) list
walther@60004
    28
walther@59987
    29
  val variables: T -> term list
walther@60004
    30
  val get_field: descriptor -> T -> m_field option
Walther@60697
    31
  datatype for = Problem | Method | Undef
Walther@60556
    32
Walther@60556
    33
  val adapt_to_type: Proof.context -> single -> single
Walther@60698
    34
(*from isac_test for Minisubpbl*)
Walther@60698
    35
  val split_descriptor: Proof.context -> m_field * term * Position.T ->
Walther@60698
    36
    (m_field * (descriptor * term) * Position.T)
Walther@60701
    37
  datatype pre_model_single' =
Walther@60698
    38
      Empty of (m_field * (descriptor * empty_input) * Position.T)
Walther@60698
    39
    | Proper of (m_field * (descriptor * term) * Position.T)
Walther@60698
    40
  val parse_pattern: Proof.context -> 'a * (string * Position.T) -> 'a * term * Position.T
Walther@60718
    41
Walther@60721
    42
  val typ_of_element: descriptor -> typ
Walther@60719
    43
  val is_list_descr: descriptor -> bool
Walther@60718
    44
  val empty_for: descriptor -> empty_input
Walther@60698
    45
  val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
Walther@60698
    46
    m_field * term * Position.T
Walther@60701
    47
  val parse_empty_input: Proof.context -> m_field * (string * Position.T) -> pre_model_single'
Walther@60700
    48
  val is_undefined: term -> bool
Walther@60556
    49
wenzelm@60223
    50
\<^isac_test>\<open>
Walther@60698
    51
  (**)
wenzelm@60223
    52
\<close>
walther@59882
    53
end
walther@59882
    54
walther@59882
    55
(**)
walther@59945
    56
structure Model_Pattern(**): MODEL_PATTERN(**) =
walther@59882
    57
struct
walther@59882
    58
(**)
walther@59882
    59
walther@59884
    60
(* the pattern for an item of a problems model or a methods guard *)
walther@59945
    61
type m_field = string;
walther@59952
    62
type descriptor = term;
walther@59945
    63
type single =
Walther@60722
    64
  (m_field *      (* field Given, Find, Relate / Where in Pre_Conds *)
Walther@60722
    65
	  (descriptor * (* for term                                       *)
Walther@60722
    66
	     term))     (* internal identifier for substitution           *)
Walther@60722
    67
(* does NOT contain Pre_Conds, because these have no \<open>descriptor\<close>   *)
walther@59945
    68
type T = single list;
walther@59945
    69
Walther@60698
    70
type model_input_pos =                       (* for internal use                       *)
Walther@60698
    71
  (m_field *                                 (* "#Given", "#Find", "#Where", "#Relate" *)
Walther@60688
    72
    ((*TermC.as_*)string * Position.T) list) (* list of items belonging to m_field     *)
Walther@60698
    73
  list;                                      (* list of "#Given" .. "#Relate"          *)
Walther@60698
    74
type empty_input = string
Walther@60720
    75
datatype descr_type = List of typ | Single of typ
Walther@60718
    76
fun descr_type (Type ("fun", [Type ("List.list", [typ]), _])) = List typ
Walther@60720
    77
  | descr_type (Type ("fun", [typ, _])) = Single typ
Walther@60720
    78
  | descr_type typ = raise TYPE ("Model_Pattern.descr_type", [typ], [])
Walther@60721
    79
fun typ_of_element descr =
Walther@60721
    80
  case descr_type (type_of descr) of
Walther@60721
    81
    List typ => typ
Walther@60721
    82
  | Single typ => typ
Walther@60718
    83
fun is_list_descr descr =
Walther@60718
    84
  case descr_type (type_of descr) of List _ => true | _ => false
Walther@60717
    85
fun empty_for descr =
Walther@60717
    86
  case descr_type (type_of descr) of
Walther@60718
    87
    List typ => if typ = HOLogic.boolT then "[__=__, __=__]" else "[__, __]"
Walther@60720
    88
  | Single typ => if typ = HOLogic.boolT then "(__=__)" else "__"
Walther@60718
    89
Walther@60624
    90
type pre_model_single = (m_field * (descriptor * term) * Position.T)
Walther@60701
    91
datatype pre_model_single' =
Walther@60698
    92
    Empty of (m_field * (descriptor * empty_input) * Position.T)
Walther@60698
    93
  | Proper of (m_field * (descriptor * term) * Position.T)
Walther@60698
    94
type pre_model = pre_model_single list
Walther@60701
    95
type pre_model' = pre_model_single' list
Walther@60602
    96
Walther@60624
    97
(*val split_descriptor: Proof.context -> m_field * term * Position.T ->
Walther@60624
    98
    m_field * (descriptor * term)(* * Position.T*)*)
Walther@60624
    99
fun split_descriptor ctxt (m_field: string, dsc_tm, pos) = 
Walther@60602
   100
  let
Walther@60624
   101
    val (m_field, (hd, arg)) = case strip_comb dsc_tm of
Walther@60602
   102
      (hd, [arg]) => (m_field, (hd, arg))
Walther@60675
   103
    | _ => error ("Wrong descriptor " ^ quote (UnparseC.term ctxt dsc_tm) ^ Position.here pos)
Walther@60624
   104
  in (m_field, (hd, arg), pos) end
Walther@60583
   105
Walther@60604
   106
(*val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) -> m_field * term*)
Walther@60604
   107
fun parse_term ctxt (m_field, (str, pos)) =
Walther@60660
   108
  (m_field, ParseC.term_position ctxt (str, pos), pos)
Walther@60701
   109
Walther@60701
   110
fun is_undefined tm =
Walther@60701
   111
  if Term.exists_subterm (fn Const ("HOL.undefined", _) => true | _ => false) tm then true else false
Walther@60701
   112
fun parse_empty_input ctxt (m_field, (str, pos)) =
Walther@60698
   113
  let
Walther@60699
   114
    val (m_field, term, pos) = parse_term ctxt (m_field, (str, pos))
Walther@60699
   115
    val (m_field, (descr, arg), pos) = split_descriptor ctxt (m_field, term, pos)
Walther@60698
   116
  in
Walther@60699
   117
    if is_undefined arg
Walther@60717
   118
    then Empty (m_field, (descr, descr |> empty_for), pos)
Walther@60699
   119
    else Proper (m_field, (descr, arg), pos)
Walther@60698
   120
  end 
Walther@60698
   121
Walther@60604
   122
fun parse_pattern ctxt (m_field, (str, pos)) =
Walther@60660
   123
  (m_field, ParseC.pattern_position ctxt (str, pos), pos)
Walther@60624
   124
Walther@60624
   125
fun parse_pos ctxt model_input =
Walther@60602
   126
  let
Walther@60602
   127
    val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
Walther@60602
   128
    val model = items 
Walther@60602
   129
      |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60604
   130
      |> map (parse_term ctxt)
Walther@60624
   131
      |> map (split_descriptor ctxt)
Walther@60602
   132
    val where_ = items 
Walther@60603
   133
      |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60604
   134
      |> map (parse_pattern ctxt)
Walther@60624
   135
      |> map (fn (_, a, b) => (a, b))
Walther@60602
   136
  in (model, where_) end
Walther@60701
   137
fun parse_pos_empty ctxt model_input =
Walther@60698
   138
  let
Walther@60698
   139
    val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
Walther@60698
   140
    val model = items 
Walther@60699
   141
      |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
Walther@60701
   142
      |> map (parse_empty_input ctxt)
Walther@60698
   143
    val where_ = items 
Walther@60698
   144
      |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60698
   145
      |> map (parse_pattern ctxt)
Walther@60698
   146
      |> map (fn (_, a, b) => (a, b))
Walther@60698
   147
  in (model, where_) end
Walther@60583
   148
Walther@60655
   149
fun pat2str ctxt (field, (dsc, id)) =
Walther@60675
   150
  pair2str (field, pair2str (UnparseC.term ctxt dsc, UnparseC.term ctxt id));
Walther@60655
   151
fun to_string ctxt pats = (strs2str o (map (pat2str ctxt))) pats;
Walther@60654
   152
wenzelm@60223
   153
\<^isac_test>\<open>
Walther@60655
   154
(**)
wenzelm@60223
   155
\<close>
walther@59882
   156
walther@59987
   157
(* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
walther@59987
   158
fun variables pbl_ = 
walther@59987
   159
  let
walther@59987
   160
    fun var_of_pbl_ (_, (_, t)) = t: term
walther@59987
   161
  in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end
walther@59987
   162
walther@60004
   163
fun get_field descriptor m_patt = 
walther@60004
   164
  (filter ((curry (fn (desc, (_, (desc', _))) => desc = desc')) descriptor) m_patt
walther@60004
   165
    |> the_single
walther@60004
   166
    |> (fn (a, _) => SOME a))
walther@60004
   167
  handle List.Empty => NONE
Walther@60697
   168
  datatype for = Problem | Method | Undef
Walther@60697
   169
walther@60004
   170
Walther@60660
   171
(* adapt type of terms with most general type to a more specific one *)
Walther@60556
   172
fun adapt_to_type ctxt (field, (descr, term_as_string)) =
Walther@60660
   173
  (field, (ParseC.adapt_term_to_type ctxt descr, ParseC.adapt_term_to_type ctxt term_as_string))
Walther@60603
   174
Walther@60603
   175
(**)end(*struct*)