src/Tools/isac/Interpret/inform.sml
author Walther Neuper <wneuper@ist.tugraz.at>
Mon, 06 Feb 2017 06:27:31 +0100
changeset 59310 14333576fb70
parent 59308 15e75745a7fa
child 59313 8f730d631591
permissions -rw-r--r--
begin to re-arrange structures in Interpret.thy
neuper@37906
     1
(* Handle user-input during the specify- and the solve-phase. 
neuper@37906
     2
   author: Walther Neuper
neuper@37906
     3
   0603
neuper@37906
     4
   (c) due to copyright terms
neuper@37906
     5
*)
neuper@37906
     6
wneuper@59262
     7
signature INPUT_FORMULAS =
wneuper@59262
     8
sig
wneuper@59262
     9
  datatype iitem = Find of cterm' list | Given of cterm' list | Relate of cterm' list
wneuper@59262
    10
  type imodel = iitem list
wneuper@59276
    11
  type icalhd = Ctree.pos' * cterm' * imodel * Ctree.pos_ * spec
wneuper@59302
    12
  val fetchErrorpatterns : Tac.tac -> errpatID list
wneuper@59279
    13
  val input_icalhd : Ctree.ctree -> icalhd -> Ctree.ctree * Ctree.ocalhd
wneuper@59265
    14
  val inform : Chead.calcstate' -> string -> string * Chead.calcstate'
wneuper@59301
    15
  val find_fillpatterns : Ctree.state -> errpatID -> (fillpatID * term * thm * Selem.subs option) list
wneuper@59302
    16
  val is_exactly_equal : Ctree.state -> string -> string * Tac.tac
wneuper@59310
    17
(* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
wneuper@59310
    18
  (*  NONE *)
wneuper@59299
    19
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
wneuper@59262
    20
  val dropwhile' : ('a -> 'b -> bool) -> 'a list -> 'b list -> 'a list * 'b list
wneuper@59279
    21
  val cas_input : term -> (Ctree.ctree * Ctree.ocalhd) option
wneuper@59262
    22
  val rev_deriv' : 'a * rule * ('b * 'c) -> 'b * rule * ('a * 'c)
wneuper@59281
    23
  val compare_step : Generate.taci list * Ctree.pos' list * (Ctree.state) -> term -> string * Chead.calcstate'
wneuper@59262
    24
  val check_err_patt : term * term -> subst -> errpatID * term -> rls -> errpatID option
wneuper@59262
    25
  val concat_deriv : 'a * ((term * term) list -> term * term -> bool) ->
wneuper@59262
    26
    rls -> rule list -> term -> term -> bool * (term * rule * (term * term list)) list
wneuper@59262
    27
  val check_error_patterns :
wneuper@59262
    28
    term * term ->
wneuper@59262
    29
    term * (term * term) list -> (errpatID * term list * 'a list) list * rls -> errpatID option
wneuper@59262
    30
  val get_fillform :
wneuper@59262
    31
     'a * (term * term) list -> 'b * term -> errpatID -> fillpat -> (fillpatID * term * 'b * 'a) option
wneuper@59262
    32
  val get_fillpats :
wneuper@59262
    33
     'a * (term * term) list -> term -> errpatID -> thm -> (fillpatID * term * thm * 'a) list
wneuper@59299
    34
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
wneuper@59310
    35
wneuper@59310
    36
(*----- unused code, kept as hints to design ideas ---------------------------------------------*)
wneuper@59310
    37
  (* NONE *)
wneuper@59262
    38
end
neuper@37906
    39
wneuper@59262
    40
(**)
wneuper@59262
    41
structure Inform(**): INPUT_FORMULAS(**) =
wneuper@59262
    42
struct
wneuper@59262
    43
(**)
neuper@37906
    44
wneuper@59262
    45
(*** handle an input calc-head ***)
neuper@37906
    46
neuper@37906
    47
datatype iitem = 
neuper@37906
    48
  Given of cterm' list
neuper@37906
    49
(*Where is never input*) 
neuper@37906
    50
| Find  of cterm' list
wneuper@59262
    51
| Relate  of cterm' list
neuper@37906
    52
wneuper@59262
    53
type imodel = iitem list
neuper@37906
    54
neuper@37906
    55
(*calc-head as input*)
neuper@37906
    56
type icalhd =
wneuper@59276
    57
  Ctree.pos' *     (*the position of the calc-head in the calc-tree*) 
wneuper@59262
    58
  cterm' *   (*the headline*)
wneuper@59262
    59
  imodel *   (*the model (without Find) of the calc-head*)
wneuper@59276
    60
  Ctree.pos_ *     (*model belongs to Pbl or Met*)
wneuper@59262
    61
  spec;      (*specification: domID, pblID, metID*)
wneuper@59276
    62
val e_icalhd = (Ctree.e_pos', "", [Given [""]], Ctree.Pbl, e_spec) : icalhd
neuper@37906
    63
wneuper@59298
    64
fun is_casinput (hdf : cterm') ((fmz_, spec) : Selem.fmz) =
wneuper@59262
    65
  hdf <> "" andalso fmz_ = [] andalso spec = e_spec
neuper@37906
    66
neuper@37906
    67
(*.handle an input as into an algebra system.*)
neuper@37906
    68
fun dtss2itm_ ppc (d, ts) =
wneuper@59264
    69
  let
wneuper@59264
    70
    val (f, (d, id)) = the (find_first ((curry op= d) o 
wneuper@59264
    71
  		(#1: (term * term) -> term) o
wneuper@59264
    72
  		(#2: pbt_ -> (term * term))) ppc)
wneuper@59264
    73
  in
wneuper@59308
    74
    ([1], true, f, Stool.Cor ((d, ts), (id, ts)))
wneuper@59264
    75
  end
neuper@37906
    76
wneuper@59262
    77
fun flattup2 (a, (b ,c, d, e)) = (a, b, c, d, e)
neuper@37906
    78
wneuper@59262
    79
fun cas_input_ ((dI, pI, mI): spec) dtss = (*WN110515 reconsider thy..ctxt*)
neuper@41995
    80
  let
neuper@41995
    81
    val thy = assoc_thy dI
wneuper@59269
    82
	  val {ppc, ...} = Specify.get_pbt pI
neuper@41995
    83
	  val its_ = map (dtss2itm_ ppc) dtss (*([1],true,"#Given",Cor (...))*)
wneuper@59269
    84
	  val its = Specify.add_id its_
neuper@41995
    85
	  val pits = map flattup2 its
neuper@41995
    86
	  val (pI, mI) =
neuper@41995
    87
      if mI <> ["no_met"]
neuper@41995
    88
      then (pI, mI)
neuper@41995
    89
		  else
wneuper@59269
    90
        case Specify.refine_pbl thy pI pits of
wneuper@59269
    91
			    SOME (pI,_) => (pI, (hd o #met o Specify.get_pbt) pI)
wneuper@59269
    92
			  | NONE => (pI, (hd o #met o Specify.get_pbt) pI)
wneuper@59269
    93
	  val {ppc, pre, prls, ...} = Specify.get_met mI
neuper@41995
    94
	  val its_ = map (dtss2itm_ ppc) dtss (*([1],true,"#Given",Cor (...))*)
wneuper@59269
    95
	  val its = Specify.add_id its_
neuper@41995
    96
	  val mits = map flattup2 its
wneuper@59308
    97
	  val pre = Stool.check_preconds thy prls pre mits
wneuper@59301
    98
    val ctxt = Selem.e_ctxt (*WN110515 cas_input_ DOESNT WORK*)
wneuper@59308
    99
  in (pI, pits, mI, mits, pre, ctxt) end;
neuper@37906
   100
neuper@37906
   101
wneuper@59279
   102
(* check if the input term is a CAScmd and return a ctree with a _complete_ calchead *)
neuper@37906
   103
fun cas_input hdt =
wneuper@59262
   104
  let
wneuper@59262
   105
    val (h, argl) = strip_comb hdt
neuper@41995
   106
  in
s1210629013@55443
   107
    case assoc_cas (assoc_thy "Isac") h of
wneuper@59262
   108
      NONE => NONE
wneuper@59262
   109
    | SOME (spec as (dI,_,_), argl2dtss) =>
neuper@41995
   110
	      let
neuper@41995
   111
          val dtss = argl2dtss argl
neuper@41995
   112
	        val (pI, pits, mI, mits, pre, ctxt) = cas_input_ spec dtss
neuper@41995
   113
	        val spec = (dI, pI, mI)
neuper@41995
   114
	        val (pt,_) = 
wneuper@59301
   115
		        Ctree.cappend_problem Ctree.e_ctree [] (Selem.e_istate, Selem.e_ctxt) ([], e_spec) ([], e_spec, hdt)
wneuper@59276
   116
	        val pt = Ctree.update_spec pt [] spec
wneuper@59276
   117
	        val pt = Ctree.update_pbl pt [] pits
wneuper@59276
   118
	        val pt = Ctree.update_met pt [] mits
wneuper@59276
   119
	        val pt = Ctree.update_ctxt pt [] ctxt
wneuper@59262
   120
	      in
wneuper@59276
   121
	        SOME (pt, (true, Ctree.Met, hdt, mits, pre, spec) : Ctree.ocalhd)
wneuper@59262
   122
	      end
wneuper@59262
   123
  end
neuper@37906
   124
neuper@40836
   125
(*lazy evaluation for (Thy_Info.get_theory "Isac")*)
neuper@38050
   126
fun Isac _  = assoc_thy "Isac";
neuper@37906
   127
wneuper@59262
   128
(* re-parse itms with a new thy and prepare for checking with ori list *)
wneuper@59308
   129
fun parsitm dI (itm as (i, v, _, f, Stool.Cor ((d, ts), _))) =
wneuper@59308
   130
    (let val t = Stool.comp_dts (d, ts)
wneuper@59262
   131
     val _ = (term_to_string''' dI t)
wneuper@59262
   132
     (*t his ^^^^^^^^^^^^ should raise the exn on unability of re-parsing dts *)
neuper@52070
   133
    in itm end
wneuper@59308
   134
    handle _ => (i, v, false, f, Stool.Syn (term2str t)))
wneuper@59308
   135
  | parsitm dI (i, v, b, f, Stool.Syn str) =
wneuper@59262
   136
    (let val _ = (Thm.term_of o the o (parse dI)) str
wneuper@59308
   137
    in (i, v, b ,f, Stool.Par str) end
wneuper@59308
   138
    handle _ => (i, v, b, f, Stool.Syn str))
wneuper@59308
   139
  | parsitm dI (i, v, b, f, Stool.Typ str) =
wneuper@59262
   140
    (let val _ = (Thm.term_of o the o (parse dI)) str
wneuper@59308
   141
     in (i, v, b, f, Stool.Par str) end
wneuper@59308
   142
     handle _ => (i, v, b, f, Stool.Syn str))
wneuper@59308
   143
  | parsitm dI (itm as (i, v, _, f, Stool.Inc ((d, ts), _))) =
wneuper@59308
   144
    (let val t = Stool.comp_dts (d,ts);
wneuper@59262
   145
	       val _ = term_to_string''' dI t;
neuper@37906
   146
     (*this    ^ should raise the exn on unability of re-parsing dts*)
neuper@52070
   147
     in itm end
wneuper@59308
   148
     handle _ => (i, v, false, f, Stool.Syn (term2str t)))
wneuper@59308
   149
  | parsitm dI (itm as (i, v, _, f, Stool.Sup (d, ts))) =
wneuper@59308
   150
    (let val t = Stool.comp_dts (d,ts);
wneuper@59262
   151
	       val _ = term_to_string''' dI t;
neuper@37906
   152
     (*this    ^ should raise the exn on unability of re-parsing dts*)
neuper@52070
   153
    in itm end
wneuper@59308
   154
    handle _ => (i, v, false, f, Stool.Syn (term2str t)))
wneuper@59308
   155
  | parsitm dI (itm as (i, v, _, f, Stool.Mis (d, t'))) =
neuper@37906
   156
    (let val t = d $ t';
wneuper@59262
   157
	       val _ = term_to_string''' dI t;
neuper@37906
   158
     (*this    ^ should raise the exn on unability of re-parsing dts*)
neuper@52070
   159
    in itm end
wneuper@59308
   160
    handle _ => (i, v, false, f, Stool.Syn (term2str t)))
wneuper@59308
   161
  | parsitm dI (itm as (_, _, _, _, Stool.Par _)) = 
wneuper@59308
   162
    error ("parsitm (" ^ Stool.itm2str_ (thy2ctxt dI) itm ^ "): Par should be internal");
neuper@37906
   163
neuper@37906
   164
(*separate a list to a pair of elements that do NOT satisfy the predicate,
neuper@37906
   165
 and of elements that satisfy the predicate, i.e. (false, true)*)
neuper@37906
   166
fun filter_sep pred xs =
wneuper@59262
   167
  let
wneuper@59262
   168
    fun filt ab [] = ab
wneuper@59262
   169
      | filt (a, b) (x :: xs) =
wneuper@59262
   170
        if pred x 
wneuper@59262
   171
			  then filt (a, b @ [x]) xs 
wneuper@59262
   172
			  else filt (a @ [x], b) xs
wneuper@59262
   173
  in filt ([], []) xs end;
wneuper@59308
   174
fun is_Par (_, _, _, _, Stool.Par _) = true
neuper@37906
   175
  | is_Par _ = false;
neuper@37906
   176
neuper@37906
   177
fun is_e_ts [] = true
neuper@37906
   178
  | is_e_ts [Const ("List.list.Nil", _)] = true
neuper@37906
   179
  | is_e_ts _ = false;
neuper@37906
   180
wneuper@59262
   181
(* WN.9.11.03 copied from fun appl_add *)
neuper@37906
   182
fun appl_add' dI oris ppc pbt (sel, ct) = 
wneuper@59262
   183
  let 
wneuper@59262
   184
     val ctxt = assoc_thy dI |> thy2ctxt;
wneuper@59262
   185
  in
wneuper@59262
   186
    case parseNEW ctxt ct of
wneuper@59308
   187
	    NONE => (0, [], false, sel, Stool.Syn ct)
wneuper@59262
   188
	  | SOME t =>
wneuper@59265
   189
	    (case Chead.is_known ctxt sel oris t of
wneuper@59262
   190
        ("", ori', all) =>
wneuper@59265
   191
          (case Chead.is_notyet_input ctxt ppc all ori' pbt of
wneuper@59262
   192
            ("",itm)  => itm
wneuper@59262
   193
          | (msg,_) => error ("appl_add': " ^ msg))
wneuper@59262
   194
      | (_, (i, v, _, d, ts), _) =>
wneuper@59262
   195
        if is_e_ts ts
wneuper@59308
   196
        then (i, v, false, sel, Stool.Inc ((d, ts), (e_term, [])))
wneuper@59308
   197
        else (i, v, false, sel, Stool.Sup (d, ts)))
wneuper@59262
   198
   end
neuper@37906
   199
wneuper@59262
   200
(* generate preliminary itm_ from a strin (with field "#Given" etc.) *)
wneuper@59262
   201
fun eq7 (f, d) (f', (d', _)) = f = f' andalso d = d';
neuper@37906
   202
fun fstr2itm_ thy pbt (f, str) =
wneuper@59262
   203
  let
wneuper@59262
   204
    val topt = parse thy str
wneuper@59262
   205
  in
wneuper@59262
   206
    case topt of
wneuper@59308
   207
      NONE => ([], false, f, Stool.Syn str)
wneuper@59262
   208
    | SOME ct => 
wneuper@59262
   209
	    let
wneuper@59308
   210
	      val (d, ts) = (Stool.split_dts o Thm.term_of) ct
wneuper@59262
   211
	      val popt = find_first (eq7 (f, d)) pbt
wneuper@59262
   212
	    in
wneuper@59262
   213
	      case popt of
wneuper@59308
   214
	        NONE => ([1](*??*), true(*??*), f, Stool.Sup (d, ts))
wneuper@59308
   215
	      | SOME (f, (d, id)) => ([1], true, f, Stool.Cor ((d, ts), (id, ts))) 
wneuper@59262
   216
	    end
wneuper@59262
   217
  end
neuper@37906
   218
neuper@37906
   219
(*.input into empty PblObj, i.e. empty fmz+origin (unknown example).*)
neuper@37906
   220
fun unknown_expl dI pbt selcts =
neuper@37906
   221
  let
neuper@37906
   222
    val thy = assoc_thy dI
neuper@37906
   223
    val its_ = map (fstr2itm_ thy pbt) selcts (*([1],true,"#Given",Cor (...))*)
wneuper@59269
   224
    val its = Specify.add_id its_ 
wneuper@59308
   225
  in map flattup2 its end
neuper@37906
   226
wneuper@59262
   227
(* WN.11.03 for input_icalhd, ~ specify_additem for Add_Given/_Find/_Relation
wneuper@59262
   228
   appl_add': generate 1 item 
wneuper@59262
   229
   appl_add' . is_known: parse, get data from oris (vats, all (elems if list)..)
wneuper@59262
   230
   appl_add' . is_notyet_input: compare with items in model already input
wneuper@59262
   231
   insert_ppc': insert this 1 item*)
wneuper@59262
   232
fun appl_adds dI [] _ pbt selcts = unknown_expl dI pbt selcts
wneuper@59262
   233
    (*already present itms in model are being overwritten*)
wneuper@59262
   234
  | appl_adds _ _ ppc _ [] = ppc
wneuper@59262
   235
  | appl_adds dI oris ppc pbt (selct :: ss) =
wneuper@59262
   236
    let val itm = appl_add' dI oris ppc pbt selct;
wneuper@59265
   237
    in appl_adds dI oris (Chead.insert_ppc' itm ppc) pbt ss end
neuper@37906
   238
wneuper@59308
   239
fun oris2itms _  _ [] = [] (* WN161130: similar in ptyps ?!? *)
wneuper@59308
   240
  | oris2itms pbt vat ((i, v, f, d, ts) :: os) =
neuper@37930
   241
    if member op = vat v 
wneuper@59308
   242
    then (i, v, true, f, Stool.Cor ((d, ts), (e_term, []))) :: (oris2itms pbt vat os)
wneuper@59262
   243
    else oris2itms pbt vat os
neuper@37906
   244
wneuper@59308
   245
fun par2fstr (_, _, _, f, Stool.Par s) = (f, s)
wneuper@59308
   246
  | par2fstr itm = error ("par2fstr: called with " ^ Stool.itm2str_ (thy2ctxt' "Isac") itm)
wneuper@59308
   247
fun itms2fstr (_, _, _, f, Stool.Cor ((d, ts), _)) = (f, Stool.comp_dts'' (d, ts))
wneuper@59308
   248
  | itms2fstr (_, _, _, f, Stool.Syn str) = (f, str)
wneuper@59308
   249
  | itms2fstr (_, _, _, f, Stool.Typ str) = (f, str)
wneuper@59308
   250
  | itms2fstr (_, _, _, f, Stool.Inc ((d, ts), _)) = (f, Stool.comp_dts'' (d,ts))
wneuper@59308
   251
  | itms2fstr (_, _, _, f, Stool.Sup (d, ts)) = (f, Stool.comp_dts'' (d, ts))
wneuper@59308
   252
  | itms2fstr (_, _, _, f, Stool.Mis (d, t)) = (f, term2str (d $ t))
wneuper@59308
   253
  | itms2fstr (itm as (_, _, _, _, Stool.Par _)) = 
wneuper@59308
   254
    error ("parsitm (" ^ Stool.itm2str_ (thy2ctxt' "Isac") itm ^ "): Par should be internal");
neuper@37906
   255
neuper@37906
   256
fun imodel2fstr iitems = 
neuper@41976
   257
  let 
neuper@41976
   258
    fun xxx is [] = is
neuper@41976
   259
	    | xxx is ((Given strs)::iis) = xxx (is @ (map (pair "#Given") strs)) iis
neuper@41976
   260
	    | xxx is ((Find strs)::iis) = xxx (is @ (map (pair "#Find") strs)) iis
neuper@41976
   261
	    | xxx is ((Relate strs)::iis) = xxx (is @ (map (pair "#Relate") strs)) iis
neuper@41976
   262
  in xxx [] iitems end;
neuper@37906
   263
neuper@41976
   264
(* input a calchead, WN110505 "prep_oris -> (_, ctxt)" not handled properly *)
wneuper@59264
   265
fun input_icalhd pt (((p, _), hdf, imodel, Pbl, spec as (dI, pI, mI)) : icalhd) =
wneuper@59264
   266
    let
wneuper@59276
   267
		  val (fmz, fmz_, oris, ospec, hdf', sspec, sdI, spI, smI, probl, meth) = case Ctree.get_obj I pt p of
wneuper@59276
   268
		    Ctree.PblObj {fmz = fmz as (fmz_,_), origin = (oris, ospec, hdf'), 
wneuper@59264
   269
		      spec = sspec as (sdI, spI, smI), probl, meth, ...}
wneuper@59264
   270
        => (fmz, fmz_, oris, ospec, hdf', sspec, sdI, spI, smI, probl, meth)
wneuper@59264
   271
      | _ => error "input_icalhd: uncovered case of get_obj I pt p"
neuper@37906
   272
    in if is_casinput hdf fmz then the (cas_input (str2term hdf)) 
neuper@37906
   273
       else        (*hacked WN0602 ~~~            ~~~~~~~~~,   ..dropped !*)
neuper@41976
   274
         let val (pos_, pits, mits) = 
neuper@41976
   275
	         if dI <> sdI
neuper@41976
   276
	         then let val its = map (parsitm (assoc_thy dI)) probl;
neuper@41976
   277
			            val (its, trms) = filter_sep is_Par its;
wneuper@59269
   278
			            val pbt = (#ppc o Specify.get_pbt) (#2 (Chead.some_spec ospec sspec))
neuper@41976
   279
		            in (Pbl, appl_adds dI oris its pbt  (map par2fstr trms), meth) end 
wneuper@59264
   280
           else
wneuper@59264
   281
             if pI <> spI 
wneuper@59264
   282
	           then if pI = snd3 ospec then (Pbl, probl, meth) 
wneuper@59264
   283
                  else
wneuper@59269
   284
		                let val pbt = (#ppc o Specify.get_pbt) pI
wneuper@59265
   285
			                val dI' = #1 (Chead.some_spec ospec spec)
wneuper@59264
   286
			                val oris = if pI = #2 ospec then oris 
wneuper@59269
   287
				                         else Specify.prep_ori fmz_(assoc_thy"Isac") pbt |> #1;
wneuper@59264
   288
		                in (Pbl, appl_adds dI' oris probl pbt 
wneuper@59264
   289
				              (map itms2fstr probl), meth) end 
wneuper@59264
   290
             else if mI <> smI (*FIXME.WN0311: what if probl is incomplete?!*)
wneuper@59269
   291
	                then let val met = (#ppc o Specify.get_met) mI
wneuper@59265
   292
		                     val mits = Chead.complete_metitms oris probl meth met
wneuper@59264
   293
		                   in if foldl and_ (true, map #3 mits)
wneuper@59276
   294
		                      then (Pbl, probl, mits) else (Ctree.Met, probl, mits) 
wneuper@59264
   295
		                   end 
wneuper@59265
   296
                  else (Pbl, appl_adds (#1 (Chead.some_spec ospec spec)) oris [(*!!!*)]
wneuper@59269
   297
			                  ((#ppc o Specify.get_pbt) (#2 (Chead.some_spec ospec spec)))
wneuper@59264
   298
			                  (imodel2fstr imodel), meth)
wneuper@59276
   299
	         val pt = Ctree.update_spec pt p spec;
neuper@41976
   300
         in if pos_ = Pbl
wneuper@59269
   301
	          then let val {prls,where_,...} = Specify.get_pbt (#2 (Chead.some_spec ospec spec))
wneuper@59308
   302
		               val pre = Stool.check_preconds (assoc_thy"Isac") prls where_ pits
wneuper@59276
   303
	               in (Ctree.update_pbl pt p pits,
wneuper@59276
   304
		                 (Chead.ocalhd_complete pits pre spec, Pbl, hdf', pits, pre, spec): Ctree.ocalhd) 
neuper@41976
   305
                 end
wneuper@59269
   306
	           else let val {prls,pre,...} = Specify.get_met (#3 (Chead.some_spec ospec spec))
wneuper@59308
   307
		                val pre = Stool.check_preconds (assoc_thy"Isac") prls pre mits
wneuper@59276
   308
	                in (Ctree.update_met pt p mits,
wneuper@59276
   309
		                  (Chead.ocalhd_complete mits pre spec, Ctree.Met, hdf', mits, pre, spec) : Ctree.ocalhd)
neuper@41976
   310
                  end
neuper@41976
   311
         end 
neuper@41976
   312
    end
wneuper@59264
   313
  | input_icalhd _ (_, _, _, _(*Met*), _) = error "input_icalhd Met not impl."
neuper@37906
   314
neuper@37906
   315
neuper@37906
   316
(***. handle an input formula .***)
neuper@37906
   317
wneuper@59264
   318
fun equal a b = a = b
neuper@37906
   319
neuper@37906
   320
(*the lists contain eq-al elem-pairs at the beginning;
neuper@37906
   321
  return first list reverted (again) - ie. in order as required subsequently*)
neuper@37906
   322
fun dropwhile' equal (f1::f2::fs) (i1::i2::is) =
wneuper@59264
   323
    if equal f1 i1
wneuper@59264
   324
    then
wneuper@59264
   325
      if equal f2 i2 then dropwhile' equal (f2 :: fs) (i2 :: is)
wneuper@59264
   326
      else (rev (f1 :: f2 :: fs), i1 :: i2 :: is)
neuper@38031
   327
    else error "dropwhile': did not start with equal elements"
neuper@37906
   328
  | dropwhile' equal (f::fs) [i] =
wneuper@59264
   329
    if equal f i
wneuper@59264
   330
    then (rev (f::fs), [i])
neuper@38031
   331
    else error "dropwhile': did not start with equal elements"
neuper@37906
   332
  | dropwhile' equal [f] (i::is) =
wneuper@59264
   333
    if equal f i
wneuper@59264
   334
    then ([f], i::is)
wneuper@59264
   335
    else error "dropwhile': did not start with equal elements"
wneuper@59264
   336
  | dropwhile' _ _ _ = error "dropwhile': uncovered case"
neuper@37906
   337
wneuper@59264
   338
(* 040214: version for concat_deriv *)
wneuper@59263
   339
fun rev_deriv' (t, r, (t', a)) = (t', Rtools.sym_rule r, (t, a));
neuper@37906
   340
wneuper@59250
   341
fun mk_tacis ro erls (t, r as Thm (id, thm), (t', a)) = 
wneuper@59302
   342
      (Tac.Rewrite (id, thm), 
wneuper@59302
   343
        Tac.Rewrite' ("Isac", fst ro, erls, false, Lucin.rule2thm'' r, t, (t', a)),
wneuper@59301
   344
       (Ctree.e_pos'(*to be updated before generate tacis!!!*), (Selem.Uistate, Selem.e_ctxt)))
wneuper@59253
   345
  | mk_tacis _ _ (t, r as Rls_ rls, (t', a)) = 
wneuper@59302
   346
      (Tac.Rewrite_Set (Lucin.rule2rls' r), 
wneuper@59302
   347
        Tac.Rewrite_Set' ("Isac", false, rls, t, (t', a)),
wneuper@59301
   348
       (Ctree.e_pos'(*to be updated before generate tacis!!!*), (Selem.Uistate, Selem.e_ctxt)))
wneuper@59264
   349
  | mk_tacis _ _ (t, r, _) = error ("mk_tacis: not impl. for " ^ rule2str r ^ " at " ^ term2str t)
neuper@37906
   350
wneuper@59264
   351
(* fo = ifo excluded already in inform *)
neuper@37906
   352
fun concat_deriv rew_ord erls rules fo ifo =
neuper@55487
   353
  let 
neuper@55487
   354
    fun derivat ([]:(term * rule * (term * term list)) list) = e_term
neuper@55487
   355
      | derivat dt = (#1 o #3 o last_elem) dt
neuper@55487
   356
    fun equal (_,_,(t1, _)) (_,_,(t2, _)) = t1=t2
wneuper@59263
   357
    val  fod = Rtools.make_deriv (Isac"") erls rules (snd rew_ord) NONE  fo
wneuper@59263
   358
    val ifod = Rtools.make_deriv (Isac"") erls rules (snd rew_ord) NONE ifo
neuper@55487
   359
  in 
neuper@55487
   360
    case (fod, ifod) of
neuper@55487
   361
      ([], []) => if fo = ifo then (true, []) else (false, [])
neuper@55487
   362
    | (fod, []) => if derivat fod = ifo then (true, fod) (*ifo is normal form*) else (false, [])
neuper@55487
   363
    | ([], ifod) => if fo = derivat ifod then (true, ((map rev_deriv') o rev) ifod) else (false, [])
neuper@55487
   364
    | (fod, ifod) =>
neuper@55487
   365
      if derivat fod = derivat ifod (*common normal form found*)
neuper@55487
   366
      then
neuper@55487
   367
        let 
neuper@55487
   368
          val (fod', rifod') = dropwhile' equal (rev fod) (rev ifod)
neuper@55487
   369
        in (true, fod' @ (map rev_deriv' rifod')) end
neuper@55487
   370
      else (false, [])
wneuper@59264
   371
  end
neuper@37906
   372
neuper@41995
   373
(* compare inform with ctree.form at current pos by nrls;
neuper@37906
   374
   if found, embed the derivation generated during comparison
neuper@41995
   375
   if not, let the mat-engine compute the next ctree.form *)
wneuper@59280
   376
(* code's structure is copied from complete_solve
wneuper@59264
   377
   CAUTION: tacis in returned calcstate' do NOT construct resulting ptp --
wneuper@59264
   378
            all_modspec etc. has to be inserted at Subproblem'*)
wneuper@59265
   379
fun compare_step ((tacis, c, ptp as (pt, pos as (p,p_))): Chead.calcstate') ifo =
neuper@41995
   380
  let
neuper@41995
   381
    val fo =
neuper@41995
   382
      case p_ of
wneuper@59276
   383
        Frm => Ctree.get_obj Ctree.g_form pt p
wneuper@59276
   384
			| Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p
neuper@41995
   385
			| _ => e_term (*on PblObj is fo <> ifo*);
wneuper@59276
   386
	  val {nrls, ...} = Specify.get_met (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
neuper@41995
   387
	  val {rew_ord, erls, rules, ...} = rep_rls nrls
neuper@42423
   388
	  val (found, der) = concat_deriv rew_ord erls rules fo ifo; (*<---------------*)
neuper@41995
   389
  in
neuper@41995
   390
    if found
neuper@41995
   391
    then
neuper@41995
   392
       let
neuper@41995
   393
         val tacis' = map (mk_tacis rew_ord erls) der;
wneuper@59271
   394
		     val (c', ptp) = Generate.embed_deriv tacis' ptp;
neuper@41995
   395
	     in ("ok", (tacis (*@ tacis'?WN050408*), c @ c', ptp)) end
neuper@41995
   396
     else 
wneuper@59276
   397
	     if pos = ([], Ctree.Res) (*TODO: we should stop earlier with trying subproblems *)
wneuper@59265
   398
	     then ("no derivation found", (tacis, c, ptp): Chead.calcstate') 
neuper@41995
   399
	     else
neuper@41995
   400
         let
wneuper@59273
   401
           val cs' as (tacis, c', ptp) = Solve.nxt_solve_ ptp; (*<---------------------*)
wneuper@59264
   402
		       val (tacis, c'', ptp) = case tacis of
wneuper@59302
   403
			       ((Tac.Subproblem _, _, _)::_) => 
wneuper@59264
   404
			         let
wneuper@59265
   405
                 val ptp as (pt, (p,_)) = Chead.all_modspec ptp (*<--------------------*)
wneuper@59276
   406
				         val mI = Ctree.get_obj Ctree.g_metID pt p
wneuper@59264
   407
			         in
wneuper@59302
   408
			           Solve.nxt_solv (Tac.Apply_Method' (mI, NONE, Selem.e_istate, Selem.e_ctxt)) (Selem.e_istate, Selem.e_ctxt) ptp
wneuper@59264
   409
               end
wneuper@59264
   410
			     | _ => cs';
neuper@41995
   411
		     in compare_step (tacis, c @ c' @ c'', ptp) ifo end
wneuper@59265
   412
  end
neuper@37906
   413
neuper@42428
   414
(* check if (agreed result, input formula) matches the error pattern "pat" modulo simplifier rls *)
neuper@42426
   415
fun check_err_patt (res, inf) (subst: subst) (errpatID: errpatID, pat) rls =
neuper@42423
   416
  let 
neuper@42423
   417
    val (res', _, _, rewritten) =
neuper@42426
   418
      rew_sub (Isac()) 1 subst e_rew_ord e_rls false [] (Trueprop $ pat) res;
neuper@42423
   419
  in
neuper@42423
   420
    if rewritten
neuper@42423
   421
    then 
neuper@42423
   422
      let
neuper@42426
   423
        val norm_res = case rewrite_set_inst_ (Isac()) false subst rls  res' of
neuper@42423
   424
          NONE => res'
neuper@42423
   425
        | SOME (norm_res, _) => norm_res
neuper@42426
   426
        val norm_inf = case rewrite_set_inst_ (Isac()) false subst rls inf of
neuper@42423
   427
          NONE => inf
neuper@42423
   428
        | SOME (norm_inf, _) => norm_inf
neuper@42423
   429
      in if norm_res = norm_inf then SOME errpatID else NONE
neuper@42423
   430
      end
neuper@42423
   431
    else NONE
neuper@42423
   432
  end;
neuper@42423
   433
neuper@42428
   434
(* check if (agreed result, input formula) matches SOME error pattern modulo simplifier rls;
neuper@42428
   435
   (prog, env) for retrieval of casual substitution for bdv in the pattern. *)
neuper@42428
   436
fun check_error_patterns (res, inf) (prog, env) (errpats, rls) =
neuper@42428
   437
  let
wneuper@59263
   438
    val (_, subst) = Rtools.get_bdv_subst prog env
neuper@42428
   439
    fun scan (_, [], _) = NONE
neuper@42428
   440
      | scan (errpatID, errpat :: errpats, _) =
neuper@42428
   441
          case check_err_patt (res, inf) (subst: subst) (errpatID, errpat) rls of
neuper@42428
   442
            NONE => scan (errpatID, errpats, [])
neuper@42428
   443
          | SOME errpatID => SOME errpatID
neuper@42428
   444
    fun scans [] = NONE
neuper@42428
   445
      | scans (group :: groups) =
neuper@42428
   446
          case scan group of
neuper@42428
   447
            NONE => scans groups
neuper@42428
   448
          | SOME errpatID => SOME errpatID
neuper@42428
   449
  in scans errpats end;
neuper@42428
   450
neuper@37906
   451
(*.handle a user-input formula, which may be a CAS-command, too.
neuper@37906
   452
CAS-command:
neuper@37906
   453
   create a calchead, and do 1 step
neuper@37906
   454
   TOOODO.WN0602 works only for the root-problem !!!
neuper@37906
   455
formula, which is no CAS-command:
neuper@37906
   456
   compare iform with calc-tree.form at pos by equ_nrls and all subsequent pos;
neuper@42423
   457
   collect all the tacs applied by the way;
neuper@42426
   458
   if "no derivation found" then check_error_patterns.
neuper@42427
   459
   ALTERNATIVE: check_error_patterns _within_ compare_step seems too expensive.*)
wneuper@59265
   460
fun inform (cs as (_, _, (pt, pos as (p, _))): Chead.calcstate') istr =
neuper@42423
   461
  case parse (assoc_thy "Isac") istr of
neuper@42427
   462
	  SOME f_in =>
neuper@42423
   463
	    let
wneuper@59186
   464
	      val f_in = Thm.term_of f_in
wneuper@59276
   465
	      val f_succ = Ctree.get_curr_formula (pt, pos);
neuper@42423
   466
			in
neuper@42427
   467
			  if f_succ = f_in
neuper@42423
   468
			  then ("same-formula", cs) (* ctree not cut with replaceFormula *)
neuper@42423
   469
			  else
neuper@42427
   470
			    case cas_input f_in of
wneuper@59276
   471
			      SOME (pt, _) => ("ok",([], [], (pt, (p, Ctree.Met))))
neuper@42423
   472
			    | NONE =>
neuper@42428
   473
			        let
wneuper@59276
   474
			          val pos_pred = Ctree.lev_back' pos (*f_pred ---"step pos cs"---> f_succ in appendFormula*)
wneuper@59276
   475
			          val f_pred = Ctree.get_curr_formula (pt, pos_pred)
neuper@42430
   476
			          val msg_calcstate' = compare_step ([], [], (pt, pos_pred)) f_in (*<<=====*)
neuper@42426
   477
			          (*last step re-calc in compare_step TODO before WN09*)
neuper@42423
   478
			        in
neuper@42423
   479
			          case msg_calcstate' of
neuper@42426
   480
			            ("no derivation found", calcstate') => 
neuper@42426
   481
			               let
wneuper@59276
   482
			                 val pp = Ctree.par_pblobj pt p
wneuper@59276
   483
			                 val (errpats, nrls, prog) = case Specify.get_met (Ctree.get_obj Ctree.g_metID pt pp) of
wneuper@59264
   484
			                   {errpats, nrls, scr = Prog prog, ...} => (errpats, nrls, prog)
wneuper@59264
   485
			                 | _ => error "inform: uncovered case of get_met"
wneuper@59276
   486
			                 val env = case Ctree.get_istate pt pos of
wneuper@59300
   487
			                   Selem.ScrState (env, _, _, _, _, _) => env
wneuper@59264
   488
			                 | _ => error "inform: uncovered case of get_istate"
neuper@42426
   489
			               in
neuper@42428
   490
			                 case check_error_patterns (f_pred, f_in) (prog, env) (errpats, nrls) of
neuper@42426
   491
			                   SOME errpatID => ("error pattern #" ^ errpatID ^ "#", calcstate')
neuper@42426
   492
			                 | NONE => msg_calcstate'
neuper@42426
   493
			               end
neuper@42423
   494
			          | _ => msg_calcstate'
neuper@42423
   495
			        end
neuper@42423
   496
			end
wneuper@59265
   497
    | NONE => ("syntax error in '" ^ istr ^ "'", Chead.e_calcstate')
neuper@37906
   498
neuper@42433
   499
(* fill-in patterns an forms.
neuper@42433
   500
  returns thm required by "fun in_fillform *)
neuper@42433
   501
fun get_fillform (subs_opt, subst) (thm, form) errpatID ((fillpatID, pat, erpaID): fillpat) =
neuper@42430
   502
  let
neuper@42430
   503
    val (form', _, _, rewritten) =
neuper@42430
   504
      rew_sub (Isac()) 1 subst e_rew_ord e_rls false [] (Trueprop $ pat) form;
neuper@42430
   505
  in (*the fillpat of the thm must be dedicated to errpatID*)
neuper@42430
   506
    if errpatID = erpaID andalso rewritten
wneuper@59264
   507
    then SOME (fillpatID, HOLogic.mk_eq (form, form'), thm, subs_opt) 
wneuper@59264
   508
    else NONE
wneuper@59264
   509
  end
neuper@42430
   510
neuper@42430
   511
fun get_fillpats subst form errpatID thm =
wneuper@59264
   512
  let
wneuper@59264
   513
    val thmDeriv = Thm.get_name_hint thm
wneuper@59264
   514
    val (part, thyID) = Rtools.thy_containing_thm thmDeriv
wneuper@59264
   515
    val theID = [part, thyID, "Theorems", thmID_of_derivation_name thmDeriv]
wneuper@59269
   516
    val fillpats = case Specify.get_the theID of
wneuper@59264
   517
      Hthm {fillpats, ...} => fillpats
wneuper@59264
   518
    | _ => error "get_fillpats: uncovered case of get_the"
wneuper@59264
   519
    val some = map (get_fillform subst (thm, form) errpatID) fillpats
wneuper@59264
   520
  in some |> filter is_some |> map the end
neuper@42430
   521
wneuper@59276
   522
fun find_fillpatterns (pt, pos as (p, _): Ctree.pos') errpatID =
neuper@42430
   523
  let 
wneuper@59276
   524
    val f_curr = Ctree.get_curr_formula (pt, pos);
wneuper@59276
   525
    val pp = Ctree.par_pblobj pt p
wneuper@59276
   526
    val (errpats, prog) = case Specify.get_met (Ctree.get_obj Ctree.g_metID pt pp) of
wneuper@59264
   527
      {errpats, scr = Prog prog, ...} => (errpats, prog)
wneuper@59264
   528
    | _ => error "find_fillpatterns: uncovered case of get_met"
wneuper@59276
   529
    val env = case Ctree.get_istate pt pos of
wneuper@59300
   530
		  Selem.ScrState (env, _, _, _, _, _) => env
wneuper@59264
   531
		| _ => error "inform: uncovered case of get_istate"
wneuper@59263
   532
    val subst = Rtools.get_bdv_subst prog env
neuper@42430
   533
    val errpatthms = errpats
neuper@42430
   534
      |> filter ((curry op = errpatID) o (#1: errpat -> errpatID))
neuper@42430
   535
      |> map (#3: errpat -> thm list)
neuper@42430
   536
      |> flat
wneuper@59264
   537
  in map (get_fillpats subst f_curr errpatID) errpatthms |> flat end
neuper@37906
   538
neuper@42437
   539
(* check if an input formula is exactly equal the rewrite from a rule
neuper@42437
   540
   which is stored at the pos where the input is stored of "ok". *)
neuper@42437
   541
fun is_exactly_equal (pt, pos as (p, _)) istr =
neuper@42437
   542
  case parseNEW (assoc_thy "Isac" |> thy2ctxt) istr of
wneuper@59302
   543
    NONE => ("syntax error in '" ^ istr ^ "'", Tac.Tac "")
neuper@42437
   544
  | SOME ifo => 
neuper@42437
   545
      let
wneuper@59276
   546
        val p' = Ctree.lev_on p;
wneuper@59276
   547
        val tac = Ctree.get_obj Ctree.g_tac pt p';
neuper@42437
   548
      in 
wneuper@59272
   549
        case Applicable.applicable_in pos pt tac of
wneuper@59302
   550
          Chead.Notappl msg => (msg, Tac.Tac "")
wneuper@59265
   551
        | Chead.Appl rew =>
neuper@42437
   552
            let
neuper@42437
   553
              val res = case rew of
wneuper@59302
   554
               Tac.Rewrite_Inst' (_, _, _, _, _, _, _, (res, _)) => res
wneuper@59302
   555
              |Tac.Rewrite' (_, _, _, _, _, _, (res, _)) => res
wneuper@59302
   556
              | t => error ("is_exactly_equal: uncovered case for " ^ Tac.tac_2str t)
neuper@42437
   557
            in 
neuper@42437
   558
              if not (ifo = res)
wneuper@59302
   559
              then ("input does not exactly fill the gaps", Tac.Tac "")
neuper@42437
   560
              else ("ok", tac)
neuper@42437
   561
            end
neuper@42437
   562
      end
neuper@42437
   563
neuper@42458
   564
(* fetch errpatIDs from an arbitrary tactic *)
neuper@42458
   565
fun fetchErrorpatterns tac =
neuper@42458
   566
  let
neuper@42458
   567
    val rlsID =
neuper@42458
   568
      case tac of
wneuper@59302
   569
       Tac.Rewrite_Set rlsID => rlsID
wneuper@59302
   570
      |Tac.Rewrite_Set_Inst (_, rlsID) => rlsID
neuper@55415
   571
      | _ => "e_rls"
wneuper@59263
   572
    val (part, thyID) = Rtools.thy_containing_rls "Isac" rlsID;
wneuper@59269
   573
    val rls = case Specify.get_the [part, thyID, "Rulesets", rlsID] of
wneuper@59264
   574
      Hrls {thy_rls = (_, rls), ...} => rls
wneuper@59264
   575
    | _ => error "fetchErrorpatterns: uncovered case of get_the"
neuper@42458
   576
  in case rls of
wneuper@59264
   577
    Rls {errpatts, ...} => errpatts
wneuper@59264
   578
  | Seq {errpatts, ...} => errpatts
wneuper@59264
   579
  | Rrls {errpatts, ...} => errpatts
wneuper@59264
   580
  | Erls => []
neuper@42458
   581
  end
wneuper@59264
   582
wneuper@59262
   583
(**)
neuper@37906
   584
end
wneuper@59262
   585
(**)