src/Tools/isac/Specify/pre-conditions.sml
author wneuper <Walther.Neuper@jku.at>
Mon, 11 Dec 2023 17:26:30 +0100
changeset 60782 e797d1bdfe37
parent 60778 41abd196342a
permissions -rw-r--r--
eliminate the intermediate *_POS
Walther@60605
     1
(* Title:  Specify/pre-conds.sml
walther@59960
     2
   Author: Walther Neuper 110226
Walther@60705
     3
   (c) due to copyrigh,t terms
walther@59960
     4
*)
walther@59960
     5
walther@59960
     6
signature PRE_CONDITIONS =
walther@59960
     7
sig
walther@59963
     8
  type T
Walther@60605
     9
  type unchecked
Walther@60741
    10
  type unchecked_pos
Walther@60705
    11
  type checked
Walther@60741
    12
  type checked_pos
Walther@60705
    13
Walther@60705
    14
  type env_subst
Walther@60705
    15
  type env_eval
Walther@60556
    16
  type input
Walther@60705
    17
Walther@60673
    18
  val to_string : Proof.context -> T -> string
Walther@60740
    19
  val eval: Proof.context -> Rule_Set.T -> bool * term -> bool * term
walther@59967
    20
Walther@60782
    21
  val environment: Model_Pattern.T -> Model_Def.i_model -> Env.T
Walther@60782
    22
  val make_environments: Model_Pattern.T -> Model_Def.i_model -> Env.T * (env_subst * env_eval)
Walther@60782
    23
  val make_envs_preconds: (Model_Pattern.single * Model_Def.i_model_single) list ->
Walther@60747
    24
    ((term * term) * (term * term)) list
Walther@60740
    25
Walther@60741
    26
  val check_pos: Proof.context -> Rule_Set.T -> unchecked_pos -> 
Walther@60782
    27
    Model_Pattern.T * Model_Def.i_model -> checked_pos
Walther@60782
    28
  val check_internal: Proof.context -> Model_Def.i_model -> (Pos.pos_ * References_Def.id)
Walther@60756
    29
    -> checked
Walther@60741
    30
  val check_envs: Proof.context -> Rule_Set.T -> unchecked -> Env.T * (env_subst * env_eval)
Walther@60732
    31
    -> checked
Walther@60741
    32
  val check: Proof.context -> Rule_Set.T -> unchecked ->
Walther@60782
    33
    Model_Pattern.T * Model_Def.i_model -> checked
Walther@60706
    34
Walther@60756
    35
(*/----- from isac_test for Minisubpbl*)
Walther@60782
    36
  val get_equal_descr: Model_Def.i_model -> Model_Pattern.single ->
Walther@60782
    37
    (Model_Pattern.single * Model_Def.i_model_single) list
Walther@60782
    38
  val unchecked_OLD_to: term list -> (term * Position.T) list
Walther@60705
    39
Walther@60710
    40
  val all_lhs_atoms: term list -> bool
Walther@60766
    41
  val handle_lists: term -> Model_Def.values -> Env.T
Walther@60782
    42
  val filter_variants': Model_Def.i_model -> Model_Def.variant -> Model_Def.i_model
Walther@60741
    43
  val switch_type: Model_Def.descriptor -> term list -> Model_Def.descriptor;
Walther@60782
    44
  val discern_feedback: term -> Model_Def.i_model_feedback ->
Walther@60728
    45
    ((term * term) * (term * term)) list
Walther@60766
    46
  val discern_typ: term -> Model_Def.descriptor * term list ->
Walther@60728
    47
    ((term * term) * (term * term)) list
Walther@60710
    48
Walther@60782
    49
  val mk_env_model: term -> Model_Def.i_model_feedback -> Env.T
Walther@60782
    50
  val make_env_model: (Model_Pattern.single * Model_Def.i_model_single) list -> Env.T
Walther@60740
    51
Walther@60782
    52
  val get_values: Model_Def.i_model_feedback -> Model_Def.values
Walther@60782
    53
  val get_descr_vnt: Model_Def.descriptor -> Model_Def.variants -> Model_Def.i_model ->
Walther@60782
    54
    Model_Def.i_model_single
Walther@60782
    55
  val get_descr_vnt': Model_Def.i_model_feedback -> Model_Def.variants -> O_Model.T ->
