[errors 4, Test_Isac_Short] resolve hacks, part 4: reapired O_Model.complete_for
1 (* Title: Specify/o-model.sml
2 Author: Walther Neuper 110226
3 (c) due to copyright terms
5 An \<open>O_Model\<close> holds \<open>O\<close>riginal data, \<open>descriptor\<close> and \<open>values\<close> parsed from \<open>Formalise.model\<close>
6 selected with respect to a \<open>Model_Pattern\<close> and combined with respective \<open>m_field\<close>s.
7 \<open>complete_for\<close> a \<open>Model_Pattern\<close> is done by \<open>Tactic.Model_Problem\<close>
8 (with defaults from \<open>Formalise\<close>refs), by \<open>Tactic.Specify_Problem\<close> and \<open>Tactic.Specify_Method\<close>
10 \<open>O_Model\<close> serves efficiency of student's interactive modelling via \<open>I_Model\<close>.
12 \<open>O_Model\<close> marks elements with \<open>m_field\<close> \<open>#undef\<close>, which are not required by the \<open>Model_Pattern\<close>
13 of the \<open>Problem\<close> or the \<open>Method\<close> .. TODO redes: \<open>m_field\<close> probably different in root..Subproblem
15 TODO: revise with an example with more than 1 variant.
16 + consider: drop m_field ?
19 signature ORIGINAL_MODEL =
28 val to_string: T -> string
29 val single_to_string: single -> string
30 val single_empty: single
32 (*val init: theory -> Formalise.model -> Model_Pattern.T -> T ..TODO*)
33 val init: Formalise.model -> theory -> Model_Pattern.T -> T
34 val add : theory -> Model_Pattern.T -> T -> T
35 val values : T -> term list
36 val values': T -> Formalise.model * term list
37 val complete_for: Model_Pattern.T -> T -> T * Proof.context -> T * Proof.context
38 (*/------- rename -------\*)
39 (*val seek_oridts: Proof.context -> ?/////? -> descriptor * values -> T -> message * single * values*)
40 val seek_oridts: Proof.context -> m_field -> descriptor * values -> T -> message * single * values
41 (*val single_for_values:!!! values -> Proof.context -> m_field -> T -> message * single * values*)
42 val seek_orits: Proof.context -> m_field -> values -> T -> message * single * values
43 (*val ?contains:!!! term -> Proof.context -> m_field -> T -> message * single * values*)
44 val is_known: Proof.context -> m_field -> T -> term -> message * single * values
45 (*val typeless: term -> term*)
46 val typeless: term -> term
47 (*val test_types: Proof.context -> descriptor * values -> string*)
48 val test_types: Proof.context -> descriptor * values -> string
50 (*put add_id into a new auxiliary fun, see ONLY call..*)
51 val add_id: 'a list -> (int * 'a) list
53 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
54 (*val cpy_nam: Model_Pattern.T -> preori list -> Model_Pattern.single -> preori*)
55 val cpy_nam: Model_Pattern.T -> preori list -> Model_Pattern.single -> preori
56 val is_copy_named: Model_Pattern.single -> bool
57 val is_copy_named_idstr: string -> bool
58 val is_copy_named_generating_idstr: string -> bool
59 val is_copy_named_generating: Model_Pattern.single -> bool
61 val preoris2str : preori list -> string
62 (*val getr_ct: theory -> single -> m_field * UnparseC.term_as_string*)
63 val getr_ct: theory -> single -> m_field * UnparseC.term_as_string
65 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
66 val add_field: theory -> Model_Pattern.T -> descriptor * values -> m_field * descriptor * values
67 val add_variants: ('a * ''b * 'c) list -> (int * ('a * ''b * 'c)) list
68 (*val max: variants -> int*)
69 val max: variants -> int
70 (*val coll_variants: ('a * ''b) list -> ('a list * ''b) list*)
71 val coll_variants: ('a * ''b) list -> ('a list * ''b) list
72 (*val replace_0: int -> int list -> int list*)
73 val replace_0: int -> int list -> int list
74 val flattup: 'a * ('b * ('c * 'd * 'e)) -> 'a * 'b * 'c * 'd * 'e
75 (*val mark: ('a * 'a -> bool) -> 'a list -> (int * 'a) list*)
76 val mark: ('a * 'a -> bool) -> 'a list -> (int * 'a) list
77 (*\------- rename -------/*)
78 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
82 structure O_Model(**) : ORIGINAL_MODEL(**) =
88 type variants = Model_Def.variants;
89 type m_field = Model_Def.m_field;
90 type descriptor = Model_Def.descriptor;
91 type values = Model_Def.values;
92 type message = string;
94 type T = Model_Def.o_model;
95 type single = Model_Def.o_model_single
96 val single_empty = Model_Def.o_model_empty;
97 val single_to_string = Model_Def.o_model_single_to_string;
98 val to_string = Model_Def.o_model_to_string;
100 (* O_Model.single without leading integer *)
101 type preori = (variants * m_field * term * term list);
102 fun preori2str (vs, fi, t, ts) =
103 "(" ^ (strs2str o (map string_of_int)) vs ^ ", " ^ fi ^ ", " ^
104 UnparseC.term t ^ ", " ^ (strs2str o (map UnparseC.term)) ts ^ ")";
105 val preoris2str = (strs2str' o (map (linefeed o preori2str)));
107 (* get the first term in ts from ori *)
108 fun getr_ct thy (_, _, fd, d, ts) =
109 (fd, ((UnparseC.term_in_thy thy) o Input_Descript.join) (d,[hd ts]))
112 (** initialise O_Model **)
114 (* compare d and dsc in pbt and transfer field to pre-ori *)
115 fun add_field (_: theory) pbt (d,ts) =
116 let fun eq d pt = (d = (fst o snd) pt);
117 in case filter (eq d) pbt of
118 [(fi, (_, _))] => (fi, d, ts)
119 | [] => ("#undef", d, ts) (*may come with met.ppc*)
120 | _ => raise ERROR ("add_field: " ^ UnparseC.term d ^ " more than once in pbt")
124 mark an element with the position within a plateau;
125 a plateau with length 1 is marked with 0
127 fun mark _ [] = raise ERROR "mark []"
130 fun mar xx _ [x] n = xx @ [(if n = 1 then 0 else n, x)]
131 | mar _ _ [] _ = raise ERROR "mark []"
132 | mar xx eq (x:: x' :: xs) n =
133 if eq(x, x') then mar (xx @ [(n, x)]) eq (x' :: xs) (n + 1)
134 else mar (xx @ [(if n = 1 then 0 else n, x)]) eq (x' :: xs) 1;
135 in mar [] eq xs 1 end;
138 assumes equal descriptions to be in adjacent 'plateaus',
139 items at a certain position within the plateaus form a variant;
140 length = 1 ... marked with 0: covers all variants
142 fun add_variants fdts =
144 fun eq (a, b) = curry op= (snd3 a) (snd3 b);
147 fun max [] = raise ERROR "max of []"
150 | mx x (y :: ys) = if x < y then mx y ys else mx x ys;
153 fun coll_variants (((v,x) :: vxs)) =
155 fun col xs (vs, x) [] = xs @ [(vs, x)]
156 | col xs (vs, x) ((v', x') :: vxs') =
157 if x = x' then col xs (vs @ [v'], x') vxs'
158 else col (xs @ [(vs, x)]) ([v'], x') vxs';
159 in col [] ([v], x) vxs end
160 | coll_variants _ = raise ERROR "coll_variants: called with []";
162 fun replace_0 vm [0] = intsto vm
163 | replace_0 _ vs = vs;
165 fun add_id [] = raise ERROR "O_Model.add_id []"
169 | add n (x :: xs) = (n, x) :: add (n + 1) xs;
172 fun flattup (a, (b, (c, d, e))) = (a, b, c, d, e);
179 |> TermC.parseNEW'' thy
180 |> Input_Descript.split
181 |> add_field thy pbt) fmz)
183 val maxv = model |> map fst |> max;
184 val maxv = if maxv = 0 then 1 else maxv;
187 |> map (replace_0 maxv |> apfst)
193 (** add new m_field's from method \<rightarrow> REPLACE BY complete_for **)
195 (* for the root-problem *)
198 fun eq d pt = (d = (fst o snd) pt);
199 fun repl mpc (i, v, _, d, ts) =
200 case filter (eq d) mpc of
201 [(fi, (_, _))] => [(i, v, fi, d, ts)]
202 | [] => [] (*25.2.02: dsc in ori, but not in met -> superfluous*)
203 | _ => raise ERROR ("O_Model.add: " ^ UnparseC.term d ^ " more than once in met");
204 in flat ((map (repl mpc)) ori) end;
207 (** get the values **)
209 fun mkval _(*dsc*) [] = raise ERROR "mkval called with []"
211 | mkval _ ts = TermC.list2isalist ((type_of o hd) ts) ts;
212 fun mkval' x = mkval TermC.empty x;
213 (*TODO: unify with values'*)
214 fun values (oris:T) =
215 ((map (mkval' o (#5))) o (filter ((member_swap op= 1) o (#2)))) oris
218 (** complete wrt. Model_Pattern.T by use of root's O_Model.T **)
220 fun complete_for m_patt root_model (o_model, ctxt) =
222 val missing = m_patt |> filter_out
223 (fn (_, (descriptor, _)) => (Library.member op = (map #4 o_model) descriptor))
224 val add = (root_model
226 (fn (_, _, _, descriptor, _) => (Library.member op = (map (fst o snd) missing)) descriptor))
227 (*OLD* )|> map (fn (a, b, _, d, e) => (a, b, "#undef", d, e))
228 ( *OLD*)(* indicate, that m_field ---------^^^^^^^^ might change from root- to sub-Model_Pattern *)
231 (*NEW*)|> map (fn (a, b, _, descr, e) => (a, b, the (Model_Pattern.get_field descr m_patt), descr, e))
233 |> map (fn (_, b, c, d, e) => (b, c, d, e)) (* for correct enumeration *)
234 |> add_id (* for correct enumeration *)
235 |> map (fn (a, (b, c, d, e)) => (a, b, c, d, e)), (* for correct enumeration *)
236 ctxt |> ContextC.add_constraints (add |> values |> TermC.vars'))
242 (* make oris from args of the stac SubProblem and from pbt.
243 can this formal argument (of a model-pattern) be omitted in the arg-list
244 of a SubProblem ? see calcelems.sml 'type met ' *)
245 fun is_copy_named_idstr str =
246 case (rev o Symbol.explode) str of
247 "'" :: _ :: "'" :: _ => true
249 fun is_copy_named (_, (_, t)) = (is_copy_named_idstr o TermC.free2str) t
251 (* should this formal argument (of a model-pattern) create a new identifier? *)
252 fun is_copy_named_generating_idstr str =
253 if is_copy_named_idstr str
255 case (rev o Symbol.explode) str of
256 "'" :: "'" :: "'" :: _ => false
259 fun is_copy_named_generating (_, (_, t)) = (is_copy_named_generating_idstr o TermC.free2str) t
261 (* generate a new variable "x_i" name from a related given one "x"
262 by use of oris relating "v_v'i'" (is_copy_named!) to "v_v"
263 e.g. (v_v, x) & (v_v'i', ?) --> (v_v'i', x_i),
264 but leave is_copy_named_generating as is, e.t. ss''' *)
265 fun cpy_nam pbt oris (p as (field, (dsc, t))) =
266 (if is_copy_named_generating p
267 then (*WN051014 kept strange old code ...*)
268 let fun sel (_,_,d,ts) = Input_Descript.join'''' (d, ts)
269 val cy' = (implode o (drop_last_n 3) o Symbol.explode o TermC.free2str) t
270 val ext = (last_elem o drop_last o Symbol.explode o TermC.free2str) t
271 val vars' = map (Term.term_name o snd o snd) pbt (*cpy-nam filtered_out*)
272 val vals = map sel oris
273 val cy_ext = (Term.term_name o the) (assoc (vars' ~~ vals, cy')) ^ "_" ^ ext
274 in ([1], field, dsc, [TermC.mk_free (type_of t) cy_ext]) end
275 else ([1], field, dsc, [t])
276 ) handle _ => raise ERROR ("cpy_nam: for "^ UnparseC.term t)
278 (* ["BOOL (1+x=2)", "REAL x"] --match_ags--> oris
279 --values'--> ["equality (1+x=2)", "boundVariable x", "solutions L"] *)
280 (*TODO: unify with values*)
282 let fun ori2fmz_vals (_, _, _, dsc, ts) =
283 ((UnparseC.term o Input_Descript.join') (dsc, ts), last_elem ts)
284 handle _ => raise ERROR ("ori2fmz_env called with " ^ UnparseC.terms ts)
285 in (split_list o (map ori2fmz_vals)) oris end
288 (** tools for I_Model **)
291 fun seek_oridts ctxt sel (d, ts) [] =
292 ("seek_oridts: input ('" ^
293 (UnparseC.term_in_ctxt ctxt (Input_Descript.join (d, ts))) ^ "') not found in oris (typed)",
296 | seek_oridts ctxt sel (d, ts) ((id, vat, sel', d', ts') :: oris) =
297 if sel = sel' andalso d = d' andalso (inter op = ts ts') <> []
298 then ("", (id, vat, sel, d, inter op = ts ts'), ts')
299 else seek_oridts ctxt sel (d, ts) oris
301 fun seek_oridts ctxt m_field (descript, vals) [] =
302 ("seek_oridts: input ('" ^ UnparseC.term_in_ctxt ctxt (Input_Descript.join (descript, vals)) ^
303 "') not found in oris (typed)", (0, [], m_field, descript, vals), [])
304 | seek_oridts ctxt m_field (descript, vals) ((id, vat, m_field', descript', vals') :: oris) =
305 if (inter op = vals vals') <> [] andalso descript = descript' then
306 if m_field = "#undef" then (* m_field may change from root- to sub-Model_Pattern *)
307 ("", (id, vat, m_field, descript, inter op = vals vals'), vals')
308 else if m_field = m_field' then
309 ("", (id, vat, m_field, descript, inter op = vals vals'), vals')
311 (((strs2str' o map (UnparseC.term_in_ctxt ctxt)) vals) ^
312 " not for " ^ m_field, single_empty, [])
313 else seek_oridts ctxt m_field (descript, vals) oris
315 (* to an input (_,ts) find the according ori and insert the ts *)
316 fun seek_orits ctxt _ values [] =
317 ("seek_orits: input (_, '" ^ strs2str (map (UnparseC.term_in_ctxt ctxt) values) ^
318 "') not found in oris (typed)", single_empty, [])
319 | seek_orits ctxt sel values ((id, vat, sel', d, values') :: oris) =
320 if (inter op = values values') <> [] then
321 if sel = "#undef" then (* indicates that m_field changed from root- to sub-Model_Pattern *)
322 ("", (id, vat, sel, d, inter op = values values'), values')
323 else if sel = sel' then
324 ("", (id, vat, sel, d, inter op = values values'), values')
326 (((strs2str' o map (UnparseC.term_in_ctxt ctxt)) values) ^
327 " not for " ^ sel, single_empty, [])
328 else seek_orits ctxt sel values oris
330 fun test_types ctxt (d,ts) =
332 val opt = (try Input_Descript.join) (d, ts)
333 val msg = case opt of
335 | NONE => (UnparseC.term_in_ctxt ctxt d ^ " " ^
336 (strs2str' o map (UnparseC.term_in_ctxt ctxt)) ts ^ " is illtyped")
339 (* make a term 'typeless' for comparing with another 'typeless' term;
340 'type-less' usually is illtyped *)
341 fun typeless (Const (s, _)) = (Const (s, TermC.typ_empty))
342 | typeless (Free (s, _)) = (Free (s, TermC.typ_empty))
343 | typeless (Var (n, _)) = (Var (n, TermC.typ_empty))
344 | typeless (Bound i) = (Bound i)
345 | typeless (Abs (s, _,t)) = Abs(s, TermC.typ_empty, typeless t)
346 | typeless (t1 $ t2) = (typeless t1) $ (typeless t2)
348 (* is the term t input (or taken from fmz) known in O_Model ?
349 give feedback on all(?) strange input;
350 return _all_ terms already input to this item (e.g. valuesFor a,b) *)
351 fun is_known ctxt sel ori t =
353 val ots = (distinct o flat o (map #5)) ori
354 val oids = ((map (fst o dest_Free)) o distinct o flat o (map TermC.vars)) ots
355 val (d, ts) = Input_Descript.split t
356 val ids = map (fst o dest_Free) ((distinct o (flat o (map TermC.vars))) ts)
358 if (subtract op = oids ids) <> []
359 then ("identifiers " ^ strs2str' (subtract op = oids ids) ^ " not in example", single_empty, [])
363 if not (subset op = (map typeless ts, map typeless ots))
364 then ("terms '" ^ (strs2str' o (map (UnparseC.term_in_ctxt ctxt))) ts ^
365 "' not in example (typeless)", single_empty, [])
367 (case seek_orits ctxt sel ts(*..values*) ori of
368 ("", ori_ as (_, _, _, d, ts), all) =>
369 (case test_types ctxt (d,ts) of
370 "" => ("", ori_, all)
371 | msg => (msg, single_empty, []))
372 | (msg, _, _) => (msg, single_empty, []))
374 if member op = (map #4 ori) d
375 then seek_oridts ctxt sel (d, ts) ori
376 else (UnparseC.term_in_ctxt ctxt d ^ " not in example", (0, [], sel, d, ts), [])