src/Tools/isac/BaseDefinitions/model-pattern.sml
author wneuper <Walther.Neuper@jku.at>
Fri, 31 Mar 2023 12:07:52 +0200
changeset 60705 b719a0b7c6b5
parent 60701 2a6671d7c214
child 60710 21ae85b023bb
permissions -rw-r--r--
//new Pre_Conds.check/_TEST breaks tests, need new signature
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@60624
    15
Walther@60624
    16
  type model_input_pos
Walther@60698
    17
  type empty_input
Walther@60602
    18
  type pre_model
Walther@60701
    19
  type pre_model'
Walther@60603
    20
walther@59952
    21
  type m_field = string
walther@59952
    22
  type descriptor = term
Walther@60624
    23
  val parse_pos: Proof.context -> (m_field * (string * Position.T) list) list ->
Walther@60624
    24
    pre_model * (term * Position.T) list
Walther@60701
    25
  val parse_pos_empty: Proof.context -> (m_field * (string * Position.T) list) list ->
Walther@60701
    26
    pre_model' * (term * Position.T) list
walther@60004
    27
walther@59987
    28
  val variables: T -> term list
walther@60004
    29
  val get_field: descriptor -> T -> m_field option
Walther@60697
    30
  datatype for = Problem | Method | Undef
Walther@60556
    31
Walther@60556
    32
  val adapt_to_type: Proof.context -> single -> single
Walther@60698
    33
(*from isac_test for Minisubpbl*)
Walther@60698
    34
  val split_descriptor: Proof.context -> m_field * term * Position.T ->
Walther@60698
    35
    (m_field * (descriptor * term) * Position.T)
Walther@60701
    36
  datatype pre_model_single' =
Walther@60698
    37
      Empty of (m_field * (descriptor * empty_input) * Position.T)
Walther@60698
    38
    | Proper of (m_field * (descriptor * term) * Position.T)
Walther@60698
    39
  val parse_pattern: Proof.context -> 'a * (string * Position.T) -> 'a * term * Position.T
Walther@60698
    40
  val empty_for: typ -> string
Walther@60698
    41
  val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
Walther@60698
    42
    m_field * term * Position.T
Walther@60701
    43
  val parse_empty_input: Proof.context -> m_field * (string * Position.T) -> pre_model_single'
Walther@60700
    44
  val is_undefined: term -> bool
Walther@60556
    45
wenzelm@60223
    46
\<^isac_test>\<open>
Walther@60698
    47
  (**)
wenzelm@60223
    48
\<close>
walther@59882
    49
end
walther@59882
    50
walther@59882
    51
(**)
walther@59945
    52
structure Model_Pattern(**): MODEL_PATTERN(**) =
walther@59882
    53
struct
walther@59882
    54
(**)
walther@59882
    55
walther@59884
    56
(* the pattern for an item of a problems model or a methods guard *)
walther@59945
    57
type m_field = string;
walther@59952
    58
type descriptor = term;
walther@59945
    59
type single =
walther@59952
    60
  (m_field *      (* field Given, Find, Relate *)
walther@59952
    61
	  (descriptor * (* for snd term              *)
walther@59952
    62
	     term))     (* id | arbitrary term       *);
Walther@60602
    63
(* does NOT contain pre-conditions, because these have no \<open>descriptor\<close> *)
walther@59945
    64
type T = single list;
walther@59945
    65
Walther@60698
    66
type model_input_pos =                       (* for internal use                       *)
Walther@60698
    67
  (m_field *                                 (* "#Given", "#Find", "#Where", "#Relate" *)
Walther@60688
    68
    ((*TermC.as_*)string * Position.T) list) (* list of items belonging to m_field     *)
Walther@60698
    69
  list;                                      (* list of "#Given" .. "#Relate"          *)
Walther@60698
    70
type empty_input = string
Walther@60705
    71
  (* compare Pre_Conds.mk_eval_env *)
Walther@60701
    72
fun empty_for (Type ("fun", [Type ("List.list", [Type ("HOL.bool", [])]), _])) = "[__=__, __=__]"
Walther@60701
    73
  | empty_for (Type ("fun", [Type ("List.list", [Type ("Real.real", [])]), _])) = "[__, __]"
Walther@60701
    74
  | empty_for (Type ("HOL.bool", [])) = "(__=__)"
Walther@60701
    75
  | empty_for _ = "__"
Walther@60624
    76
type pre_model_single = (m_field * (descriptor * term) * Position.T)
Walther@60701
    77
datatype pre_model_single' =
Walther@60698
    78
    Empty of (m_field * (descriptor * empty_input) * Position.T)
Walther@60698
    79
  | Proper of (m_field * (descriptor * term) * Position.T)
Walther@60698
    80
type pre_model = pre_model_single list
Walther@60701
    81
type pre_model' = pre_model_single' list
Walther@60602
    82
Walther@60624
    83
