1 (* Title: Model for (sub-)calculations.
2 Various representations: item and ppc for frontend, itm_ and itm for internal functions.
3 The former are related to structure Specify, the latter to structure Chead --
4 -- apt to re-arrangement of structures
5 Author: Walther Neuper 170207
6 (c) due to copyright terms
12 val oris2str : ori list -> string
15 = Correct of TermC.as_string | False of TermC.as_string | Incompl of TermC.as_string | Missing of TermC.as_string | Superfl of string
16 | SyntaxE of string | TypeE of string
17 datatype itm_ = Cor of (term * (term list)) * (term * (term list))
18 | Syn of TermC.as_string | Typ of TermC.as_string | Inc of (term * (term list)) * (term * (term list))
19 | Sup of (term * (term list)) | Mis of (term * term) | Par of TermC.as_string
20 val itm_2str : itm_ -> string
21 val itm_2str_ : Proof.context -> itm_ -> string
23 val itm2str_ : Proof.context -> itm -> string
24 val itms2str_ : Proof.context -> itm list -> string
27 val empty_ppc : item ppc
28 val ppc2str : {Find: string list, Given: string list, Relate: string list, Where: string list,
29 With: string list} -> string
30 val itemppc2str : item ppc -> string
33 val comp_dts : term * term list -> term
34 val comp_dts' : term * term list -> term
35 val comp_dts'' : term * term list -> string
36 val comp_ts : term * term list -> term
37 val split_dts : term -> term * term list
38 val split_dts' : term * term -> term list
39 val pbl_ids' : term -> term list -> term list
40 val mkval' : term list -> term
42 val d_in : itm_ -> term
43 val ts_in : itm_ -> term list
44 val penvval_in : itm_ -> term list
45 val mk_env : itm list -> (term * term) list (* close to Chead.all_dsc_in, Chead.is_error, etc *)
46 val vars_of : itm list -> term list
47 val max_vt : itm list -> int
49 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
51 val penv2str_ : Proof.context -> penv -> string (* NONE *)
53 val preoris2str : preori list -> string
54 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
56 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
58 (*----- unused code, kept as hints to design ideas ---------------------------------------------*)
59 val untouched : itm list -> bool
61 val upds_envv : Proof.context -> envv -> (vats * term * term * term) list -> envv
62 val item_ppc : string ppc -> item ppc
63 val all_ts_in : itm_ list -> term list
64 val pres2str : (bool * term) list -> string
67 structure Model(**) : MODEL(**) =
69 (*==========================================================================
70 23.3.02 TODO: ideas on redesign of type itm_,type item,type ori,type item ppc
72 (1.1) untouched: for modeling only dsc displayed(impossible after match_itms)
73 =(presently) Mis (? should be Inc initially, and Mis after match_itms?)
74 (1.2) Syn,Typ,Sup: not related to oris
75 Syn, Typ (presently) should be accepted in appl_add (instead Error')
76 Sup (presently) should be accepted in appl_add (instead Error')
77 _could_ be w.r.t current vat (and then _is_ related to vat
78 Mis should _not_ be made Inc ((presently, by appl_add & match_itms)
79 - dsc in itm_ is timeconsuming -- keep id for respective queries ?
80 - order of items in ppc should be stable w.r.t order of itms
82 - stepwise input of itms --- match_itms (in one go) ..not coordinated
84 - match_itms / match_itms_oris ..2 versions ?!
85 (fast, for refine / slow, for modeling)
87 - clarify: efficiency <--> simplicity !!!
88 ?: shift dsc itm_ -> itm | discard int in ori,itm | take int instead dsc
89 | take int for perserving order of item ppc in itms
90 | make all(!?) handling of itms stable against reordering(?)
91 | field in ori ?? (not from fmz!) -- meant for efficiency (not doc!???)
92 -"- "#undef" ?= not touched ?= (id,..)
93 -----------------------------------------------------------------
95 def: type pbt = (field, (dsc, pid)) *** design considerations ***
98 (2) input + oris -> itm
99 (3) match_itms : schnell(?) f"ur refine
100 match_itms_oris : r"uckmeldung f"ur item ppc
102 (1.1) in oris fehlt daher pid: (i,v,f,d,ts,pid)
103 ---------- ^^^^^ --- dh. pbt meist als argument zu viel !!!
105 (3.1) abwarten, wie das matchen mehr unterschiedlicher pbt's sich macht;
106 wenn Problem pbt v"ollig neue, dann w"are eigentlich n"otig ????:
107 (a) (_,_,d1,ts,_):ori + pbt -> (i,vt,d2,ts,pid) dh.vt neu ????
109 ==========================================================================*)
111 val script_parse = the o (@{theory ProgLang} |> ThyC.to_ctxt |> TermC.parseNEW);
112 val e_listReal = script_parse "[]::(real list)";
113 val e_listBool = script_parse "[]::(bool list)";
115 (* take list-term apart w.r.t. handling elementwise input: @{term "[a, b]"} \<rightarrow> ["[a]","[b]"] *)
117 let val elems = TermC.isalist2list t
118 in map ((TermC.list2isalist (type_of (hd elems))) o single) elems end;
119 fun take_apart_inv ts = (* t = (take_apart_inv o take_apart) t *)
120 let val elems = (flat o (map TermC.isalist2list)) ts;
121 in TermC.list2isalist (type_of (hd elems)) elems end;
123 fun is_var (Free _) = true
126 (* special handling for lists. ?WN:14.5.03 ??!? *)
127 fun dest_list (d, ts) =
129 if Input_Descript.is_list_dsc d andalso not (Input_Descript.is_unl d) andalso not (is_var t) (*..for pbt*)
130 then TermC.isalist2list t
132 in (flat o (map dest)) ts end;
134 (* revert split_dts only for ts; compare comp_dts *)
135 fun comp_ts (d, ts) =
136 if Input_Descript.is_list_dsc d
137 then if TermC.is_list (hd ts)
138 then if Input_Descript.is_unl d
139 then (hd ts) (* e.g. someList [1,3,2] *)
140 else (take_apart_inv ts) (* [ [a], [b] ] -> [a,b] *)
141 else (hd ts) (* a variable or metavariable for a list *)
143 fun comp_dts (d, []) =
144 if Input_Descript.is_reall_dsc d
145 then (d $ e_listReal)
146 else if Input_Descript.is_booll_dsc d then (d $ e_listBool) else d
147 | comp_dts (d, ts) = (d $ (comp_ts (d, ts)))
148 handle _ => error ("comp_dts: " ^ UnparseC.term d ^ " $ " ^ UnparseC.term (hd ts));
149 fun comp_dts' (d, []) =
150 if Input_Descript.is_reall_dsc d
151 then (d $ e_listReal)
152 else if Input_Descript.is_booll_dsc d then (d $ e_listBool) else d
153 | comp_dts' (d, ts) = (d $ (comp_ts (d, ts)))
154 handle _ => error ("comp_dts': " ^ UnparseC.term d ^ " $ " ^ UnparseC.term (hd ts));
155 fun comp_dts'' (d, []) =
156 if Input_Descript.is_reall_dsc d
157 then UnparseC.term (d $ e_listReal)
158 else if Input_Descript.is_booll_dsc d
159 then UnparseC.term (d $ e_listBool)
161 | comp_dts'' (d, ts) = UnparseC.term (d $ (comp_ts (d, ts)))
162 handle _ => error ("comp_dts'': " ^ UnparseC.term d ^ " $ " ^ UnparseC.term (hd ts));
164 (* decompose an input into description, terms (ev. elems of lists),
165 and the value for the problem-environment; inv to comp_dts *)
166 fun split_dts (t as d $ arg) =
167 if Input_Descript.is_dsc d
168 then if Input_Descript.is_list_dsc d andalso TermC.is_list arg andalso Input_Descript.is_unl d |> not
169 then (d, take_apart arg)
171 else (TermC.empty, TermC.dest_list' t)
173 let val t' as (h, _) = strip_comb t;
175 if Input_Descript.is_dsc h
176 then (h, dest_list t')
177 else (TermC.empty, TermC.dest_list' t)
179 (* version returning ts only *)
180 fun split_dts' (d, arg) =
181 if Input_Descript.is_dsc d
182 then if Input_Descript.is_list_dsc d
183 then if TermC.is_list arg
184 then if Input_Descript.is_unl d
185 then ([arg]) (* e.g. someList [1,3,2] *)
186 else (take_apart arg) (* [a,b] --> SML[ [a], [b] ]SML *)
187 else ([arg]) (* a variable or metavariable for a list *)
189 else (TermC.dest_list' arg)
190 (* WN170204: Warning "redundant"
191 | split_dts' (d, t) = (*either dsc or term; 14.5.03 only copied*)
192 let val (h,argl) = strip_comb t
196 else (dest_list (h,argl))
199 WN050903 we do NOT know which is from subtheory, description or term;
200 typecheck thus may lead to TYPE-error 'unknown constant';
201 solution: typecheck with (Thy_Info_get_theory "Isac_Knowledge"); i.e. arg 'thy' superfluous*)
202 (*fun comp_dts thy (d,[]) =
203 Thm.global_cterm_of (*(sign_of o assoc_thy) "Isac_Knowledge"*)
204 (Thy_Info_get_theory "Isac_Knowledge")
205 (*comp_dts:FIXXME stay with term for efficiency !!!*)
206 (if is_reall_dsc d then (d $ e_listReal)
207 else if is_booll_dsc d then (d $ e_listBool)
210 (Thm.global_cterm_of (*(sign_of o assoc_thy) "Isac_Knowledge"*)
211 (Thy_Info_get_theory "Isac_Knowledge")
212 (*comp_dts:FIXXME stay with term for efficiency !!*)
213 (d $ (comp_ts (d, ts)))
214 handle _ => error ("comp_dts: "^(term2str d)^
215 " $ "^(term2str (hd ts))));*)
217 (* 27.8.01: problem-environment
218 WN.6.5.03: FIXXME reconsider if penv is worth the effort --
219 -- just rerun a whole expl with num/var may show the same ?!
220 WN.9.5.03: penv-concept stalled, immediately generate script env !
221 but [#0, epsilon] only outcommented for eventual reconsideration *)
222 type penv = (* problem-environment *)
224 * (term list) (* [#0, epsilon] 9.5.03 outcommented *)
226 fun pen2str ctxt (t, ts) =
227 pair2str (UnparseC.term_in_ctxt ctxt t, (strs2str' o map (UnparseC.term_in_ctxt ctxt)) ts);
228 fun penv2str_ thy penv = (strs2str' o (map (pen2str thy))) penv;
230 (* get the constant value from a penv *)
231 fun getval (id, values) =
233 [] => error ("penv_value: no values in '" ^ UnparseC.term id)
235 | (v1 :: v2 :: _) => (case v1 of
236 Const ("Program.Arbfix",_) => (id, v2)
239 (* 9.5.03: still unused, but left for eventual future development *)
240 type envv = (int * penv) list; (* over variants *)
242 (* 14.9.01: not used after putting penv-values into itm_
243 make the result of split_* a value of problem-environment *)
244 fun mkval _(*dsc*) [] = error "mkval called with []"
246 | mkval _ ts = TermC.list2isalist ((type_of o hd) ts) ts;
247 fun mkval' x = mkval TermC.empty x;
249 (* the internal representation of a models' item
250 4.9.01: not consistent:
251 after Init_Proof 'Inc', but after copy_probl 'Mis' - for same situation
252 (involves 'is_error');
253 bool in itm really necessary ???*)
255 Cor of (term * (* description *)
256 (term list)) * (* for list: elem-wise input *)
257 (term * (term list)) (* elem of penv ---- penv delayed to future *)
258 | Syn of TermC.as_string
259 | Typ of TermC.as_string
260 | Inc of (term * (term list)) * (term * (term list)) (*lists,
261 + init_pbl WN.11.03 FIXXME: empty penv .. bad; init_pbl should return Mis !!! *)
262 | Sup of (term * (term list)) (* user-input not found in pbt(+?oris?11.03)*)
263 | Mis of (term * term) (* after re-specification pbt-item not found in pbl: only dsc, pid_*)
264 | Par of TermC.as_string; (* internal state from fun parsitm *)
266 type vats = int list; (* variants in formalizations *)
268 (* data-type for working on pbl/met-ppc:
269 in pbl initially holds descriptions (only) for user guidance *)
271 int * (* id =0 .. untouched - descript (only) from init
272 seems to correspond to ori (fun insert_ppc) <> maintain order in item ppc? *)
273 vats * (* variants - copy from ori *)
274 bool * (* input on this item is not/complete *)
275 string * (* #Given | #Find | #Relate *)
277 val e_itm = (0, [], false, "e_itm", Syn "e_itm");
279 (* in CalcTree/Subproblem an 'untouched' model is created
280 FIXME.WN.9.03 model should be filled to 'untouched' by Model/Refine_Problem*)
281 fun untouched itms = foldl and_ (true , map ((curry op = 0) o (#1 : itm -> int)) itms);
283 (* find most frequent variant v in itms *)
284 fun vts_in itms = (distinct o flat o (map #2)) (itms:itm list);
286 fun cnt itms v = (v, (length o (filter (curry op = v)) o flat o (map #2)) itms);
287 fun vts_cnt vts itms = map (cnt itms) vts;
288 fun max2 [] = error "max2 of []"
291 fun mx (a,x) [] = (a,x)
292 | mx (a, x) ((b,y) :: ys) = if x < y then mx (b, y) ys else mx (a, x) ys;
295 (* find the variant with most items already input *)
297 let val vts = (vts_cnt (vts_in itms)) itms;
298 in if vts = [] then 0 else (fst o max2) vts end;
300 (* TODO ev. make more efficient by avoiding flat *)
301 fun mk_e (Cor (_, iv)) = [getval iv]
304 | mk_e (Inc (_, iv)) = [getval iv]
307 | mk_e _ = error "mk_e: uncovered case in fun.def.";
308 fun mk_en vt (_, vts, _, _, itm_) = if member op = vts vt then mk_e itm_ else [];
310 (* extract the environment from an item list; takes the variant with most items *)
312 let val vt = max_vt itms
313 in (flat o (map (mk_en vt))) itms end;
315 (* example as provided by an author, complete w.r.t. pbt specified
316 not touched by any user action *)
318 (int * (* id: 10.3.00ff impl. only <>0 .. touched
319 21.3.02: insert_ppc needs it ! ?:purpose maintain order in item ppc ??? *)
320 vats * (* variants 21.3.02: related to pbt..discard ? *)
321 string * (* #Given | #Find | #Relate 21.3.02: discard ? *)
322 term * (* description *)
323 term list (* isalist2list t | [t] *)
325 val e_ori = (0, [], "", TermC.empty, [TermC.empty]) : ori;
327 fun ori2str (i, vs, fi, t, ts) =
328 "(" ^ string_of_int i ^ ", " ^ (strs2str o (map string_of_int)) vs ^ ", " ^ fi ^ "," ^
329 UnparseC.term t ^ ", " ^ (strs2str o (map UnparseC.term)) ts ^ ")";
330 val oris2str = strs2str' o (map (linefeed o ori2str));
332 (* an or without leading integer *)
333 type preori = (vats * string * term * term list);
334 fun preori2str (vs, fi, t, ts) =
335 "(" ^ (strs2str o (map string_of_int)) vs ^ ", " ^ fi ^ ", " ^
336 UnparseC.term t ^ ", " ^ (strs2str o (map UnparseC.term)) ts ^ ")";
337 val preoris2str = (strs2str' o (map (linefeed o preori2str)));
339 (* 9.5.03 penv postponed: pbl_ids' *)
340 fun pbl_ids' d vs = [comp_ts (d, vs)];
342 (* 14.9.01: not used after putting values for penv into itm_
343 WN.5.5.03: used in upd .. upd_envv *)
344 fun upd_penv ctxt penv dsc (id, vl) =
345 ((*tracing"### upd_penv used !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
346 tracing"### upd_penv used !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
347 tracing"### upd_penv used !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";*)
348 overwrite (penv, (id, Input_Descript.pbl_ids ctxt dsc vl))
351 (* WN.9.5.03: not reconsidered; looks strange !!!*)
352 fun upd thy envv dsc (id, vl) i =
353 let val penv = case assoc (envv, i) of
356 val penv' = upd_penv thy penv dsc (id, vl);
359 (* 14.9.01: not used after putting pre-penv into itm_*)
360 fun upd_envv thy envv vats dsc id vl =
361 let val vats = if length vats = 0
362 then (*unknown id to _all_ variants*)
363 if length envv = 0 then [1]
364 else (intsto o length) envv
366 fun isin vats (i, _) = member op = vats i;
367 val envs_notin_vat = filter_out (isin vats) envv;
368 in (map (upd thy envv dsc (id, vl)) vats) @ envs_notin_vat end;
370 (* update envv by folding from a list of arguments *)
371 fun upds_envv _ envv [] = envv
372 | upds_envv thy envv ((vs, dsc, id, vl) :: ps) =
373 upds_envv thy (upd_envv thy envv vs dsc id vl) ps;
375 (* for _output_ of the items of a Model *)
377 Correct of TermC.as_string (* labels a correct formula (type cterm') *)
378 | SyntaxE of string (**)
379 | TypeE of string (**)
380 | False of TermC.as_string (* WN050618 notexistent in itm_: only used in Where *)
381 | Incompl of TermC.as_string (**)
382 | Superfl of string (**)
383 | Missing of TermC.as_string;
384 fun item2str (Correct s) ="Correct " ^ s
385 | item2str (SyntaxE s) ="SyntaxE " ^ s
386 | item2str (TypeE s) ="TypeE " ^ s
387 | item2str (False s) ="False " ^ s
388 | item2str (Incompl s) ="Incompl " ^ s
389 | item2str (Superfl s) ="Superfl " ^ s
390 | item2str (Missing s) ="Missing " ^ s;
391 (*make string for error-msgs*)
392 fun itm_2str_ ctxt (Cor ((d, ts), penv)) =
393 "Cor " ^ UnparseC.term_in_ctxt ctxt (comp_dts (d, ts)) ^ " ," ^ pen2str ctxt penv
394 | itm_2str_ _ (Syn c) = "Syn " ^ c
395 | itm_2str_ _ (Typ c) = "Typ " ^ c
396 | itm_2str_ ctxt (Inc ((d, ts), penv)) =
397 "Inc " ^ UnparseC.term_in_ctxt ctxt (comp_dts (d, ts)) ^ " ," ^ pen2str ctxt penv
398 | itm_2str_ ctxt (Sup (d, ts)) =
399 "Sup " ^ UnparseC.term_in_ctxt ctxt (comp_dts (d, ts))
400 | itm_2str_ ctxt (Mis (d, pid)) =
401 "Mis "^ UnparseC.term_in_ctxt ctxt d ^ " " ^ UnparseC.term_in_ctxt ctxt pid
402 | itm_2str_ _ (Par s) = "Trm "^s;
403 fun itm_2str t = itm_2str_ (ThyC.id_to_ctxt "Isac_Knowledge") t;
404 fun itm2str_ ctxt ((i, is, b, s, itm_):itm) =
405 "(" ^ string_of_int i ^ " ," ^ ints2str' is ^ " ," ^ bool2str b ^ " ," ^
406 s ^ " ," ^ itm_2str_ ctxt itm_ ^ ")";
407 fun itms2str_ ctxt itms = strs2str' (map (linefeed o (itm2str_ ctxt)) itms);
408 fun init_item str = SyntaxE str;
411 {Given : 'a list, Where: 'a list, Find : 'a list, With : 'a list, Relate: 'a list};
412 fun ppc2str {Given = Given, Where = Where, Find = Find, With = With, Relate = Relate}=
413 "{Given =" ^ strs2str Given ^ ",Where=" ^ strs2str Where ^ ",Find =" ^ strs2str Find ^
414 ",With =" ^ strs2str With ^ ",Relate=" ^ strs2str Relate ^ "}";
416 fun item_ppc {Given = gi, Where= wh, Find = fi, With = wi, Relate= re} =
417 {Given = map init_item gi, Where= map init_item wh, Find = map init_item fi,
418 With = map init_item wi, Relate= map init_item re};
419 fun itemppc2str ({Given=Given,Where=Where,
420 Find=Find,With=With,Relate=Relate}:item ppc)=
421 ("{Given =" ^ ((strs2str' o (map item2str)) Given ) ^
422 ",Where=" ^ ((strs2str' o (map item2str)) Where) ^
423 ",Find =" ^ ((strs2str' o (map item2str)) Find ) ^
424 ",With =" ^ ((strs2str' o (map item2str)) With ) ^
425 ",Relate=" ^ ((strs2str' o (map item2str)) Relate) ^ "}");
427 val empty_ppc = {Given = [], Where= [], Find = [], With = [], Relate= []};
429 fun ts_in (Cor ((_, ts), _)) = ts
432 | ts_in (Inc ((_, ts), _)) = ts
433 | ts_in (Sup (_, ts)) = ts
435 | ts_in _ = error "ts_in: uncovered case in fun.def.";
437 fun all_ts_in itm_s = (flat o (map ts_in)) itm_s;
438 val unique = (Thm.term_of o the o (TermC.parse @{theory "Real"} )) "UnIqE_tErM";
439 fun d_in (Cor ((d ,_), _)) = d
440 | d_in (Syn c) = ((*tracing ("*** d_in: Syn ("^c^")");*) unique)
441 | d_in (Typ c) = ((*tracing ("*** d_in: Typ ("^c^")");*) unique)
442 | d_in (Inc ((d, _), _)) = d
443 | d_in (Sup (d, _)) = d
444 | d_in (Mis (d, _)) = d
445 | d_in _ = raise ERROR "d_in: uncovered case in fun.def.";
447 fun dts2str (d, ts) = pair2str (UnparseC.term d, UnparseC.terms ts);
448 fun penvval_in (Cor ((d, _), (_, ts))) = [comp_ts (d,ts)]
449 | penvval_in (Syn (c)) = ((*tracing("*** penvval_in: Syn ("^c^")");*) [])
450 | penvval_in (Typ (c)) = ((*tracing("*** penvval_in: Typ ("^c^")");*) [])
451 | penvval_in (Inc (_, (_, ts))) = ts
452 | penvval_in (Sup dts) = ((*tracing ("*** penvval_in: Sup " ^ dts2str dts);*) [])
453 | penvval_in (Mis (d, t)) = ((*tracing ("*** penvval_in: Mis " ^
454 pair2str(UnparseC.term d, UnparseC.term t));*) [])
455 | penvval_in _ = error "penvval_in: uncovered case in fun.def.";
457 (* check a predicate labelled with indication of incomplete substitution;
458 rls -> (* for eval_true *)
459 bool * (* have _all_ variables(Free) from the model-pattern
460 been substituted by a value from the pattern's environment ?*)
461 term -> (* the precondition *)
462 bool * (* has the precondition evaluated to true *)
463 term (* the precondition (for map) *)
465 fun pre2str (b, t) = pair2str(bool2str b, UnparseC.term t);
466 fun pres2str pres = strs2str' (map (linefeed o pre2str) pres);
468 fun vars_of itms = itms |> mk_env |> map snd