src/Tools/isac/Specify/refine.sml
author wneuper <Walther.Neuper@jku.at>
Thu, 30 Nov 2023 08:11:50 +0100
changeset 60769 0df0759fed26
parent 60768 14da2230d5c3
child 60770 365758b39d90
permissions -rw-r--r--
some renamings
     1 (* Title:  Specify/refine.sml
     2    Author: Walther Neuper 110226
     3    (c) due to copyright terms
     4 
     5 Refine a problem by a search for a \<open>ML_structure Model_Pattern\<close> 
     6 better fitting the respective where_-condition.
     7 
     8 The search on the tree given by @{term Know_Store.get_pbls} is costly such that 
     9 \<open>ML_structure Know_Store\<close> holds terms pre-parsed with a most generally type. 
    10 
    11 On transfer to a calculation these terms are strongly typed by Model_Pattern.adapt_to_type
    12 (and users of this function in \<open>ML_structure Error_Pattern, MethodC, Problem\<close>)
    13 according to the current context.
    14 
    15 Note: From the children of eb89f586b0b2 onwards the old functions (\<open>term TermC.typ_a2real\<close> etc)
    16 are adapted for "adapt_to_type on the fly" until further clarification.
    17 
    18 timing (from evaluating imports to use-cases.sml) for Test_Isac_Short
    19   before adapt_to_type: 01:05 sec:sec
    20   after  adapt_to_type: 
    21 timing for test/../refine.sml --- equation with CalcTree [ = 6 / 5] for timing: ...
    22   before adapt_to_type: 1.5 sec
    23   after  adapt_to_type: 
    24 timing for test/../refine.sml --- refine ad-hoc equation for timing: ...
    25   before adapt_to_type: 0.05 sec
    26   after  adapt_to_type: 
    27 *)                          
    28 
    29 signature REFINE_PROBLEM =
    30 sig
    31 (**)
    32   val problem: theory -> Problem.id -> I_Model.T -> (Problem.id * (I_Model.T * Pre_Conds.T)) option
    33 
    34   val by_o_model : Proof.context -> O_Model.T -> Problem.id -> Problem.id option
    35   val by_o_model' : Proof.context -> O_Model.T -> Problem.id -> Problem.id
    36   val by_formalise: Proof.context -> Formalise.model -> Problem.id -> M_Match.T list
    37 
    38 (*from isac_test for Minisubpbl*)
    39   datatype match_model_prec = Match_ of Problem.id * (( I_Model.T) * (Pre_Conds.T)) | NoMatch_;
    40   val find_match: theory -> Problem.id -> I_Model.T -> match_model_prec list -> Problem.T Store.node -> match_model_prec list
    41   val find_node_elem: (Probl_Def.T Store.node -> 'a) -> Store.key -> Store.key -> 'a
    42   val check_match: Proof.context -> Problem.id -> O_Model.T -> Problem.T Store.node ->
    43     Problem.id option
    44   val refins: Proof.context -> Problem.id -> O_Model.T -> Problem.T Store.node list ->
    45     Problem.id option
    46 
    47 \<^isac_test>\<open>
    48   val match_found: match_model_prec list -> match_model_prec option
    49   val find_matchs: theory -> Problem.id -> I_Model.T -> match_model_prec list -> Problem.T Store.node list -> match_model_prec list
    50 \<close>
    51 end
    52 
    53 (**)
    54 structure Refine(**) : REFINE_PROBLEM(**) =
    55 struct
    56 (**)
    57 
    58 datatype match_model_prec = 
    59   Match_ of Problem.id * (( I_Model.T) * (Pre_Conds.T))
    60 | NoMatch_;
    61 
    62 fun is_matches_ (Match_ _) = true
    63   | is_matches_ _ = false;
    64 
    65 fun match_found ms = ((find_first is_matches_) o rev) ms;
    66 
    67 fun eq1 d (_, (d', _)) = (d = d');
    68 
    69 (*  chk_: theory -> ('a * (term * term)) list -> I_Model.single -> I_Model.single*)
    70 (*T_TESTold*)
    71 fun chk_ (_: theory) pbt (i, vats, b, f, I_Model.Cor ((d, vs), _)) =
    72       (case find_first (eq1 d) pbt of 
    73         SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor ((d, vs), (id, [Input_Descript.join'''' (d, vs)])))
    74       | NONE =>  (i, vats, false, f, I_Model.Sup (d, vs)))
    75   | chk_ _ pbt (i, vats, b, f, I_Model.Inc ((d, vs), _)) =
    76       (case find_first (eq1 d) pbt of 
    77         SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor ((d, vs), (id, [Input_Descript.join'''' (d, vs)])))
    78       | NONE => (i, vats, false, f, I_Model.Sup (d, vs)))
    79   | chk_ _ _ (itm as (_, _, _, _, I_Model.Syn _)) = itm
    80   | chk_ _ _ (itm as (_, _, _, _, I_Model.Typ _)) = itm
    81   | chk_ _ pbt (i, vats, b, f, I_Model.Sup (d, vs)) =
    82       (case find_first (eq1 d) pbt of 
    83         SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor ((d,vs), (id, [Input_Descript.join'''' (d, vs)])))
    84       | NONE => (i, vats, false, f, I_Model.Sup (d, vs)))
    85   | chk_ _ pbt (i, vats, _, f, I_Model.Mis (d, vs)) =
    86       (case find_first (eq1 d) pbt of
    87         SOME _ =>
    88           raise ERROR "chk_: ((i,vats,b,f,I_Model.Cor ((d,vs),(id, Input_Descript.join'''' d vs))):itm)"
    89       | NONE => (i, vats, false, f, I_Model.Sup (d, [vs])))
    90   | chk_ _ _ _ = raise ERROR "chk_: uncovered fun def.";
    91 (*T_TEST*)
    92 fun chk_TEST (_: theory) pbt (i, vats, b, f, I_Model.Cor_TEST (d, vs)) =
    93       (case find_first (eq1 d) pbt of 
    94         SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor_TEST (d, vs))
    95       | NONE =>  (i, vats, false, f, I_Model.Sup_TEST (d, vs)))
    96   | chk_TEST _ pbt (i, vats, b, f, I_Model.Inc_TEST (d, vs)) =
    97       (case find_first (eq1 d) pbt of 
    98         SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor_TEST (d, vs))
    99       | NONE => (i, vats, false, f, I_Model.Sup_TEST (d, vs)))
   100   | chk_TEST _ pbt (i, vats, b, f, I_Model.Sup_TEST (d, vs)) =
   101       (case find_first (eq1 d) pbt of 
   102         SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor_TEST (d, vs))
   103       | NONE => (i, vats, false, f, I_Model.Sup_TEST (d, vs)))
   104 (*T_TESTnew*)
   105 
   106 fun eq2 (_, (d, _)) (_, _, _, _, itm_) = d = I_Model.descriptor itm_;
   107 fun eq0 (0, _, _, _, _) = true
   108   | eq0 _ = false;
   109 fun max_i i [] = i
   110   | max_i i ((id, _, _, _, _) :: is) = if i > id then max_i i is else max_i id is;
   111 fun max_id [] = 0
   112   | max_id ((id, _, _, _, _) :: is) = max_i id is;
   113 fun add_idvat itms _ _ [] = itms
   114   | add_idvat itms i mvat ((_, _, b, f, itm_) :: its) =
   115     add_idvat (itms @ [(i, [], b, f, itm_)]) (i + 1) mvat its;
   116 
   117 (* find elements of pbt not contained in itms;
   118    if such one is untouched, return this one, otherwise create new itm *)
   119 fun chk_m itms untouched (p as (f, (d, id))) = 
   120   case find_first (eq2 p) itms of
   121 	  SOME _ => []
   122   | NONE =>
   123       (case find_first (eq2 p) untouched of
   124         SOME itm => [itm]
   125       | NONE => [(0, [], false, f, I_Model.Mis (d, id))]);
   126 
   127 fun chk_mis mvat itms untouched pbt = 
   128     let val mis = (flat o (map (chk_m itms untouched))) pbt; 
   129         val mid = max_id itms;
   130     in add_idvat [] (mid + 1) mvat mis end;
   131 
   132 (*
   133   check a problem (ie. i?model) for matching a problemtype, 
   134   takes the Pre_Conds.max_variant for concluding completeness
   135 *)
   136 (*  match_itms: theory -> I_Model.T -> Model_Pattern.T * unchecked * Rule_Def.rule_set ->
   137          bool * (I_Model.T * (bool * term) list)*)
   138 fun match_itms thy itms (pbt, where_, where_rls) = 
   139   let
   140     fun okv mvat (_, vats, b, _, _) = member op = vats mvat andalso b;
   141     val itms' = map (chk_ thy pbt) itms; (* all found are #3 true *)
   142     val mvat = Pre_Conds.max_variant itms';
   143 	  val itms'' = filter (okv mvat) itms';
   144 	  val untouched = filter eq0 itms; (* i.e. dsc only (from init)*)
   145 	  val mis = chk_mis mvat itms'' untouched pbt;
   146 	  val (pb, where_')  = Pre_Conds.check (Proof_Context.init_global thy) where_rls where_
   147 	    (pbt, I_Model.OLD_to_TEST itms'')
   148   in (length mis = 0 andalso pb, (itms'@ mis, where_')) end;
   149 
   150 (* version for tactic Refine_Problem *)
   151 fun find_match _ (pblRD: Problem.id) itms pbls (Store.Node (pI, [py], [])) =
   152     let
   153 	    val {thy, model, where_, where_rls, ...} = py
   154 	    (*TODO val where_ = map TermC.adapt_to_type where_ ...  adapt to current ctxt*)
   155 	    val (b, (itms', where_')) = match_itms thy itms (model, where_, where_rls);
   156     in
   157       if b
   158       then pbls @ [Match_ (rev (pblRD @ [pI]), (itms', where_'))]
   159       else pbls @ [NoMatch_] 
   160     end
   161   | find_match _ pblRD itms pbls (Store.Node (pI, [py], pys)) =
   162     let
   163       val {thy, model, where_, where_rls, ...} = py 
   164       val (b, (itms', where_')) = match_itms thy itms (model, where_, where_rls);
   165     in if b 
   166        then let val pbl = Match_ (rev (pblRD @ [pI]), (itms', where_'))
   167 	    in find_matchs thy (pblRD @ [pI]) itms (pbls @ [pbl]) pys end
   168        else (pbls @ [NoMatch_])
   169     end              
   170   | find_match _ _ _ _ _ = raise ERROR "find_match: uncovered fun def."
   171 and find_matchs _ _ _ pbls [] = pbls
   172   | find_matchs thy pblRD itms pbls ((p as Store.Node _) :: pts) =
   173     let
   174       val pbls' = find_match thy pblRD itms pbls p
   175     in case last_elem pbls' of
   176       Match_ _ => pbls'
   177     | NoMatch_ => find_matchs thy pblRD itms pbls' pts
   178   end;
   179 
   180 fun problem thy pblID itms =
   181   case match_found ((Store.apply (get_pbls ())) (find_match thy ((rev o tl) pblID) itms [])
   182       pblID (rev pblID)) of
   183 	  NONE => NONE
   184   | SOME (Match_ (rfd as (pI', _))) => if pblID = pI' then NONE else SOME rfd;
   185 
   186 (* 
   187   refine a problem; construct pblRD while scanning Problem.T Store.T
   188 TODO: as \<open>check_match: 'a -> .. -> 'b option\<close> could be ignorant of Store.T structure.
   189 *)
   190 fun check_match ctxt pblRD ori (Store.Node (pI, [py], [])) =
   191     let
   192       val {where_rls, model, where_, ...} = py: Problem.T
   193       val model = map (Model_Pattern.adapt_to_type ctxt) model
   194       val where_ = map (ParseC.adapt_term_to_type ctxt) where_
   195     in
   196       if M_Match.by_o_model ctxt ori (model, where_, where_rls) 
   197       then SOME (pblRD(**) @ [pI](**))
   198       else NONE
   199     end
   200   | check_match ctxt pblRD ori (Store.Node (pI, [py], pys)) =
   201     let
   202       val {where_rls, model, where_, ...} = py: Problem.T
   203       val model = map (Model_Pattern.adapt_to_type ctxt) model
   204       val where_ = map (ParseC.adapt_term_to_type ctxt) where_
   205     in
   206       if M_Match.by_o_model ctxt ori (model, where_, where_rls)
   207       then (case refins ctxt (pblRD @ [pI]) ori pys of
   208 	        SOME pblRD' => SOME pblRD'
   209 	      | NONE => SOME (pblRD (**)@ [pI](**)))
   210       else NONE
   211     end
   212   | check_match _ _ _ _ = raise ERROR "check_match: uncovered fun def."
   213 and refins _ _ _ [] = NONE
   214   | refins ctxt pblRD ori ((p as Store.Node _) :: pts) =
   215     (case check_match ctxt pblRD ori p of
   216       SOME pblRD' => SOME pblRD'
   217     | NONE => refins ctxt pblRD ori pts)
   218 
   219 \<^isac_test>\<open>
   220 (**)
   221 \<close>
   222 
   223 (* refine a problem; version providing output for math authors *)
   224 (*val refin': Proof.context -> Problem.id -> Formalise.model -> M_Match.T list -> 
   225     Probl_Def.T Store.node -> M_Match.T list*)
   226 fun refin' ctxt pblRD fmz pbls (Store.Node (pI, [py: Probl_Def.T], [])) =
   227     let
   228       val _ = (tracing o (curry op ^ "*** pass ") o strs2str) (pblRD @ [pI])
   229       val {thy, model, where_, where_rls, ...} = py 
   230       val model = map (Model_Pattern.adapt_to_type ctxt) model
   231       val where_ = map (ParseC.adapt_term_to_type ctxt) where_
   232       val (oris, _) = O_Model.init thy fmz model; (*WN020803: oris might NOT be complete here*)
   233       val (b, (itms, where_')) =
   234         M_Match.data_by_o ctxt oris (model, where_, where_rls)
   235     in                                                  
   236       if b
   237       then pbls @ [M_Match.Matches (rev (pblRD @ [pI]), P_Model.from thy (I_Model.TEST_to_OLD itms) where_')]
   238       else pbls @ [M_Match.NoMatch (rev (pblRD @ [pI]), P_Model.from thy (I_Model.TEST_to_OLD itms) where_')]
   239     end
   240   | refin' ctxt pblRD fmz pbls (Store.Node (pI, [py], pys)) =
   241     let
   242       val _ = (tracing o ((curry op ^)"*** pass ") o strs2str) (pblRD @ [pI])
   243       val {thy, model, where_, where_rls, ...} = py 
   244       val model = map (Model_Pattern.adapt_to_type ctxt) model
   245       val where_ = map (ParseC.adapt_term_to_type ctxt) where_
   246       val (oris, _) = O_Model.init thy fmz model; (*WN020803: oris might NOT be complete here*)
   247       val (b, (itms, where_')) =
   248         M_Match.data_by_o ctxt oris (model, where_, where_rls)
   249     in
   250       if b 
   251       then
   252         let val pbl = M_Match.Matches (rev (pblRD @ [pI]), P_Model.from thy (I_Model.TEST_to_OLD itms) where_')
   253 	      in refins' ctxt (pblRD @ [pI]) fmz (pbls @ [pbl]) pys end
   254       else (pbls @ [M_Match.NoMatch (rev (pblRD @ [pI]), P_Model.from thy (I_Model.TEST_to_OLD itms) where_')])
   255     end
   256   | refin' _ _ _ _ _ = raise ERROR "refin': uncovered fun def."
   257 and refins' _ _ _ pbls [] = pbls
   258   | refins' ctxt pblRD fmz pbls ((p as Store.Node _) :: pts) =
   259     let
   260       val pbls' = refin' ctxt pblRD fmz pbls p
   261     in
   262       case last_elem pbls' of
   263         M_Match.Matches _ => pbls'
   264       | M_Match.NoMatch _ => refins' ctxt pblRD fmz pbls' pts
   265     end;
   266 
   267 (* Store.apply scans Store.T only to the first hit *)
   268 (*val find_node_elem: (Probl_Def.T Store.node -> 'a) -> Store.key -> Store.key -> 'a*)
   269 fun find_node_elem x = Store.apply (get_pbls ()) x;
   270 
   271 (*for tactic Refine_Tacitly; oris are already created wrt. some pbt; ctxt overrides thy in pbt*)
   272 fun by_o_model ctxt oris pblID =
   273   let
   274     val opt = find_node_elem (check_match ctxt ((rev o tl) pblID) oris) pblID (rev pblID);
   275   in case opt of 
   276       SOME pblRD =>
   277         let val pblID': Problem.id = rev pblRD
   278 			  in if pblID' = pblID then NONE else SOME pblID' end
   279 	  | NONE => NONE
   280 	end;
   281 fun by_o_model' ctxt oris pI = perhaps (by_o_model ctxt oris) pI;
   282 
   283 (*specifically for tests*)
   284 fun by_formalise ctxt fmz pblID =
   285   find_node_elem (refin' ctxt ((rev o tl) pblID) fmz []) pblID (rev pblID);
   286 
   287 \<^isac_test>\<open>
   288 (**)
   289 \<close>
   290 
   291 (**)end(**)