src/Tools/isac/BaseDefinitions/model-pattern.sml
author wneuper <Walther.Neuper@jku.at>
Thu, 26 Jan 2023 18:54:25 +0100
changeset 60655 f73460617c3d
parent 60654 c2db35151fba
child 60660 c4b24621077e
permissions -rw-r--r--
use exclusively some new *.to_string ctxt
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@60602
    17
  type pre_model
Walther@60624
    18
  type pre_model_single
Walther@60603
    19
walther@59952
    20
  type m_field = string
walther@59952
    21
  type descriptor = term
Walther@60624
    22
  val parse_pos: Proof.context -> (m_field * (string * Position.T) list) list ->
Walther@60624
    23
    pre_model * (term * Position.T) list
walther@60004
    24
walther@59987
    25
  val variables: T -> term list
walther@60004
    26
  val get_field: descriptor -> T -> m_field option
Walther@60556
    27
Walther@60556
    28
  val adapt_to_type: Proof.context -> single -> single
Walther@60556
    29
  val adapt_term_to_type: Proof.context -> term -> term
Walther@60556
    30
  val adapt_to_type_real: term -> term
Walther@60556
    31
  val adapt_to_type_int: term -> term
Walther@60556
    32
wenzelm@60223
    33
\<^isac_test>\<open>
Walther@60624
    34
  val split_descriptor: Proof.context -> m_field * term * Position.T -> pre_model_single
Walther@60624
    35
  val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
Walther@60624
    36
    m_field * term * Position.T
Walther@60624
    37
  val parse_pattern: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
Walther@60624
    38
    m_field * term * Position.T
wenzelm@60223
    39
\<close>
walther@59882
    40
end
walther@59882
    41
walther@59882
    42
(**)
walther@59945
    43
structure Model_Pattern(**): MODEL_PATTERN(**) =
walther@59882
    44
struct
walther@59882
    45
(**)
walther@59882
    46
walther@59884
    47
(* the pattern for an item of a problems model or a methods guard *)
walther@59945
    48
type m_field = string;
walther@59952
    49
type descriptor = term;
walther@59945
    50
type single =
walther@59952
    51
  (m_field *      (* field Given, Find, Relate *)
walther@59952
    52
	  (descriptor * (* for snd term              *)
walther@59952
    53
	     term))     (* id | arbitrary term       *);
Walther@60602
    54
(* does NOT contain pre-conditions, because these have no \<open>descriptor\<close> *)
walther@59945
    55
type T = single list;
walther@59945
    56
Walther@60602
    57
type model_input_pos = (string * (string * Position.T) list) list
Walther@60624
    58
type pre_model_single = (m_field * (descriptor * term) * Position.T)
Walther@60624
    59
type pre_model = (m_field * (term * term) * Position.T) list
Walther@60602
    60
Walther@60624
    61
(*val split_descriptor: Proof.context -> m_field * term * Position.T ->
Walther@60624
    62
    m_field * (descriptor * term)(* * Position.T*)*)
Walther@60624
    63
fun split_descriptor ctxt (m_field: string, dsc_tm, pos) = 
Walther@60602
    64
  let
Walther@60624
    65
    val (m_field, (hd, arg)) = case strip_comb dsc_tm of
Walther@60602
    66
      (hd, [arg]) => (m_field, (hd, arg))
Walther@60624
    67
    | _ => error ("Wrong descriptor " ^ quote (UnparseC.term_in_ctxt ctxt dsc_tm) ^ Position.here pos)
Walther@60624
    68
  in (m_field, (hd, arg), pos) end
Walther@60583
    69
Walther@60603
    70
Walther@60604
    71
(*val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) -> m_field * term*)
Walther@60604
    72
fun parse_term ctxt (m_field, (str, pos)) =
Walther@60603
    73
  (m_field,
Walther@60603
    74
    (Syntax.read_term ctxt str
Walther@60624
    75
      handle ERROR msg => error (msg ^ Position.here pos)),
Walther@60624
    76
    pos)
Walther@60604
    77
fun parse_pattern ctxt (m_field, (str, pos)) =
Walther@60603
    78
  (m_field,
Walther@60603
    79
    (Proof_Context.read_term_pattern ctxt str
Walther@60624
    80
      handle ERROR msg => error (msg ^ Position.here pos)),
Walther@60624
    81
    pos)
Walther@60624
    82
Walther@60624
    83
fun parse_pos ctxt model_input =
Walther@60602
    84
  let
Walther@60602
    85
    val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
Walther@60602
    86
    val model = items 
Walther@60602
    87
      |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60604
    88
      |> map (parse_term ctxt)