(*val split_descriptor: Proof.context -> m_field * term * Position.T ->
Walther@60624
    84
    m_field * (descriptor * term)(* * Position.T*)*)
Walther@60624
    85
fun split_descriptor ctxt (m_field: string, dsc_tm, pos) = 
Walther@60602
    86
  let
Walther@60624
    87
    val (m_field, (hd, arg)) = case strip_comb dsc_tm of
Walther@60602
    88
      (hd, [arg]) => (m_field, (hd, arg))
Walther@60675
    89
    | _ => error ("Wrong descriptor " ^ quote (UnparseC.term ctxt dsc_tm) ^ Position.here pos)
Walther@60624
    90
  in (m_field, (hd, arg), pos) end
Walther@60583
    91
Walther@60604
    92
(*val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) -> m_field * term*)
Walther@60604
    93
fun parse_term ctxt (m_field, (str, pos)) =
Walther@60660
    94
  (m_field, ParseC.term_position ctxt (str, pos), pos)
Walther@60701
    95
Walther@60701
    96
fun is_undefined tm =
Walther@60701
    97
  if Term.exists_subterm (fn Const ("HOL.undefined", _) => true | _ => false) tm then true else false
Walther@60701
    98
fun parse_empty_input ctxt (m_field, (str, pos)) =
Walther@60698
    99
  let
Walther@60699
   100
    val (m_field, term, pos) = parse_term ctxt (m_field, (str, pos))
Walther@60699
   101
    val (m_field, (descr, arg), pos) = split_descriptor ctxt (m_field, term, pos)
Walther@60698
   102
  in
Walther@60699
   103
    if is_undefined arg
Walther@60699
   104
    then Empty (m_field, (descr, descr |> type_of |> empty_for), pos)
Walther@60699
   105
    else Proper (m_field, (descr, arg), pos)
Walther@60698
   106
  end 
Walther@60698
   107
Walther@60604
   108
fun parse_pattern ctxt (m_field, (str, pos)) =
Walther@60660
   109
  (m_field, ParseC.pattern_position ctxt (str, pos), pos)
Walther@60624
   110
Walther@60624
   111
fun parse_pos ctxt model_input =
Walther@60602
   112
  let
Walther@60602
   113
    val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
Walther@60602
   114
    val model = items 
Walther@60602
   115
      |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60604
   116
      |> map (parse_term ctxt)
Walther@60624
   117
      |> map (split_descriptor ctxt)
Walther@60602
   118
    val where_ = items 
Walther@60603
   119
      |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60604
   120
      |> map (parse_pattern ctxt)
Walther@60624
   121
      |> map (fn (_, a, b) => (a, b))
Walther@60602
   122
  in (model, where_) end
Walther@60701
   123
fun parse_pos_empty ctxt model_input =
Walther@60698
   124
  let
Walther@60698
   125
    val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
Walther@60698
   126
    val model = items 
Walther@60699
   127
      |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
Walther@60701
   128
      |> map (parse_empty_input ctxt)
Walther@60698
   129
    val where_ = items 
Walther@60698
   130
      |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60698
   131
      |> map (parse_pattern ctxt)
Walther@60698
   132
      |> map (fn (_, a, b) => (a, b))
Walther@60698
   133
  in (model, where_) end
Walther@60583
   134
Walther@60655
   135
fun pat2str ctxt (field, (dsc, id)) =
Walther@60675
   136
  pair2str (field, pair2str (UnparseC.term ctxt dsc, UnparseC.term ctxt id));
Walther@60655
   137
fun to_string ctxt pats = (strs2str o (map (pat2str ctxt))) pats;
Walther@60654
   138
wenzelm@60223
   139
\<^isac_test>\<open>
Walther@60655
   140
(**)
wenzelm@60223
   141
\<close>
walther@59882
   142
walther@59987
   143
(* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
walther@59987
   144
fun variables pbl_ = 
walther@59987
   145
  let
walther@59987
   146
    fun var_of_pbl_ (_, (_, t)) = t: term
walther@59987
   147
  in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end
walther@59987
   148
walther@60004
   149
fun get_field descriptor m_patt = 
walther@60004
   150
  (filter ((curry (fn (desc, (_, (desc', _))) => desc = desc')) descriptor) m_patt
walther@60004
   151
    |> the_single
walther@60004
   152
    |> (fn (a, _) => SOME a))
walther@60004
   153
  handle List.Empty => NONE
Walther@60697
   154
  datatype for = Problem | Method | Undef
Walther@60697
   155
walther@60004
   156
Walther@60660
   157
(* adapt type of terms with most general type to a more specific one *)
Walther@60556
   158
fun adapt_to_type ctxt (field, (descr, term_as_string)) =
Walther@60660
   159
  (field, (ParseC.adapt_term_to_type ctxt descr, ParseC.adapt_term_to_type ctxt term_as_string))
Walther@60603
   160
Walther@60603
   161
(**)end(*struct*)