src/Tools/isac/Specify/o-model.sml
author Walther Neuper <walther.neuper@jku.at>
Wed, 20 May 2020 12:52:09 +0200
changeset 59997 46fe5a8c3911
parent 59996 7e314dd233fd
child 59998 5dd825c9e2d5
permissions -rw-r--r--
standard format for string lists
walther@59938
     1
(* Title:  Specify/o-model.sml
walther@59938
     2
   Author: Walther Neuper 110226
walther@59938
     3
   (c) due to copyright terms
walther@59953
     4
walther@59984
     5
An original model is created initially from Formalise.T and Model_Pattern.T;
walther@59953
     6
This model makes student's editing via I_Model.T more efficient.
walther@59953
     7
TODO: revise with an example with more than 1 variant.
walther@59953
     8
*)
walther@59938
     9
walther@59938
    10
signature ORIGINAL_MODEL =
walther@59938
    11
sig
walther@59961
    12
  type T
walther@59961
    13
  type single
walther@59961
    14
  type variants
walther@59961
    15
  type m_field
walther@59961
    16
  type descriptor
walther@59940
    17
  val to_string: T -> string
walther@59957
    18
  val single_to_string: single -> string
walther@59940
    19
  val single_empty: single
walther@59939
    20
walther@59952
    21
  val init: Formalise.model -> theory -> Model_Pattern.T -> T
walther@59960
    22
  val add : theory -> Model_Pattern.T -> T -> T
walther@59969
    23
  val values : T -> term list
walther@59987
    24
  val values': T -> Formalise.model * term list
walther@59969
    25
walther@59987
    26
(*/------- rename -------\*)
walther@59969
    27
(*put add_id into a new auxiliary fun..*)
walther@59961
    28
  val add_id: 'a list -> (int * 'a) list
walther@59961
    29
  type preori
walther@59961
    30
(* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
walther@59986
    31
  val cpy_nam: Model_Pattern.T -> preori list -> Model_Pattern.single -> preori
walther@59986
    32
  val is_copy_named: Model_Pattern.single -> bool
walther@59986
    33
  val is_copy_named_idstr: string -> bool
walther@59986
    34
  val is_copy_named_generating_idstr: string -> bool
walther@59986
    35
  val is_copy_named_generating: Model_Pattern.single -> bool
walther@59986
    36
walther@59961
    37
  val preoris2str : preori list -> string
walther@59992
    38
  val getr_ct: theory -> single -> m_field * UnparseC.term_as_string
walther@59992
    39
walther@59961
    40
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
walther@59952
    41
  val add_field: theory -> Model_Pattern.T -> term * 'b -> m_field * descriptor * 'b
walther@59952
    42
  val add_variants: ('a * ''b * 'c) list -> (int * ('a * ''b * 'c)) list
walther@59952
    43
  val max: variants -> int
walther@59947
    44
  val coll_variants: ('a * ''b) list -> ('a list * ''b) list
walther@59947
    45
  val replace_0: int -> int list -> int list
walther@59947
    46
  val flattup: 'a * ('b * ('c * 'd * 'e)) -> 'a * 'b * 'c * 'd * 'e
walther@59996
    47
 val mark: ('a * 'a -> bool) -> 'a list -> (int * 'a) list
walther@59987
    48
(*\------- rename -------/*)
walther@59938
    49
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
walther@59938
    50
end
walther@59938
    51
walther@59974
    52
(**)
walther@59938
    53
structure O_Model(**) : ORIGINAL_MODEL(**) =
walther@59938
    54
struct
walther@59974
    55
(**)
walther@59938
    56
walther@59960
    57
(** types **)
walther@59960
    58
walther@59940
    59
type variants =  Model_Def.variants;
walther@59952
    60
type m_field = Model_Def.m_field;
walther@59952
    61
type descriptor = Model_Def.descriptor;
walther@59938
    62
walther@59940
    63
type T = Model_Def.o_model;
walther@59940
    64
type single = Model_Def.o_model_single
walther@59940
    65
val single_empty = Model_Def.o_model_empty;
walther@59957
    66
val single_to_string = Model_Def.o_model_single_to_string;
walther@59940
    67
val to_string = Model_Def.o_model_to_string;
walther@59940
    68
walther@59952
    69
(* O_Model.single without leading integer *)
walther@59952
    70
type preori = (variants * m_field * term * term list);
walther@59942
    71
fun preori2str (vs, fi, t, ts) = 
walther@59942
    72
  "(" ^ (strs2str o (map string_of_int)) vs ^ ", " ^ fi ^ ", " ^
walther@59942
    73
  UnparseC.term t ^ ", " ^ (strs2str o (map UnparseC.term)) ts ^ ")";
walther@59942
    74
val preoris2str = (strs2str' o (map (linefeed o preori2str)));
walther@59942
    75
walther@59992
    76
(* get the first term in ts from ori *)
walther@59992
    77
fun getr_ct thy (_, _, fd, d, ts) =
walther@59992
    78
  (fd, ((UnparseC.term_in_thy thy) o Input_Descript.join) (d,[hd ts]))
walther@59992
    79
walther@59960
    80
walther@59960
    81
(** initialise O_Model **)
walther@59960
    82
walther@59947
    83
(* compare d and dsc in pbt and transfer field to pre-ori *)
walther@59947
    84
fun add_field (_: theory) pbt (d,ts) = 
walther@59947
    85
  let fun eq d pt = (d = (fst o snd) pt);
walther@59947
    86
  in case filter (eq d) pbt of
walther@59947
    87
       [(fi, (_, _))] => (fi, d, ts)
walther@59947
    88
     | [] => ("#undef", d, ts)   (*may come with met.ppc*)
walther@59952
    89
     | _ => raise ERROR ("add_field: " ^ UnparseC.term d ^ " more than once in pbt")
walther@59947
    90
  end;
walther@59947
    91
walther@59952
    92
(*
walther@59952
    93
  mark an element with the position within a plateau;
walther@59952
    94
  a plateau with length 1 is marked with 0
walther@59952
    95
*)
walther@59952
    96
fun mark _ [] = raise ERROR "mark []"
walther@59952
    97
  | mark eq xs =
walther@59952
    98
    let
walther@59952
    99
      fun mar xx _ [x] n = xx @ [(if n = 1 then 0 else n, x)]
walther@59952
   100
        | mar _ _ [] _ = raise ERROR "mark []"
walther@59952
   101
        | mar xx eq (x:: x' :: xs) n = 
walther@59952
   102
        if eq(x, x') then mar (xx @ [(n, x)]) eq (x' :: xs) (n + 1)
walther@59952
   103
        else mar (xx @ [(if n = 1 then 0 else n, x)]) eq (x' :: xs) 1;
walther@59952
   104
    in mar [] eq xs 1 end;
walther@59952
   105
walther@59952
   106
(*
walther@59952
   107
  assumes equal descriptions to be in adjacent 'plateaus',
walther@59952
   108
  items at a certain position within the plateaus form a variant;
walther@59952
   109
  length = 1 ... marked with 0: covers all variants
walther@59952
   110
*)
walther@59947
   111
fun add_variants fdts = 
walther@59947
   112
  let 
walther@59947
   113
    fun eq (a, b) = curry op= (snd3 a) (snd3 b);
walther@59947
   114
  in mark eq fdts end;
walther@59947
   115
walther@59952
   116
fun max [] = raise ERROR "max of []"
walther@59947
   117
  | max (y :: ys) =
walther@59947
   118
  let fun mx x [] = x
walther@59947
   119
	| mx x (y :: ys) = if x < y then mx y ys else mx x ys;
walther@59947
   120
in mx y ys end;
walther@59947
   121
walther@59947
   122
fun coll_variants (((v,x) :: vxs)) =
walther@59947
   123
    let
walther@59947
   124
      fun col xs (vs, x) [] = xs @ [(vs, x)]
walther@59947
   125
        | col xs (vs, x) ((v', x') :: vxs') = 
walther@59947
   126
        if x = x' then col xs (vs @ [v'], x') vxs'
walther@59947
   127
        else col (xs @ [(vs, x)]) ([v'], x') vxs';
walther@59947
   128
    in col [] ([v], x) vxs end
walther@59952
   129
  | coll_variants _ = raise ERROR "coll_variants: called with []";
walther@59947
   130
walther@59947
   131
fun replace_0 vm [0] = intsto vm
walther@59947
   132
  | replace_0 _ vs = vs;
walther@59947
   133
walther@59961
   134
fun add_id [] = raise ERROR "O_Model.add_id []"
walther@59947
   135
  | add_id xs =
walther@59947
   136
    let
walther@59947
   137
      fun add _ [] = []
walther@59947
   138
        | add n (x :: xs) = (n, x) :: add (n + 1) xs;
walther@59947
   139
    in add 1 xs end;
walther@59947
   140
walther@59947
   141
fun flattup (a, (b, (c, d, e))) = (a, b, c, d, e);
walther@59947
   142
walther@59952
   143
fun init [] _ _ = []
walther@59952
   144
  | init fmz thy pbt =
walther@59947
   145
    let
walther@59996
   146
      val model =
walther@59996
   147
        (map (fn str => str
walther@59996
   148
          |> TermC.parseNEW'' thy
walther@59996
   149
          |> Input_Descript.split
walther@59996
   150
          |> add_field thy pbt) fmz)
walther@59996
   151
        |> add_variants;
walther@59952
   152
      val maxv = model |> map fst |> max;
walther@59947
   153
      val maxv = if maxv = 0 then 1 else maxv;
walther@59952
   154
      val model' = model
walther@59952
   155
        |> coll_variants
walther@59947
   156
        |> map (replace_0 maxv |> apfst)
walther@59947
   157
        |> add_id
walther@59947
   158
        |> map flattup;
walther@59952
   159
    in model' end;
walther@59938
   160
walther@59960
   161
walther@59960
   162
(** add new m_field's from method **)
walther@59960
   163
walther@59960
   164
fun add _ mpc ori =
walther@59960
   165
  let
walther@59960
   166
    fun eq d pt = (d = (fst o snd) pt);
walther@59960
   167
    fun repl mpc (i, v, _, d, ts) = 
walther@59960
   168
      case filter (eq d) mpc of
walther@59960
   169
	      [(fi, (_, _))] => [(i, v, fi, d, ts)]
walther@59960
   170
      | [] => [] (*25.2.02: dsc in ori, but not in met -> superfluous*)    
walther@59962
   171
      | _ => raise ERROR ("O_Model.add: " ^ UnparseC.term d ^ " more than once in met");
walther@59960
   172
  in flat ((map (repl mpc)) ori) end;
walther@59960
   173
walther@59969
   174
walther@59969
   175
(** get the values **)
walther@59969
   176
walther@59969
   177
fun mkval _(*dsc*) [] = raise ERROR "mkval called with []"
walther@59969
   178
  | mkval _ [t] = t
walther@59969
   179
  | mkval _ ts = TermC.list2isalist ((type_of o hd) ts) ts;
walther@59969
   180
fun mkval' x = mkval TermC.empty x;
walther@59987
   181
(*TODO: unify with values'*)
walther@59987
   182
fun values (oris:T) =
walther@59969
   183
  ((map (mkval' o (#5))) o (filter ((member_swap op= 1) o (#2)))) oris
walther@59969
   184
walther@59986
   185
walther@59986
   186
(** ? ? ? **)
walther@59986
   187
walther@59986
   188
(* make oris from args of the stac SubProblem and from pbt.
walther@59986
   189
   can this formal argument (of a model-pattern) be omitted in the arg-list
walther@59986
   190
   of a SubProblem ? see calcelems.sml 'type met '                        *)
walther@59986
   191
fun is_copy_named_idstr str =
walther@59986
   192
  case (rev o Symbol.explode) str of
walther@59986
   193
	  "'" :: _ :: "'" :: _ => true
walther@59986
   194
  | _ => false
walther@59986
   195
fun is_copy_named (_, (_, t)) = (is_copy_named_idstr o TermC.free2str) t
walther@59986
   196
walther@59986
   197
(* should this formal argument (of a model-pattern) create a new identifier? *)
walther@59986
   198
fun is_copy_named_generating_idstr str =
walther@59986
   199
  if is_copy_named_idstr str
walther@59986
   200
  then
walther@59986
   201
    case (rev o Symbol.explode) str of
walther@59986
   202
	    "'" :: "'" :: "'" :: _ => false
walther@59986
   203
    | _ => true
walther@59986
   204
  else false
walther@59986
   205
fun is_copy_named_generating (_, (_, t)) = (is_copy_named_generating_idstr o TermC.free2str) t
walther@59986
   206
walther@59986
   207
(* generate a new variable "x_i" name from a related given one "x"
walther@59986
   208
   by use of oris relating "v_v'i'" (is_copy_named!) to "v_v"
walther@59986
   209
   e.g. (v_v, x) & (v_v'i', ?) --> (v_v'i', x_i),
walther@59986
   210
   but leave is_copy_named_generating as is, e.t. ss''' *)
walther@59986
   211
fun cpy_nam pbt oris (p as (field, (dsc, t))) =
walther@59986
   212
  (if is_copy_named_generating p
walther@59986
   213
   then (*WN051014 kept strange old code ...*)
walther@59986
   214
     let fun sel (_,_,d,ts) = Input_Descript.join'''' (d, ts) 
walther@59986
   215
       val cy' = (implode o (drop_last_n 3) o Symbol.explode o TermC.free2str) t
walther@59986
   216
       val ext = (last_elem o drop_last o Symbol.explode o TermC.free2str) t
walther@59986
   217
       val vars' = map (Term.term_name o snd o snd) pbt (*cpy-nam filtered_out*)
walther@59986
   218
       val vals = map sel oris
walther@59986
   219
       val cy_ext = (Term.term_name o the) (assoc (vars' ~~ vals, cy')) ^ "_" ^ ext
walther@59986
   220
     in ([1], field, dsc, [TermC.mk_free (type_of t) cy_ext]) end
walther@59986
   221
   else ([1], field, dsc, [t])
walther@59986
   222
	) handle _ => raise ERROR ("cpy_nam: for "^ UnparseC.term t)
walther@59986
   223
walther@59997
   224
(* ["BOOL (1+x=2)", "REAL x"] --match_ags--> oris 
walther@59997
   225
   --values'--> ["equality (1+x=2)", "boundVariable x", "solutions L"] *)
walther@59987
   226
(*TODO: unify with values*)
walther@59987
   227
fun values' oris =
walther@59986
   228
  let fun ori2fmz_vals (_, _, _, dsc, ts) = 
walther@59986
   229
	  ((UnparseC.term o Input_Descript.join') (dsc, ts), last_elem ts) 
walther@59986
   230
	  handle _ => raise ERROR ("ori2fmz_env called with " ^ UnparseC.terms ts)
walther@59986
   231
  in (split_list o (map ori2fmz_vals)) oris end
walther@59986
   232
walther@59938
   233
(**)end(**);