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