src/Tools/isac/Specify/m-match.sml
author wneuper <Walther.Neuper@jku.at>
Wed, 11 Jan 2023 11:38:01 +0100
changeset 60650 06ec8abfd3bc
parent 60590 35846e25713e
child 60653 fff1c0f0a9e7
permissions -rw-r--r--
eliminate use of Thy_Info 12: TermC partially
walther@59960
     1
(* Title:  Specify/model.sml
walther@59960
     2
   Author: Walther Neuper 110226
walther@59960
     3
   (c) due to copyright terms
walther@59960
     4
walther@59960
     5
Operations on models.
walther@59960
     6
*)
walther@59960
     7
walther@59984
     8
signature MODEL_MATCH =
walther@59960
     9
sig
walther@60010
    10
  datatype T = (* ------------vvvvvvvvv--- adapt to PIDE *)
walther@59969
    11
      Matches of Problem.id * P_Model.T
walther@59971
    12
    | NoMatch of Problem.id * P_Model.T  
walther@59984
    13
  val matchs2str : T list -> string
Walther@60556
    14
(*/------- rename: TODO 220917 review -------\*)
Walther@60556
    15
(*val o_model: theory -> Rule_Set.T -> O_Model.T -> Model_Pattern.T * term list -> bool*)
Walther@60590
    16
  val match_oris: Proof.context -> Rule_Set.T -> O_Model.T -> Model_Pattern.T * term list -> bool
walther@59971
    17
(*unify                     ^^^^^^^^^^                                  vvvvvvvvvv 
walther@59971
    18
                             vvvvvvvvv    ^^^^^^^^^*)
walther@60010
    19
(*val match_oris': theory -> O_Model.T -> Model_Pattern.T * term list * Rule_Set.T ->
walther@60010
    20
    bool * (I_Model.T * Pre_Conds.T)*)
Walther@60556
    21
  val match_oris': theory -> O_Model.T -> Model_Pattern.T * term list(*Pre_Cond.unchecked*) * Rule_Set.T ->
walther@60010
    22
    bool * (I_Model.T * Pre_Conds.T)    (*^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v--- type*)
walther@60010
    23
(*val o_i_model: O_Model.T * I_Model.T -> Model_Pattern.T * term list * Rule_Set.T -> theory ->
walther@60010
    24
    bool * (I_Model.T * Pre_Conds.T)             (*?values--^^^^^^^^^?*)*)
walther@60010
    25
  val match_itms_oris: theory -> I_Model.T -> Model_Pattern.T * term list * Rule_Set.T ->
walther@59971
    26
    O_Model.T -> bool * (I_Model.T * Pre_Conds.T)
walther@59987
    27
walther@60010
    28
(*val arguments: theory -> Model_Pattern.T -> term list -> O_Model.T*)
walther@59996
    29
  val arguments: theory -> Model_Pattern.T -> term list -> O_Model.T
walther@60010
    30
(*val arguments_msg: Problem.id -> term -> term list -> unit*)
walther@59987
    31
  val arguments_msg: Problem.id -> term -> term list -> unit
walther@59968
    32
walther@60251
    33
  datatype match' =  (* constructors for tests only *)
walther@60251
    34
    Matches' of P_Model.T | NoMatch' of P_Model.T
walther@59971
    35
  val match_pbl : Formalise.model -> Problem.T -> match'
wenzelm@60223
    36
\<^isac_test>\<open>
walther@60010
    37
(*val matc: theory -> Model_Pattern.T -> term list -> O_Model.T -> O_Model.T*)
walther@60010
    38
  val matc: theory -> Model_Pattern.T -> term list -> O_Model.T -> O_Model.T
wenzelm@60223
    39
\<close>
walther@59987
    40
