src/Tools/isac/Specify/refine.sml
author wneuper <Walther.Neuper@jku.at>
Tue, 21 Jun 2022 16:04:43 +0200
changeset 60477 4ac966aaa785
parent 60469 89e1d8a633bb
child 60478 feed17a67534
permissions -rw-r--r--
rename functions in i-model.sml
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@59960
     5
Operations on models.
walther@59960
     6
*)
walther@59960
     7
walther@59960
     8
signature REFINE_PROBLEM =
walther@59960
     9
sig
walther@59968
    10
  val problem: theory -> Problem.id -> I_Model.T -> (Problem.id * (I_Model.T * Pre_Conds.T)) option
walther@59968
    11
walther@59968
    12
  val refine_ori : O_Model.T -> Problem.id -> Problem.id option
walther@59968
    13
  val refine_ori' : O_Model.T -> Problem.id -> Problem.id
walther@59960
    14
wenzelm@60223
    15
\<^isac_test>\<open>
walther@59984
    16
  val refine : Formalise.model -> Problem.id -> M_Match.T list
walther@60021
    17
  datatype match_ = Match_ of Problem.id * (( I_Model.T) * (Pre_Conds.T)) | NoMatch_;
walther@60021
    18
  val refined_: match_ list -> match_ option
walther@60021
    19
  val refin'': theory -> Problem.id -> I_Model.T -> match_ list -> Probl_Def.T Store.node -> match_ list
walther@60021
    20
  val refins'': theory -> Problem.id -> I_Model.T -> match_ list -> Probl_Def.T Store.node list -> match_ list
wenzelm@60223
    21
\<close>
walther@59960
    22
end
walther@59960
    23
walther@59965
    24
(**)
walther@59960
    25
structure Refine(**) : REFINE_PROBLEM(**) =
walther@59960
    26
struct
walther@59965
    27
(**)
walther@59960
    28
walther@59960
    29
datatype match_ = 
walther@59963
    30
  Match_ of Problem.id * (( I_Model.T) * (Pre_Conds.T))
walther@59960
    31
| NoMatch_;
walther@59960
    32
walther@59960
    33
fun is_matches_ (Match_ _) = true
walther@59960
    34
  | is_matches_ _ = false;
walther@59960
    35
walther@59960
    36
fun refined_ ms = ((find_first is_matches_) o rev) ms;
walther@59960
    37
walther@59960
    38
