src/Tools/isac/Specify/specify.sml
author wneuper <Walther.Neuper@jku.at>
Wed, 30 Aug 2023 06:37:56 +0200
changeset 60746 3ba85d40b3c7
parent 60741 22586d7fedb0
child 60752 77958bc6ed7d
permissions -rw-r--r--
prepare 2: I_Model.of_max_variant ready for use in I_Model.complete
walther@59984
     1
signature SPECIFY =
walther@59763
     2
sig
walther@59775
     3
  val find_next_step: Calc.T -> string * (Pos.pos_ * Tactic.input)
walther@59990
     4
  val do_all: Calc.T -> Calc.T 
walther@59990
     5
  val finish_phase: Calc.T -> Calc.T
walther@59990
     6
walther@60002
     7
  val item_to_add: theory -> O_Model.T -> Model_Pattern.T -> I_Model.T ->
walther@60002
     8
    (Model_Def.m_field * TermC.as_string) option
walther@60016
     9
  val by_Add_: string -> TermC.as_string -> Calc.T -> string * Calc.state_post
Walther@60578
    10
(*from isac_test for Minisubpbl*)
Walther@60575
    11
  val for_problem: Proof.context -> O_Model.T -> References.T * References.T -> I_Model.T * I_Model.T ->
walther@60019
    12
    string * (Pos.pos_ * Tactic.input)
Walther@60575
    13
  val for_method: Proof.context -> O_Model.T -> References.T * References.T -> I_Model.T * I_Model.T ->
walther@60019
    14
    string * (Pos.pos_ * Tactic.input)
Walther@60578
    15
Walther@60578
    16
\<^isac_test>\<open>
Walther@60578
    17
(**)
wenzelm@60223
    18
\<close>
walther@59763
    19
end
walther@59763
    20
walther@59763
    21
(**)
walther@59984
    22
structure Specify(**): SPECIFY(**) =
walther@59763
    23
struct
walther@59763
    24
(**)
walther@59763
    25
walther@59990
    26
(*
walther@59990
    27
  select an item in oris, notyet input in itms 
walther@59990
    28
  (precondition: in itms are only I_Model.Cor, I_Model.Sup, I_Model.Inc)
walther@60011
    29
args of item_to_add
walther@59990
    30
  thy : for?
walther@59990
    31
  oris: from formalization 'type fmz', structured for efficient access 
walther@59990
    32
  pbt : the problem-pattern to be matched with oris in order to get itms
walther@59990
    33
  itms: already input items
walther@59990
    34
*)
walther@60002
    35
fun item_to_add thy [] pbt itms = (*root (only) ori...fmz=[]*)
walther@60002
    36
    let
Walther@60477
    37
      fun test_d d (i, _, _, _, itm_) = (d = (I_Model.descriptor itm_)) andalso i <> 0
walther@60002
    38
      fun is_elem itms (_, (d, _)) = 
walther@60002
    39
        case find_first (test_d d) itms of SOME _ => true | NONE => false
walther@60002
    40
    in
walther@60002
    41
      case filter_out (is_elem itms) pbt of
walther@60002
    42
        (f, (d, _)) :: _ => SOME (f, ((UnparseC.term_in_thy thy) o Input_Descript.join) (d, []))
walther@60002
    43
      | _ => NONE
walther@60002
    44
    end
walther@60004
    45
    (* m_field is in ------vvvv *)
walther@60002
    46
  | item_to_add thy oris _ itms =
walther@60002
    47
    let