(*\------- rename -------/*)
walther@59960
    41
end
walther@59960
    42
walther@59968
    43
(**)
walther@59997
    44
structure M_Match(** ) : MODEL_MATCH( **) =
walther@59960
    45
struct
walther@59968
    46
(**)
walther@59960
    47
walther@59984
    48
datatype T = 
walther@59969
    49
  Matches of Problem.id *  P_Model.T
walther@59969
    50
| NoMatch of Problem.id *  P_Model.T;
Walther@60585
    51
fun match2str (Matches (pI, model)) = "Matches (" ^ strs2str pI ^ ", " ^  P_Model.to_string model ^ ")"
Walther@60585
    52
  | match2str (NoMatch (pI, model)) = "NoMatch (" ^ strs2str pI ^ ", " ^  P_Model.to_string model ^ ")";
walther@59965
    53
fun matchs2str ms = (strs2str o (map match2str)) ms;
walther@59965
    54
walther@59968
    55
walther@59968
    56
fun field_eq f (_, _, f', _, _) = f = f';
walther@59968
    57
walther@59968
    58
fun eq2' (_, (d, _)) (_, _, _, d', _) = d = d';
Walther@60477
    59
fun eq2 (_, (d, _)) (_, _, _, _, itm_) = d = I_Model.descriptor itm_;
walther@59968
    60
fun eq1 d (_, (d', _)) = (d = d');
walther@59968
    61
walther@59968
    62
fun ori2itmSup (i, v, _, d, ts) = (i, v, true, "#Given", I_Model.Sup (d, ts));
walther@59968
    63
walther@59968
    64
(* check an ori for matching a problemtype by description; 
walther@59968
    65
   returns true only for itms found in pbt              *)
Walther@60590
    66
fun chk1_ pbt (i, vats, f, d, vs) =
walther@59968
    67
  case find_first (eq1 d) pbt of 
Walther@60478
    68
	  SOME (_, (_, id)) => [(i, vats, true, f, I_Model.Cor ((d, vs), (id, [Input_Descript.join'''' (d, vs)])))]
walther@59968
    69
  | NONE => [];
walther@59968
    70
walther@59968
    71
(* elem 'p' of pbt contained in itms ? *)
walther@59968
    72
fun chk1_m itms p = case find_first (eq2 p) itms of SOME _ => true | NONE => false;
walther@59968
    73
fun chk1_m' oris (p as (f, (d, t))) = 
walther@59968
    74
  case find_first (eq2' p) oris of
walther@59968
    75
	  SOME _ => []
walther@59968
    76
  | NONE => [(f, I_Model.Mis (d, t))];
walther@59968
    77
fun pair0vatsfalse (f, itm_) = (0, [], false, f, itm_);
walther@59968
    78
Walther@60585
    79
fun chk1_mis _(*mvat*) itms model = foldl and_ (true, map (chk1_m itms) model);
Walther@60585
    80
fun chk1_mis' oris model = map pair0vatsfalse ((flat o (map (chk1_m' oris))) model);
walther@59968
    81
  
walther@59968
    82
(* check a problem (ie. ori list) for matching a problemtype, 
Walther@60477
    83
   takes the I_Model.variables for concluding completeness (FIXME could be another!) *)
Walther@60590
    84
fun match_oris ctxt where_rls oris (pbt,where_) = 
walther@59968
    85
  let
Walther@60590
    86
    val itms = (flat o (map (chk1_ pbt))) oris;
Walther@60477
    87
    val mvat = I_Model.variables itms;
walther@59968
    88
    val complete = chk1_mis mvat itms pbt;
Walther@60590
    89
    val (pb, _(*where_'*)) = Pre_Conds.check ctxt where_rls where_ itms mvat;
walther@59968
    90
  in if complete andalso pb then true else false end;
walther@59968
    91
walther@59968
    92
(* check a problem (ie. ori list) for matching a problemtype, 
walther@59968
    93
   returns items for output to math-experts *)
Walther@60586
    94
fun match_oris' thy oris (model, where_, where_rls) =
walther@59968
    95
  let
Walther@60590
    96
    val itms = (flat o (map (chk1_ model))) oris;
walther@59968
    97
    val sups = ((map ori2itmSup) o (filter (field_eq "#undef"))) oris;
Walther@60477
    98
    val mvat = I_Model.variables itms;
Walther@60585
    99
    val miss = chk1_mis' oris model;
Walther@60590
   100
    val (pb, where_')  = Pre_Conds.check (Proof_Context.init_global thy) where_rls where_ itms mvat;
Walther@60586
   101
  in (miss = [] andalso pb, (itms @ miss @ sups, where_')) end;
walther@59968
   102
walther@59971
   103
walther@59971
   104
(** check a problem (ie. itm list) for matching a problemtype **)
walther@59971
   105
walther@59971
   106
(* check a problem (or method) pbl (ie. itm list) for matching a problemtype pbt,
walther@59971
   107
   for missing items get data from formalization (ie. ori list); 
Walther@60477
   108
   takes the I_Model.variables for concluding completeness (could be another!)
walther@59971
   109
 
walther@59971
   110
  (0) determine the most frequent variant mv in pbl
walther@59971
   111
   ALL pbt. (1) dsc(pbt) notmem dsc(pbls) =>
walther@59971
   112
            (2) filter (dsc(pbt) = dsc(oris)) oris; -> news;
walther@59971
   113
            (3) newitms = filter (mv mem vat(news)) news 
walther@59971
   114
   (4) pbt @ newitms                                           *)
Walther@60590
   115
fun match_itms_oris ctxt pbl (pbt, where_, where_rls) oris =
walther@59971
   116
  let 
Walther@60477
   117
 (*0*)val mv = I_Model.max_variant pbl;
walther@59971
   118
Walther@60477
   119
      fun eqdsc_pbt_itm ((_,(d,_))) (_, _, _, _, itm_) = d = I_Model.descriptor itm_;
walther@59971
   120
      fun notmem pbl pbt1 = case find_first (eqdsc_pbt_itm pbt1) pbl of
walther@59971
   121
				SOME _ => false | NONE => true;
walther@59971
   122
 (*1*)val mis = (filter (notmem pbl)) pbt;
walther@59971
   123
walther@59971
   124
      fun eqdsc_ori (_,(d,_)) (_, _, _, d', _) = d = d';
walther@59971
   125
      fun ori2itmMis (f, (d, pid)) (i, v, _, _, _) = (i, v, false, f, I_Model.Mis (d, pid));
walther@59971
   126
 (*2*)fun oris2itms oris mis1 = ((map (ori2itmMis mis1)) o (filter (eqdsc_ori mis1))) oris;
walther@59971
   127
      val news = (flat o (map (oris2itms oris))) mis;
walther@59971
   128
 (*3*)fun mem_vat (_, vats, _, _, _) = member op = vats mv;
walther@59971
   129
      val newitms = filter mem_vat news;
walther@59971
   130
 (*4*)val itms' = pbl @ newitms;
Walther@60590
   131
      val (pb, where_') = Pre_Conds.check ctxt where_rls where_ itms' mv;
Walther@60586
   132
  in (length mis = 0 andalso pb, (itms', where_')) end;
walther@59971
   133
walther@59971
   134
walther@59971
   135
(** for use by math-authors **)
walther@59971
   136
walther@59971
   137
datatype match' = (* for the user *)
walther@59971
   138
  Matches' of P_Model.T
walther@59971
   139
| NoMatch' of P_Model.T;
walther@59971
   140
walther@59971
   141
(* match a formalization with a problem type, for tests *)
Walther@60586
   142
fun match_pbl fmz ({thy = thy, where_ = where_, model, where_rls = er, ...}: Problem.T) =
walther@59971
   143
  let
Walther@60585
   144
    val oris = O_Model.init thy fmz model(* |> #1*);
Walther@60586
   145
    val (bool, (itms, where_')) = match_oris' thy oris (model, where_, er);
walther@59971
   146
  in
walther@59971
   147
    if bool
Walther@60586
   148
    then Matches' (P_Model.from thy itms where_')
Walther@60586
   149
    else NoMatch' (P_Model.from thy itms where_')
walther@59971
   150
  end;
walther@59971
   151
Walther@60586
   152
(* split type-wrapper from program-arg and build part of an ori;
walther@59987
   153
   an type-error is reported immediately, raises an exn, 
walther@59987
   154
   subsequent handling of exn provides 2nd part of error message *)
walther@59987
   155
fun mtc thy (str, (dsc, _)) (ty $ var) =
Walther@60650
   156
    let val ctxt = Proof_Context.init_global thy
Walther@60650
   157
    in
walther@59987
   158
    ((Thm.global_cterm_of thy (dsc $ var);(*type check*)
walther@59987
   159
      SOME (([1], str, dsc, (*[var]*)
walther@59987
   160
	    Input_Descript.split' (dsc, var))) (*:ori without leading #*))
walther@59987
   161
      handle e as TYPE _ => 
walther@59987
   162
	      (tracing (dashs 70 ^ "\n"
walther@59987
   163
	        ^ "*** ERROR while creating the items for the model of the ->problem\n"
walther@59987
   164
	        ^ "*** from the ->stac with ->typeconstructor in arglist:\n"
Walther@60650
   165
	        ^ "*** item (->description ->value): " ^ UnparseC.term_in_ctxt ctxt dsc ^ " " ^ UnparseC.term_in_ctxt ctxt var ^ "\n"
Walther@60650
   166
	        ^ "*** description: " ^ TermC.string_of_detail ctxt dsc
Walther@60650
   167
	        ^ "*** value: " ^ TermC.string_of_detail ctxt var
Walther@60650
   168
	        ^ "*** typeconstructor in script: " ^ TermC.string_of_detail ctxt ty
walther@59987
   169
	        ^ "*** checked by theory: " ^ Context.theory_name thy ^ "\n"
walther@59987
   170
	        ^ "*** " ^ dots 66);
walther@59987
   171
          writeln (@{make_string} e);
walther@59987
   172
          Exn.reraise e; (*raise ERROR "actual args do not match formal args";FIXXXME.WN100916*)
walther@59987
   173
      NONE))
Walther@60650
   174
    end
Walther@60650
   175
  | mtc thy _ t =
Walther@60650
   176
    let val ctxt = Proof_Context.init_global thy
Walther@60650
   177
    in raise ERROR ("mtc: uncovered case with" ^ UnparseC.term_in_ctxt ctxt t) end
walther@59987
   178
walther@59987
   179
(* match each pat of the model-pattern with an actual argument;
walther@59987
   180
   precondition: copy-named vars are filtered out            *)
walther@59987
   181
fun matc _ [] _ oris = oris
walther@59987
   182
  | matc _ pbt [] _ =
walther@59987
   183
    (tracing (dashs 70);
walther@59987
   184
     raise ERROR ("actual arg(s) missing for '" ^ Model_Pattern.to_string pbt ^ "' i.e. should be 'copy-named' by '*_._'"))
walther@59987
   185
  | matc thy ((p as (_, (_, t))) :: pbt) (a :: ags) oris =
Walther@60475
   186
    (*del?..*)if (O_Model.is_copy_named' o TermC.free2str) t then oris
walther@59987
   187
    else(*..del?*)
walther@59987
   188
      let val opt = mtc thy p a
walther@59987
   189
      in
walther@59987
   190
        case opt of
walther@59987
   191
          SOME ori => matc thy pbt ags (oris @ [ori])
walther@59987
   192
	      | NONE => [](*WN050903 skipped by exn handled in arguments*)
walther@59987
   193
	 end
walther@59987
   194
walther@59987
   195
(* match the actual arguments of a SubProblem with a model-pattern
Walther@60473
   196
   and create an O_Model (in root-pbl created from Formalise.model).
walther@59987
   197
   expects ags:pats = 1:1, while copy-named are filtered out of pats;
walther@59987
   198
   if no 1:1 then exn raised by matc/mtc and handled at call.
walther@60152
   199
   copy-named pats are appended in order to get them into the Model-items *)
walther@59987
   200
fun arguments thy pbt ags =
walther@59987
   201
  let
walther@59987
   202
    fun flattup (i, (var, bool, str, itm_)) = (i, var, bool, str, itm_)
walther@59987
   203
    val pbt' = filter_out O_Model.is_copy_named pbt
walther@59987
   204
    val cy = filter O_Model.is_copy_named pbt  (* cy is NOT a (formal) argument, but the fun's result *)
walther@59987
   205
    val oris' = matc thy pbt' ags []
Walther@60473
   206
    val cy' = map (O_Model.copy_name pbt' oris') cy
Walther@60472
   207
    val ors = O_Model.add_enumerate (oris' @ cy') (*...appended in order to get into the Model-items *)
walther@59987
   208
  in (map flattup ors) end
walther@59987
   209
walther@59987
   210
(* report part of the error-msg which is not available in match_args *)
Walther@60559
   211
fun arguments_msg ctxt pI stac ags =
walther@59987
   212
  let
Walther@60585
   213
    val pats = (#model o Problem.from_store ctxt) pI
walther@59987
   214
    val msg = (dots 70 ^ "\n"
walther@59987
   215
       ^ "*** problem " ^ strs2str pI ^ " has the ...\n"
walther@59987
   216
       ^ "*** model-pattern " ^ Model_Pattern.to_string pats ^ "\n"
walther@59987
   217
       ^ "*** stac   '" ^ UnparseC.term stac ^ "' has the ...\n"
walther@59987
   218
       ^ "*** arg-list " ^ UnparseC.terms ags ^ "\n"
walther@59987
   219
       ^ dashs 70)
Walther@60556
   220
  in tracing msg end
walther@59987
   221
walther@59968
   222
(**)end(**)