Walther@60749
    56
    O_Model.T
Walther@60756
    57
(*\----- from isac_test for Minisubpbl*)
Walther@60747
    58
Walther@60747
    59
\<^isac_test>\<open>
Walther@60740
    60
(**)
wenzelm@60223
    61
\<close>
walther@59960
    62
end
Walther@60722
    63
                 
walther@59965
    64
(**)
walther@59960
    65
structure Pre_Conds(**) : PRE_CONDITIONS(**) =
walther@59960
    66
struct
walther@59965
    67
(**)
Walther@60706
    68
open Model_Def
walther@59960
    69
Walther@60673
    70
type T = Pre_Conds_Def.T;  (*= (bool * term) list;*)
Walther@60605
    71
type unchecked = term list
Walther@60741
    72
type unchecked_pos = (term * Position.T) list
Walther@60705
    73
type checked = bool * (bool * term) list
Walther@60741
    74
type checked_pos = bool * ((bool * (term * Position.T)) list)
Walther@60705
    75
Walther@60715
    76
(* 
Walther@60715
    77
  we have three kinds of Env.T in the specification-phase:
Walther@60758
    78
(*1*) Env.T produced by Pre_Conds.make_environments and required to create I_Model.T from
Walther@60715
    79
    Model_Pattern.T.
Walther@60715
    80
                       Env.T                  / (Constants, fixes)  in Model_Pattern.T
Walther@60715
    81
                       e.g.[(fixes, [r = 7])] |
Walther@60722
    82
                                              > (Constants, [<r = 7>]) in O/I_Model.T       *)
Walther@60715
    83
Walther@60715
    84
(*2*) type env_subst = Env.T (*               / 0 < fixes           in Problem.{where_, ...}
Walther@60715
    85
                       eg. [(fixes, r)]       |
Walther@60715
    86
                                              > 0 < r *)
Walther@60715
    87
(*3*) type env_eval =  Env.T (*               |
Walther@60715
    88
                       eg. [(r, 7)]           |
Walther@60715
    89
                                              > 0 < 7 \<longrightarrow> true
Walther@60715
    90
Walther@60715
    91
  (*1*) is required to produce (*2*) and (*3*); thus respective code is shifted to Pre_Conds.
Walther@60758
    92
  (*2*) and (*3*) are produced from Pre_Conds.make_environments by restricting to "#Given".
Walther@60715
    93
  
Walther@60715
    94
  There is a typing problem, probably to be solved by a language for Specification in the future:
Walther@60715
    95
  term <fixes> in (*1*) has type "bool list"
Walther@60715
    96
  term <fixes> in (*2*) has type "real". So for the transition from (*1*) to (*2..3*)
Walther@60715
    97
    fun switch_type is required.
Walther@60715
    98
  The transition requires better modelling by a novel language for Specification.
Walther@60715
    99
*)
Walther@60715
   100
Walther@60605
   101
type input = TermC.as_string list;
walther@59963
   102
Walther@60756
   103
Walther@60740
   104
(** tools **)
Walther@60740
   105
Walther@60675
   106
fun to_str ctxt (b, t) = pair2str (bool2str b, UnparseC.term ctxt t);
Walther@60673
   107
fun to_string ctxt pres = strs2str' (map (linefeed o (to_str ctxt)) pres);
walther@59960
   108
Walther@60590
   109