walther@60017
    48
      fun testr_vt v ori = member op= (#2 (ori : O_Model.single)) v andalso (#3 ori) <> "#undef"
walther@60017
    49
      fun testi_vt v itm = member op= (#2 (itm : I_Model.single)) v
walther@60017
    50
      fun test_id ids r = member op= ids (#1 (r : O_Model.single))
walther@60002
    51
      fun test_subset itm (_, _, _, d, ts) = 
Walther@60477
    52
        (I_Model.descriptor (#5 (itm: I_Model.single))) = d andalso subset op = (I_Model.o_model_values (#5 itm), ts)
walther@60002
    53
      fun false_and_not_Sup (_, _, false, _, I_Model.Sup _) = false
walther@60002
    54
        | false_and_not_Sup (_, _, false, _, _) = true
walther@60002
    55
        | false_and_not_Sup _ = false
Walther@60705
    56
      val v = if itms = [] then 1 else Pre_Conds.max_variant itms
walther@60011
    57
      val vors = if v = 0 then oris else filter (testr_vt v) oris
walther@60002
    58
      val vits =
walther@60002
    59
        if v = 0
walther@60002
    60
        then itms                                 (* because of dsc without dat *)
walther@60002
    61
  	    else filter (testi_vt v) itms;                             (* itms..vat *)
walther@60002
    62
      val icl = filter false_and_not_Sup vits;                    (* incomplete *)
walther@60002
    63
    in
walther@60002
    64
      if icl = [] then
walther@60002
    65
        case filter_out (test_id (map #1 vits)) vors of
walther@60002
    66
          [] => NONE
Walther@60469
    67
        | miss => SOME (O_Model.get_field_term thy (hd miss))
walther@60002
    68
      else
walther@60002
    69
        case find_first (test_subset (hd icl)) vors of
walther@60011
    70
          NONE => raise ERROR "item_to_add: types or dsc DO NOT MATCH BETWEEN fmz --- pbt"
Walther@60477
    71
        | SOME ori => SOME (I_Model.get_field_term thy ori (hd icl))
walther@60002
    72
    end
walther@60002
    73
walther@60019
    74
walther@60019
    75
(** find a next step in the specify-phase **)
walther@60021
    76
(*
Walther@60575
    77
  here should be mutual recursion between for_problem ctxt and for_method
walther@60021
    78
*)
Walther@60575
    79
fun for_problem ctxt oris ((dI', pI', mI'), (dI, pI, mI)) (pbl, met) =
walther@59763
    80
  let
walther@60019
    81
    val cpI = if pI = Problem.id_empty then pI' else pI;
walther@60154
    82
    val cmI = if mI = MethodC.id_empty then mI' else mI;
Walther@60585
    83
    val {model = pbt, where_rls, where_, ...} = Problem.from_store ctxt cpI;
Walther@60586
    84
    val {model = mpc, ...} = MethodC.from_store ctxt cmI
Walther@60741
    85
    val (preok, _) = Pre_Conds.check ctxt where_rls where_ (pbt, I_Model.OLD_to_TEST pbl);
walther@60019
    86
  in
walther@60021
    87
    if dI' = ThyC.id_empty andalso dI = ThyC.id_empty then
walther@60019
    88
      ("dummy", (Pos.Pbl, Tactic.Specify_Theory dI'))
walther@60019
    89
    else if pI' = Problem.id_empty andalso pI = Problem.id_empty then
walther@60019
    90
        ("dummy", (Pos.Pbl, Tactic.Specify_Problem pI'))
walther@60019
    91
    else
walther@60019
    92
      case find_first (I_Model.is_error o #5) pbl of
walther@60019
    93
        SOME (_, _, _, fd, itm_) =>
Walther@60676
    94
          ("dummy", (Pos.Pbl, P_Model.mk_delete (ThyC.get_theory ctxt
walther@60019
    95
            (if dI = ThyC.id_empty then dI' else dI)) fd itm_))
walther@60019
    96
      | NONE => 
Walther@60676
    97
        (case item_to_add (ThyC.get_theory ctxt
Walther@60578
    98
            (if dI = ThyC.id_empty then dI' else dI)) oris pbt pbl of
walther@60019
    99
           SOME (fd, ct') => ("dummy", (Pos.Pbl, P_Model.mk_additem fd ct'))
walther@60019
   100
         | NONE => (*pbl-items complete*)        
walther@60019
   101
           if not preok then ("dummy", (Pos.Pbl, Tactic.Refine_Problem pI'))
Walther@60726
   102
           (*this is an ERROR fall through ------^^^^^^^^^^^^^^^^^^^^^ for Pre_Conds, redesign ?*)
walther@60019
   103
           else if dI = ThyC.id_empty then ("dummy", (Pos.Pbl, Tactic.Specify_Theory dI'))
walther@60019
   104
           else if pI = Problem.id_empty then ("dummy", (Pos.Pbl, Tactic.Specify_Problem pI'))
walther@60154
   105
           else if mI = MethodC.id_empty then ("dummy", (Pos.Pbl, Tactic.Specify_Method mI'))
walther@60019
   106
           else
walther@60019
   107
            case find_first (I_Model.is_error o #5) met of
walther@60019
   108
              SOME (_, _, _, fd, itm_) =>
Walther@60676
   109
                 ("dummy", (Pos.Met, P_Model.mk_delete (ThyC.get_theory ctxt dI) fd itm_))
walther@60019
   110
            | NONE => 
Walther@60676
   111
              (case item_to_add (ThyC.get_theory ctxt dI) oris mpc met of
walther@60019
   112
    	          SOME (fd, ct') =>
Walther@60586
   113
                   ("dummy", (Pos.Met, P_Model.mk_additem fd ct')) (*30.8.01: where_?!?*)
walther@60021
   114
    		      | NONE => ("dummy", (Pos.Met, Tactic.Apply_Method mI))))
walther@60019
   115
  end
walther@60019
   116
Walther@60706
   117
fun for_method ctxt oris ((dI', pI', mI'), (dI, pI, mI)) (_, met) =
walther@60019
   118
  let
walther@60154
   119
    val cmI = if mI = MethodC.id_empty then mI' else mI;
Walther@60586
   120
    val {model = mpc, where_rls, where_, ...} = MethodC.from_store ctxt cmI;
Walther@60741
   121
    val (preok, _) = Pre_Conds.check ctxt where_rls where_ (mpc, I_Model.OLD_to_TEST met);
walther@60019
   122
  in
walther@60019
   123
    (case find_first (I_Model.is_error o #5) met of
walther@60019
   124
      SOME (_,_,_, fd, itm_) =>
Walther@60676
   125
        ("dummy", (Pos.Met, P_Model.mk_delete (ThyC.get_theory ctxt
Walther@60578
   126
            (if dI = ThyC.id_empty then dI' else dI)) fd itm_))
walther@60019
   127
    | NONE => 
Walther@60676
   128
      case item_to_add (ThyC.get_theory ctxt 
Walther@60578
   129
          (if dI = ThyC.id_empty then dI' else dI)) oris mpc met of
walther@60019
   130
        SOME (fd, ct') =>
walther@60019
   131
          ("dummy", (Pos.Met, P_Model.mk_additem fd ct')) (*->->*)
walther@60019
   132
      | NONE => 
walther@60019
   133
        (if dI = ThyC.id_empty then ("dummy", (Pos.Met, Tactic.Specify_Theory dI'))
walther@60019
   134
         else if pI = Problem.id_empty then ("dummy", (Pos.Met, Tactic.Specify_Problem pI'))
walther@60019
   135
         else if not preok then ("dummy", (Pos.Met, Tactic.Specify_Method mI))
walther@60019
   136
         else ("dummy", (Pos.Met, Tactic.Apply_Method mI))))
walther@60019
   137
  end
walther@60019
   138
walther@60019
   139
(*
walther@60019
   140
  on finding a next step switching from problem to method or vice versa is possible,
walther@60019
   141
  because the user is free to switch and edit the respective models independently.
walther@60019
   142
TODO: this free switch is NOT yet implemented; e.g. 
Walther@60575
   143
  preok is relevant for problem + method, i.e. in for_problem ctxt + for_method
walther@60019
   144
*)
walther@60019
   145
fun find_next_step (pt, pos as (_, p_)) =
walther@60019
   146
  let
walther@60019
   147
    val {meth = met, origin = origin as (oris, o_refs as (_, pI', mI'), _), probl = pbl,
walther@60019
   148
      spec = refs, ...} = Calc.specify_data (pt, pos);
Walther@60556
   149
    val ctxt = Ctree.get_ctxt pt pos
walther@60011
   150
    in
walther@60019
   151
      if Ctree.just_created (pt, pos) andalso origin <> Ctree.e_origin then
walther@60011
   152
        case mI' of
walther@60011
   153
          ["no_met"] => ("ok", (Pos.Pbl, Tactic.Refine_Tacitly pI'))
walther@60011
   154
        | _ => ("ok", (Pos.Pbl, Tactic.Model_Problem))
walther@60019
   155
      else if p_ = Pos.Pbl then
Walther@60575
   156
        for_problem ctxt oris (o_refs, refs) (pbl, met)
walther@60011
   157
      else
Walther@60575
   158
        for_method ctxt oris (o_refs, refs) (pbl, met)
walther@60019
   159
    end
walther@60019
   160
walther@60019
   161
walther@60021
   162
(** tools **)
walther@59763
   163
Walther@60556
   164
fun by_Add_  m_field ct (pt, pos as (_, p_)) =
walther@60016
   165
  let
walther@60097
   166
    val (met, oris, (_, pI', mI'), pbl, (_, pI, mI), ctxt) = SpecificationC.get_data (pt, pos)
walther@60016
   167
    val (i_model, m_patt) =
walther@60016
   168
       if p_ = Pos.Met then
walther@60016
   169
         (met,
Walther@60586
   170
           (if mI = MethodC.id_empty then mI' else mI) |> MethodC.from_store ctxt |> #model)
walther@60016
   171
       else
walther@60016
   172
         (pbl,
Walther@60585
   173
           (if pI = Problem.id_empty then pI' else pI) |> Problem.from_store ctxt |> #model)
walther@60016
   174
    in
walther@60016
   175
      case I_Model.check_single ctxt m_field oris i_model m_patt ct of
walther@60016
   176
        I_Model.Add i_single => (*..union old input *)
walther@60016
   177
	        let
walther@60016
   178
	          val i_model' = I_Model.add_single (Proof_Context.theory_of ctxt) i_single i_model
Walther@60477
   179
            val tac' = I_Model.make_tactic m_field (ct, i_model')
walther@60016
   180
	          val  (_, _, _, pt') =  Specify_Step.add tac' (Istate_Def.Uistate, ctxt) (pt, pos)
walther@60016
   181
	        in
Walther@60611
   182
            ("ok", ([(Tactic.input_from_T ctxt tac', tac', (pos, (Istate_Def.Uistate, ctxt)))],
walther@60021
   183
              [], (pt', pos)))
walther@60016
   184
          end
walther@60016
   185
      | I_Model.Err msg => (msg, ([], [], (pt, pos)))
walther@60016
   186
    end
walther@59990
   187
walther@59990
   188
(* complete _NON_empty calc-head for autocalc (sub-)pbl from oris
walther@59990
   189
  + met from fmz; assumes pos on PblObj, meth = []                    *)
walther@59990
   190
fun finish_phase (pt, pos as (p, p_)) =
walther@59990
   191
  let
walther@59990
   192
    val _ = if p_ <> Pos.Pbl 
walther@59990
   193
	    then raise ERROR ("###finish_phase: only impl.for Pbl, called with " ^ Pos.pos'2str pos)
walther@59990
   194
	    else ()
walther@59990
   195
	  val (oris, ospec, probl, spec) = case Ctree.get_obj I pt p of
walther@59990
   196
	    Ctree.PblObj {origin = (oris, ospec, _), probl, spec, ...} => (oris, ospec, probl, spec)
walther@59990
   197
	  | _ => raise ERROR "finish_phase: unvered case get_obj"
Walther@60494
   198
  	val (_, pI, mI) = References.select_input ospec spec
Walther@60556
   199
  	val ctxt = Ctree.get_ctxt pt pos
Walther@60586
   200
  	val mpc = (#model o MethodC.from_store ctxt) mI
Walther@60586
   201
  	val model = (#model o Problem.from_store ctxt) pI
Walther@60586
   202
  	val (pits, mits) = I_Model.complete_method (oris, mpc, model, probl)
walther@59990
   203
    val pt = Ctree.update_pblppc pt p pits
walther@59990
   204
	  val pt = Ctree.update_metppc pt p mits
walther@59990
   205
  in (pt, (p, Pos.Met)) end
Walther@60556
   206
Walther@60654
   207
(*
Walther@60654
   208
  do all specification in one single step:
Walther@60746
   209
  bypass input of Problem.model and go immediately for MethodC: I_Model.complete'
walther@59990
   210
*)
Walther@60654
   211
fun do_all (pt, (*old* )pos as( *old*) (p, _)) =
walther@59990
   212
  let
Walther@60654
   213
    val (o_model, o_refs as (_, _, met_id), ctxt) = case Ctree.get_obj I pt p of
Walther@60654
   214
      Ctree.PblObj {origin = (o_model, o_refs, _), ctxt, ...}
Walther@60654
   215
        => (o_model, o_refs, ctxt)
Walther@60746
   216
    | _ => raise ERROR "Specify.do_all: uncovered case get_obj"
Walther@60654
   217
    val mod_pat = MethodC.from_store ctxt met_id |> #model
Walther@60654
   218
    val i_model = map (I_Model.complete' mod_pat) o_model
Walther@60746
   219
      (*no parse, ^^^ takes existing terms; ctxt already created by O_Model.init*)
Walther@60654
   220
    val (pt, _) = Ctree.cupdate_problem pt p (o_refs, i_model, i_model, ctxt)
walther@59990
   221
  in
walther@59990
   222
    (pt, (p, Pos.Met))
walther@59990
   223
  end
walther@59990
   224
walther@59946
   225
(**)end(**)