fun eq1 d (_, (d', _)) = (d = d');
walther@59960
    39
walther@59960
    40
fun chk_ (_: theory) pbt (i, vats, b, f, I_Model.Cor ((d, vs), _)) =
walther@59960
    41
      (case find_first (eq1 d) pbt of 
walther@59960
    42
        SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor ((d, vs), (id, I_Model.pbl_ids' d vs)))
walther@59960
    43
      | NONE =>  (i, vats, false, f, I_Model.Sup (d, vs)))
walther@59960
    44
  | chk_ _ pbt (i, vats, b, f, I_Model.Inc ((d, vs), _)) =
walther@59960
    45
      (case find_first (eq1 d) pbt of 
walther@59960
    46
        SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor ((d, vs), (id, I_Model.pbl_ids' d vs)))
walther@59960
    47
      | NONE => (i, vats, false, f, I_Model.Sup (d, vs)))
walther@59960
    48
  | chk_ _ _ (itm as (_, _, _, _, I_Model.Syn _)) = itm
walther@59960
    49
  | chk_ _ _ (itm as (_, _, _, _, I_Model.Typ _)) = itm
walther@59960
    50
  | chk_ _ pbt (i, vats, b, f, I_Model.Sup (d, vs)) =
walther@59960
    51
      (case find_first (eq1 d) pbt of 
walther@59960
    52
        SOME (_, (_, id)) => (i, vats, b, f, I_Model.Cor ((d,vs), (id, I_Model.pbl_ids' d vs)))
walther@59960
    53
      | NONE => (i, vats, false, f, I_Model.Sup (d, vs)))
walther@59960
    54
  | chk_ _ pbt (i, vats, _, f, I_Model.Mis (d, vs)) =
walther@59960
    55
      (case find_first (eq1 d) pbt of
walther@59962
    56
        SOME (_, _) => raise ERROR "chk_: ((i,vats,b,f,I_Model.Cor ((d,vs),(id, I_Model.pbl_ids' d vs))):itm)"
walther@59960
    57
      | NONE => (i, vats, false, f, I_Model.Sup (d, [vs])))
walther@59960
    58
  | chk_ _ _ _ = raise ERROR "chk_: uncovered fun def.";
walther@59960
    59
Walther@60477
    60
fun eq2 (_, (d, _)) (_, _, _, _, itm_) = d = I_Model.descriptor itm_;
walther@59960
    61
fun eq0 (0, _, _, _, _) = true
walther@59960
    62
  | eq0 _ = false;
walther@59960
    63
fun max_i i [] = i
walther@59960
    64
  | max_i i ((id, _, _, _, _) :: is) = if i > id then max_i i is else max_i id is;
walther@59960
    65
fun max_id [] = 0
walther@59960
    66
  | max_id ((id, _, _, _, _) :: is) = max_i id is;
walther@59960
    67
fun add_idvat itms _ _ [] = itms
walther@59960
    68
  | add_idvat itms i mvat ((_, _, b, f, itm_) :: its) =
walther@59960
    69
    add_idvat (itms @ [(i, [], b, f, itm_)]) (i + 1) mvat its;
walther@59960
    70
walther@59960
    71
(* find elements of pbt not contained in itms;
walther@59960
    72
   if such one is untouched, return this one, otherwise create new itm *)
walther@59960
    73
fun chk_m itms untouched (p as (f, (d, id))) = 
walther@59960
    74
  case find_first (eq2 p) itms of
walther@59960
    75
	  SOME _ => []
walther@59960
    76
  | NONE =>
walther@59960
    77
      (case find_first (eq2 p) untouched of
walther@59960
    78
        SOME itm => [itm]
walther@59960
    79
      | NONE => [(0, [], false, f, I_Model.Mis (d, id))]);
walther@59960
    80
walther@59960
    81
fun chk_mis mvat itms untouched pbt = 
walther@59960
    82
    let val mis = (flat o (map (chk_m itms untouched))) pbt; 
walther@59960
    83
        val mid = max_id itms;
walther@59960
    84
    in add_idvat [] (mid + 1) mvat mis end;
walther@59960
    85
walther@59960
    86
(* check a problem (ie. itm list) for matching a problemtype, 
Walther@60477
    87
   takes the I_Model.max_variant for concluding completeness (could be another!) *)
walther@59960
    88
fun match_itms thy itms (pbt, pre, prls) = 
walther@59960
    89
  let
walther@59960
    90
    fun okv mvat (_, vats, b, _, _) = member op = vats mvat andalso b;
walther@59960
    91
    val itms' = map (chk_ thy pbt) itms; (* all found are #3 true *)
Walther@60477
    92
    val mvat = I_Model.max_variant itms';
walther@59960
    93
	  val itms'' = filter (okv mvat) itms';
walther@59960
    94
	  val untouched = filter eq0 itms; (* i.e. dsc only (from init)*)
walther@59960
    95
	  val mis = chk_mis mvat itms'' untouched pbt;
walther@60018
    96
	  val (pb, pre')  = Pre_Conds.check prls pre itms'' mvat
walther@59960
    97
  in (length mis = 0 andalso pb, (itms'@ mis, pre')) end;
walther@59960
    98
walther@59960
    99
(* refine a problem; version for tactic Refine_Problem *)
walther@59960
   100
fun refin'' _ (pblRD: Problem.id) itms pbls (Store.Node (pI, [py], [])) =
walther@59960
   101
    let
walther@59960
   102
	    val {thy, ppc, where_, prls, ...} = py 
walther@59960
   103
	    val (b, (itms', pre')) = match_itms thy itms (ppc, where_, prls);
walther@59960
   104
    in
walther@59960
   105
      if b
walther@59960
   106
      then pbls @ [Match_ (rev (pblRD @ [pI]), (itms', pre'))]
walther@59960
   107
      else pbls @ [NoMatch_] 
walther@59960
   108
    end
walther@59960
   109
  | refin'' _ pblRD itms pbls (Store.Node (pI, [py], pys)) =
walther@59960
   110
    let
walther@59960
   111
      val {thy, ppc, where_, prls, ...} = py 
walther@59960
   112
      val (b, (itms', pre')) = match_itms thy itms (ppc, where_, prls);
walther@59960
   113
    in if b 
walther@59960
   114
       then let val pbl = Match_ (rev (pblRD @ [pI]), (itms', pre'))
walther@59960
   115
	    in refins'' thy (pblRD @ [pI]) itms (pbls @ [pbl]) pys end
walther@59960
   116
       else (pbls @ [NoMatch_])
walther@59960
   117
    end
walther@59965
   118
  | refin'' _ _ _ _ _ = raise ERROR "refin'': uncovered fun def."
walther@59960
   119
and refins'' _ _ _ pbls [] = pbls
walther@59960
   120
  | refins'' thy pblRD itms pbls ((p as Store.Node _) :: pts) =
walther@59960
   121
    let
walther@59960
   122
      val pbls' = refin'' thy pblRD itms pbls p
walther@59960
   123
    in case last_elem pbls' of
walther@59960
   124
      Match_ _ => pbls'
walther@59960
   125
    | NoMatch_ => refins'' thy pblRD itms pbls' pts
walther@59960
   126
  end;
walther@59960
   127
walther@59960
   128
fun problem thy pblID itms =
walther@60324
   129
  case refined_ ((Store.apply (get_ptyps ())) (refin'' thy ((rev o tl) pblID) itms [])
walther@60324
   130
      pblID (rev pblID)) of
walther@59960
   131
	  NONE => NONE
walther@59960
   132
  | SOME (Match_ (rfd as (pI', _))) => if pblID = pI' then NONE else SOME rfd
walther@59960
   133
  | _ => raise ERROR "Refine.problem: uncovered case refined_";
walther@59960
   134
walther@59968
   135
(* refine a problem; construct pblRD while scanning *)
walther@59968
   136
fun refin pblRD ori (Store.Node (pI, [py], [])) =
walther@59984
   137
    if M_Match.match_oris (#thy py) (#prls py) ori (#ppc py, #where_ py) 
walther@59968
   138
    then SOME (pblRD @ [pI])
walther@59968
   139
    else NONE
walther@59968
   140
  | refin pblRD ori (Store.Node (pI, [py], pys)) =
walther@59984
   141
    if M_Match.match_oris (#thy py) (#prls py) ori (#ppc py, #where_ py) 
walther@59968
   142
    then (case refins (pblRD @ [pI]) ori pys of
walther@59968
   143
	      SOME pblRD' => SOME pblRD'
walther@59968
   144
	    | NONE => SOME (pblRD @ [pI]))
walther@59968
   145
    else NONE
walther@59968
   146
  | refin _ _ _ = raise ERROR "refin: uncovered fun def."
walther@59968
   147
and refins _ _ [] = NONE
walther@59968
   148
  | refins pblRD ori ((p as Store.Node _) :: pts) =
walther@59968
   149
    (case refin pblRD ori p of
walther@59968
   150
      SOME pblRD' => SOME pblRD'
walther@59968
   151
    | NONE => refins pblRD ori pts);
walther@59968
   152
walther@59968
   153
(* refine a problem; version providing output for math-experts *)
walther@60268
   154
\<^isac_test>\<open>
walther@60268
   155
fun refin' pblRD fmz pbls (Store.Node (pI, [py: Probl_Def.T], [])) =
walther@59968
   156
    let
walther@59968
   157
      val _ = (tracing o (curry op ^ "*** pass ") o strs2str) (pblRD @ [pI])
walther@59968
   158
      val {thy, ppc, where_, prls, ...} = py 
Walther@60469
   159
      val oris = O_Model.init thy fmz ppc(* |> #1*);
walther@59968
   160
      (* WN020803: itms!: oris might _not_ be complete here *)
walther@59984
   161
      val (b, (itms, pre')) = M_Match.match_oris' thy oris (ppc, where_, prls)
walther@59968
   162
    in
walther@59968
   163
      if b
walther@59984
   164
      then pbls @ [M_Match.Matches (rev (pblRD @ [pI]), P_Model.from thy itms pre')]
walther@59984
   165
      else pbls @ [M_Match.NoMatch (rev (pblRD @ [pI]), P_Model.from thy itms pre')]
walther@59968
   166
    end
walther@59968
   167
  | refin' pblRD fmz pbls (Store.Node (pI, [py], pys)) =
walther@59968
   168
    let
walther@59968
   169
      val _ = (tracing o ((curry op ^)"*** pass ") o strs2str) (pblRD @ [pI])
walther@59968
   170
      val {thy, ppc, where_, prls, ...} = py 
Walther@60469
   171
      val oris = O_Model.init thy fmz ppc(* |> #1*);
walther@59968
   172
      (* WN020803: itms!: oris might _not_ be complete here *)
walther@59984
   173
      val(b, (itms, pre')) = M_Match.match_oris' thy oris (ppc,where_,prls);
walther@59968
   174
    in
walther@59968
   175
      if b 
walther@59968
   176
      then
walther@59984
   177
        let val pbl = M_Match.Matches (rev (pblRD @ [pI]), P_Model.from thy itms pre')
walther@59968
   178
	      in refins' (pblRD @ [pI]) fmz (pbls @ [pbl]) pys end
walther@59984
   179
      else (pbls @ [M_Match.NoMatch (rev (pblRD @ [pI]), P_Model.from thy itms pre')])
walther@59968
   180
    end
walther@59968
   181
  | refin' _ _ _ _ = raise ERROR "refin': uncovered fun def."
walther@59968
   182
and refins' _ _ pbls [] = pbls
walther@59968
   183
  | refins' pblRD fmz pbls ((p as Store.Node _) :: pts) =
walther@59968
   184
    let
walther@59968
   185
      val pbls' = refin' pblRD fmz pbls p
walther@59968
   186
    in
walther@59968
   187
      case last_elem pbls' of
walther@59984
   188
        M_Match.Matches _ => pbls'
walther@59984
   189
      | M_Match.NoMatch _ => refins' pblRD fmz pbls' pts
walther@59968
   190
    end;
walther@60268
   191
\<close>
walther@59968
   192
walther@59968
   193
(* apply a fun to a ptyps node *)
walther@59968
   194
fun app_ptyp x = Store.apply (get_ptyps ()) x;
walther@59968
   195
walther@59968
   196
(* for tactic Refine_Tacitly
walther@59968
   197
   oris are already created wrt. some pbt; pbt contains thy for parsing *)
walther@59968
   198
fun refine_ori oris pblID =
walther@59968
   199
  let
walther@59968
   200
    val opt = app_ptyp (refin ((rev o tl) pblID) oris) pblID (rev pblID);
walther@59968
   201
    in case opt of 
walther@59968
   202
      SOME pblRD =>
walther@59968
   203
        let val pblID': Problem.id = rev pblRD
walther@59968
   204
			  in if pblID' = pblID then NONE else SOME pblID' end
walther@59968
   205
	  | NONE => NONE
walther@59968
   206
	end;
walther@59969
   207
fun refine_ori' oris pI = perhaps (refine_ori oris) pI;
walther@59968
   208
walther@59968
   209
(* for math-authoring and test; TODO: needs thy for parsing fmz *)
walther@60268
   210
\<^isac_test>\<open>
walther@59968
   211
fun refine fmz pblID =
walther@59968
   212
  app_ptyp (refin' ((rev o tl) pblID) fmz []) pblID (rev pblID);
walther@60268
   213
\<close>
walther@59968
   214
walther@59965
   215
(**)end(**)