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