Walther@60624
    89
      |> map (split_descriptor ctxt)
Walther@60602
    90
    val where_ = items 
Walther@60603
    91
      |> filter ((fn f => (fn (f', _) => f = f')) "#Where") 
Walther@60604
    92
      |> map (parse_pattern ctxt)
Walther@60624
    93
      |> map (fn (_, a, b) => (a, b))
Walther@60602
    94
  in (model, where_) end
Walther@60583
    95
Walther@60655
    96
fun pat2str ctxt (field, (dsc, id)) =
Walther@60654
    97
  pair2str (field, pair2str (UnparseC.term_in_ctxt ctxt dsc, UnparseC.term_in_ctxt ctxt id));
Walther@60655
    98
fun to_string ctxt pats = (strs2str o (map (pat2str ctxt))) pats;
Walther@60654
    99
wenzelm@60223
   100
\<^isac_test>\<open>
Walther@60655
   101
(**)
wenzelm@60223
   102
\<close>
walther@59882
   103
walther@59987
   104
(* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
walther@59987
   105
fun variables pbl_ = 
walther@59987
   106
  let
walther@59987
   107
    fun var_of_pbl_ (_, (_, t)) = t: term
walther@59987
   108
  in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end
walther@59987
   109
walther@60004
   110
fun get_field descriptor m_patt = 
walther@60004
   111
  (filter ((curry (fn (desc, (_, (desc', _))) => desc = desc')) descriptor) m_patt
walther@60004
   112
    |> the_single
walther@60004
   113
    |> (fn (a, _) => SOME a))
walther@60004
   114
  handle List.Empty => NONE
walther@60004
   115
Walther@60556
   116
(* 
Walther@60556
   117
  adapt type of terms with most general type to a more specific one.
Walther@60556
   118
  TODO: clarify how to decide by use of data from the current context.
Walther@60556
   119
*)
Walther@60556
   120
fun T_a2real (Type (s, [])) = 
Walther@60556
   121
    if s = "'a" orelse s = "'b" orelse s = "'c" then HOLogic.realT else Type (s, [])
Walther@60556
   122
  | T_a2real (Type (s, Ts)) = Type (s, map T_a2real Ts)
Walther@60556
   123
  | T_a2real (TFree (s, srt)) = 
Walther@60556
   124
    if s = "'a" orelse s = "'b" orelse s = "'c" then HOLogic.realT else TFree (s, srt)
Walther@60556
   125
  | T_a2real (TVar (("DUMMY", _), _)) = HOLogic.realT
Walther@60556
   126
  | T_a2real (TVar ((s, i), srt)) = 
Walther@60556
   127
    if s = "'a" orelse s = "'b" orelse s = "'c" then HOLogic.realT else TVar ((s, i), srt)
Walther@60556
   128
(*val adapt_to_type_real: term -> term*)
Walther@60556
   129
fun adapt_to_type_real (Const( s, T)) = (Const( s, T_a2real T)) 
Walther@60556
   130
  | adapt_to_type_real (Free( s, T)) = (Free( s, T_a2real T))
Walther@60556
   131
  | adapt_to_type_real (Var( n, T)) = (Var( n, T_a2real T))
Walther@60556
   132
  | adapt_to_type_real (Bound i) = (Bound i)
Walther@60556
   133
  | adapt_to_type_real (Abs(s,T,t)) = Abs(s, T, adapt_to_type_real t)
Walther@60556
   134
  | adapt_to_type_real (t1 $ t2) = (adapt_to_type_real t1) $ (adapt_to_type_real t2);
Walther@60556
   135
(*val adapt_to_type_int: term -> term*)
Walther@60556
   136
fun adapt_to_type_int _ = raise ERROR "Model_Pattern.adapt_to_type NOT implemented for HOLogic.intT"
Walther@60556
   137
Walther@60556
   138
fun adapt_term_to_type ctxt t =
Walther@60556
   139
  let
Walther@60556
   140
    val choice = ctxt |> K HOLogic.realT (*clarify how ctxt can be used here*)
Walther@60556
   141
  in
Walther@60556
   142
    if choice = HOLogic.realT then adapt_to_type_real t
Walther@60556
   143
    else if choice = HOLogic.intT then adapt_to_type_int t
Walther@60556
   144
    else raise ERROR "TermC.adapt_to_type only implemented for HOLogic.realT"
Walther@60556
   145
  end
Walther@60556
   146
fun adapt_to_type ctxt (field, (descr, term_as_string)) =
Walther@60556
   147
  (field, (adapt_term_to_type ctxt descr, adapt_term_to_type ctxt term_as_string))
Walther@60603
   148
Walther@60603
   149
(**)end(*struct*)