src/Tools/isac/Specify/i-model.sml
author wneuper <Walther.Neuper@jku.at>
Mon, 18 Sep 2023 08:38:33 +0200
changeset 60747 2eff296ab809
parent 60746 3ba85d40b3c7
child 60748 d9bae125ba2a
permissions -rw-r--r--
prepare 3: shift new code
     1 (* Title:  Specify/i-model.sml
     2    Author: Walther Neuper 110226
     3    (c) due to copyright terms
     4 
     5 \<open>I_Model\<close> serves students' interactive modelling and gives feedback in the specify-phase.
     6 *)
     7 
     8 signature INTERACTION_MODEL =
     9 sig
    10 
    11   type T
    12   type T_TEST
    13   val OLD_to_TEST: T -> T_TEST
    14   val TEST_to_OLD: T_TEST -> T
    15   val empty: T
    16   val empty_TEST: T_TEST
    17 
    18   type single
    19   type single_TEST
    20   val empty_single: single
    21   val empty_single_TEST: single_TEST
    22   val is_empty_single_TEST: single_TEST -> bool
    23 
    24   type variant
    25   type variants
    26   type m_field
    27   type descriptor
    28 
    29   datatype feedback = datatype Model_Def.i_model_feedback
    30   datatype feedback_TEST = datatype Model_Def.i_model_feedback_TEST
    31   val feedback_empty_TEST: Model_Def.i_model_feedback_TEST
    32 
    33   type env
    34   type message
    35 
    36   val single_to_string: Proof.context -> single -> string
    37   val single_to_string_TEST: Proof.context -> single_TEST -> string
    38   val to_string: Proof.context -> T -> string
    39   val to_string_TEST: Proof.context -> T_TEST -> string
    40   val feedback_OLD_to_TEST: feedback -> feedback_TEST
    41 
    42   datatype add_single = Add of single | Err of string
    43   val init: Model_Pattern.T -> T
    44   val init_TEST: O_Model.T -> Model_Pattern.T -> T_TEST
    45   val check_single: Proof.context -> m_field -> O_Model.T -> T -> Model_Pattern.T ->
    46     TermC.as_string -> add_single
    47   val add_single: theory -> single -> T -> T
    48 
    49   val make_tactic: m_field -> TermC.as_string * T -> Tactic.T
    50   val descriptor: feedback -> descriptor
    51   val descriptor_TEST: feedback_TEST -> descriptor
    52   val descr_pairs_to_string: Proof.context -> (Model_Pattern.single * single_TEST) list -> string
    53   val o_model_values: feedback -> O_Model.values
    54   val variables: Model_Pattern.T -> Model_Def.i_model_TEST -> term list
    55   val is_notyet_input : Proof.context -> T -> O_Model.values -> O_Model.single -> Model_Pattern.T
    56     -> message * single
    57   val get_field_term: theory -> O_Model.single -> single -> m_field * TermC.as_string
    58 
    59   val of_max_variant: Model_Pattern.T -> T_TEST ->
    60     (bool * Model_Def.variant * T_TEST) * Env.T * (Pre_Conds.env_subst * Pre_Conds.env_eval)
    61 
    62 (*REN make_complete*)
    63   val complete: O_Model.T -> (*Problem*)T -> (*MethodC*)T -> Model_Pattern.T -> T
    64   val add: single -> T -> T
    65   val complete_method: O_Model.T * Model_Pattern.T * Model_Pattern.T * T -> T * T
    66 
    67 
    68 
    69   val is_error: feedback -> bool
    70 (*REN complete_internal*)
    71   val complete': Model_Pattern.T -> O_Model.single -> single
    72 
    73   val fill_method: O_Model.T -> T_TEST -> Model_Pattern.T -> T_TEST
    74 
    75   val is_complete: T -> bool
    76   val is_complete_variant: Model_Def.variant -> T_TEST-> bool
    77   val to_p_model: theory -> feedback -> string
    78 
    79 (*from isac_test for Minisubpbl*)
    80   val eq1: ''a -> 'b * (''a * 'c) -> bool
    81   val filter_outs: O_Model.T -> T -> O_Model.T
    82   val filter_outs_TEST: O_Model.T -> T_TEST -> O_Model.T
    83   val feedback_to_string: Proof.context -> feedback -> string
    84   val feedback_TEST_to_string: Proof.context -> feedback_TEST -> string
    85 
    86   val ori_2itm: feedback -> term -> term list -> 'a * 'b * string * descriptor * term list -> 
    87     'a * 'b * bool * string * feedback
    88   val seek_ppc: int -> T -> single option
    89   val overwrite_ppc: theory -> single -> T -> T
    90 
    91 \<^isac_test>\<open>
    92   (**)
    93 
    94 \<close>
    95 
    96 end
    97 
    98 (**)
    99 structure I_Model(**) : INTERACTION_MODEL(**) =
   100 struct
   101 (**)
   102 
   103 (** data types **)
   104 
   105 type variant =  Model_Def.variant;
   106 type variants =  Model_Def.variants;
   107 type m_field = Model_Def.m_field;
   108 type descriptor = Model_Def.descriptor;
   109 
   110 type T = Model_Def.i_model_single list;
   111 (* for developing input from PIDE, we use T_TEST with these ideas:
   112   (1) the new structure is as close to old T, because we want to preserve the old tests
   113   (2) after development (with *_TEST) of essential parts of the Specification's semantics,
   114       we adapt the old tests to the new T_TEST
   115   (3) together with adaption of the tests we remove the *_TEST
   116 *)
   117 type T_TEST = Model_Def.i_model_single_TEST list;
   118 datatype feedback = datatype Model_Def.i_model_feedback;
   119 datatype feedback_TEST = datatype Model_Def.i_model_feedback_TEST;
   120 val feedback_empty_TEST = Model_Def.feedback_empty_TEST
   121 type single = Model_Def.i_model_single;
   122 type single_TEST = Model_Def.i_model_single_TEST;
   123 val empty_single = Model_Def.i_model_empty;
   124 val empty_single_TEST = Model_Def.i_model_empty_TEST;
   125 fun is_empty_single_TEST (0, [], false, "i_model_empty", _) = true
   126   | is_empty_single_TEST _ = false
   127 
   128 val empty = []: T;
   129 val empty_TEST = []: T_TEST;
   130 
   131 type env = Env.T
   132 
   133 
   134 fun feedback_OLD_to_TEST (Cor ((d, ts), penv)) = (Model_Def.Cor_TEST ((d, ts), penv)) 
   135   | feedback_OLD_to_TEST (Syn c) = (Model_Def.Syn_TEST c)
   136   | feedback_OLD_to_TEST (Typ c) = (Model_Def.Syn_TEST c)
   137   | feedback_OLD_to_TEST (Inc ((d, ts), penv)) = (Model_Def.Inc_TEST ((d, ts), penv))
   138   | feedback_OLD_to_TEST (Sup (d, ts)) = (Model_Def.Sup_TEST (d, ts))
   139   | feedback_OLD_to_TEST (Mis (d, pid)) = Model_Def.Syn_TEST ((UnparseC.term (ContextC.for_ERROR ()) d) ^ " " ^
   140       (UnparseC.term (ContextC.for_ERROR ()) pid))
   141   | feedback_OLD_to_TEST (Par s) = (Model_Def.Syn_TEST s)
   142 fun OLD_to_TEST i_old =
   143   map (fn (a, b, c, d, e) => (a, b, c, d, (feedback_OLD_to_TEST e, Position.none))) i_old
   144 
   145 fun feedback_TEST_to_OLD (Model_Def.Cor_TEST ((d, ts), penv)) = (Cor ((d, ts), penv))
   146   | feedback_TEST_to_OLD (Model_Def.Syn_TEST c) = (Syn c)
   147   | feedback_TEST_to_OLD (Model_Def.Inc_TEST ((d, ts), penv)) = (Inc ((d, ts), penv))
   148   | feedback_TEST_to_OLD (Model_Def.Sup_TEST (d, ts)) = (Sup (d, ts))
   149 fun TEST_to_OLD i_model = 
   150   map (fn (a, b, c, d, (e, _)) => (a, b, c, d, feedback_TEST_to_OLD e)) i_model
   151 
   152 type message = string;
   153 
   154 fun feedback_to_string ctxt (Cor ((d, ts), _)) = 
   155     "Cor " ^ UnparseC.term  ctxt (Input_Descript.join (d, ts)) ^ " , pen2str"
   156   | feedback_to_string _ (Syn c) = "Syn " ^ c
   157   | feedback_to_string _ (Typ c) = "Typ " ^ c
   158   | feedback_to_string ctxt (Inc ((d, ts), _)) = 
   159     "Inc " ^ UnparseC.term  ctxt (Input_Descript.join (d, ts)) ^ " , pen2str"
   160   | feedback_to_string ctxt (Sup (d, ts)) = 
   161     "Sup " ^ UnparseC.term  ctxt (Input_Descript.join (d, ts))
   162   | feedback_to_string ctxt (Mis (d, pid)) = 
   163     "Mis " ^ UnparseC.term  ctxt d ^ " " ^ UnparseC.term ctxt pid
   164   | feedback_to_string _ (Par s) = "Trm "^s;
   165 
   166 (**)
   167 fun feedback_TEST_to_string ctxt (Cor_TEST ((d, ts), _)) = 
   168     "Cor_TEST " ^ UnparseC.term ctxt (Input_Descript.join (d, ts)) ^ " , pen2str"
   169   | feedback_TEST_to_string _ (Syn_TEST c) =
   170     "Syn_TEST " ^ c
   171   | feedback_TEST_to_string ctxt (Inc_TEST ((d, []), _)) = 
   172     "Inc_TEST " ^ UnparseC.term ctxt (Input_Descript.join (d, [])) ^ " " ^ 
   173       Model_Pattern.empty_for d
   174   | feedback_TEST_to_string ctxt (Inc_TEST ((d, ts), _)) =
   175     "Inc_TEST " ^ UnparseC.term ctxt (Input_Descript.join (d, ts)) ^ " , pen2str"
   176   | feedback_TEST_to_string ctxt (Sup_TEST (d, ts)) = 
   177     "Sup_TEST " ^ UnparseC.term ctxt (Input_Descript.join (d, ts))
   178 
   179 fun single_to_string ctxt (i, is, b, s, itm_) = 
   180   "(" ^ string_of_int i ^ " ," ^ ints2str' is ^ " ," ^ bool2str b ^ " ," ^
   181   s ^ " ," ^ feedback_to_string ctxt itm_ ^ ")";
   182 fun single_to_string_TEST ctxt (i, is, b, s, (itm_, _(*Position.T*))) = 
   183   "(" ^ string_of_int i ^ ", " ^ ints2str' is ^ ", " ^ bool2str b ^ " ," ^
   184   s ^ ", (" ^ feedback_TEST_to_string ctxt itm_ ^ ", Position.T))";
   185 
   186 fun to_string ctxt itms = strs2str' (map (linefeed o (single_to_string ctxt)) itms);
   187 fun to_string_TEST ctxt itms = strs2str' (map (linefeed o (single_to_string_TEST ctxt)) itms);
   188 
   189 
   190 (** make a Tactic.T **)
   191 
   192 fun make_tactic m_field (term_as_string, i_model) =
   193   case m_field of
   194     "#Given" => Tactic.Add_Given' (term_as_string, i_model)
   195   | "#Find" => Tactic.Add_Find' (term_as_string, i_model)
   196   | "#Relate" => Tactic.Add_Relation'(term_as_string, i_model)
   197   | str => raise ERROR ("specify_additem Frm, Pbl: uncovered case with " ^ str);
   198 
   199 
   200 (** initialise a model **)
   201 
   202 fun init pbt = 
   203   let
   204     fun pbt2itm (f, (d, _)) = (0, [], false, f, Inc ((d, []), (TermC.empty, [])))
   205   in map pbt2itm pbt end
   206 
   207 (*
   208   Design decision:
   209 * Now the Model in Specification is intialised such that the placement of items can be
   210   maximally stable during interactive input to the Specification.
   211 * Template.show provides the initial output to the user and thus determines what will be parsed
   212   by Outer_Syntax later during interaction.
   213 * The relation between O_Model.T and I_Model.T becomes much simpler.
   214 *)
   215 (**)
   216 fun pat_to_item o_model (_, (descriptor, _)) =
   217   case find_first (fn (_, _, _, desc, _) => desc = descriptor) o_model of
   218     NONE => raise ERROR "I_Model.pat_to_item_TEST with NONE"
   219   | SOME (_, variants, m_field, descr, _) => (variants, false, m_field,
   220     (Inc_TEST ((descr, []), (descr, [])), Position.none))
   221 fun init_TEST o_model model_patt =
   222   let
   223     val pre_items = map (pat_to_item o_model) model_patt
   224   in
   225     O_Model.add_enumerate pre_items |> map (fn (a, (b, c, d, e)) => (a, b, c, d, e))
   226   end
   227 
   228 (*/---------------- old code -----------------------------------------------------------------\*)
   229 fun o_model_values (Cor ((_, ts), _)) = ts
   230   | o_model_values (Syn _) = []
   231   | o_model_values (Typ _) = []
   232   | o_model_values (Inc ((_, ts), _)) = ts
   233   | o_model_values (Sup (_, ts)) = ts
   234   | o_model_values (Mis _) = []
   235   | o_model_values _ = raise ERROR "o_model_values: uncovered case in fun.def.";
   236 
   237 val unique = Syntax.read_term\<^context> "UnIqE_tErM";
   238 fun descriptor (Cor ((d ,_), _)) = d
   239   | descriptor (Syn _) = ((*tracing ("*** descriptor: Syn ("^c^")");*) unique)
   240   | descriptor (Typ _) = ((*tracing ("*** descriptor: Typ ("^c^")");*) unique)
   241   | descriptor (Inc ((d, _), _)) = d
   242   | descriptor (Sup (d, _)) = d
   243   | descriptor (Mis (d, _)) = d
   244   | descriptor _ = raise ERROR "descriptor: uncovered case in fun.def.";
   245 fun descriptor_TEST (Cor_TEST ((d ,_), _)) = d
   246   | descriptor_TEST (Syn_TEST _) = ((*tracing ("*** descriptor: Syn ("^c^")");*) unique)
   247   | descriptor_TEST (Inc_TEST ((d, _), _)) = d
   248   | descriptor_TEST (Sup_TEST (d, _)) = d
   249 
   250 fun descr_pairs_to_string ctxt equal_descr_pairs =
   251 (map (fn (a, b) => pair (Model_Pattern.pat2str ctxt a) (single_to_string_TEST ctxt b)
   252     |> pair2str) equal_descr_pairs)
   253   |> strs2str'
   254 
   255 fun variables model_patt i_model =
   256   Pre_Conds.environment_TEST model_patt i_model
   257   |> map snd
   258 
   259 val unknown_descriptor = Syntax.read_term\<^context> "unknown::'a => unknow";
   260 
   261 (* get a term from O_Model, notyet input in I_Model.
   262    the term from O_Model is thrown back to a string in order to reuse
   263    machinery for immediate input by the user. *)
   264 fun get_field_term thy (_, _, _, d, ts) (_, _, _, fd, itm_) =
   265   (fd, ((UnparseC.term_in_thy thy) o Input_Descript.join) (d, subtract op = (o_model_values itm_) ts))
   266 
   267 (*update the itm_ already input, all..from ori*)
   268 fun ori_2itm itm_ pid all (id, vt, fd, d, ts) = 
   269   let 
   270     val ts' = union op = (o_model_values itm_) ts;
   271     val pval = [Input_Descript.join'''' (d, ts')]
   272 	  (*WN.9.5.03: FIXXXME [#0, epsilon] here would upd_penv be called for [#0, epsilon] etc*)
   273     val complete = if eq_set op = (ts', all) then true else false
   274   in
   275     case itm_ of
   276       (Cor _) => 
   277         (if fd = "#undef" then (id, vt, complete, fd, Sup (d, ts')) 
   278 	       else (id, vt, complete, fd, Cor ((d, ts'), (pid, pval))))
   279     | (Syn c) => raise ERROR ("ori_2itm wants to overwrite " ^ c)
   280     | (Typ c) => raise ERROR ("ori_2itm wants to overwrite " ^ c)
   281     | (Inc _) =>
   282       if complete
   283   	  then (id, vt, true, fd, Cor ((d, ts'), (pid, pval)))
   284   	  else (id, vt, false, fd, Inc ((d, ts'), (pid, pval)))
   285     | (Sup (d,ts')) => (*4.9.01 lost env*)
   286   	  (*if fd = "#undef" then*) (id,vt,complete,fd,Sup(d,ts'))
   287   	  (*else (id,vt,complete,fd,Cor((d,ts'),e))*)
   288       (* 28.1.00: not completely clear ---^^^ etc.*)
   289     | (Mis _) => (* 4.9.01: Mis just copied *)
   290        if complete
   291   		 then (id, vt, true, fd, Cor ((d,ts'), (pid, pval)))
   292   		 else (id, vt, false, fd, Inc ((d,ts'), (pid, pval)))
   293     | i => raise ERROR ("ori_2itm: uncovered case of " ^ feedback_to_string (ContextC.for_ERROR ()) i)
   294   end
   295 
   296 
   297 (** find next step **)
   298 
   299 fun eq1 d (_, (d', _)) = (d = d')
   300 fun eq3 f d (_, _, _, f', itm_) = f = f' andalso d = (descriptor itm_) 
   301 
   302 fun is_notyet_input ctxt itms all (i, v, f, d, ts) pbt =
   303   case find_first (eq1 d) pbt of
   304     SOME (_, (_, pid)) =>
   305       (case find_first (eq3 f d) itms of
   306         SOME (_, _, _, _, itm_) =>
   307           let val ts' = inter op = (o_model_values itm_) ts
   308           in 
   309             if subset op = (ts, ts') 
   310             then (((strs2str' o map (UnparseC.term ctxt)) ts') ^ " already input", empty_single)
   311 	          else ("", ori_2itm itm_ pid all (i, v, f, d, subtract op = ts' ts))
   312 	          end
   313 	    | NONE => ("", ori_2itm (Inc ((TermC.empty, []), (pid, []))) pid all (i, v, f, d, ts)))
   314   | NONE => ("", ori_2itm (Sup (d, ts)) TermC.empty all (i, v, f, d, ts))
   315 
   316 datatype add_single =
   317 	Add of single   (* return-value of check_single *)
   318 | Err of string   (* error-message                *)
   319 
   320 (*
   321   Create feedback for input of TermC.as_string to m_field;
   322   check w.r.t. O_Model.T and Model_Pattern.T.
   323   In case of O_Model.T = [] (i.e. no data for user-guidance in Formalise.T)
   324   check_single is extremely permissive.
   325 *)
   326 (*will come directly from PIDE -----------------vvvvvvvvvvv
   327   in case t comes from Step.specify_do_next -----------vvv = Position.none*)
   328 fun check_single ctxt m_field [] i_model m_patt (ct(*, pos*)) =
   329     let
   330       val i = 1 + (if i_model = [] then 0 else map #1 i_model |> maxl)
   331     (*/------------ replace by ParseC.term_position -----------\*)
   332       val t = Syntax.read_term ctxt ct
   333         handle ERROR msg => error (msg (*^ Position.here pos*))
   334     (*\------------ replace by ParseC.term_position -----------/*)
   335         (*NONE => Add (i, [], false, m_field, Syn ct)*)
   336       val (d, ts) = Input_Descript.split t
   337     in 
   338       if d = TermC.empty then
   339         Add (i, [], false, m_field, Mis (unknown_descriptor, hd ts)) 
   340       else
   341         (case find_first (eq1 d) m_patt of
   342           NONE => Add (i, [], true, m_field, Sup (d,ts))
   343         | SOME (f, (_, id)) =>
   344             let
   345               fun eq2 d (i, _, _, _, itm_) = d = (descriptor itm_) andalso i <> 0
   346             in
   347               case find_first (eq2 d) i_model of
   348                 NONE => Add (i, [], true, f,Cor ((d, ts), (id, [Input_Descript.join'''' (d, ts)])))
   349               | SOME (i', _, _, _, itm_) => 
   350                   if Input_Descript.for_list d then 
   351                     let
   352                       val in_itm = o_model_values itm_
   353                       val ts' = union op = ts in_itm
   354                       val i'' = if in_itm = [] then i else i'
   355                     in Add (i'', [], true, f, Cor ((d, ts'), (id, [Input_Descript.join'''' (d, ts')])))end
   356                   else Add (i', [], true, f, Cor ((d, ts), (id, [Input_Descript.join'''' (d, ts)])))
   357             end)
   358     end
   359     (*for MethodC:   #undef  completed vvvvv vvvvvv term_as_string*)
   360     (*will come directly from PIDE ----------------------vvvvvvvvvvv*)
   361   | check_single ctxt m_field o_model i_model m_patt (str(*, pos*)) =
   362     let
   363       val (t as (descriptor $ _)) = Syntax.read_term ctxt str
   364         handle ERROR msg => error (msg (*TODO: ^ Position.here pp*))
   365         (*old code: NONE => Err ("ERROR I_Model.check_single: syntax error in \"" ^ str ^ "\"")*)
   366     in 
   367         case Model_Pattern.get_field descriptor m_patt of
   368           NONE => Err ("ERROR I_Model.check_single: unknown descriptor \"" ^
   369             UnparseC.term ctxt descriptor ^ "\"")
   370         | SOME m_field' => 
   371           if m_field <> m_field' then
   372             Err ("ERROR I_Model.check_single: \"" ^ UnparseC.term ctxt t ^ "\"" ^
   373              "\" not for field \"" ^ m_field ^ "\"")
   374           else
   375             case O_Model.contains ctxt m_field o_model t of
   376               ("", ori', all) => 
   377                 (case is_notyet_input ctxt i_model all ori' m_patt of
   378                    ("", itm) => Add itm
   379                  | (msg, _) => Err ("ERROR I_Model.check_single: is_notyet_input: " ^ msg))
   380             | (msg, _, _) => Err ("ERROR I_Model.check_single: contains: " ^ msg)
   381     end
   382      
   383 
   384 (** add input **)
   385 
   386 fun overwrite_ppc thy itm model =
   387   let 
   388     fun repl _ (_, _, _, _, itm_) [] =
   389         raise ERROR ("overwrite_ppc: " ^ feedback_to_string (Proof_Context.init_global thy) itm_
   390           ^ " not found")
   391       | repl model' itm (p :: model) =
   392 	      if (#1 itm) = (#1 p)
   393 	      then model' @ [itm] @ model
   394 	      else repl (model' @ [p]) itm model
   395   in repl [] itm model end
   396 
   397 (*find_first item with #1 equal to id*)
   398 fun seek_ppc _ [] = NONE
   399   | seek_ppc id (p :: model) = if id = #1 (p: single) then SOME p else seek_ppc id model
   400 
   401 (* 10.3.00: insert the already compiled itm into model;
   402    ev. filter_out  untouched (in FE: (0,...)) item related to insert-item *)
   403 fun add_single thy itm model =
   404   let 
   405     fun eq_untouched d (0, _, _, _, itm_) = (d = descriptor itm_)
   406       | eq_untouched _ _ = false
   407     val model' = case seek_ppc (#1 itm) model of
   408       SOME _ => overwrite_ppc thy itm model (*itm updated in is_notyet_input WN.11.03*)
   409     | NONE => (model @ [itm])
   410   in filter_out (eq_untouched ((descriptor o #5) itm)) model' end
   411 
   412 
   413 (** complete I_Model.T **)
   414 
   415 (*
   416   TODO: investigate dependencies between OLD funs (and reconsider (1..4)):
   417     OLD complete_method uses OLD complete
   418     ..
   419   
   420   Survey on completion of i-models. There are 2 internal cases and 2 interactive cases
   421   Internal cases
   422     (1) fill_both
   423       for internally automated specify-phase: fill both models from o_model
   424       TODO random number for selection from variants in o_model
   425         ? https://www.isa-afp.org/theories/executable_randomized_algorithms/#Dice_Roll.html
   426       used in Specify.finish_phase -- SubProblem,
   427         ?! Step_Specify.by_tactic Model_Problem ?!
   428 \<Longrightarrow> (2) fill_method (WAS complete, which allowed met_imod <> [])
   429       for skipping model of MethodC; assumes Problem (+Pre_Conds) is complete, MethodC#model = []
   430       used in LI.by_tactic Apply_Method'
   431         P_Spec.input_icalhd (will be dropped)
   432   Interactive cases: assume an interactive element activated by the user
   433     (3) complete_method_pos
   434       for interactive specify-phase in case of setting "skip modelling method"
   435       (needs NOT Problem.is_complete due to (4))
   436     (4) complete_pos
   437       for interactive specify-phase on Problem AND MethodC, Position.T for feedback
   438       used in TODO
   439 
   440   Divide functionality of I_Model.of_max_variant into parts in ordeer for re-use in is_complete
   441     I_Model.max_variants
   442       return variant list, because Problem#model might be insufficient to determine
   443       variant of MethodC.#model (FunctionVariable a ! b)
   444       + (Model_Pattern.single * I_Model.single) list for make_environments
   445       ^^NO: need ONLY max_variants
   446     Pre_Conds.make_environments
   447       takes above list
   448 
   449   Related
   450 
   451   Coordination with I_Model.is_complete:
   452     uses I_Model.max_variants, Pre_Conds.make_environments for Pre_Conds.check
   453     determines by use of both models independently (?)    
   454 *)
   455 
   456 fun complete' pbt (i, v, f, d, ts) =
   457   case \<^try>\<open> (i, v, true, f, Cor ((d, ts),
   458       ((find_first ((fn descriptor => (fn (_, (d, _)) => descriptor = d)) d)) pbt |> the |> snd |> snd, ts)
   459     ))\<close> of
   460     SOME x => x
   461   | NONE => (i, v, true, f, Cor ((d, ts), (d, ts)))
   462 
   463 (*filter out oris which have same description in itms*)
   464 (* ---------------------------------- type problems ---vv---------vv
   465 fun filter_outs oris [] = oris
   466   | filter_outs oris (i::itms) = 
   467     let
   468       val ors = filter_out ((curry op = ((descriptor o #5) i)) o (#4)) oris
   469     in
   470       filter_outs ors itms
   471     end
   472 *)
   473 (*with types..*)
   474 (*T_TESTold*)
   475 fun filter_outs oris [] = oris
   476   | filter_outs oris (i::itms) = 
   477     let
   478       val ors = filter_out ((curry op = ((descriptor o 
   479         (#5: single -> feedback)) i)) o
   480         (#4: O_Model.single -> O_Model.descriptor)) oris
   481     in
   482       filter_outs ors itms
   483     end
   484 (*T_TEST*)
   485 fun filter_outs_TEST oris [] = oris
   486   | filter_outs_TEST oris (i::itms) = 
   487     let
   488       val ors = filter_out ((curry op = ((descriptor_TEST o 
   489         ((#1 o #5): single_TEST -> feedback_TEST) ) i) ) o
   490         (#4: O_Model.single -> O_Model.descriptor) ) oris
   491     in
   492       filter_outs_TEST ors itms
   493     end
   494 (*T_TESTnew*)
   495 
   496 (*filter oris which are in pbt, too*)
   497 fun filter_pbt oris pbt =
   498   let
   499     val dscs = map (fst o snd) pbt
   500   in
   501     filter ((member op= dscs) o (#4)) oris
   502   end
   503 
   504 fun is_error (Cor _) = false
   505   | is_error (Sup _) = false
   506   | is_error (Inc _) = false
   507   | is_error (Mis _) = false
   508   | is_error _ = true
   509 
   510 (*create output-string for itm*)
   511 fun to_p_model thy (Cor ((d, ts), _)) = UnparseC.term_in_thy thy (Input_Descript.join (d, ts))
   512   | to_p_model _ (Syn c) = c
   513   | to_p_model _ (Typ c) = c
   514   | to_p_model thy (Inc ((d, ts), _)) = UnparseC.term_in_thy thy (Input_Descript.join (d, ts))
   515   | to_p_model thy (Sup (d, ts)) = UnparseC.term_in_thy thy (Input_Descript.join (d, ts))
   516   | to_p_model thy (Mis (d, pid)) = UnparseC.term_in_thy thy d ^ " " ^ UnparseC.term_in_thy thy pid
   517   | to_p_model _ _ = raise ERROR "to_p_model: uncovered definition"
   518 
   519 fun eq_dsc ((_, _, _, _, itm_), (_, _, _, _, iitm_)) = (descriptor itm_ = descriptor iitm_)
   520 
   521 (* insert_ppc = add for appl_add', input_icalhd 11.03,
   522    handles superfluous items carelessly                       *)
   523 fun add itm itms = if member eq_dsc itms itm then itms else itms @ [itm] (* @ new itm *)
   524 
   525 (*combine itms from pbl + met and complete them wrt. pbt*)
   526 (* FIXXXME.WN031205 complete doesnt handle incorrect itms !*)
   527 fun complete oris pits mits met = 
   528   let
   529     val vat = Pre_Conds.max_variant pits;
   530     val itms = pits @ (filter ((member_swap op = vat) o (#2 )) mits)
   531     val ors = filter ((member_swap op= vat) o (#2)) oris
   532     val os = filter_outs ors itms (*WN.12.03?: does _NOT_ add itms from met ?!*)
   533   in
   534     itms @ (map (complete' met) os)
   535   end
   536 (**)
   537 
   538 (*T_TESTold*)
   539 (*complete model and guard of a calc-head*)
   540 fun complete_method (oris, mpc, model, probl) =
   541   let
   542     val pits = filter_out ((curry op= false) o (#3)) probl
   543     val vat = if probl = [] then 1 else Pre_Conds.max_variant probl
   544     val pors = filter ((member_swap op = vat) o (#2)) oris
   545     val pors = filter_outs pors pits (*which are in pbl already*)
   546     val pors = (filter_pbt pors model) (*which are in pbt, too*)
   547     val pits = pits @ (map (complete' model) pors)
   548     val mits = complete oris pits [] mpc
   549   in (pits, mits) end
   550 (*T_TEST*)
   551 fun msg vnts feedb = "get_descr_vnt' returns NONE: i.e. it does not find an item of o_model with\n" ^
   552   "variants " ^ ints2str' vnts ^ " and descriptor " ^
   553   (feedb |> Pre_Conds.get_dscr' |> the |> UnparseC.term (ContextC.for_ERROR ()))
   554 fun fill_method o_model pbl_imod met_patt =
   555   let
   556     val (pbl_max_vnts, _) = Pre_Conds.max_variants met_patt pbl_imod;
   557     val from_pbl = map (fn (_, (descr, _)) =>
   558       Pre_Conds.get_descr_vnt descr pbl_max_vnts pbl_imod) met_patt
   559     val from_o_model = map ((fn i_single as (_, _, _, _, (feedb, _)) =>
   560       if is_empty_single_TEST i_single
   561       then
   562         case Pre_Conds.get_descr_vnt' feedb pbl_max_vnts o_model of
   563           NONE => raise ERROR (msg pbl_max_vnts feedb)
   564         | SOME (i, vnts, m_field, descr, ts) =>
   565           (i, vnts, true, m_field, (Cor_TEST ((descr, ts), (TermC.empty, [])), Position.none))
   566       else i_single (*fetched before from pbl_imod*))) from_pbl
   567   in
   568     from_o_model
   569   end
   570 (*T_TESTnew*)
   571 
   572 (*TODO: also check if all elements are I_Model.Cor*)
   573 fun is_complete ([]: T) = false
   574   | is_complete itms = foldl and_ (true, (map #3 itms))
   575 
   576 (*for PIDE: are all feedback Cor ? MISSING: Pre_Conds.check *)
   577 fun is_complete_variant no_model_items i_model =
   578   no_model_items = length (filter (fn (_, _, _, _, (Cor_TEST _, _)) =>  true | _ => false) i_model)
   579 
   580 val of_max_variant = Pre_Conds.of_max_variant
   581 
   582 (**)end(**);