1 (* Title: Specify/o-model.sml
2 Author: Walther Neuper 110226
3 (c) due to copyright terms
5 An original model is created initially from Formalise.T and Model_Pattern.T;
6 This model makes student's editing via I_Model.T more efficient.
7 TODO: revise with an example with more than 1 variant.
10 signature ORIGINAL_MODEL =
17 val to_string: T -> string
18 val single_to_string: single -> string
19 val single_empty: single
21 val init: Formalise.model -> theory -> Model_Pattern.T -> T
22 val add : theory -> Model_Pattern.T -> T -> T
23 val values : T -> term list
25 (*/--- use struct.id for appropriate names ..*)
26 val match_ags: theory -> Model_Pattern.T -> term list -> T (*?\<rightarrow>M_Match?*)
27 val match_ags_msg: Problem.id -> term -> term list -> unit (*?\<rightarrow>M_Match?*)
28 val oris2fmz_vals: T -> string list * term list
29 (*val variables: Model_Pattern.T -> term list*) (*(*?\<rightarrow>Model_Pattern?*)*)
30 val vars_of_pbl_': Model_Pattern.T -> term list (*(*?\<rightarrow>Model_Pattern?*)*)
32 (*put add_id into a new auxiliary fun..*)
33 val add_id: 'a list -> (int * 'a) list
35 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
36 val cpy_nam: Model_Pattern.T -> preori list -> Model_Pattern.single -> preori
37 val is_copy_named: Model_Pattern.single -> bool
38 val is_copy_named_idstr: string -> bool
39 val is_copy_named_generating_idstr: string -> bool
40 val is_copy_named_generating: Model_Pattern.single -> bool
41 val matc: theory -> Model_Pattern.T -> term list -> preori list -> preori list
42 val mtc: theory -> Model_Pattern.single -> term -> preori option
44 val preoris2str : preori list -> string
45 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
46 val add_field: theory -> Model_Pattern.T -> term * 'b -> m_field * descriptor * 'b
47 val add_variants: ('a * ''b * 'c) list -> (int * ('a * ''b * 'c)) list
48 val max: variants -> int
49 val coll_variants: ('a * ''b) list -> ('a list * ''b) list
50 val replace_0: int -> int list -> int list
51 val flattup: 'a * ('b * ('c * 'd * 'e)) -> 'a * 'b * 'c * 'd * 'e
52 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
56 structure O_Model(**) : ORIGINAL_MODEL(**) =
62 type variants = Model_Def.variants;
63 type m_field = Model_Def.m_field;
64 type descriptor = Model_Def.descriptor;
66 type T = Model_Def.o_model;
67 type single = Model_Def.o_model_single
68 val single_empty = Model_Def.o_model_empty;
69 val single_to_string = Model_Def.o_model_single_to_string;
70 val to_string = Model_Def.o_model_to_string;
72 (* O_Model.single without leading integer *)
73 type preori = (variants * m_field * term * term list);
74 fun preori2str (vs, fi, t, ts) =
75 "(" ^ (strs2str o (map string_of_int)) vs ^ ", " ^ fi ^ ", " ^
76 UnparseC.term t ^ ", " ^ (strs2str o (map UnparseC.term)) ts ^ ")";
77 val preoris2str = (strs2str' o (map (linefeed o preori2str)));
80 (** initialise O_Model **)
82 (* compare d and dsc in pbt and transfer field to pre-ori *)
83 fun add_field (_: theory) pbt (d,ts) =
84 let fun eq d pt = (d = (fst o snd) pt);
85 in case filter (eq d) pbt of
86 [(fi, (_, _))] => (fi, d, ts)
87 | [] => ("#undef", d, ts) (*may come with met.ppc*)
88 | _ => raise ERROR ("add_field: " ^ UnparseC.term d ^ " more than once in pbt")
92 mark an element with the position within a plateau;
93 a plateau with length 1 is marked with 0
95 fun mark _ [] = raise ERROR "mark []"
98 fun mar xx _ [x] n = xx @ [(if n = 1 then 0 else n, x)]
99 | mar _ _ [] _ = raise ERROR "mark []"
100 | mar xx eq (x:: x' :: xs) n =
101 if eq(x, x') then mar (xx @ [(n, x)]) eq (x' :: xs) (n + 1)
102 else mar (xx @ [(if n = 1 then 0 else n, x)]) eq (x' :: xs) 1;
103 in mar [] eq xs 1 end;
106 assumes equal descriptions to be in adjacent 'plateaus',
107 items at a certain position within the plateaus form a variant;
108 length = 1 ... marked with 0: covers all variants
110 fun add_variants fdts =
112 fun eq (a, b) = curry op= (snd3 a) (snd3 b);
115 fun max [] = raise ERROR "max of []"
118 | mx x (y :: ys) = if x < y then mx y ys else mx x ys;
121 fun coll_variants (((v,x) :: vxs)) =
123 fun col xs (vs, x) [] = xs @ [(vs, x)]
124 | col xs (vs, x) ((v', x') :: vxs') =
125 if x = x' then col xs (vs @ [v'], x') vxs'
126 else col (xs @ [(vs, x)]) ([v'], x') vxs';
127 in col [] ([v], x) vxs end
128 | coll_variants _ = raise ERROR "coll_variants: called with []";
130 fun replace_0 vm [0] = intsto vm
131 | replace_0 _ vs = vs;
133 fun add_id [] = raise ERROR "O_Model.add_id []"
137 | add n (x :: xs) = (n, x) :: add (n + 1) xs;
140 fun flattup (a, (b, (c, d, e))) = (a, b, c, d, e);
145 val model = (map (fn str => str
146 |> TermC.parseNEW'' thy
147 |> Input_Descript.split
148 |> add_field thy pbt) fmz)
150 val maxv = model |> map fst |> max;
151 val maxv = if maxv = 0 then 1 else maxv;
154 |> map (replace_0 maxv |> apfst)
160 (** add new m_field's from method **)
164 fun eq d pt = (d = (fst o snd) pt);
165 fun repl mpc (i, v, _, d, ts) =
166 case filter (eq d) mpc of
167 [(fi, (_, _))] => [(i, v, fi, d, ts)]
168 | [] => [] (*25.2.02: dsc in ori, but not in met -> superfluous*)
169 | _ => raise ERROR ("O_Model.add: " ^ UnparseC.term d ^ " more than once in met");
170 in flat ((map (repl mpc)) ori) end;
173 (** get the values **)
175 fun mkval _(*dsc*) [] = raise ERROR "mkval called with []"
177 | mkval _ ts = TermC.list2isalist ((type_of o hd) ts) ts;
178 fun mkval' x = mkval TermC.empty x;
180 ((map (mkval' o (#5))) o (filter ((member_swap op= 1) o (#2)))) oris
185 (* make oris from args of the stac SubProblem and from pbt.
186 can this formal argument (of a model-pattern) be omitted in the arg-list
187 of a SubProblem ? see calcelems.sml 'type met ' *)
188 fun is_copy_named_idstr str =
189 case (rev o Symbol.explode) str of
190 "'" :: _ :: "'" :: _ => true
192 fun is_copy_named (_, (_, t)) = (is_copy_named_idstr o TermC.free2str) t
194 (* should this formal argument (of a model-pattern) create a new identifier? *)
195 fun is_copy_named_generating_idstr str =
196 if is_copy_named_idstr str
198 case (rev o Symbol.explode) str of
199 "'" :: "'" :: "'" :: _ => false
202 fun is_copy_named_generating (_, (_, t)) = (is_copy_named_generating_idstr o TermC.free2str) t
205 (* split type-wrapper from scr-arg and build part of an ori;
206 an type-error is reported immediately, raises an exn,
207 subsequent handling of exn provides 2nd part of error message *)
208 fun mtc thy (str, (dsc, _)) (ty $ var) =
209 ((Thm.global_cterm_of thy (dsc $ var);(*type check*)
210 SOME (([1], str, dsc, (*[var]*)
211 Input_Descript.split' (dsc, var))) (*:ori without leading #*))
212 handle e as TYPE _ =>
213 (tracing (dashs 70 ^ "\n"
214 ^ "*** ERROR while creating the items for the model of the ->problem\n"
215 ^ "*** from the ->stac with ->typeconstructor in arglist:\n"
216 ^ "*** item (->description ->value): " ^ UnparseC.term dsc ^ " " ^ UnparseC.term var ^ "\n"
217 ^ "*** description: " ^ TermC.term_detail2str dsc
218 ^ "*** value: " ^ TermC.term_detail2str var
219 ^ "*** typeconstructor in script: " ^ TermC.term_detail2str ty
220 ^ "*** checked by theory: " ^ Context.theory_name thy ^ "\n"
222 writeln (@{make_string} e);
223 Exn.reraise e; (*raise ERROR "actual args do not match formal args";FIXXXME.WN100916*)
225 | mtc _ _ t = raise ERROR ("mtc: uncovered case with" ^ UnparseC.term t)
227 (* match each pat of the model-pattern with an actual argument;
228 precondition: copy-named vars are filtered out *)
229 fun matc _ [] _ oris = oris
232 raise ERROR ("actual arg(s) missing for '" ^ Model_Pattern.to_string pbt ^ "' i.e. should be 'copy-named' by '*_._'"))
233 | matc thy ((p as (_, (_, t))) :: pbt) (a :: ags) oris =
234 (*del?..*)if (is_copy_named_idstr o TermC.free2str) t then oris
236 let val opt = mtc thy p a
239 SOME ori => matc thy pbt ags (oris @ [ori])
240 | NONE => [](*WN050903 skipped by exn handled in match_ags*)
243 (* generate a new variable "x_i" name from a related given one "x"
244 by use of oris relating "v_v'i'" (is_copy_named!) to "v_v"
245 e.g. (v_v, x) & (v_v'i', ?) --> (v_v'i', x_i),
246 but leave is_copy_named_generating as is, e.t. ss''' *)
247 fun cpy_nam pbt oris (p as (field, (dsc, t))) =
248 (if is_copy_named_generating p
249 then (*WN051014 kept strange old code ...*)
250 let fun sel (_,_,d,ts) = Input_Descript.join'''' (d, ts)
251 val cy' = (implode o (drop_last_n 3) o Symbol.explode o TermC.free2str) t
252 val ext = (last_elem o drop_last o Symbol.explode o TermC.free2str) t
253 val vars' = map (Term.term_name o snd o snd) pbt (*cpy-nam filtered_out*)
254 val vals = map sel oris
255 val cy_ext = (Term.term_name o the) (assoc (vars' ~~ vals, cy')) ^ "_" ^ ext
256 in ([1], field, dsc, [TermC.mk_free (type_of t) cy_ext]) end
257 else ([1], field, dsc, [t])
258 ) handle _ => raise ERROR ("cpy_nam: for "^ UnparseC.term t)
260 (* ["BOOL (1+x=2)","REAL x"] --match_ags--> oris
261 --oris2fmz_vals--> ["equality (1+x=2)","boundVariable x","solutions L"] *)
262 fun oris2fmz_vals oris =
263 let fun ori2fmz_vals (_, _, _, dsc, ts) =
264 ((UnparseC.term o Input_Descript.join') (dsc, ts), last_elem ts)
265 handle _ => raise ERROR ("ori2fmz_env called with " ^ UnparseC.terms ts)
266 in (split_list o (map ori2fmz_vals)) oris end
268 (* match the actual arguments of a SubProblem with a model-pattern
269 and create an ori list (in root-pbl created from formalization).
270 expects ags:pats = 1:1, while copy-named are filtered out of pats;
271 if no 1:1 then exn raised by matc/mtc and handled at call.
272 copy-named pats are appended in order to get them into the model-items *)
273 fun match_ags thy pbt ags =
275 fun flattup (i, (var, bool, str, itm_)) = (i, var, bool, str, itm_)
276 val pbt' = filter_out is_copy_named pbt
277 val cy = filter is_copy_named pbt (* cy is NOT a (formal) argument, but the fun's result *)
278 val oris' = matc thy pbt' ags []
279 val cy' = map (cpy_nam pbt' oris') cy
280 val ors = add_id (oris' @ cy') (*...appended in order to get into the model-items *)
281 in (map flattup ors) end
283 (* report part of the error-msg which is not available in match_args *)
284 fun match_ags_msg pI stac ags =
286 val pats = (#ppc o Problem.from_store) pI
287 val msg = (dots 70 ^ "\n"
288 ^ "*** problem " ^ strs2str pI ^ " has the ...\n"
289 ^ "*** model-pattern " ^ Model_Pattern.to_string pats ^ "\n"
290 ^ "*** stac '" ^ UnparseC.term stac ^ "' has the ...\n"
291 ^ "*** arg-list " ^ UnparseC.terms ags ^ "\n"
293 (*WN100921 ^^^^ expect TYPE errormsg below; lost with Isa09*)
296 (* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
297 fun vars_of_pbl_' pbl_ =
299 fun var_of_pbl_ (_, (_, t)) = t: term
300 in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end