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