src/Tools/isac/Specify/m-match.sml
author wneuper <Walther.Neuper@jku.at>
Fri, 01 Dec 2023 06:08:22 +0100
changeset 60771 1b072aab8f4e
parent 60770 365758b39d90
child 60772 ac0317936138
permissions -rw-r--r--
PIDE turn 13: rename ALL(?) code already handling Position.T from *_TEST to *_POS

Note: after switching all src to Position.T *_POS shall be cut of identifiers.
Walther@60760
     1
(* Title:  Specify/m-match.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@60768
    10
  datatype T =
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@60768
    14
Walther@60768
    15
  val data_by_o: Proof.context -> O_Model.T ->
Walther@60770
    16
    Model_Pattern.T * Pre_Conds.unchecked * Rule_Def.rule_set ->
Walther@60771
    17
      bool * (I_Model.T_POS * Pre_Conds.T)
Walther@60768
    18
  val by_o_model: Proof.context -> O_Model.T ->
Walther@60768
    19
    Model_Pattern.single list * Pre_Conds.unchecked * Rule_Def.rule_set -> bool
Walther@60771
    20
  val by_i_model: Proof.context -> I_Model.T_POS ->
Walther@60770
    21
    Model_Pattern.T * Pre_Conds.unchecked * Rule_Def.rule_set -> bool * Pre_Conds.T
Walther@60771
    22
  val by_i_models: Proof.context -> O_Model.T -> I_Model.T_POS * I_Model.T_POS ->
Walther@60760
    23
    Model_Pattern.T * Pre_Conds.unchecked * Rule_Def.rule_set ->
Walther@60771
    24
      bool * (I_Model.T_POS * Pre_Conds.T)
walther@59987
    25
walther@59996
    26
  val arguments: theory -> Model_Pattern.T -> term list -> O_Model.T
walther@59987
    27
  val arguments_msg: Problem.id -> term -> term list -> unit
walther@59968
    28
walther@60251
    29
  datatype match' =  (* constructors for tests only *)
walther@60251
    30
    Matches' of P_Model.T | NoMatch' of P_Model.T
Walther@60769
    31
  val by_formalise : Formalise.model -> Problem.T -> match'
Walther@60729
    32
Walther@60729
    33
(*from isac_test for Minisubpbl*)
Walther@60729
    34
  val chk1_: Model_Pattern.T -> O_Model.single -> I_Model.T
Walther@60770
    35
  val contains_o: Model_Def.descriptor -> O_Model.T -> bool
Walther@60729
    36
wenzelm@60223
    37
\<^isac_test>\<open>
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@60770
    55
fun contains_o descr o_model =
Walther@60768
    56
  case find_first (fn (_, _, _, descr', _) => descr' = descr) o_model of
Walther@60768
    57
     SOME _ => true | NONE => false
Walther@60768
    58
fun data_by_o ctxt o_model (model_patt, where_, where_rls) =
Walther@60768
    59
  let
Walther@60768
    60
    val o_model_vnt = o_model
Walther@60768
    61
      |> map (fn o_single as (_, variants, _, _, _)
Walther@60768
    62
        => if member_swap op = 1 (*variant 1 is mandatory*) variants then [o_single] else [])
Walther@60768
    63
      |> flat
Walther@60768
    64
    val is_complete = model_patt
Walther@60770
    65
      |> map (fn (_, (descr, _)) => contains_o descr o_model_vnt) 
Walther@60768
    66
      |> curry (foldl and_) true
Walther@60768
    67
    val i_model = (*in order to match sig of Pre_Conds.check*)
Walther@60771
    68
      map (fn (a, b, c, d, e) => (a, b, true, c, (I_Model.Cor_POS (d, e), Position.none))) o_model_vnt
Walther@60768
    69
    val (pre_conds_check, pre_conds) = Pre_Conds.check ctxt where_rls where_ (model_patt, i_model)
Walther@60768
    70
  in
Walther@60768
    71
    (is_complete andalso pre_conds_check, (i_model, pre_conds))
Walther@60768
    72
  end
walther@59968
    73
Walther@60768
    74
fun by_o_model ctxt o_model (model_patt, where_, where_rls) = 
Walther@60768
    75
  (data_by_o ctxt o_model (model_patt, where_, where_rls)) |> #1
walther@59968
    76
Walther@60769
    77
fun by_i_models ctxt o_model (pbl_imod, met_imod) (met_patt, where_, where_rls) =
Walther@60760
    78
  let
Walther@60760
    79
    val met_imod = I_Model.fill_method o_model (pbl_imod, met_imod) met_patt
Walther@60760
    80
    val (check, preconds) = Pre_Conds.check ctxt where_rls where_ (met_patt, met_imod)
Walther@60760
    81
  in    
Walther@60760
    82
   (check, (met_imod, preconds))
Walther@60760
    83
  end
walther@59971
    84
Walther@60771
    85
(*contains_i: descriptor -> I_Model.T_POS -> bool*)
Walther@60770
    86
fun contains_i descr i_model =
Walther@60770
    87
  case find_first (fn (_, _, _, _, (feedb, _)) => Model_Def.get_descr feedb = descr) i_model of
Walther@60770
    88
     SOME _ => true | NONE => false
Walther@60770
    89
fun by_i_model ctxt i_model (model_patt, where_, where_rls) =
Walther@60770
    90
  let
Walther@60770
    91
    val max_vnt = last_elem (Model_Def.max_variants'' i_model)
Walther@60770
    92
    val i_model_vnt = filter (fn (_, vnts, _, _, _) => member op= vnts max_vnt) i_model
Walther@60770
    93
    val is_complete = model_patt
Walther@60770
    94
      |> map (fn (_, (descr, _)) => contains_i descr i_model_vnt)
Walther@60770
    95
      |> curry (foldl and_) true
Walther@60770
    96
Walther@60770
    97
    val (env_model, (env_subst, env_eval)) = Pre_Conds.make_environments model_patt i_model_vnt;
Walther@60770
    98
    val (prec_check, precs)
Walther@60770
    99
      = Pre_Conds.check_envs ctxt where_rls where_ (env_model, (env_subst, env_eval))
Walther@60770
   100
  in
Walther@60770
   101
    (is_complete andalso prec_check, precs)
Walther@60770
   102
  end
Walther@60770
   103
walther@59971
   104
walther@59971
   105
(** for use by math-authors **)
walther@59971
   106
walther@59971
   107
datatype match' = (* for the user *)
walther@59971
   108
  Matches' of P_Model.T
walther@59971
   109
| NoMatch' of P_Model.T;
walther@59971
   110
walther@59971
   111
(* match a formalization with a problem type, for tests *)
Walther@60769
   112
fun by_formalise fmz ({thy, where_, model, where_rls, ...}: Problem.T) =
walther@59971
   113
  let
Walther@60768
   114
    val ctxt = Proof_Context.init_global thy
Walther@60768
   115
    val (oris, _) = O_Model.init thy fmz model
Walther@60768
   116
    val (bool, (itms, where_')) = data_by_o ctxt oris (model, where_, where_rls);
walther@59971
   117
  in
walther@59971
   118
    if bool
Walther@60768
   119
    then Matches' (P_Model.from thy (I_Model.TEST_to_OLD itms) where_')
Walther@60768
   120
    else NoMatch' (P_Model.from thy (I_Model.TEST_to_OLD itms) where_')
walther@59971
   121
  end;
walther@59971
   122
Walther@60586
   123
(* split type-wrapper from program-arg and build part of an ori;
walther@59987
   124
   an type-error is reported immediately, raises an exn, 
walther@59987
   125
   subsequent handling of exn provides 2nd part of error message *)
walther@59987
   126
fun mtc thy (str, (dsc, _)) (ty $ var) =
Walther@60650
   127
    let val ctxt = Proof_Context.init_global thy
Walther@60650
   128
    in
walther@59987
   129
    ((Thm.global_cterm_of thy (dsc $ var);(*type check*)
walther@59987
   130
      SOME (([1], str, dsc, (*[var]*)
walther@59987
   131
	    Input_Descript.split' (dsc, var))) (*:ori without leading #*))
walther@59987
   132
      handle e as TYPE _ => 
walther@59987
   133
	      (tracing (dashs 70 ^ "\n"
walther@59987
   134
	        ^ "*** ERROR while creating the items for the model of the ->problem\n"
walther@59987
   135
	        ^ "*** from the ->stac with ->typeconstructor in arglist:\n"
Walther@60675
   136
	        ^ "*** item (->description ->value): " ^ UnparseC.term ctxt dsc ^ " " ^ UnparseC.term ctxt var ^ "\n"
Walther@60650
   137
	        ^ "*** description: " ^ TermC.string_of_detail ctxt dsc
Walther@60650
   138
	        ^ "*** value: " ^ TermC.string_of_detail ctxt var
Walther@60650
   139
	        ^ "*** typeconstructor in script: " ^ TermC.string_of_detail ctxt ty
walther@59987
   140
	        ^ "*** checked by theory: " ^ Context.theory_name thy ^ "\n"
walther@59987
   141
	        ^ "*** " ^ dots 66);
walther@59987
   142
          writeln (@{make_string} e);
walther@59987
   143
          Exn.reraise e; (*raise ERROR "actual args do not match formal args";FIXXXME.WN100916*)
walther@59987
   144
      NONE))
Walther@60650
   145
    end
Walther@60650
   146
  | mtc thy _ t =
Walther@60650
   147
    let val ctxt = Proof_Context.init_global thy
Walther@60675
   148
    in raise ERROR ("mtc: uncovered case with" ^ UnparseC.term ctxt t) end
walther@59987
   149
walther@59987
   150
(* match each pat of the model-pattern with an actual argument;
walther@59987
   151
   precondition: copy-named vars are filtered out            *)
walther@59987
   152
fun matc _ [] _ oris = oris
Walther@60655
   153
  | matc thy pbt [] _ =
walther@59987
   154
    (tracing (dashs 70);
Walther@60655
   155
     raise ERROR ("actual arg(s) missing for '" ^ Model_Pattern.to_string
Walther@60655
   156
       (Proof_Context.init_global thy) pbt ^ "' i.e. should be 'copy-named' by '*_._'"))
walther@59987
   157
  | matc thy ((p as (_, (_, t))) :: pbt) (a :: ags) oris =
Walther@60475
   158
    (*del?..*)if (O_Model.is_copy_named' o TermC.free2str) t then oris
walther@59987
   159
    else(*..del?*)
walther@59987
   160
      let val opt = mtc thy p a
walther@59987
   161
      in
walther@59987
   162
        case opt of
walther@59987
   163
          SOME ori => matc thy pbt ags (oris @ [ori])
walther@59987
   164
	      | NONE => [](*WN050903 skipped by exn handled in arguments*)
walther@59987
   165
	 end
walther@59987
   166
walther@59987
   167
(* match the actual arguments of a SubProblem with a model-pattern
Walther@60473
   168
   and create an O_Model (in root-pbl created from Formalise.model).
walther@59987
   169
   expects ags:pats = 1:1, while copy-named are filtered out of pats;
walther@59987
   170
   if no 1:1 then exn raised by matc/mtc and handled at call.
walther@60152
   171
   copy-named pats are appended in order to get them into the Model-items *)
walther@59987
   172
fun arguments thy pbt ags =
walther@59987
   173
  let
walther@59987
   174
    fun flattup (i, (var, bool, str, itm_)) = (i, var, bool, str, itm_)
walther@59987
   175
    val pbt' = filter_out O_Model.is_copy_named pbt
walther@59987
   176
    val cy = filter O_Model.is_copy_named pbt  (* cy is NOT a (formal) argument, but the fun's result *)
walther@59987
   177
    val oris' = matc thy pbt' ags []
Walther@60473
   178
    val cy' = map (O_Model.copy_name pbt' oris') cy
Walther@60472
   179
    val ors = O_Model.add_enumerate (oris' @ cy') (*...appended in order to get into the Model-items *)
walther@59987
   180
  in (map flattup ors) end
walther@59987
   181
walther@59987
   182
(* report part of the error-msg which is not available in match_args *)
Walther@60559
   183
fun arguments_msg ctxt pI stac ags =
walther@59987
   184
  let
Walther@60585
   185
    val pats = (#model o Problem.from_store ctxt) pI
walther@59987
   186
    val msg = (dots 70 ^ "\n"
walther@59987
   187
       ^ "*** problem " ^ strs2str pI ^ " has the ...\n"
Walther@60655
   188
       ^ "*** model-pattern " ^ Model_Pattern.to_string ctxt pats ^ "\n"
Walther@60675
   189
       ^ "*** stac   '" ^ UnparseC.term ctxt stac ^ "' has the ...\n"
Walther@60675
   190
       ^ "*** arg-list " ^ UnparseC.terms ctxt ags ^ "\n"
walther@59987
   191
       ^ dashs 70)
Walther@60556
   192
  in tracing msg end
walther@59987
   193
walther@59968
   194
(**)end(**)