fun eval _ _ (false, where_) = (false, where_) (*NOT ALL Free's have been substituted*)
Walther@60590
   110
  | eval ctxt where_rls (true, where_) =
Walther@60590
   111
    if Rewrite.eval_true ctxt [where_] where_rls
Walther@60706
   112
    then (true, where_)
Walther@60706
   113
    else (false, where_);
walther@59960
   114
Walther@60712
   115
Walther@60740
   116
(** find the maximal variant within an I_Model.T **)
Walther@60705
   117
Walther@60706
   118
fun get_equal_descr i_model (m_patt_single as (_, (descr, _))) =
Walther@60706
   119
  let
Walther@60760
   120
    val equal_descr = 
Walther@60767
   121
      filter (fn i_single => case get_descr_opt i_single of
Walther@60770
   122
          NONE => false
Walther@60760
   123
        | SOME descr' => descr' = descr) i_model
Walther@60706
   124
    in
Walther@60760
   125
      (map (pair m_patt_single) equal_descr)
Walther@60706
   126
    end
Walther@60712
   127
Walther@60782
   128
fun get_values (Cor (_, values)) = values
Walther@60782
   129
  | get_values (Syn _) = raise ERROR "Pre_Conds.get_values not for Syn"
Walther@60782
   130
  | get_values (Inc (_, values)) = values
Walther@60782
   131
  | get_values (Sup (_, values)) = values
Walther@60763
   132
Walther@60760
   133
(*
Walther@60760
   134
  get an appropriate (description, variant)-item from i_model, otherwise return empty item,
Walther@60760
   135
  i.e. this function produces items with Sup.
Walther@60760
   136
*)
Walther@60747
   137
fun get_descr_vnt descr vnts i_model =
Walther@60747
   138
  let
Walther@60767
   139
    val equal_descr = filter (fn (_, _, _, _, (feedb, _)) => case get_dscr_opt feedb of NONE => false
Walther@60747
   140
      | SOME descr' => if descr = descr' then true else false) i_model 
Walther@60747
   141
  in
Walther@60749
   142
    case filter (fn (_, vnts', _, _, _) => inter op= vnts' vnts <> []) equal_descr of
Walther@60782
   143
      [] => (0, [], false, "i_model_empty", (Sup (descr, []), Position.none))
Walther@60749
   144
    | items => Library.the_single items (*only applied to model_patt, which has each descr once*)
Walther@60747
   145
  end
Walther@60747
   146
(*
Walther@60747
   147
  get an appropriate (description, variant) item from o_model;
Walther@60782
   148
  called in case of item in met_imod is_empty_single
Walther@60747
   149
  (i.e. was not transferred pbl_mod by \<open>fun get_descr_vnt\<close>).
Walther@60747
   150
*)
Walther@60747
   151
fun get_descr_vnt' feedb vnts o_model =
Walther@60753
   152
  filter (fn (_, vnts', _, descr', _) =>
Walther@60767
   153
    case get_dscr_opt feedb of
Walther@60753
   154
      SOME descr => if descr' = descr andalso inter op= vnts' vnts <> [] then true else false
Walther@60753
   155
    | NONE => false) o_model
Walther@60747
   156
Walther@60740
   157
(*  all_lhs_atoms: term list -> bool*)
Walther@60740
   158
fun all_lhs_atoms ts = fold (curry and_) (map (fn t =>
Walther@60740
   159
  if can TermC.lhs t andalso not (TermC.is_num (TermC.lhs t))
Walther@60740
   160
  then TermC.is_atom (TermC.lhs t)
Walther@60740
   161
  else false) ts) true
Walther@60706
   162
Walther@60769
   163
fun handle_lists id values = [(id, values_to_present values)]
Walther@60726
   164
Walther@60782
   165
fun mk_env_model _ (Model_Def.Cor (_, [])) = []
Walther@60782
   166
  | mk_env_model id (Model_Def.Cor (_, ts)) = handle_lists id ts
Walther@60782
   167
  | mk_env_model _ (Model_Def.Syn _) = [] (*TODO handle correct list elements*)
Walther@60782
   168
  | mk_env_model _ (Model_Def.Inc (_, [])) = []
Walther@60782
   169
  | mk_env_model id (Model_Def.Inc (_, ts)) = handle_lists id ts
Walther@60782
   170
  | mk_env_model _ (Model_Def.Sup _) = []
Walther@60722
   171
fun make_env_model equal_descr_pairs =
Walther@60721
   172
  map (fn ((_, (_, id)), (_, _, _, _, (feedb, _)))
Walther@60722
   173
        => (mk_env_model id feedb)) equal_descr_pairs
Walther@60721
   174
  |> flat
Walther@60722
   175
Walther@60741
   176
fun switch_type descr [] = descr
Walther@60741
   177
  | switch_type (Free (id_string, _)) ts =
Walther@60724
   178
    Free (id_string, ts |> hd |> TermC.lhs |> type_of)
Walther@60741
   179
  | switch_type descr _ = raise ERROR ("switch_type undefined argument " ^
Walther@60722
   180
      quote (UnparseC.term (ContextC.for_ERROR ()) descr))
Walther@60740
   181
Walther@60729
   182
fun discern_typ _ (_, []) = []
Walther@60729
   183
  | discern_typ id (descr, ts) =
Walther@60729
   184
(*TODO.md "review (descriptor, ts)" REMOVE--------------------------------------\*)
Walther@60729
   185
    let
Walther@60766
   186
      val ts = if Model_Def.is_list_descr descr
Walther@60729
   187
        then if TermC.is_list (hd ts)
Walther@60729
   188
          then ts |> map TermC.isalist2list |> flat
Walther@60729
   189
          else ts
Walther@60729
   190
        else ts
Walther@60729
   191
    in
Walther@60729
   192
(*TODO.md "review (descriptor, ts)" REMOVE--------------------------------------/*)
Walther@60729
   193
  if Model_Pattern.typ_of_element descr = HOLogic.boolT andalso all_lhs_atoms ts
Walther@60729
   194
  then
Walther@60729
   195
    if length ts > 1
Walther@60729
   196
    then (writeln "model items of type 'bool' in lists with 'lengt ts > 1' NOT YET IMPLEMENTED";
Walther@60729
   197
      [])
Walther@60741
   198
    else [((switch_type id ts, TermC.lhs (hd ts)), 
Walther@60729
   199
           (TermC.lhs (hd ts), TermC.rhs (hd ts)))]
Walther@60729
   200
  else []
Walther@60729
   201
(*TODO.md "review (descriptor, ts)" REMOVE--------------------------------------\*)
Walther@60729
   202
    end
Walther@60729
   203
(*TODO.md "review (descriptor, ts)" REMOVE--------------------------------------/*)
Walther@60782
   204
(*Tnew*)
Walther@60729
   205
Walther@60782
   206
fun discern_feedback id (Model_Def.Cor (descr, ts)) = discern_typ id (descr, ts)
Walther@60782
   207
  | discern_feedback _ (Model_Def.Syn _) = [] (*TODO: handle correct elements*)
Walther@60782
   208
  | discern_feedback id (Model_Def.Inc (descr, ts)) = discern_typ id (descr, ts)
Walther@60782
   209
  | discern_feedback _ (Model_Def.Sup _) = []
Walther@60728
   210
fun make_envs_preconds equal_givens =
Walther@60722
   211
  map (fn ((_, (_, id)), (_, _, _, _, (feedb, _))) => discern_feedback id feedb) equal_givens
Walther@60722
   212
  |> flat
Walther@60721
   213
Walther@60756
   214
fun make_environments model_patt i_model =
Walther@60756
   215
  let
Walther@60756
   216
    val equal_descr_pairs = map (get_equal_descr i_model) model_patt
Walther@60756
   217
      |> flat
Walther@60756
   218
    val env_model = make_env_model equal_descr_pairs
Walther@60756
   219
    val equal_givens = filter (fn ((m_field, _), _) => m_field = "#Given") equal_descr_pairs
Walther@60756
   220
    val subst_eval_list = make_envs_preconds equal_givens
Walther@60756
   221
    val (env_subst, env_eval) = split_list subst_eval_list
Walther@60756
   222
  in
Walther@60756
   223
    (env_model, (env_subst, env_eval))
Walther@60756
   224
  end 
Walther@60756
   225
Walther@60756
   226
fun check_internal ctxt i_model (pbl_met, id) =
Walther@60756
   227
  let
Walther@60756
   228
    val (model, where_rls, where_) = case pbl_met of
Walther@60756
   229
        Pos.Pbl => let val {model, where_rls, where_, ...} = Problem.from_store ctxt id
Walther@60756
   230
          in (model, where_rls, where_) end
Walther@60756
   231
      | Pos.Met => let val {model, where_rls, where_, ...} = MethodC.from_store ctxt id
Walther@60756
   232
          in (model, where_rls, where_) end
Walther@60756
   233
      | _ => raise ERROR ("Pre_Conds.check_internal calles with " ^ Pos.pos_2str pbl_met)
Walther@60766
   234
    val (env_model, (env_subst, env_eval)) = make_environments model
Walther@60756
   235
      ((*filter (fn (_, _, _, m_field ,_) => m_field = "#Given")*) i_model)
Walther@60756
   236
Walther@60756
   237
    val pres_subst = map (TermC.subst_atomic_all env_subst) where_;
Walther@60756
   238
    val pres_subst_other = map (TermC.subst_atomic_all env_model) (map #2 pres_subst);
Walther@60756
   239
    val full_subst = if env_eval = [] then pres_subst_other
Walther@60756
   240
      else map (TermC.subst_atomic_all env_eval) (map #2 pres_subst_other)
Walther@60756
   241
    val evals = map (eval ctxt where_rls) full_subst
Walther@60756
   242
  in
Walther@60756
   243
      (foldl and_ (true, map fst evals), pres_subst_other)
Walther@60756
   244
  end;
Walther@60756
   245
Walther@60758
   246
(*extract one environment rom make_environments *)
Walther@60782
   247
fun environment model_patt i_model = make_environments model_patt i_model |> #1
Walther@60740
   248
Walther@60712
   249
(** check pre-conditions **)
Walther@60782
   250
fun check_pos ctxt where_rls where_ (model_patt, i_model) =
Walther@60732
   251
    let
Walther@60758
   252
      val (_, (_, env_eval)) = make_environments model_patt 
Walther@60732
   253
        (filter (fn (_, _, _, m_field ,_) => m_field = "#Given") i_model)
Walther@60732
   254
      val full_subst = if env_eval = []
Walther@60782
   255
        then map (fn (t, pos) => ((true, t), pos)) where_
Walther@60782
   256
        else map (fn (t, pos) => (TermC.subst_atomic_all env_eval t, pos)) where_
Walther@60732
   257
      val evals = map (fn ((bool_t), pos) => (eval ctxt where_rls bool_t, pos)) full_subst;
Walther@60782
   258
      val display = map (fn ((t, pos), ((bool, _), _)) => (bool, (t, pos))) (where_ ~~ evals)
Walther@60732
   259
    in
Walther@60732
   260
      (foldl and_ (true, map (fn ((bool, _: term), _: Position.T) => bool) evals), display)
Walther@60732
   261
    end;
Walther@60732
   262
Walther@60758
   263
(*takes the envs resulting from make_environments*)
Walther@60741
   264
fun check_envs ctxt where_rls where_ (env_model, (env_subst, env_eval)) =
Walther@60727
   265
  let
Walther@60732
   266
      val pres_subst = map (TermC.subst_atomic_all env_subst) where_;
Walther@60727
   267
      val pres_subst_other = map (TermC.subst_atomic_all env_model) (map #2 pres_subst);
Walther@60727
   268
      val full_subst = if env_eval = [] then pres_subst_other
Walther@60727
   269
        else map (TermC.subst_atomic_all env_eval) (map #2 pres_subst_other)
Walther@60727
   270
      val evals = map (eval ctxt where_rls) full_subst
Walther@60732
   271
  in
Walther@60727
   272
      (foldl and_ (true, map fst evals), pres_subst_other)
Walther@60732
   273
  end
Walther@60710
   274
Walther@60740
   275
(*expects the precondition from Problem, ie. needs substitution by env_model*)
Walther@60741
   276
fun check _ _ [] _  = (true, [])
Walther@60741
   277
  | check ctxt where_rls where_ (model_patt, i_model) =
Walther@60706
   278
    let
Walther@60758
   279
      val (env_model, (env_subst, env_eval)) = make_environments model_patt i_model
Walther@60729
   280
      val pres_subst = map (TermC.subst_atomic_all env_subst) where_;
Walther@60726
   281
      val pres_subst_other = map (TermC.subst_atomic_all env_model) (map #2 pres_subst);
Walther@60726
   282
      val full_subst = if env_eval = [] then pres_subst_other
Walther@60726
   283
        else map (TermC.subst_atomic_all env_eval) (map #2 pres_subst_other)
Walther@60706
   284
      val evals = map (eval ctxt where_rls) full_subst
Walther@60706
   285
    in
Walther@60726
   286
      (foldl and_ (true, map fst evals), pres_subst_other)
Walther@60706
   287
    end;
Walther@60706
   288
Walther@60782
   289
fun unchecked_OLD_to pres = map (fn t => (t, Position.none)) pres
Walther@60706
   290
walther@59965
   291
(**)end(**)